aboutsummaryrefslogtreecommitdiff
path: root/src/server/scripts/northrend
diff options
context:
space:
mode:
authorclick <none@none>2010-06-05 21:22:47 +0200
committerclick <none@none>2010-06-05 21:22:47 +0200
commit455bfb01645510c677b88c693e0092244e1901e4 (patch)
treef9a1d305217c4967fdd572b595a98e2f58a0c482 /src/server/scripts/northrend
parenta2d6e7ff8c95e688adc625c01387af2ca3cde3a0 (diff)
Move core/realm files to new subdirectory
--HG-- branch : trunk rename : src/framework/CMakeLists.txt => src/server/framework/CMakeLists.txt rename : src/framework/Dynamic/FactoryHolder.h => src/server/framework/Dynamic/FactoryHolder.h rename : src/framework/Dynamic/ObjectRegistry.h => src/server/framework/Dynamic/ObjectRegistry.h rename : src/framework/GameSystem/Grid.h => src/server/framework/GameSystem/Grid.h rename : src/framework/GameSystem/GridLoader.h => src/server/framework/GameSystem/GridLoader.h rename : src/framework/GameSystem/GridRefManager.h => src/server/framework/GameSystem/GridRefManager.h rename : src/framework/GameSystem/GridReference.h => src/server/framework/GameSystem/GridReference.h rename : src/framework/GameSystem/NGrid.h => src/server/framework/GameSystem/NGrid.h rename : src/framework/GameSystem/TypeContainer.h => src/server/framework/GameSystem/TypeContainer.h rename : src/framework/GameSystem/TypeContainerFunctions.h => src/server/framework/GameSystem/TypeContainerFunctions.h rename : src/framework/GameSystem/TypeContainerFunctionsPtr.h => src/server/framework/GameSystem/TypeContainerFunctionsPtr.h rename : src/framework/GameSystem/TypeContainerVisitor.h => src/server/framework/GameSystem/TypeContainerVisitor.h rename : src/framework/Network/SocketDefines.h => src/server/framework/Network/SocketDefines.h rename : src/framework/Platform/CompilerDefs.h => src/server/framework/Platform/CompilerDefs.h rename : src/framework/Platform/Define.h => src/server/framework/Platform/Define.h rename : src/framework/Policies/CreationPolicy.h => src/server/framework/Policies/CreationPolicy.h rename : src/framework/Policies/ObjectLifeTime.cpp => src/server/framework/Policies/ObjectLifeTime.cpp rename : src/framework/Policies/ObjectLifeTime.h => src/server/framework/Policies/ObjectLifeTime.h rename : src/framework/Policies/Singleton.h => src/server/framework/Policies/Singleton.h rename : src/framework/Policies/SingletonImp.h => src/server/framework/Policies/SingletonImp.h rename : src/framework/Policies/ThreadingModel.h => src/server/framework/Policies/ThreadingModel.h rename : src/framework/Utilities/ByteConverter.h => src/server/framework/Utilities/ByteConverter.h rename : src/framework/Utilities/Callback.h => src/server/framework/Utilities/Callback.h rename : src/framework/Utilities/CountedReference/Reference.h => src/server/framework/Utilities/CountedReference/Reference.h rename : src/framework/Utilities/CountedReference/ReferenceHolder.h => src/server/framework/Utilities/CountedReference/ReferenceHolder.h rename : src/framework/Utilities/CountedReference/ReferenceImpl.h => src/server/framework/Utilities/CountedReference/ReferenceImpl.h rename : src/framework/Utilities/EventProcessor.cpp => src/server/framework/Utilities/EventProcessor.cpp rename : src/framework/Utilities/EventProcessor.h => src/server/framework/Utilities/EventProcessor.h rename : src/framework/Utilities/LinkedList.h => src/server/framework/Utilities/LinkedList.h rename : src/framework/Utilities/LinkedReference/RefManager.h => src/server/framework/Utilities/LinkedReference/RefManager.h rename : src/framework/Utilities/LinkedReference/Reference.h => src/server/framework/Utilities/LinkedReference/Reference.h rename : src/framework/Utilities/TypeList.h => src/server/framework/Utilities/TypeList.h rename : src/framework/Utilities/UnorderedMap.h => src/server/framework/Utilities/UnorderedMap.h rename : src/game/AccountMgr.cpp => src/server/game/AccountMgr.cpp rename : src/game/AccountMgr.h => src/server/game/AccountMgr.h rename : src/game/AchievementMgr.cpp => src/server/game/AchievementMgr.cpp rename : src/game/AchievementMgr.h => src/server/game/AchievementMgr.h rename : src/game/AddonHandler.cpp => src/server/game/AddonHandler.cpp rename : src/game/AddonHandler.h => src/server/game/AddonHandler.h rename : src/game/AddonMgr.cpp => src/server/game/AddonMgr.cpp rename : src/game/AddonMgr.h => src/server/game/AddonMgr.h rename : src/game/ArenaTeam.cpp => src/server/game/ArenaTeam.cpp rename : src/game/ArenaTeam.h => src/server/game/ArenaTeam.h rename : src/game/ArenaTeamHandler.cpp => src/server/game/ArenaTeamHandler.cpp rename : src/game/AuctionHouseBot.cpp => src/server/game/AuctionHouseBot.cpp rename : src/game/AuctionHouseBot.h => src/server/game/AuctionHouseBot.h rename : src/game/AuctionHouseHandler.cpp => src/server/game/AuctionHouseHandler.cpp rename : src/game/AuctionHouseMgr.cpp => src/server/game/AuctionHouseMgr.cpp rename : src/game/AuctionHouseMgr.h => src/server/game/AuctionHouseMgr.h rename : src/game/Bag.cpp => src/server/game/Bag.cpp rename : src/game/Bag.h => src/server/game/Bag.h rename : src/game/BattleGround.cpp => src/server/game/BattleGround.cpp rename : src/game/BattleGround.h => src/server/game/BattleGround.h rename : src/game/BattleGroundAA.cpp => src/server/game/BattleGroundAA.cpp rename : src/game/BattleGroundAA.h => src/server/game/BattleGroundAA.h rename : src/game/BattleGroundAB.cpp => src/server/game/BattleGroundAB.cpp rename : src/game/BattleGroundAB.h => src/server/game/BattleGroundAB.h rename : src/game/BattleGroundAV.cpp => src/server/game/BattleGroundAV.cpp rename : src/game/BattleGroundAV.h => src/server/game/BattleGroundAV.h rename : src/game/BattleGroundBE.cpp => src/server/game/BattleGroundBE.cpp rename : src/game/BattleGroundBE.h => src/server/game/BattleGroundBE.h rename : src/game/BattleGroundDS.cpp => src/server/game/BattleGroundDS.cpp rename : src/game/BattleGroundDS.h => src/server/game/BattleGroundDS.h rename : src/game/BattleGroundEY.cpp => src/server/game/BattleGroundEY.cpp rename : src/game/BattleGroundEY.h => src/server/game/BattleGroundEY.h rename : src/game/BattleGroundHandler.cpp => src/server/game/BattleGroundHandler.cpp rename : src/game/BattleGroundIC.cpp => src/server/game/BattleGroundIC.cpp rename : src/game/BattleGroundIC.h => src/server/game/BattleGroundIC.h rename : src/game/BattleGroundMgr.cpp => src/server/game/BattleGroundMgr.cpp rename : src/game/BattleGroundMgr.h => src/server/game/BattleGroundMgr.h rename : src/game/BattleGroundNA.cpp => src/server/game/BattleGroundNA.cpp rename : src/game/BattleGroundNA.h => src/server/game/BattleGroundNA.h rename : src/game/BattleGroundRB.cpp => src/server/game/BattleGroundRB.cpp rename : src/game/BattleGroundRB.h => src/server/game/BattleGroundRB.h rename : src/game/BattleGroundRL.cpp => src/server/game/BattleGroundRL.cpp rename : src/game/BattleGroundRL.h => src/server/game/BattleGroundRL.h rename : src/game/BattleGroundRV.cpp => src/server/game/BattleGroundRV.cpp rename : src/game/BattleGroundRV.h => src/server/game/BattleGroundRV.h rename : src/game/BattleGroundSA.cpp => src/server/game/BattleGroundSA.cpp rename : src/game/BattleGroundSA.h => src/server/game/BattleGroundSA.h rename : src/game/BattleGroundWS.cpp => src/server/game/BattleGroundWS.cpp rename : src/game/BattleGroundWS.h => src/server/game/BattleGroundWS.h rename : src/game/CMakeLists.txt => src/server/game/CMakeLists.txt rename : src/game/Calendar.cpp => src/server/game/Calendar.cpp rename : src/game/Calendar.h => src/server/game/Calendar.h rename : src/game/CalendarHandler.cpp => src/server/game/CalendarHandler.cpp rename : src/game/Cell.h => src/server/game/Cell.h rename : src/game/CellImpl.h => src/server/game/CellImpl.h rename : src/game/Channel.cpp => src/server/game/Channel.cpp rename : src/game/Channel.h => src/server/game/Channel.h rename : src/game/ChannelHandler.cpp => src/server/game/ChannelHandler.cpp rename : src/game/ChannelMgr.cpp => src/server/game/ChannelMgr.cpp rename : src/game/ChannelMgr.h => src/server/game/ChannelMgr.h rename : src/game/CharacterHandler.cpp => src/server/game/CharacterHandler.cpp rename : src/game/Chat.cpp => src/server/game/Chat.cpp rename : src/game/Chat.h => src/server/game/Chat.h rename : src/game/ChatHandler.cpp => src/server/game/ChatHandler.cpp rename : src/game/CombatAI.cpp => src/server/game/CombatAI.cpp rename : src/game/CombatAI.h => src/server/game/CombatAI.h rename : src/game/CombatHandler.cpp => src/server/game/CombatHandler.cpp rename : src/game/ConditionMgr.cpp => src/server/game/ConditionMgr.cpp rename : src/game/ConditionMgr.h => src/server/game/ConditionMgr.h rename : src/game/ConfusedMovementGenerator.cpp => src/server/game/ConfusedMovementGenerator.cpp rename : src/game/ConfusedMovementGenerator.h => src/server/game/ConfusedMovementGenerator.h rename : src/game/Corpse.cpp => src/server/game/Corpse.cpp rename : src/game/Corpse.h => src/server/game/Corpse.h rename : src/game/Creature.cpp => src/server/game/Creature.cpp rename : src/game/Creature.h => src/server/game/Creature.h rename : src/game/CreatureAI.cpp => src/server/game/CreatureAI.cpp rename : src/game/CreatureAI.h => src/server/game/CreatureAI.h rename : src/game/CreatureAIFactory.h => src/server/game/CreatureAIFactory.h rename : src/game/CreatureAIImpl.h => src/server/game/CreatureAIImpl.h rename : src/game/CreatureAIRegistry.cpp => src/server/game/CreatureAIRegistry.cpp rename : src/game/CreatureAIRegistry.h => src/server/game/CreatureAIRegistry.h rename : src/game/CreatureAISelector.cpp => src/server/game/CreatureAISelector.cpp rename : src/game/CreatureAISelector.h => src/server/game/CreatureAISelector.h rename : src/game/CreatureEventAI.cpp => src/server/game/CreatureEventAI.cpp rename : src/game/CreatureEventAI.h => src/server/game/CreatureEventAI.h rename : src/game/CreatureEventAIMgr.cpp => src/server/game/CreatureEventAIMgr.cpp rename : src/game/CreatureEventAIMgr.h => src/server/game/CreatureEventAIMgr.h rename : src/game/CreatureGroups.cpp => src/server/game/CreatureGroups.cpp rename : src/game/CreatureGroups.h => src/server/game/CreatureGroups.h rename : src/game/DBCEnums.h => src/server/game/DBCEnums.h rename : src/game/DBCStores.cpp => src/server/game/DBCStores.cpp rename : src/game/DBCStores.h => src/server/game/DBCStores.h rename : src/game/DBCStructure.h => src/server/game/DBCStructure.h rename : src/game/DBCfmt.h => src/server/game/DBCfmt.h rename : src/game/Debugcmds.cpp => src/server/game/Debugcmds.cpp rename : src/game/DestinationHolder.cpp => src/server/game/DestinationHolder.cpp rename : src/game/DestinationHolder.h => src/server/game/DestinationHolder.h rename : src/game/DestinationHolderImp.h => src/server/game/DestinationHolderImp.h rename : src/game/DuelHandler.cpp => src/server/game/DuelHandler.cpp rename : src/game/DynamicObject.cpp => src/server/game/DynamicObject.cpp rename : src/game/DynamicObject.h => src/server/game/DynamicObject.h rename : src/game/FleeingMovementGenerator.cpp => src/server/game/FleeingMovementGenerator.cpp rename : src/game/FleeingMovementGenerator.h => src/server/game/FleeingMovementGenerator.h rename : src/game/FollowerRefManager.h => src/server/game/FollowerRefManager.h rename : src/game/FollowerReference.cpp => src/server/game/FollowerReference.cpp rename : src/game/FollowerReference.h => src/server/game/FollowerReference.h rename : src/game/Formulas.h => src/server/game/Formulas.h rename : src/game/GameEventMgr.cpp => src/server/game/GameEventMgr.cpp rename : src/game/GameEventMgr.h => src/server/game/GameEventMgr.h rename : src/game/GameObject.cpp => src/server/game/GameObject.cpp rename : src/game/GameObject.h => src/server/game/GameObject.h rename : src/game/GlobalEvents.cpp => src/server/game/GlobalEvents.cpp rename : src/game/GlobalEvents.h => src/server/game/GlobalEvents.h rename : src/game/GossipDef.cpp => src/server/game/GossipDef.cpp rename : src/game/GossipDef.h => src/server/game/GossipDef.h rename : src/game/GridDefines.h => src/server/game/GridDefines.h rename : src/game/GridNotifiers.cpp => src/server/game/GridNotifiers.cpp rename : src/game/GridNotifiers.h => src/server/game/GridNotifiers.h rename : src/game/GridNotifiersImpl.h => src/server/game/GridNotifiersImpl.h rename : src/game/GridStates.cpp => src/server/game/GridStates.cpp rename : src/game/GridStates.h => src/server/game/GridStates.h rename : src/game/Group.cpp => src/server/game/Group.cpp rename : src/game/Group.h => src/server/game/Group.h rename : src/game/GroupHandler.cpp => src/server/game/GroupHandler.cpp rename : src/game/GroupRefManager.h => src/server/game/GroupRefManager.h rename : src/game/GroupReference.cpp => src/server/game/GroupReference.cpp rename : src/game/GroupReference.h => src/server/game/GroupReference.h rename : src/game/GuardAI.cpp => src/server/game/GuardAI.cpp rename : src/game/GuardAI.h => src/server/game/GuardAI.h rename : src/game/Guild.cpp => src/server/game/Guild.cpp rename : src/game/Guild.h => src/server/game/Guild.h rename : src/game/GuildHandler.cpp => src/server/game/GuildHandler.cpp rename : src/game/HomeMovementGenerator.cpp => src/server/game/HomeMovementGenerator.cpp rename : src/game/HomeMovementGenerator.h => src/server/game/HomeMovementGenerator.h rename : src/game/HostileRefManager.cpp => src/server/game/HostileRefManager.cpp rename : src/game/HostileRefManager.h => src/server/game/HostileRefManager.h rename : src/game/IdleMovementGenerator.cpp => src/server/game/IdleMovementGenerator.cpp rename : src/game/IdleMovementGenerator.h => src/server/game/IdleMovementGenerator.h rename : src/game/InstanceData.cpp => src/server/game/InstanceData.cpp rename : src/game/InstanceData.h => src/server/game/InstanceData.h rename : src/game/InstanceSaveMgr.cpp => src/server/game/InstanceSaveMgr.cpp rename : src/game/InstanceSaveMgr.h => src/server/game/InstanceSaveMgr.h rename : src/game/Item.cpp => src/server/game/Item.cpp rename : src/game/Item.h => src/server/game/Item.h rename : src/game/ItemEnchantmentMgr.cpp => src/server/game/ItemEnchantmentMgr.cpp rename : src/game/ItemEnchantmentMgr.h => src/server/game/ItemEnchantmentMgr.h rename : src/game/ItemHandler.cpp => src/server/game/ItemHandler.cpp rename : src/game/ItemPrototype.h => src/server/game/ItemPrototype.h rename : src/game/LFG.h => src/server/game/LFG.h rename : src/game/LFGHandler.cpp => src/server/game/LFGHandler.cpp rename : src/game/LFGMgr.cpp => src/server/game/LFGMgr.cpp rename : src/game/LFGMgr.h => src/server/game/LFGMgr.h rename : src/game/Language.h => src/server/game/Language.h rename : src/game/Level0.cpp => src/server/game/Level0.cpp rename : src/game/Level1.cpp => src/server/game/Level1.cpp rename : src/game/Level2.cpp => src/server/game/Level2.cpp rename : src/game/Level3.cpp => src/server/game/Level3.cpp rename : src/game/LootHandler.cpp => src/server/game/LootHandler.cpp rename : src/game/LootMgr.cpp => src/server/game/LootMgr.cpp rename : src/game/LootMgr.h => src/server/game/LootMgr.h rename : src/game/Mail.cpp => src/server/game/Mail.cpp rename : src/game/Mail.h => src/server/game/Mail.h rename : src/game/Map.cpp => src/server/game/Map.cpp rename : src/game/Map.h => src/server/game/Map.h rename : src/game/MapInstanced.cpp => src/server/game/MapInstanced.cpp rename : src/game/MapInstanced.h => src/server/game/MapInstanced.h rename : src/game/MapManager.cpp => src/server/game/MapManager.cpp rename : src/game/MapManager.h => src/server/game/MapManager.h rename : src/game/MapRefManager.h => src/server/game/MapRefManager.h rename : src/game/MapReference.h => src/server/game/MapReference.h rename : src/game/MapUpdater.cpp => src/server/game/MapUpdater.cpp rename : src/game/MapUpdater.h => src/server/game/MapUpdater.h rename : src/game/MiscHandler.cpp => src/server/game/MiscHandler.cpp rename : src/game/MotionMaster.cpp => src/server/game/MotionMaster.cpp rename : src/game/MotionMaster.h => src/server/game/MotionMaster.h rename : src/game/MovementGenerator.cpp => src/server/game/MovementGenerator.cpp rename : src/game/MovementGenerator.h => src/server/game/MovementGenerator.h rename : src/game/MovementGeneratorImpl.h => src/server/game/MovementGeneratorImpl.h rename : src/game/MovementHandler.cpp => src/server/game/MovementHandler.cpp rename : src/game/NPCHandler.cpp => src/server/game/NPCHandler.cpp rename : src/game/NPCHandler.h => src/server/game/NPCHandler.h rename : src/game/Object.cpp => src/server/game/Object.cpp rename : src/game/Object.h => src/server/game/Object.h rename : src/game/ObjectAccessor.cpp => src/server/game/ObjectAccessor.cpp rename : src/game/ObjectAccessor.h => src/server/game/ObjectAccessor.h rename : src/game/ObjectDefines.h => src/server/game/ObjectDefines.h rename : src/game/ObjectGridLoader.cpp => src/server/game/ObjectGridLoader.cpp rename : src/game/ObjectGridLoader.h => src/server/game/ObjectGridLoader.h rename : src/game/ObjectMgr.cpp => src/server/game/ObjectMgr.cpp rename : src/game/ObjectMgr.h => src/server/game/ObjectMgr.h rename : src/game/ObjectPosSelector.cpp => src/server/game/ObjectPosSelector.cpp rename : src/game/ObjectPosSelector.h => src/server/game/ObjectPosSelector.h rename : src/game/Opcodes.cpp => src/server/game/Opcodes.cpp rename : src/game/Opcodes.h => src/server/game/Opcodes.h rename : src/game/OutdoorPvP.cpp => src/server/game/OutdoorPvP.cpp rename : src/game/OutdoorPvP.h => src/server/game/OutdoorPvP.h rename : src/game/OutdoorPvPEP.cpp => src/server/game/OutdoorPvPEP.cpp rename : src/game/OutdoorPvPEP.h => src/server/game/OutdoorPvPEP.h rename : src/game/OutdoorPvPHP.cpp => src/server/game/OutdoorPvPHP.cpp rename : src/game/OutdoorPvPHP.h => src/server/game/OutdoorPvPHP.h rename : src/game/OutdoorPvPImpl.h => src/server/game/OutdoorPvPImpl.h rename : src/game/OutdoorPvPMgr.cpp => src/server/game/OutdoorPvPMgr.cpp rename : src/game/OutdoorPvPMgr.h => src/server/game/OutdoorPvPMgr.h rename : src/game/OutdoorPvPNA.cpp => src/server/game/OutdoorPvPNA.cpp rename : src/game/OutdoorPvPNA.h => src/server/game/OutdoorPvPNA.h rename : src/game/OutdoorPvPSI.cpp => src/server/game/OutdoorPvPSI.cpp rename : src/game/OutdoorPvPSI.h => src/server/game/OutdoorPvPSI.h rename : src/game/OutdoorPvPTF.cpp => src/server/game/OutdoorPvPTF.cpp rename : src/game/OutdoorPvPTF.h => src/server/game/OutdoorPvPTF.h rename : src/game/OutdoorPvPZM.cpp => src/server/game/OutdoorPvPZM.cpp rename : src/game/OutdoorPvPZM.h => src/server/game/OutdoorPvPZM.h rename : src/game/PassiveAI.cpp => src/server/game/PassiveAI.cpp rename : src/game/PassiveAI.h => src/server/game/PassiveAI.h rename : src/game/Path.h => src/server/game/Path.h rename : src/game/Pet.cpp => src/server/game/Pet.cpp rename : src/game/Pet.h => src/server/game/Pet.h rename : src/game/PetAI.cpp => src/server/game/PetAI.cpp rename : src/game/PetAI.h => src/server/game/PetAI.h rename : src/game/PetHandler.cpp => src/server/game/PetHandler.cpp rename : src/game/PetitionsHandler.cpp => src/server/game/PetitionsHandler.cpp rename : src/game/Player.cpp => src/server/game/Player.cpp rename : src/game/Player.h => src/server/game/Player.h rename : src/game/PlayerDump.cpp => src/server/game/PlayerDump.cpp rename : src/game/PlayerDump.h => src/server/game/PlayerDump.h rename : src/game/PointMovementGenerator.cpp => src/server/game/PointMovementGenerator.cpp rename : src/game/PointMovementGenerator.h => src/server/game/PointMovementGenerator.h rename : src/game/PoolHandler.cpp => src/server/game/PoolHandler.cpp rename : src/game/PoolHandler.h => src/server/game/PoolHandler.h rename : src/game/QueryHandler.cpp => src/server/game/QueryHandler.cpp rename : src/game/QuestDef.cpp => src/server/game/QuestDef.cpp rename : src/game/QuestDef.h => src/server/game/QuestDef.h rename : src/game/QuestHandler.cpp => src/server/game/QuestHandler.cpp rename : src/game/RandomMovementGenerator.cpp => src/server/game/RandomMovementGenerator.cpp rename : src/game/RandomMovementGenerator.h => src/server/game/RandomMovementGenerator.h rename : src/game/ReactorAI.cpp => src/server/game/ReactorAI.cpp rename : src/game/ReactorAI.h => src/server/game/ReactorAI.h rename : src/game/ReputationMgr.cpp => src/server/game/ReputationMgr.cpp rename : src/game/ReputationMgr.h => src/server/game/ReputationMgr.h rename : src/game/ScriptLoader.cpp => src/server/game/ScriptLoader.cpp rename : src/game/ScriptLoader.h => src/server/game/ScriptLoader.h rename : src/game/ScriptMgr.cpp => src/server/game/ScriptMgr.cpp rename : src/game/ScriptMgr.h => src/server/game/ScriptMgr.h rename : src/game/ScriptSystem.cpp => src/server/game/ScriptSystem.cpp rename : src/game/ScriptSystem.h => src/server/game/ScriptSystem.h rename : src/game/ScriptedCreature.cpp => src/server/game/ScriptedCreature.cpp rename : src/game/ScriptedCreature.h => src/server/game/ScriptedCreature.h rename : src/game/ScriptedEscortAI.cpp => src/server/game/ScriptedEscortAI.cpp rename : src/game/ScriptedEscortAI.h => src/server/game/ScriptedEscortAI.h rename : src/game/ScriptedFollowerAI.cpp => src/server/game/ScriptedFollowerAI.cpp rename : src/game/ScriptedFollowerAI.h => src/server/game/ScriptedFollowerAI.h rename : src/game/ScriptedGossip.h => src/server/game/ScriptedGossip.h rename : src/game/ScriptedGuardAI.cpp => src/server/game/ScriptedGuardAI.cpp rename : src/game/ScriptedGuardAI.h => src/server/game/ScriptedGuardAI.h rename : src/game/ScriptedInstance.h => src/server/game/ScriptedInstance.h rename : src/game/ScriptedPch.cpp => src/server/game/ScriptedPch.cpp rename : src/game/ScriptedPch.h => src/server/game/ScriptedPch.h rename : src/game/ScriptedSimpleAI.cpp => src/server/game/ScriptedSimpleAI.cpp rename : src/game/ScriptedSimpleAI.h => src/server/game/ScriptedSimpleAI.h rename : src/game/ScriptedSmartAI.cpp => src/server/game/ScriptedSmartAI.cpp rename : src/game/ScriptedSmartAI.h => src/server/game/ScriptedSmartAI.h rename : src/game/SharedDefines.h => src/server/game/SharedDefines.h rename : src/game/SkillDiscovery.cpp => src/server/game/SkillDiscovery.cpp rename : src/game/SkillDiscovery.h => src/server/game/SkillDiscovery.h rename : src/game/SkillExtraItems.cpp => src/server/game/SkillExtraItems.cpp rename : src/game/SkillExtraItems.h => src/server/game/SkillExtraItems.h rename : src/game/SkillHandler.cpp => src/server/game/SkillHandler.cpp rename : src/game/SocialMgr.cpp => src/server/game/SocialMgr.cpp rename : src/game/SocialMgr.h => src/server/game/SocialMgr.h rename : src/game/Spell.cpp => src/server/game/Spell.cpp rename : src/game/Spell.h => src/server/game/Spell.h rename : src/game/SpellAuraDefines.h => src/server/game/SpellAuraDefines.h rename : src/game/SpellAuraEffects.cpp => src/server/game/SpellAuraEffects.cpp rename : src/game/SpellAuraEffects.h => src/server/game/SpellAuraEffects.h rename : src/game/SpellAuras.cpp => src/server/game/SpellAuras.cpp rename : src/game/SpellAuras.h => src/server/game/SpellAuras.h rename : src/game/SpellEffects.cpp => src/server/game/SpellEffects.cpp rename : src/game/SpellHandler.cpp => src/server/game/SpellHandler.cpp rename : src/game/SpellMgr.cpp => src/server/game/SpellMgr.cpp rename : src/game/SpellMgr.h => src/server/game/SpellMgr.h rename : src/game/StatSystem.cpp => src/server/game/StatSystem.cpp rename : src/game/TargetedMovementGenerator.cpp => src/server/game/TargetedMovementGenerator.cpp rename : src/game/TargetedMovementGenerator.h => src/server/game/TargetedMovementGenerator.h rename : src/game/TaxiHandler.cpp => src/server/game/TaxiHandler.cpp rename : src/game/TemporarySummon.cpp => src/server/game/TemporarySummon.cpp rename : src/game/TemporarySummon.h => src/server/game/TemporarySummon.h rename : src/game/ThreatManager.cpp => src/server/game/ThreatManager.cpp rename : src/game/ThreatManager.h => src/server/game/ThreatManager.h rename : src/game/TicketHandler.cpp => src/server/game/TicketHandler.cpp rename : src/game/TimeMgr.cpp => src/server/game/TimeMgr.cpp rename : src/game/TimeMgr.h => src/server/game/TimeMgr.h rename : src/game/Tools.cpp => src/server/game/Tools.cpp rename : src/game/Tools.h => src/server/game/Tools.h rename : src/game/Totem.cpp => src/server/game/Totem.cpp rename : src/game/Totem.h => src/server/game/Totem.h rename : src/game/TotemAI.cpp => src/server/game/TotemAI.cpp rename : src/game/TotemAI.h => src/server/game/TotemAI.h rename : src/game/TradeHandler.cpp => src/server/game/TradeHandler.cpp rename : src/game/Transports.cpp => src/server/game/Transports.cpp rename : src/game/Transports.h => src/server/game/Transports.h rename : src/game/Traveller.h => src/server/game/Traveller.h rename : src/game/Unit.cpp => src/server/game/Unit.cpp rename : src/game/Unit.h => src/server/game/Unit.h rename : src/game/UnitAI.cpp => src/server/game/UnitAI.cpp rename : src/game/UnitAI.h => src/server/game/UnitAI.h rename : src/game/UnitEvents.h => src/server/game/UnitEvents.h rename : src/game/UpdateData.cpp => src/server/game/UpdateData.cpp rename : src/game/UpdateData.h => src/server/game/UpdateData.h rename : src/game/UpdateFields.h => src/server/game/UpdateFields.h rename : src/game/UpdateMask.h => src/server/game/UpdateMask.h rename : src/game/Vehicle.cpp => src/server/game/Vehicle.cpp rename : src/game/Vehicle.h => src/server/game/Vehicle.h rename : src/game/VoiceChatHandler.cpp => src/server/game/VoiceChatHandler.cpp rename : src/game/WaypointManager.cpp => src/server/game/WaypointManager.cpp rename : src/game/WaypointManager.h => src/server/game/WaypointManager.h rename : src/game/WaypointMovementGenerator.cpp => src/server/game/WaypointMovementGenerator.cpp rename : src/game/WaypointMovementGenerator.h => src/server/game/WaypointMovementGenerator.h rename : src/game/Weather.cpp => src/server/game/Weather.cpp rename : src/game/Weather.h => src/server/game/Weather.h rename : src/game/World.cpp => src/server/game/World.cpp rename : src/game/World.h => src/server/game/World.h rename : src/game/WorldLog.cpp => src/server/game/WorldLog.cpp rename : src/game/WorldLog.h => src/server/game/WorldLog.h rename : src/game/WorldSession.cpp => src/server/game/WorldSession.cpp rename : src/game/WorldSession.h => src/server/game/WorldSession.h rename : src/game/WorldSocket.cpp => src/server/game/WorldSocket.cpp rename : src/game/WorldSocket.h => src/server/game/WorldSocket.h rename : src/game/WorldSocketMgr.cpp => src/server/game/WorldSocketMgr.cpp rename : src/game/WorldSocketMgr.h => src/server/game/WorldSocketMgr.h rename : src/game/ZoneScript.h => src/server/game/ZoneScript.h rename : src/game/pchdef.cpp => src/server/game/pchdef.cpp rename : src/game/pchdef.h => src/server/game/pchdef.h rename : src/game/pchlinux.cpp => src/server/game/pchlinux.cpp rename : src/game/pchlinux.h => src/server/game/pchlinux.h rename : src/scripts/CMakeLists.txt => src/server/scripts/CMakeLists.txt rename : src/scripts/custom/custom_example.cpp => src/server/scripts/custom/custom_example.cpp rename : src/scripts/custom/custom_gossip_codebox.cpp => src/server/scripts/custom/custom_gossip_codebox.cpp rename : src/scripts/custom/npc_acherus_taxi.cpp => src/server/scripts/custom/npc_acherus_taxi.cpp rename : src/scripts/custom/npc_wyrmresttempel_taxi.cpp => src/server/scripts/custom/npc_wyrmresttempel_taxi.cpp rename : src/scripts/custom/on_events.cpp => src/server/scripts/custom/on_events.cpp rename : src/scripts/custom/test.cpp => src/server/scripts/custom/test.cpp rename : src/scripts/eastern_kingdoms/alterac_mountains.cpp => src/server/scripts/eastern_kingdoms/alterac_mountains.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/alterac_valley.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/alterac_valley.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/boss_balinda.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/boss_balinda.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/boss_drekthar.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/boss_drekthar.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/boss_galvangar.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/boss_galvangar.cpp rename : src/scripts/eastern_kingdoms/alterac_valley/boss_vanndar.cpp => src/server/scripts/eastern_kingdoms/alterac_valley/boss_vanndar.cpp rename : src/scripts/eastern_kingdoms/arathi_highlands.cpp => src/server/scripts/eastern_kingdoms/arathi_highlands.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h => src/server/scripts/eastern_kingdoms/blackrock_depths/blackrock_depths.h rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_ambassador_flamelash.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_ambassador_flamelash.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_anubshiah.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_anubshiah.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_emperor_dagran_thaurissan.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_emperor_dagran_thaurissan.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_general_angerforge.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_general_angerforge.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_gorosh_the_dervish.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_gorosh_the_dervish.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_grizzle.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_grizzle.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_high_interrogator_gerstahn.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_high_interrogator_gerstahn.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_magmus.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_magmus.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_moira_bronzebeard.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_moira_bronzebeard.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/boss_tomb_of_seven.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/boss_tomb_of_seven.cpp rename : src/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp => src/server/scripts/eastern_kingdoms/blackrock_depths/instance_blackrock_depths.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.h => src/server/scripts/eastern_kingdoms/blackrock_spire/blackrock_spire.h rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_drakkisath.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_drakkisath.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_gyth.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_gyth.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_halycon.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_halycon.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_highlord_omokk.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_highlord_omokk.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_mother_smolderweb.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_mother_smolderweb.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_overlord_wyrmthalak.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_overlord_wyrmthalak.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_pyroguard_emberseer.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_pyroguard_emberseer.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_quartermaster_zigris.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_quartermaster_zigris.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_rend_blackhand.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_rend_blackhand.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_shadow_hunter_voshgajin.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_shadow_hunter_voshgajin.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_the_beast.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_the_beast.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/boss_warmaster_voone.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/boss_warmaster_voone.cpp rename : src/scripts/eastern_kingdoms/blackrock_spire/instance_blackrock_spire.cpp => src/server/scripts/eastern_kingdoms/blackrock_spire/instance_blackrock_spire.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_broodlord_lashlayer.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_broodlord_lashlayer.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_chromaggus.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_ebonroc.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_ebonroc.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_firemaw.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_firemaw.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_flamegor.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_flamegor.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_nefarian.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_nefarian.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_razorgore.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_razorgore.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_vaelastrasz.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_vaelastrasz.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/boss_victor_nefarius.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/boss_victor_nefarius.cpp rename : src/scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp => src/server/scripts/eastern_kingdoms/blackwing_lair/instance_blackwing_lair.cpp rename : src/scripts/eastern_kingdoms/blasted_lands.cpp => src/server/scripts/eastern_kingdoms/blasted_lands.cpp rename : src/scripts/eastern_kingdoms/boss_kruul.cpp => src/server/scripts/eastern_kingdoms/boss_kruul.cpp rename : src/scripts/eastern_kingdoms/burning_steppes.cpp => src/server/scripts/eastern_kingdoms/burning_steppes.cpp rename : src/scripts/eastern_kingdoms/deadmines/boss_mr_smite.cpp => src/server/scripts/eastern_kingdoms/deadmines/boss_mr_smite.cpp rename : src/scripts/eastern_kingdoms/deadmines/deadmines.cpp => src/server/scripts/eastern_kingdoms/deadmines/deadmines.cpp rename : src/scripts/eastern_kingdoms/deadmines/deadmines.h => src/server/scripts/eastern_kingdoms/deadmines/deadmines.h rename : src/scripts/eastern_kingdoms/deadmines/instance_deadmines.cpp => src/server/scripts/eastern_kingdoms/deadmines/instance_deadmines.cpp rename : src/scripts/eastern_kingdoms/dun_morogh.cpp => src/server/scripts/eastern_kingdoms/dun_morogh.cpp rename : src/scripts/eastern_kingdoms/duskwood.cpp => src/server/scripts/eastern_kingdoms/duskwood.cpp rename : src/scripts/eastern_kingdoms/eastern_plaguelands.cpp => src/server/scripts/eastern_kingdoms/eastern_plaguelands.cpp rename : src/scripts/eastern_kingdoms/elwynn_forest.cpp => src/server/scripts/eastern_kingdoms/elwynn_forest.cpp rename : src/scripts/eastern_kingdoms/eversong_woods.cpp => src/server/scripts/eastern_kingdoms/eversong_woods.cpp rename : src/scripts/eastern_kingdoms/ghostlands.cpp => src/server/scripts/eastern_kingdoms/ghostlands.cpp rename : src/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp => src/server/scripts/eastern_kingdoms/gnomeregan/gnomeregan.cpp rename : src/scripts/eastern_kingdoms/gnomeregan/gnomeregan.h => src/server/scripts/eastern_kingdoms/gnomeregan/gnomeregan.h rename : src/scripts/eastern_kingdoms/gnomeregan/instance_gnomeregan.cpp => src/server/scripts/eastern_kingdoms/gnomeregan/instance_gnomeregan.cpp rename : src/scripts/eastern_kingdoms/hinterlands.cpp => src/server/scripts/eastern_kingdoms/hinterlands.cpp rename : src/scripts/eastern_kingdoms/ironforge.cpp => src/server/scripts/eastern_kingdoms/ironforge.cpp rename : src/scripts/eastern_kingdoms/isle_of_queldanas.cpp => src/server/scripts/eastern_kingdoms/isle_of_queldanas.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_curator.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_curator.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_maiden_of_virtue.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_maiden_of_virtue.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_midnight.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_midnight.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_moroes.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_moroes.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_netherspite.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_netherspite.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_nightbane.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_nightbane.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_prince_malchezaar.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_shade_of_aran.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_shade_of_aran.cpp rename : src/scripts/eastern_kingdoms/karazhan/boss_terestian_illhoof.cpp => src/server/scripts/eastern_kingdoms/karazhan/boss_terestian_illhoof.cpp rename : src/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp => src/server/scripts/eastern_kingdoms/karazhan/bosses_opera.cpp rename : src/scripts/eastern_kingdoms/karazhan/instance_karazhan.cpp => src/server/scripts/eastern_kingdoms/karazhan/instance_karazhan.cpp rename : src/scripts/eastern_kingdoms/karazhan/karazhan.cpp => src/server/scripts/eastern_kingdoms/karazhan/karazhan.cpp rename : src/scripts/eastern_kingdoms/karazhan/karazhan.h => src/server/scripts/eastern_kingdoms/karazhan/karazhan.h rename : src/scripts/eastern_kingdoms/loch_modan.cpp => src/server/scripts/eastern_kingdoms/loch_modan.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/boss_felblood_kaelthas.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/boss_priestess_delrissa.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/boss_priestess_delrissa.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/boss_selin_fireheart.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/boss_selin_fireheart.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/boss_vexallus.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/boss_vexallus.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/instance_magisters_terrace.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/instance_magisters_terrace.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.cpp => src/server/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.cpp rename : src/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.h => src/server/scripts/eastern_kingdoms/magisters_terrace/magisters_terrace.h rename : src/scripts/eastern_kingdoms/molten_core/boss_baron_geddon.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_baron_geddon.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_garr.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_garr.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_gehennas.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_gehennas.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_golemagg.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_golemagg.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_lucifron.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_lucifron.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_magmadar.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_magmadar.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_ragnaros.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_shazzrah.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_shazzrah.cpp rename : src/scripts/eastern_kingdoms/molten_core/boss_sulfuron_harbinger.cpp => src/server/scripts/eastern_kingdoms/molten_core/boss_sulfuron_harbinger.cpp rename : src/scripts/eastern_kingdoms/molten_core/instance_molten_core.cpp => src/server/scripts/eastern_kingdoms/molten_core/instance_molten_core.cpp rename : src/scripts/eastern_kingdoms/molten_core/molten_core.cpp => src/server/scripts/eastern_kingdoms/molten_core/molten_core.cpp rename : src/scripts/eastern_kingdoms/molten_core/molten_core.h => src/server/scripts/eastern_kingdoms/molten_core/molten_core.h rename : src/scripts/eastern_kingdoms/redridge_mountains.cpp => src/server/scripts/eastern_kingdoms/redridge_mountains.cpp rename : src/scripts/eastern_kingdoms/scarlet_enclave/chapter1.cpp => src/server/scripts/eastern_kingdoms/scarlet_enclave/chapter1.cpp rename : src/scripts/eastern_kingdoms/scarlet_enclave/chapter2.cpp => src/server/scripts/eastern_kingdoms/scarlet_enclave/chapter2.cpp rename : src/scripts/eastern_kingdoms/scarlet_enclave/chapter5.cpp => src/server/scripts/eastern_kingdoms/scarlet_enclave/chapter5.cpp rename : src/scripts/eastern_kingdoms/scarlet_enclave/the_scarlet_enclave.cpp => src/server/scripts/eastern_kingdoms/scarlet_enclave/the_scarlet_enclave.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_arcanist_doan.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_arcanist_doan.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_azshir_the_sleepless.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_azshir_the_sleepless.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_bloodmage_thalnos.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_bloodmage_thalnos.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_headless_horseman.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_headless_horseman.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_herod.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_herod.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_high_inquisitor_fairbanks.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_houndmaster_loksey.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_houndmaster_loksey.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_interrogator_vishas.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_interrogator_vishas.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_mograine_and_whitemane.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_mograine_and_whitemane.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/boss_scorn.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/boss_scorn.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/instance_scarlet_monastery.cpp => src/server/scripts/eastern_kingdoms/scarlet_monastery/instance_scarlet_monastery.cpp rename : src/scripts/eastern_kingdoms/scarlet_monastery/scarlet_monastery.h => src/server/scripts/eastern_kingdoms/scarlet_monastery/scarlet_monastery.h rename : src/scripts/eastern_kingdoms/scholomance/boss_darkmaster_gandling.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_darkmaster_gandling.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_death_knight_darkreaver.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_death_knight_darkreaver.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_doctor_theolen_krastinov.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_doctor_theolen_krastinov.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_illucia_barov.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_illucia_barov.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_instructor_malicia.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_instructor_malicia.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_jandice_barov.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_jandice_barov.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_kormok.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_kormok.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_lord_alexei_barov.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_lord_alexei_barov.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_lorekeeper_polkelt.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_lorekeeper_polkelt.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_ras_frostwhisper.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_ras_frostwhisper.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_the_ravenian.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_the_ravenian.cpp rename : src/scripts/eastern_kingdoms/scholomance/boss_vectus.cpp => src/server/scripts/eastern_kingdoms/scholomance/boss_vectus.cpp rename : src/scripts/eastern_kingdoms/scholomance/instance_scholomance.cpp => src/server/scripts/eastern_kingdoms/scholomance/instance_scholomance.cpp rename : src/scripts/eastern_kingdoms/scholomance/scholomance.h => src/server/scripts/eastern_kingdoms/scholomance/scholomance.h rename : src/scripts/eastern_kingdoms/searing_gorge.cpp => src/server/scripts/eastern_kingdoms/searing_gorge.cpp rename : src/scripts/eastern_kingdoms/shadowfang_keep/instance_shadowfang_keep.cpp => src/server/scripts/eastern_kingdoms/shadowfang_keep/instance_shadowfang_keep.cpp rename : src/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp => src/server/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp rename : src/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.h => src/server/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.h rename : src/scripts/eastern_kingdoms/silvermoon_city.cpp => src/server/scripts/eastern_kingdoms/silvermoon_city.cpp rename : src/scripts/eastern_kingdoms/silverpine_forest.cpp => src/server/scripts/eastern_kingdoms/silverpine_forest.cpp rename : src/scripts/eastern_kingdoms/stormwind_city.cpp => src/server/scripts/eastern_kingdoms/stormwind_city.cpp rename : src/scripts/eastern_kingdoms/stranglethorn_vale.cpp => src/server/scripts/eastern_kingdoms/stranglethorn_vale.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_baron_rivendare.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_baron_rivendare.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_baroness_anastari.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_baroness_anastari.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_cannon_master_willey.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_cannon_master_willey.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_dathrohan_balnazzar.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_dathrohan_balnazzar.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_magistrate_barthilas.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_magistrate_barthilas.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_maleki_the_pallid.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_maleki_the_pallid.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_nerubenkan.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_nerubenkan.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_order_of_silver_hand.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_order_of_silver_hand.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_postmaster_malown.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_postmaster_malown.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_ramstein_the_gorger.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_ramstein_the_gorger.cpp rename : src/scripts/eastern_kingdoms/stratholme/boss_timmy_the_cruel.cpp => src/server/scripts/eastern_kingdoms/stratholme/boss_timmy_the_cruel.cpp rename : src/scripts/eastern_kingdoms/stratholme/instance_stratholme.cpp => src/server/scripts/eastern_kingdoms/stratholme/instance_stratholme.cpp rename : src/scripts/eastern_kingdoms/stratholme/stratholme.cpp => src/server/scripts/eastern_kingdoms/stratholme/stratholme.cpp rename : src/scripts/eastern_kingdoms/stratholme/stratholme.h => src/server/scripts/eastern_kingdoms/stratholme/stratholme.h rename : src/scripts/eastern_kingdoms/sunken_temple/instance_sunken_temple.cpp => src/server/scripts/eastern_kingdoms/sunken_temple/instance_sunken_temple.cpp rename : src/scripts/eastern_kingdoms/sunken_temple/sunken_temple.cpp => src/server/scripts/eastern_kingdoms/sunken_temple/sunken_temple.cpp rename : src/scripts/eastern_kingdoms/sunken_temple/sunken_temple.h => src/server/scripts/eastern_kingdoms/sunken_temple/sunken_temple.h rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_brutallus.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_brutallus.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_eredar_twins.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_eredar_twins.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_felmyst.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_felmyst.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_kalecgos.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_kalecgos.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_kiljaeden.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_kiljaeden.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/boss_muru.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/boss_muru.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/instance_sunwell_plateau.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/instance_sunwell_plateau.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.cpp => src/server/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.cpp rename : src/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.h => src/server/scripts/eastern_kingdoms/sunwell_plateau/sunwell_plateau.h rename : src/scripts/eastern_kingdoms/tirisfal_glades.cpp => src/server/scripts/eastern_kingdoms/tirisfal_glades.cpp rename : src/scripts/eastern_kingdoms/uldaman/boss_archaedas.cpp => src/server/scripts/eastern_kingdoms/uldaman/boss_archaedas.cpp rename : src/scripts/eastern_kingdoms/uldaman/boss_ironaya.cpp => src/server/scripts/eastern_kingdoms/uldaman/boss_ironaya.cpp rename : src/scripts/eastern_kingdoms/uldaman/instance_uldaman.cpp => src/server/scripts/eastern_kingdoms/uldaman/instance_uldaman.cpp rename : src/scripts/eastern_kingdoms/uldaman/uldaman.cpp => src/server/scripts/eastern_kingdoms/uldaman/uldaman.cpp rename : src/scripts/eastern_kingdoms/undercity.cpp => src/server/scripts/eastern_kingdoms/undercity.cpp rename : src/scripts/eastern_kingdoms/western_plaguelands.cpp => src/server/scripts/eastern_kingdoms/western_plaguelands.cpp rename : src/scripts/eastern_kingdoms/westfall.cpp => src/server/scripts/eastern_kingdoms/westfall.cpp rename : src/scripts/eastern_kingdoms/wetlands.cpp => src/server/scripts/eastern_kingdoms/wetlands.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_akilzon.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_akilzon.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_halazzi.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_halazzi.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_hexlord.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_hexlord.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_janalai.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_janalai.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_nalorakk.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_nalorakk.cpp rename : src/scripts/eastern_kingdoms/zulaman/boss_zuljin.cpp => src/server/scripts/eastern_kingdoms/zulaman/boss_zuljin.cpp rename : src/scripts/eastern_kingdoms/zulaman/instance_zulaman.cpp => src/server/scripts/eastern_kingdoms/zulaman/instance_zulaman.cpp rename : src/scripts/eastern_kingdoms/zulaman/zulaman.cpp => src/server/scripts/eastern_kingdoms/zulaman/zulaman.cpp rename : src/scripts/eastern_kingdoms/zulaman/zulaman.h => src/server/scripts/eastern_kingdoms/zulaman/zulaman.h rename : src/scripts/eastern_kingdoms/zulgurub/boss_arlokk.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_arlokk.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_gahzranka.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_gahzranka.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_grilek.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_grilek.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_hakkar.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_hakkar.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_hazzarah.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_hazzarah.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_jeklik.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_jindo.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_jindo.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_mandokir.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_marli.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_marli.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_renataki.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_renataki.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_thekal.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_venoxis.cpp rename : src/scripts/eastern_kingdoms/zulgurub/boss_wushoolay.cpp => src/server/scripts/eastern_kingdoms/zulgurub/boss_wushoolay.cpp rename : src/scripts/eastern_kingdoms/zulgurub/instance_zulgurub.cpp => src/server/scripts/eastern_kingdoms/zulgurub/instance_zulgurub.cpp rename : src/scripts/eastern_kingdoms/zulgurub/zulgurub.h => src/server/scripts/eastern_kingdoms/zulgurub/zulgurub.h rename : src/scripts/examples/example_creature.cpp => src/server/scripts/examples/example_creature.cpp rename : src/scripts/examples/example_escort.cpp => src/server/scripts/examples/example_escort.cpp rename : src/scripts/examples/example_gossip_codebox.cpp => src/server/scripts/examples/example_gossip_codebox.cpp rename : src/scripts/examples/example_misc.cpp => src/server/scripts/examples/example_misc.cpp rename : src/scripts/kalimdor/ashenvale.cpp => src/server/scripts/kalimdor/ashenvale.cpp rename : src/scripts/kalimdor/azshara.cpp => src/server/scripts/kalimdor/azshara.cpp rename : src/scripts/kalimdor/azuremyst_isle.cpp => src/server/scripts/kalimdor/azuremyst_isle.cpp rename : src/scripts/kalimdor/blackfathom_depths/blackfathom_deeps.cpp => src/server/scripts/kalimdor/blackfathom_depths/blackfathom_deeps.cpp rename : src/scripts/kalimdor/blackfathom_depths/blackfathom_deeps.h => src/server/scripts/kalimdor/blackfathom_depths/blackfathom_deeps.h rename : src/scripts/kalimdor/blackfathom_depths/boss_aku_mai.cpp => src/server/scripts/kalimdor/blackfathom_depths/boss_aku_mai.cpp rename : src/scripts/kalimdor/blackfathom_depths/boss_gelihast.cpp => src/server/scripts/kalimdor/blackfathom_depths/boss_gelihast.cpp rename : src/scripts/kalimdor/blackfathom_depths/boss_kelris.cpp => src/server/scripts/kalimdor/blackfathom_depths/boss_kelris.cpp rename : src/scripts/kalimdor/blackfathom_depths/instance_blackfathom_deeps.cpp => src/server/scripts/kalimdor/blackfathom_depths/instance_blackfathom_deeps.cpp rename : src/scripts/kalimdor/bloodmyst_isle.cpp => src/server/scripts/kalimdor/bloodmyst_isle.cpp rename : src/scripts/kalimdor/boss_azuregos.cpp => src/server/scripts/kalimdor/boss_azuregos.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_epoch.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_epoch.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_infinite.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_infinite.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_mal_ganis.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_mal_ganis.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_meathook.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_meathook.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_salramm.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/boss_salramm.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.cpp rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.h => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/culling_of_stratholme.h rename : src/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp => src/server/scripts/kalimdor/caverns_of_time/culling_of_stratholme/instance_culling_of_stratholme.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/boss_aeonus.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/boss_aeonus.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/boss_chrono_lord_deja.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/boss_temporus.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/boss_temporus.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.cpp rename : src/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.h => src/server/scripts/kalimdor/caverns_of_time/dark_portal/dark_portal.h rename : src/scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp => src/server/scripts/kalimdor/caverns_of_time/dark_portal/instance_dark_portal.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_anetheron.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_anetheron.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_archimonde.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_azgalor.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_azgalor.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_kazrogal.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_kazrogal.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/boss_rage_winterchill.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/boss_rage_winterchill.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjal.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjal.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjal.h => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjal.h rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.h => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.h rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.cpp rename : src/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.h => src/server/scripts/kalimdor/caverns_of_time/hyjal/hyjal_trash.h rename : src/scripts/kalimdor/caverns_of_time/hyjal/instance_hyjal.cpp => src/server/scripts/kalimdor/caverns_of_time/hyjal/instance_hyjal.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_captain_skarloc.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_epoch_hunter.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/boss_leutenant_drake.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/instance_old_hillsbrad.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp rename : src/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.h => src/server/scripts/kalimdor/caverns_of_time/old_hillsbrad/old_hillsbrad.h rename : src/scripts/kalimdor/darkshore.cpp => src/server/scripts/kalimdor/darkshore.cpp rename : src/scripts/kalimdor/desolace.cpp => src/server/scripts/kalimdor/desolace.cpp rename : src/scripts/kalimdor/durotar.cpp => src/server/scripts/kalimdor/durotar.cpp rename : src/scripts/kalimdor/dustwallow_marsh.cpp => src/server/scripts/kalimdor/dustwallow_marsh.cpp rename : src/scripts/kalimdor/felwood.cpp => src/server/scripts/kalimdor/felwood.cpp rename : src/scripts/kalimdor/feralas.cpp => src/server/scripts/kalimdor/feralas.cpp rename : src/scripts/kalimdor/maraudon/boss_celebras_the_cursed.cpp => src/server/scripts/kalimdor/maraudon/boss_celebras_the_cursed.cpp rename : src/scripts/kalimdor/maraudon/boss_landslide.cpp => src/server/scripts/kalimdor/maraudon/boss_landslide.cpp rename : src/scripts/kalimdor/maraudon/boss_noxxion.cpp => src/server/scripts/kalimdor/maraudon/boss_noxxion.cpp rename : src/scripts/kalimdor/maraudon/boss_princess_theradras.cpp => src/server/scripts/kalimdor/maraudon/boss_princess_theradras.cpp rename : src/scripts/kalimdor/moonglade.cpp => src/server/scripts/kalimdor/moonglade.cpp rename : src/scripts/kalimdor/mulgore.cpp => src/server/scripts/kalimdor/mulgore.cpp rename : src/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp => src/server/scripts/kalimdor/onyxias_lair/boss_onyxia.cpp rename : src/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp => src/server/scripts/kalimdor/onyxias_lair/instance_onyxias_lair.cpp rename : src/scripts/kalimdor/onyxias_lair/onyxias_lair.h => src/server/scripts/kalimdor/onyxias_lair/onyxias_lair.h rename : src/scripts/kalimdor/orgrimmar.cpp => src/server/scripts/kalimdor/orgrimmar.cpp rename : src/scripts/kalimdor/razorfen_downs/boss_amnennar_the_coldbringer.cpp => src/server/scripts/kalimdor/razorfen_downs/boss_amnennar_the_coldbringer.cpp rename : src/scripts/kalimdor/razorfen_downs/instance_razorfen_downs.cpp => src/server/scripts/kalimdor/razorfen_downs/instance_razorfen_downs.cpp rename : src/scripts/kalimdor/razorfen_downs/razorfen_downs.cpp => src/server/scripts/kalimdor/razorfen_downs/razorfen_downs.cpp rename : src/scripts/kalimdor/razorfen_downs/razorfen_downs.h => src/server/scripts/kalimdor/razorfen_downs/razorfen_downs.h rename : src/scripts/kalimdor/razorfen_kraul/instance_razorfen_kraul.cpp => src/server/scripts/kalimdor/razorfen_kraul/instance_razorfen_kraul.cpp rename : src/scripts/kalimdor/razorfen_kraul/razorfen_kraul.cpp => src/server/scripts/kalimdor/razorfen_kraul/razorfen_kraul.cpp rename : src/scripts/kalimdor/razorfen_kraul/razorfen_kraul.h => src/server/scripts/kalimdor/razorfen_kraul/razorfen_kraul.h rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_ayamiss.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_ayamiss.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_buru.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_buru.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_kurinnaxx.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_kurinnaxx.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_moam.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_moam.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_ossirian.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_ossirian.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/boss_rajaxx.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/boss_rajaxx.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp => src/server/scripts/kalimdor/ruins_of_ahnqiraj/instance_ruins_of_ahnqiraj.cpp rename : src/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h => src/server/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h rename : src/scripts/kalimdor/silithus.cpp => src/server/scripts/kalimdor/silithus.cpp rename : src/scripts/kalimdor/stonetalon_mountains.cpp => src/server/scripts/kalimdor/stonetalon_mountains.cpp rename : src/scripts/kalimdor/tanaris.cpp => src/server/scripts/kalimdor/tanaris.cpp rename : src/scripts/kalimdor/teldrassil.cpp => src/server/scripts/kalimdor/teldrassil.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_cthun.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_cthun.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_fankriss.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_fankriss.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_huhuran.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_huhuran.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_ouro.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_ouro.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_sartura.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_sartura.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_skeram.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/boss_viscidus.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/boss_viscidus.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/instance_temple_of_ahnqiraj.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp => src/server/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp rename : src/scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.h => src/server/scripts/kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.h rename : src/scripts/kalimdor/the_barrens.cpp => src/server/scripts/kalimdor/the_barrens.cpp rename : src/scripts/kalimdor/thousand_needles.cpp => src/server/scripts/kalimdor/thousand_needles.cpp rename : src/scripts/kalimdor/thunder_bluff.cpp => src/server/scripts/kalimdor/thunder_bluff.cpp rename : src/scripts/kalimdor/ungoro_crater.cpp => src/server/scripts/kalimdor/ungoro_crater.cpp rename : src/scripts/kalimdor/wailing_caverns/instance_wailing_caverns.cpp => src/server/scripts/kalimdor/wailing_caverns/instance_wailing_caverns.cpp rename : src/scripts/kalimdor/wailing_caverns/wailing_caverns.cpp => src/server/scripts/kalimdor/wailing_caverns/wailing_caverns.cpp rename : src/scripts/kalimdor/wailing_caverns/wailing_caverns.h => src/server/scripts/kalimdor/wailing_caverns/wailing_caverns.h rename : src/scripts/kalimdor/winterspring.cpp => src/server/scripts/kalimdor/winterspring.cpp rename : src/scripts/kalimdor/zulfarrak/instance_zulfarrak.cpp => src/server/scripts/kalimdor/zulfarrak/instance_zulfarrak.cpp rename : src/scripts/kalimdor/zulfarrak/zulfarrak.cpp => src/server/scripts/kalimdor/zulfarrak/zulfarrak.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/ahnkahet.h => src/server/scripts/northrend/azjol_nerub/ahnkahet/ahnkahet.h rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_amanitar.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_amanitar.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_elder_nadox.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_elder_nadox.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_herald_volazj.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_herald_volazj.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp rename : src/scripts/northrend/azjol_nerub/ahnkahet/instance_ahnkahet.cpp => src/server/scripts/northrend/azjol_nerub/ahnkahet/instance_ahnkahet.cpp rename : src/scripts/northrend/azjol_nerub/azjol_nerub/azjol_nerub.h => src/server/scripts/northrend/azjol_nerub/azjol_nerub/azjol_nerub.h rename : src/scripts/northrend/azjol_nerub/azjol_nerub/boss_anubarak.cpp => src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_anubarak.cpp rename : src/scripts/northrend/azjol_nerub/azjol_nerub/boss_hadronox.cpp => src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_hadronox.cpp rename : src/scripts/northrend/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp => src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp rename : src/scripts/northrend/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp => src/server/scripts/northrend/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp rename : src/scripts/northrend/borean_tundra.cpp => src/server/scripts/northrend/borean_tundra.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp rename : src/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h => src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h rename : src/scripts/northrend/crystalsong_forest.cpp => src/server/scripts/northrend/crystalsong_forest.cpp rename : src/scripts/northrend/dalaran.cpp => src/server/scripts/northrend/dalaran.cpp rename : src/scripts/northrend/dragonblight.cpp => src/server/scripts/northrend/dragonblight.cpp rename : src/scripts/northrend/draktharon_keep/boss_dred.cpp => src/server/scripts/northrend/draktharon_keep/boss_dred.cpp rename : src/scripts/northrend/draktharon_keep/boss_novos.cpp => src/server/scripts/northrend/draktharon_keep/boss_novos.cpp rename : src/scripts/northrend/draktharon_keep/boss_tharon_ja.cpp => src/server/scripts/northrend/draktharon_keep/boss_tharon_ja.cpp rename : src/scripts/northrend/draktharon_keep/boss_trollgore.cpp => src/server/scripts/northrend/draktharon_keep/boss_trollgore.cpp rename : src/scripts/northrend/draktharon_keep/drak_tharon_keep.h => src/server/scripts/northrend/draktharon_keep/drak_tharon_keep.h rename : src/scripts/northrend/draktharon_keep/instance_drak_tharon_keep.cpp => src/server/scripts/northrend/draktharon_keep/instance_drak_tharon_keep.cpp rename : src/scripts/northrend/frozen_halls/forge_of_souls/boss_bronjahm.cpp => src/server/scripts/northrend/frozen_halls/forge_of_souls/boss_bronjahm.cpp rename : src/scripts/northrend/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp => src/server/scripts/northrend/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp rename : src/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.cpp => src/server/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.cpp rename : src/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.h => src/server/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.h rename : src/scripts/northrend/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp => src/server/scripts/northrend/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp rename : src/scripts/northrend/frozen_halls/halls_of_reflection/boss_falric.cpp => src/server/scripts/northrend/frozen_halls/halls_of_reflection/boss_falric.cpp rename : src/scripts/northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp => src/server/scripts/northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp rename : src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp => src/server/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp rename : src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h => src/server/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h rename : src/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp => src/server/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp => src/server/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp rename : src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h => src/server/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h rename : src/scripts/northrend/grizzly_hills.cpp => src/server/scripts/northrend/grizzly_hills.cpp rename : src/scripts/northrend/gundrak/boss_drakkari_colossus.cpp => src/server/scripts/northrend/gundrak/boss_drakkari_colossus.cpp rename : src/scripts/northrend/gundrak/boss_eck.cpp => src/server/scripts/northrend/gundrak/boss_eck.cpp rename : src/scripts/northrend/gundrak/boss_gal_darah.cpp => src/server/scripts/northrend/gundrak/boss_gal_darah.cpp rename : src/scripts/northrend/gundrak/boss_moorabi.cpp => src/server/scripts/northrend/gundrak/boss_moorabi.cpp rename : src/scripts/northrend/gundrak/boss_slad_ran.cpp => src/server/scripts/northrend/gundrak/boss_slad_ran.cpp rename : src/scripts/northrend/gundrak/gundrak.h => src/server/scripts/northrend/gundrak/gundrak.h rename : src/scripts/northrend/gundrak/instance_gundrak.cpp => src/server/scripts/northrend/gundrak/instance_gundrak.cpp rename : src/scripts/northrend/howling_fjord.cpp => src/server/scripts/northrend/howling_fjord.cpp rename : src/scripts/northrend/icecrown.cpp => src/server/scripts/northrend/icecrown.cpp rename : src/scripts/northrend/naxxramas/boss_anubrekhan.cpp => src/server/scripts/northrend/naxxramas/boss_anubrekhan.cpp rename : src/scripts/northrend/naxxramas/boss_faerlina.cpp => src/server/scripts/northrend/naxxramas/boss_faerlina.cpp rename : src/scripts/northrend/naxxramas/boss_four_horsemen.cpp => src/server/scripts/northrend/naxxramas/boss_four_horsemen.cpp rename : src/scripts/northrend/naxxramas/boss_gluth.cpp => src/server/scripts/northrend/naxxramas/boss_gluth.cpp rename : src/scripts/northrend/naxxramas/boss_gothik.cpp => src/server/scripts/northrend/naxxramas/boss_gothik.cpp rename : src/scripts/northrend/naxxramas/boss_grobbulus.cpp => src/server/scripts/northrend/naxxramas/boss_grobbulus.cpp rename : src/scripts/northrend/naxxramas/boss_heigan.cpp => src/server/scripts/northrend/naxxramas/boss_heigan.cpp rename : src/scripts/northrend/naxxramas/boss_highlord_mograine.cpp => src/server/scripts/northrend/naxxramas/boss_highlord_mograine.cpp rename : src/scripts/northrend/naxxramas/boss_kelthuzad.cpp => src/server/scripts/northrend/naxxramas/boss_kelthuzad.cpp rename : src/scripts/northrend/naxxramas/boss_loatheb.cpp => src/server/scripts/northrend/naxxramas/boss_loatheb.cpp rename : src/scripts/northrend/naxxramas/boss_maexxna.cpp => src/server/scripts/northrend/naxxramas/boss_maexxna.cpp rename : src/scripts/northrend/naxxramas/boss_noth.cpp => src/server/scripts/northrend/naxxramas/boss_noth.cpp rename : src/scripts/northrend/naxxramas/boss_patchwerk.cpp => src/server/scripts/northrend/naxxramas/boss_patchwerk.cpp rename : src/scripts/northrend/naxxramas/boss_razuvious.cpp => src/server/scripts/northrend/naxxramas/boss_razuvious.cpp rename : src/scripts/northrend/naxxramas/boss_sapphiron.cpp => src/server/scripts/northrend/naxxramas/boss_sapphiron.cpp rename : src/scripts/northrend/naxxramas/boss_thaddius.cpp => src/server/scripts/northrend/naxxramas/boss_thaddius.cpp rename : src/scripts/northrend/naxxramas/instance_naxxramas.cpp => src/server/scripts/northrend/naxxramas/instance_naxxramas.cpp rename : src/scripts/northrend/naxxramas/naxxramas.h => src/server/scripts/northrend/naxxramas/naxxramas.h rename : src/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp => src/server/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp rename : src/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h => src/server/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h rename : src/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp => src/server/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp rename : src/scripts/northrend/nexus/nexus/boss_anomalus.cpp => src/server/scripts/northrend/nexus/nexus/boss_anomalus.cpp rename : src/scripts/northrend/nexus/nexus/boss_keristrasza.cpp => src/server/scripts/northrend/nexus/nexus/boss_keristrasza.cpp rename : src/scripts/northrend/nexus/nexus/boss_magus_telestra.cpp => src/server/scripts/northrend/nexus/nexus/boss_magus_telestra.cpp rename : src/scripts/northrend/nexus/nexus/boss_ormorok.cpp => src/server/scripts/northrend/nexus/nexus/boss_ormorok.cpp rename : src/scripts/northrend/nexus/nexus/commander_kolurg.cpp => src/server/scripts/northrend/nexus/nexus/commander_kolurg.cpp rename : src/scripts/northrend/nexus/nexus/commander_stoutbeard.cpp => src/server/scripts/northrend/nexus/nexus/commander_stoutbeard.cpp rename : src/scripts/northrend/nexus/nexus/instance_nexus.cpp => src/server/scripts/northrend/nexus/nexus/instance_nexus.cpp rename : src/scripts/northrend/nexus/nexus/nexus.h => src/server/scripts/northrend/nexus/nexus/nexus.h rename : src/scripts/northrend/nexus/oculus/boss_drakos.cpp => src/server/scripts/northrend/nexus/oculus/boss_drakos.cpp rename : src/scripts/northrend/nexus/oculus/boss_eregos.cpp => src/server/scripts/northrend/nexus/oculus/boss_eregos.cpp rename : src/scripts/northrend/nexus/oculus/boss_urom.cpp => src/server/scripts/northrend/nexus/oculus/boss_urom.cpp rename : src/scripts/northrend/nexus/oculus/boss_varos.cpp => src/server/scripts/northrend/nexus/oculus/boss_varos.cpp rename : src/scripts/northrend/nexus/oculus/instance_oculus.cpp => src/server/scripts/northrend/nexus/oculus/instance_oculus.cpp rename : src/scripts/northrend/nexus/oculus/oculus.cpp => src/server/scripts/northrend/nexus/oculus/oculus.cpp rename : src/scripts/northrend/nexus/oculus/oculus.h => src/server/scripts/northrend/nexus/oculus/oculus.h rename : src/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp => src/server/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp rename : src/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp => src/server/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp rename : src/scripts/northrend/obsidian_sanctum/obsidian_sanctum.h => src/server/scripts/northrend/obsidian_sanctum/obsidian_sanctum.h rename : src/scripts/northrend/sholazar_basin.cpp => src/server/scripts/northrend/sholazar_basin.cpp rename : src/scripts/northrend/storm_peaks.cpp => src/server/scripts/northrend/storm_peaks.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp rename : src/scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h => src/server/scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h rename : src/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp => src/server/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp rename : src/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h => src/server/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h rename : src/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp => src/server/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_algalon.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_algalon.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_assembly_of_iron.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_assembly_of_iron.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_freya.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_freya.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_hodir.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_hodir.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_ignis.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_ignis.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_thorim.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_thorim.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_xt002.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_xt002.cpp rename : src/scripts/northrend/ulduar/ulduar/boss_yoggsaron.cpp => src/server/scripts/northrend/ulduar/ulduar/boss_yoggsaron.cpp rename : src/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp => src/server/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp rename : src/scripts/northrend/ulduar/ulduar/ulduar.h => src/server/scripts/northrend/ulduar/ulduar/ulduar.h rename : src/scripts/northrend/ulduar/ulduar/ulduar_teleporter.cpp => src/server/scripts/northrend/ulduar/ulduar/ulduar_teleporter.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h => src/server/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp rename : src/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h => src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h rename : src/scripts/northrend/vault_of_archavon/boss_archavon.cpp => src/server/scripts/northrend/vault_of_archavon/boss_archavon.cpp rename : src/scripts/northrend/vault_of_archavon/boss_emalon.cpp => src/server/scripts/northrend/vault_of_archavon/boss_emalon.cpp rename : src/scripts/northrend/vault_of_archavon/boss_koralon.cpp => src/server/scripts/northrend/vault_of_archavon/boss_koralon.cpp rename : src/scripts/northrend/vault_of_archavon/boss_toravon.cpp => src/server/scripts/northrend/vault_of_archavon/boss_toravon.cpp rename : src/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp => src/server/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp rename : src/scripts/northrend/vault_of_archavon/vault_of_archavon.h => src/server/scripts/northrend/vault_of_archavon/vault_of_archavon.h rename : src/scripts/northrend/violet_hold/boss_cyanigosa.cpp => src/server/scripts/northrend/violet_hold/boss_cyanigosa.cpp rename : src/scripts/northrend/violet_hold/boss_erekem.cpp => src/server/scripts/northrend/violet_hold/boss_erekem.cpp rename : src/scripts/northrend/violet_hold/boss_ichoron.cpp => src/server/scripts/northrend/violet_hold/boss_ichoron.cpp rename : src/scripts/northrend/violet_hold/boss_lavanthor.cpp => src/server/scripts/northrend/violet_hold/boss_lavanthor.cpp rename : src/scripts/northrend/violet_hold/boss_moragg.cpp => src/server/scripts/northrend/violet_hold/boss_moragg.cpp rename : src/scripts/northrend/violet_hold/boss_xevozz.cpp => src/server/scripts/northrend/violet_hold/boss_xevozz.cpp rename : src/scripts/northrend/violet_hold/boss_zuramat.cpp => src/server/scripts/northrend/violet_hold/boss_zuramat.cpp rename : src/scripts/northrend/violet_hold/instance_violet_hold.cpp => src/server/scripts/northrend/violet_hold/instance_violet_hold.cpp rename : src/scripts/northrend/violet_hold/violet_hold.cpp => src/server/scripts/northrend/violet_hold/violet_hold.cpp rename : src/scripts/northrend/violet_hold/violet_hold.h => src/server/scripts/northrend/violet_hold/violet_hold.h rename : src/scripts/northrend/zuldrak.cpp => src/server/scripts/northrend/zuldrak.cpp rename : src/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp => src/server/scripts/outland/auchindoun/auchenai_crypts/boss_exarch_maladaar.cpp rename : src/scripts/outland/auchindoun/auchenai_crypts/boss_shirrak_the_dead_watcher.cpp => src/server/scripts/outland/auchindoun/auchenai_crypts/boss_shirrak_the_dead_watcher.cpp rename : src/scripts/outland/auchindoun/mana_tombs/boss_nexusprince_shaffar.cpp => src/server/scripts/outland/auchindoun/mana_tombs/boss_nexusprince_shaffar.cpp rename : src/scripts/outland/auchindoun/mana_tombs/boss_pandemonius.cpp => src/server/scripts/outland/auchindoun/mana_tombs/boss_pandemonius.cpp rename : src/scripts/outland/auchindoun/sethekk_halls/boss_darkweaver_syth.cpp => src/server/scripts/outland/auchindoun/sethekk_halls/boss_darkweaver_syth.cpp rename : src/scripts/outland/auchindoun/sethekk_halls/boss_tailonking_ikiss.cpp => src/server/scripts/outland/auchindoun/sethekk_halls/boss_tailonking_ikiss.cpp rename : src/scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp => src/server/scripts/outland/auchindoun/sethekk_halls/instance_sethekk_halls.cpp rename : src/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h => src/server/scripts/outland/auchindoun/sethekk_halls/sethekk_halls.h rename : src/scripts/outland/auchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/boss_ambassador_hellmaw.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp => src/server/scripts/outland/auchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp rename : src/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h => src/server/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h rename : src/scripts/outland/black_temple/black_temple.cpp => src/server/scripts/outland/black_temple/black_temple.cpp rename : src/scripts/outland/black_temple/black_temple.h => src/server/scripts/outland/black_temple/black_temple.h rename : src/scripts/outland/black_temple/boss_bloodboil.cpp => src/server/scripts/outland/black_temple/boss_bloodboil.cpp rename : src/scripts/outland/black_temple/boss_illidan.cpp => src/server/scripts/outland/black_temple/boss_illidan.cpp rename : src/scripts/outland/black_temple/boss_mother_shahraz.cpp => src/server/scripts/outland/black_temple/boss_mother_shahraz.cpp rename : src/scripts/outland/black_temple/boss_reliquary_of_souls.cpp => src/server/scripts/outland/black_temple/boss_reliquary_of_souls.cpp rename : src/scripts/outland/black_temple/boss_shade_of_akama.cpp => src/server/scripts/outland/black_temple/boss_shade_of_akama.cpp rename : src/scripts/outland/black_temple/boss_supremus.cpp => src/server/scripts/outland/black_temple/boss_supremus.cpp rename : src/scripts/outland/black_temple/boss_teron_gorefiend.cpp => src/server/scripts/outland/black_temple/boss_teron_gorefiend.cpp rename : src/scripts/outland/black_temple/boss_warlord_najentus.cpp => src/server/scripts/outland/black_temple/boss_warlord_najentus.cpp rename : src/scripts/outland/black_temple/illidari_council.cpp => src/server/scripts/outland/black_temple/illidari_council.cpp rename : src/scripts/outland/black_temple/instance_black_temple.cpp => src/server/scripts/outland/black_temple/instance_black_temple.cpp rename : src/scripts/outland/blades_edge_mountains.cpp => src/server/scripts/outland/blades_edge_mountains.cpp rename : src/scripts/outland/boss_doomlord_kazzak.cpp => src/server/scripts/outland/boss_doomlord_kazzak.cpp rename : src/scripts/outland/boss_doomwalker.cpp => src/server/scripts/outland/boss_doomwalker.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_fathomlord_karathress.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lurker_below.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/boss_morogrim_tidewalker.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp rename : src/scripts/outland/coilfang_resevoir/serpent_shrine/serpent_shrine.h => src/server/scripts/outland/coilfang_resevoir/serpent_shrine/serpent_shrine.h rename : src/scripts/outland/coilfang_resevoir/steam_vault/boss_hydromancer_thespia.cpp => src/server/scripts/outland/coilfang_resevoir/steam_vault/boss_hydromancer_thespia.cpp rename : src/scripts/outland/coilfang_resevoir/steam_vault/boss_mekgineer_steamrigger.cpp => src/server/scripts/outland/coilfang_resevoir/steam_vault/boss_mekgineer_steamrigger.cpp rename : src/scripts/outland/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp => src/server/scripts/outland/coilfang_resevoir/steam_vault/boss_warlord_kalithresh.cpp rename : src/scripts/outland/coilfang_resevoir/steam_vault/instance_steam_vault.cpp => src/server/scripts/outland/coilfang_resevoir/steam_vault/instance_steam_vault.cpp rename : src/scripts/outland/coilfang_resevoir/steam_vault/steam_vault.h => src/server/scripts/outland/coilfang_resevoir/steam_vault/steam_vault.h rename : src/scripts/outland/coilfang_resevoir/underbog/boss_hungarfen.cpp => src/server/scripts/outland/coilfang_resevoir/underbog/boss_hungarfen.cpp rename : src/scripts/outland/coilfang_resevoir/underbog/boss_the_black_stalker.cpp => src/server/scripts/outland/coilfang_resevoir/underbog/boss_the_black_stalker.cpp rename : src/scripts/outland/gruuls_lair/boss_gruul.cpp => src/server/scripts/outland/gruuls_lair/boss_gruul.cpp rename : src/scripts/outland/gruuls_lair/boss_high_king_maulgar.cpp => src/server/scripts/outland/gruuls_lair/boss_high_king_maulgar.cpp rename : src/scripts/outland/gruuls_lair/gruuls_lair.h => src/server/scripts/outland/gruuls_lair/gruuls_lair.h rename : src/scripts/outland/gruuls_lair/instance_gruuls_lair.cpp => src/server/scripts/outland/gruuls_lair/instance_gruuls_lair.cpp rename : src/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h => src/server/scripts/outland/hellfire_citadel/blood_furnace/blood_furnace.h rename : src/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp => src/server/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp rename : src/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp => src/server/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp rename : src/scripts/outland/hellfire_citadel/blood_furnace/boss_the_maker.cpp => src/server/scripts/outland/hellfire_citadel/blood_furnace/boss_the_maker.cpp rename : src/scripts/outland/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp => src/server/scripts/outland/hellfire_citadel/blood_furnace/instance_blood_furnace.cpp rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_omor_the_unscarred.cpp rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_vazruden_the_herald.cpp => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_vazruden_the_herald.cpp rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/boss_watchkeeper_gargolmar.cpp rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/hellfire_ramparts.h => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/hellfire_ramparts.h rename : src/scripts/outland/hellfire_citadel/hellfire_ramparts/instance_hellfire_ramparts.cpp => src/server/scripts/outland/hellfire_citadel/hellfire_ramparts/instance_hellfire_ramparts.cpp rename : src/scripts/outland/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp => src/server/scripts/outland/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp rename : src/scripts/outland/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp => src/server/scripts/outland/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp rename : src/scripts/outland/hellfire_citadel/magtheridons_lair/magtheridons_lair.h => src/server/scripts/outland/hellfire_citadel/magtheridons_lair/magtheridons_lair.h rename : src/scripts/outland/hellfire_citadel/shattered_halls/boss_nethekurse.cpp => src/server/scripts/outland/hellfire_citadel/shattered_halls/boss_nethekurse.cpp rename : src/scripts/outland/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp => src/server/scripts/outland/hellfire_citadel/shattered_halls/boss_warbringer_omrogg.cpp rename : src/scripts/outland/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp => src/server/scripts/outland/hellfire_citadel/shattered_halls/boss_warchief_kargath_bladefist.cpp rename : src/scripts/outland/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp => src/server/scripts/outland/hellfire_citadel/shattered_halls/instance_shattered_halls.cpp rename : src/scripts/outland/hellfire_citadel/shattered_halls/shattered_halls.h => src/server/scripts/outland/hellfire_citadel/shattered_halls/shattered_halls.h rename : src/scripts/outland/hellfire_peninsula.cpp => src/server/scripts/outland/hellfire_peninsula.cpp rename : src/scripts/outland/nagrand.cpp => src/server/scripts/outland/nagrand.cpp rename : src/scripts/outland/netherstorm.cpp => src/server/scripts/outland/netherstorm.cpp rename : src/scripts/outland/shadowmoon_valley.cpp => src/server/scripts/outland/shadowmoon_valley.cpp rename : src/scripts/outland/shattrath_city.cpp => src/server/scripts/outland/shattrath_city.cpp rename : src/scripts/outland/tempest_keep/arcatraz/arcatraz.cpp => src/server/scripts/outland/tempest_keep/arcatraz/arcatraz.cpp rename : src/scripts/outland/tempest_keep/arcatraz/arcatraz.h => src/server/scripts/outland/tempest_keep/arcatraz/arcatraz.h rename : src/scripts/outland/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp => src/server/scripts/outland/tempest_keep/arcatraz/boss_harbinger_skyriss.cpp rename : src/scripts/outland/tempest_keep/arcatraz/instance_arcatraz.cpp => src/server/scripts/outland/tempest_keep/arcatraz/instance_arcatraz.cpp rename : src/scripts/outland/tempest_keep/botanica/boss_high_botanist_freywinn.cpp => src/server/scripts/outland/tempest_keep/botanica/boss_high_botanist_freywinn.cpp rename : src/scripts/outland/tempest_keep/botanica/boss_laj.cpp => src/server/scripts/outland/tempest_keep/botanica/boss_laj.cpp rename : src/scripts/outland/tempest_keep/botanica/boss_warp_splinter.cpp => src/server/scripts/outland/tempest_keep/botanica/boss_warp_splinter.cpp rename : src/scripts/outland/tempest_keep/the_eye/boss_alar.cpp => src/server/scripts/outland/tempest_keep/the_eye/boss_alar.cpp rename : src/scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp => src/server/scripts/outland/tempest_keep/the_eye/boss_astromancer.cpp rename : src/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp => src/server/scripts/outland/tempest_keep/the_eye/boss_kaelthas.cpp rename : src/scripts/outland/tempest_keep/the_eye/boss_void_reaver.cpp => src/server/scripts/outland/tempest_keep/the_eye/boss_void_reaver.cpp rename : src/scripts/outland/tempest_keep/the_eye/instance_the_eye.cpp => src/server/scripts/outland/tempest_keep/the_eye/instance_the_eye.cpp rename : src/scripts/outland/tempest_keep/the_eye/the_eye.cpp => src/server/scripts/outland/tempest_keep/the_eye/the_eye.cpp rename : src/scripts/outland/tempest_keep/the_eye/the_eye.h => src/server/scripts/outland/tempest_keep/the_eye/the_eye.h rename : src/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_gyrokill.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/boss_gatewatcher_ironhand.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/boss_nethermancer_sepethrea.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/boss_pathaleon_the_calculator.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/instance_mechanar.cpp => src/server/scripts/outland/tempest_keep/the_mechanar/instance_mechanar.cpp rename : src/scripts/outland/tempest_keep/the_mechanar/mechanar.h => src/server/scripts/outland/tempest_keep/the_mechanar/mechanar.h rename : src/scripts/outland/terokkar_forest.cpp => src/server/scripts/outland/terokkar_forest.cpp rename : src/scripts/outland/zangarmarsh.cpp => src/server/scripts/outland/zangarmarsh.cpp rename : src/scripts/world/areatrigger_scripts.cpp => src/server/scripts/world/areatrigger_scripts.cpp rename : src/scripts/world/boss_emeriss.cpp => src/server/scripts/world/boss_emeriss.cpp rename : src/scripts/world/boss_lethon.cpp => src/server/scripts/world/boss_lethon.cpp rename : src/scripts/world/boss_taerar.cpp => src/server/scripts/world/boss_taerar.cpp rename : src/scripts/world/boss_ysondre.cpp => src/server/scripts/world/boss_ysondre.cpp rename : src/scripts/world/go_scripts.cpp => src/server/scripts/world/go_scripts.cpp rename : src/scripts/world/guards.cpp => src/server/scripts/world/guards.cpp rename : src/scripts/world/item_scripts.cpp => src/server/scripts/world/item_scripts.cpp rename : src/scripts/world/mob_generic_creature.cpp => src/server/scripts/world/mob_generic_creature.cpp rename : src/scripts/world/npc_innkeeper.cpp => src/server/scripts/world/npc_innkeeper.cpp rename : src/scripts/world/npc_professions.cpp => src/server/scripts/world/npc_professions.cpp rename : src/scripts/world/npc_taxi.cpp => src/server/scripts/world/npc_taxi.cpp rename : src/scripts/world/npcs_special.cpp => src/server/scripts/world/npcs_special.cpp rename : src/shared/Auth/AuthCrypt.cpp => src/server/shared/Auth/AuthCrypt.cpp rename : src/shared/Auth/AuthCrypt.h => src/server/shared/Auth/AuthCrypt.h rename : src/shared/Auth/BigNumber.cpp => src/server/shared/Auth/BigNumber.cpp rename : src/shared/Auth/BigNumber.h => src/server/shared/Auth/BigNumber.h rename : src/shared/Auth/CMakeLists.txt => src/server/shared/Auth/CMakeLists.txt rename : src/shared/Auth/Hmac.cpp => src/server/shared/Auth/Hmac.cpp rename : src/shared/Auth/Hmac.h => src/server/shared/Auth/Hmac.h rename : src/shared/Auth/SARC4.cpp => src/server/shared/Auth/SARC4.cpp rename : src/shared/Auth/SARC4.h => src/server/shared/Auth/SARC4.h rename : src/shared/Auth/Sha1.cpp => src/server/shared/Auth/Sha1.cpp rename : src/shared/Auth/Sha1.h => src/server/shared/Auth/Sha1.h rename : src/shared/Auth/md5.c => src/server/shared/Auth/md5.c rename : src/shared/Auth/md5.h => src/server/shared/Auth/md5.h rename : src/shared/ByteBuffer.h => src/server/shared/ByteBuffer.h rename : src/shared/CMakeLists.txt => src/server/shared/CMakeLists.txt rename : src/shared/Common.cpp => src/server/shared/Common.cpp rename : src/shared/Common.h => src/server/shared/Common.h rename : src/shared/Config/CMakeLists.txt => src/server/shared/Config/CMakeLists.txt rename : src/shared/Config/Config.cpp => src/server/shared/Config/Config.cpp rename : src/shared/Config/Config.h => src/server/shared/Config/Config.h rename : src/shared/Config/ConfigEnv.h => src/server/shared/Config/ConfigEnv.h rename : src/shared/Config/ConfigLibrary.vcproj => src/server/shared/Config/ConfigLibrary.vcproj rename : src/shared/Config/dotconfpp/dotconfpp.cpp => src/server/shared/Config/dotconfpp/dotconfpp.cpp rename : src/shared/Config/dotconfpp/dotconfpp.h => src/server/shared/Config/dotconfpp/dotconfpp.h rename : src/shared/Config/dotconfpp/mempool.cpp => src/server/shared/Config/dotconfpp/mempool.cpp rename : src/shared/Config/dotconfpp/mempool.h => src/server/shared/Config/dotconfpp/mempool.h rename : src/shared/Database/CMakeLists.txt => src/server/shared/Database/CMakeLists.txt rename : src/shared/Database/DBCFileLoader.cpp => src/server/shared/Database/DBCFileLoader.cpp rename : src/shared/Database/DBCFileLoader.h => src/server/shared/Database/DBCFileLoader.h rename : src/shared/Database/DBCStore.h => src/server/shared/Database/DBCStore.h rename : src/shared/Database/Database.cpp => src/server/shared/Database/Database.cpp rename : src/shared/Database/Database.h => src/server/shared/Database/Database.h rename : src/shared/Database/DatabaseEnv.h => src/server/shared/Database/DatabaseEnv.h rename : src/shared/Database/DatabaseImpl.h => src/server/shared/Database/DatabaseImpl.h rename : src/shared/Database/Field.cpp => src/server/shared/Database/Field.cpp rename : src/shared/Database/Field.h => src/server/shared/Database/Field.h rename : src/shared/Database/QueryResult.cpp => src/server/shared/Database/QueryResult.cpp rename : src/shared/Database/QueryResult.h => src/server/shared/Database/QueryResult.h rename : src/shared/Database/SQLStorage.cpp => src/server/shared/Database/SQLStorage.cpp rename : src/shared/Database/SQLStorage.h => src/server/shared/Database/SQLStorage.h rename : src/shared/Database/SQLStorageImpl.h => src/server/shared/Database/SQLStorageImpl.h rename : src/shared/Database/SqlDelayThread.cpp => src/server/shared/Database/SqlDelayThread.cpp rename : src/shared/Database/SqlDelayThread.h => src/server/shared/Database/SqlDelayThread.h rename : src/shared/Database/SqlOperations.cpp => src/server/shared/Database/SqlOperations.cpp rename : src/shared/Database/SqlOperations.h => src/server/shared/Database/SqlOperations.h rename : src/shared/DelayExecutor.cpp => src/server/shared/DelayExecutor.cpp rename : src/shared/DelayExecutor.h => src/server/shared/DelayExecutor.h rename : src/shared/Errors.h => src/server/shared/Errors.h rename : src/shared/LockedQueue.h => src/server/shared/LockedQueue.h rename : src/shared/Log.cpp => src/server/shared/Log.cpp rename : src/shared/Log.h => src/server/shared/Log.h rename : src/shared/MemoryLeaks.cpp => src/server/shared/MemoryLeaks.cpp rename : src/shared/MemoryLeaks.h => src/server/shared/MemoryLeaks.h rename : src/shared/PacketLog.cpp => src/server/shared/PacketLog.cpp rename : src/shared/PacketLog.h => src/server/shared/PacketLog.h rename : src/shared/ProgressBar.cpp => src/server/shared/ProgressBar.cpp rename : src/shared/ProgressBar.h => src/server/shared/ProgressBar.h rename : src/shared/ServiceWin32.cpp => src/server/shared/ServiceWin32.cpp rename : src/shared/ServiceWin32.h => src/server/shared/ServiceWin32.h rename : src/shared/SignalHandler.h => src/server/shared/SignalHandler.h rename : src/shared/SystemConfig.h => src/server/shared/SystemConfig.h rename : src/shared/Threading.cpp => src/server/shared/Threading.cpp rename : src/shared/Threading.h => src/server/shared/Threading.h rename : src/shared/Timer.h => src/server/shared/Timer.h rename : src/shared/Util.cpp => src/server/shared/Util.cpp rename : src/shared/Util.h => src/server/shared/Util.h rename : src/shared/WheatyExceptionReport.cpp => src/server/shared/WheatyExceptionReport.cpp rename : src/shared/WheatyExceptionReport.h => src/server/shared/WheatyExceptionReport.h rename : src/shared/WorldPacket.h => src/server/shared/WorldPacket.h rename : src/shared/vmap/BIH.cpp => src/server/shared/vmap/BIH.cpp rename : src/shared/vmap/BIH.h => src/server/shared/vmap/BIH.h rename : src/shared/vmap/CMakeLists.txt => src/server/shared/vmap/CMakeLists.txt rename : src/shared/vmap/IVMapManager.h => src/server/shared/vmap/IVMapManager.h rename : src/shared/vmap/MapTree.cpp => src/server/shared/vmap/MapTree.cpp rename : src/shared/vmap/MapTree.h => src/server/shared/vmap/MapTree.h rename : src/shared/vmap/ModelInstance.cpp => src/server/shared/vmap/ModelInstance.cpp rename : src/shared/vmap/ModelInstance.h => src/server/shared/vmap/ModelInstance.h rename : src/shared/vmap/TileAssembler.cpp => src/server/shared/vmap/TileAssembler.cpp rename : src/shared/vmap/TileAssembler.h => src/server/shared/vmap/TileAssembler.h rename : src/shared/vmap/VMapDefinitions.h => src/server/shared/vmap/VMapDefinitions.h rename : src/shared/vmap/VMapFactory.cpp => src/server/shared/vmap/VMapFactory.cpp rename : src/shared/vmap/VMapFactory.h => src/server/shared/vmap/VMapFactory.h rename : src/shared/vmap/VMapManager2.cpp => src/server/shared/vmap/VMapManager2.cpp rename : src/shared/vmap/VMapManager2.h => src/server/shared/vmap/VMapManager2.h rename : src/shared/vmap/VMapTools.h => src/server/shared/vmap/VMapTools.h rename : src/shared/vmap/WorldModel.cpp => src/server/shared/vmap/WorldModel.cpp rename : src/shared/vmap/WorldModel.h => src/server/shared/vmap/WorldModel.h rename : src/trinitycore/CMakeLists.txt => src/server/trinitycore/CMakeLists.txt rename : src/trinitycore/CliRunnable.cpp => src/server/trinitycore/CliRunnable.cpp rename : src/trinitycore/CliRunnable.h => src/server/trinitycore/CliRunnable.h rename : src/trinitycore/Main.cpp => src/server/trinitycore/Main.cpp rename : src/trinitycore/Master.cpp => src/server/trinitycore/Master.cpp rename : src/trinitycore/Master.h => src/server/trinitycore/Master.h rename : src/trinitycore/RASocket.cpp => src/server/trinitycore/RASocket.cpp rename : src/trinitycore/RASocket.h => src/server/trinitycore/RASocket.h rename : src/trinitycore/TrinityCore.ico => src/server/trinitycore/TrinityCore.ico rename : src/trinitycore/TrinityCore.rc => src/server/trinitycore/TrinityCore.rc rename : src/trinitycore/WorldRunnable.cpp => src/server/trinitycore/WorldRunnable.cpp rename : src/trinitycore/WorldRunnable.h => src/server/trinitycore/WorldRunnable.h rename : src/trinitycore/resource.h => src/server/trinitycore/resource.h rename : src/trinitycore/trinitycore.conf.dist => src/server/trinitycore/trinitycore.conf.dist rename : src/trinityrealm/AuthCodes.cpp => src/server/trinityrealm/AuthCodes.cpp rename : src/trinityrealm/AuthCodes.h => src/server/trinityrealm/AuthCodes.h rename : src/trinityrealm/AuthSocket.cpp => src/server/trinityrealm/AuthSocket.cpp rename : src/trinityrealm/AuthSocket.h => src/server/trinityrealm/AuthSocket.h rename : src/trinityrealm/CMakeLists.txt => src/server/trinityrealm/CMakeLists.txt rename : src/trinityrealm/Main.cpp => src/server/trinityrealm/Main.cpp rename : src/trinityrealm/RealmAcceptor.h => src/server/trinityrealm/RealmAcceptor.h rename : src/trinityrealm/RealmList.cpp => src/server/trinityrealm/RealmList.cpp rename : src/trinityrealm/RealmList.h => src/server/trinityrealm/RealmList.h rename : src/trinityrealm/RealmSocket.cpp => src/server/trinityrealm/RealmSocket.cpp rename : src/trinityrealm/RealmSocket.h => src/server/trinityrealm/RealmSocket.h rename : src/trinityrealm/TrinityRealm.ico => src/server/trinityrealm/TrinityRealm.ico rename : src/trinityrealm/TrinityRealm.rc => src/server/trinityrealm/TrinityRealm.rc rename : src/trinityrealm/resource.h => src/server/trinityrealm/resource.h rename : src/trinityrealm/trinityrealm.conf.dist => src/server/trinityrealm/trinityrealm.conf.dist
Diffstat (limited to 'src/server/scripts/northrend')
-rw-r--r--src/server/scripts/northrend/azjol_nerub/ahnkahet/ahnkahet.h52
-rw-r--r--src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_amanitar.cpp226
-rw-r--r--src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_elder_nadox.cpp283
-rw-r--r--src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_herald_volazj.cpp328
-rw-r--r--src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp588
-rw-r--r--src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp412
-rw-r--r--src/server/scripts/northrend/azjol_nerub/ahnkahet/instance_ahnkahet.cpp313
-rw-r--r--src/server/scripts/northrend/azjol_nerub/azjol_nerub/azjol_nerub.h38
-rw-r--r--src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_anubarak.cpp360
-rw-r--r--src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_hadronox.cpp206
-rw-r--r--src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp553
-rw-r--r--src/server/scripts/northrend/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp215
-rw-r--r--src/server/scripts/northrend/borean_tundra.cpp2323
-rw-r--r--src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp512
-rw-r--r--src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp373
-rw-r--r--src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp993
-rw-r--r--src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp340
-rw-r--r--src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp512
-rw-r--r--src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h115
-rw-r--r--src/server/scripts/northrend/crystalsong_forest.cpp110
-rw-r--r--src/server/scripts/northrend/dalaran.cpp159
-rw-r--r--src/server/scripts/northrend/dragonblight.cpp272
-rw-r--r--src/server/scripts/northrend/draktharon_keep/boss_dred.cpp270
-rw-r--r--src/server/scripts/northrend/draktharon_keep/boss_novos.cpp328
-rw-r--r--src/server/scripts/northrend/draktharon_keep/boss_tharon_ja.cpp260
-rw-r--r--src/server/scripts/northrend/draktharon_keep/boss_trollgore.cpp197
-rw-r--r--src/server/scripts/northrend/draktharon_keep/drak_tharon_keep.h40
-rw-r--r--src/server/scripts/northrend/draktharon_keep/instance_drak_tharon_keep.cpp243
-rw-r--r--src/server/scripts/northrend/frozen_halls/forge_of_souls/boss_bronjahm.cpp263
-rw-r--r--src/server/scripts/northrend/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp349
-rw-r--r--src/server/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.cpp899
-rw-r--r--src/server/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.h52
-rw-r--r--src/server/scripts/northrend/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp168
-rw-r--r--src/server/scripts/northrend/frozen_halls/halls_of_reflection/boss_falric.cpp142
-rw-r--r--src/server/scripts/northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp133
-rw-r--r--src/server/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp1022
-rw-r--r--src/server/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h156
-rw-r--r--src/server/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp431
-rw-r--r--src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp209
-rw-r--r--src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp482
-rw-r--r--src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp273
-rw-r--r--src/server/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp236
-rw-r--r--src/server/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp1101
-rw-r--r--src/server/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h63
-rw-r--r--src/server/scripts/northrend/grizzly_hills.cpp625
-rw-r--r--src/server/scripts/northrend/gundrak/boss_drakkari_colossus.cpp317
-rw-r--r--src/server/scripts/northrend/gundrak/boss_eck.cpp168
-rw-r--r--src/server/scripts/northrend/gundrak/boss_gal_darah.cpp288
-rw-r--r--src/server/scripts/northrend/gundrak/boss_moorabi.cpp175
-rw-r--r--src/server/scripts/northrend/gundrak/boss_slad_ran.cpp266
-rw-r--r--src/server/scripts/northrend/gundrak/gundrak.h54
-rw-r--r--src/server/scripts/northrend/gundrak/instance_gundrak.cpp536
-rw-r--r--src/server/scripts/northrend/howling_fjord.cpp338
-rw-r--r--src/server/scripts/northrend/icecrown.cpp422
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_anubrekhan.cpp185
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_faerlina.cpp218
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_four_horsemen.cpp397
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_gluth.cpp147
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_gothik.cpp582
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_grobbulus.cpp142
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_heigan.cpp149
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_highlord_mograine.cpp179
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_kelthuzad.cpp706
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_loatheb.cpp125
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_maexxna.cpp186
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_noth.cpp212
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_patchwerk.cpp159
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_razuvious.cpp139
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_sapphiron.cpp403
-rw-r--r--src/server/scripts/northrend/naxxramas/boss_thaddius.cpp400
-rw-r--r--src/server/scripts/northrend/naxxramas/instance_naxxramas.cpp324
-rw-r--r--src/server/scripts/northrend/naxxramas/naxxramas.h75
-rw-r--r--src/server/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp175
-rw-r--r--src/server/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h4
-rw-r--r--src/server/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp21
-rw-r--r--src/server/scripts/northrend/nexus/nexus/boss_anomalus.cpp253
-rw-r--r--src/server/scripts/northrend/nexus/nexus/boss_keristrasza.cpp247
-rw-r--r--src/server/scripts/northrend/nexus/nexus/boss_magus_telestra.cpp327
-rw-r--r--src/server/scripts/northrend/nexus/nexus/boss_ormorok.cpp298
-rw-r--r--src/server/scripts/northrend/nexus/nexus/commander_kolurg.cpp58
-rw-r--r--src/server/scripts/northrend/nexus/nexus/commander_stoutbeard.cpp64
-rw-r--r--src/server/scripts/northrend/nexus/nexus/instance_nexus.cpp259
-rw-r--r--src/server/scripts/northrend/nexus/nexus/nexus.h35
-rw-r--r--src/server/scripts/northrend/nexus/oculus/boss_drakos.cpp218
-rw-r--r--src/server/scripts/northrend/nexus/oculus/boss_eregos.cpp129
-rw-r--r--src/server/scripts/northrend/nexus/oculus/boss_urom.cpp356
-rw-r--r--src/server/scripts/northrend/nexus/oculus/boss_varos.cpp105
-rw-r--r--src/server/scripts/northrend/nexus/oculus/instance_oculus.cpp205
-rw-r--r--src/server/scripts/northrend/nexus/oculus/oculus.cpp174
-rw-r--r--src/server/scripts/northrend/nexus/oculus/oculus.h34
-rw-r--r--src/server/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp1421
-rw-r--r--src/server/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp97
-rw-r--r--src/server/scripts/northrend/obsidian_sanctum/obsidian_sanctum.h20
-rw-r--r--src/server/scripts/northrend/sholazar_basin.cpp449
-rw-r--r--src/server/scripts/northrend/storm_peaks.cpp491
-rw-r--r--src/server/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp432
-rw-r--r--src/server/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp388
-rw-r--r--src/server/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp222
-rw-r--r--src/server/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp478
-rw-r--r--src/server/scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h34
-rw-r--r--src/server/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp248
-rw-r--r--src/server/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp148
-rw-r--r--src/server/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp166
-rw-r--r--src/server/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp300
-rw-r--r--src/server/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp724
-rw-r--r--src/server/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h48
-rw-r--r--src/server/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp254
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/boss_algalon.cpp384
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/boss_assembly_of_iron.cpp589
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp106
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp574
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/boss_freya.cpp125
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp31
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/boss_hodir.cpp89
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/boss_ignis.cpp137
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp166
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp44
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp331
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/boss_thorim.cpp103
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/boss_xt002.cpp850
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/boss_yoggsaron.cpp55
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp408
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/ulduar.h71
-rw-r--r--src/server/scripts/northrend/ulduar/ulduar/ulduar_teleporter.cpp92
-rw-r--r--src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp442
-rw-r--r--src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp361
-rw-r--r--src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp389
-rw-r--r--src/server/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp312
-rw-r--r--src/server/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp160
-rw-r--r--src/server/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h35
-rw-r--r--src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp830
-rw-r--r--src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp477
-rw-r--r--src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp408
-rw-r--r--src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp367
-rw-r--r--src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp241
-rw-r--r--src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h42
-rw-r--r--src/server/scripts/northrend/vault_of_archavon/boss_archavon.cpp218
-rw-r--r--src/server/scripts/northrend/vault_of_archavon/boss_emalon.cpp270
-rw-r--r--src/server/scripts/northrend/vault_of_archavon/boss_koralon.cpp222
-rw-r--r--src/server/scripts/northrend/vault_of_archavon/boss_toravon.cpp301
-rw-r--r--src/server/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp143
-rw-r--r--src/server/scripts/northrend/vault_of_archavon/vault_of_archavon.h28
-rw-r--r--src/server/scripts/northrend/violet_hold/boss_cyanigosa.cpp156
-rw-r--r--src/server/scripts/northrend/violet_hold/boss_erekem.cpp329
-rw-r--r--src/server/scripts/northrend/violet_hold/boss_ichoron.cpp394
-rw-r--r--src/server/scripts/northrend/violet_hold/boss_lavanthor.cpp155
-rw-r--r--src/server/scripts/northrend/violet_hold/boss_moragg.cpp133
-rw-r--r--src/server/scripts/northrend/violet_hold/boss_xevozz.cpp307
-rw-r--r--src/server/scripts/northrend/violet_hold/boss_zuramat.cpp178
-rw-r--r--src/server/scripts/northrend/violet_hold/instance_violet_hold.cpp528
-rw-r--r--src/server/scripts/northrend/violet_hold/violet_hold.cpp274
-rw-r--r--src/server/scripts/northrend/violet_hold/violet_hold.h71
-rw-r--r--src/server/scripts/northrend/zuldrak.cpp1403
153 files changed, 46728 insertions, 0 deletions
diff --git a/src/server/scripts/northrend/azjol_nerub/ahnkahet/ahnkahet.h b/src/server/scripts/northrend/azjol_nerub/ahnkahet/ahnkahet.h
new file mode 100644
index 00000000000..240ad77c74d
--- /dev/null
+++ b/src/server/scripts/northrend/azjol_nerub/ahnkahet/ahnkahet.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DEF_AHNKAHET_H
+#define DEF_AHNKAHET_H
+
+enum Data64
+{
+ DATA_ELDER_NADOX,
+ DATA_PRINCE_TALDARAM,
+ DATA_JEDOGA_SHADOWSEEKER,
+ DATA_HERALD_VOLAZJ,
+ DATA_AMANITAR,
+ DATA_SPHERE1,
+ DATA_SPHERE2,
+ DATA_PRINCE_TALDARAM_PLATFORM,
+ DATA_PL_JEDOGA_TARGET,
+ DATA_ADD_JEDOGA_OPFER,
+ DATA_ADD_JEDOGA_INITIAND
+};
+
+enum Data
+{
+ DATA_ELDER_NADOX_EVENT,
+ DATA_PRINCE_TALDARAM_EVENT,
+ DATA_JEDOGA_SHADOWSEEKER_EVENT,
+ DATA_HERALD_VOLAZJ_EVENT,
+ DATA_AMANITAR_EVENT,
+ DATA_SPHERE1_EVENT,
+ DATA_SPHERE2_EVENT,
+ DATA_JEDOGA_TRIGGER_SWITCH,
+ DATA_JEDOGA_RESET_INITIANDS,
+ DATA_INITIAND_KILLED,
+ DATA_ALL_INITIAND_DEAD
+};
+
+#endif
diff --git a/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_amanitar.cpp b/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_amanitar.cpp
new file mode 100644
index 00000000000..51c4bce0c2d
--- /dev/null
+++ b/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_amanitar.cpp
@@ -0,0 +1,226 @@
+/*
+* Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+ * Comment: Find correct mushrooms spell to make them visible - buffs of the mushrooms not ever applied to the users...
+ */
+
+#include "ScriptedPch.h"
+#include "ahnkahet.h"
+
+enum Spells
+{
+ SPELL_BASH = 57094, // Victim
+ SPELL_ENTANGLING_ROOTS = 57095, // Random Victim 100Y
+ SPELL_MINI = 57055, // Self
+ SPELL_VENOM_BOLT_VOLLEY = 57088, // Random Victim 100Y
+ SPELL_HEALTHY_MUSHROOM_POTENT_FUNGUS = 56648, // Killer 3Y
+ SPELL_POISONOUS_MUSHROOM_POISON_CLOUD = 57061, // Self - Duration 8 Sec
+ SPELL_POISONOUS_MUSHROOM_VISUAL_AREA = 61566, // Self
+ SPELL_POISONOUS_MUSHROOM_VISUAL_AURA = 56741, // Self
+ SPELL_PUTRID_MUSHROOM = 31690, // To make the mushrooms visible
+};
+
+enum Creatures
+{
+ NPC_HEALTHY_MUSHROOM = 30391,
+ NPC_POISONOUS_MUSHROOM = 30435
+};
+
+struct boss_amanitarAI : public ScriptedAI
+{
+ boss_amanitarAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ bFirstTime = true;
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiRootTimer;
+ uint32 uiBashTimer;
+ uint32 uiBoltTimer;
+ uint32 uiSpawnTimer;
+
+ bool bFirstTime;
+
+ void Reset()
+ {
+ uiRootTimer = urand(5*IN_MILISECONDS,9*IN_MILISECONDS);
+ uiBashTimer = urand(10*IN_MILISECONDS,14*IN_MILISECONDS);
+ uiBoltTimer = urand(15*IN_MILISECONDS,30*IN_MILISECONDS);
+ uiSpawnTimer = 0;
+
+ me->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE);
+ me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
+
+ if (pInstance)
+ {
+ pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MINI);
+ if (!bFirstTime)
+ pInstance->SetData(DATA_AMANITAR_EVENT, FAIL);
+ else
+ bFirstTime = false;
+ }
+ }
+
+ void JustDied(Unit * /*Killer*/)
+ {
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_AMANITAR_EVENT, DONE);
+ pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MINI);
+ }
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_AMANITAR_EVENT, IN_PROGRESS);
+
+ DoCast(me, SPELL_MINI, false);
+ }
+
+ void SpawnAdds()
+ {
+ for (uint8 i = 0; i < 30; ++i)
+ {
+ Unit* victim = SelectUnit(SELECT_TARGET_RANDOM, 0);
+
+ if (victim)
+ {
+ Position pos;
+ victim->GetPosition(&pos);
+ me->GetRandomNearPosition(pos, float(urand(5,80)));
+ me->SummonCreature(NPC_POISONOUS_MUSHROOM, pos, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30*IN_MILISECONDS);
+ me->GetRandomNearPosition(pos, float(urand(5,80)));
+ me->SummonCreature(NPC_HEALTHY_MUSHROOM, pos, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30*IN_MILISECONDS);
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiSpawnTimer <= diff)
+ {
+ SpawnAdds();
+ uiSpawnTimer = urand(35*IN_MILISECONDS,40*IN_MILISECONDS);
+ } else uiSpawnTimer -= diff;
+
+ if (uiRootTimer <= diff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_ENTANGLING_ROOTS);
+ uiRootTimer = urand(15*IN_MILISECONDS,30*IN_MILISECONDS);
+ } else uiRootTimer -= diff;
+
+ if (uiBashTimer <= diff)
+ {
+ DoCastVictim(SPELL_BASH);
+ uiBashTimer = urand(15*IN_MILISECONDS,30*IN_MILISECONDS);
+ } else uiBashTimer -= diff;
+
+ if (uiBoltTimer <= diff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_VENOM_BOLT_VOLLEY);
+ uiBoltTimer = urand(15*IN_MILISECONDS,30*IN_MILISECONDS);
+ } else uiBoltTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_amanitar_mushroomsAI : public Scripted_NoMovementAI
+{
+ mob_amanitar_mushroomsAI(Creature* c) : Scripted_NoMovementAI(c) {}
+
+ uint32 uiAuraTimer;
+ uint32 uiDeathTimer;
+
+ void Reset()
+ {
+ DoCast(me, SPELL_PUTRID_MUSHROOM, true); // Hack, to make the mushrooms visible, can't find orig. spell...
+
+ if (me->GetEntry() == NPC_POISONOUS_MUSHROOM)
+ DoCast(me, SPELL_POISONOUS_MUSHROOM_VISUAL_AURA, true);
+
+ uiAuraTimer = 0;
+ uiDeathTimer = 30*IN_MILISECONDS;
+ }
+
+ void JustDied(Unit *killer)
+ {
+ if (!killer)
+ return;
+
+ if (me->GetEntry() == NPC_HEALTHY_MUSHROOM && killer->GetTypeId() == TYPEID_PLAYER)
+ {
+ me->InterruptNonMeleeSpells(false);
+ DoCast(killer, SPELL_HEALTHY_MUSHROOM_POTENT_FUNGUS, false);
+ }
+ }
+
+ void EnterCombat(Unit * /*who*/) {}
+ void AttackStart(Unit * /*victim*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (me->GetEntry() == NPC_POISONOUS_MUSHROOM)
+ {
+ if (uiAuraTimer <= diff)
+ {
+ DoCast(me, SPELL_POISONOUS_MUSHROOM_VISUAL_AREA, true);
+ DoCast(me, SPELL_POISONOUS_MUSHROOM_POISON_CLOUD, false);
+ uiAuraTimer = 7*IN_MILISECONDS;
+ } else uiAuraTimer -= diff;
+ }
+ if (uiDeathTimer <= diff)
+ me->DisappearAndDie();
+ else uiDeathTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_boss_amanitar(Creature* pCreature)
+{
+ return new boss_amanitarAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_amanitar_mushrooms(Creature *pCreature)
+{
+ return new mob_amanitar_mushroomsAI (pCreature);
+}
+
+void AddSC_boss_amanitar()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_amanitar";
+ newscript->GetAI = &GetAI_boss_amanitar;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_amanitar_mushrooms";
+ newscript->GetAI = &GetAI_mob_amanitar_mushrooms;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_elder_nadox.cpp b/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_elder_nadox.cpp
new file mode 100644
index 00000000000..2215d91c749
--- /dev/null
+++ b/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_elder_nadox.cpp
@@ -0,0 +1,283 @@
+/*
+* Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "ahnkahet.h"
+
+bool DeadAhnkaharGuardian; // needed for achievement: Respect Your Elders(2038)
+
+enum Achievements
+{
+ ACHIEV_RESPECT_YOUR_ELDERS = 2038
+};
+
+//not in db
+enum Yells
+{
+ SAY_AGGRO = -1619014,
+ SAY_SLAY_1 = -1619015,
+ SAY_SLAY_2 = -1619016,
+ SAY_SLAY_3 = -1619017,
+ SAY_DEATH = -1619018,
+ SAY_EGG_SAC_1 = -1619019,
+ SAY_EGG_SAC_2 = -1619020
+};
+
+enum Spells
+{
+ SPELL_BROOD_PLAGUE = 56130,
+ H_SPELL_BROOD_PLAGUE = 59467,
+ H_SPELL_BROOD_RAGE = 59465,
+ SPELL_ENRAGE = 26662, // Enraged if too far away from home
+ SPELL_SUMMON_SWARMERS = 56119, //2x 30178 -- 2x every 10secs
+ SPELL_SUMMON_SWARM_GUARD = 56120, //1x 30176 -- every 25secs
+};
+
+enum Creatures
+{
+ MOB_AHNKAHAR_SWARMER = 30178,
+ MOB_AHNKAHAR_GUARDIAN_ENTRY = 30176
+};
+
+#define EMOTE_HATCHES "An Ahn'kahar Guardian hatches!"
+
+struct boss_elder_nadoxAI : public ScriptedAI
+{
+ boss_elder_nadoxAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiPlagueTimer;
+ uint32 uiRagueTimer;
+
+ uint32 uiSwarmerSpawnTimer;
+ uint32 uiGuardSpawnTimer;
+ uint32 uiEnragueTimer;
+
+ bool bGuardSpawned;
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ uiPlagueTimer = 13*IN_MILISECONDS;
+ uiRagueTimer = 20*IN_MILISECONDS;
+
+ uiSwarmerSpawnTimer = 10*IN_MILISECONDS;
+ uiGuardSpawnTimer = 25*IN_MILISECONDS;
+
+ uiEnragueTimer = 5*IN_MILISECONDS;
+
+ DeadAhnkaharGuardian = false;
+ bGuardSpawned = false;
+
+ if (pInstance)
+ pInstance->SetData(DATA_ELDER_NADOX_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ DoScriptText(SAY_DEATH,me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_ELDER_NADOX_EVENT, IN_PROGRESS);
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_SLAY_3,me); //SAY_SLAY_3 on death?
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_ELDER_NADOX_EVENT, DONE);
+ if (IsHeroic() && !DeadAhnkaharGuardian)
+ pInstance->DoCompleteAchievement(ACHIEV_RESPECT_YOUR_ELDERS);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiPlagueTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_BROOD_PLAGUE);
+ uiPlagueTimer = 15*IN_MILISECONDS;
+ } else uiPlagueTimer -= diff;
+
+ if (IsHeroic())
+ if (uiRagueTimer <= diff)
+ {
+ if (Creature *pSwarmer = me->FindNearestCreature(MOB_AHNKAHAR_SWARMER, 35))
+ {
+ DoCast(pSwarmer, H_SPELL_BROOD_RAGE, true);
+ uiRagueTimer = 15*IN_MILISECONDS;
+ }
+ } else uiRagueTimer -= diff;
+
+ if (uiSwarmerSpawnTimer <= diff)
+ {
+ DoCast(me, SPELL_SUMMON_SWARMERS, true);
+ DoCast(me, SPELL_SUMMON_SWARMERS);
+ if (urand(1,3) == 3) // 33% chance of dialog
+ DoScriptText(RAND(SAY_EGG_SAC_1,SAY_EGG_SAC_2), me);
+
+ uiSwarmerSpawnTimer = 10*IN_MILISECONDS;
+ } else uiSwarmerSpawnTimer -= diff;
+
+ if (!bGuardSpawned && uiGuardSpawnTimer <= diff)
+ {
+ me->MonsterTextEmote(EMOTE_HATCHES,me->GetGUID(),true);
+ DoCast(me, SPELL_SUMMON_SWARM_GUARD);
+ bGuardSpawned = true;
+ } else uiGuardSpawnTimer -= diff;
+
+ if (uiEnragueTimer <= diff)
+ {
+ if (me->HasAura(SPELL_ENRAGE,0))
+ return;
+
+ float x, y, z, o;
+ me->GetHomePosition(x, y, z, o);
+ if (z < 24)
+ if (!me->IsNonMeleeSpellCasted(false))
+ DoCast(me, SPELL_ENRAGE, true);
+
+ uiEnragueTimer = 5*IN_MILISECONDS;
+ } else uiEnragueTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_elder_nadox(Creature* pCreature)
+{
+ return new boss_elder_nadoxAI(pCreature);
+}
+
+enum AddSpells
+{
+ SPELL_SPRINT = 56354,
+ SPELL_GUARDIAN_AURA = 56151
+};
+
+struct mob_ahnkahar_nerubianAI : public ScriptedAI
+{
+ mob_ahnkahar_nerubianAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance *pInstance;
+ uint32 uiSprintTimer;
+
+ void Reset()
+ {
+ if (me->GetEntry() == MOB_AHNKAHAR_GUARDIAN_ENTRY) //magic numbers are bad!
+ DoCast(me, SPELL_GUARDIAN_AURA, true);
+ uiSprintTimer = 10*IN_MILISECONDS;
+ }
+
+ void JustDied(Unit * /*killer*/)
+ {
+ if (me->GetEntry() == MOB_AHNKAHAR_GUARDIAN_ENTRY)
+ DeadAhnkaharGuardian = true;
+ }
+
+ void EnterCombat(Unit * /*who*/){}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (me->GetEntry() == MOB_AHNKAHAR_GUARDIAN_ENTRY)
+ me->RemoveAurasDueToSpell(SPELL_GUARDIAN_AURA);
+
+ if (pInstance)
+ {
+ if (pInstance->GetData(DATA_ELDER_NADOX_EVENT) != IN_PROGRESS)
+ {
+ me->DisappearAndDie();
+ }
+ }
+
+ if (!UpdateVictim())
+ return;
+
+ if (uiSprintTimer <= diff)
+ {
+ DoCast(me, SPELL_SPRINT);
+ uiSprintTimer = 25*IN_MILISECONDS;
+ } else uiSprintTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+//HACK: No, AI. Replace with proper db content?
+struct mob_nadox_eggsAI : public Scripted_NoMovementAI
+{
+ mob_nadox_eggsAI(Creature* c) : Scripted_NoMovementAI(c)
+ {
+ c->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
+ c->UpdateAllStats();
+ }
+ void Reset() {}
+ void EnterCombat(Unit* /*who*/) {}
+ void AttackStart(Unit* /*victim*/) {}
+ void MoveInLineOfSight(Unit* /*who*/) {}
+ void UpdateAI(const uint32 /*diff*/) {}
+};
+
+CreatureAI* GetAI_mob_ahnkahar_nerubian(Creature* pCreature)
+{
+ return new mob_ahnkahar_nerubianAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_nadox_eggs(Creature* _Creature)
+{
+ return new mob_nadox_eggsAI(_Creature);
+}
+
+void AddSC_boss_elder_nadox()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_elder_nadox";
+ newscript->GetAI = &GetAI_boss_elder_nadox;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_ahnkahar_nerubian";
+ newscript->GetAI = &GetAI_mob_ahnkahar_nerubian;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_nadox_eggs";
+ newscript->GetAI = &GetAI_mob_nadox_eggs;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_herald_volazj.cpp b/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_herald_volazj.cpp
new file mode 100644
index 00000000000..16c291d6484
--- /dev/null
+++ b/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_herald_volazj.cpp
@@ -0,0 +1,328 @@
+/*
+* Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+ * Comment: Missing AI for Twisted Visages
+ */
+
+#include "ScriptedPch.h"
+#include "ahnkahet.h"
+
+enum Spells
+{
+ SPELL_INSANITY = 57496, //Dummy
+ INSANITY_VISUAL = 57561,
+ SPELL_INSANITY_TARGET = 57508,
+ SPELL_MIND_FLAY = 57941,
+ SPELL_SHADOW_BOLT_VOLLEY = 57942,
+ SPELL_SHIVER = 57949,
+ SPELL_CLONE_PLAYER = 57507, //casted on player during insanity
+ SPELL_INSANITY_PHASING_1 = 57508,
+ SPELL_INSANITY_PHASING_2 = 57509,
+ SPELL_INSANITY_PHASING_3 = 57510,
+ SPELL_INSANITY_PHASING_4 = 57511,
+ SPELL_INSANITY_PHASING_5 = 57512
+};
+
+enum Creatures
+{
+ MOB_TWISTED_VISAGE = 30625
+};
+
+//not in db
+enum Yells
+{
+ SAY_AGGRO = -1619030,
+ SAY_SLAY_1 = -1619031,
+ SAY_SLAY_2 = -1619032,
+ SAY_SLAY_3 = -1619033,
+ SAY_DEATH_1 = -1619034,
+ SAY_DEATH_2 = -1619035,
+ SAY_PHASE = -1619036
+};
+
+enum Achievements
+{
+ ACHIEV_QUICK_DEMISE_START_EVENT = 20382,
+};
+
+struct boss_volazjAI : public ScriptedAI
+{
+ boss_volazjAI(Creature* pCreature) : ScriptedAI(pCreature),Summons(me)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance *pInstance;
+
+ uint32 uiMindFlayTimer;
+ uint32 uiShadowBoltVolleyTimer;
+ uint32 uiShiverTimer;
+ uint32 insanityHandled;
+ SummonList Summons;
+
+ // returns the percentage of health after taking the given damage.
+ uint32 GetHealthPct(uint32 damage)
+ {
+ if (damage > me->GetHealth())
+ return 0;
+ return 100*(me->GetHealth()-damage)/me->GetMaxHealth();
+ }
+
+ void DamageTaken(Unit * /*pAttacker*/, uint32 &damage)
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
+ damage = 0;
+
+ if ((GetHealthPct(0) >= 66 && GetHealthPct(damage) < 66)||
+ (GetHealthPct(0) >= 33 && GetHealthPct(damage) < 33))
+ {
+ me->InterruptNonMeleeSpells(false);
+ DoCast(me, SPELL_INSANITY, false);
+ }
+ }
+
+ void SpellHitTarget(Unit *pTarget, const SpellEntry *spell)
+ {
+ if (spell->Id == SPELL_INSANITY)
+ {
+ // Not good target or too many players
+ if (pTarget->GetTypeId() != TYPEID_PLAYER || insanityHandled > 4)
+ return;
+ // First target - start channel visual and set self as unnattackable
+ if (!insanityHandled)
+ {
+ // Channel visual
+ DoCast(me, INSANITY_VISUAL, true);
+ // Unattackable
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetControlled(true, UNIT_STAT_STUNNED);
+ }
+ // phase mask
+ pTarget->CastSpell(pTarget, SPELL_INSANITY_TARGET+insanityHandled, true);
+ // summon twisted party members for this target
+ Map::PlayerList const &players = me->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
+ {
+ Player *plr = i->getSource();
+ if (!plr || !plr->isAlive())
+ continue;
+ // Summon clone
+ if (Unit *summon = me->SummonCreature(MOB_TWISTED_VISAGE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(),TEMPSUMMON_CORPSE_DESPAWN,0))
+ {
+ // required for correct visual
+ // Fixme: allow mirror image query to send other guid to get rid of minion status
+ summon->SetUInt64Value(UNIT_FIELD_CREATEDBY, plr->GetGUID());
+ // clone
+ plr->CastSpell(summon, SPELL_CLONE_PLAYER, true);
+ // set phase
+ summon->SetPhaseMask((1<<(4+insanityHandled)),true);
+ }
+ }
+ ++insanityHandled;
+ }
+ }
+
+ void ResetPlayersPhaseMask()
+ {
+ Map::PlayerList const &players = me->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
+ {
+ Player* pPlayer = i->getSource();
+ pPlayer->RemoveAurasDueToSpell(GetSpellForPhaseMask(pPlayer->GetPhaseMask()));
+ }
+ }
+
+ void Reset()
+ {
+ uiMindFlayTimer = 8*IN_MILISECONDS;
+ uiShadowBoltVolleyTimer = 5*IN_MILISECONDS;
+ uiShiverTimer = 15*IN_MILISECONDS;
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_HERALD_VOLAZJ, NOT_STARTED);
+ pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_QUICK_DEMISE_START_EVENT);
+ }
+
+ // Visible for all players in insanity
+ me->SetPhaseMask((1|16|32|64|128|256),true);
+ // Used for Insanity handling
+ insanityHandled = 0;
+
+ ResetPlayersPhaseMask();
+
+ // Cleanup
+ Summons.DespawnAll();
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_HERALD_VOLAZJ, IN_PROGRESS);
+ pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_QUICK_DEMISE_START_EVENT);
+ }
+ }
+
+ void JustSummoned(Creature *summon)
+ {
+ Summons.Summon(summon);
+ }
+
+ uint32 GetSpellForPhaseMask(uint32 phase)
+ {
+ uint32 spell = 0;
+ switch (phase)
+ {
+ case 16:
+ spell = SPELL_INSANITY_PHASING_1;
+ break;
+ case 32:
+ spell = SPELL_INSANITY_PHASING_2;
+ break;
+ case 64:
+ spell = SPELL_INSANITY_PHASING_3;
+ break;
+ case 128:
+ spell = SPELL_INSANITY_PHASING_4;
+ break;
+ case 256:
+ spell = SPELL_INSANITY_PHASING_5;
+ break;
+ }
+ return spell;
+ }
+
+ void SummonedCreatureDespawn(Creature *summon)
+ {
+ uint32 phase= summon->GetPhaseMask();
+ uint32 nextPhase = 0;
+ Summons.Despawn(summon);
+
+ // Check if all summons in this phase killed
+ for (SummonList::const_iterator iter = Summons.begin(); iter != Summons.end(); ++iter)
+ {
+ if (Creature *visage = Unit::GetCreature(*me, *iter))
+ {
+ // Not all are dead
+ if (phase == visage->GetPhaseMask())
+ return;
+ else
+ nextPhase = visage->GetPhaseMask();
+ }
+ }
+
+ // Roll Insanity
+ uint32 spell = GetSpellForPhaseMask(phase);
+ uint32 spell2 = GetSpellForPhaseMask(nextPhase);
+ Map* pMap = me->GetMap();
+ if (!pMap)
+ return;
+
+ Map::PlayerList const &PlayerList = pMap->GetPlayers();
+ if (!PlayerList.isEmpty())
+ {
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (Player* pPlayer = i->getSource())
+ {
+ if (pPlayer->HasAura(spell))
+ {
+ pPlayer->RemoveAurasDueToSpell(spell);
+ if (spell2) // if there is still some different mask cast spell for it
+ pPlayer->CastSpell(pPlayer, spell2, true);
+ }
+ }
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (insanityHandled)
+ {
+ if (!Summons.empty())
+ return;
+
+ insanityHandled = 0;
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetControlled(false, UNIT_STAT_STUNNED);
+ me->RemoveAurasDueToSpell(INSANITY_VISUAL);
+ }
+
+ if (uiMindFlayTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_MIND_FLAY);
+ uiMindFlayTimer = 20*IN_MILISECONDS;
+ } else uiMindFlayTimer -= diff;
+
+ if (uiShadowBoltVolleyTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_SHADOW_BOLT_VOLLEY);
+ uiShadowBoltVolleyTimer = 5*IN_MILISECONDS;
+ } else uiShadowBoltVolleyTimer -= diff;
+
+ if (uiShiverTimer <= diff)
+ {
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SHIVER);
+ uiShiverTimer = 15*IN_MILISECONDS;
+ } else uiShiverTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH_1, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_HERALD_VOLAZJ, DONE);
+
+ Summons.DespawnAll();
+ ResetPlayersPhaseMask();
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+};
+
+CreatureAI* GetAI_boss_volazj(Creature* pCreature)
+{
+ return new boss_volazjAI (pCreature);
+}
+
+void AddSC_boss_volazj()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_volazj";
+ newscript->GetAI = &GetAI_boss_volazj;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp b/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp
new file mode 100644
index 00000000000..eb8046f63cd
--- /dev/null
+++ b/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_jedoga_shadowseeker.cpp
@@ -0,0 +1,588 @@
+/*
+* Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+ * Comment: Complete - BUT THE TRIGGER NEEDS DATA WHETHER THE PRISON OF TALDARAM IS OFFLINE !
+ */
+
+#include "ScriptedPch.h"
+#include "ahnkahet.h"
+
+enum Yells
+{
+ TEXT_AGGRO = -1619000,
+ TEXT_SACRIFICE_1_1 = -1619001,
+ TEXT_SACRIFICE_1_2 = -1619002,
+ TEXT_SACRIFICE_2_1 = -1619003,
+ TEXT_SACRIFICE_2_2 = -1619004,
+ TEXT_SLAY_1 = -1619005,
+ TEXT_SLAY_2 = -1619006,
+ TEXT_SLAY_3 = -1619007,
+ TEXT_DEATH = -1619008,
+ TEXT_PREACHING_1 = -1619009,
+ TEXT_PREACHING_2 = -1619010,
+ TEXT_PREACHING_3 = -1619011,
+ TEXT_PREACHING_4 = -1619012,
+ TEXT_PREACHING_5 = -1619013
+};
+
+enum Spells
+{
+ SPELL_SPHERE_VISUAL = 56075,
+ SPELL_GIFT_OF_THE_HERALD = 56219,
+ SPELL_CYCLONE_STRIKE = 56855, // Self
+ SPELL_CYCLONE_STRIKE_H = 60030,
+ SPELL_LIGHTNING_BOLT = 56891, // 40Y
+ SPELL_LIGHTNING_BOLT_H = 60032, // 40Y
+ SPELL_THUNDERSHOCK = 56926, // 30Y
+ SPELL_THUNDERSHOCK_H = 60029 // 30Y
+};
+
+enum Creatures
+{
+ NPC_JEDOGA_CONTROLLER = 30181
+};
+
+const Position JedogaPosition[2] =
+{
+ {372.330994f, -705.278015f, -0.624178f, 5.427970f},
+ {372.330994f, -705.278015f, -16.179716f, 5.427970f}
+};
+
+struct boss_jedoga_shadowseekerAI : public ScriptedAI
+{
+ boss_jedoga_shadowseekerAI(Creature* c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ bFirstTime = true;
+ bPreDone = false;
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiOpFerTimer;
+ uint32 uiCycloneTimer;
+ uint32 uiBoltTimer;
+ uint32 uiThunderTimer;
+
+ bool bPreDone;
+ bool bOpFerok;
+ bool bOnGround;
+ bool bOpFerokFail;
+ bool bCanDown;
+
+ bool bFirstTime;
+
+ void Reset()
+ {
+ uiOpFerTimer = urand(15*IN_MILISECONDS,20*IN_MILISECONDS);
+
+ uiCycloneTimer = 3*IN_MILISECONDS;
+ uiBoltTimer = 7*IN_MILISECONDS;
+ uiThunderTimer = 12*IN_MILISECONDS;
+
+ bOpFerok = false;
+ bOpFerokFail = false;
+ bOnGround = false;
+ bCanDown = false;
+
+ if (pInstance)
+ {
+ if (!bFirstTime)
+ pInstance->SetData(DATA_JEDOGA_SHADOWSEEKER_EVENT, FAIL);
+
+ pInstance->SetData64(DATA_PL_JEDOGA_TARGET, 0);
+ pInstance->SetData64(DATA_ADD_JEDOGA_OPFER, 0);
+ pInstance->SetData(DATA_JEDOGA_RESET_INITIANDS, 0);
+ }
+ MoveUp();
+
+ bFirstTime = false;
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ if (!pInstance || (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_JEDOGA_CONTROLLER))
+ return;
+
+ DoScriptText(TEXT_AGGRO, me);
+ me->SetInCombatWithZone();
+ pInstance->SetData(DATA_JEDOGA_SHADOWSEEKER_EVENT, IN_PROGRESS);
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if (!who || (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_JEDOGA_CONTROLLER))
+ return;
+
+ ScriptedAI::AttackStart(who);
+ }
+
+ void KilledUnit(Unit* Victim)
+ {
+ if (!Victim || Victim->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ DoScriptText(RAND(TEXT_SLAY_1, TEXT_SLAY_2, TEXT_SLAY_3), me);
+ }
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ DoScriptText(TEXT_DEATH, me);
+ if (pInstance)
+ pInstance->SetData(DATA_JEDOGA_SHADOWSEEKER_EVENT, DONE);
+ }
+
+ void MoveInLineOfSight(Unit* who)
+ {
+ if (!pInstance || !who || (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_JEDOGA_CONTROLLER))
+ return;
+
+ if (!bPreDone && who->GetTypeId() == TYPEID_PLAYER && me->GetDistance(who) < 100.0f)
+ {
+ DoScriptText(RAND(TEXT_PREACHING_1, TEXT_PREACHING_2, TEXT_PREACHING_3, TEXT_PREACHING_4, TEXT_PREACHING_5), me);
+ bPreDone = true;
+ }
+
+ if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) != IN_PROGRESS || !bOnGround)
+ return;
+
+ if (!me->getVictim() && who->isTargetableForAttack() && me->IsHostileTo(who) && who->isInAccessiblePlaceFor(me))
+ {
+ float attackRadius = me->GetAttackDistance(who);
+ if (me->IsWithinDistInMap(who, attackRadius) && me->IsWithinLOSInMap(who))
+ {
+ if (!me->getVictim())
+ {
+ who->RemoveAurasByType(SPELL_AURA_MOD_STEALTH);
+ AttackStart(who);
+ }
+ else if (me->GetMap()->IsDungeon())
+ {
+ who->SetInCombatWith(me);
+ me->AddThreat(who, 0.0f);
+ }
+ }
+ }
+ }
+
+ void MoveDown()
+ {
+ if (!pInstance)
+ return;
+
+ bOpFerokFail = false;
+
+ pInstance->SetData(DATA_JEDOGA_TRIGGER_SWITCH, 0);
+ me->GetMotionMaster()->MovePoint(1, JedogaPosition[1]);
+/* me->SetUnitMovementFlags(MOVEMENTFLAG_JUMPING);
+ me->SendMonsterMove(JedogaPosition[1], MOVEFLAG_JUMP, 0);
+ me->Relocate(JedogaPosition[1][0], JedogaPosition[1][1], JedogaPosition[1][2], JedogaPosition[1][3]);
+ me->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
+*/
+ me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, false);
+ me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, false);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
+
+ me->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL);
+
+ bOnGround = true;
+
+ if (UpdateVictim())
+ {
+ AttackStart(me->getVictim());
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+ }
+ else
+ {
+ if (Unit* pTarget = Unit::GetUnit(*me, pInstance->GetData64(DATA_PL_JEDOGA_TARGET)))
+ {
+ AttackStart(pTarget);
+ pInstance->SetData(DATA_JEDOGA_RESET_INITIANDS, 0);
+ if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) != IN_PROGRESS)
+ EnterCombat(pTarget);
+ }
+ else if (!me->isInCombat())
+ EnterEvadeMode();
+ }
+ }
+
+ void MoveUp()
+ {
+ if (!pInstance)
+ return;
+
+ me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true);
+ me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
+
+ me->AttackStop();
+ me->RemoveAllAuras();
+ me->LoadCreaturesAddon();
+ me->GetMotionMaster()->MovePoint(0, JedogaPosition[0]);
+/* me->SetUnitMovementFlags(MOVEMENTFLAG_JUMPING);
+ me->SendMonsterMove(JedogaPosition[0][0], JedogaPosition[0][1], JedogaPosition[0][2], 0, MOVEFLAG_JUMP, 0);
+ me->Relocate(JedogaPosition[0][0], JedogaPosition[0][1], JedogaPosition[0][2], JedogaPosition[0][3]);
+ me->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveIdle();
+ me->StopMoving();
+*/
+
+ pInstance->SetData(DATA_JEDOGA_TRIGGER_SWITCH, 1);
+ if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS) OpferRufen();
+
+ bOnGround = false;
+ uiOpFerTimer = urand(15*IN_MILISECONDS,30*IN_MILISECONDS);
+ }
+
+ void OpferRufen()
+ {
+ if (!pInstance)
+ return;
+
+ uint64 opfer = pInstance->GetData64(DATA_ADD_JEDOGA_INITIAND);
+
+ if (opfer)
+ {
+ DoScriptText(RAND(TEXT_SACRIFICE_1_1, TEXT_SACRIFICE_1_2), me);
+ pInstance->SetData64(DATA_ADD_JEDOGA_OPFER, opfer);
+ } else
+ bCanDown = true;
+ }
+
+ void Opfern()
+ {
+ DoScriptText(RAND(TEXT_SACRIFICE_2_1, TEXT_SACRIFICE_2_2), me);
+
+ me->InterruptNonMeleeSpells(false);
+ DoCast(me, SPELL_GIFT_OF_THE_HERALD, false);
+
+ bOpFerok = false;
+ bCanDown = true;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!pInstance)
+ return;
+
+ if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) != IN_PROGRESS && pInstance->GetData(DATA_ALL_INITIAND_DEAD))
+ MoveDown();
+
+ if (bOpFerok && !bOnGround && !bCanDown) Opfern();
+
+ if (bOpFerokFail && !bOnGround && !bCanDown)
+ bCanDown = true;
+
+ if (bCanDown)
+ {
+ MoveDown();
+ bCanDown = false;
+ }
+
+ if (bOnGround)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiCycloneTimer <= diff)
+ {
+ DoCast(me, SPELL_CYCLONE_STRIKE, false);
+ uiCycloneTimer = urand(15*IN_MILISECONDS,30*IN_MILISECONDS);
+ } else uiCycloneTimer -= diff;
+
+ if (uiBoltTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ me->CastSpell(pTarget, DUNGEON_MODE(SPELL_LIGHTNING_BOLT, SPELL_LIGHTNING_BOLT_H), false);
+
+ uiBoltTimer = urand(15*IN_MILISECONDS,30*IN_MILISECONDS);
+ } else uiBoltTimer -= diff;
+
+ if (uiThunderTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ me->CastSpell(pTarget, DUNGEON_MODE(SPELL_THUNDERSHOCK, SPELL_THUNDERSHOCK_H), false);
+
+ uiThunderTimer = urand(15*IN_MILISECONDS,30*IN_MILISECONDS);
+ } else uiThunderTimer -= diff;
+
+ if (uiOpFerTimer <= diff)
+ MoveUp();
+ else
+ uiOpFerTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+ }
+};
+
+struct mob_jedoga_initiandAI : public ScriptedAI
+{
+ mob_jedoga_initiandAI(Creature* c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 bCheckTimer;
+
+ bool bWalking;
+
+ void Reset()
+ {
+ if (!pInstance)
+ return;
+
+ bWalking = false;
+ bCheckTimer = 2*IN_MILISECONDS;
+
+ if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) != IN_PROGRESS)
+ {
+ me->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL);
+ me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, false);
+ me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, false);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
+ }
+ else
+ {
+ DoCast(me, SPELL_SPHERE_VISUAL, false);
+ me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true);
+ me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
+ }
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ if (!Killer || !pInstance) return;
+
+ if (bWalking)
+ {
+ Creature* boss = me->GetMap()->GetCreature(pInstance->GetData64(DATA_JEDOGA_SHADOWSEEKER));
+ if (boss && !CAST_AI(boss_jedoga_shadowseekerAI, boss->AI())->bOpFerok) CAST_AI(boss_jedoga_shadowseekerAI, boss->AI())->bOpFerokFail = true;
+
+ if (Killer->GetTypeId() == TYPEID_PLAYER) pInstance->SetData(DATA_INITIAND_KILLED, 1);
+ pInstance->SetData64(DATA_ADD_JEDOGA_OPFER, 0);
+
+ bWalking = false;
+ }
+ if (Killer->GetTypeId() == TYPEID_PLAYER) pInstance->SetData64(DATA_PL_JEDOGA_TARGET, Killer->GetGUID());
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ if ((pInstance && pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS) || !who) return;
+ }
+
+ void AttackStart(Unit* victim)
+ {
+ if ((pInstance && pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS) || !victim) return;
+
+ ScriptedAI::AttackStart(victim);
+ }
+
+ void MoveInLineOfSight(Unit* who)
+ {
+ if ((pInstance && pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS) || !who) return;
+
+ ScriptedAI::MoveInLineOfSight(who);
+ }
+
+ void MovementInform(uint32 uiType, uint32 uiPointId)
+ {
+ if (uiType != POINT_MOTION_TYPE || !pInstance) return;
+
+ switch(uiPointId)
+ {
+ case 1:
+ {
+ Creature* boss = me->GetMap()->GetCreature(pInstance->GetData64(DATA_JEDOGA_SHADOWSEEKER));
+ if (boss)
+ {
+ CAST_AI(boss_jedoga_shadowseekerAI, boss->AI())->bOpFerok = true;
+ CAST_AI(boss_jedoga_shadowseekerAI, boss->AI())->bOpFerokFail = false;
+ me->Kill(me);
+ }
+ }
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (pInstance && bCheckTimer <= diff)
+ {
+ if (me->GetGUID() == pInstance->GetData64(DATA_ADD_JEDOGA_OPFER) && !bWalking)
+ {
+ me->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL);
+ me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, false);
+ me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, false);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
+
+ float distance = me->GetDistance(JedogaPosition[1]);
+
+ if (distance < 9.0f)
+ me->SetSpeed(MOVE_WALK, 0.5f, true);
+ else if (distance < 15.0f)
+ me->SetSpeed(MOVE_WALK, 0.75f, true);
+ else if (distance < 20.0f)
+ me->SetSpeed(MOVE_WALK, 1.0f, true);
+
+ me->GetMotionMaster()->Clear(false);
+ me->GetMotionMaster()->MovePoint(1, JedogaPosition[1]);
+ bWalking = true;
+ }
+ if (!bWalking)
+ {
+ if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) != IN_PROGRESS && me->HasAura(SPELL_SPHERE_VISUAL))
+ {
+ me->RemoveAurasDueToSpell(SPELL_SPHERE_VISUAL);
+ me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, false);
+ me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, false);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
+ }
+ if (pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == IN_PROGRESS && !me->HasAura(SPELL_SPHERE_VISUAL))
+ {
+ DoCast(me, SPELL_SPHERE_VISUAL, false);
+ me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true);
+ me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
+ }
+ }
+ bCheckTimer = 2*IN_MILISECONDS;
+ } else bCheckTimer -= diff;
+
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+// ------------------------------------------------------------------------------------------------------------
+// Jedogas Aufseher - Entry: 30181
+// ------------------------------------------------------------------------------------------------------------
+enum AufseherSpell
+{
+ SPELL_BEAM_VISUAL_JEDOGAS_AUFSEHER_1 = 60342,
+ SPELL_BEAM_VISUAL_JEDOGAS_AUFSEHER_2 = 56312
+};
+
+struct npc_jedogas_aufseher_triggerAI : public Scripted_NoMovementAI
+{
+ npc_jedogas_aufseher_triggerAI(Creature* c) : Scripted_NoMovementAI(c)
+ {
+ pInstance = c->GetInstanceData();
+// c->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);
+// c->setFaction(35);
+ bRemoved = false;
+ bRemoved2 = false;
+ bCasted = false;
+ bCasted2 = false;
+ }
+
+ ScriptedInstance* pInstance;
+
+ bool bRemoved;
+ bool bRemoved2;
+ bool bCasted;
+ bool bCasted2;
+
+ void Reset() {}
+ void EnterCombat(Unit* /*who*/) {}
+ void AttackStart(Unit* /*victim*/) {}
+ void MoveInLineOfSight(Unit* /*who*/) {}
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ if (!pInstance)
+ return;
+
+ if (!bRemoved && me->GetPositionX() > 440.0f)
+ {
+ if (pInstance->GetData(DATA_PRINCE_TALDARAM_EVENT) == DONE)
+ {
+ me->InterruptNonMeleeSpells(true);
+ bRemoved = true;
+ return;
+ }
+ if (!bCasted)
+ {
+ DoCast(me, SPELL_BEAM_VISUAL_JEDOGAS_AUFSEHER_1, false);
+ bCasted = true;
+ }
+ }
+ if (!bRemoved2 && me->GetPositionX() < 440.0f)
+ {
+ if (!bCasted2 && pInstance->GetData(DATA_JEDOGA_TRIGGER_SWITCH))
+ {
+ DoCast(me, SPELL_BEAM_VISUAL_JEDOGAS_AUFSEHER_2, false);
+ bCasted2 = true;
+ }
+ if (bCasted2 && !pInstance->GetData(DATA_JEDOGA_TRIGGER_SWITCH))
+ {
+ me->InterruptNonMeleeSpells(true);
+ bCasted2 = false;
+ }
+ if (!bRemoved2 && pInstance->GetData(DATA_JEDOGA_SHADOWSEEKER_EVENT) == DONE)
+ {
+ me->InterruptNonMeleeSpells(true);
+ bRemoved2 = true;
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_jedoga_shadowseeker(Creature* pCreature)
+{
+ return new boss_jedoga_shadowseekerAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_jedoga_initiand(Creature* pCreature)
+{
+ return new mob_jedoga_initiandAI (pCreature);
+}
+
+CreatureAI* GetAI_npc_jedogas_aufseher_trigger(Creature* pCreature)
+{
+ return new npc_jedogas_aufseher_triggerAI (pCreature);
+}
+
+void AddSC_boss_jedoga_shadowseeker()
+{
+ Script* newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_jedoga_shadowseeker";
+ newscript->GetAI = &GetAI_boss_jedoga_shadowseeker;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_jedoga_initiand";
+ newscript->GetAI = &GetAI_mob_jedoga_initiand;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_jedogas_aufseher_trigger";
+ newscript->GetAI = &GetAI_npc_jedogas_aufseher_trigger;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp
new file mode 100644
index 00000000000..93a66ccfbca
--- /dev/null
+++ b/src/server/scripts/northrend/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "ahnkahet.h"
+
+enum Spells
+{
+ SPELL_BLOODTHIRST = 55968, //Trigger Spell + add aura
+ SPELL_CONJURE_FLAME_SPHERE = 55931,
+ SPELL_FLAME_SPHERE_SUMMON_1 = 55895,// 1x 30106
+ H_SPELL_FLAME_SPHERE_SUMMON_1 = 59511,// 1x 31686
+ H_SPELL_FLAME_SPHERE_SUMMON_2 = 59512,// 1x 31687
+ SPELL_FLAME_SPHERE_SPAWN_EFFECT = 55891,
+ SPELL_FLAME_SPHERE_VISUAL = 55928,
+ SPELL_FLAME_SPHERE_PERIODIC = 55926,
+ H_SPELL_FLAME_SPHERE_PERIODIC = 59508,
+ SPELL_FLAME_SPHERE_DEATH_EFFECT = 55947,
+ SPELL_BEAM_VISUAL = 60342,
+ SPELL_EMBRACE_OF_THE_VAMPYR = 55959,
+ H_SPELL_EMBRACE_OF_THE_VAMPYR = 59513,
+ SPELL_VANISH = 55964,
+ CREATURE_FLAME_SPHERE = 30106,
+ H_CREATURE_FLAME_SPHERE_1 = 31686,
+ H_CREATURE_FLAME_SPHERE_2 = 31687
+};
+enum Misc
+{
+ DATA_EMBRACE_DMG = 20000,
+ H_DATA_EMBRACE_DMG = 40000,
+ DATA_SPHERE_DISTANCE = 15
+};
+#define DATA_SPHERE_ANGLE_OFFSET 0.7
+#define DATA_GROUND_POSITION_Z 11.4
+
+enum Yells
+{
+ SAY_AGGRO = -1619021,
+ SAY_SLAY_1 = -1619022,
+ SAY_SLAY_2 = -1619023,
+ SAY_DEATH = -1619024,
+ SAY_FEED_1 = -1619025,
+ SAY_FEED_2 = -1619026,
+ SAY_VANISH_1 = -1619027,
+ SAY_VANISH_2 = -1619028
+};
+enum CombatPhase
+{
+ NORMAL,
+ CASTING_FLAME_SPHERES,
+ JUST_VANISHED,
+ VANISHED,
+ FEEDING
+};
+enum GameObjects
+{
+ GO_SPHERE1 = 193093,
+ GO_SPHERE2 = 193094
+};
+
+struct boss_taldaramAI : public ScriptedAI
+{
+ boss_taldaramAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ uint32 uiBloodthirstTimer;
+ uint32 uiVanishTimer;
+ uint32 uiWaitTimer;
+ uint32 uiEmbraceTimer;
+ uint32 uiEmbraceTakenDamage;
+ uint32 uiFlamesphereTimer;
+ uint32 uiPhaseTimer;
+
+ uint64 uiEmbraceTarget;
+
+ CombatPhase Phase;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiBloodthirstTimer = 10*IN_MILISECONDS;
+ uiVanishTimer = urand(25*IN_MILISECONDS,35*IN_MILISECONDS);
+ uiEmbraceTimer = 20*IN_MILISECONDS;
+ uiFlamesphereTimer = 5*IN_MILISECONDS;
+ uiEmbraceTakenDamage = 0;
+ Phase = NORMAL;
+ uiPhaseTimer = 0;
+ uiEmbraceTarget = 0;
+ if (pInstance)
+ pInstance->SetData(DATA_PRINCE_TALDARAM_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_PRINCE_TALDARAM_EVENT, IN_PROGRESS);
+ DoScriptText(SAY_AGGRO, me);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+ if (uiPhaseTimer <= diff)
+ {
+ switch (Phase)
+ {
+ case CASTING_FLAME_SPHERES:
+ {
+ Creature* pSpheres[3];
+
+ //DoCast(me, SPELL_FLAME_SPHERE_SUMMON_1);
+ pSpheres[0] = DoSpawnCreature(CREATURE_FLAME_SPHERE, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10*IN_MILISECONDS);
+ Unit *pSphereTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
+ if (pSphereTarget && pSpheres[0])
+ {
+ float angle,x,y;
+ angle = pSpheres[0]->GetAngle(pSphereTarget);
+ x = pSpheres[0]->GetPositionX() + DATA_SPHERE_DISTANCE * cos(angle);
+ y = pSpheres[0]->GetPositionY() + DATA_SPHERE_DISTANCE * sin(angle);
+ pSpheres[0]->GetMotionMaster()->MovePoint(0, x, y, pSpheres[0]->GetPositionZ());
+ }
+ if (IsHeroic())
+ {
+ //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_1);
+ pSpheres[1] = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_1, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10*IN_MILISECONDS);
+ //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_2);
+ pSpheres[2] = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_2, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10*IN_MILISECONDS);
+ if (pSphereTarget && pSpheres[1] && pSpheres[2])
+ {
+ float angle,x,y;
+ angle = pSpheres[1]->GetAngle(pSphereTarget) + DATA_SPHERE_ANGLE_OFFSET;
+ x = pSpheres[1]->GetPositionX() + DATA_SPHERE_DISTANCE/2 * cos(angle);
+ y = pSpheres[1]->GetPositionY() + DATA_SPHERE_DISTANCE/2 * sin(angle);
+ pSpheres[1]->GetMotionMaster()->MovePoint(0, x, y, pSpheres[1]->GetPositionZ());
+ angle = pSpheres[2]->GetAngle(pSphereTarget) - DATA_SPHERE_ANGLE_OFFSET;
+ x = pSpheres[2]->GetPositionX() + DATA_SPHERE_DISTANCE/2 * cos(angle);
+ y = pSpheres[2]->GetPositionY() + DATA_SPHERE_DISTANCE/2 * sin(angle);
+ pSpheres[2]->GetMotionMaster()->MovePoint(0, x, y, pSpheres[2]->GetPositionZ());
+ }
+ }
+
+ Phase = NORMAL;
+ uiPhaseTimer = 0;
+ break;
+ }
+ case JUST_VANISHED:
+ if (Unit *pEmbraceTarget = GetEmbraceTarget())
+ {
+ me->GetMotionMaster()->Clear();
+ me->SetSpeed(MOVE_WALK, 2.0f, true);
+ me->GetMotionMaster()->MoveChase(pEmbraceTarget);
+ }
+ Phase = VANISHED;
+ uiPhaseTimer = 1300;
+ break;
+ case VANISHED:
+ if (Unit *pEmbraceTarget = GetEmbraceTarget())
+ DoCast(pEmbraceTarget, SPELL_EMBRACE_OF_THE_VAMPYR);
+ me->GetMotionMaster()->Clear();
+ me->SetSpeed(MOVE_WALK, 1.0f, true);
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+ Phase = FEEDING;
+ uiPhaseTimer = 20*IN_MILISECONDS;
+ break;
+ case FEEDING:
+ Phase = NORMAL;
+ uiPhaseTimer = 0;
+ uiEmbraceTarget = 0;
+ break;
+ case NORMAL:
+ if (uiBloodthirstTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_BLOODTHIRST);
+ uiBloodthirstTimer = 10*IN_MILISECONDS;
+ } else uiBloodthirstTimer -= diff;
+
+ if (uiFlamesphereTimer <= diff)
+ {
+ DoCast(me, SPELL_CONJURE_FLAME_SPHERE);
+ Phase = CASTING_FLAME_SPHERES;
+ uiPhaseTimer = 3*IN_MILISECONDS + diff;
+ uiFlamesphereTimer = 15*IN_MILISECONDS;
+ } else uiFlamesphereTimer -= diff;
+
+ if (uiVanishTimer <= diff)
+ {
+ //Count alive players
+ Unit *pTarget = NULL;
+ std::list<HostileReference *> t_list = me->getThreatManager().getThreatList();
+ std::vector<Unit *> target_list;
+ for (std::list<HostileReference *>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
+ {
+ pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid());
+ // exclude pets & totems
+ if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->isAlive())
+ target_list.push_back(pTarget);
+ pTarget = NULL;
+ }
+ //He only vanishes if there are 3 or more alive players
+ if (target_list.size() > 2)
+ {
+ DoScriptText(RAND(SAY_VANISH_1,SAY_VANISH_2), me);
+ DoCast(me, SPELL_VANISH);
+ Phase = JUST_VANISHED;
+ uiPhaseTimer = 500;
+ if (Unit* pEmbraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ uiEmbraceTarget = pEmbraceTarget->GetGUID();
+
+ }
+ uiVanishTimer = urand(25*IN_MILISECONDS,35*IN_MILISECONDS);
+ } else uiVanishTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ break;
+ }
+ } else uiPhaseTimer -= diff;
+ }
+
+ void DamageTaken(Unit* /*done_by*/, uint32 &damage)
+ {
+ Unit* pEmbraceTarget = GetEmbraceTarget();
+
+ if (Phase == FEEDING && pEmbraceTarget && pEmbraceTarget->isAlive())
+ {
+ uiEmbraceTakenDamage += damage;
+ if (uiEmbraceTakenDamage > DUNGEON_MODE(DATA_EMBRACE_DMG, H_DATA_EMBRACE_DMG))
+ {
+ Phase = NORMAL;
+ uiPhaseTimer = 0;
+ uiEmbraceTarget = 0;
+ me->CastStop();
+ }
+ }
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_PRINCE_TALDARAM_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+
+ Unit* pEmbraceTarget = GetEmbraceTarget();
+ if (Phase == FEEDING && pEmbraceTarget && victim == pEmbraceTarget)
+ {
+ Phase = NORMAL;
+ uiPhaseTimer = 0;
+ uiEmbraceTarget = 0;
+ }
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ bool CheckSpheres()
+ {
+ if (!pInstance)
+ return false;
+
+ uint64 uiSphereGuids[2];
+ uiSphereGuids[0] = pInstance->GetData64(DATA_SPHERE1);
+ uiSphereGuids[1] = pInstance->GetData64(DATA_SPHERE2);
+
+ for (uint8 i=0; i < 2; ++i)
+ {
+ GameObject *pSpheres = pInstance->instance->GetGameObject(uiSphereGuids[i]);
+ if (!pSpheres)
+ return false;
+ if (pSpheres->GetGoState() != GO_STATE_ACTIVE)
+ return false;
+ }
+ RemovePrison();
+ return true;
+ }
+
+ Unit* GetEmbraceTarget()
+ {
+ if (!uiEmbraceTarget)
+ return NULL;
+
+ return Unit::GetUnit(*me, uiEmbraceTarget);
+ }
+
+ void RemovePrison()
+ {
+ if (!pInstance)
+ return;
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->RemoveAurasDueToSpell(SPELL_BEAM_VISUAL);
+ me->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
+ me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), DATA_GROUND_POSITION_Z, me->GetOrientation());
+ uint64 prison_GUID = pInstance->GetData64(DATA_PRINCE_TALDARAM_PLATFORM);
+ pInstance->HandleGameObject(prison_GUID,true);
+ }
+};
+
+struct mob_taldaram_flamesphereAI : public ScriptedAI
+{
+ mob_taldaram_flamesphereAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiDespawnTimer;
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING);
+ me->setFaction(16);
+ me->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
+ DoCast(me, SPELL_FLAME_SPHERE_VISUAL);
+ DoCast(me, SPELL_FLAME_SPHERE_SPAWN_EFFECT);
+ DoCast(me, SPELL_FLAME_SPHERE_PERIODIC);
+ uiDespawnTimer = 10*IN_MILISECONDS;
+ }
+
+ void EnterCombat(Unit * /*who*/) {}
+ void MoveInLineOfSight(Unit * /*who*/) {}
+
+ void JustDied(Unit* /*who*/)
+ {
+ DoCast(me, SPELL_FLAME_SPHERE_DEATH_EFFECT);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (uiDespawnTimer <= diff)
+ me->DisappearAndDie();
+ else
+ uiDespawnTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_boss_taldaram(Creature* pCreature)
+{
+ return new boss_taldaramAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_taldaram_flamesphere(Creature* pCreature)
+{
+ return new mob_taldaram_flamesphereAI (pCreature);
+}
+
+bool GOHello_prince_taldaram_sphere(Player * /*pPlayer*/, GameObject *pGO)
+{
+ ScriptedInstance *pInstance = pGO->GetInstanceData();
+
+ Creature *pPrinceTaldaram = Unit::GetCreature(*pGO, pInstance ? pInstance->GetData64(DATA_PRINCE_TALDARAM) : 0);
+ if (pPrinceTaldaram && pPrinceTaldaram->isAlive())
+ {
+ // maybe these are hacks :(
+ pGO->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ pGO->SetGoState(GO_STATE_ACTIVE);
+
+ switch(pGO->GetEntry())
+ {
+ case GO_SPHERE1: pInstance->SetData(DATA_SPHERE1_EVENT,IN_PROGRESS); break;
+ case GO_SPHERE2: pInstance->SetData(DATA_SPHERE2_EVENT,IN_PROGRESS); break;
+ }
+
+ CAST_AI(boss_taldaramAI, pPrinceTaldaram->AI())->CheckSpheres();
+ }
+ return true;
+}
+
+void AddSC_boss_taldaram()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_taldaram";
+ newscript->GetAI = &GetAI_boss_taldaram;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_taldaram_flamesphere";
+ newscript->GetAI = &GetAI_mob_taldaram_flamesphere;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "prince_taldaram_sphere";
+ newscript->pGOHello = &GOHello_prince_taldaram_sphere;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/azjol_nerub/ahnkahet/instance_ahnkahet.cpp b/src/server/scripts/northrend/azjol_nerub/ahnkahet/instance_ahnkahet.cpp
new file mode 100644
index 00000000000..4e6e3ec8c9f
--- /dev/null
+++ b/src/server/scripts/northrend/azjol_nerub/ahnkahet/instance_ahnkahet.cpp
@@ -0,0 +1,313 @@
+/*
+* Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "ahnkahet.h"
+
+/* Ahn'kahet encounters:
+0 - Elder Nadox
+1 - Prince Taldaram
+2 - Jedoga Shadowseeker
+3 - Herald Volazj
+4 - Amanitar (Heroic only)
+*/
+
+#define MAX_ENCOUNTER 5
+
+enum Achievements
+{
+ ACHIEV_VOLUNTEER_WORK = 2056
+};
+
+struct instance_ahnkahet : public ScriptedInstance
+{
+ instance_ahnkahet(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+
+ uint64 Elder_Nadox;
+ uint64 Prince_Taldaram;
+ uint64 Jedoga_Shadowseeker;
+ uint64 Herald_Volazj;
+ uint64 Amanitar;
+
+ uint64 Prince_TaldaramSpheres[2];
+ uint64 Prince_TaldaramPlatform;
+ uint64 Prince_TaldaramGate;
+
+ std::set<uint64> InitiandGUIDs;
+ uint64 JedogaSacrifices;
+ uint64 JedogaTarget;
+
+ uint32 m_auiEncounter[MAX_ENCOUNTER];
+ uint32 spheres[2];
+
+ uint8 InitiandCnt,
+ switchtrigger,
+ initiandkilled;
+
+ std::string str_data;
+
+ void Initialize()
+ {
+ memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+ InitiandGUIDs.clear();
+
+ Elder_Nadox =0;
+ Prince_Taldaram =0;
+ Jedoga_Shadowseeker =0;
+ Herald_Volazj =0;
+ Amanitar =0;
+
+ spheres[0] = NOT_STARTED;
+ spheres[1] = NOT_STARTED;
+
+ InitiandCnt = 0;
+ switchtrigger = 0;
+ initiandkilled = 0;
+ JedogaSacrifices = 0;
+ JedogaTarget = 0;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool /*add*/)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case 29309: Elder_Nadox = pCreature->GetGUID(); break;
+ case 29308: Prince_Taldaram = pCreature->GetGUID(); break;
+ case 29310: Jedoga_Shadowseeker = pCreature->GetGUID(); break;
+ case 29311: Herald_Volazj = pCreature->GetGUID(); break;
+ case 30258: Amanitar = pCreature->GetGUID(); break;
+ case 30114: InitiandGUIDs.insert(pCreature->GetGUID()); break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
+ {
+ switch(pGo->GetEntry())
+ {
+ case 193564: Prince_TaldaramPlatform = pGo->GetGUID();
+ if (m_auiEncounter[1] == DONE) HandleGameObject(NULL,true,pGo); break;
+ case 193093: Prince_TaldaramSpheres[0] = pGo->GetGUID();
+ if (spheres[0] == IN_PROGRESS)
+ {
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ }
+ else pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ break;
+ case 193094: Prince_TaldaramSpheres[1] = pGo->GetGUID();
+ if (spheres[1] == IN_PROGRESS)
+ {
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ }
+ else pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ break;
+ case 192236: Prince_TaldaramGate = pGo->GetGUID(); // Web gate past Prince Taldaram
+ if (m_auiEncounter[1] == DONE)HandleGameObject(NULL,true,pGo);break;
+ }
+ }
+
+ void SetData64(uint32 idx, uint64 guid)
+ {
+ switch(idx)
+ {
+ case DATA_ADD_JEDOGA_OPFER: JedogaSacrifices = guid; break;
+ case DATA_PL_JEDOGA_TARGET: JedogaTarget = guid; break;
+ }
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_ELDER_NADOX: return Elder_Nadox;
+ case DATA_PRINCE_TALDARAM: return Prince_Taldaram;
+ case DATA_JEDOGA_SHADOWSEEKER: return Jedoga_Shadowseeker;
+ case DATA_HERALD_VOLAZJ: return Herald_Volazj;
+ case DATA_AMANITAR: return Amanitar;
+ case DATA_SPHERE1: return Prince_TaldaramSpheres[0];
+ case DATA_SPHERE2: return Prince_TaldaramSpheres[1];
+ case DATA_PRINCE_TALDARAM_PLATFORM: return Prince_TaldaramPlatform;
+ case DATA_ADD_JEDOGA_INITIAND:
+ {
+ std::vector<uint64> vInitiands;
+ vInitiands.clear();
+ for (std::set<uint64>::const_iterator itr = InitiandGUIDs.begin(); itr != InitiandGUIDs.end(); ++itr)
+ {
+ Creature* cr = instance->GetCreature(*itr);
+ if (cr && cr->isAlive())
+ vInitiands.push_back(*itr);
+ }
+ if (vInitiands.empty())
+ return 0;
+ uint8 j = urand(0,vInitiands.size() -1);
+ return vInitiands[j];
+ }
+ case DATA_ADD_JEDOGA_OPFER: return JedogaSacrifices;
+ case DATA_PL_JEDOGA_TARGET: return JedogaTarget;
+ }
+ return 0;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_ELDER_NADOX_EVENT: m_auiEncounter[0] = data; break;
+ case DATA_PRINCE_TALDARAM_EVENT:
+ if (data == DONE)
+ HandleGameObject(Prince_TaldaramGate,true);
+ m_auiEncounter[1] = data;
+ break;
+ case DATA_JEDOGA_SHADOWSEEKER_EVENT:
+ m_auiEncounter[2] = data;
+ if (data == DONE)
+ {
+ for (std::set<uint64>::const_iterator itr = InitiandGUIDs.begin(); itr != InitiandGUIDs.end(); ++itr)
+ {
+ Creature* cr = instance->GetCreature(*itr);
+ if (cr && cr->isAlive())
+ {
+ cr->SetVisibility(VISIBILITY_OFF);
+ cr->setDeathState(JUST_DIED);
+ cr->RemoveCorpse();
+ }
+ }
+ if (!initiandkilled && instance->IsHeroic())
+ DoCompleteAchievement(ACHIEV_VOLUNTEER_WORK);
+ }
+ break;
+ case DATA_HERALD_VOLAZJ_EVENT: m_auiEncounter[3] = data; break;
+ case DATA_AMANITAR_EVENT: m_auiEncounter[4] = data; break;
+ case DATA_SPHERE1_EVENT: spheres[0] = data; break;
+ case DATA_SPHERE2_EVENT: spheres[1] = data; break;
+ case DATA_JEDOGA_TRIGGER_SWITCH: switchtrigger = data; break;
+ case DATA_INITIAND_KILLED: initiandkilled = data; break;
+ case DATA_JEDOGA_RESET_INITIANDS:
+ for (std::set<uint64>::const_iterator itr = InitiandGUIDs.begin(); itr != InitiandGUIDs.end(); ++itr)
+ {
+ Creature* cr = instance->GetCreature(*itr);
+ if (cr)
+ {
+ cr->Respawn();
+ if (!cr->IsInEvadeMode()) cr->AI()->EnterEvadeMode();
+ }
+ }
+ break;
+ }
+ if (data == DONE)
+ SaveToDB();
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_ELDER_NADOX_EVENT: return m_auiEncounter[0];
+ case DATA_PRINCE_TALDARAM_EVENT: return m_auiEncounter[1];
+ case DATA_JEDOGA_SHADOWSEEKER_EVENT: return m_auiEncounter[2];
+ case DATA_HERALD_VOLAZJ: return m_auiEncounter[3];
+ case DATA_AMANITAR_EVENT: return m_auiEncounter[4];
+ case DATA_SPHERE1_EVENT: return spheres[0];
+ case DATA_SPHERE2_EVENT: return spheres[1];
+ case DATA_ALL_INITIAND_DEAD:
+ for (std::set<uint64>::const_iterator itr = InitiandGUIDs.begin(); itr != InitiandGUIDs.end(); ++itr)
+ {
+ Creature* cr = instance->GetCreature(*itr);
+ if (!cr || (cr && cr->isAlive())) return 0;
+ }
+ return 1;
+ case DATA_JEDOGA_TRIGGER_SWITCH: return switchtrigger;
+ case DATA_INITIAND_KILLED: return initiandkilled;
+ }
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "A K " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
+ << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " "
+ << spheres[0] << " " << spheres[1];
+
+ str_data = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return str_data;
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0, data1, data2, data3, data4, data5, data6;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4 >> data5 >> data6;
+
+ if (dataHead1 == 'A' && dataHead2 == 'K')
+ {
+ m_auiEncounter[0] = data0;
+ m_auiEncounter[1] = data1;
+ m_auiEncounter[2] = data2;
+ m_auiEncounter[3] = data3;
+ m_auiEncounter[4] = data4;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+
+ spheres[0] = data5;
+ spheres[1] = data6;
+
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_ahnkahet(Map* pMap)
+{
+ return new instance_ahnkahet(pMap);
+}
+
+void AddSC_instance_ahnkahet()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_ahnkahet";
+ newscript->GetInstanceData = &GetInstanceData_instance_ahnkahet;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/azjol_nerub/azjol_nerub/azjol_nerub.h b/src/server/scripts/northrend/azjol_nerub/azjol_nerub/azjol_nerub.h
new file mode 100644
index 00000000000..4113885b6f4
--- /dev/null
+++ b/src/server/scripts/northrend/azjol_nerub/azjol_nerub/azjol_nerub.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DEF_AZJOL_NERUB_H
+#define DEF_AZJOL_NERUB_H
+
+enum Data64
+{
+ DATA_KRIKTHIR_THE_GATEWATCHER,
+ DATA_HADRONOX,
+ DATA_ANUBARAK,
+ DATA_WATCHER_GASHRA,
+ DATA_WATCHER_SILTHIK,
+ DATA_WATCHER_NARJIL
+};
+enum Data
+{
+ DATA_KRIKTHIR_THE_GATEWATCHER_EVENT,
+ DATA_HADRONOX_EVENT,
+ DATA_ANUBARAK_EVENT
+};
+
+#endif
diff --git a/src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_anubarak.cpp b/src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_anubarak.cpp
new file mode 100644
index 00000000000..6de6578f7bb
--- /dev/null
+++ b/src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_anubarak.cpp
@@ -0,0 +1,360 @@
+/*
+* Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "azjol_nerub.h"
+
+//SQL: UPDATE creature_template SET mechanic_immune_mask = 1073741823 WHERE name like "anub'arak%";
+
+enum Spells
+{
+ SPELL_CARRION_BEETLES = 53520,
+ SPELL_SUMMON_CARRION_BEETLES = 53521,
+ SPELL_LEECHING_SWARM = 53467,
+ SPELL_POUND = 53472,
+ SPELL_POUND_H = 59433,
+ SPELL_SUBMERGE = 53421,
+ SPELL_IMPALE_DMG = 53454,
+ SPELL_IMPALE_DMG_H = 59446,
+ SPELL_IMPALE_SHAKEGROUND = 53455,
+ SPELL_IMPALE_SPIKE = 53539, //this is not the correct visual effect
+ //SPELL_IMPALE_TARGET = 53458,
+};
+
+enum Creatures
+{
+ CREATURE_GUARDIAN = 29216,
+ CREATURE_VENOMANCER = 29217,
+ CREATURE_DATTER = 29213,
+ CREATURE_IMPALE_TARGET = 89,
+ DISPLAY_INVISIBLE = 11686
+};
+
+// not in db
+enum Yells
+{
+ SAY_INTRO = -1601010,
+ SAY_AGGRO = -1601000,
+ SAY_SLAY_1 = -1601001,
+ SAY_SLAY_2 = -1601002,
+ SAY_SLAY_3 = -1601003,
+ SAY_LOCUST_1 = -1601005,
+ SAY_LOCUST_2 = -1601006,
+ SAY_LOCUST_3 = -1601007,
+ SAY_SUBMERGE_1 = -1601008,
+ SAY_SUBMERGE_2 = -1601009,
+ SAY_DEATH = -1601004
+};
+
+enum
+{
+ ACHIEV_TIMED_START_EVENT = 20381,
+};
+
+enum Phases
+{
+ PHASE_MELEE = 0,
+ PHASE_UNDERGROUND = 1,
+ IMPALE_PHASE_TARGET = 0,
+ IMPALE_PHASE_ATTACK = 1,
+ IMPALE_PHASE_DMG = 2
+};
+
+const Position SpawnPoint[2] =
+{
+ { 550.7, 282.8, 224.3 },
+ { 551.1, 229.4, 224.3 },
+};
+
+const Position SpawnPointGuardian[2] =
+{
+ { 550.348633, 316.006805, 234.2947 },
+ { 550.188660, 324.264557, 237.7412 },
+};
+
+struct boss_anub_arakAI : public ScriptedAI
+{
+ boss_anub_arakAI(Creature *c) : ScriptedAI(c), lSummons(me)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance *pInstance;
+
+ bool bChanneling;
+ bool bGuardianSummoned;
+ bool bVenomancerSummoned;
+ bool bDatterSummoned;
+ uint8 uiPhase;
+ uint32 uiUndergroundPhase;
+ uint32 uiCarrionBeetlesTimer;
+ uint32 uiLeechingSwarmTimer;
+ uint32 uiPoundTimer;
+ uint32 uiSubmergeTimer;
+ uint32 uiUndergroundTimer;
+ uint32 uiVenomancerTimer;
+ uint32 uiDatterTimer;
+
+ uint32 uiImpaleTimer;
+ uint32 uiImpalePhase;
+ uint64 uiImpaleTarget;
+
+ SummonList lSummons;
+
+ void Reset()
+ {
+ uiCarrionBeetlesTimer = 8*IN_MILISECONDS;
+ uiLeechingSwarmTimer = 20*IN_MILISECONDS;
+ uiImpaleTimer = 9*IN_MILISECONDS;
+ uiPoundTimer = 15*IN_MILISECONDS;
+
+ uiPhase = PHASE_MELEE;
+ uiUndergroundPhase = 0;
+ bChanneling = false;
+ uiImpalePhase = IMPALE_PHASE_TARGET;
+
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveAura(SPELL_SUBMERGE);
+
+ lSummons.DespawnAll();
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_ANUBARAK_EVENT, NOT_STARTED);
+ pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ }
+ }
+
+ Creature* DoSummonImpaleTarget(Unit *pTarget)
+ {
+ Position targetPos;
+ pTarget->GetPosition(&targetPos);
+
+ if (TempSummon* pImpaleTarget = me->SummonCreature(CREATURE_IMPALE_TARGET, targetPos, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 6*IN_MILISECONDS))
+ {
+ uiImpaleTarget = pImpaleTarget->GetGUID();
+ pImpaleTarget->SetReactState(REACT_PASSIVE);
+ pImpaleTarget->SetDisplayId(DISPLAY_INVISIBLE);
+ pImpaleTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE|UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ return pImpaleTarget;
+ }
+
+ return NULL;
+ }
+
+ void EnterCombat(Unit * /*pWho*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_ANUBARAK_EVENT, IN_PROGRESS);
+ pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ switch (uiPhase)
+ {
+ case PHASE_UNDERGROUND:
+ if (uiImpaleTimer <= diff)
+ {
+ switch(uiImpalePhase)
+ {
+ case IMPALE_PHASE_TARGET:
+ if (Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ {
+ if (Creature *pImpaleTarget = DoSummonImpaleTarget(target))
+ pImpaleTarget->CastSpell(pImpaleTarget, SPELL_IMPALE_SHAKEGROUND, true);
+ uiImpaleTimer = 3*IN_MILISECONDS;
+ uiImpalePhase = IMPALE_PHASE_ATTACK;
+ }
+ break;
+ case IMPALE_PHASE_ATTACK:
+ if (Creature* pImpaleTarget = Unit::GetCreature(*me, uiImpaleTarget))
+ {
+ pImpaleTarget->CastSpell(pImpaleTarget, SPELL_IMPALE_SPIKE, false);
+ pImpaleTarget->RemoveAurasDueToSpell(SPELL_IMPALE_SHAKEGROUND);
+ }
+ uiImpalePhase = IMPALE_PHASE_DMG;
+ uiImpaleTimer = 1*IN_MILISECONDS;
+ break;
+ case IMPALE_PHASE_DMG:
+ if (Creature* pImpaleTarget = Unit::GetCreature(*me, uiImpaleTarget))
+ me->CastSpell(pImpaleTarget, DUNGEON_MODE(SPELL_IMPALE_DMG, SPELL_IMPALE_DMG_H), true);
+ uiImpalePhase = IMPALE_PHASE_TARGET;
+ uiImpaleTimer = 9*IN_MILISECONDS;
+ break;
+ }
+ } else uiImpaleTimer -= diff;
+
+ if (!bGuardianSummoned)
+ {
+ for (uint8 i = 0; i < 2; ++i)
+ {
+ if (Creature *Guardian = me->SummonCreature(CREATURE_GUARDIAN,SpawnPointGuardian[i],TEMPSUMMON_CORPSE_DESPAWN,0))
+ {
+ Guardian->AddThreat(me->getVictim(), 0.0f);
+ DoZoneInCombat(Guardian);
+ }
+ }
+ bGuardianSummoned = true;
+ }
+
+ if (!bVenomancerSummoned)
+ {
+ if (uiVenomancerTimer <= diff)
+ {
+ if (uiUndergroundPhase > 1)
+ {
+ for (uint8 i = 0; i < 2; ++i)
+ {
+ if (Creature *Venomancer = me->SummonCreature(CREATURE_VENOMANCER,SpawnPoint[i],TEMPSUMMON_CORPSE_DESPAWN,0))
+ {
+ Venomancer->AddThreat(me->getVictim(), 0.0f);
+ DoZoneInCombat(Venomancer);
+ }
+ }
+ bVenomancerSummoned = true;
+ }
+ } else uiVenomancerTimer -= diff;
+ }
+
+ if (!bDatterSummoned)
+ {
+ if (uiDatterTimer <= diff)
+ {
+ if (uiUndergroundPhase > 2)
+ {
+ for (uint8 i = 0; i < 2; ++i)
+ {
+ if (Creature *Datter = me->SummonCreature(CREATURE_DATTER,SpawnPoint[i],TEMPSUMMON_CORPSE_DESPAWN,0))
+ {
+ Datter->AddThreat(me->getVictim(), 0.0f);
+ DoZoneInCombat(Datter);
+ }
+ }
+ bDatterSummoned = true;
+ }
+ } else uiDatterTimer -= diff;
+ }
+
+ if (uiUndergroundTimer <= diff)
+ {
+ me->RemoveAura(SPELL_SUBMERGE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ uiPhase = PHASE_MELEE;
+ } else uiUndergroundTimer -= diff;
+ break;
+
+ case PHASE_MELEE:
+ if (((uiUndergroundPhase == 0 && HealthBelowPct(75))
+ || (uiUndergroundPhase == 1 && HealthBelowPct(50))
+ || (uiUndergroundPhase == 2 && HealthBelowPct(25)))
+ && !me->hasUnitState(UNIT_STAT_CASTING))
+ {
+ bGuardianSummoned = false;
+ bVenomancerSummoned = false;
+ bDatterSummoned = false;
+
+ uiUndergroundTimer = 40*IN_MILISECONDS;
+ uiVenomancerTimer = 25*IN_MILISECONDS;
+ uiDatterTimer = 32*IN_MILISECONDS;
+
+ uiImpalePhase = 0;
+ uiImpaleTimer = 9*IN_MILISECONDS;
+
+ DoCast(me, SPELL_SUBMERGE, false);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+
+ uiPhase = PHASE_UNDERGROUND;
+ ++uiUndergroundPhase;
+ }
+
+ if (bChanneling == true)
+ {
+ for (uint8 i = 0; i < 8; ++i)
+ DoCast(me->getVictim(), SPELL_SUMMON_CARRION_BEETLES, true);
+ bChanneling = false;
+ }
+ else if (uiCarrionBeetlesTimer <= diff)
+ {
+ bChanneling = true;
+ DoCastVictim(SPELL_CARRION_BEETLES);
+ uiCarrionBeetlesTimer = 25*IN_MILISECONDS;
+ } else uiCarrionBeetlesTimer -= diff;
+
+ if (uiLeechingSwarmTimer <= diff)
+ {
+ DoCast(me, SPELL_LEECHING_SWARM, true);
+ uiLeechingSwarmTimer = 19*IN_MILISECONDS;
+ } else uiLeechingSwarmTimer -= diff;
+
+ if (uiPoundTimer <= diff)
+ {
+ if (Unit *target = me->getVictim())
+ {
+ if (Creature *pImpaleTarget = DoSummonImpaleTarget(target))
+ me->CastSpell(pImpaleTarget, DUNGEON_MODE(SPELL_POUND, SPELL_POUND_H), false);
+ }
+ uiPoundTimer = 16.5*IN_MILISECONDS;
+ } else uiPoundTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ break;
+ }
+ }
+
+ void JustDied(Unit * /*pKiller*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ lSummons.DespawnAll();
+ if (pInstance)
+ pInstance->SetData(DATA_ANUBARAK_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit *pVictim)
+ {
+ if (pVictim == me)
+ return;
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ lSummons.Summon(summon);
+ }
+};
+
+CreatureAI* GetAI_boss_anub_arak(Creature *pCreature)
+{
+ return new boss_anub_arakAI (pCreature);
+}
+
+void AddSC_boss_anub_arak()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_anub_arak";
+ newscript->GetAI = &GetAI_boss_anub_arak;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_hadronox.cpp b/src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_hadronox.cpp
new file mode 100644
index 00000000000..0fc4e87d7c5
--- /dev/null
+++ b/src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_hadronox.cpp
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+* Comment: No Waves atm and the doors spells are crazy...
+*
+* When your group enters the main room (the one after the bridge), you will notice a group of 3 Nerubians.
+* When you engage them, 2 more groups like this one spawn behind the first one - it is important to pull the first group back,
+* so you don't aggro all 3. Hadronox will be under you, fighting Nerubians.
+*
+* This is the timed gauntlet - waves of non-elite spiders
+* will spawn from the 3 doors located a little above the main room, and will then head down to fight Hadronox. After clearing the
+* main room, it is recommended to just stay in it, kill the occasional non-elites that will attack you instead of the boss, and wait for
+* Hadronox to make his way to you. When Hadronox enters the main room, she will web the doors, and no more non-elites will spawn.
+*/
+
+#include "ScriptedPch.h"
+#include "azjol_nerub.h"
+
+enum Spells
+{
+ SPELL_ACID_CLOUD = 53400, // Victim
+ SPELL_LEECH_POISON = 53030, // Victim
+ SPELL_PIERCE_ARMOR = 53418, // Victim
+ SPELL_WEB_GRAB = 57731, // Victim
+ SPELL_WEB_FRONT_DOORS = 53177, // Self
+ SPELL_WEB_SIDE_DOORS = 53185, // Self
+ H_SPELL_ACID_CLOUD = 59419,
+ H_SPELL_LEECH_POISON = 59417,
+ H_SPELL_WEB_GRAB = 59421
+};
+
+struct boss_hadronoxAI : public ScriptedAI
+{
+ boss_hadronoxAI(Creature* c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ fMaxDistance = 50.0f;
+ bFirstTime = true;
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiAcidTimer;
+ uint32 uiLeechTimer;
+ uint32 uiPierceTimer;
+ uint32 uiGrabTimer;
+ uint32 uiDoorsTimer;
+ uint32 uiCheckDistanceTimer;
+
+ bool bFirstTime;
+
+ float fMaxDistance;
+
+ void Reset()
+ {
+ me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 9.0f);
+ me->SetFloatValue(UNIT_FIELD_COMBATREACH, 9.0f);
+
+ uiAcidTimer = urand(10*IN_MILISECONDS,14*IN_MILISECONDS);
+ uiLeechTimer = urand(3*IN_MILISECONDS,9*IN_MILISECONDS);
+ uiPierceTimer = urand(1*IN_MILISECONDS,3*IN_MILISECONDS);
+ uiGrabTimer = urand(15*IN_MILISECONDS,19*IN_MILISECONDS);
+ uiDoorsTimer = urand(20*IN_MILISECONDS,30*IN_MILISECONDS);
+ uiCheckDistanceTimer = 2*IN_MILISECONDS;
+
+ if (pInstance && (pInstance->GetData(DATA_HADRONOX_EVENT) != DONE && !bFirstTime))
+ pInstance->SetData(DATA_HADRONOX_EVENT, FAIL);
+
+ bFirstTime = false;
+ }
+
+ //when Hadronox kills any enemy (that includes a party member) she will regain 10% of her HP if the target had Leech Poison on
+ void KilledUnit(Unit* Victim)
+ {
+ // not sure if this aura check is correct, I think it is though
+ if (!Victim || !Victim->HasAura(DUNGEON_MODE(SPELL_LEECH_POISON, H_SPELL_LEECH_POISON)) || !me->isAlive())
+ return;
+
+ uint32 health = me->GetMaxHealth()/10;
+
+ if ((me->GetHealth()+health) >= me->GetMaxHealth())
+ me->SetHealth(me->GetMaxHealth());
+ else
+ me->SetHealth(me->GetHealth()+health);
+ }
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_HADRONOX_EVENT, DONE);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_HADRONOX_EVENT, IN_PROGRESS);
+ me->SetInCombatWithZone();
+ }
+
+ void CheckDistance(float dist, const uint32 uiDiff)
+ {
+ if (!me->isInCombat())
+ return;
+
+ float x=0.0f, y=0.0f, z=0.0f;
+ me->GetRespawnCoord(x,y,z);
+
+ if (uiCheckDistanceTimer <= uiDiff)
+ uiCheckDistanceTimer = 5*IN_MILISECONDS;
+ else
+ {
+ uiCheckDistanceTimer -= uiDiff;
+ return;
+ }
+ if (me->IsInEvadeMode() || !me->getVictim())
+ return;
+ if (me->GetDistance(x,y,z) > dist)
+ EnterEvadeMode();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim()) return;
+
+ // Without he comes up through the air to players on the bridge after krikthir if players crossing this bridge!
+ CheckDistance(fMaxDistance, diff);
+
+ if (me->HasAura(SPELL_WEB_FRONT_DOORS) || me->HasAura(SPELL_WEB_SIDE_DOORS))
+ {
+ if (IsCombatMovement())
+ SetCombatMovement(false);
+ }
+ else if (!IsCombatMovement())
+ SetCombatMovement(true);
+
+ if (uiPierceTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_PIERCE_ARMOR);
+ uiPierceTimer = 8*IN_MILISECONDS;
+ } else uiPierceTimer -= diff;
+
+ if (uiAcidTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_ACID_CLOUD);
+
+ uiAcidTimer = urand(20*IN_MILISECONDS,30*IN_MILISECONDS);
+ } else uiAcidTimer -= diff;
+
+ if (uiLeechTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_LEECH_POISON);
+
+ uiLeechTimer = urand(11*IN_MILISECONDS,14*IN_MILISECONDS);
+ } else uiLeechTimer -= diff;
+
+ if (uiGrabTimer <= diff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) // Draws all players (and attacking Mobs) to itself.
+ DoCast(pTarget, SPELL_WEB_GRAB);
+
+ uiGrabTimer = urand(15*IN_MILISECONDS,30*IN_MILISECONDS);
+ } else uiGrabTimer -= diff;
+
+ if (uiDoorsTimer <= diff)
+ {
+ //DoCast(me, RAND(SPELL_WEB_FRONT_DOORS, SPELL_WEB_SIDE_DOORS));
+ uiDoorsTimer = urand(30*IN_MILISECONDS,60*IN_MILISECONDS);
+ } else uiDoorsTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_hadronox(Creature* pCreature)
+{
+ return new boss_hadronoxAI (pCreature);
+}
+
+void AddSC_boss_hadronox()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_hadronox";
+ newscript->GetAI = &GetAI_boss_hadronox;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp b/src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp
new file mode 100644
index 00000000000..4863bdcb032
--- /dev/null
+++ b/src/server/scripts/northrend/azjol_nerub/azjol_nerub/boss_krikthir_the_gatewatcher.cpp
@@ -0,0 +1,553 @@
+/*
+ * Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Comment: Find in the future best timers and the event is not implemented.
+ */
+
+#include "ScriptedPch.h"
+#include "azjol_nerub.h"
+
+enum Spells
+{
+ SPELL_MIND_FLAY = 52586,
+ H_SPELL_MIND_FLAY = 59367,
+ SPELL_CURSE_OF_FATIGUE = 52592,
+ H_SPELL_CURSE_OF_FATIGUE = 59368,
+ SPELL_FRENZY = 28747, //maybe 53361
+ SPELL_SUMMON_SKITTERING_SWARMER = 52438, //AOE Effect 140, maybe 52439
+ SPELL_SUMMON_SKITTERING_SWARMER_1 = 52439, //Summon 3x 28735
+ H_SPELL_ACID_SPLASH = 59363,
+ SPELL_ACID_SPLASH = 52446,
+ SPELL_CHARGE = 16979,//maybe is another spell
+ SPELL_BACKSTAB = 52540,
+ SPELL_SHADOW_BOLT = 52534,
+ H_SPELL_SHADOW_BOLT = 59357,
+ SPELL_SHADOW_NOVA = 52535,
+ H_SPELL_SHADOW_NOVA = 59358,
+ SPELL_STRIKE = 52532,
+ SPELL_CLEAVE = 49806,
+ SPELL_ENRAGE = 52470,
+ SPELL_INFECTED_BITE = 52469,
+ H_SPELL_INFECTED_BITE = 59364,
+ SPELL_WEB_WRAP = 52086,//the spell is not working properly
+ SPELL_BLINDING_WEBS = 52524,
+ H_SPELL_BLINDING_WEBS = 59365,
+ SPELL_POSION_SPRAY = 52493,
+ H_SPELL_POSION_SPRAY = 59366
+};
+
+enum Mobs
+{
+ MOB_SKITTERING_SWARMER = 28735,
+ MOB_SKITTERING_SWARMER_CONTROLLER = 32593,
+ MOB_SKITTERING_INFECTIOR = 28736
+};
+
+enum Yells
+{
+ SAY_AGGRO = -1601011,
+ SAY_SLAY_1 = -1601012,
+ SAY_SLAY_2 = -1601013,
+ SAY_DEATH = -1601014,
+ //Not in db
+ SAY_SEND_GROUP_1 = -1601020,
+ SAY_SEND_GROUP_2 = -1601021,
+ SAY_SEND_GROUP_3 = -1601022,
+ SAY_SWARM_1 = -1601015,
+ SAY_SWARM_2 = -1601016,
+ SAY_PREFIGHT_1 = -1601017,
+ SAY_PREFIGHT_2 = -1601018,
+ SAY_PREFIGHT_3 = -1601019
+};
+
+enum Misc
+{
+ ACHIEV_WATH_HIM_DIE = 1296
+};
+
+const Position SpawnPoint[] =
+{
+ { 566.164, 682.087, 769.079, 2.21657 },
+ { 529.042, 706.941, 777.298, 1.0821 },
+ { 489.975, 671.239, 772.131, 0.261799 },
+ { 488.556, 692.95, 771.764, 4.88692 },
+ { 553.34, 640.387, 777.419, 1.20428 },
+ { 517.486, 706.398, 777.335, 5.35816 },
+ { 504.01, 637.693, 777.479, 0.506145 },
+ { 552.625, 706.408, 777.177, 3.4383 }
+};
+struct boss_krik_thirAI : public ScriptedAI
+{
+ boss_krik_thirAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiMindFlayTimer;
+ uint32 uiCurseFatigueTimer;
+ uint32 uiSummonTimer;
+
+ void Reset()
+ {
+ uiMindFlayTimer = 15*IN_MILISECONDS;
+ uiCurseFatigueTimer = 12*IN_MILISECONDS;
+
+ if (pInstance)
+ pInstance->SetData(DATA_KRIKTHIR_THE_GATEWATCHER_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ Summon();
+ uiSummonTimer = 15*IN_MILISECONDS;
+
+ if (pInstance)
+ pInstance->SetData(DATA_KRIKTHIR_THE_GATEWATCHER_EVENT, IN_PROGRESS);
+ }
+
+ void Summon()
+ {
+ me->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[0],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[0],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[1],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[1],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[2],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[2],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[3],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[3],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_INFECTIOR,SpawnPoint[4],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[4],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_INFECTIOR,SpawnPoint[5],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[5],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_INFECTIOR,SpawnPoint[6],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[6],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[7],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ me->SummonCreature(MOB_SKITTERING_SWARMER,SpawnPoint[7],TEMPSUMMON_TIMED_DESPAWN,25*IN_MILISECONDS);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiSummonTimer <= diff)
+ {
+ Summon();
+ uiSummonTimer = 15*IN_MILISECONDS;
+ } else uiSummonTimer -= diff;
+
+ if (uiMindFlayTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_MIND_FLAY);
+ uiMindFlayTimer = 15*IN_MILISECONDS;
+ } else uiMindFlayTimer -= diff;
+
+ if (uiCurseFatigueTimer <= diff)
+ {
+ //WowWiki say "Curse of Fatigue-Kirk'thir will cast Curse of Fatigue on 2-3 targets periodically."
+ Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
+ Unit *pTarget_1 = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true);
+
+ DoCast(pTarget, SPELL_CURSE_OF_FATIGUE);
+ DoCast(pTarget_1, SPELL_CURSE_OF_FATIGUE);
+
+ uiCurseFatigueTimer = 10*IN_MILISECONDS;
+ } else uiCurseFatigueTimer -= diff;
+
+ if (!me->HasAura(SPELL_FRENZY) && HealthBelowPct(10))
+ DoCast(me, SPELL_FRENZY, true);
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (!pInstance)
+ return;
+
+ pInstance->SetData(DATA_KRIKTHIR_THE_GATEWATCHER_EVENT, DONE);
+ //Achievement: Watch him die
+ Creature *pAdd = Unit::GetCreature(*me, pInstance->GetData64(DATA_WATCHER_GASHRA));
+ if (!pAdd || !pAdd->isAlive())
+ return;
+
+ pAdd = Unit::GetCreature(*me, pInstance->GetData64(DATA_WATCHER_SILTHIK));
+ if (!pAdd || !pAdd->isAlive())
+ return;
+
+ pAdd = Unit::GetCreature(*me, pInstance->GetData64(DATA_WATCHER_NARJIL));
+ if (!pAdd || !pAdd->isAlive())
+ return;
+
+ pInstance->DoCompleteAchievement(ACHIEV_WATH_HIM_DIE);
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ summoned->GetMotionMaster()->MovePoint(0,me->GetPositionX(),me->GetPositionY(),me->GetPositionZ());
+ }
+};
+
+struct npc_skittering_infectorAI : public ScriptedAI
+{
+ npc_skittering_infectorAI(Creature *c) : ScriptedAI(c) {}
+
+ void JustDied(Unit* /*killer*/)
+ {
+ //The spell is not working propperly
+ DoCast(me->getVictim(),SPELL_ACID_SPLASH, true);
+ }
+
+};
+
+struct npc_anub_ar_skirmisherAI : public ScriptedAI
+{
+ npc_anub_ar_skirmisherAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 uiChargeTimer;
+ uint32 uiBackstabTimer;
+
+ void Reset()
+ {
+ uiChargeTimer = 11*IN_MILISECONDS;
+ uiBackstabTimer = 7*IN_MILISECONDS;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiChargeTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ {
+ DoResetThreat();
+ me->AddThreat(pTarget,1.0f);
+ DoCast(pTarget, SPELL_CHARGE, true);
+ }
+ uiChargeTimer = 15*IN_MILISECONDS;
+ } else uiChargeTimer -= diff;
+
+ if (uiBackstabTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_BACKSTAB);
+ uiBackstabTimer = 12*IN_MILISECONDS;
+ } else uiBackstabTimer -= diff;
+
+ DoMeleeAttackIfReady();
+
+ }
+};
+
+struct npc_anub_ar_shadowcasterAI : public ScriptedAI
+{
+ npc_anub_ar_shadowcasterAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 uiShadowBoltTimer;
+ uint32 uiShadowNovaTimer;
+
+ void Reset()
+ {
+ uiShadowBoltTimer = 6*IN_MILISECONDS;
+ uiShadowNovaTimer = 15*IN_MILISECONDS;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiShadowBoltTimer <= diff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_SHADOW_BOLT, true);
+ uiShadowBoltTimer = 15*IN_MILISECONDS;
+ } else uiShadowBoltTimer -= diff;
+
+ if (uiShadowNovaTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_SHADOW_NOVA, true);
+ uiShadowNovaTimer = 17*IN_MILISECONDS;
+ } else uiShadowNovaTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct npc_anub_ar_warriorAI : public ScriptedAI
+{
+ npc_anub_ar_warriorAI(Creature *c) : ScriptedAI(c){}
+
+ uint32 uiCleaveTimer;
+ uint32 uiStrikeTimer;
+
+ void Reset()
+ {
+ uiCleaveTimer = 11*IN_MILISECONDS;
+ uiStrikeTimer = 6*IN_MILISECONDS;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiStrikeTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_STRIKE, true);
+ uiStrikeTimer = 15*IN_MILISECONDS;
+ } else uiStrikeTimer -= diff;
+
+ if (uiCleaveTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_CLEAVE, true);
+ uiCleaveTimer = 17*IN_MILISECONDS;
+ } else uiCleaveTimer -= diff;
+
+ DoMeleeAttackIfReady();
+
+ }
+
+};
+
+struct npc_watcher_gashraAI : public ScriptedAI
+{
+ npc_watcher_gashraAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 uiWebWrapTimer;
+ uint32 uiInfectedBiteTimer;
+
+ void Reset()
+ {
+ uiWebWrapTimer = 11*IN_MILISECONDS;
+ uiInfectedBiteTimer = 4*IN_MILISECONDS;
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoCast(me, SPELL_ENRAGE, true);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiWebWrapTimer <= diff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_WEB_WRAP, true);
+ uiWebWrapTimer = 17*IN_MILISECONDS;
+ } else uiWebWrapTimer -= diff;
+
+ if (uiInfectedBiteTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_INFECTED_BITE, true);
+ uiInfectedBiteTimer = 15*IN_MILISECONDS;
+ } else uiInfectedBiteTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct npc_watcher_narjilAI : public ScriptedAI
+{
+ npc_watcher_narjilAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 uiWebWrapTimer;
+ uint32 uiInfectedBiteTimer;
+ uint32 uiBindingWebsTimer;
+
+ void Reset()
+ {
+ uiWebWrapTimer = 11*IN_MILISECONDS;
+ uiInfectedBiteTimer = 4*IN_MILISECONDS;
+ uiBindingWebsTimer = 17*IN_MILISECONDS;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiWebWrapTimer <= diff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_WEB_WRAP, true);
+ uiWebWrapTimer = 15*IN_MILISECONDS;
+ } else uiWebWrapTimer -= diff;
+
+ if (uiInfectedBiteTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_INFECTED_BITE, true);
+ uiInfectedBiteTimer = 11*IN_MILISECONDS;
+ } else uiInfectedBiteTimer -= diff;
+
+ if (uiBindingWebsTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_BLINDING_WEBS, true);
+ uiBindingWebsTimer = 17*IN_MILISECONDS;
+ } else uiBindingWebsTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct npc_watcher_silthikAI : public ScriptedAI
+{
+ npc_watcher_silthikAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 uiWebWrapTimer;
+ uint32 uiInfectedBiteTimer;
+ uint32 uiPoisonSprayTimer;
+
+ void Reset()
+ {
+ uiWebWrapTimer = 11*IN_MILISECONDS;
+ uiInfectedBiteTimer = 4*IN_MILISECONDS;
+ uiPoisonSprayTimer = 15*IN_MILISECONDS;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiWebWrapTimer <= diff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_WEB_WRAP, true);
+
+ uiWebWrapTimer = 15*IN_MILISECONDS;
+ } else uiWebWrapTimer -= diff;
+
+ if (uiInfectedBiteTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_INFECTED_BITE, true);
+ uiInfectedBiteTimer = 15*IN_MILISECONDS;
+ } else uiInfectedBiteTimer -= diff;
+
+ if (uiPoisonSprayTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_POSION_SPRAY, true);
+ uiPoisonSprayTimer = 17*IN_MILISECONDS;
+ } else uiPoisonSprayTimer -= diff;
+
+ DoMeleeAttackIfReady();
+
+ }
+};
+
+CreatureAI* GetAI_boss_krik_thir(Creature* pCreature)
+{
+ return new boss_krik_thirAI (pCreature);
+}
+
+CreatureAI* GetAI_npc_anub_ar_skirmisher (Creature* pCreature)
+{
+ return new npc_anub_ar_skirmisherAI (pCreature);
+}
+
+CreatureAI* GetAI_npc_skittering_infector (Creature* pCreature)
+{
+ return new npc_skittering_infectorAI (pCreature);
+}
+
+CreatureAI* GetAI_npc_anub_ar_shadowcaster (Creature* pCreature)
+{
+ return new npc_anub_ar_shadowcasterAI (pCreature);
+}
+
+CreatureAI* GetAI_npc_anub_ar_warrior (Creature* pCreature)
+{
+ return new npc_anub_ar_warriorAI (pCreature);
+}
+
+CreatureAI* GetAI_npc_watcher_gashra (Creature* pCreature)
+{
+ return new npc_watcher_gashraAI (pCreature);
+}
+
+CreatureAI* GetAI_npc_watcher_narjil (Creature* pCreature)
+{
+ return new npc_watcher_narjilAI (pCreature);
+}
+
+CreatureAI* GetAI_npc_watcher_silthik (Creature* pCreature)
+{
+ return new npc_watcher_silthikAI (pCreature);
+}
+
+void AddSC_boss_krik_thir()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_krik_thir";
+ newscript->GetAI = &GetAI_boss_krik_thir;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_skittering_infector";
+ newscript->GetAI = &GetAI_npc_skittering_infector;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_anub_ar_skirmisher";
+ newscript->GetAI = &GetAI_npc_anub_ar_skirmisher;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_anub_ar_shadowcaster";
+ newscript->GetAI = &GetAI_npc_anub_ar_shadowcaster;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_watcher_gashra";
+ newscript->GetAI = &GetAI_npc_watcher_gashra;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_anub_ar_warrior";
+ newscript->GetAI = &GetAI_npc_anub_ar_warrior;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_watcher_silthik";
+ newscript->GetAI = &GetAI_npc_watcher_silthik;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_watcher_narjil";
+ newscript->GetAI = &GetAI_npc_watcher_narjil;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp b/src/server/scripts/northrend/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp
new file mode 100644
index 00000000000..d12dbd604ba
--- /dev/null
+++ b/src/server/scripts/northrend/azjol_nerub/azjol_nerub/instance_azjol_nerub.cpp
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "azjol_nerub.h"
+
+#define MAX_ENCOUNTER 3
+
+/* Azjol Nerub encounters:
+0 - Krik'thir the Gatewatcher
+1 - Hadronox
+2 - Anub'arak
+*/
+
+struct instance_azjol_nerub : public ScriptedInstance
+{
+ instance_azjol_nerub(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+
+ uint64 uiKrikthir;
+ uint64 uiHadronox;
+ uint64 uiAnubarak;
+ uint64 uiWatcherGashra;
+ uint64 uiWatcherSilthik;
+ uint64 uiWatcherNarjil;
+ uint64 uiAnubarakDoor[3];
+
+ uint64 uiKrikthirDoor;
+
+ uint32 auiEncounter[MAX_ENCOUNTER];
+
+ void Initialize()
+ {
+ memset(&auiEncounter, 0, sizeof(auiEncounter));
+ memset(&uiAnubarakDoor, 0, sizeof(uiAnubarakDoor));
+
+ uiKrikthir = 0;
+ uiHadronox = 0;
+ uiAnubarak = 0;
+ uiWatcherGashra = 0;
+ uiWatcherSilthik = 0;
+ uiWatcherNarjil = 0;
+ uiKrikthirDoor = 0;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (auiEncounter[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool /*add*/)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case 28684: uiKrikthir = pCreature->GetGUID(); break;
+ case 28921: uiHadronox = pCreature->GetGUID(); break;
+ case 29120: uiAnubarak = pCreature->GetGUID(); break;
+ case 28730: uiWatcherGashra = pCreature->GetGUID(); break;
+ case 28731: uiWatcherSilthik = pCreature->GetGUID(); break;
+ case 28729: uiWatcherNarjil = pCreature->GetGUID(); break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
+ {
+ switch (pGo->GetEntry())
+ {
+ case 192395:
+ uiKrikthirDoor = pGo->GetGUID();
+ if (auiEncounter[0] == DONE)
+ HandleGameObject(NULL,true,pGo);
+ break;
+ case 192396:
+ uiAnubarakDoor[0] = pGo->GetGUID();
+ break;
+ case 192397:
+ uiAnubarakDoor[1] = pGo->GetGUID();
+ break;
+ case 192398:
+ uiAnubarakDoor[2] = pGo->GetGUID();
+ break;
+ }
+ }
+
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_KRIKTHIR_THE_GATEWATCHER: return uiKrikthir;
+ case DATA_HADRONOX: return uiHadronox;
+ case DATA_ANUBARAK: return uiAnubarak;
+ case DATA_WATCHER_GASHRA: return uiWatcherGashra;
+ case DATA_WATCHER_SILTHIK: return uiWatcherSilthik;
+ case DATA_WATCHER_NARJIL: return uiWatcherNarjil;
+ }
+
+ return 0;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_KRIKTHIR_THE_GATEWATCHER_EVENT:
+ auiEncounter[0] = data;
+ if (data == DONE)
+ HandleGameObject(uiKrikthirDoor,true);
+ break;
+ case DATA_HADRONOX_EVENT:
+ auiEncounter[1] = data;
+ break;
+ case DATA_ANUBARAK_EVENT:
+ auiEncounter[2] = data;
+ if (data == IN_PROGRESS)
+ for (uint8 i = 0; i < 3; ++i)
+ HandleGameObject(uiAnubarakDoor[i], false);
+ else if (data == NOT_STARTED || data == DONE)
+ for (uint8 i = 0; i < 3; ++i)
+ HandleGameObject(uiAnubarakDoor[i], true);
+ break;
+ }
+
+ if (data == DONE)
+ {
+ SaveToDB();
+ }
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_KRIKTHIR_THE_GATEWATCHER_EVENT: return auiEncounter[0];
+ case DATA_HADRONOX_EVENT: return auiEncounter[1];
+ case DATA_ANUBARAK_EVENT: return auiEncounter[2];
+ }
+
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "A N " << auiEncounter[0] << " " << auiEncounter[1] << " "
+ << auiEncounter[2];
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return saveStream.str();
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0,data1,data2;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2;
+
+ if (dataHead1 == 'A' && dataHead2 == 'N')
+ {
+ auiEncounter[0] = data0;
+ auiEncounter[1] = data1;
+ auiEncounter[2] = data2;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (auiEncounter[i] == IN_PROGRESS)
+ auiEncounter[i] = NOT_STARTED;
+
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_azjol_nerub(Map* pMap)
+{
+ return new instance_azjol_nerub(pMap);
+}
+
+void AddSC_instance_azjol_nerub()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_azjol_nerub";
+ newscript->GetInstanceData = &GetInstanceData_instance_azjol_nerub;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/borean_tundra.cpp b/src/server/scripts/northrend/borean_tundra.cpp
new file mode 100644
index 00000000000..19d82dc9044
--- /dev/null
+++ b/src/server/scripts/northrend/borean_tundra.cpp
@@ -0,0 +1,2323 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Borean_Tundra
+SD%Complete: 100
+SDComment: Quest support: 11708. Taxi vendors.
+SDCategory: Borean Tundra
+EndScriptData */
+
+/* ContentData
+npc_iruk
+npc_corastrasza
+npc_jenny
+npc_sinkhole_kill_credit
+npc_khunok_the_behemoth
+npc_scourge_prisoner
+mob_nerubar_victim
+npc_keristrasza
+npc_nesingwary_trapper
+npc_lurgglbr
+npc_nexus_drake_hatchling
+EndContentData */
+
+#include "ScriptedPch.h"
+#include "ScriptedEscortAI.h"
+#include "ScriptedFollowerAI.h"
+
+/*######
+## npc_sinkhole_kill_credit
+######*/
+
+enum eSinkhole
+{
+ SPELL_SET_CART = 46797,
+ SPELL_EXPLODE_CART = 46799,
+ SPELL_SUMMON_CART = 46798,
+ SPELL_SUMMON_WORM = 46800,
+};
+
+struct npc_sinkhole_kill_creditAI : public ScriptedAI
+{
+ npc_sinkhole_kill_creditAI(Creature* c) : ScriptedAI(c){}
+
+ uint32 uiPhaseTimer;
+ uint8 Phase;
+ uint64 casterGuid;
+
+ void Reset()
+ {
+ uiPhaseTimer = 500;
+ Phase = 0;
+ casterGuid = 0;
+ }
+
+ void SpellHit(Unit *caster, const SpellEntry *spell)
+ {
+ if (Phase)
+ return;
+
+ if (spell->Id == SPELL_SET_CART && caster->GetTypeId() == TYPEID_PLAYER
+ && CAST_PLR(caster)->GetQuestStatus(11897) == QUEST_STATUS_INCOMPLETE)
+ {
+ Phase = 1;
+ casterGuid = caster->GetGUID();
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/){}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!Phase)
+ return;
+
+ if (uiPhaseTimer <= diff)
+ {
+ switch (Phase)
+ {
+ case 1:
+ DoCast(me, SPELL_EXPLODE_CART, true);
+ DoCast(me, SPELL_SUMMON_CART, true);
+ if (GameObject* cart = me->FindNearestGameObject(188160,3))
+ cart->SetUInt32Value(GAMEOBJECT_FACTION, 14);
+ uiPhaseTimer = 3000;
+ Phase = 2;
+ break;
+ case 2:
+ if (GameObject* cart = me->FindNearestGameObject(188160,3))
+ cart->UseDoorOrButton();
+ DoCast(me, SPELL_EXPLODE_CART, true);
+ uiPhaseTimer = 3000;
+ Phase = 3;
+ break;
+ case 3:
+ DoCast(me, SPELL_EXPLODE_CART, true);
+ uiPhaseTimer = 2000;
+ Phase = 4;
+ case 5:
+ DoCast(me, SPELL_SUMMON_WORM, true);
+ if (Unit* worm = me->FindNearestCreature(26250, 3))
+ {
+ worm->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ worm->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
+ }
+ uiPhaseTimer = 1000;
+ Phase = 6;
+ break;
+ case 6:
+ DoCast(me, SPELL_EXPLODE_CART, true);
+ if (Unit* worm = me->FindNearestCreature(26250, 3))
+ {
+ me->Kill(worm);
+ worm->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ uiPhaseTimer = 2000;
+ Phase = 7;
+ break;
+ case 7:
+ DoCast(me, SPELL_EXPLODE_CART, true);
+ if (Player *caster = Unit::GetPlayer(casterGuid))
+ caster->KilledMonster(me->GetCreatureInfo(),me->GetGUID());
+ uiPhaseTimer = 5000;
+ Phase = 8;
+ break;
+ case 8:
+ EnterEvadeMode();
+ break;
+ }
+ } else uiPhaseTimer -= diff;
+
+ }
+
+};
+
+CreatureAI* GetAI_npc_sinkhole_kill_credit(Creature* pCreature)
+{
+ return new npc_sinkhole_kill_creditAI(pCreature);
+}
+
+/*######
+## npc_khunok_the_behemoth
+######*/
+
+struct npc_khunok_the_behemothAI : public ScriptedAI
+{
+ npc_khunok_the_behemothAI(Creature *c) : ScriptedAI(c) {}
+
+ void MoveInLineOfSight(Unit *who)
+ {
+ ScriptedAI::MoveInLineOfSight(who);
+
+ if (who->GetTypeId() != TYPEID_UNIT)
+ return;
+
+ if (who->GetEntry() == 25861 && me->IsWithinDistInMap(who, 10.0f))
+ {
+ if (Unit *owner = who->GetOwner())
+ {
+ if (owner->GetTypeId() == TYPEID_PLAYER)
+ {
+ owner->CastSpell(owner, 46231, true);
+ CAST_CRE(who)->ForcedDespawn();
+ }
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_khunok_the_behemoth(Creature* pCreature)
+{
+ return new npc_khunok_the_behemothAI(pCreature);
+}
+
+/*######
+## npc_keristrasza
+######*/
+
+enum eKeristrasza
+{
+ SPELL_TELEPORT_TO_SARAGOSA = 46772
+};
+
+#define GOSSIP_HELLO_KERI "I am prepared to face Saragosa!"
+
+bool GossipHello_npc_keristrasza(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(11957) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_KERI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_keristrasza(Player* pPlayer, Creature* /*pCreature*/, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF + 1)
+ {
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_TELEPORT_TO_SARAGOSA, true);
+ }
+
+ return true;
+}
+
+/*######
+## npc_corastrasza
+######*/
+
+#define GOSSIP_ITEM_C_1 "I... I think so..."
+
+enum eCorastrasza
+{
+ SPELL_SUMMON_WYRMREST_SKYTALON = 61240,
+ SPELL_WYRMREST_SKYTALON_RIDE_PERIODIC = 61244,
+
+ QUEST_ACES_HIGH_DAILY = 13414,
+ QUEST_ACES_HIGH = 13413
+};
+
+bool GossipHello_npc_corastrasza(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_ACES_HIGH) == QUEST_STATUS_INCOMPLETE || pPlayer->GetQuestStatus(QUEST_ACES_HIGH_DAILY) == QUEST_STATUS_INCOMPLETE) //It's the same dragon for both quests.
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_C_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_corastrasza(Player* pPlayer, Creature* /*pCreature*/, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ pPlayer->CLOSE_GOSSIP_MENU();
+
+ pPlayer->CastSpell(pPlayer, SPELL_SUMMON_WYRMREST_SKYTALON, true);
+ pPlayer->CastSpell(pPlayer, SPELL_WYRMREST_SKYTALON_RIDE_PERIODIC, true);
+
+ }
+
+ return true;
+}
+
+/*######
+## npc_iruk
+######*/
+
+#define GOSSIP_ITEM_I "<Search corpse for Issliruk's Totem.>"
+
+enum eIruk
+{
+ QUEST_SPIRITS_WATCH_OVER_US = 11961,
+ SPELL_CREATURE_TOTEM_OF_ISSLIRUK = 46816,
+ GOSSIP_TEXT_I = 12585
+};
+
+bool GossipHello_npc_iruk(Player* pPlayer, Creature* pCreature)
+{
+
+ if (pPlayer->GetQuestStatus(QUEST_SPIRITS_WATCH_OVER_US) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_I, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXT_I, pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_iruk(Player* pPlayer, Creature* /*pCreature*/, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch (uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->CastSpell(pPlayer, SPELL_CREATURE_TOTEM_OF_ISSLIRUK, true);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+
+ }
+ return true;
+}
+/*######
+## mob_nerubar_victim
+######*/
+
+#define WARSONG_PEON 25270
+
+const uint32 nerubarVictims[3] =
+{
+ 45526, 45527, 45514
+};
+struct mob_nerubar_victimAI : public ScriptedAI
+{
+ mob_nerubar_victimAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit * /*who*/) {}
+ void MoveInLineOfSight(Unit * /*who*/) {}
+
+ void JustDied(Unit* Killer)
+ {
+ if (Killer->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (CAST_PLR(Killer)->GetQuestStatus(11611) == QUEST_STATUS_INCOMPLETE)
+ {
+ uint8 uiRand = urand(0,99);
+ if (uiRand < 25)
+ {
+ Killer->CastSpell(me,45532,true);
+ CAST_PLR(Killer)->KilledMonsterCredit(WARSONG_PEON, 0);
+ }
+ else if (uiRand < 75)
+ Killer->CastSpell(me, nerubarVictims[urand(0,2)], true);
+ }
+ }
+ }
+};
+CreatureAI* GetAI_mob_nerubar_victim(Creature *pCreature)
+{
+ return new mob_nerubar_victimAI (pCreature);
+}
+/*######
+## npc_scourge_prisoner
+######*/
+
+enum eScourgePrisoner
+{
+ GO_SCOURGE_CAGE = 187867
+};
+
+struct npc_scourge_prisonerAI : public ScriptedAI
+{
+ npc_scourge_prisonerAI(Creature* pCreature) : ScriptedAI (pCreature){}
+
+ void Reset()
+ {
+ me->SetReactState(REACT_PASSIVE);
+
+ if (GameObject* pGO = me->FindNearestGameObject(GO_SCOURGE_CAGE,5.0f))
+ if (pGO->GetGoState() == GO_STATE_ACTIVE)
+ pGO->SetGoState(GO_STATE_READY);
+ }
+
+};
+CreatureAI* GetAI_npc_scourge_prisoner(Creature* pCreature)
+{
+ return new npc_scourge_prisonerAI(pCreature);
+}
+
+/*######
+## npc_jenny
+######*/
+enum eJenny
+{
+ QUEST_LOADER_UP = 11881,
+
+ NPC_FEZZIX_GEARTWIST = 25849,
+ NPC_JENNY = 25969,
+
+ SPELL_GIVE_JENNY_CREDIT = 46358,
+ SPELL_CRATES_CARRIED = 46340,
+ SPELL_DROP_CRATE = 46342
+};
+
+struct npc_jennyAI : public ScriptedAI
+{
+ npc_jennyAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ bool setCrateNumber;
+
+ void Reset()
+ {
+ if (!setCrateNumber)
+ setCrateNumber = true;
+
+ me->SetReactState(REACT_PASSIVE);
+
+ switch (CAST_PLR(me->GetOwner())->GetTeamId())
+ {
+ case TEAM_ALLIANCE:
+ me->setFaction(FACTION_ESCORT_A_NEUTRAL_ACTIVE);
+ break;
+ default:
+ case TEAM_HORDE:
+ me->setFaction(FACTION_ESCORT_H_NEUTRAL_ACTIVE);
+ break;
+ }
+ }
+
+ void DamageTaken(Unit* /*pDone_by*/, uint32& /*uiDamage*/)
+ {
+ DoCast(me, SPELL_DROP_CRATE, true);
+ }
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ if (setCrateNumber)
+ {
+ me->AddAura(SPELL_CRATES_CARRIED,me);
+ setCrateNumber = false;
+ }
+
+ if (!setCrateNumber && !me->HasAura(SPELL_CRATES_CARRIED))
+ me->DisappearAndDie();
+
+ if (!UpdateVictim())
+ return;
+ }
+};
+
+CreatureAI* GetAI_npc_jenny(Creature *pCreature)
+{
+ return new npc_jennyAI (pCreature);
+}
+
+/*######
+## npc_fezzix_geartwist
+######*/
+
+struct npc_fezzix_geartwistAI : public ScriptedAI
+{
+ npc_fezzix_geartwistAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ ScriptedAI::MoveInLineOfSight(pWho);
+
+ if (pWho->GetTypeId() != TYPEID_UNIT)
+ return;
+
+ if (pWho->GetEntry() == NPC_JENNY && me->IsWithinDistInMap(pWho, 10.0f))
+ {
+ if (Unit* pOwner = pWho->GetOwner())
+ {
+ if (pOwner->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (pWho->HasAura(SPELL_CRATES_CARRIED))
+ {
+ pOwner->CastSpell(pOwner, SPELL_GIVE_JENNY_CREDIT, true); // Maybe is not working.
+ CAST_PLR(pOwner)->CompleteQuest(QUEST_LOADER_UP);
+ CAST_CRE(pWho)->DisappearAndDie();
+ }
+ }
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_fezzix_geartwist(Creature* pCreature)
+{
+ return new npc_fezzix_geartwistAI(pCreature);
+}
+
+/*######
+## npc_nesingwary_trapper
+######*/
+
+enum eNesingwaryTrapper
+{
+ GO_HIGH_QUALITY_FUR = 187983,
+
+ GO_CARIBOU_TRAP_1 = 187982,
+ GO_CARIBOU_TRAP_2 = 187995,
+ GO_CARIBOU_TRAP_3 = 187996,
+ GO_CARIBOU_TRAP_4 = 187997,
+ GO_CARIBOU_TRAP_5 = 187998,
+ GO_CARIBOU_TRAP_6 = 187999,
+ GO_CARIBOU_TRAP_7 = 188000,
+ GO_CARIBOU_TRAP_8 = 188001,
+ GO_CARIBOU_TRAP_9 = 188002,
+ GO_CARIBOU_TRAP_10 = 188003,
+ GO_CARIBOU_TRAP_11 = 188004,
+ GO_CARIBOU_TRAP_12 = 188005,
+ GO_CARIBOU_TRAP_13 = 188006,
+ GO_CARIBOU_TRAP_14 = 188007,
+ GO_CARIBOU_TRAP_15 = 188008,
+
+ SPELL_TRAPPED = 46104,
+};
+
+#define CaribouTrapsNum 15
+const uint32 CaribouTraps[CaribouTrapsNum] =
+{
+ GO_CARIBOU_TRAP_1, GO_CARIBOU_TRAP_2, GO_CARIBOU_TRAP_3, GO_CARIBOU_TRAP_4, GO_CARIBOU_TRAP_5,
+ GO_CARIBOU_TRAP_6, GO_CARIBOU_TRAP_7, GO_CARIBOU_TRAP_8, GO_CARIBOU_TRAP_9, GO_CARIBOU_TRAP_10,
+ GO_CARIBOU_TRAP_11, GO_CARIBOU_TRAP_12, GO_CARIBOU_TRAP_13, GO_CARIBOU_TRAP_14, GO_CARIBOU_TRAP_15,
+};
+//#define SAY_NESINGWARY_1 -1571008
+
+struct npc_nesingwary_trapperAI : public ScriptedAI
+{
+ npc_nesingwary_trapperAI(Creature *c) : ScriptedAI(c) { c->SetVisibility(VISIBILITY_OFF); }
+
+ uint64 go_caribouGUID;
+ uint8 Phase;
+ uint32 uiPhaseTimer;
+
+ void Reset()
+ {
+ me->SetVisibility(VISIBILITY_OFF);
+ uiPhaseTimer = 2500;
+ Phase = 1;
+ go_caribouGUID = 0;
+ }
+ void EnterCombat(Unit * /*who*/) {}
+ void MoveInLineOfSight(Unit * /*who*/) {}
+
+ void JustDied(Unit * /*who*/)
+ {
+ if (GameObject *go_caribou = me->GetMap()->GetGameObject(go_caribouGUID))
+ go_caribou->SetLootState(GO_JUST_DEACTIVATED);
+
+ if (TempSummon *summon = me->ToTempSummon())
+ if (summon->isSummon())
+ if (Unit *pTemp = summon->GetSummoner())
+ if (pTemp->GetTypeId() == TYPEID_PLAYER)
+ CAST_PLR(pTemp)->KilledMonsterCredit(me->GetEntry(),0);
+
+ if (GameObject *go_caribou = me->GetMap()->GetGameObject(go_caribouGUID))
+ go_caribou->SetGoState(GO_STATE_READY);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (uiPhaseTimer <= diff)
+ {
+ switch (Phase)
+ {
+ case 1:
+ me->SetVisibility(VISIBILITY_ON);
+ uiPhaseTimer = 2000;
+ Phase = 2;
+ break;
+
+ case 2:
+ if (GameObject *go_fur = me->FindNearestGameObject(GO_HIGH_QUALITY_FUR, 11.0f))
+ me->GetMotionMaster()->MovePoint(0, go_fur->GetPositionX(), go_fur->GetPositionY(), go_fur->GetPositionZ());
+ uiPhaseTimer = 1500;
+ Phase = 3;
+ break;
+ case 3:
+ //DoScriptText(SAY_NESINGWARY_1, me);
+ uiPhaseTimer = 2000;
+ Phase = 4;
+ break;
+ case 4:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LOOT);
+ uiPhaseTimer = 1000;
+ Phase = 5;
+ break;
+ case 5:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_NONE);
+ uiPhaseTimer = 500;
+ Phase = 6;
+ break;
+ case 6:
+ if (GameObject *go_fur = me->FindNearestGameObject(GO_HIGH_QUALITY_FUR, 11.0f))
+ go_fur->Delete();
+ uiPhaseTimer = 500;
+ Phase = 7;
+ break;
+
+ case 7:
+ {
+ GameObject *go_caribou = NULL;
+ for (uint8 i = 0; i < CaribouTrapsNum; ++i)
+ {
+ go_caribou = me->FindNearestGameObject(CaribouTraps[i], 5.0f);
+ if (go_caribou)
+ {
+ go_caribou->SetGoState(GO_STATE_ACTIVE);
+ go_caribouGUID = go_caribou->GetGUID();
+ break;
+ }
+ }
+ Phase = 8;
+ uiPhaseTimer = 1000;
+ }
+ break;
+ case 8:
+ DoCast(me, SPELL_TRAPPED, true);
+ Phase = 0;
+ break;
+ }
+ } else uiPhaseTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_npc_nesingwary_trapper(Creature *pCreature)
+{
+ return new npc_nesingwary_trapperAI (pCreature);
+}
+
+/*######
+## npc_lurgglbr
+######*/
+
+enum eLurgglbr
+{
+ QUEST_ESCAPE_WINTERFIN_CAVERNS = 11570,
+
+ GO_CAGE = 187369,
+
+ FACTION_ESCORTEE_A = 774,
+ FACTION_ESCORTEE_H = 775,
+};
+
+/*#define SAY_WP_1_LUR_START -1571004
+#define SAY_WP_1_LUR_END -1571005
+#define SAY_WP_41_LUR_START -1571006
+#define SAY_WP_41_LUR_END -1571007*/
+
+struct npc_lurgglbrAI : public npc_escortAI
+{
+ npc_lurgglbrAI(Creature* pCreature) : npc_escortAI(pCreature){}
+
+ uint32 IntroTimer;
+ uint32 IntroPhase;
+
+ void Reset()
+ {
+ if (!HasEscortState(STATE_ESCORT_ESCORTING))
+ {
+ IntroTimer = 0;
+ IntroPhase = 0;
+ }
+ }
+
+ void WaypointReached(uint32 i)
+ {
+ switch (i)
+ {
+ case 0:
+ IntroPhase = 1;
+ IntroTimer = 2000;
+ break;
+ case 41:
+ IntroPhase = 4;
+ IntroTimer = 2000;
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (IntroPhase)
+ {
+ if (IntroTimer <= diff)
+ {
+ switch(IntroPhase)
+ {
+ case 1:
+ //DoScriptText(SAY_WP_1_LUR_START,me);
+ IntroPhase = 2;
+ IntroTimer = 7500;
+ break;
+ case 2:
+ //DoScriptText(SAY_WP_1_LUR_END,me);
+ IntroPhase = 3;
+ IntroTimer = 7500;
+ break;
+ case 3:
+ me->SetReactState(REACT_AGGRESSIVE);
+ IntroPhase = 0;
+ IntroTimer = 0;
+ break;
+ case 4:
+ //DoScriptText(SAY_WP_41_LUR_START,me);
+ IntroPhase = 5;
+ IntroTimer = 8000;
+ break;
+ case 5:
+ //DoScriptText(SAY_WP_41_LUR_END,me);
+ IntroPhase = 6;
+ IntroTimer = 2500;
+ break;
+
+ case 6:
+ if (Player* pPlayer = GetPlayerForEscort())
+ pPlayer->AreaExploredOrEventHappens(QUEST_ESCAPE_WINTERFIN_CAVERNS);
+ IntroPhase = 7;
+ IntroTimer = 2500;
+ break;
+
+ case 7:
+ me->ForcedDespawn();
+ IntroPhase = 0;
+ IntroTimer = 0;
+ break;
+ }
+ } else IntroTimer -= diff;
+ }
+ npc_escortAI::UpdateAI(diff);
+
+ if (!UpdateVictim())
+ return;
+ }
+};
+
+CreatureAI* GetAI_npc_lurgglbr(Creature* pCreature)
+{
+ return new npc_lurgglbrAI(pCreature);
+}
+
+bool QuestAccept_npc_lurgglbr(Player* pPlayer, Creature* pCreature, Quest const *pQuest)
+{
+ if (pQuest->GetQuestId() == QUEST_ESCAPE_WINTERFIN_CAVERNS)
+ {
+ if (GameObject* pGo = pCreature->FindNearestGameObject(GO_CAGE, 5.0f))
+ {
+ pGo->SetRespawnTime(0);
+ pGo->SetGoType(GAMEOBJECT_TYPE_BUTTON);
+ pGo->UseDoorOrButton(20);
+ }
+
+ if (npc_escortAI* pEscortAI = CAST_AI(npc_lurgglbrAI, pCreature->AI()))
+ pEscortAI->Start(true, false, pPlayer->GetGUID());
+
+ switch (pPlayer->GetTeam())
+ {
+ case ALLIANCE:
+ pCreature->setFaction(FACTION_ESCORTEE_A);
+ break;
+ default:
+ case HORDE:
+ pCreature->setFaction(FACTION_ESCORTEE_H);
+ break;
+ }
+
+ return true;
+ }
+ return false;
+}
+
+/*######
+## npc_nexus_drake_hatchling
+######*/
+
+enum eNexusDrakeHatchling
+{
+ SPELL_DRAKE_HARPOON = 46607,
+ SPELL_RED_DRAGONBLOOD = 46620,
+ SPELL_DRAKE_HATCHLING_SUBDUED = 46691,
+ SPELL_SUBDUED = 46675,
+
+ NPC_RAELORASZ = 26117,
+
+ QUEST_DRAKE_HUNT = 11919,
+ QUEST_DRAKE_HUNT_D = 11940
+};
+
+struct npc_nexus_drake_hatchlingAI : public FollowerAI //The spell who makes the npc follow the player is missing, also we can use FollowerAI!
+{
+ npc_nexus_drake_hatchlingAI(Creature *c) : FollowerAI(c) {}
+
+ uint64 HarpoonerGUID;
+ bool WithRedDragonBlood;
+
+ void Reset()
+ {
+ WithRedDragonBlood = false;
+ HarpoonerGUID = 0;
+ }
+
+ void EnterCombat(Unit* pWho)
+ {
+ if (me->canAttack(pWho))
+ AttackStart(pWho);
+ }
+
+ void SpellHit(Unit *caster, const SpellEntry *spell)
+ {
+ if (spell->Id == SPELL_DRAKE_HARPOON && caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ HarpoonerGUID = caster->GetGUID();
+ DoCast(me, SPELL_RED_DRAGONBLOOD, true);
+ }
+ WithRedDragonBlood = true;
+ }
+
+ void MoveInLineOfSight(Unit *pWho)
+ {
+ FollowerAI::MoveInLineOfSight(pWho);
+
+ if (!HarpoonerGUID)
+ return;
+
+ if (me->HasAura(SPELL_SUBDUED) && pWho->GetEntry() == NPC_RAELORASZ)
+ {
+ if (me->IsWithinDistInMap(pWho, INTERACTION_DISTANCE))
+ {
+ if (Player *pHarpooner = Unit::GetPlayer(HarpoonerGUID))
+ {
+ pHarpooner->KilledMonsterCredit(26175,0);
+ pHarpooner->RemoveAura(SPELL_DRAKE_HATCHLING_SUBDUED);
+ SetFollowComplete();
+ HarpoonerGUID = 0;
+ me->DisappearAndDie();
+ }
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ if (WithRedDragonBlood && HarpoonerGUID && !me->HasAura(SPELL_RED_DRAGONBLOOD))
+ {
+ if (Player *pHarpooner = Unit::GetPlayer(HarpoonerGUID))
+ {
+ EnterEvadeMode();
+ StartFollow(pHarpooner, 35, NULL);
+
+ DoCast(me, SPELL_SUBDUED, true);
+ pHarpooner->CastSpell(pHarpooner, SPELL_DRAKE_HATCHLING_SUBDUED, true);
+
+ me->AttackStop();
+ WithRedDragonBlood = false;
+ }
+ }
+
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_nexus_drake_hatchling(Creature* pCreature)
+{
+ return new npc_nexus_drake_hatchlingAI(pCreature);
+}
+
+/*######
+## npc_thassarian
+######*/
+
+enum eThassarian
+{
+ QUEST_LAST_RITES = 12019,
+
+ SPELL_TRANSFORM_VALANAR = 46753,
+ SPELL_STUN = 46957,
+ SPELL_SHADOW_BOLT = 15537,
+
+ NPC_IMAGE_LICH_KING = 26203,
+ NPC_COUNSELOR_TALBOT = 25301,
+ NPC_PRINCE_VALANAR = 28189,
+ NPC_GENERAL_ARLOS = 25250,
+ NPC_LERYSSA = 25251,
+
+ SAY_TALBOT_1 = -1571004,
+ SAY_LICH_1 = -1571005,
+ SAY_TALBOT_2 = -1571006,
+ SAY_THASSARIAN_1 = -1571007,
+ SAY_THASSARIAN_2 = -1571008,
+ SAY_LICH_2 = -1571009,
+ SAY_THASSARIAN_3 = -1571010,
+ SAY_TALBOT_3 = -1571011,
+ SAY_LICH_3 = -1571012,
+ SAY_TALBOT_4 = -1571013,
+ SAY_ARLOS_1 = -1571014,
+ SAY_ARLOS_2 = -1571015,
+ SAY_LERYSSA_1 = -1571016,
+ SAY_THASSARIAN_4 = -1571017,
+ SAY_LERYSSA_2 = -1571018,
+ SAY_THASSARIAN_5 = -1571019,
+ SAY_LERYSSA_3 = -1571020,
+ SAY_THASSARIAN_6 = -1571021,
+ SAY_LERYSSA_4 = -1571022,
+ SAY_THASSARIAN_7 = -1571023,
+};
+
+#define GOSSIP_ITEM_T "Let's do this, Thassarian. It's now or never."
+
+struct npc_thassarianAI : public npc_escortAI
+{
+ npc_thassarianAI(Creature* pCreature) : npc_escortAI(pCreature)
+ {
+ }
+
+ uint64 uiArthas;
+ uint64 uiTalbot;
+ uint64 uiLeryssa;
+ uint64 uiArlos;
+
+ bool bArthasInPosition;
+ bool bArlosInPosition;
+ bool bLeryssaInPosition;
+ bool bTalbotInPosition;
+
+ uint32 uiPhase;
+ uint32 uiPhaseTimer;
+
+ void Reset()
+ {
+ me->RestoreFaction();
+ me->RemoveStandFlags(UNIT_STAND_STATE_SIT);
+
+ uiArthas = 0;
+ uiTalbot = 0;
+ uiLeryssa = 0;
+ uiArlos = 0;
+
+ bArthasInPosition = false;
+ bArlosInPosition = false;
+ bLeryssaInPosition = false;
+ bTalbotInPosition = false;
+
+ uiPhase = 0;
+ uiPhaseTimer = 0;
+ }
+
+ void WaypointReached(uint32 uiPointId)
+ {
+ Player* pPlayer = GetPlayerForEscort();
+
+ if (!pPlayer)
+ return;
+
+ switch(uiPointId)
+ {
+ case 3:
+ SetEscortPaused(true);
+ if (Creature *pArthas = me->SummonCreature(NPC_IMAGE_LICH_KING, 3730.313, 3518.689, 473.324, 1.562, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 120000))
+ {
+ uiArthas = pArthas->GetGUID();
+ pArthas->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pArthas->SetReactState(REACT_PASSIVE);
+ pArthas->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ pArthas->GetMotionMaster()->MovePoint(0, 3737.374756,3564.841309,477.433014);
+ }
+ if (Creature *pTalbot = me->SummonCreature(NPC_COUNSELOR_TALBOT, 3747.23, 3614.936, 473.321, 4.462012, TEMPSUMMON_CORPSE_TIMED_DESPAWN,120000))
+ {
+ uiTalbot = pTalbot->GetGUID();
+ pTalbot->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ pTalbot->GetMotionMaster()->MovePoint(0, 3738.000977,3568.882080,477.433014);
+ }
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ break;
+
+ case 4:
+ SetEscortPaused(true);
+ uiPhase = 7;
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ npc_escortAI::UpdateAI(uiDiff);
+
+ if (bArthasInPosition && bTalbotInPosition)
+ {
+ uiPhase = 1;
+ bArthasInPosition = false;
+ bTalbotInPosition = false;
+ }
+
+ if (bArlosInPosition && bLeryssaInPosition)
+ {
+ bArlosInPosition = false;
+ bLeryssaInPosition = false;
+ DoScriptText(SAY_THASSARIAN_1, me);
+ SetEscortPaused(false);
+ }
+
+ if (uiPhaseTimer <= uiDiff)
+ {
+ Creature* pTalbot = me->GetCreature(*me, uiTalbot);
+ Creature* pArthas = me->GetCreature(*me, uiArthas);
+ switch (uiPhase)
+ {
+ case 1:
+ if (pTalbot)
+ pTalbot->SetStandState(UNIT_STAND_STATE_KNEEL);
+ uiPhaseTimer = 3000;
+ ++uiPhase;
+ break;
+
+ case 2:
+ if (pTalbot)
+ {
+ pTalbot->UpdateEntry(NPC_PRINCE_VALANAR,ALLIANCE);
+ pTalbot->setFaction(14);
+ pTalbot->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pTalbot->SetReactState(REACT_PASSIVE);
+ }
+ uiPhaseTimer = 5000;
+ ++uiPhase;
+ break;
+
+ case 3:
+ if (pTalbot)
+ DoScriptText(SAY_TALBOT_1, pTalbot);
+ uiPhaseTimer = 5000;
+ ++uiPhase;
+ break;
+
+ case 4:
+ if (pArthas)
+ DoScriptText(SAY_LICH_1, pArthas);
+ uiPhaseTimer = 5000;
+ ++uiPhase;
+ break;
+
+ case 5:
+ if (pTalbot)
+ DoScriptText(SAY_TALBOT_2, pTalbot);
+ uiPhaseTimer = 5000;
+ ++uiPhase;
+ break;
+
+ case 6:
+ if (Creature* pArlos = me->SummonCreature(NPC_GENERAL_ARLOS, 3745.527100, 3615.655029, 473.321533, 4.447805, TEMPSUMMON_CORPSE_TIMED_DESPAWN,120000))
+ {
+ uiArlos = pArlos->GetGUID();
+ pArlos->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ pArlos->GetMotionMaster()->MovePoint(0, 3735.570068, 3572.419922, 477.441010);
+ }
+ if (Creature *pLeryssa = me->SummonCreature(NPC_LERYSSA, 3749.654541, 3614.959717, 473.323486, 4.524959, TEMPSUMMON_CORPSE_TIMED_DESPAWN,120000))
+ {
+ uiLeryssa = pLeryssa->GetGUID();
+ pLeryssa->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ pLeryssa->SetReactState(REACT_PASSIVE);
+ pLeryssa->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pLeryssa->GetMotionMaster()->MovePoint(0, 3741.969971, 3571.439941, 477.441010);
+ }
+ uiPhaseTimer = 2000;
+ uiPhase = 0;
+ break;
+
+ case 7:
+ DoScriptText(SAY_THASSARIAN_2, me);
+ uiPhaseTimer = 5000;
+ ++uiPhase;
+ break;
+
+ case 8:
+ if (pArthas && pTalbot)
+ {
+ pArthas->SetInFront(me); //The client doesen't update with the new orientation :l
+ pTalbot->SetStandState(UNIT_STAND_STATE_STAND);
+ DoScriptText(SAY_LICH_2, pArthas);
+ }
+ uiPhaseTimer = 5000;
+ uiPhase = 9;
+ break;
+
+ case 9:
+ DoScriptText(SAY_THASSARIAN_3, me);
+ uiPhaseTimer = 5000;
+ uiPhase = 10;
+ break;
+
+ case 10:
+ if (pTalbot)
+ DoScriptText(SAY_TALBOT_3, pTalbot);
+ uiPhaseTimer = 5000;
+ uiPhase = 11;
+ break;
+
+ case 11:
+ if (pArthas)
+ DoScriptText(SAY_LICH_3, pArthas);
+ uiPhaseTimer = 5000;
+ uiPhase = 12;
+ break;
+
+ case 12:
+ if (pTalbot)
+ DoScriptText(SAY_TALBOT_4, pTalbot);
+ uiPhaseTimer = 2000;
+ uiPhase = 13;
+ break;
+
+ case 13:
+ if (pArthas)
+ pArthas->RemoveFromWorld();
+ ++uiPhase;
+ break;
+
+ case 14:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (pTalbot)
+ {
+ pTalbot->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pTalbot->SetReactState(REACT_AGGRESSIVE);
+ pTalbot->CastSpell(me, SPELL_SHADOW_BOLT, false);
+ }
+ uiPhaseTimer = 1500;
+ ++uiPhase;
+ break;
+
+ case 15:
+ me->SetReactState(REACT_AGGRESSIVE);
+ AttackStart(pTalbot);
+ uiPhase = 0;
+ break;
+
+ case 16:
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ uiPhaseTimer = 20000;
+ ++uiPhase;
+ break;
+
+ case 17:
+ if (Creature* pLeryssa = me->GetCreature(*me, uiLeryssa))
+ pLeryssa->RemoveFromWorld();
+ if (Creature* pArlos= me->GetCreature(*me, uiArlos))
+ pArlos->RemoveFromWorld();
+ if (pTalbot)
+ pTalbot->RemoveFromWorld();
+ me->RemoveStandFlags(UNIT_STAND_STATE_SIT);
+ SetEscortPaused(false);
+ uiPhaseTimer = 0;
+ uiPhase = 0;
+ }
+ } else uiPhaseTimer -= uiDiff;
+
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ if (Creature* pTalbot = me->GetCreature(*me, uiTalbot))
+ pTalbot->RemoveFromWorld();
+
+ if (Creature* pLeryssa = me->GetCreature(*me, uiLeryssa))
+ pLeryssa->RemoveFromWorld();
+
+ if (Creature* pArlos = me->GetCreature(*me, uiArlos))
+ pArlos->RemoveFromWorld();
+
+ if (Creature* pArthas = me->GetCreature(*me, uiArthas))
+ pArthas->RemoveFromWorld();
+ }
+};
+
+bool GossipHello_npc_thassarian(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_LAST_RITES) == QUEST_STATUS_INCOMPLETE && pCreature->GetAreaId() == 4125)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_T, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_thassarian(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch (uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ CAST_AI(npc_escortAI, (pCreature->AI()))->Start(true, false, pPlayer->GetGUID());
+ CAST_AI(npc_escortAI, (pCreature->AI()))->SetMaxPlayerDistance(200.0f);
+ break;
+ }
+ return true;
+}
+
+CreatureAI* GetAI_npc_thassarian(Creature *pCreature)
+{
+ return new npc_thassarianAI (pCreature);
+}
+
+/*######
+## npc_image_lich_king
+######*/
+
+struct npc_image_lich_kingAI : public ScriptedAI
+{
+ npc_image_lich_kingAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ void Reset()
+ {
+ me->RestoreFaction();
+ }
+
+ void MovementInform(uint32 uiType, uint32 /*uiId*/)
+ {
+ if (uiType != POINT_MOTION_TYPE)
+ return;
+
+ if (me->isSummon())
+ if (Unit* pSummoner = CAST_SUM(me)->GetSummoner())
+ CAST_AI(npc_thassarianAI,CAST_CRE(pSummoner)->AI())->bArthasInPosition = true;
+ }
+};
+
+CreatureAI* GetAI_npc_image_lich_king(Creature* pCreature)
+{
+ return new npc_image_lich_kingAI (pCreature);
+}
+
+/*######
+## npc_general_arlos
+######*/
+
+struct npc_general_arlosAI : public ScriptedAI
+{
+ npc_general_arlosAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ void MovementInform(uint32 uiType, uint32 /*uiId*/)
+ {
+ if (uiType != POINT_MOTION_TYPE)
+ return;
+
+ me->addUnitState(UNIT_STAT_STUNNED);
+ me->CastSpell(me, SPELL_STUN, true);
+ if (me->isSummon())
+ if (Unit* pSummoner = CAST_SUM(me)->GetSummoner())
+ CAST_AI(npc_thassarianAI,CAST_CRE(pSummoner)->AI())->bArlosInPosition = true;
+ }
+};
+
+CreatureAI* GetAI_npc_general_arlos(Creature *pCreature)
+{
+ return new npc_general_arlosAI(pCreature);
+}
+
+/*######
+## npc_counselor_talbot
+######*/
+
+enum eCounselorTalbot
+{
+ SPELL_DEFLECTION = 51009,
+ SPELL_SOUL_BLAST = 50992,
+};
+
+struct npc_counselor_talbotAI : public ScriptedAI
+{
+ npc_counselor_talbotAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pCreature->RestoreFaction();
+ }
+
+ uint64 LeryssaGUID;
+ uint64 ArlosGUID;
+
+ bool bCheck;
+
+ uint32 uiShadowBoltTimer;
+ uint32 uiDeflectionTimer;
+ uint32 uiSoulBlastTimer;
+
+ void Reset()
+ {
+ LeryssaGUID = 0;
+ ArlosGUID = 0;
+ bCheck = false;
+ uiShadowBoltTimer = urand(5000,12000);
+ uiDeflectionTimer = urand(20000,25000);
+ uiSoulBlastTimer = urand (12000,18000);
+ }
+ void MovementInform(uint32 uiType, uint32 /*uiId*/)
+ {
+ if (uiType != POINT_MOTION_TYPE)
+ return;
+
+ if (me->isSummon())
+ if (Unit* pSummoner = CAST_SUM(me)->GetSummoner())
+ CAST_AI(npc_thassarianAI,CAST_CRE(pSummoner)->AI())->bTalbotInPosition = true;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (bCheck)
+ {
+ if (Creature *pLeryssa = me->FindNearestCreature(NPC_LERYSSA, 50.0f, true))
+ LeryssaGUID = pLeryssa->GetGUID();
+ if (Creature *pArlos = me->FindNearestCreature(NPC_GENERAL_ARLOS, 50.0f, true))
+ ArlosGUID = pArlos->GetGUID();
+ bCheck = false;
+ }
+
+ if (!UpdateVictim())
+ return;
+
+ if (me->GetAreaId() == 4125)
+ {
+ if (uiShadowBoltTimer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_SHADOW_BOLT);
+ uiShadowBoltTimer = urand(5000,12000);
+ } else uiShadowBoltTimer -= uiDiff;
+
+ if (uiDeflectionTimer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_DEFLECTION);
+ uiDeflectionTimer = urand(20000,25000);
+ } else uiDeflectionTimer -= uiDiff;
+
+ if (uiSoulBlastTimer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_SOUL_BLAST);
+ uiSoulBlastTimer = urand (12000,18000);
+ } else uiSoulBlastTimer -= uiDiff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!LeryssaGUID || !ArlosGUID)
+ return;
+
+ Creature *pLeryssa = Unit::GetCreature(*me, LeryssaGUID);
+ Creature *pArlos = Unit::GetCreature(*me, ArlosGUID);
+ if (!pLeryssa || !pArlos)
+ return;
+
+ DoScriptText(SAY_ARLOS_1, pArlos);
+ DoScriptText(SAY_ARLOS_2, pArlos);
+ DoScriptText(SAY_LERYSSA_1, pLeryssa);
+ pArlos->Kill(pArlos, false);
+ pLeryssa->RemoveAura(SPELL_STUN);
+ pLeryssa->clearUnitState(UNIT_STAT_STUNNED);
+ pLeryssa->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ pLeryssa->GetMotionMaster()->MovePoint(0,3722.114502, 3564.201660, 477.441437);
+
+ if (pKiller->GetTypeId() == TYPEID_PLAYER)
+ CAST_PLR(pKiller)->RewardPlayerAndGroupAtEvent(NPC_PRINCE_VALANAR, 0);
+ }
+};
+
+CreatureAI* GetAI_npc_counselor_talbot(Creature* pCreature)
+{
+ return new npc_counselor_talbotAI (pCreature);
+}
+
+/*######
+## npc_leryssa
+######*/
+
+struct npc_leryssaAI : public ScriptedAI
+{
+ npc_leryssaAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ bDone = false;
+ Phase = 0;
+ uiPhaseTimer = 0;
+
+ pCreature->RemoveStandFlags(UNIT_STAND_STATE_SIT);
+ }
+
+ bool bDone;
+
+ uint32 Phase;
+ uint32 uiPhaseTimer;
+
+ void MovementInform(uint32 uiType, uint32 /*uiId*/)
+ {
+ if (uiType != POINT_MOTION_TYPE)
+ return;
+
+ if (!bDone)
+ {
+ if (Creature* pTalbot = me->FindNearestCreature(NPC_PRINCE_VALANAR, 50.0f, true))
+ CAST_AI(npc_counselor_talbotAI, pTalbot->AI())->bCheck = true;
+
+ me->addUnitState(UNIT_STAT_STUNNED);
+ me->CastSpell(me, SPELL_STUN, true);
+
+ if (me->isSummon())
+ if (Unit* pSummoner = CAST_SUM(me)->GetSummoner())
+ CAST_AI(npc_thassarianAI,CAST_CRE(pSummoner)->AI())->bLeryssaInPosition = true;
+ bDone = true;
+ }
+ else
+ {
+ me->SetStandState(UNIT_STAND_STATE_SIT);
+ if (me->isSummon())
+ if (Unit* pSummoner = CAST_SUM(me)->GetSummoner())
+ pSummoner->SetStandState(UNIT_STAND_STATE_SIT);
+ uiPhaseTimer = 1500;
+ Phase = 1;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ ScriptedAI::UpdateAI(uiDiff);
+
+ if (uiPhaseTimer <= uiDiff)
+ {
+ switch (Phase)
+ {
+ case 1:
+ if (me->isSummon())
+ if (Unit* pThassarian = CAST_SUM(me)->GetSummoner())
+ DoScriptText(SAY_THASSARIAN_4, pThassarian);
+ uiPhaseTimer = 5000;
+ ++Phase;
+ break;
+ case 2:
+ DoScriptText(SAY_LERYSSA_2, me);
+ uiPhaseTimer = 5000;
+ ++Phase;
+ break;
+ case 3:
+ if (me->isSummon())
+ if (Unit* pThassarian = CAST_SUM(me)->GetSummoner())
+ DoScriptText(SAY_THASSARIAN_5, pThassarian);
+ uiPhaseTimer = 5000;
+ ++Phase;
+ break;
+ case 4:
+ DoScriptText(SAY_LERYSSA_3, me);
+ uiPhaseTimer = 5000;
+ ++Phase;
+ break;
+ case 5:
+ if (me->isSummon())
+ if (Unit* pThassarian = CAST_SUM(me)->GetSummoner())
+ DoScriptText(SAY_THASSARIAN_6, pThassarian);
+ uiPhaseTimer = 5000;
+ ++Phase;
+ break;
+
+ case 6:
+ DoScriptText(SAY_LERYSSA_4, me);
+ uiPhaseTimer = 5000;
+ ++Phase;
+ break;
+ case 7:
+ if (me->isSummon())
+ if (Unit* pThassarian = CAST_SUM(me)->GetSummoner())
+ {
+ DoScriptText(SAY_THASSARIAN_7, pThassarian);
+ CAST_AI(npc_thassarianAI,CAST_CRE(pThassarian)->AI())->uiPhase = 16;
+ }
+ uiPhaseTimer = 5000;
+ Phase = 0;
+ break;
+ }
+ } else uiPhaseTimer -= uiDiff;
+
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_leryssa(Creature *pCreature)
+{
+ return new npc_leryssaAI (pCreature);
+}
+
+/*######
+## npc_beryl_sorcerer
+######*/
+
+enum eBerylSorcerer
+{
+ NPC_CAPTURED_BERLY_SORCERER = 25474,
+ NPC_LIBRARIAN_DONATHAN = 25262,
+
+ SPELL_ARCANE_CHAINS = 45611,
+ SPELL_COSMETIC_CHAINS = 54324,
+ SPELL_COSMETIC_ENSLAVE_CHAINS_SELF = 45631
+};
+
+struct npc_beryl_sorcererAI : public FollowerAI
+{
+ npc_beryl_sorcererAI(Creature* pCreature) : FollowerAI(pCreature) {}
+
+ bool bEnslaved;
+
+ void Reset()
+ {
+ me->SetReactState(REACT_AGGRESSIVE);
+ bEnslaved = false;
+ }
+
+ void EnterCombat(Unit* pWho)
+ {
+ if (me->canAttack(pWho))
+ AttackStart(pWho);
+ }
+
+ void SpellHit(Unit* pCaster, const SpellEntry* pSpell)
+ {
+ if (pSpell->Id == SPELL_ARCANE_CHAINS && pCaster->GetTypeId() == TYPEID_PLAYER && me->GetHealth()*100 / me->GetMaxHealth() <= 50 && !bEnslaved)
+ {
+ EnterEvadeMode(); //We make sure that the npc is not attacking the player!
+ me->SetReactState(REACT_PASSIVE);
+ StartFollow(CAST_PLR(pCaster), NULL, NULL);
+ me->UpdateEntry(NPC_CAPTURED_BERLY_SORCERER, TEAM_NEUTRAL);
+ DoCast(me, SPELL_COSMETIC_ENSLAVE_CHAINS_SELF, true);
+ CAST_PLR(pCaster)->KilledMonsterCredit(NPC_CAPTURED_BERLY_SORCERER, 0);
+ bEnslaved = true;
+ }
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ FollowerAI::MoveInLineOfSight(pWho);
+
+ if (pWho->GetEntry() == NPC_LIBRARIAN_DONATHAN && me->IsWithinDistInMap(pWho, INTERACTION_DISTANCE))
+ {
+ SetFollowComplete();
+ me->DisappearAndDie();
+ }
+ }
+
+ void UpdateAI(const uint32 /*uiDiff*/)
+ {
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_beryl_sorcerer(Creature* pCreature)
+{
+ return new npc_beryl_sorcererAI(pCreature);
+}
+
+/*######
+## npc_imprisoned_beryl_sorcerer
+######*/
+
+enum eImprisionedBerylSorcerer
+{
+ SPELL_NEURAL_NEEDLE = 45634,
+
+ NPC_IMPRISONED_BERYL_SORCERER = 25478,
+
+ SAY_IMPRISIONED_BERYL_1 = -1571024,
+ SAY_IMPRISIONED_BERYL_2 = -1571025,
+ SAY_IMPRISIONED_BERYL_3 = -1571026,
+ SAY_IMPRISIONED_BERYL_4 = -1571027,
+ SAY_IMPRISIONED_BERYL_5 = -1571028,
+ SAY_IMPRISIONED_BERYL_6 = -1571029,
+ SAY_IMPRISIONED_BERYL_7 = -1571030,
+};
+
+struct npc_imprisoned_beryl_sorcererAI : public ScriptedAI
+{
+ npc_imprisoned_beryl_sorcererAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint64 CasterGUID;
+
+ uint32 uiStep;
+ uint32 uiPhase;
+
+ void Reset()
+ {
+ uiStep = 1;
+ uiPhase = 0;
+ CasterGUID = NULL;
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ }
+
+ void SpellHit(Unit* pUnit, const SpellEntry* pSpell)
+ {
+ if (pSpell->Id == SPELL_NEURAL_NEEDLE && pUnit->GetTypeId() == TYPEID_PLAYER)
+ {
+ ++uiPhase;
+ CasterGUID = pUnit->GetGUID();
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ ScriptedAI::UpdateAI(uiDiff);
+
+ if (!me->HasAura(SPELL_COSMETIC_ENSLAVE_CHAINS_SELF))
+ DoCast(me, SPELL_COSMETIC_ENSLAVE_CHAINS_SELF);
+
+ if (me->GetReactState() != REACT_PASSIVE)
+ me->SetReactState(REACT_PASSIVE);
+
+ switch (uiPhase)
+ {
+ case 1:
+ if (uiStep == 1)
+ {
+ DoScriptText(SAY_IMPRISIONED_BERYL_1, me);
+ uiStep = 2;
+ }
+ break;
+
+ case 2:
+ if (uiStep == 2)
+ {
+ DoScriptText(SAY_IMPRISIONED_BERYL_2, me);
+ uiStep = 3;
+ }
+ break;
+
+ case 3:
+ if (uiStep == 3)
+ {
+ DoScriptText(SAY_IMPRISIONED_BERYL_3, me);
+ uiStep = 4;
+ }
+ break;
+
+ case 4:
+ if (uiStep == 4)
+ {
+ DoScriptText(SAY_IMPRISIONED_BERYL_4, me);
+ uiStep = 5;
+ }
+ break;
+
+ case 5:
+ if (uiStep == 5)
+ {
+ if (Player *pCaster = Unit::GetPlayer(CasterGUID))
+ {
+ DoScriptText(SAY_IMPRISIONED_BERYL_5, me);
+ pCaster->KilledMonsterCredit(25478,0);
+ uiStep = 6;
+ }
+ }
+ break;
+
+ case 6:
+ if (uiStep == 6)
+ {
+ DoScriptText(SAY_IMPRISIONED_BERYL_6, me);
+ uiStep = 7;
+ }
+ break;
+
+ case 7:
+ if (uiStep == 7)
+ {
+ DoScriptText(SAY_IMPRISIONED_BERYL_7, me);
+ uiStep = 1;
+ uiPhase = 0;
+ }
+ break;
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_imprisoned_beryl_sorcerer(Creature* pCreature)
+{
+ return new npc_imprisoned_beryl_sorcererAI(pCreature);
+}
+
+/*######
+## npc_mootoo_the_younger
+######*/
+enum Script_Texts_Mootoo_the_Younger
+{
+ SAY_1 =-1750040,
+ SAY_2 =-1750041,
+ SAY_3 =-1750042,
+ SAY_4 =-1750043,
+ SAY_5 =-1750044
+};
+enum Mootoo_the_Younger_Entries
+{
+ NPC_MOOTOO_THE_YOUNGER =25504,
+ QUEST_ESCAPING_THE_MIST =11664
+};
+bool QuestAccept_npc_mootoo_the_younger(Player* pPlayer, Creature* pCreature, Quest const* quest)
+{
+ if (quest->GetQuestId() == QUEST_ESCAPING_THE_MIST)
+ {
+ switch (pPlayer->GetTeam())
+ {
+ case ALLIANCE:
+ pCreature->setFaction(FACTION_ESCORTEE_A);
+ break;
+ case HORDE:
+ pCreature->setFaction(FACTION_ESCORTEE_H);
+ break;
+ }
+ DoScriptText(SAY_1, pCreature);
+ CAST_AI(npc_escortAI, (pCreature->AI()))->Start(true, false, pPlayer->GetGUID());
+ }
+ return true;
+}
+struct npc_mootoo_the_youngerAI : public npc_escortAI
+{
+ npc_mootoo_the_youngerAI(Creature *c) : npc_escortAI(c) {}
+
+ void Reset()
+ {
+ SetDespawnAtFar(false);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (Player* pPlayer=GetPlayerForEscort())
+ pPlayer->FailQuest(QUEST_ESCAPING_THE_MIST);
+ }
+
+ void WaypointReached(uint32 i)
+ {
+ Player* pPlayer = GetPlayerForEscort();
+
+ if (!pPlayer)
+ return;
+
+ switch(i)
+ {
+ case 10:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
+ DoScriptText(SAY_2, me);
+ break;
+ case 12:
+ DoScriptText(SAY_3, me);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LOOT);
+ break;
+ case 16:
+ DoScriptText(SAY_4, me);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
+ break;
+ case 20:
+ me->SetPhaseMask(1,true);
+ DoScriptText(SAY_5, me);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
+ if (pPlayer)
+ pPlayer->GroupEventHappens(QUEST_ESCAPING_THE_MIST, me);
+ SetRun(true);
+ break;
+ }
+ }
+};
+CreatureAI* GetAI_npc_mootoo_the_younger(Creature* pCreature)
+{
+ return new npc_mootoo_the_youngerAI(pCreature);
+}
+
+/*######
+## npc_bonker_togglevolt
+######*/
+
+enum Bonker_Togglevolt_Entries
+{
+ NPC_BONKER_TOGGLEVOLT =25589,
+ QUEST_GET_ME_OUTA_HERE =11673
+};
+enum Script_Texts_Bonker_Togglevolt
+{
+ SAY_bonker_1 =-1700002,
+ SAY_bonker_2 =-1700003
+};
+
+bool QuestAccept_npc_bonker_togglevolt(Player* pPlayer, Creature* pCreature, Quest const* quest)
+{
+ if (quest->GetQuestId() == QUEST_GET_ME_OUTA_HERE)
+ {
+ switch (pPlayer->GetTeam())
+ {
+ case ALLIANCE:
+ pCreature->setFaction(FACTION_ESCORTEE_A);
+ break;
+ case HORDE:
+ pCreature->setFaction(FACTION_ESCORTEE_H);
+ break;
+ }
+ DoScriptText(SAY_bonker_2, pCreature, pPlayer);
+ CAST_AI(npc_escortAI, (pCreature->AI()))->Start(true, true, pPlayer->GetGUID());
+ }
+ return true;
+}
+struct npc_bonker_togglevoltAI : public npc_escortAI
+{
+ npc_bonker_togglevoltAI(Creature *c) : npc_escortAI(c) {}
+ uint32 Bonker_agro;
+
+ void Reset()
+ {
+ Bonker_agro=0;
+ SetDespawnAtFar(false);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (Player* pPlayer = GetPlayerForEscort())
+ pPlayer->FailQuest(QUEST_ESCAPING_THE_MIST);
+ }
+
+ void UpdateEscortAI(const uint32 /*diff*/)
+ {
+ if (GetAttack() && UpdateVictim())
+ {
+ if (Bonker_agro == 0)
+ {
+ DoScriptText(SAY_bonker_1,me);
+ Bonker_agro++;
+ }
+ DoMeleeAttackIfReady();
+ }
+ else Bonker_agro=0;
+ }
+
+ void WaypointReached(uint32 i)
+ {
+ Player* pPlayer = GetPlayerForEscort();
+
+ if (!pPlayer)
+ return;
+
+ switch(i)
+ {
+ case 29:
+ if (pPlayer)
+ pPlayer->GroupEventHappens(QUEST_GET_ME_OUTA_HERE, me);
+ break;
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_bonker_togglevolt(Creature* pCreature)
+{
+ return new npc_bonker_togglevoltAI(pCreature);
+}
+
+/*######
+## Help Those That Cannot Help Themselves, Quest 11876
+######*/
+
+enum eHelpThemselves
+{
+ QUEST_CANNOT_HELP_THEMSELVES = 11876,
+ GO_MAMMOTH_TRAP_1 = 188022,
+ GO_MAMMOTH_TRAP_2 = 188024,
+ GO_MAMMOTH_TRAP_3 = 188025,
+ GO_MAMMOTH_TRAP_4 = 188026,
+ GO_MAMMOTH_TRAP_5 = 188027,
+ GO_MAMMOTH_TRAP_6 = 188028,
+ GO_MAMMOTH_TRAP_7 = 188029,
+ GO_MAMMOTH_TRAP_8 = 188030,
+ GO_MAMMOTH_TRAP_9 = 188031,
+ GO_MAMMOTH_TRAP_10 = 188032,
+ GO_MAMMOTH_TRAP_11 = 188033,
+ GO_MAMMOTH_TRAP_12 = 188034,
+ GO_MAMMOTH_TRAP_13 = 188035,
+ GO_MAMMOTH_TRAP_14 = 188036,
+ GO_MAMMOTH_TRAP_15 = 188037,
+ GO_MAMMOTH_TRAP_16 = 188038,
+ GO_MAMMOTH_TRAP_17 = 188039,
+ GO_MAMMOTH_TRAP_18 = 188040,
+ GO_MAMMOTH_TRAP_19 = 188041,
+ GO_MAMMOTH_TRAP_20 = 188042,
+ GO_MAMMOTH_TRAP_21 = 188043,
+ GO_MAMMOTH_TRAP_22 = 188044,
+};
+
+#define MammothTrapsNum 22
+const uint32 MammothTraps[MammothTrapsNum] =
+{
+ GO_MAMMOTH_TRAP_1, GO_MAMMOTH_TRAP_2, GO_MAMMOTH_TRAP_3, GO_MAMMOTH_TRAP_4, GO_MAMMOTH_TRAP_5,
+ GO_MAMMOTH_TRAP_6, GO_MAMMOTH_TRAP_7, GO_MAMMOTH_TRAP_8, GO_MAMMOTH_TRAP_9, GO_MAMMOTH_TRAP_10,
+ GO_MAMMOTH_TRAP_11, GO_MAMMOTH_TRAP_12, GO_MAMMOTH_TRAP_13, GO_MAMMOTH_TRAP_14, GO_MAMMOTH_TRAP_15,
+ GO_MAMMOTH_TRAP_16, GO_MAMMOTH_TRAP_17, GO_MAMMOTH_TRAP_18, GO_MAMMOTH_TRAP_19, GO_MAMMOTH_TRAP_20,
+ GO_MAMMOTH_TRAP_21, GO_MAMMOTH_TRAP_22
+};
+
+struct npc_trapped_mammoth_calfAI : public ScriptedAI
+{
+ npc_trapped_mammoth_calfAI(Creature* c) : ScriptedAI(c) {}
+
+ uint32 uiTimer;
+ bool bStarted;
+
+ void Reset()
+ {
+ uiTimer = 1500;
+ bStarted = false;
+
+ GameObject* pTrap;
+ for (uint8 i = 0; i < MammothTrapsNum; ++i)
+ {
+ pTrap = me->FindNearestGameObject(MammothTraps[i],11.0f);
+ if (pTrap)
+ {
+ pTrap->SetGoState(GO_STATE_ACTIVE);
+ return;
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (bStarted)
+ {
+ if (uiTimer <= diff)
+ {
+ Position pos;
+ me->GetRandomNearPosition(pos, 10.0f);
+ me->GetMotionMaster()->MovePoint(0,pos);
+ bStarted = false;
+ }
+ else uiTimer -= diff;
+ }
+ }
+
+ void DoAction(const int32 param)
+ {
+ if (param == 1)
+ bStarted = true;
+ }
+
+ void MovementInform(uint32 uiType, uint32 /*uiId*/)
+ {
+
+ if (uiType != POINT_MOTION_TYPE)
+ return;
+ me->DisappearAndDie();
+ GameObject* pTrap;
+ for (uint8 i = 0; i < MammothTrapsNum; ++i)
+ {
+ pTrap = me->FindNearestGameObject(MammothTraps[i],11.0f);
+ if (pTrap)
+ {
+ pTrap->SetLootState(GO_JUST_DEACTIVATED);
+ return;
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_trapped_mammoth_calf(Creature* pCreature)
+{
+ return new npc_trapped_mammoth_calfAI(pCreature);
+}
+
+/*######
+## Quest 11653: Hah... You're Not So Big Now!
+######*/
+
+enum eNotSoBig
+{
+ QUEST_YOU_RE_NOT_SO_BIG_NOW = 11653,
+ SPELL_AURA_NOTSOBIG_1 = 45672,
+ SPELL_AURA_NOTSOBIG_2 = 45673,
+ SPELL_AURA_NOTSOBIG_3 = 45677,
+ SPELL_AURA_NOTSOBIG_4 = 45681
+};
+
+struct npc_magmoth_crusherAI : public ScriptedAI
+{
+ npc_magmoth_crusherAI(Creature* c) : ScriptedAI(c) {}
+
+ void JustDied(Unit *pKiller)
+ {
+ if (pKiller->GetTypeId() == TYPEID_PLAYER &&
+ CAST_PLR(pKiller)->GetQuestStatus(QUEST_YOU_RE_NOT_SO_BIG_NOW) == QUEST_STATUS_INCOMPLETE &&
+ (me->HasAura(SPELL_AURA_NOTSOBIG_1) || me->HasAura(SPELL_AURA_NOTSOBIG_2) ||
+ me->HasAura(SPELL_AURA_NOTSOBIG_3) || me->HasAura(SPELL_AURA_NOTSOBIG_4)))
+ {
+ Quest const* qInfo = objmgr.GetQuestTemplate(QUEST_YOU_RE_NOT_SO_BIG_NOW);
+ if (qInfo)
+ CAST_PLR(pKiller)->KilledMonsterCredit(qInfo->ReqCreatureOrGOId[0],0);
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_magmoth_crusher(Creature* pCreature)
+{
+ return new npc_magmoth_crusherAI(pCreature);
+}
+
+/*######
+## Quest 11608: Bury Those Cockroaches!
+######*/
+
+#define QUEST_BURY_THOSE_COCKROACHES 11608
+#define SPELL_SEAFORIUM_DEPTH_CHARGE_EXPLOSION 45502
+
+struct npc_seaforium_depth_chargeAI : public ScriptedAI
+{
+ npc_seaforium_depth_chargeAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 uiExplosionTimer;
+ void Reset()
+ {
+ uiExplosionTimer = urand(5000,10000);
+ }
+ void UpdateAI(const uint32 diff)
+ {
+ if (uiExplosionTimer < diff)
+ {
+ DoCast(SPELL_SEAFORIUM_DEPTH_CHARGE_EXPLOSION);
+ for (uint8 i = 0; i < 4; ++i)
+ {
+ if (Creature* cCredit = me->FindNearestCreature(25402 + i, 10.0f))//25402-25405 credit markers
+ {
+ if (Unit* uOwner = me->GetOwner(true))
+ {
+ Player* pOwner = uOwner->ToPlayer();
+ if (pOwner && pOwner->GetQuestStatus(QUEST_BURY_THOSE_COCKROACHES) == QUEST_STATUS_INCOMPLETE)
+ pOwner->KilledMonsterCredit(cCredit->GetEntry(),cCredit->GetGUID());
+ }
+ }
+ }
+ me->Kill(me);
+ return;
+ } else uiExplosionTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_npc_seaforium_depth_charge(Creature* pCreature)
+{
+ return new npc_seaforium_depth_chargeAI(pCreature);
+}
+
+/*######
+## Help Those That Cannot Help Themselves, Quest 11876
+######*/
+
+enum eValiancekeepcannons
+{
+ GO_VALIANCE_KEEP_CANNON_1 = 187560,
+ GO_VALIANCE_KEEP_CANNON_2 = 188692
+};
+
+struct npc_valiance_keep_cannoneerAI : public ScriptedAI
+{
+ npc_valiance_keep_cannoneerAI(Creature* c) : ScriptedAI(c) {}
+
+ uint32 uiTimer;
+
+ void Reset()
+ {
+ uiTimer = urand(13000,18000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (uiTimer <= diff)
+ {
+ me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
+ GameObject* pCannon = me->FindNearestGameObject(GO_VALIANCE_KEEP_CANNON_1,10);
+ if (!pCannon)
+ pCannon = me->FindNearestGameObject(GO_VALIANCE_KEEP_CANNON_2,10);
+ if (pCannon)
+ pCannon->Use(me);
+ uiTimer = urand(13000,18000);
+ }
+ else uiTimer -= diff;
+
+ if (!UpdateVictim())
+ return;
+ }
+
+};
+
+CreatureAI* GetAI_npc_valiance_keep_cannoneer(Creature* pCreature)
+{
+ return new npc_valiance_keep_cannoneerAI(pCreature);
+}
+
+/*******************************************************
+ * npc_warmage_coldarra
+ *******************************************************/
+
+enum Spells
+{
+ SPELL_TRANSITUS_SHIELD_BEAM = 48310
+};
+
+enum NPCs
+{
+ NPC_TRANSITUS_SHIELD_DUMMY = 27306,
+ NPC_WARMAGE_HOLLISTER = 27906,
+ NPC_WARMAGE_CALANDRA = 27173,
+ NPC_WARMAGE_WATKINS = 27904
+};
+
+struct npc_warmage_coldarraAI : public Scripted_NoMovementAI
+{
+ npc_warmage_coldarraAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature){}
+
+ uint32 m_uiTimer; //Timer until recast
+
+ void Reset()
+ {
+ m_uiTimer = 0;
+ }
+
+ void Aggro(Unit* /*pWho*/) {}
+
+ void AttackStart(Unit* /*pWho*/) {}
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_uiTimer <= uiDiff)
+ {
+ std::list<Creature*> orbList;
+ GetCreatureListWithEntryInGrid(orbList, me, NPC_TRANSITUS_SHIELD_DUMMY, 32.0f);
+
+ switch(me->GetEntry())
+ {
+ case NPC_WARMAGE_HOLLISTER:
+ {
+ if (!orbList.empty())
+ {
+ for (std::list<Creature*>::const_iterator itr = orbList.begin(); itr != orbList.end(); ++itr)
+ {
+ if (Creature* pOrb = *itr)
+ if (pOrb->GetPositionY() > 6680)
+ DoCast(pOrb,SPELL_TRANSITUS_SHIELD_BEAM);
+ }
+ }
+ m_uiTimer = urand(90000,120000);
+ }
+ break;
+ case NPC_WARMAGE_CALANDRA:
+ {
+ if (!orbList.empty())
+ {
+ for (std::list<Creature*>::const_iterator itr = orbList.begin(); itr != orbList.end(); ++itr)
+ {
+ if (Creature* pOrb = *itr)
+ if ((pOrb->GetPositionY() < 6680) && (pOrb->GetPositionY() > 6630))
+ DoCast(pOrb,SPELL_TRANSITUS_SHIELD_BEAM);
+ }
+ }
+ m_uiTimer = urand(90000,120000);
+ }
+ break;
+ case NPC_WARMAGE_WATKINS:
+ {
+ if (!orbList.empty())
+ {
+ for (std::list<Creature*>::const_iterator itr = orbList.begin(); itr != orbList.end(); ++itr)
+ {
+ if (Creature* pOrb = *itr)
+ if (pOrb->GetPositionY() < 6630)
+ DoCast(pOrb,SPELL_TRANSITUS_SHIELD_BEAM);
+ }
+ }
+ m_uiTimer = urand(90000,120000);
+ }
+ break;
+ }
+ }
+ else m_uiTimer -= uiDiff;
+
+ ScriptedAI::UpdateAI(uiDiff);
+
+ if (!UpdateVictim())
+ return;
+ }
+};
+
+CreatureAI* GetAI_npc_warmage_coldarra(Creature* pCreature)
+{
+ return new npc_warmage_coldarraAI(pCreature);
+}
+
+void AddSC_borean_tundra()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_sinkhole_kill_credit";
+ newscript->GetAI = &GetAI_npc_sinkhole_kill_credit;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_khunok_the_behemoth";
+ newscript->GetAI = &GetAI_npc_khunok_the_behemoth;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_keristrasza";
+ newscript->pGossipHello = &GossipHello_npc_keristrasza;
+ newscript->pGossipSelect = &GossipSelect_npc_keristrasza;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_corastrasza";
+ newscript->pGossipHello = &GossipHello_npc_corastrasza;
+ newscript->pGossipSelect = &GossipSelect_npc_corastrasza;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_iruk";
+ newscript->pGossipHello = &GossipHello_npc_iruk;
+ newscript->pGossipSelect = &GossipSelect_npc_iruk;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_nerubar_victim";
+ newscript->GetAI = &GetAI_mob_nerubar_victim;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_scourge_prisoner";
+ newscript->GetAI = &GetAI_npc_scourge_prisoner;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_jenny";
+ newscript->GetAI = &GetAI_npc_jenny;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_fezzix_geartwist";
+ newscript->GetAI = &GetAI_npc_fezzix_geartwist;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_nesingwary_trapper";
+ newscript->GetAI = &GetAI_npc_nesingwary_trapper;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_lurgglbr";
+ newscript->GetAI = &GetAI_npc_lurgglbr;
+ newscript->pQuestAccept = &QuestAccept_npc_lurgglbr;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_nexus_drake_hatchling";
+ newscript->GetAI = &GetAI_npc_nexus_drake_hatchling;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_thassarian";
+ newscript->GetAI = &GetAI_npc_thassarian;
+ newscript->pGossipHello = &GossipHello_npc_thassarian;
+ newscript->pGossipSelect = &GossipSelect_npc_thassarian;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_image_lich_king";
+ newscript->GetAI = &GetAI_npc_image_lich_king;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_counselor_talbot";
+ newscript->GetAI = &GetAI_npc_counselor_talbot;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_leryssa";
+ newscript->GetAI = &GetAI_npc_leryssa;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_general_arlos";
+ newscript->GetAI = &GetAI_npc_general_arlos;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_beryl_sorcerer";
+ newscript->GetAI = &GetAI_npc_beryl_sorcerer;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_imprisoned_beryl_sorcerer";
+ newscript->GetAI = &GetAI_npc_imprisoned_beryl_sorcerer;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_mootoo_the_younger";
+ newscript->GetAI = &GetAI_npc_mootoo_the_younger;
+ newscript->pQuestAccept=&QuestAccept_npc_mootoo_the_younger;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_bonker_togglevolt";
+ newscript->GetAI = &GetAI_npc_bonker_togglevolt;
+ newscript->pQuestAccept=&QuestAccept_npc_bonker_togglevolt;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_trapped_mammoth_calf";
+ newscript->GetAI = &GetAI_npc_trapped_mammoth_calf;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_magmoth_crusher";
+ newscript->GetAI = &GetAI_npc_magmoth_crusher;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_seaforium_depth_charge";
+ newscript->GetAI = &GetAI_npc_seaforium_depth_charge;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_valiance_keep_cannoneer";
+ newscript->GetAI = &GetAI_npc_valiance_keep_cannoneer;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_warmage_coldarra";
+ newscript->GetAI = &GetAI_npc_warmage_coldarra;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp b/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp
new file mode 100644
index 00000000000..c33ea69fa2d
--- /dev/null
+++ b/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_argent_challenge.cpp
@@ -0,0 +1,512 @@
+/*
+ * Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Argent Challenge Encounter.
+SD%Complete: 50 %
+SDComment: AI for Argent Soldiers are not implemented. AI from bosses need more improvements.
+SDCategory: Trial of the Champion
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "trial_of_the_champion.h"
+#include "ScriptedEscortAI.h"
+
+enum eSpells
+{
+ //Eadric
+ SPELL_EADRIC_ACHIEVEMENT = 68197,
+ SPELL_HAMMER_JUSTICE = 66863,
+ SPELL_HAMMER_RIGHTEOUS = 66867,
+ SPELL_RADIANCE = 66935,
+ SPELL_VENGEANCE = 66865,
+
+ //Paletress
+ SPELL_SMITE = 66536,
+ SPELL_SMITE_H = 67674,
+ SPELL_HOLY_FIRE = 66538,
+ SPELL_HOLY_FIRE_H = 67676,
+ SPELL_RENEW = 66537,
+ SPELL_RENEW_H = 67675,
+ SPELL_HOLY_NOVA = 66546,
+ SPELL_SHIELD = 66515,
+ SPELL_CONFESS = 66680,
+ SPELL_SUMMON_MEMORY = 66545,
+
+ //Memory
+ SPELL_OLD_WOUNDS = 66620,
+ SPELL_OLD_WOUNDS_H = 67679,
+ SPELL_SHADOWS_PAST = 66619,
+ SPELL_SHADOWS_PAST_H = 67678,
+ SPELL_WAKING_NIGHTMARE = 66552,
+ SPELL_WAKING_NIGHTMARE_H = 67677
+};
+
+struct boss_eadricAI : public ScriptedAI
+{
+ boss_eadricAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ pCreature->SetReactState(REACT_PASSIVE);
+ pCreature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiVenganceTimer;
+ uint32 uiRadianceTimer;
+ uint32 uiHammerJusticeTimer;
+ uint32 uiResetTimer;
+
+ bool bDone;
+
+ void Reset()
+ {
+ uiVenganceTimer = 10000;
+ uiRadianceTimer = 16000;
+ uiHammerJusticeTimer = 25000;
+ uiResetTimer = 5000;
+
+ bDone = false;
+ }
+
+ void DamageTaken(Unit * /*done_by*/, uint32 &damage)
+ {
+ if (damage >= me->GetHealth())
+ {
+ damage = 0;
+ EnterEvadeMode();
+ me->setFaction(35);
+ bDone = true;
+ }
+ }
+
+ void MovementInform(uint32 MovementType, uint32 /*Data*/)
+ {
+ if (MovementType != POINT_MOTION_TYPE)
+ return;
+
+ if (pInstance)
+ pInstance->SetData(BOSS_ARGENT_CHALLENGE_E, DONE);
+
+ me->DisappearAndDie();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (bDone && uiResetTimer <= uiDiff)
+ {
+ me->GetMotionMaster()->MovePoint(0,746.87,665.87,411.75);
+ bDone = false;
+ } else uiResetTimer -= uiDiff;
+
+ if (!UpdateVictim())
+ return;
+
+ if (uiHammerJusticeTimer <= uiDiff)
+ {
+ me->InterruptNonMeleeSpells(true);
+
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 250, true))
+ {
+ if (pTarget && pTarget->isAlive())
+ {
+ DoCast(pTarget, SPELL_HAMMER_JUSTICE);
+ DoCast(pTarget, SPELL_HAMMER_RIGHTEOUS);
+ }
+ }
+ uiHammerJusticeTimer = 25000;
+ } else uiHammerJusticeTimer -= uiDiff;
+
+ if (uiVenganceTimer <= uiDiff)
+ {
+ DoCast(me,SPELL_VENGEANCE);
+
+ uiVenganceTimer = 10000;
+ } else uiVenganceTimer -= uiDiff;
+
+ if (uiRadianceTimer <= uiDiff)
+ {
+ DoCastAOE(SPELL_RADIANCE);
+
+ uiRadianceTimer = 16000;
+ } else uiRadianceTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_eadric(Creature* pCreature)
+{
+ return new boss_eadricAI(pCreature);
+}
+
+struct boss_paletressAI : public ScriptedAI
+{
+ boss_paletressAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+
+ MemoryGUID = 0;
+ pCreature->SetReactState(REACT_PASSIVE);
+ pCreature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE);
+ pCreature->RestoreFaction();
+ }
+
+ ScriptedInstance* pInstance;
+
+ Creature* pMemory;
+ uint64 MemoryGUID;
+
+ bool bHealth;
+ bool bDone;
+
+ uint32 uiHolyFireTimer;
+ uint32 uiHolySmiteTimer;
+ uint32 uiRenewTimer;
+ uint32 uiResetTimer;
+
+ void Reset()
+ {
+ me->RemoveAllAuras();
+
+ uiHolyFireTimer = urand(9000,12000);
+ uiHolySmiteTimer = urand(5000,7000);
+ uiRenewTimer = urand(2000,5000);
+
+ uiResetTimer = 7000;
+
+ bHealth = false;
+ bDone = false;
+
+ if (Creature *pMemory = Unit::GetCreature(*me, MemoryGUID))
+ if (pMemory->isAlive())
+ pMemory->RemoveFromWorld();
+ }
+
+ void SetData(uint32 uiId, uint32 /*uiValue*/)
+ {
+ if (uiId == 1)
+ me->RemoveAura(SPELL_SHIELD);
+ }
+
+ void DamageTaken(Unit * /*done_by*/, uint32 &damage)
+ {
+ if (damage >= me->GetHealth())
+ {
+ damage = 0;
+ EnterEvadeMode();
+ me->setFaction(35);
+ bDone = true;
+ }
+ }
+
+ void MovementInform(uint32 MovementType, uint32 Point)
+ {
+ if (MovementType != POINT_MOTION_TYPE || Point != 0)
+ return;
+
+ if (pInstance)
+ pInstance->SetData(BOSS_ARGENT_CHALLENGE_P, DONE);
+
+ me->DisappearAndDie();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (bDone && uiResetTimer <= uiDiff)
+ {
+ me->GetMotionMaster()->MovePoint(0,746.87,665.87,411.75);
+ bDone = false;
+ } else uiResetTimer -= uiDiff;
+
+ if (!UpdateVictim())
+ return;
+
+ if (uiHolyFireTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 250, true))
+ {
+ if (pTarget && pTarget->isAlive())
+ DoCast(pTarget,SPELL_HOLY_FIRE);
+ }
+ if (me->HasAura(SPELL_SHIELD))
+ uiHolyFireTimer = 13000;
+ else
+ uiHolyFireTimer = urand(9000,12000);
+ } else uiHolyFireTimer -= uiDiff;
+
+ if (uiHolySmiteTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 250, true))
+ {
+ if (pTarget && pTarget->isAlive())
+ DoCast(pTarget,SPELL_SMITE);
+ }
+ if (me->HasAura(SPELL_SHIELD))
+ uiHolySmiteTimer = 9000;
+ else
+ uiHolySmiteTimer = urand(5000,7000);
+ } else uiHolySmiteTimer -= uiDiff;
+
+ if (me->HasAura(SPELL_SHIELD))
+ if (uiRenewTimer <= uiDiff)
+ {
+ me->InterruptNonMeleeSpells(true);
+ uint8 uiTarget = urand(0,1);
+ switch(uiTarget)
+ {
+ case 0:
+ DoCast(me,SPELL_RENEW);
+ break;
+ case 1:
+ if (Creature *pMemory = Unit::GetCreature(*me, MemoryGUID))
+ if (pMemory->isAlive())
+ DoCast(pMemory, SPELL_RENEW);
+ break;
+ }
+ uiRenewTimer = urand(15000,17000);
+ } else uiRenewTimer -= uiDiff;
+
+
+ if (!bHealth && me->GetHealth()*100 / me->GetMaxHealth() <= 25)
+ {
+ me->InterruptNonMeleeSpells(true);
+ DoCastAOE(SPELL_HOLY_NOVA,false);
+ DoCast(me, SPELL_SHIELD);
+ DoCastAOE(SPELL_SUMMON_MEMORY,false);
+ DoCastAOE(SPELL_CONFESS,false);
+
+ bHealth = true;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustSummoned(Creature* pSummon)
+ {
+ MemoryGUID = pSummon->GetGUID();
+ }
+};
+
+CreatureAI* GetAI_boss_paletress(Creature* pCreature)
+{
+ return new boss_paletressAI(pCreature);
+}
+
+struct npc_memoryAI : public ScriptedAI
+{
+ npc_memoryAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint32 uiOldWoundsTimer;
+ uint32 uiShadowPastTimer;
+ uint32 uiWakingNightmare;
+
+ void Reset()
+ {
+ uiOldWoundsTimer = 12000;
+ uiShadowPastTimer = 5000;
+ uiWakingNightmare = 7000;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiOldWoundsTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
+ {
+ if (pTarget && pTarget->isAlive())
+ DoCast(pTarget, SPELL_OLD_WOUNDS);
+ }
+ uiOldWoundsTimer = 12000;
+ }else uiOldWoundsTimer -= uiDiff;
+
+ if (uiWakingNightmare <= uiDiff)
+ {
+ DoCast(me, SPELL_WAKING_NIGHTMARE);
+ uiWakingNightmare = 7000;
+ }else uiWakingNightmare -= uiDiff;
+
+ if (uiShadowPastTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,1))
+ {
+ if (pTarget && pTarget->isAlive())
+ DoCast(pTarget,SPELL_SHADOWS_PAST);
+ }
+ uiShadowPastTimer = 5000;
+ }else uiShadowPastTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ if (me->isSummon())
+ {
+ if (Unit* pSummoner = CAST_SUM(me)->GetSummoner())
+ {
+ if (pSummoner && pSummoner->isAlive())
+ CAST_CRE(pSummoner)->AI()->SetData(1,0);
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_memory(Creature* pCreature)
+{
+ return new npc_memoryAI(pCreature);
+}
+
+// THIS AI NEEDS MORE IMPROVEMENTS
+struct npc_argent_soldierAI : public npc_escortAI
+{
+ npc_argent_soldierAI(Creature* pCreature) : npc_escortAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ me->SetReactState(REACT_DEFENSIVE);
+ SetDespawnAtEnd(false);
+ uiWaypoint = 0;
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint8 uiWaypoint;
+
+ void WaypointReached(uint32 uiPoint)
+ {
+ if (uiPoint == 0)
+ {
+ switch(uiWaypoint)
+ {
+ case 0:
+ me->SetOrientation(5.81);
+ break;
+ case 1:
+ me->SetOrientation(4.60);
+ break;
+ case 2:
+ me->SetOrientation(2.79);
+ break;
+ }
+
+ me->SendMovementFlagUpdate();
+ }
+ }
+
+ void SetData(uint32 uiType, uint32 /*uiData*/)
+ {
+ switch(me->GetEntry())
+ {
+ case NPC_ARGENT_LIGHWIELDER:
+ switch(uiType)
+ {
+ case 0:
+ AddWaypoint(0,712.14,628.42,411.88);
+ break;
+ case 1:
+ AddWaypoint(0,742.44,650.29,411.79);
+ break;
+ case 2:
+ AddWaypoint(0,783.33,615.29,411.84);
+ break;
+ }
+ break;
+ case NPC_ARGENT_MONK:
+ switch(uiType)
+ {
+ case 0:
+ AddWaypoint(0,713.12,632.97,411.90);
+ break;
+ case 1:
+ AddWaypoint(0,746.73,650.24,411.56);
+ break;
+ case 2:
+ AddWaypoint(0,781.32,610.54,411.82);
+ break;
+ }
+ break;
+ case NPC_PRIESTESS:
+ switch(uiType)
+ {
+ case 0:
+ AddWaypoint(0,715.06,637.07,411.91);
+ break;
+ case 1:
+ AddWaypoint(0,750.72,650.20,411.77);
+ break;
+ case 2:
+ AddWaypoint(0,779.77,607.03,411.81);
+ break;
+ }
+ break;
+ }
+
+ Start(false,true,0);
+ uiWaypoint = uiType;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ npc_escortAI::UpdateAI(uiDiff);
+
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_ARGENT_SOLDIER_DEFEATED,pInstance->GetData(DATA_ARGENT_SOLDIER_DEFEATED) + 1);
+ }
+};
+
+CreatureAI* GetAI_npc_argent_soldier(Creature* pCreature)
+{
+ return new npc_argent_soldierAI(pCreature);
+}
+
+void AddSC_boss_argent_challenge()
+{
+ Script* NewScript;
+
+ NewScript = new Script;
+ NewScript->Name = "boss_eadric";
+ NewScript->GetAI = &GetAI_boss_eadric;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "boss_paletress";
+ NewScript->GetAI = &GetAI_boss_paletress;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "npc_memory";
+ NewScript->GetAI = &GetAI_npc_memory;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "npc_argent_soldier";
+ NewScript->GetAI = &GetAI_npc_argent_soldier;
+ NewScript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp b/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp
new file mode 100644
index 00000000000..e1f4586ca6c
--- /dev/null
+++ b/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_black_knight.cpp
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Boss Black Knight
+SD%Complete: 80%
+SDComment: missing yells. not sure about timers.
+SDCategory: Trial of the Champion
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "ScriptedEscortAI.h"
+#include "trial_of_the_champion.h"
+
+enum eSpells
+{
+ //phase 1
+ SPELL_PLAGUE_STRIKE = 67884,
+ SPELL_PLAGUE_STRIKE_2 = 67724,
+ SPELL_ICY_TOUCH_H = 67881,
+ SPELL_ICY_TOUCH = 67718,
+ SPELL_DEATH_RESPITE = 67745,
+ SPELL_DEATH_RESPITE_2 = 68306,
+ SPELL_DEATH_RESPITE_3 = 66798,
+ SPELL_OBLITERATE_H = 67883,
+ SPELL_OBLITERATE = 67725,
+ //in this phase should rise herald (the spell is missing)
+
+ //phase 2 - During this phase, the Black Knight will use the same abilities as in phase 1, except for Death's Respite
+ SPELL_ARMY_DEAD = 67761,
+ SPELL_DESECRATION = 67778,
+ SPELL_DESECRATION_2 = 67778,
+ SPELL_GHOUL_EXPLODE = 67751,
+
+ //phase 3
+ SPELL_DEATH_BITE_H = 67875,
+ SPELL_DEATH_BITE = 67808,
+ SPELL_MARKED_DEATH = 67882,
+ SPELL_MARKED_DEATH_2 = 67823,
+
+ SPELL_BLACK_KNIGHT_RES = 67693,
+
+ SPELL_LEAP = 67749,
+ SPELL_LEAP_H = 67880
+};
+
+enum eModels
+{
+ MODEL_SKELETON = 29846,
+ MODEL_GHOST = 21300
+};
+
+enum ePhases
+{
+ PHASE_UNDEAD = 1,
+ PHASE_SKELETON = 2,
+ PHASE_GHOST = 3
+};
+
+struct boss_black_knightAI : public ScriptedAI
+{
+ boss_black_knightAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ std::list<uint64> SummonList;
+
+ bool bEventInProgress;
+ bool bEvent;
+ bool bSummonArmy;
+ bool bDeathArmyDone;
+
+ uint8 uiPhase;
+
+ uint32 uiPlagueStrikeTimer;
+ uint32 uiIcyTouchTimer;
+ uint32 uiDeathRespiteTimer;
+ uint32 uiObliterateTimer;
+ uint32 uiDesecration;
+ uint32 uiResurrectTimer;
+ uint32 uiDeathArmyCheckTimer;
+ uint32 uiGhoulExplodeTimer;
+ uint32 uiDeathBiteTimer;
+ uint32 uiMarkedDeathTimer;
+
+ void Reset()
+ {
+ RemoveSummons();
+ me->SetDisplayId(me->GetNativeDisplayId());
+ me->clearUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
+
+ bEventInProgress = false;
+ bEvent = false;
+ bSummonArmy = false;
+ bDeathArmyDone = false;
+
+ uiPhase = PHASE_UNDEAD;
+
+ uiIcyTouchTimer = urand(5000,9000);
+ uiPlagueStrikeTimer = urand(10000,13000);
+ uiDeathRespiteTimer = urand(15000,16000);
+ uiObliterateTimer = urand(17000,19000);
+ uiDesecration = urand(15000,16000);
+ uiDeathArmyCheckTimer = 7000;
+ uiResurrectTimer = 4000;
+ uiGhoulExplodeTimer = 8000;
+ uiDeathBiteTimer = urand (2000,4000);
+ uiMarkedDeathTimer = urand (5000,7000);
+ }
+
+ void RemoveSummons()
+ {
+ if (SummonList.empty())
+ return;
+
+ for (std::list<uint64>::const_iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr)
+ {
+ if (Creature* pTemp = Unit::GetCreature(*me, *itr))
+ if (pTemp)
+ pTemp->DisappearAndDie();
+ }
+ SummonList.clear();
+ }
+
+ void JustSummoned(Creature* pSummon)
+ {
+ SummonList.push_back(pSummon->GetGUID());
+ pSummon->AI()->AttackStart(me->getVictim());
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (bEventInProgress)
+ if (uiResurrectTimer <= uiDiff)
+ {
+ me->SetHealth(me->GetMaxHealth());
+ DoCast(me,SPELL_BLACK_KNIGHT_RES,true);
+ uiPhase++;
+ uiResurrectTimer = 4000;
+ bEventInProgress = false;
+ me->clearUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
+ } else uiResurrectTimer -= uiDiff;
+
+ switch(uiPhase)
+ {
+ case PHASE_UNDEAD:
+ case PHASE_SKELETON:
+ {
+ if (uiIcyTouchTimer <= uiDiff)
+ {
+ DoCastVictim(SPELL_ICY_TOUCH);
+ uiIcyTouchTimer = urand(5000,7000);
+ } else uiIcyTouchTimer -= uiDiff;
+ if (uiPlagueStrikeTimer <= uiDiff)
+ {
+ DoCastVictim(SPELL_ICY_TOUCH);
+ uiPlagueStrikeTimer = urand(12000,15000);
+ } else uiPlagueStrikeTimer -= uiDiff;
+ if (uiObliterateTimer <= uiDiff)
+ {
+ DoCastVictim(SPELL_OBLITERATE);
+ uiObliterateTimer = urand(17000,19000);
+ } else uiObliterateTimer -= uiDiff;
+ switch(uiPhase)
+ {
+ case PHASE_UNDEAD:
+ {
+ if (uiDeathRespiteTimer <= uiDiff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ {
+ if (pTarget && pTarget->isAlive())
+ DoCast(pTarget,SPELL_DEATH_RESPITE);
+ }
+ uiDeathRespiteTimer = urand(15000,16000);
+ } else uiDeathRespiteTimer -= uiDiff;
+ break;
+ }
+ case PHASE_SKELETON:
+ {
+ if (!bSummonArmy)
+ {
+ bSummonArmy = true;
+ me->addUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
+ DoCast(me, SPELL_ARMY_DEAD);
+ }
+ if (!bDeathArmyDone)
+ if (uiDeathArmyCheckTimer <= uiDiff)
+ {
+ me->clearUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
+ uiDeathArmyCheckTimer = 0;
+ bDeathArmyDone = true;
+ } else uiDeathArmyCheckTimer -= uiDiff;
+ if (uiDesecration <= uiDiff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ {
+ if (pTarget && pTarget->isAlive())
+ DoCast(pTarget,SPELL_DESECRATION);
+ }
+ uiDesecration = urand(15000,16000);
+ } else uiDesecration -= uiDiff;
+ if (uiGhoulExplodeTimer <= uiDiff)
+ {
+ DoCast(me, SPELL_GHOUL_EXPLODE);
+ uiGhoulExplodeTimer = 8000;
+ } else uiGhoulExplodeTimer -= uiDiff;
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ case PHASE_GHOST:
+ {
+ if (uiDeathBiteTimer <= uiDiff)
+ {
+ DoCastAOE(SPELL_DEATH_BITE);
+ uiDeathBiteTimer = urand (2000, 4000);
+ } else uiDeathBiteTimer -= uiDiff;
+ if (uiMarkedDeathTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ {
+ if (pTarget && pTarget->isAlive())
+ DoCast(pTarget,SPELL_MARKED_DEATH);
+ }
+ uiMarkedDeathTimer = urand (5000, 7000);
+ } else uiMarkedDeathTimer -= uiDiff;
+ break;
+ }
+ }
+
+ if (!me->hasUnitState(UNIT_STAT_ROOT) && !me->GetHealth()*100 / me->GetMaxHealth() <= 0)
+ DoMeleeAttackIfReady();
+ }
+
+ void DamageTaken(Unit* /*pDoneBy*/, uint32& uiDamage)
+ {
+ if (uiDamage > me->GetHealth() && uiPhase <= PHASE_SKELETON)
+ {
+ uiDamage = 0;
+ me->SetHealth(0);
+ me->addUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED);
+ RemoveSummons();
+ switch(uiPhase)
+ {
+ case PHASE_UNDEAD:
+ me->SetDisplayId(MODEL_SKELETON);
+ break;
+ case PHASE_SKELETON:
+ me->SetDisplayId(MODEL_GHOST);
+ break;
+ }
+ bEventInProgress = true;
+ }
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ if (pInstance)
+ pInstance->SetData(BOSS_BLACK_KNIGHT,DONE);
+ }
+};
+
+CreatureAI* GetAI_boss_black_knight(Creature *pCreature)
+{
+ return new boss_black_knightAI (pCreature);
+}
+
+struct npc_risen_ghoulAI : public ScriptedAI
+{
+ npc_risen_ghoulAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint32 uiAttackTimer;
+
+ void Reset()
+ {
+ uiAttackTimer = 3500;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiAttackTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true))
+ {
+ if (pTarget && pTarget->isAlive())
+ DoCast(pTarget, (SPELL_LEAP));
+ }
+ uiAttackTimer = 3500;
+ } else uiAttackTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_risen_ghoul(Creature* pCreature)
+{
+ return new npc_risen_ghoulAI(pCreature);
+}
+
+struct npc_black_knight_skeletal_gryphonAI : public npc_escortAI
+{
+ npc_black_knight_skeletal_gryphonAI(Creature* pCreature) : npc_escortAI(pCreature)
+ {
+ Start(false,true,0,NULL);
+ }
+
+ void WaypointReached(uint32 /*i*/)
+ {
+
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ npc_escortAI::UpdateAI(uiDiff);
+
+ if (!UpdateVictim())
+ return;
+ }
+
+};
+
+CreatureAI* GetAI_npc_black_knight_skeletal_gryphon(Creature* pCreature)
+{
+ return new npc_black_knight_skeletal_gryphonAI(pCreature);
+}
+
+void AddSC_boss_black_knight()
+{
+ Script* NewScript;
+
+ NewScript = new Script;
+ NewScript->Name = "boss_black_knight";
+ NewScript->GetAI = &GetAI_boss_black_knight;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "npc_risen_ghoul";
+ NewScript->GetAI = &GetAI_npc_risen_ghoul;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "npc_black_knight_skeletal_gryphon";
+ NewScript->GetAI = &GetAI_npc_black_knight_skeletal_gryphon;
+ NewScript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp b/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp
new file mode 100644
index 00000000000..4bf8143a210
--- /dev/null
+++ b/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/boss_grand_champions.cpp
@@ -0,0 +1,993 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+* 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: boss_grand_champions
+SD%Complete: 50 %
+SDComment: Is missing the ai to make the npcs look for a new mount and use it.
+SDCategory: Trial Of the Champion
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "ScriptedEscortAI.h"
+#include "Vehicle.h"
+#include "trial_of_the_champion.h"
+
+enum eSpells
+{
+ //Vehicle
+ SPELL_CHARGE = 63010,
+ SPELL_SHIELD_BREAKER = 68504,
+ SPELL_SHIELD = 66482,
+
+ // Marshal Jacob Alerius && Mokra the Skullcrusher || Warrior
+ SPELL_MORTAL_STRIKE = 68783,
+ SPELL_MORTAL_STRIKE_H = 68784,
+ SPELL_BLADESTORM = 63784,
+ SPELL_INTERCEPT = 67540,
+ SPELL_ROLLING_THROW = 47115, //not implemented in the AI yet...
+
+ // Ambrose Boltspark && Eressea Dawnsinger || Mage
+ SPELL_FIREBALL = 66042,
+ SPELL_FIREBALL_H = 68310,
+ SPELL_BLAST_WAVE = 66044,
+ SPELL_BLAST_WAVE_H = 68312,
+ SPELL_HASTE = 66045,
+ SPELL_POLYMORPH = 66043,
+ SPELL_POLYMORPH_H = 68311,
+
+ // Colosos && Runok Wildmane || Shaman
+ SPELL_CHAIN_LIGHTNING = 67529,
+ SPELL_CHAIN_LIGHTNING_H = 68319,
+ SPELL_EARTH_SHIELD = 67530,
+ SPELL_HEALING_WAVE = 67528,
+ SPELL_HEALING_WAVE_H = 68318,
+ SPELL_HEX_OF_MENDING = 67534,
+
+ // Jaelyne Evensong && Zul'tore || Hunter
+ SPELL_DISENGAGE = 68340, //not implemented in the AI yet...
+ SPELL_LIGHTNING_ARROWS = 66083,
+ SPELL_MULTI_SHOT = 66081,
+ SPELL_SHOOT = 65868,
+ SPELL_SHOOT_H = 67988,
+
+ // Lana Stouthammer Evensong && Deathstalker Visceri || Rouge
+ SPELL_EVISCERATE = 67709,
+ SPELL_EVISCERATE_H = 68317,
+ SPELL_FAN_OF_KNIVES = 67706,
+ SPELL_POISON_BOTTLE = 67701
+};
+
+enum eSeat
+{
+ SEAT_ID_0 = 0
+};
+
+struct Point
+{
+ float x,y,z;
+};
+
+const Point MovementPoint[] =
+{
+ {746.84,623.15,411.41},
+ {747.96,620.29,411.09},
+ {750.23,618.35,411.09}
+};
+
+void AggroAllPlayers(Creature* pTemp)
+{
+ Map::PlayerList const &PlList = pTemp->GetMap()->GetPlayers();
+
+ if (PlList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i)
+ {
+ if (Player* pPlayer = i->getSource())
+ {
+ if (pPlayer->isGameMaster())
+ continue;
+
+ if (pPlayer->isAlive())
+ {
+ pTemp->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ pTemp->SetReactState(REACT_AGGRESSIVE);
+ pTemp->SetInCombatWith(pPlayer);
+ pPlayer->SetInCombatWith(pTemp);
+ pTemp->AddThreat(pPlayer, 0.0f);
+ }
+ }
+ }
+}
+
+bool GrandChampionsOutVehicle(Creature* me)
+{
+ ScriptedInstance* pInstance = me->GetInstanceData();
+
+ if (!pInstance)
+ return false;
+
+ Creature* pGrandChampion1 = Unit::GetCreature(*me, pInstance->GetData64(DATA_GRAND_CHAMPION_1));
+ Creature* pGrandChampion2 = Unit::GetCreature(*me, pInstance->GetData64(DATA_GRAND_CHAMPION_2));
+ Creature* pGrandChampion3 = Unit::GetCreature(*me, pInstance->GetData64(DATA_GRAND_CHAMPION_3));
+
+ if (pGrandChampion1 && pGrandChampion2 && pGrandChampion3)
+ {
+ if (!pGrandChampion1->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) &&
+ !pGrandChampion2->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) &&
+ !pGrandChampion3->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ return true;
+ }
+
+ return false;
+}
+
+/*
+* Generic AI for vehicles used by npcs in ToC, it needs more improvements. *
+* Script Complete: 25%. *
+*/
+
+struct generic_vehicleAI_toc5AI : public npc_escortAI
+{
+ generic_vehicleAI_toc5AI(Creature* pCreature) : npc_escortAI(pCreature)
+ {
+ SetDespawnAtEnd(false);
+ uiWaypointPath = 0;
+
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiChargeTimer;
+ uint32 uiShieldBreakerTimer;
+ uint32 uiBuffTimer;
+
+ uint32 uiWaypointPath;
+
+ void Reset()
+ {
+ uiChargeTimer = 5000;
+ uiShieldBreakerTimer = 8000;
+ uiBuffTimer = urand(30000,60000);
+ }
+
+ void SetData(uint32 uiType, uint32 /*uiData*/)
+ {
+ switch(uiType)
+ {
+ case 1:
+ AddWaypoint(0,747.36,634.07,411.572);
+ AddWaypoint(1,780.43,607.15,411.82);
+ AddWaypoint(2,785.99,599.41,411.92);
+ AddWaypoint(3,778.44,601.64,411.79);
+ uiWaypointPath = 1;
+ break;
+ case 2:
+ AddWaypoint(0,747.35,634.07,411.57);
+ AddWaypoint(1,768.72,581.01,411.92);
+ AddWaypoint(2,763.55,590.52,411.71);
+ uiWaypointPath = 2;
+ break;
+ case 3:
+ AddWaypoint(0,747.35,634.07,411.57);
+ AddWaypoint(1,784.02,645.33,412.39);
+ AddWaypoint(2,775.67,641.91,411.91);
+ uiWaypointPath = 3;
+ break;
+ }
+
+ if (uiType <= 3)
+ Start(false,true,0,NULL);
+ }
+
+ void WaypointReached(uint32 i)
+ {
+ switch(i)
+ {
+ case 2:
+ if (pInstance && uiWaypointPath == 3 || uiWaypointPath == 2)
+ pInstance->SetData(DATA_MOVEMENT_DONE, pInstance->GetData(DATA_MOVEMENT_DONE)+1);
+ break;
+ case 3:
+ if (pInstance)
+ pInstance->SetData(DATA_MOVEMENT_DONE, pInstance->GetData(DATA_MOVEMENT_DONE)+1);
+ break;
+ }
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoCastSpellShield();
+ }
+
+ void DoCastSpellShield()
+ {
+ for (uint8 i = 0; i < 3; ++i)
+ DoCast(me,SPELL_SHIELD,true);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ npc_escortAI::UpdateAI(uiDiff);
+
+ if (!UpdateVictim())
+ return;
+
+ if (uiBuffTimer <= uiDiff)
+ {
+ if (!me->HasAura(SPELL_SHIELD))
+ DoCastSpellShield();
+
+ uiBuffTimer = urand(30000,45000);
+ }else uiBuffTimer -= uiDiff;
+
+ if (uiChargeTimer <= uiDiff)
+ {
+ Map::PlayerList const& players = me->GetMap()->GetPlayers();
+ if (me->GetMap()->IsDungeon() && !players.isEmpty())
+ {
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ {
+ Player* pPlayer = itr->getSource();
+ if (pPlayer && !pPlayer->isGameMaster() && me->IsInRange(pPlayer,8.0f,25.0f,false))
+ {
+ DoResetThreat();
+ me->AddThreat(pPlayer,1.0f);
+ DoCast(pPlayer, SPELL_CHARGE);
+ break;
+ }
+ }
+ }
+ uiChargeTimer = 5000;
+ }else uiChargeTimer -= uiDiff;
+
+ //dosen't work at all
+ if (uiShieldBreakerTimer <= uiDiff)
+ {
+ Vehicle *pVehicle = me->GetVehicleKit();
+ if (!pVehicle)
+ return;
+
+ if (Unit* pPassenger = pVehicle->GetPassenger(SEAT_ID_0))
+ {
+ Map::PlayerList const& players = me->GetMap()->GetPlayers();
+ if (me->GetMap()->IsDungeon() && !players.isEmpty())
+ {
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ {
+ Player* pPlayer = itr->getSource();
+ if (pPlayer && !pPlayer->isGameMaster() && me->IsInRange(pPlayer,10.0f,30.0f,false))
+ {
+ pPassenger->CastSpell(pPlayer,SPELL_SHIELD_BREAKER,true);
+ break;
+ }
+ }
+ }
+ }
+ uiShieldBreakerTimer = 7000;
+ }else uiShieldBreakerTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_generic_vehicleAI_toc5(Creature* pCreature)
+{
+ return new generic_vehicleAI_toc5AI(pCreature);
+}
+
+// Marshal Jacob Alerius && Mokra the Skullcrusher || Warrior
+struct boss_warrior_toc5AI : public ScriptedAI
+{
+ boss_warrior_toc5AI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+
+ bDone = false;
+ bHome = false;
+
+ uiPhase = 0;
+ uiPhaseTimer = 0;
+
+ me->SetReactState(REACT_PASSIVE);
+ // THIS IS A HACK, SHOULD BE REMOVED WHEN THE EVENT IS FULL SCRIPTED
+ me->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint8 uiPhase;
+ uint32 uiPhaseTimer;
+
+ uint32 uiBladeStormTimer;
+ uint32 uiInterceptTimer;
+ uint32 uiMortalStrikeTimer;
+ uint32 uiAttackTimer;
+
+ bool bDone;
+ bool bHome;
+
+ void Reset()
+ {
+ uiBladeStormTimer = urand(15000,20000);
+ uiInterceptTimer = 7000;
+ uiMortalStrikeTimer = urand(8000,12000);
+ }
+
+ void JustReachedHome()
+ {
+ ScriptedAI::JustReachedHome();
+
+ if (!bHome)
+ return;
+
+ uiPhaseTimer = 15000;
+ uiPhase = 1;
+
+ bHome = false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!bDone && GrandChampionsOutVehicle(me))
+ {
+ bDone = true;
+
+ if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_1))
+ me->SetHomePosition(739.678,662.541,412.393,4.49);
+ else if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_2))
+ me->SetHomePosition(746.71,661.02,411.69,4.6);
+ else if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_3))
+ me->SetHomePosition(754.34,660.70,412.39,4.79);
+
+ EnterEvadeMode();
+ bHome = true;
+ }
+
+ if (uiPhaseTimer <= uiDiff)
+ {
+ if (uiPhase == 1)
+ {
+ AggroAllPlayers(me);
+ uiPhase = 0;
+ }
+ }else uiPhaseTimer -= uiDiff;
+
+ if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ return;
+
+ if (uiInterceptTimer <= uiDiff)
+ {
+ Map::PlayerList const& players = me->GetMap()->GetPlayers();
+ if (me->GetMap()->IsDungeon() && !players.isEmpty())
+ {
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ {
+ Player* pPlayer = itr->getSource();
+ if (pPlayer && !pPlayer->isGameMaster() && me->IsInRange(pPlayer,8.0f,25.0f,false))
+ {
+ DoResetThreat();
+ me->AddThreat(pPlayer,5.0f);
+ DoCast(pPlayer,SPELL_INTERCEPT);
+ break;
+ }
+ }
+ }
+ uiInterceptTimer = 7000;
+ } else uiInterceptTimer -= uiDiff;
+
+ if (uiBladeStormTimer <= uiDiff)
+ {
+ DoCastVictim(SPELL_BLADESTORM);
+ uiBladeStormTimer = urand(15000,20000);
+ } else uiBladeStormTimer -= uiDiff;
+
+ if (uiMortalStrikeTimer <= uiDiff)
+ {
+ DoCastVictim(SPELL_MORTAL_STRIKE);
+ uiMortalStrikeTimer = urand(8000,12000);
+ } else uiMortalStrikeTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ if (pInstance)
+ pInstance->SetData(BOSS_GRAND_CHAMPIONS, DONE);
+ }
+};
+
+CreatureAI* GetAI_boss_warrior_toc5(Creature* pCreature)
+{
+ return new boss_warrior_toc5AI(pCreature);
+}
+
+// Ambrose Boltspark && Eressea Dawnsinger || Mage
+struct boss_mage_toc5AI : public ScriptedAI
+{
+ boss_mage_toc5AI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+
+ bDone = false;
+ bHome = false;
+
+ uiPhase = 0;
+ uiPhaseTimer = 0;
+
+ me->SetReactState(REACT_PASSIVE);
+ // THIS IS A HACK, SHOULD BE REMOVED WHEN THE EVENT IS FULL SCRIPTED
+ me->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint8 uiPhase;
+ uint32 uiPhaseTimer;
+
+ uint32 uiFireBallTimer;
+ uint32 uiBlastWaveTimer;
+ uint32 uiHasteTimer;
+ uint32 uiPolymorphTimer;
+
+ bool bDone;
+ bool bHome;
+
+ void Reset()
+ {
+ uiFireBallTimer = 5000;
+ uiPolymorphTimer = 8000;
+ uiBlastWaveTimer = 12000;
+ uiHasteTimer = 22000;
+ }
+
+ void JustReachedHome()
+ {
+ ScriptedAI::JustReachedHome();
+
+ if (!bHome)
+ return;
+
+ uiPhaseTimer = 15000;
+ uiPhase = 1;
+
+ bHome = false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!bDone && GrandChampionsOutVehicle(me))
+ {
+ bDone = true;
+
+ if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_1))
+ me->SetHomePosition(739.678,662.541,412.393,4.49);
+ else if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_2))
+ me->SetHomePosition(746.71,661.02,411.69,4.6);
+ else if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_3))
+ me->SetHomePosition(754.34,660.70,412.39,4.79);
+
+ if (pInstance)
+ pInstance->SetData(BOSS_GRAND_CHAMPIONS, IN_PROGRESS);
+
+ EnterEvadeMode();
+ bHome = true;
+ }
+
+ if (uiPhaseTimer <= uiDiff)
+ {
+ if (uiPhase == 1)
+ {
+ AggroAllPlayers(me);
+ uiPhase = 0;
+ }
+ }else uiPhaseTimer -= uiDiff;
+
+ if (uiFireBallTimer <= uiDiff)
+ {
+ if (me->getVictim())
+ DoCastVictim(SPELL_FIREBALL);
+ uiFireBallTimer = 5000;
+ } else uiFireBallTimer -= uiDiff;
+
+
+ if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ return;
+
+ if (uiFireBallTimer <= uiDiff)
+ {
+ DoCastVictim(SPELL_FIREBALL);
+ uiFireBallTimer = 5000;
+ } else uiFireBallTimer -= uiDiff;
+
+ if (uiPolymorphTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
+ DoCast(pTarget, SPELL_POLYMORPH);
+ uiPolymorphTimer = 8000;
+ } else uiPolymorphTimer -= uiDiff;
+
+ if (uiBlastWaveTimer <= uiDiff)
+ {
+ DoCastAOE(SPELL_BLAST_WAVE,false);
+ uiBlastWaveTimer = 13000;
+ } else uiBlastWaveTimer -= uiDiff;
+
+ if (uiHasteTimer <= uiDiff)
+ {
+ me->InterruptNonMeleeSpells(true);
+
+ DoCast(me,SPELL_HASTE);
+ uiHasteTimer = 22000;
+ } else uiHasteTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ if (pInstance)
+ pInstance->SetData(BOSS_GRAND_CHAMPIONS, DONE);
+ }
+};
+
+CreatureAI* GetAI_boss_mage_toc5(Creature* pCreature)
+{
+ return new boss_mage_toc5AI(pCreature);
+}
+
+// Colosos && Runok Wildmane || Shaman
+struct boss_shaman_toc5AI : public ScriptedAI
+{
+ boss_shaman_toc5AI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+
+ bDone = false;
+ bHome = false;
+
+ uiPhase = 0;
+ uiPhaseTimer = 0;
+
+ me->SetReactState(REACT_PASSIVE);
+ // THIS IS A HACK, SHOULD BE REMOVED WHEN THE EVENT IS FULL SCRIPTED
+ me->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint8 uiPhase;
+ uint32 uiPhaseTimer;
+
+ uint32 uiChainLightningTimer;
+ uint32 uiEartShieldTimer;
+ uint32 uiHealingWaveTimer;
+ uint32 uiHexMendingTimer;
+
+ bool bDone;
+ bool bHome;
+
+ void Reset()
+ {
+ uiChainLightningTimer = 16000;
+ uiHealingWaveTimer = 12000;
+ uiEartShieldTimer = urand(30000,35000);
+ uiHexMendingTimer = urand(20000,25000);
+ }
+
+ void EnterCombat(Unit* pWho)
+ {
+ DoCast(me,SPELL_EARTH_SHIELD);
+ DoCast(pWho,SPELL_HEX_OF_MENDING);
+ };
+
+ void JustReachedHome()
+ {
+ ScriptedAI::JustReachedHome();
+
+ if (!bHome)
+ return;
+
+ uiPhaseTimer = 15000;
+ uiPhase = 1;
+
+ bHome = false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!bDone && GrandChampionsOutVehicle(me))
+ {
+ bDone = true;
+
+ if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_1))
+ me->SetHomePosition(739.678,662.541,412.393,4.49);
+ else if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_2))
+ me->SetHomePosition(746.71,661.02,411.69,4.6);
+ else if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_3))
+ me->SetHomePosition(754.34,660.70,412.39,4.79);
+
+ if (pInstance)
+ pInstance->SetData(BOSS_GRAND_CHAMPIONS, IN_PROGRESS);
+
+ EnterEvadeMode();
+ bHome = true;
+ }
+
+ if (uiPhaseTimer <= uiDiff)
+ {
+ if (uiPhase == 1)
+ {
+ AggroAllPlayers(me);
+ uiPhase = 0;
+ }
+ }else uiPhaseTimer -= uiDiff;
+
+ if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ return;
+
+ if (uiChainLightningTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
+ DoCast(pTarget,SPELL_CHAIN_LIGHTNING);
+
+ uiChainLightningTimer = 16000;
+ } else uiChainLightningTimer -= uiDiff;
+
+ if (uiHealingWaveTimer <= uiDiff)
+ {
+ bool bChance = urand(0,1);
+
+ if (!bChance)
+ {
+ if (Unit* pFriend = DoSelectLowestHpFriendly(40))
+ DoCast(pFriend,SPELL_HEALING_WAVE);
+ } else
+ DoCast(me,SPELL_HEALING_WAVE);
+
+ uiHealingWaveTimer = 12000;
+ } else uiHealingWaveTimer -= uiDiff;
+
+ if (uiEartShieldTimer <= uiDiff)
+ {
+ DoCast(me,SPELL_EARTH_SHIELD);
+
+ uiEartShieldTimer = urand(30000,35000);
+ } else uiEartShieldTimer -= uiDiff;
+
+ if (uiHexMendingTimer <= uiDiff)
+ {
+ DoCastVictim(SPELL_HEX_OF_MENDING,true);
+
+ uiHexMendingTimer = urand(20000,25000);
+ } else uiHexMendingTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ if (pInstance)
+ pInstance->SetData(BOSS_GRAND_CHAMPIONS, DONE);
+ }
+};
+
+CreatureAI* GetAI_boss_shaman_toc5(Creature* pCreature)
+{
+ return new boss_shaman_toc5AI(pCreature);
+}
+
+// Jaelyne Evensong && Zul'tore || Hunter
+struct boss_hunter_toc5AI : public ScriptedAI
+{
+ boss_hunter_toc5AI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+
+ bDone = false;
+ bHome = false;
+
+ uiPhase = 0;
+ uiPhaseTimer = 0;
+
+ me->SetReactState(REACT_PASSIVE);
+ // THIS IS A HACK, SHOULD BE REMOVED WHEN THE EVENT IS FULL SCRIPTED
+ me->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint8 uiPhase;
+ uint32 uiPhaseTimer;
+
+ uint32 uiShootTimer;
+ uint32 uiMultiShotTimer;
+ uint32 uiLightningArrowsTimer;
+
+ uint64 uiTargetGUID;
+
+ bool bShoot;
+ bool bDone;
+ bool bHome;
+
+ void Reset()
+ {
+ uiShootTimer = 12000;
+ uiMultiShotTimer = 0;
+ uiLightningArrowsTimer = 7000;
+
+ uiTargetGUID = 0;
+
+ bShoot = false;
+ }
+
+ void JustReachedHome()
+ {
+ ScriptedAI::JustReachedHome();
+
+ if (!bHome)
+ return;
+
+ uiPhaseTimer = 15000;
+ uiPhase = 1;
+
+ bHome = false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!bDone && GrandChampionsOutVehicle(me))
+ {
+ bDone = true;
+
+ if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_1))
+ me->SetHomePosition(739.678,662.541,412.393,4.49);
+ else if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_2))
+ me->SetHomePosition(746.71,661.02,411.69,4.6);
+ else if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_3))
+ me->SetHomePosition(754.34,660.70,412.39,4.79);
+
+ if (pInstance)
+ pInstance->SetData(BOSS_GRAND_CHAMPIONS, IN_PROGRESS);
+
+ EnterEvadeMode();
+ bHome = true;
+ }
+
+ if (uiPhaseTimer <= uiDiff)
+ {
+ if (uiPhase == 1)
+ {
+ AggroAllPlayers(me);
+ uiPhase = 0;
+ }
+ }else uiPhaseTimer -= uiDiff;
+
+ if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ return;
+
+ if (uiLightningArrowsTimer <= uiDiff)
+ {
+ DoCastAOE(SPELL_LIGHTNING_ARROWS,false);
+ uiLightningArrowsTimer = 7000;
+ } else uiLightningArrowsTimer -= uiDiff;
+
+ if (uiShootTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_FARTHEST,0,30.0f))
+ {
+ uiTargetGUID = pTarget->GetGUID();
+ DoCast(pTarget, SPELL_SHOOT);
+ }
+ uiShootTimer = 12000;
+ uiMultiShotTimer = 3000;
+ bShoot = true;
+ } else uiShootTimer -= uiDiff;
+
+ if (bShoot && uiMultiShotTimer <= uiDiff)
+ {
+ me->InterruptNonMeleeSpells(true);
+ Unit* pTarget = Unit::GetUnit(*me, uiTargetGUID);
+
+ if (pTarget && me->IsInRange(pTarget,5.0f,30.0f,false))
+ {
+ DoCast(pTarget,SPELL_MULTI_SHOT);
+ } else
+ {
+ Map::PlayerList const& players = me->GetMap()->GetPlayers();
+ if (me->GetMap()->IsDungeon() && !players.isEmpty())
+ {
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ {
+ Player* pPlayer = itr->getSource();
+ if (pPlayer && !pPlayer->isGameMaster() && me->IsInRange(pPlayer,5.0f,30.0f,false))
+ {
+ DoCast(pTarget,SPELL_MULTI_SHOT);
+ break;
+ }
+ }
+ }
+ }
+ bShoot = false;
+ } else uiMultiShotTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ if (pInstance)
+ pInstance->SetData(BOSS_GRAND_CHAMPIONS, DONE);
+ }
+};
+
+CreatureAI* GetAI_boss_hunter_toc5(Creature* pCreature)
+{
+ return new boss_hunter_toc5AI(pCreature);
+}
+
+// Lana Stouthammer Evensong && Deathstalker Visceri || Rouge
+struct boss_rouge_toc5AI : public ScriptedAI
+{
+ boss_rouge_toc5AI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+
+ bDone = false;
+ bHome = false;
+
+ uiPhase = 0;
+ uiPhaseTimer = 0;
+
+ me->SetReactState(REACT_PASSIVE);
+ // THIS IS A HACK, SHOULD BE REMOVED WHEN THE EVENT IS FULL SCRIPTED
+ me->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint8 uiPhase;
+ uint32 uiPhaseTimer;
+ uint32 uiEviscerateTimer;
+ uint32 uiFanKivesTimer;
+ uint32 uiPosionBottleTimer;
+
+ bool bDone;
+ bool bHome;
+
+ void Reset()
+ {
+ uiEviscerateTimer = 8000;
+ uiFanKivesTimer = 14000;
+ uiPosionBottleTimer = 19000;
+ }
+
+ void JustReachedHome()
+ {
+ ScriptedAI::JustReachedHome();
+
+ if (!bHome)
+ return;
+
+ uiPhaseTimer = 15000;
+ uiPhase = 1;
+
+ bHome = false;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!bDone && GrandChampionsOutVehicle(me))
+ {
+ bDone = true;
+
+ if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_1))
+ me->SetHomePosition(739.678,662.541,412.393,4.49);
+ else if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_2))
+ me->SetHomePosition(746.71,661.02,411.69,4.6);
+ else if (pInstance && me->GetGUID() == pInstance->GetData64(DATA_GRAND_CHAMPION_3))
+ me->SetHomePosition(754.34,660.70,412.39,4.79);
+
+ if (pInstance)
+ pInstance->SetData(BOSS_GRAND_CHAMPIONS, IN_PROGRESS);
+
+ EnterEvadeMode();
+ bHome = true;
+ }
+
+ if (uiPhaseTimer <= uiDiff)
+ {
+ if (uiPhase == 1)
+ {
+ AggroAllPlayers(me);
+ uiPhase = 0;
+ }
+ } else uiPhaseTimer -= uiDiff;
+
+ if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ return;
+
+ if (uiEviscerateTimer <= uiDiff)
+ {
+ DoCast(me->getVictim(),SPELL_EVISCERATE);
+ uiEviscerateTimer = 8000;
+ } else uiEviscerateTimer -= uiDiff;
+
+ if (uiFanKivesTimer <= uiDiff)
+ {
+ DoCastAOE(SPELL_FAN_OF_KNIVES,false);
+ uiFanKivesTimer = 14000;
+ } else uiFanKivesTimer -= uiDiff;
+
+ if (uiPosionBottleTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
+ DoCast(pTarget,SPELL_POISON_BOTTLE);
+ uiPosionBottleTimer = 19000;
+ } else uiPosionBottleTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ if (pInstance)
+ pInstance->SetData(BOSS_GRAND_CHAMPIONS, DONE);
+ }
+};
+
+CreatureAI* GetAI_boss_rouge_toc5(Creature* pCreature)
+{
+ return new boss_rouge_toc5AI(pCreature);
+}
+
+void AddSC_boss_grand_champions()
+{
+ Script* NewScript;
+
+ NewScript = new Script;
+ NewScript->Name = "generic_vehicleAI_toc5";
+ NewScript->GetAI = &GetAI_generic_vehicleAI_toc5;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "boss_warrior_toc5";
+ NewScript->GetAI = &GetAI_boss_warrior_toc5;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "boss_mage_toc5";
+ NewScript->GetAI = &GetAI_boss_mage_toc5;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "boss_shaman_toc5";
+ NewScript->GetAI = &GetAI_boss_shaman_toc5;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "boss_hunter_toc5";
+ NewScript->GetAI = &GetAI_boss_hunter_toc5;
+ NewScript->RegisterSelf();
+
+ NewScript = new Script;
+ NewScript->Name = "boss_rouge_toc5";
+ NewScript->GetAI = &GetAI_boss_rouge_toc5;
+ NewScript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp b/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp
new file mode 100644
index 00000000000..04b671ec11c
--- /dev/null
+++ b/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/instance_trial_of_the_champion.cpp
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+/* ScriptData
+SDName: Instance Trial of the Champion
+SDComment:
+SDCategory: Trial Of the Champion
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "trial_of_the_champion.h"
+
+#define MAX_ENCOUNTER 4
+
+struct instance_trial_of_the_champion : public ScriptedInstance
+{
+ instance_trial_of_the_champion(Map* pMap) : ScriptedInstance(pMap) {Initialize();}
+
+ uint32 m_auiEncounter[MAX_ENCOUNTER];
+
+ uint8 uiMovementDone;
+ uint8 uiGrandChampionsDeaths;
+ uint8 uiArgentSoldierDeaths;
+
+ uint64 uiAnnouncerGUID;
+ uint64 uiMainGateGUID;
+ uint64 uiGrandChampionVehicle1GUID;
+ uint64 uiGrandChampionVehicle2GUID;
+ uint64 uiGrandChampionVehicle3GUID;
+ uint64 uiGrandChampion1GUID;
+ uint64 uiGrandChampion2GUID;
+ uint64 uiGrandChampion3GUID;
+ uint64 uiChampionLootGUID;
+ uint64 uiArgentChampionGUID;
+
+ std::list<uint64> VehicleList;
+
+ std::string str_data;
+
+ bool bDone;
+
+ void Initialize()
+ {
+ uiMovementDone = 0;
+ uiGrandChampionsDeaths = 0;
+ uiArgentSoldierDeaths = 0;
+
+ uiAnnouncerGUID = 0;
+ uiMainGateGUID = 0;
+ uiGrandChampionVehicle1GUID = 0;
+ uiGrandChampionVehicle2GUID = 0;
+ uiGrandChampionVehicle3GUID = 0;
+ uiGrandChampion1GUID = 0;
+ uiGrandChampion2GUID = 0;
+ uiGrandChampion3GUID = 0;
+ uiChampionLootGUID = 0;
+ uiArgentChampionGUID = 0;
+
+ bDone = false;
+
+ VehicleList.clear();
+
+ memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ {
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ return true;
+ }
+
+ return false;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool /*bAdd*/)
+ {
+ Map::PlayerList const &players = instance->GetPlayers();
+ uint32 TeamInInstance = 0;
+
+ if (!players.isEmpty())
+ {
+ if (Player* pPlayer = players.begin()->getSource())
+ TeamInInstance = pPlayer->GetTeam();
+ }
+
+ switch(pCreature->GetEntry())
+ {
+ // Champions
+ case VEHICLE_MOKRA_SKILLCRUSHER_MOUNT:
+ if (TeamInInstance == HORDE)
+ pCreature->UpdateEntry(VEHICLE_MARSHAL_JACOB_ALERIUS_MOUNT, ALLIANCE);
+ break;
+ case VEHICLE_ERESSEA_DAWNSINGER_MOUNT:
+ if (TeamInInstance == HORDE)
+ pCreature->UpdateEntry(VEHICLE_AMBROSE_BOLTSPARK_MOUNT, ALLIANCE);
+ break;
+ case VEHICLE_RUNOK_WILDMANE_MOUNT:
+ if (TeamInInstance == HORDE)
+ pCreature->UpdateEntry(VEHICLE_COLOSOS_MOUNT, ALLIANCE);
+ break;
+ case VEHICLE_ZUL_TORE_MOUNT:
+ if (TeamInInstance == HORDE)
+ pCreature->UpdateEntry(VEHICLE_EVENSONG_MOUNT, ALLIANCE);
+ break;
+ case VEHICLE_DEATHSTALKER_VESCERI_MOUNT:
+ if (TeamInInstance == HORDE)
+ pCreature->UpdateEntry(VEHICLE_LANA_STOUTHAMMER_MOUNT, ALLIANCE);
+ break;
+ // Coliseum Announcer || Just NPC_JAEREN must be spawned.
+ case NPC_JAEREN:
+ uiAnnouncerGUID = pCreature->GetGUID();
+ if (TeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_ARELAS,ALLIANCE);
+ break;
+ case VEHICLE_ARGENT_WARHORSE:
+ case VEHICLE_ARGENT_BATTLEWORG:
+ VehicleList.push_back(pCreature->GetGUID());
+ break;
+ case NPC_EADRIC:
+ case NPC_PALETRESS:
+ uiArgentChampionGUID = pCreature->GetGUID();
+ break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* pGO, bool /*bAdd*/)
+ {
+ switch(pGO->GetEntry())
+ {
+ case GO_MAIN_GATE:
+ uiMainGateGUID = pGO->GetGUID();
+ break;
+ case GO_CHAMPIONS_LOOT:
+ case GO_CHAMPIONS_LOOT_H:
+ uiChampionLootGUID = pGO->GetGUID();
+ break;
+ }
+ }
+
+ void SetData(uint32 uiType, uint32 uiData)
+ {
+ switch(uiType)
+ {
+ case DATA_MOVEMENT_DONE:
+ uiMovementDone = uiData;
+ if (uiMovementDone == 3)
+ {
+ if (Creature* pAnnouncer = instance->GetCreature(uiAnnouncerGUID))
+ pAnnouncer->AI()->SetData(DATA_IN_POSITION,0);
+ }
+ break;
+ case BOSS_GRAND_CHAMPIONS:
+ m_auiEncounter[0] = uiData;
+ if (uiData == IN_PROGRESS)
+ {
+ for (std::list<uint64>::const_iterator itr = VehicleList.begin(); itr != VehicleList.end(); ++itr)
+ if (Creature* pSummon = instance->GetCreature(*itr))
+ pSummon->RemoveFromWorld();
+ }else if (uiData == DONE)
+ {
+ ++uiGrandChampionsDeaths;
+ if (uiGrandChampionsDeaths == 3)
+ {
+ if (Creature* pAnnouncer = instance->GetCreature(uiAnnouncerGUID))
+ {
+ pAnnouncer->GetMotionMaster()->MovePoint(0,748.309,619.487,411.171);
+ pAnnouncer->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ pAnnouncer->SummonGameObject(instance->IsHeroic()? GO_CHAMPIONS_LOOT_H : GO_CHAMPIONS_LOOT,746.59,618.49,411.09,1.42,0, 0, 0, 0,90000000);
+ }
+ }
+ }
+ break;
+ case DATA_ARGENT_SOLDIER_DEFEATED:
+ uiArgentSoldierDeaths = uiData;
+ if (uiArgentSoldierDeaths == 9)
+ {
+ if (Creature* pBoss = instance->GetCreature(uiArgentChampionGUID))
+ {
+ pBoss->GetMotionMaster()->MovePoint(0,746.88,618.74,411.06);
+ pBoss->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE);
+ pBoss->SetReactState(REACT_AGGRESSIVE);
+ }
+ }
+ break;
+ case BOSS_ARGENT_CHALLENGE_E:
+ m_auiEncounter[1] = uiData;
+ if (Creature* pAnnouncer = instance->GetCreature(uiAnnouncerGUID))
+ {
+ pAnnouncer->GetMotionMaster()->MovePoint(0,748.309,619.487,411.171);
+ pAnnouncer->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ pAnnouncer->SummonGameObject(instance->IsHeroic()? GO_EADRIC_LOOT_H : GO_EADRIC_LOOT,746.59,618.49,411.09,1.42,0, 0, 0, 0,90000000);
+ }
+ break;
+ case BOSS_ARGENT_CHALLENGE_P:
+ m_auiEncounter[2] = uiData;
+ if (Creature* pAnnouncer = instance->GetCreature(uiAnnouncerGUID))
+ {
+ pAnnouncer->GetMotionMaster()->MovePoint(0,748.309,619.487,411.171);
+ pAnnouncer->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ pAnnouncer->SummonGameObject(instance->IsHeroic()? GO_PALETRESS_LOOT_H : GO_PALETRESS_LOOT,746.59,618.49,411.09,1.42,0, 0, 0, 0,90000000);
+ }
+ break;
+ }
+
+ if (uiData == DONE)
+ SaveToDB();
+ }
+
+ uint32 GetData(uint32 uiData)
+ {
+ switch(uiData)
+ {
+ case BOSS_GRAND_CHAMPIONS: return m_auiEncounter[0];
+ case BOSS_ARGENT_CHALLENGE_E: return m_auiEncounter[1];
+ case BOSS_ARGENT_CHALLENGE_P: return m_auiEncounter[2];
+ case BOSS_BLACK_KNIGHT: return m_auiEncounter[3];
+
+ case DATA_MOVEMENT_DONE: return uiMovementDone;
+ case DATA_ARGENT_SOLDIER_DEFEATED: return uiArgentSoldierDeaths;
+ }
+
+ return 0;
+ }
+
+ uint64 GetData64(uint32 uiData)
+ {
+ switch(uiData)
+ {
+ case DATA_ANNOUNCER: return uiAnnouncerGUID;
+ case DATA_MAIN_GATE: return uiMainGateGUID;
+
+ case DATA_GRAND_CHAMPION_1: return uiGrandChampion1GUID;
+ case DATA_GRAND_CHAMPION_2: return uiGrandChampion2GUID;
+ case DATA_GRAND_CHAMPION_3: return uiGrandChampion3GUID;
+ }
+
+ return 0;
+ }
+
+ void SetData64(uint32 uiType, uint64 uiData)
+ {
+ switch(uiType)
+ {
+ case DATA_GRAND_CHAMPION_1:
+ uiGrandChampion1GUID = uiData;
+ break;
+ case DATA_GRAND_CHAMPION_2:
+ uiGrandChampion2GUID = uiData;
+ break;
+ case DATA_GRAND_CHAMPION_3:
+ uiGrandChampion3GUID = uiData;
+ break;
+ }
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+
+ saveStream << "T C " << m_auiEncounter[0]
+ << " " << m_auiEncounter[1]
+ << " " << m_auiEncounter[2]
+ << " " << m_auiEncounter[3]
+ << " " << uiGrandChampionsDeaths
+ << " " << uiMovementDone;
+
+ str_data = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return str_data;
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0, data1, data2, data3, data4, data5;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4 >> data5;
+
+ if (dataHead1 == 'T' && dataHead2 == 'C')
+ {
+ m_auiEncounter[0] = data0;
+ m_auiEncounter[1] = data1;
+ m_auiEncounter[2] = data2;
+ m_auiEncounter[3] = data3;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+
+ uiGrandChampionsDeaths = data4;
+ uiMovementDone = data5;
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_trial_of_the_champion(Map* pMap)
+{
+ return new instance_trial_of_the_champion(pMap);
+}
+
+void AddSC_instance_trial_of_the_champion()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_trial_of_the_champion";
+ newscript->GetInstanceData = &GetInstanceData_instance_trial_of_the_champion;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp b/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp
new file mode 100644
index 00000000000..090b64b96cc
--- /dev/null
+++ b/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.cpp
@@ -0,0 +1,512 @@
+/*
+ * Copyright (C) 2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Trial Of the Champion
+SD%Complete:
+SDComment:
+SDCategory: trial_of_the_champion
+EndScriptData */
+
+/* ContentData
+npc_announcer_toc5
+EndContentData */
+
+#include "ScriptedPch.h"
+#include "trial_of_the_champion.h"
+#include "Vehicle.h"
+
+#define GOSSIP_START_EVENT1 "I'm ready to start challenge."
+#define GOSSIP_START_EVENT2 "I'm ready for the next challenge."
+
+#define ORIENTATION 4.714
+
+/*######
+## npc_announcer_toc5
+######*/
+
+const Position SpawnPosition = {746.261,657.401,411.681,4.65};
+
+struct npc_announcer_toc5AI : public ScriptedAI
+{
+ npc_announcer_toc5AI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+
+ uiSummonTimes = 0;
+ uiPosition = 0;
+ uiLesserChampions = 0;
+
+ uiFirstBoss = 0;
+ uiSecondBoss = 0;
+ uiThirdBoss = 0;
+
+ uiArgentChampion = 0;
+
+ uiPhase = 0;
+ uiTimer = 0;
+
+ uiVehicle1GUID = 0;
+ uiVehicle2GUID = 0;
+ uiVehicle3GUID = 0;
+
+ Champion1List.clear();
+ Champion2List.clear();
+ Champion3List.clear();
+
+ me->SetReactState(REACT_PASSIVE);
+ me->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE);
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+
+ SetGrandChampionsForEncounter();
+ SetArgentChampion();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint8 uiSummonTimes;
+ uint8 uiPosition;
+ uint8 uiLesserChampions;
+
+ uint32 uiArgentChampion;
+
+ uint32 uiFirstBoss;
+ uint32 uiSecondBoss;
+ uint32 uiThirdBoss;
+
+ uint32 uiPhase;
+ uint32 uiTimer;
+
+ uint64 uiVehicle1GUID;
+ uint64 uiVehicle2GUID;
+ uint64 uiVehicle3GUID;
+
+ uint64 uiGrandChampionBoss1;
+
+ std::list<uint64> Champion1List;
+ std::list<uint64> Champion2List;
+ std::list<uint64> Champion3List;
+
+ void NextStep(uint32 uiTimerStep,bool bNextStep = true,uint8 uiPhaseStep = 0)
+ {
+ uiTimer = uiTimerStep;
+ if (bNextStep)
+ ++uiPhase;
+ else
+ uiPhase = uiPhaseStep;
+ }
+
+ void SetData(uint32 uiType, uint32 /*uiData*/)
+ {
+ switch (uiType)
+ {
+ case DATA_START:
+ DoSummonGrandChampion(uiFirstBoss);
+ NextStep(10000,false,1);
+ break;
+ case DATA_IN_POSITION: //movement done.
+ me->GetMotionMaster()->MovePoint(1,735.81,661.92,412.39);
+ if (GameObject* pGO = GameObject::GetGameObject(*me, pInstance->GetData64(DATA_MAIN_GATE)))
+ pInstance->HandleGameObject(pGO->GetGUID(),false);
+ NextStep(10000,false,3);
+ break;
+ case DATA_LESSER_CHAMPIONS_DEFEATED:
+ {
+ ++uiLesserChampions;
+ std::list<uint64> TempList;
+ if (uiLesserChampions == 3 || uiLesserChampions == 6)
+ {
+ switch(uiLesserChampions)
+ {
+ case 3:
+ TempList = Champion2List;
+ break;
+ case 6:
+ TempList = Champion3List;
+ break;
+ }
+
+ for (std::list<uint64>::const_iterator itr = TempList.begin(); itr != TempList.end(); ++itr)
+ if (Creature* pSummon = Unit::GetCreature(*me, *itr))
+ AggroAllPlayers(pSummon);
+ }else if (uiLesserChampions == 9)
+ StartGrandChampionsAttack();
+
+ break;
+ }
+ }
+ }
+
+ void StartGrandChampionsAttack()
+ {
+ Creature* pGrandChampion1 = Unit::GetCreature(*me, uiVehicle1GUID);
+ Creature* pGrandChampion2 = Unit::GetCreature(*me, uiVehicle2GUID);
+ Creature* pGrandChampion3 = Unit::GetCreature(*me, uiVehicle3GUID);
+
+ if (pGrandChampion1 && pGrandChampion2 && pGrandChampion3)
+ {
+ AggroAllPlayers(pGrandChampion1);
+ AggroAllPlayers(pGrandChampion2);
+ AggroAllPlayers(pGrandChampion3);
+ }
+ }
+
+ void MovementInform(uint32 uiType, uint32 uiPointId)
+ {
+ if (uiType != POINT_MOTION_TYPE)
+ return;
+
+ if (uiPointId == 1)
+ {
+ me->SetOrientation(ORIENTATION);
+ me->SendMovementFlagUpdate();
+ }
+ }
+
+ void DoSummonGrandChampion(uint32 uiBoss)
+ {
+ ++uiSummonTimes;
+ uint32 VEHICLE_TO_SUMMON1 = 0;
+ uint32 VEHICLE_TO_SUMMON2 = 0;
+ switch(uiBoss)
+ {
+ case 0:
+ VEHICLE_TO_SUMMON1 = VEHICLE_MOKRA_SKILLCRUSHER_MOUNT;
+ VEHICLE_TO_SUMMON2 = VEHICLE_ORGRIMMAR_WOLF;
+ break;
+ case 1:
+ VEHICLE_TO_SUMMON1 = VEHICLE_ERESSEA_DAWNSINGER_MOUNT;
+ VEHICLE_TO_SUMMON2 = VEHICLE_SILVERMOON_HAWKSTRIDER;
+ break;
+ case 2:
+ VEHICLE_TO_SUMMON1 = VEHICLE_RUNOK_WILDMANE_MOUNT;
+ VEHICLE_TO_SUMMON2 = VEHICLE_THUNDER_BLUFF_KODO;
+ break;
+ case 3:
+ VEHICLE_TO_SUMMON1 = VEHICLE_ZUL_TORE_MOUNT;
+ VEHICLE_TO_SUMMON2 = VEHICLE_DARKSPEAR_RAPTOR;
+ break;
+ case 4:
+ VEHICLE_TO_SUMMON1 = VEHICLE_DEATHSTALKER_VESCERI_MOUNT;
+ VEHICLE_TO_SUMMON2 = VEHICLE_FORSAKE_WARHORSE;
+ break;
+ default:
+ return;
+ }
+
+ if (Creature* pBoss = me->SummonCreature(VEHICLE_TO_SUMMON1,SpawnPosition))
+ {
+ switch(uiSummonTimes)
+ {
+ case 1:
+ {
+ uiVehicle1GUID = pBoss->GetGUID();
+ uint64 uiGrandChampionBoss1 = 0;
+ if (Creature* pBoss = Unit::GetCreature(*me, uiVehicle1GUID))
+ if (Vehicle* pVehicle = pBoss->GetVehicleKit())
+ if (Unit* pUnit = pVehicle->GetPassenger(0))
+ uiGrandChampionBoss1 = pUnit->GetGUID();
+ if (pInstance)
+ {
+ pInstance->SetData64(DATA_GRAND_CHAMPION_VEHICLE_1,uiVehicle1GUID);
+ pInstance->SetData64(DATA_GRAND_CHAMPION_1,uiGrandChampionBoss1);
+ }
+ pBoss->AI()->SetData(1,0);
+ break;
+ }
+ case 2:
+ {
+ uiVehicle2GUID = pBoss->GetGUID();
+ uint64 uiGrandChampionBoss2 = 0;
+ if (Creature* pBoss = Unit::GetCreature(*me, uiVehicle2GUID))
+ if (Vehicle* pVehicle = pBoss->GetVehicleKit())
+ if (Unit* pUnit = pVehicle->GetPassenger(0))
+ uiGrandChampionBoss2 = pUnit->GetGUID();
+ if (pInstance)
+ {
+ pInstance->SetData64(DATA_GRAND_CHAMPION_VEHICLE_2,uiVehicle2GUID);
+ pInstance->SetData64(DATA_GRAND_CHAMPION_2,uiGrandChampionBoss2);
+ }
+ pBoss->AI()->SetData(2,0);
+ break;
+ }
+ case 3:
+ {
+ uiVehicle3GUID = pBoss->GetGUID();
+ uint64 uiGrandChampionBoss3 = 0;
+ if (Creature* pBoss = Unit::GetCreature(*me, uiVehicle3GUID))
+ if (Vehicle* pVehicle = pBoss->GetVehicleKit())
+ if (Unit* pUnit = pVehicle->GetPassenger(0))
+ uiGrandChampionBoss3 = pUnit->GetGUID();
+ if (pInstance)
+ {
+ pInstance->SetData64(DATA_GRAND_CHAMPION_VEHICLE_3,uiVehicle3GUID);
+ pInstance->SetData64(DATA_GRAND_CHAMPION_3,uiGrandChampionBoss3);
+ }
+ pBoss->AI()->SetData(3,0);
+ break;
+ }
+ default:
+ return;
+ }
+
+ for (uint8 i = 0; i < 3; ++i)
+ {
+ if (Creature* pAdd = me->SummonCreature(VEHICLE_TO_SUMMON2,SpawnPosition,TEMPSUMMON_CORPSE_DESPAWN))
+ {
+ switch(uiSummonTimes)
+ {
+ case 1:
+ Champion1List.push_back(pAdd->GetGUID());
+ break;
+ case 2:
+ Champion2List.push_back(pAdd->GetGUID());
+ break;
+ case 3:
+ Champion3List.push_back(pAdd->GetGUID());
+ break;
+ }
+
+ switch(i)
+ {
+ case 0:
+ pAdd->GetMotionMaster()->MoveFollow(pBoss,2.0f,M_PI);
+ break;
+ case 1:
+ pAdd->GetMotionMaster()->MoveFollow(pBoss,2.0f,M_PI / 2);
+ break;
+ case 2:
+ pAdd->GetMotionMaster()->MoveFollow(pBoss,2.0f,M_PI / 2 + M_PI);
+ break;
+ }
+ }
+
+ }
+ }
+ }
+
+ void DoStartArgentChampionEncounter()
+ {
+ me->GetMotionMaster()->MovePoint(1,735.81,661.92,412.39);
+
+ if (Creature* pBoss = me->SummonCreature(uiArgentChampion,SpawnPosition))
+ {
+ for (uint8 i = 0; i < 3; ++i)
+ {
+ if (Creature* pTrash = me->SummonCreature(NPC_ARGENT_LIGHWIELDER,SpawnPosition))
+ pTrash->AI()->SetData(i,0);
+ if (Creature* pTrash = me->SummonCreature(NPC_ARGENT_MONK,SpawnPosition))
+ pTrash->AI()->SetData(i,0);
+ if (Creature* pTrash = me->SummonCreature(NPC_PRIESTESS,SpawnPosition))
+ pTrash->AI()->SetData(i,0);
+ }
+ }
+ }
+
+ void SetGrandChampionsForEncounter()
+ {
+ uiFirstBoss = urand(0,4);
+
+ while (uiSecondBoss == uiFirstBoss || uiThirdBoss == uiFirstBoss || uiThirdBoss == uiSecondBoss)
+ {
+ uiSecondBoss = urand(0,4);
+ uiThirdBoss = urand(0,4);
+ }
+ }
+
+ void SetArgentChampion()
+ {
+ uint8 uiTempBoss = urand(0,1);
+
+ switch(uiTempBoss)
+ {
+ case 0:
+ uiArgentChampion = NPC_EADRIC;
+ break;
+ case 1:
+ uiArgentChampion = NPC_PALETRESS;
+ break;
+ }
+ }
+
+ void StartEncounter()
+ {
+ if (!pInstance)
+ return;
+
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+
+ if (pInstance->GetData(BOSS_BLACK_KNIGHT) == NOT_STARTED)
+ {
+ if (pInstance->GetData(BOSS_ARGENT_CHALLENGE_E) == NOT_STARTED && pInstance->GetData(BOSS_ARGENT_CHALLENGE_P) == NOT_STARTED)
+ {
+ if (pInstance->GetData(BOSS_GRAND_CHAMPIONS) == NOT_STARTED)
+ me->AI()->SetData(DATA_START,0);
+
+ if (pInstance->GetData(BOSS_GRAND_CHAMPIONS) == DONE)
+ DoStartArgentChampionEncounter();
+ }
+
+ if (pInstance->GetData(BOSS_GRAND_CHAMPIONS) == DONE &&
+ pInstance->GetData(BOSS_ARGENT_CHALLENGE_E) == DONE ||
+ pInstance->GetData(BOSS_ARGENT_CHALLENGE_P) == DONE)
+ me->SummonCreature(VEHICLE_BLACK_KNIGHT,769.834,651.915,447.035,0);
+ }
+ }
+
+ void AggroAllPlayers(Creature* pTemp)
+ {
+ Map::PlayerList const &PlList = me->GetMap()->GetPlayers();
+
+ if (PlList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i)
+ {
+ if (Player* pPlayer = i->getSource())
+ {
+ if (pPlayer->isGameMaster())
+ continue;
+
+ if (pPlayer->isAlive())
+ {
+ pTemp->SetHomePosition(me->GetPositionX(),me->GetPositionY(),me->GetPositionZ(),me->GetOrientation());
+ pTemp->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE);
+ pTemp->SetReactState(REACT_AGGRESSIVE);
+ pTemp->SetInCombatWith(pPlayer);
+ pPlayer->SetInCombatWith(pTemp);
+ pTemp->AddThreat(pPlayer, 0.0f);
+ }
+ }
+ }
+ }
+
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ ScriptedAI::UpdateAI(uiDiff);
+
+ if (uiTimer <= uiDiff)
+ {
+ switch(uiPhase)
+ {
+ case 1:
+ DoSummonGrandChampion(uiSecondBoss);
+ NextStep(10000,true);
+ break;
+ case 2:
+ DoSummonGrandChampion(uiThirdBoss);
+ NextStep(0,false);
+ break;
+ case 3:
+ if (!Champion1List.empty())
+ {
+ for (std::list<uint64>::const_iterator itr = Champion1List.begin(); itr != Champion1List.end(); ++itr)
+ if (Creature* pSummon = Unit::GetCreature(*me, *itr))
+ AggroAllPlayers(pSummon);
+ NextStep(0,false);
+ }
+ break;
+ }
+ } else uiTimer -= uiDiff;
+
+ if (!UpdateVictim())
+ return;
+ }
+
+ void JustSummoned(Creature* pSummon)
+ {
+ if (pInstance && pInstance->GetData(BOSS_GRAND_CHAMPIONS) == NOT_STARTED)
+ {
+ pSummon->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE);
+ pSummon->SetReactState(REACT_PASSIVE);
+ }
+ }
+
+ void SummonedCreatureDespawn(Creature* pSummon)
+ {
+ switch(pSummon->GetEntry())
+ {
+ case VEHICLE_DARNASSIA_NIGHTSABER:
+ case VEHICLE_EXODAR_ELEKK:
+ case VEHICLE_STORMWIND_STEED:
+ case VEHICLE_GNOMEREGAN_MECHANOSTRIDER:
+ case VEHICLE_IRONFORGE_RAM:
+ case VEHICLE_FORSAKE_WARHORSE:
+ case VEHICLE_THUNDER_BLUFF_KODO:
+ case VEHICLE_ORGRIMMAR_WOLF:
+ case VEHICLE_SILVERMOON_HAWKSTRIDER:
+ case VEHICLE_DARKSPEAR_RAPTOR:
+ me->AI()->SetData(DATA_LESSER_CHAMPIONS_DEFEATED,0);
+ break;
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_announcer_toc5(Creature* pCreature)
+{
+ return new npc_announcer_toc5AI(pCreature);
+}
+
+bool GossipHello_npc_announcer_toc5(Player* pPlayer, Creature* pCreature)
+{
+ ScriptedInstance* pInstance = pCreature->GetInstanceData();
+
+ if (pInstance &&
+ pInstance->GetData(BOSS_GRAND_CHAMPIONS) == DONE &&
+ pInstance->GetData(BOSS_BLACK_KNIGHT) == DONE &&
+ pInstance->GetData(BOSS_ARGENT_CHALLENGE_E) == DONE ||
+ pInstance->GetData(BOSS_ARGENT_CHALLENGE_P) == DONE)
+ return false;
+
+ if (pInstance &&
+ pInstance->GetData(BOSS_GRAND_CHAMPIONS) == NOT_STARTED &&
+ pInstance->GetData(BOSS_ARGENT_CHALLENGE_E) == NOT_STARTED &&
+ pInstance->GetData(BOSS_ARGENT_CHALLENGE_P) == NOT_STARTED &&
+ pInstance->GetData(BOSS_BLACK_KNIGHT) == NOT_STARTED)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_START_EVENT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ else if (pInstance)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_START_EVENT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_announcer_toc5(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ pPlayer->CLOSE_GOSSIP_MENU();
+ CAST_AI(npc_announcer_toc5AI, pCreature->AI())->StartEncounter();
+ }
+
+ return true;
+}
+
+void AddSC_trial_of_the_champion()
+{
+ Script* NewScript;
+
+ NewScript = new Script;
+ NewScript->Name = "npc_announcer_toc5";
+ NewScript->GetAI = &GetAI_npc_announcer_toc5;
+ NewScript->pGossipHello = &GossipHello_npc_announcer_toc5;
+ NewScript->pGossipSelect = &GossipSelect_npc_announcer_toc5;
+ NewScript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h b/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h
new file mode 100644
index 00000000000..221c7c0412f
--- /dev/null
+++ b/src/server/scripts/northrend/crusaders_coliseum/trial_of_the_champion/trial_of_the_champion.h
@@ -0,0 +1,115 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+* This program is free software licensed under GPL version 2
+* Please see the included DOCS/LICENSE.TXT for more information */
+
+#ifndef DEF_TOC_H
+#define DEF_TOC_H
+
+
+enum eData
+{
+ BOSS_GRAND_CHAMPIONS,
+ BOSS_ARGENT_CHALLENGE_E,
+ BOSS_ARGENT_CHALLENGE_P,
+ BOSS_BLACK_KNIGHT,
+ DATA_MOVEMENT_DONE,
+ DATA_LESSER_CHAMPIONS_DEFEATED,
+ DATA_START,
+ DATA_IN_POSITION,
+ DATA_ARGENT_SOLDIER_DEFEATED
+};
+
+enum Data64
+{
+ DATA_ANNOUNCER,
+ DATA_MAIN_GATE,
+
+ DATA_GRAND_CHAMPION_VEHICLE_1,
+ DATA_GRAND_CHAMPION_VEHICLE_2,
+ DATA_GRAND_CHAMPION_VEHICLE_3,
+
+ DATA_GRAND_CHAMPION_1,
+ DATA_GRAND_CHAMPION_2,
+ DATA_GRAND_CHAMPION_3
+};
+
+enum eNpcs
+{
+ // Horde Champions
+ NPC_MOKRA = 35572,
+ NPC_ERESSEA = 35569,
+ NPC_RUNOK = 35571,
+ NPC_ZULTORE = 35570,
+ NPC_VISCERI = 35617,
+
+ // Alliance Champions
+ NPC_JACOB = 34705,
+ NPC_AMBROSE = 34702,
+ NPC_COLOSOS = 34701,
+ NPC_JAELYNE = 34657,
+ NPC_LANA = 34703,
+
+ NPC_EADRIC = 35119,
+ NPC_PALETRESS = 34928,
+
+ NPC_ARGENT_LIGHWIELDER = 35309,
+ NPC_ARGENT_MONK = 35305,
+ NPC_PRIESTESS = 35307,
+
+ NPC_BLACK_KNIGHT = 35451,
+
+ NPC_RISEN_JAEREN = 35545,
+ NPC_RISEN_ARELAS = 35564,
+
+ NPC_JAEREN = 35004,
+ NPC_ARELAS = 35005
+};
+
+enum eGameObjects
+{
+ GO_MAIN_GATE = 195647,
+
+ GO_CHAMPIONS_LOOT = 195709,
+ GO_CHAMPIONS_LOOT_H = 195710,
+
+ GO_EADRIC_LOOT = 195374,
+ GO_EADRIC_LOOT_H = 195375,
+
+ GO_PALETRESS_LOOT = 195323,
+ GO_PALETRESS_LOOT_H = 195324
+};
+
+enum eVehicles
+{
+ //Grand Champions Alliance Vehicles
+ VEHICLE_MARSHAL_JACOB_ALERIUS_MOUNT = 35637,
+ VEHICLE_AMBROSE_BOLTSPARK_MOUNT = 35633,
+ VEHICLE_COLOSOS_MOUNT = 35768,
+ VEHICLE_EVENSONG_MOUNT = 34658,
+ VEHICLE_LANA_STOUTHAMMER_MOUNT = 35636,
+ //Faction Champions (ALLIANCE)
+ VEHICLE_DARNASSIA_NIGHTSABER = 33298,
+ VEHICLE_EXODAR_ELEKK = 33416,
+ VEHICLE_STORMWIND_STEED = 33297,
+ VEHICLE_GNOMEREGAN_MECHANOSTRIDER = 33301,
+ VEHICLE_IRONFORGE_RAM = 33408,
+ //Grand Champions Horde Vehicles
+ VEHICLE_MOKRA_SKILLCRUSHER_MOUNT = 35638,
+ VEHICLE_ERESSEA_DAWNSINGER_MOUNT = 35635,
+ VEHICLE_RUNOK_WILDMANE_MOUNT = 35640,
+ VEHICLE_ZUL_TORE_MOUNT = 35641,
+ VEHICLE_DEATHSTALKER_VESCERI_MOUNT = 35634,
+ //Faction Champions (HORDE)
+ VEHICLE_FORSAKE_WARHORSE = 33414,
+ VEHICLE_THUNDER_BLUFF_KODO = 33300,
+ VEHICLE_ORGRIMMAR_WOLF = 33409,
+ VEHICLE_SILVERMOON_HAWKSTRIDER = 33418,
+ VEHICLE_DARKSPEAR_RAPTOR = 33299,
+
+ VEHICLE_ARGENT_WARHORSE = 35644,
+ VEHICLE_ARGENT_BATTLEWORG = 36558,
+
+ VEHICLE_BLACK_KNIGHT = 35491
+};
+
+#endif
diff --git a/src/server/scripts/northrend/crystalsong_forest.cpp b/src/server/scripts/northrend/crystalsong_forest.cpp
new file mode 100644
index 00000000000..208e9dea5b5
--- /dev/null
+++ b/src/server/scripts/northrend/crystalsong_forest.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Script Data Start
+SDName: CrystalSongForest
+SDAuthor: Malcrom
+SD%Complete: 99%
+SDComment:
+SDCategory: CrystalsongForest
+Script Data End */
+
+#include "ScriptedPch.h"
+
+/*******************************************************
+ * npc_warmage_violetstand
+ *******************************************************/
+
+enum Spells
+{
+ SPELL_TRANSITUS_SHIELD_BEAM = 48310
+};
+
+enum NPCs
+{
+ NPC_TRANSITUS_SHIELD_DUMMY = 27306,
+ NPC_WARMAGE_SARINA = 32369,
+ NPC_WARMAGE_HALISTER = 32371,
+ NPC_WARMAGE_ILSUDRIA = 32372
+};
+
+struct npc_warmage_violetstandAI : public Scripted_NoMovementAI
+{
+ npc_warmage_violetstandAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature){}
+
+ uint64 uiTargetGUID;
+
+ void Reset()
+ {
+ uiTargetGUID = 0;
+ }
+
+ void UpdateAI(const uint32 /*uiDiff*/)
+ {
+ if (me->IsNonMeleeSpellCasted(false))
+ return;
+
+ if (me->GetEntry() == NPC_WARMAGE_SARINA)
+ {
+ if (!uiTargetGUID)
+ {
+ std::list<Creature*> orbList;
+ GetCreatureListWithEntryInGrid(orbList, me, NPC_TRANSITUS_SHIELD_DUMMY, 32.0f);
+ if (!orbList.empty())
+ {
+ for (std::list<Creature*>::const_iterator itr = orbList.begin(); itr != orbList.end(); ++itr)
+ {
+ if (Creature* pOrb = *itr)
+ {
+ if (pOrb->GetPositionY() < 1000)
+ {
+ uiTargetGUID = pOrb->GetGUID();
+ break;
+ }
+ }
+ }
+ }
+ }
+ }else
+ {
+ if (!uiTargetGUID)
+ if (Creature* pOrb = GetClosestCreatureWithEntry(me,NPC_TRANSITUS_SHIELD_DUMMY,32.0f))
+ uiTargetGUID = pOrb->GetGUID();
+
+ }
+
+ if (Creature* pOrb = me->GetCreature(*me,uiTargetGUID))
+ DoCast(pOrb,SPELL_TRANSITUS_SHIELD_BEAM);
+
+ }
+};
+
+CreatureAI* GetAI_npc_warmage_violetstand(Creature* pCreature)
+{
+ return new npc_warmage_violetstandAI(pCreature);
+}
+
+void AddSC_crystalsong_forest()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_warmage_violetstand";
+ newscript->GetAI = &GetAI_npc_warmage_violetstand;
+ newscript->RegisterSelf();
+} \ No newline at end of file
diff --git a/src/server/scripts/northrend/dalaran.cpp b/src/server/scripts/northrend/dalaran.cpp
new file mode 100644
index 00000000000..7d5e76ffe35
--- /dev/null
+++ b/src/server/scripts/northrend/dalaran.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Script Data Start
+SDName: Dalaran
+SDAuthor: WarHead, MaXiMiUS
+SD%Complete: 99%
+SDComment: For what is 63990+63991? Same function but don't work correct...
+SDCategory: Dalaran
+Script Data End */
+
+#include "ScriptedPch.h"
+
+/*******************************************************
+ * npc_mageguard_dalaran
+ *******************************************************/
+
+enum Spells
+{
+ SPELL_TRESPASSER_A = 54028,
+ SPELL_TRESPASSER_H = 54029
+};
+
+enum NPCs // All outdoor guards are within 35.0f of these NPCs
+{
+ NPC_APPLEBOUGH_A = 29547,
+ NPC_SWEETBERRY_H = 29715,
+};
+
+struct npc_mageguard_dalaranAI : public Scripted_NoMovementAI
+{
+ npc_mageguard_dalaranAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature)
+ {
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pCreature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_NORMAL, true);
+ pCreature->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true);
+ }
+
+ void Reset(){}
+
+ void Aggro(Unit* /*pWho*/){}
+
+ void AttackStart(Unit* /*pWho*/){}
+
+ void MoveInLineOfSight(Unit *pWho)
+ {
+ if (!pWho || !pWho->IsInWorld() || pWho->GetZoneId() != 4395)
+ return;
+
+ if (!me->IsWithinDist(pWho, 65.0f, false))
+ return;
+
+ Player *pPlayer = pWho->GetCharmerOrOwnerPlayerOrPlayerItself();
+
+ if (!pPlayer || pPlayer->isGameMaster() || pPlayer->IsBeingTeleported())
+ return;
+
+ switch (me->GetEntry())
+ {
+ case 29254:
+ if (pPlayer->GetTeam() == HORDE) // Horde unit found in Alliance area
+ if (GetClosestCreatureWithEntry(me, NPC_APPLEBOUGH_A, 32.0f))
+ {
+ if (me->isInBackInMap(pWho, 12.0f)) // In my line of sight, "outdoors", and behind me
+ DoCast(pWho, SPELL_TRESPASSER_A); // Teleport the Horde unit out
+ }
+ else // In my line of sight, and "indoors"
+ DoCast(pWho, SPELL_TRESPASSER_A); // Teleport the Horde unit out
+ break;
+ case 29255:
+ if (pPlayer->GetTeam() == ALLIANCE) // Alliance unit found in Horde area
+ if (GetClosestCreatureWithEntry(me, NPC_SWEETBERRY_H, 32.0f))
+ {
+ if (me->isInBackInMap(pWho, 12.0f)) // In my line of sight, "outdoors", and behind me
+ DoCast(pWho, SPELL_TRESPASSER_H); // Teleport the Alliance unit out
+ }
+ else // In my line of sight, and "indoors"
+ DoCast(pWho, SPELL_TRESPASSER_H); // Teleport the Alliance unit out
+ break;
+ }
+ me->SetOrientation(me->GetHomePosition().GetOrientation());
+ return;
+ }
+
+ void UpdateAI(const uint32 /*diff*/){}
+};
+
+CreatureAI* GetAI_npc_mageguard_dalaran(Creature* pCreature)
+{
+ return new npc_mageguard_dalaranAI(pCreature);
+}
+
+/*######
+## npc_hira_snowdawn
+######*/
+
+enum eHiraSnowdawn
+{
+ SPELL_COLD_WEATHER_FLYING = 54197
+};
+
+#define GOSSIP_TEXT_TRAIN_HIRA "I seek training to ride a steed."
+
+bool GossipHello_npc_hira_snowdawn(Player* pPlayer, Creature* pCreature)
+{
+ if (!pCreature->isVendor() || !pCreature->isTrainer())
+ return false;
+
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_TRAIN_HIRA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN);
+
+ if (pPlayer->getLevel() >= 80 && pPlayer->HasSpell(SPELL_COLD_WEATHER_FLYING))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_hira_snowdawn(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_TRAIN)
+ pPlayer->SEND_TRAINERLIST(pCreature->GetGUID());
+
+ if (uiAction == GOSSIP_ACTION_TRADE)
+ pPlayer->SEND_VENDORLIST(pCreature->GetGUID());
+
+ return true;
+}
+
+void AddSC_dalaran()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_mageguard_dalaran";
+ newscript->GetAI = &GetAI_npc_mageguard_dalaran;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_hira_snowdawn";
+ newscript->pGossipHello = &GossipHello_npc_hira_snowdawn;
+ newscript->pGossipSelect = &GossipSelect_npc_hira_snowdawn;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/dragonblight.cpp b/src/server/scripts/northrend/dragonblight.cpp
new file mode 100644
index 00000000000..4f26ec1de1a
--- /dev/null
+++ b/src/server/scripts/northrend/dragonblight.cpp
@@ -0,0 +1,272 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Dragonblight
+SD%Complete: 100
+SDComment:
+SDCategory: Dragonblight
+EndScriptData */
+
+/* ContentData
+npc_alexstrasza_wr_gate
+EndContentData */
+
+#include "ScriptedPch.h"
+#include "ScriptedEscortAI.h"
+
+enum eEnums
+{
+ QUEST_RETURN_TO_AG_A = 12499,
+ QUEST_RETURN_TO_AG_H = 12500,
+ MOVIE_ID_GATES = 14
+};
+
+#define GOSSIP_ITEM_WHAT_HAPPENED "Alexstrasza, can you show me what happened here?"
+
+bool GossipHello_npc_alexstrasza_wr_gate(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestRewardStatus(QUEST_RETURN_TO_AG_A) || pPlayer->GetQuestRewardStatus(QUEST_RETURN_TO_AG_H))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_WHAT_HAPPENED, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_alexstrasza_wr_gate(Player* pPlayer, Creature* /*pCreature*/, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->SendMovieStart(MOVIE_ID_GATES);
+ }
+
+ return true;
+}
+
+/*######
+## npc_inquisitor_hallard. Quest 12321
+######*/
+
+
+enum eInquisitor
+{
+ NPC_GODFREY = 27577,
+ SPELL_HOLY_FIRE = 39323,
+
+ SAY_WP_0 = -1800014,
+ SAY_WP_1 = -1800015,
+ SAY_WP_2 = -1800016,
+ SAY_WP_3 = -1800017,
+ SAY_WP_4 = -1800018,
+ SAY_WP_5 = -1800019,
+ SAY_WP_6 = -1800020,
+ SAY_WP_7 = -1800021,
+ SAY_WP_8 = -1800022,
+ SAY_WP_9 = -1800023,
+ SAY_WP_10 = -1800024,
+ SAY_WP_11 = -1800025,
+ SAY_WP_12 = -1800026,
+ SAY_WP_13 = -1800027,
+ SAY_WP_14 = -1800028,
+ SAY_WP_15 = -1800029,
+ SAY_WP_16 = -1800030,
+ SAY_WP_17 = -1800031,
+ SAY_WP_18 = -1800032,
+ SAY_WP_19 = -1800033,
+ SAY_WP_20 = -1800034,
+ SAY_WP_21 = -1800035,
+ SAY_WP_22 = -1800036,
+ SAY_WP_23 = -1800037,
+ SAY_WP_24 = -1800038,
+ SAY_WP_25 = -1800039,
+ SAY_WP_26 = -1800040,
+ SAY_WP_27 = -1800041
+};
+
+#define QUEST_A_RIGHTEOUS_SERMON 12321
+
+struct npc_inquisitor_hallardAI : public npc_escortAI
+{
+ npc_inquisitor_hallardAI(Creature* pCreature) : npc_escortAI(pCreature) { }
+
+ bool Completed;
+
+ void WaypointReached(uint32 i)
+ {
+ Player* pPlayer = GetPlayerForEscort();
+ if (!pPlayer)
+ return;
+ Creature* Godfrey = me->FindNearestCreature(NPC_GODFREY, 50, true);
+ if (!Godfrey)
+ return;
+ switch (i)
+ {
+ case 1:
+ DoScriptText(SAY_WP_1, me, Godfrey);
+ me->SetUInt64Value(UNIT_FIELD_TARGET, Godfrey->GetGUID());
+ me->HandleEmoteCommand(5);
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ break;
+ case 2:
+ Godfrey->HandleEmoteCommand(434);
+ DoScriptText(SAY_WP_2, me, Godfrey);
+ me->HandleEmoteCommand(15);
+ break;
+ case 3:
+ DoScriptText(SAY_WP_3, me, Godfrey);
+ me->HandleEmoteCommand(1);
+ break;
+ case 4:
+ DoScriptText(SAY_WP_4, Godfrey);
+ break;
+ case 5:
+ DoScriptText(SAY_WP_5, Godfrey);
+ break;
+ case 6:
+ DoScriptText(SAY_WP_6, Godfrey);
+ break;
+ case 7:
+ DoScriptText(SAY_WP_7, me, Godfrey);
+ me->HandleEmoteCommand(1);
+ break;
+ case 8:
+ DoScriptText(SAY_WP_8, me, Godfrey);
+ me->HandleEmoteCommand(16);
+ break;
+ case 9:
+ DoScriptText(SAY_WP_9, me, Godfrey);
+ me->HandleEmoteCommand(5);
+ break;
+ case 10:
+ DoScriptText(SAY_WP_10, me, Godfrey);
+ DoCast(Godfrey, SPELL_HOLY_FIRE);
+ break;
+ case 11:
+ Godfrey->HandleEmoteCommand(434);
+ DoScriptText(SAY_WP_11, Godfrey);
+ break;
+ case 12:
+ DoScriptText(SAY_WP_12, me, Godfrey);
+ DoCast(Godfrey, SPELL_HOLY_FIRE);
+ break;
+ case 13:
+ DoScriptText(SAY_WP_13, me, Godfrey);
+ DoCast(Godfrey, SPELL_HOLY_FIRE);
+ break;
+ case 14:
+ Godfrey->HandleEmoteCommand(434);
+ DoScriptText(SAY_WP_14, Godfrey);
+ break;
+ case 15:
+ DoScriptText(SAY_WP_15, me, Godfrey);
+ DoCast(Godfrey, SPELL_HOLY_FIRE);
+ break;
+ case 16:
+ DoScriptText(SAY_WP_16, me, Godfrey);
+ break;
+ case 17:
+ DoScriptText(SAY_WP_17, me, Godfrey);
+ break;
+ case 18:
+ DoScriptText(SAY_WP_18, Godfrey);
+ break;
+ case 19:
+ DoScriptText(SAY_WP_19, me, Godfrey);
+ break;
+ case 20:
+ DoScriptText(SAY_WP_20, Godfrey);
+ break;
+ case 21:
+ DoScriptText(SAY_WP_21, Godfrey);
+ break;
+ case 22:
+ DoScriptText(SAY_WP_22, me, Godfrey);
+ break;
+ case 23:
+ DoScriptText(SAY_WP_23, Godfrey);
+ break;
+ case 24:
+ DoScriptText(SAY_WP_24, Godfrey);
+ break;
+ case 25:
+ DoScriptText(SAY_WP_25, me, Godfrey);
+ break;
+ case 26:
+ DoScriptText(SAY_WP_26, me);
+ me->SetUInt64Value(UNIT_FIELD_TARGET, pPlayer->GetGUID());
+ break;
+ case 27:
+ DoScriptText(SAY_WP_27, me, Godfrey);
+ me->SetUInt64Value(UNIT_FIELD_TARGET, Godfrey->GetGUID());
+ Completed = true;
+ if (pPlayer)
+ pPlayer->GroupEventHappens(QUEST_A_RIGHTEOUS_SERMON, me);
+ break;
+ }
+ }
+
+ void Reset()
+ {
+ Completed = false;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ npc_escortAI::UpdateAI(diff);
+ }
+};
+
+bool QuestAccept_npc_inquisitor_hallard(Player* pPlayer, Creature* pCreature, Quest const* quest)
+{
+ if (quest->GetQuestId() == QUEST_A_RIGHTEOUS_SERMON)
+ {
+ DoScriptText(SAY_WP_0, pCreature, pPlayer);
+ if (npc_escortAI* pEscortAI = CAST_AI(npc_inquisitor_hallardAI, pCreature->AI()))
+ {
+ pEscortAI->Start(true, false, pPlayer->GetGUID(), 0, true);
+ pCreature->GetMotionMaster()->MovePoint(0, 3801.543, -679.350, 213.75);
+ }
+ }
+ return true;
+}
+
+CreatureAI* GetAI_npc_inquisitor_hallard(Creature* pCreature)
+{
+ return new npc_inquisitor_hallardAI(pCreature);
+}
+
+void AddSC_dragonblight()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_alexstrasza_wr_gate";
+ newscript->pGossipHello = &GossipHello_npc_alexstrasza_wr_gate;
+ newscript->pGossipSelect = &GossipSelect_npc_alexstrasza_wr_gate;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_inquisitor_hallard";
+ newscript->GetAI = &GetAI_npc_inquisitor_hallard;
+ newscript->pQuestAccept = &QuestAccept_npc_inquisitor_hallard;
+ newscript->RegisterSelf();
+
+}
diff --git a/src/server/scripts/northrend/draktharon_keep/boss_dred.cpp b/src/server/scripts/northrend/draktharon_keep/boss_dred.cpp
new file mode 100644
index 00000000000..ba64a4748dd
--- /dev/null
+++ b/src/server/scripts/northrend/draktharon_keep/boss_dred.cpp
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2008 - 2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Comment: MAYBE need more improve the "Raptor Call".
+ */
+
+#include "ScriptedPch.h"
+#include "drak_tharon_keep.h"
+
+enum eSpells
+{
+ SPELL_BELLOWING_ROAR = 22686, // fears the group, can be resisted/dispelled
+ SPELL_GRIEVOUS_BITE = 48920,
+ SPELL_MANGLING_SLASH = 48873, //casted on the current tank, adds debuf
+ SPELL_FEARSOME_ROAR = 48849,
+ H_SPELL_FEARSOME_ROAR = 59422, //Not stacking, debuff
+ SPELL_PIERCING_SLASH = 48878, //debuff -->Armor reduced by 75%
+ SPELL_RAPTOR_CALL = 59416, //dummy
+ SPELL_GUT_RIP = 49710,
+ SPELL_REND = 13738
+};
+
+enum eArchivements
+{
+ ACHIEV_BETTER_OFF_DRED = 2039
+};
+
+enum Creatures
+{
+ NPC_RAPTOR_1 = 26641,
+ NPC_RAPTOR_2 = 26628
+};
+
+struct boss_dredAI : public ScriptedAI
+{
+ boss_dredAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiBellowingRoarTimer;
+ uint32 uiGrievousBiteTimer;
+ uint32 uiManglingSlashTimer;
+ uint32 uiFearsomeRoarTimer;
+ uint32 uiPiercingSlashTimer;
+ uint32 uiRaptorCallTimer;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_DRED_EVENT,NOT_STARTED);
+ pInstance->SetData(DATA_KING_DRED_ACHIEV, 0);
+ }
+
+ uiBellowingRoarTimer = 33*IN_MILISECONDS;
+ uiGrievousBiteTimer = 20*IN_MILISECONDS;
+ uiManglingSlashTimer = 18.5*IN_MILISECONDS;
+ uiFearsomeRoarTimer = urand(10*IN_MILISECONDS,20*IN_MILISECONDS);
+ uiPiercingSlashTimer = 17*IN_MILISECONDS;
+ uiRaptorCallTimer = urand(20*IN_MILISECONDS,25*IN_MILISECONDS);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_DRED_EVENT,IN_PROGRESS);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiBellowingRoarTimer < diff)
+ {
+ DoCastAOE(SPELL_BELLOWING_ROAR, false);
+ uiBellowingRoarTimer = 40*IN_MILISECONDS;
+ } else uiBellowingRoarTimer -=diff;
+
+ if (uiGrievousBiteTimer < diff)
+ {
+ DoCastVictim(SPELL_GRIEVOUS_BITE ,false);
+ uiGrievousBiteTimer = 20*IN_MILISECONDS;
+ } else uiGrievousBiteTimer -=diff;
+
+ if (uiManglingSlashTimer < diff)
+ {
+ DoCastVictim(SPELL_MANGLING_SLASH,false);
+ uiManglingSlashTimer = 20*IN_MILISECONDS;
+ } else uiManglingSlashTimer -=diff;
+
+ if (uiFearsomeRoarTimer < diff)
+ {
+ DoCastAOE(SPELL_FEARSOME_ROAR,false);
+ uiFearsomeRoarTimer = urand(16*IN_MILISECONDS,18*IN_MILISECONDS);
+ } else uiFearsomeRoarTimer -=diff;
+
+ if (uiPiercingSlashTimer < diff)
+ {
+ DoCastVictim(SPELL_PIERCING_SLASH,false);
+ uiPiercingSlashTimer = 20*IN_MILISECONDS;
+ } else uiPiercingSlashTimer -=diff;
+
+ if (uiRaptorCallTimer < diff)
+ {
+ DoCastVictim(SPELL_RAPTOR_CALL,false);
+
+ float x,y,z;
+
+ me->GetClosePoint(x,y,z,me->GetObjectSize()/3,10.0f);
+ me->SummonCreature(RAND(NPC_RAPTOR_1,NPC_RAPTOR_2),x,y,z,0,TEMPSUMMON_DEAD_DESPAWN,1*IN_MILISECONDS);
+
+ uiRaptorCallTimer = urand(20*IN_MILISECONDS,25*IN_MILISECONDS);
+ } else uiRaptorCallTimer -=diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_DRED_EVENT,DONE);
+
+ if (IsHeroic() && pInstance->GetData(DATA_KING_DRED_ACHIEV) == 6)
+ pInstance->DoCompleteAchievement(ACHIEV_BETTER_OFF_DRED);
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_dred(Creature* pCreature)
+{
+ return new boss_dredAI (pCreature);
+}
+
+struct npc_drakkari_gutripperAI : public ScriptedAI
+{
+ npc_drakkari_gutripperAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 GutRipTimer;
+
+ void Reset()
+ {
+ GutRipTimer = urand(10000,15000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (GutRipTimer < diff)
+ {
+ DoCastVictim(SPELL_GUT_RIP,false);
+ GutRipTimer = urand(10000,15000);
+ }else GutRipTimer -=diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ {
+ if (IsHeroic() && pInstance->GetData(DATA_DRED_EVENT) == IN_PROGRESS && pInstance->GetData(DATA_KING_DRED_ACHIEV) < 6)
+ {
+ pInstance->SetData(DATA_KING_DRED_ACHIEV, pInstance->GetData(DATA_KING_DRED_ACHIEV) + 1);
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_drakkari_gutripper(Creature* pCreature)
+{
+ return new npc_drakkari_gutripperAI (pCreature);
+}
+
+struct npc_drakkari_scytheclawAI : public ScriptedAI
+{
+ npc_drakkari_scytheclawAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiRendTimer;
+
+ void Reset()
+ {
+ uiRendTimer = urand(10*IN_MILISECONDS,15*IN_MILISECONDS);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiRendTimer < diff)
+ {
+ DoCastVictim(SPELL_REND,false);
+ uiRendTimer = urand(10*IN_MILISECONDS,15*IN_MILISECONDS);
+ }else uiRendTimer -=diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ {
+ if (IsHeroic() && pInstance->GetData(DATA_DRED_EVENT) == IN_PROGRESS && pInstance->GetData(DATA_KING_DRED_ACHIEV) < 6)
+ {
+ pInstance->SetData(DATA_KING_DRED_ACHIEV, pInstance->GetData(DATA_KING_DRED_ACHIEV) + 1);
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_drakkari_scytheclaw(Creature* pCreature)
+{
+ return new npc_drakkari_scytheclawAI (pCreature);
+}
+
+void AddSC_boss_dred()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_drakkari_gutripper";
+ newscript->GetAI = &GetAI_npc_drakkari_gutripper;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_drakkari_scytheclaw";
+ newscript->GetAI = &GetAI_npc_drakkari_scytheclaw;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_dred";
+ newscript->GetAI = &GetAI_boss_dred;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/draktharon_keep/boss_novos.cpp b/src/server/scripts/northrend/draktharon_keep/boss_novos.cpp
new file mode 100644
index 00000000000..5e8792c352d
--- /dev/null
+++ b/src/server/scripts/northrend/draktharon_keep/boss_novos.cpp
@@ -0,0 +1,328 @@
+/*
+* Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "drak_tharon_keep.h"
+
+enum Spells
+{
+ SPELL_ARCANE_BLAST = 49198,
+ H_SPELL_ARCANE_BLAST = 59909,
+ SPELL_ARCANE_FIELD = 47346,
+ SPELL_BLIZZARD = 49034,
+ H_SPELL_BLIZZARD = 59854,
+ SPELL_FROSTBOLT = 49037,
+ H_SPELL_FROSTBOLT = 59855,
+ SPELL_WRATH_OF_MISERY = 50089,
+ H_SPELL_WRATH_OF_MISERY = 59856,
+ SPELL_SUMMON_MINIONS = 59910 //Summons an army of Fetid Troll Corpses to assist the caster.
+};
+//not in db
+enum Yells
+{
+ SAY_AGGRO = -1600000,
+ SAY_KILL = -1600001,
+ SAY_DEATH = -1600002,
+ SAY_NECRO_ADD = -1600003,
+ SAY_REUBBLE_1 = -1600004,
+ SAY_REUBBLE_2 = -1600005
+};
+enum Creatures
+{
+ CREATURE_RISEN_SHADOWCASTER = 27600,
+ CREATURE_FETID_TROLL_CORPSE = 27598,
+ CREATURE_HULKING_CORPSE = 27597,
+ CREATURE_CRYSTAL_HANDLER = 26627
+};
+enum CombatPhase
+{
+ IDLE,
+ PHASE_1,
+ PHASE_2
+};
+enum Achievements
+{
+ ACHIEV_OH_NOVOS = 2057
+};
+
+static Position AddSpawnPoint = { -379.20, -816.76, 59.70 };
+static Position CrystalHandlerSpawnPoint = { -326.626343, -709.956604, 27.813314 };
+static Position AddDestinyPoint = { -379.314545, -772.577637, 28.58837 };
+
+struct boss_novosAI : public Scripted_NoMovementAI
+{
+ boss_novosAI(Creature *c) : Scripted_NoMovementAI(c), lSummons(me)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiTimer;
+ uint32 uiCrystalHandlerTimer;
+
+ bool bAchiev;
+
+ SummonList lSummons;
+
+ std::list<uint64> luiCrystals;
+
+ CombatPhase Phase;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ Phase = IDLE;
+ luiCrystals.clear();
+ bAchiev = true;
+ me->CastStop();
+ lSummons.DespawnAll();
+
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_NOVOS_EVENT, NOT_STARTED);
+ luiCrystals.push_back(pInstance->GetData64(DATA_NOVOS_CRYSTAL_1));
+ luiCrystals.push_back(pInstance->GetData64(DATA_NOVOS_CRYSTAL_2));
+ luiCrystals.push_back(pInstance->GetData64(DATA_NOVOS_CRYSTAL_3));
+ luiCrystals.push_back(pInstance->GetData64(DATA_NOVOS_CRYSTAL_4));
+ for (std::list<uint64>::const_iterator itr = luiCrystals.begin(); itr != luiCrystals.end(); ++itr)
+ {
+ if (GameObject* pTemp = pInstance->instance->GetGameObject(*itr))
+ pTemp->SetGoState(GO_STATE_READY);
+ }
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ Phase = PHASE_1;
+ uiCrystalHandlerTimer = 30*IN_MILISECONDS;
+ uiTimer = 1*IN_MILISECONDS;
+ DoCast(SPELL_ARCANE_FIELD);
+ if (pInstance)
+ {
+ for (std::list<uint64>::const_iterator itr = luiCrystals.begin(); itr != luiCrystals.end(); ++itr)
+ {
+ if (GameObject *pTemp = pInstance->instance->GetGameObject(*itr))
+ pTemp->SetGoState(GO_STATE_ACTIVE);
+ }
+ pInstance->SetData(DATA_NOVOS_EVENT, IN_PROGRESS);
+ }
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ switch (Phase)
+ {
+ case PHASE_1:
+ if (uiTimer <= diff)
+ {
+ Creature *pSummon = me->SummonCreature(RAND(CREATURE_FETID_TROLL_CORPSE,CREATURE_HULKING_CORPSE,CREATURE_RISEN_SHADOWCASTER), AddSpawnPoint, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20*IN_MILISECONDS);
+ pSummon->GetMotionMaster()->MovePoint(0, AddDestinyPoint);
+ //If spell is casted stops casting arcane field so no spell casting
+ //DoCast(me, SPELL_SUMMON_MINIONS);
+ uiTimer = 3*IN_MILISECONDS;
+ } else uiTimer -= diff;
+ if (uiCrystalHandlerTimer <= diff)
+ {
+ DoScriptText(SAY_NECRO_ADD, me);
+ Creature *pCrystalHandler = me->SummonCreature(CREATURE_CRYSTAL_HANDLER, CrystalHandlerSpawnPoint, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20*IN_MILISECONDS);
+ pCrystalHandler->GetMotionMaster()->MovePoint(0, AddDestinyPoint);
+ uiCrystalHandlerTimer = urand(20*IN_MILISECONDS,30*IN_MILISECONDS);
+ } else uiCrystalHandlerTimer -= diff;
+ break;
+ case PHASE_2:
+ if (uiTimer <= diff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, DUNGEON_MODE(RAND(SPELL_ARCANE_BLAST,SPELL_BLIZZARD,SPELL_FROSTBOLT,SPELL_WRATH_OF_MISERY),
+ RAND(H_SPELL_ARCANE_BLAST,H_SPELL_BLIZZARD,H_SPELL_FROSTBOLT,H_SPELL_WRATH_OF_MISERY)));
+ uiTimer = urand(1*IN_MILISECONDS,3*IN_MILISECONDS);
+ } else uiTimer -= diff;
+ break;
+ }
+ }
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_NOVOS_EVENT, DONE);
+
+ if (IsHeroic() && bAchiev)
+ pInstance->DoCompleteAchievement(ACHIEV_OH_NOVOS);
+ }
+ lSummons.DespawnAll();
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+ DoScriptText(SAY_KILL, me);
+ }
+
+ void JustSummoned(Creature *summon)
+ {
+ lSummons.Summon(summon);
+ }
+
+ void RemoveCrystal()
+ {
+ if (!luiCrystals.empty())
+ {
+ if (pInstance)
+ if (GameObject *pTemp = pInstance->instance->GetGameObject(luiCrystals.back()))
+ pTemp->SetGoState(GO_STATE_READY);
+ luiCrystals.pop_back();
+ }
+ if (luiCrystals.empty())
+ {
+ me->CastStop();
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ Phase = PHASE_2;
+ uiTimer = 1*IN_MILISECONDS;
+ }
+ }
+
+ Unit* GetRandomTarget()
+ {
+ return SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
+ }
+};
+
+enum CrystalHandlerSpells
+{
+ SPELL_FLASH_OF_DARKNESS = 49668,
+ H_SPELL_FLASH_OF_DARKNESS = 59004
+};
+
+struct mob_crystal_handlerAI : public ScriptedAI
+{
+ mob_crystal_handlerAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiFlashOfDarknessTimer;
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ uiFlashOfDarknessTimer = 5*IN_MILISECONDS;
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (Creature* pNovos = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_NOVOS) : 0))
+ CAST_AI(boss_novosAI,pNovos->AI())->RemoveCrystal();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiFlashOfDarknessTimer <= diff)
+ {
+ DoCast(me->getVictim(), DUNGEON_MODE(SPELL_FLASH_OF_DARKNESS,H_SPELL_FLASH_OF_DARKNESS));
+ uiFlashOfDarknessTimer = 5*IN_MILISECONDS;
+ } else uiFlashOfDarknessTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE || id != 0)
+ return;
+ if (Creature *pNovos = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_NOVOS) : 0))
+ if (Unit *pTarget = CAST_AI(boss_novosAI, pNovos->AI())->GetRandomTarget())
+ AttackStart(pTarget);
+ }
+};
+
+struct mob_novos_minionAI : public ScriptedAI
+{
+ mob_novos_minionAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE || id !=0)
+ return;
+ if (Creature* pNovos = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_NOVOS) : 0))
+ {
+ CAST_AI(boss_novosAI, pNovos->AI())->bAchiev = false;
+ if (Unit *pTarget = CAST_AI(boss_novosAI, pNovos->AI())->GetRandomTarget())
+ AttackStart(pTarget);
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_novos(Creature* pCreature)
+{
+ return new boss_novosAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_crystal_handler(Creature* pCreature)
+{
+ return new mob_crystal_handlerAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_novos_minion(Creature* pCreature)
+{
+ return new mob_novos_minionAI (pCreature);
+}
+
+void AddSC_boss_novos()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_novos";
+ newscript->GetAI = &GetAI_boss_novos;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_crystal_handler";
+ newscript->GetAI = &GetAI_mob_crystal_handler;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_novos_minion";
+ newscript->GetAI = &GetAI_mob_novos_minion;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/draktharon_keep/boss_tharon_ja.cpp b/src/server/scripts/northrend/draktharon_keep/boss_tharon_ja.cpp
new file mode 100644
index 00000000000..1e60dfc6135
--- /dev/null
+++ b/src/server/scripts/northrend/draktharon_keep/boss_tharon_ja.cpp
@@ -0,0 +1,260 @@
+/*
+* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "drak_tharon_keep.h"
+
+enum Spells
+{
+ //skeletal spells (phase 1)
+ SPELL_CURSE_OF_LIFE = 49527,
+ H_SPELL_CURSE_OF_LIFE = 59972,
+ SPELL_RAIN_OF_FIRE = 49518,
+ H_SPELL_RAIN_OF_FIRE = 59971,
+ SPELL_SHADOW_VOLLEY = 49528,
+ H_SPELL_SHADOW_VOLLEY = 59973,
+ SPELL_DECAY_FLESH = 49356, //casted at end of phase 1, starts phase 2
+ //flesh spells (phase 2)
+ SPELL_GIFT_OF_THARON_JA = 52509,
+ SPELL_EYE_BEAM = 49544,
+ H_SPELL_EYE_BEAM = 59965,
+ SPELL_LIGHTNING_BREATH = 49537,
+ H_SPELL_LIGHTNING_BREATH = 59963,
+ SPELL_POISON_CLOUD = 49548,
+ H_SPELL_POISON_CLOUD = 59969,
+ SPELL_RETURN_FLESH = 53463, //Channeled spell ending phase two and returning to phase 1. This ability will stun the party for 6 seconds.
+ SPELL_ACHIEVEMENT_CHECK = 61863,
+};
+
+enum Yells
+{
+ SAY_AGGRO = -1600011,
+ SAY_KILL_1 = -1600012,
+ SAY_KILL_2 = -1600013,
+ SAY_FLESH_1 = -1600014,
+ SAY_FLESH_2 = -1600015,
+ SAY_SKELETON_1 = -1600016,
+ SAY_SKELETON_2 = -1600017,
+ SAY_DEATH = -1600018
+};
+enum Models
+{
+ MODEL_FLESH = 27073,
+ MODEL_SKELETON = 27511
+};
+enum CombatPhase
+{
+ SKELETAL,
+ GOING_FLESH,
+ FLESH,
+ GOING_SKELETAL
+};
+
+struct boss_tharon_jaAI : public ScriptedAI
+{
+ boss_tharon_jaAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiPhaseTimer;
+ uint32 uiCurseOfLifeTimer;
+ uint32 uiRainOfFireTimer;
+ uint32 uiShadowVolleyTimer;
+ uint32 uiEyeBeamTimer;
+ uint32 uiLightningBreathTimer;
+ uint32 uiPoisonCloudTimer;
+
+ CombatPhase Phase;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiPhaseTimer = 20*IN_MILISECONDS;
+ uiCurseOfLifeTimer = 1*IN_MILISECONDS;
+ uiRainOfFireTimer = urand(14*IN_MILISECONDS,18*IN_MILISECONDS);
+ uiShadowVolleyTimer = urand(8*IN_MILISECONDS,10*IN_MILISECONDS);
+ Phase = SKELETAL;
+ me->SetDisplayId(me->GetNativeDisplayId());
+ if (pInstance)
+ pInstance->SetData(DATA_THARON_JA_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_THARON_JA_EVENT, IN_PROGRESS);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ switch (Phase)
+ {
+ case SKELETAL:
+ if (uiCurseOfLifeTimer < diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_CURSE_OF_LIFE);
+ uiCurseOfLifeTimer = urand(10*IN_MILISECONDS,15*IN_MILISECONDS);
+ } else uiCurseOfLifeTimer -= diff;
+
+ if (uiShadowVolleyTimer < diff)
+ {
+ DoCastVictim(SPELL_SHADOW_VOLLEY);
+ uiShadowVolleyTimer = urand(8*IN_MILISECONDS,10*IN_MILISECONDS);
+ } else uiShadowVolleyTimer -= diff;
+
+ if (uiRainOfFireTimer < diff)
+ {
+ DoCastAOE(SPELL_RAIN_OF_FIRE);
+ uiRainOfFireTimer = urand(14*IN_MILISECONDS,18*IN_MILISECONDS);
+ } else uiRainOfFireTimer -= diff;
+
+ if (uiPhaseTimer < diff)
+ {
+ DoCast(SPELL_DECAY_FLESH);
+ Phase = GOING_FLESH;
+ uiPhaseTimer = 6*IN_MILISECONDS;
+ } else uiPhaseTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ break;
+ case GOING_FLESH:
+ if (uiPhaseTimer < diff)
+ {
+ DoScriptText(RAND(SAY_FLESH_1,SAY_FLESH_2),me);
+ me->SetDisplayId(MODEL_FLESH);
+ std::list<HostileReference*>& threatlist = me->getThreatManager().getThreatList();
+ for (std::list<HostileReference*>::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
+ {
+ Unit *pTemp = Unit::GetUnit((*me),(*itr)->getUnitGuid());
+ if (pTemp && pTemp->GetTypeId() == TYPEID_PLAYER)
+ {
+ me->AddAura(SPELL_GIFT_OF_THARON_JA,pTemp);
+ pTemp->SetDisplayId(MODEL_SKELETON);
+ }
+ }
+ uiPhaseTimer = 20*IN_MILISECONDS;
+ uiLightningBreathTimer = urand(3*IN_MILISECONDS,4*IN_MILISECONDS);
+ uiEyeBeamTimer = urand(4*IN_MILISECONDS,8*IN_MILISECONDS);
+ uiPoisonCloudTimer = urand(6*IN_MILISECONDS,7*IN_MILISECONDS);
+ Phase = FLESH;
+ } else uiPhaseTimer -= diff;
+ break;
+ case FLESH:
+ if (uiLightningBreathTimer < diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_LIGHTNING_BREATH);
+ uiLightningBreathTimer = urand(6*IN_MILISECONDS,7*IN_MILISECONDS);
+ } else uiLightningBreathTimer -= diff;
+
+ if (uiEyeBeamTimer < diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_EYE_BEAM);
+ uiEyeBeamTimer = urand(4*IN_MILISECONDS,6*IN_MILISECONDS);
+ } else uiEyeBeamTimer -= diff;
+
+ if (uiPoisonCloudTimer < diff)
+ {
+ DoCastAOE(SPELL_POISON_CLOUD);
+ uiPoisonCloudTimer = urand(10*IN_MILISECONDS,12*IN_MILISECONDS);
+ } else uiPoisonCloudTimer -= diff;
+
+ if (uiPhaseTimer < diff)
+ {
+ DoCast(SPELL_RETURN_FLESH);
+ Phase = GOING_SKELETAL;
+ uiPhaseTimer = 6*IN_MILISECONDS;
+ } else uiPhaseTimer -= diff;
+ DoMeleeAttackIfReady();
+ break;
+ case GOING_SKELETAL:
+ if (uiPhaseTimer < diff)
+ {
+ DoScriptText(RAND(SAY_SKELETON_1,SAY_SKELETON_2), me);
+ me->DeMorph();
+ Phase = SKELETAL;
+ uiPhaseTimer = 20*IN_MILISECONDS;
+ uiCurseOfLifeTimer = 1*IN_MILISECONDS;
+ uiRainOfFireTimer = urand(14*IN_MILISECONDS,18*IN_MILISECONDS);
+ uiShadowVolleyTimer = urand(8*IN_MILISECONDS,10*IN_MILISECONDS);
+ std::list<HostileReference*>& threatlist = me->getThreatManager().getThreatList();
+ for (std::list<HostileReference*>::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
+ {
+ Unit *pTemp = Unit::GetUnit((*me),(*itr)->getUnitGuid());
+ if (pTemp && pTemp->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (pTemp->HasAura(SPELL_GIFT_OF_THARON_JA))
+ pTemp->RemoveAura(SPELL_GIFT_OF_THARON_JA);
+ pTemp->DeMorph();
+ }
+ }
+ } else uiPhaseTimer -= diff;
+ break;
+ }
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(RAND(SAY_KILL_1,SAY_KILL_2),me);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH,me);
+
+ if (pInstance)
+ {
+ // clean morph on players
+ Map::PlayerList const &PlayerList = pInstance->instance->GetPlayers();
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ if (Player *pPlayer = i->getSource())
+ pPlayer->DeMorph();
+ // cast is not rewarding the achievement.
+ // DoCast(SPELL_ACHIEVEMENT_CHECK);
+ pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, SPELL_ACHIEVEMENT_CHECK);
+
+ pInstance->SetData(DATA_THARON_JA_EVENT, DONE);
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_tharon_ja(Creature* pCreature)
+{
+ return new boss_tharon_jaAI (pCreature);
+}
+
+void AddSC_boss_tharon_ja()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_tharon_ja";
+ newscript->GetAI = &GetAI_boss_tharon_ja;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/draktharon_keep/boss_trollgore.cpp b/src/server/scripts/northrend/draktharon_keep/boss_trollgore.cpp
new file mode 100644
index 00000000000..03eac73385d
--- /dev/null
+++ b/src/server/scripts/northrend/draktharon_keep/boss_trollgore.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Comment: TODO: spawn troll waves
+ */
+
+#include "ScriptedPch.h"
+#include "drak_tharon_keep.h"
+
+enum Spells
+{
+ SPELL_INFECTED_WOUND = 49637,
+ SPELL_CRUSH = 49639,
+ SPELL_CORPSE_EXPLODE = 49555,
+ SPELL_CONSUME = 49380,
+ SPELL_CONSUME_AURA = 49381,
+ //Heroic spells
+ H_SPELL_CORPSE_EXPLODE = 59807,
+ H_SPELL_CONSUME = 59803,
+ H_SPELL_CONSUME_AURA = 59805,
+};
+enum Yells
+{
+ SAY_AGGRO = -1600006,
+ SAY_KILL = -1600007,
+ SAY_CONSUME = -1600008,
+ SAY_EXPLODE = -1600009,
+ SAY_DEATH = -1600010
+};
+enum Achievements
+{
+ ACHIEV_CONSUMPTION_JUNCTION = 2151
+};
+enum Creatures
+{
+ NPC_DRAKKARI_INVADER_1 = 27753,
+ NPC_DRAKKARI_INVADER_2 = 27709
+};
+
+Position AddSpawnPoint = { -260.493011, -622.968018, 26.605301, 3.036870 };
+
+struct boss_trollgoreAI : public ScriptedAI
+{
+ boss_trollgoreAI(Creature *c) : ScriptedAI(c), lSummons(me)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiConsumeTimer;
+ uint32 uiAuraCountTimer;
+ uint32 uiCrushTimer;
+ uint32 uiInfectedWoundTimer;
+ uint32 uiExplodeCorpseTimer;
+ uint32 uiSpawnTimer;
+
+ bool bAchiev;
+
+ SummonList lSummons;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiConsumeTimer = 15*IN_MILISECONDS;
+ uiAuraCountTimer = 15.5*IN_MILISECONDS;
+ uiCrushTimer = urand(1*IN_MILISECONDS,5*IN_MILISECONDS);
+ uiInfectedWoundTimer = urand(60*IN_MILISECONDS,10*IN_MILISECONDS);
+ uiExplodeCorpseTimer = 3*IN_MILISECONDS;
+ uiSpawnTimer = urand(30*IN_MILISECONDS,40*IN_MILISECONDS);
+
+ bAchiev = IsHeroic();
+
+ lSummons.DespawnAll();
+
+ me->RemoveAura(DUNGEON_MODE(SPELL_CONSUME_AURA,H_SPELL_CONSUME_AURA));
+
+ if (pInstance)
+ pInstance->SetData(DATA_TROLLGORE_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_TROLLGORE_EVENT, IN_PROGRESS);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiSpawnTimer <= diff)
+ {
+ uint32 spawnNumber = urand(2,DUNGEON_MODE(3,5));
+ for (uint8 i = 0; i < spawnNumber; ++i)
+ DoSummon(RAND(NPC_DRAKKARI_INVADER_1,NPC_DRAKKARI_INVADER_2), AddSpawnPoint, 0, TEMPSUMMON_DEAD_DESPAWN);
+ uiSpawnTimer = urand(30*IN_MILISECONDS,40*IN_MILISECONDS);
+ } else uiSpawnTimer -= diff;
+
+ if (uiConsumeTimer <= diff)
+ {
+ DoScriptText(SAY_CONSUME, me);
+ DoCast(SPELL_CONSUME);
+ uiConsumeTimer = 15*IN_MILISECONDS;
+ } else uiConsumeTimer -= diff;
+
+ if (bAchiev)
+ {
+ Aura *pConsumeAura = me->GetAura(DUNGEON_MODE(SPELL_CONSUME_AURA,H_SPELL_CONSUME_AURA));
+ if (pConsumeAura && pConsumeAura->GetStackAmount() > 9)
+ bAchiev = false;
+ }
+
+ if (uiCrushTimer <= diff)
+ {
+ DoCastVictim(SPELL_CRUSH);
+ uiCrushTimer = urand(10*IN_MILISECONDS,15*IN_MILISECONDS);
+ } else uiCrushTimer -= diff;
+
+ if (uiInfectedWoundTimer <= diff)
+ {
+ DoCastVictim(SPELL_INFECTED_WOUND);
+ uiInfectedWoundTimer = urand(25*IN_MILISECONDS,35*IN_MILISECONDS);
+ } else uiInfectedWoundTimer -= diff;
+
+ if (uiExplodeCorpseTimer <= diff)
+ {
+ DoCast(SPELL_CORPSE_EXPLODE);
+ DoScriptText(SAY_EXPLODE, me);
+ uiExplodeCorpseTimer = urand(15*IN_MILISECONDS,19*IN_MILISECONDS);
+ } else uiExplodeCorpseTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ lSummons.DespawnAll();
+
+ if (pInstance)
+ {
+ if (bAchiev)
+ pInstance->DoCompleteAchievement(ACHIEV_CONSUMPTION_JUNCTION);
+ pInstance->SetData(DATA_TROLLGORE_EVENT, DONE);
+ }
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+ DoScriptText(SAY_KILL, me);
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ lSummons.push_back(summon->GetGUID());
+ if (summon->AI())
+ summon->AI()->AttackStart(me);
+ }
+};
+
+CreatureAI* GetAI_boss_trollgore(Creature* pCreature)
+{
+ return new boss_trollgoreAI (pCreature);
+}
+
+void AddSC_boss_trollgore()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_trollgore";
+ newscript->GetAI = &GetAI_boss_trollgore;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/draktharon_keep/drak_tharon_keep.h b/src/server/scripts/northrend/draktharon_keep/drak_tharon_keep.h
new file mode 100644
index 00000000000..597971d17dd
--- /dev/null
+++ b/src/server/scripts/northrend/draktharon_keep/drak_tharon_keep.h
@@ -0,0 +1,40 @@
+/*
+* Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef DEF_DRAK_THARON_H
+#define DEF_DRAK_THARON_H
+enum Data
+{
+ DATA_TROLLGORE_EVENT,
+ DATA_NOVOS_EVENT,
+ DATA_DRED_EVENT,
+ DATA_THARON_JA_EVENT,
+ DATA_KING_DRED_ACHIEV
+};
+enum Data64
+{
+ DATA_TROLLGORE,
+ DATA_NOVOS,
+ DATA_DRED,
+ DATA_THARON_JA,
+ DATA_NOVOS_CRYSTAL_1,
+ DATA_NOVOS_CRYSTAL_2,
+ DATA_NOVOS_CRYSTAL_3,
+ DATA_NOVOS_CRYSTAL_4
+};
+#endif
diff --git a/src/server/scripts/northrend/draktharon_keep/instance_drak_tharon_keep.cpp b/src/server/scripts/northrend/draktharon_keep/instance_drak_tharon_keep.cpp
new file mode 100644
index 00000000000..9f4d2ee52a2
--- /dev/null
+++ b/src/server/scripts/northrend/draktharon_keep/instance_drak_tharon_keep.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "drak_tharon_keep.h"
+
+#define MAX_ENCOUNTER 4
+
+/* Drak'Tharon Keep encounters:
+0 - Trollgore
+1 - Novos
+2 - King Dred
+3 - Tharon Ja
+*/
+
+enum Creatures
+{
+ NPC_TROLLGORE = 26630,
+ NPC_NOVOS = 26631,
+ NPC_KING_DRED = 27483,
+ NPC_THARON_JA = 26632
+};
+enum GameObjects
+{
+ GO_NOVOS_CRYSTAL_1 = 189299,
+ GO_NOVOS_CRYSTAL_2 = 189300,
+ GO_NOVOS_CRYSTAL_3 = 189301,
+ GO_NOVOS_CRYSTAL_4 = 189302
+};
+
+struct instance_drak_tharon : public ScriptedInstance
+{
+ instance_drak_tharon(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+
+ uint8 uiDredAchievCounter;
+
+ uint64 uiTrollgore;
+ uint64 uiNovos;
+ uint64 uiDred;
+ uint64 uiTharonJa;
+
+ uint64 uiNovosCrystal1;
+ uint64 uiNovosCrystal2;
+ uint64 uiNovosCrystal3;
+ uint64 uiNovosCrystal4;
+
+ uint8 m_auiEncounter[MAX_ENCOUNTER];
+
+ std::string str_data;
+
+ void Initialize()
+ {
+ uiTrollgore = 0;
+ uiNovos = 0;
+ uiDred = 0;
+ uiTharonJa = 0;
+ uiNovosCrystal1 = 0;
+ uiNovosCrystal2 = 0;
+ uiNovosCrystal3 = 0;
+ uiNovosCrystal4 = 0;
+ uiDredAchievCounter = 0;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+ void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
+ {
+ switch(pGo->GetEntry())
+ {
+ case GO_NOVOS_CRYSTAL_1:
+ uiNovosCrystal1 = pGo->GetGUID();
+ break;
+ case GO_NOVOS_CRYSTAL_2:
+ uiNovosCrystal2 = pGo->GetGUID();
+ break;
+ case GO_NOVOS_CRYSTAL_3:
+ uiNovosCrystal3 = pGo->GetGUID();
+ break;
+ case GO_NOVOS_CRYSTAL_4:
+ uiNovosCrystal4 = pGo->GetGUID();
+ break;
+ }
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool /*add*/)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case NPC_TROLLGORE:
+ uiTrollgore = pCreature->GetGUID();
+ break;
+ case NPC_NOVOS:
+ uiNovos = pCreature->GetGUID();
+ break;
+ case NPC_KING_DRED:
+ uiDred = pCreature->GetGUID();
+ break;
+ case NPC_THARON_JA:
+ uiTharonJa = pCreature->GetGUID();
+ break;
+ }
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_TROLLGORE: return uiTrollgore;
+ case DATA_NOVOS: return uiNovos;
+ case DATA_DRED: return uiDred;
+ case DATA_THARON_JA: return uiTharonJa;
+ case DATA_NOVOS_CRYSTAL_1: return uiNovosCrystal1;
+ case DATA_NOVOS_CRYSTAL_2: return uiNovosCrystal2;
+ case DATA_NOVOS_CRYSTAL_3: return uiNovosCrystal3;
+ case DATA_NOVOS_CRYSTAL_4: return uiNovosCrystal4;
+ }
+
+ return 0;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_TROLLGORE_EVENT:
+ m_auiEncounter[0] = data;
+ break;
+ case DATA_NOVOS_EVENT:
+ m_auiEncounter[1] = data;
+ break;
+ case DATA_DRED_EVENT:
+ m_auiEncounter[2] = data;
+ break;
+ case DATA_THARON_JA_EVENT:
+ m_auiEncounter[3] = data;
+ break;
+
+ case DATA_KING_DRED_ACHIEV:
+ uiDredAchievCounter = data;
+ break;
+ }
+
+ if (data == DONE)
+ {
+ SaveToDB();
+ }
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch (type)
+ {
+ case DATA_TROLLGORE_EVENT: return m_auiEncounter[0];
+ case DATA_NOVOS_EVENT: return m_auiEncounter[1];
+ case DATA_DRED_EVENT: return m_auiEncounter[2];
+ case DATA_THARON_JA_EVENT: return m_auiEncounter[3];
+ case DATA_KING_DRED_ACHIEV: return uiDredAchievCounter;
+ }
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::string str_data;
+
+ std::ostringstream saveStream;
+ saveStream << "D K " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
+ << m_auiEncounter[2] << " " << m_auiEncounter[3];
+
+ str_data = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return str_data;
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0,data1,data2,data3;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;
+
+ if (dataHead1 == 'D' && dataHead2 == 'K')
+ {
+ m_auiEncounter[0] = data0;
+ m_auiEncounter[1] = data1;
+ m_auiEncounter[2] = data2;
+ m_auiEncounter[3] = data3;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_drak_tharon(Map* pMap)
+{
+ return new instance_drak_tharon(pMap);
+}
+
+void AddSC_instance_drak_tharon()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_drak_tharon";
+ newscript->GetInstanceData = &GetInstanceData_instance_drak_tharon;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/frozen_halls/forge_of_souls/boss_bronjahm.cpp b/src/server/scripts/northrend/frozen_halls/forge_of_souls/boss_bronjahm.cpp
new file mode 100644
index 00000000000..59db2842735
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/forge_of_souls/boss_bronjahm.cpp
@@ -0,0 +1,263 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "forge_of_souls.h"
+
+/*
+ * TODO:
+ * - Fix Soul Storm spell and remove work around.
+ */
+
+enum Yells
+{
+ SAY_AGGRO = -1632001,
+ SAY_SLAY_1 = -1632002,
+ SAY_SLAY_2 = -1632003,
+ SAY_DEATH = -1632004,
+ SAY_SOUL_STORM = -1632005,
+ SAY_CORRUPT_SOUL = -1632006,
+};
+
+enum Spells
+{
+ SPELL_MAGIC_S_BANE = 68793,
+ SPELL_CORRUPT_SOUL = 68839,
+ SPELL_CONSUME_SOUL = 68858,
+ SPELL_TELEPORT = 68988,
+ SPELL_FEAR = 68950,
+ SPELL_SOULSTORM = 68872,
+ SPELL_SOULSTORM_AURA = 68921,
+ SPELL_SHADOW_BOLT = 70043,
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_SHADOW_BOLT,
+ EVENT_MAGIC_BANE,
+ EVENT_CORRUPT_SOUL,
+ EVENT_SOUL_STORM,
+ EVENT_SOUL_STORM_AURA,
+ EVENT_FEAR,
+};
+
+enum CombatPhases
+{
+ PHASE_1,
+ PHASE_2
+};
+
+struct boss_bronjahmAI : public ScriptedAI
+{
+ boss_bronjahmAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = me->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+ EventMap events;
+
+ CombatPhases phase;
+
+ void Reset()
+ {
+ phase = PHASE_1;
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+
+ events.Reset();
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, 2000);
+ events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000,15000));
+ events.ScheduleEvent(EVENT_CORRUPT_SOUL, urand(25000,35000));
+
+ if (pInstance)
+ pInstance->SetData(DATA_BRONJAHM_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_BRONJAHM_EVENT, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_BRONJAHM_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit * /*who*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ // Cast aura spell on all players farther than 10y
+ void ApplySoulStorm()
+ {
+ std::list<Unit*> targetList;
+
+ SelectTargetList(targetList, 100, SELECT_TARGET_TOPAGGRO, -10.0f);
+ if (targetList.empty())
+ return;
+
+ for (std::list<Unit *>::const_iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
+ {
+ Unit* pUnit = (*itr);
+ if (pUnit && pUnit->isAlive())
+ me->CastSpell(pUnit, SPELL_SOULSTORM_AURA, true);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ if (phase == PHASE_1 && HealthBelowPct(30))
+ {
+ phase = PHASE_2;
+ DoCast(me,SPELL_TELEPORT);
+ me->GetMotionMaster()->Clear();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ events.CancelEvent(EVENT_CORRUPT_SOUL);
+ events.ScheduleEvent(EVENT_SOUL_STORM, 1000);
+ events.ScheduleEvent(EVENT_FEAR, urand(8000,12000));
+ return;
+ }
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_CORRUPT_SOUL:
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,1))
+ {
+ DoScriptText(SAY_CORRUPT_SOUL, me);
+ DoCast(pTarget,SPELL_CORRUPT_SOUL);
+ }
+ events.ScheduleEvent(EVENT_CORRUPT_SOUL, urand(25000,35000));
+ break;
+ case EVENT_SOUL_STORM:
+ DoScriptText(SAY_SOUL_STORM, me);
+ // DoCast(me, SPELL_SOULSTORM); bug: put the aura without the limit of 10 yards.
+ events.ScheduleEvent(EVENT_SOUL_STORM_AURA, 1000);
+ break;
+ case EVENT_SOUL_STORM_AURA:
+ ApplySoulStorm();
+ events.ScheduleEvent(EVENT_SOUL_STORM_AURA, 1000);
+ break;
+ case EVENT_FEAR:
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,1))
+ DoCast(pTarget,SPELL_FEAR);
+ events.ScheduleEvent(EVENT_FEAR, urand(8000,12000));
+ break;
+ case EVENT_SHADOW_BOLT:
+ DoCastVictim(SPELL_SHADOW_BOLT);
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, 2000);
+ break;
+ case EVENT_MAGIC_BANE:
+ DoCastVictim(SPELL_MAGIC_S_BANE);
+ events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000,15000));
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_bronjahm(Creature* pCreature)
+{
+ return new boss_bronjahmAI(pCreature);
+}
+
+struct mob_corrupted_soul_fragmentAI : public ScriptedAI
+{
+ mob_corrupted_soul_fragmentAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = me->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiCheckTimer;
+
+ void Reset()
+ {
+ uiCheckTimer = 0; // first check is immediate
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (uiCheckTimer <= diff)
+ {
+ if (pInstance)
+ {
+ Creature* pBronjham = Unit::GetCreature(*me, pInstance->GetData64(DATA_BRONJAHM));
+ if (pBronjham && pBronjham->isAlive())
+ {
+ if (me->IsWithinMeleeRange(pBronjham))
+ {
+ pBronjham->CastSpell(pBronjham, SPELL_CONSUME_SOUL, true);
+ me->ForcedDespawn();
+ }
+ else
+ {
+ Position pos;
+ pBronjham->GetPosition(&pos);
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MovePoint(0, pos);
+ }
+ }
+ else
+ me->ForcedDespawn();
+ }
+ uiCheckTimer = 500;
+ }
+ else
+ uiCheckTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_corrupted_soul_fragment(Creature* pCreature)
+{
+ return new mob_corrupted_soul_fragmentAI(pCreature);
+}
+
+void AddSC_boss_bronjahm()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_bronjahm";
+ newscript->GetAI = &GetAI_boss_bronjahm;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_corrupted_soul_fragment";
+ newscript->GetAI = &GetAI_mob_corrupted_soul_fragment;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp b/src/server/scripts/northrend/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp
new file mode 100644
index 00000000000..6811ba953e2
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp
@@ -0,0 +1,349 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "forge_of_souls.h"
+
+/*
+ * TODO:
+ * - Fix model id during unleash soul -> seems DB issue 36503 is missing (likewise 36504 is also missing).
+ * - Fix outro npc movement
+ */
+
+#define PI 3.1415f
+
+enum Yells
+{
+ SAY_FACE_ANGER_AGGRO = -1632010,
+ SAY_FACE_DESIRE_AGGRO = -1632011,
+ SAY_FACE_ANGER_SLAY_1 = -1632012,
+ SAY_FACE_SORROW_SLAY_1 = -1632013,
+ SAY_FACE_DESIRE_SLAY_1 = -1632014,
+ SAY_FACE_ANGER_SLAY_2 = -1632015,
+ SAY_FACE_SORROW_SLAY_2 = -1632016,
+ SAY_FACE_DESIRE_SLAY_2 = -1632017,
+ SAY_FACE_SORROW_DEATH = -1632019,
+ SAY_FACE_DESIRE_DEATH = -1632020,
+ EMOTE_MIRRORED_SOUL = -1632021,
+ EMOTE_UNLEASH_SOUL = -1632022,
+ SAY_FACE_ANGER_UNLEASH_SOUL = -1632023,
+ SAY_FACE_SORROW_UNLEASH_SOUL = -1632024,
+ SAY_FACE_DESIRE_UNLEASH_SOUL = -1632025,
+ EMOTE_WAILING_SOUL = -1632026,
+ SAY_FACE_ANGER_WAILING_SOUL = -1632027,
+ SAY_FACE_DESIRE_WAILING_SOUL = -1632028,
+
+ SAY_JAINA_OUTRO = -1632029,
+ SAY_SYLVANAS_OUTRO = -1632030,
+};
+
+enum Spells
+{
+ SPELL_PHANTOM_BLAST = 68982,
+ H_SPELL_PHANTOM_BLAST = 70322,
+ SPELL_MIRRORED_SOUL = 69051,
+ SPELL_WELL_OF_SOULS = 68820,
+ SPELL_WELL_OF_SOULS_VIS = 68854,
+ SPELL_UNLEASHED_SOULS = 68939,
+ SPELL_WAILING_SOULS_STARTING = 68912, // Initial spell cast at begining of wailing souls phase
+ SPELL_WAILING_SOULS_BEAM = 68875, // the beam visual
+ SPELL_WAILING_SOULS = 68873, // the actual spell
+ H_SPELL_WAILING_SOULS = 70324,
+// 68871,68873,68875,68876,68899,68912,70324,
+// 68899 trigger 68871
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_PHANTOM_BLAST,
+ EVENT_MIRRORED_SOUL,
+ EVENT_WELL_OF_SOULS,
+ EVENT_UNLEASHED_SOULS,
+ EVENT_WAILING_SOULS,
+ EVENT_WAILING_SOULS_TICK,
+ EVENT_FACE_ANGER,
+};
+
+enum eEnum
+{
+ ACHIEV_THREE_FACED = 4523,
+ DISPLAY_ANGER = 30148,
+ DISPLAY_SORROW = 30149,
+ DISPLAY_DESIRE = 30150,
+};
+
+struct
+{
+ uint32 entry[2];
+ Position movePosition;
+} outroPositions[] =
+{
+ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5590.47, 2427.79, 705.935, 0.802851 } },
+ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5593.59, 2428.34, 705.935, 0.977384 } },
+ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5600.81, 2429.31, 705.935, 0.890118 } },
+ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5600.81, 2421.12, 705.935, 0.890118 } },
+ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5601.43, 2426.53, 705.935, 0.890118 } },
+ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5601.55, 2418.36, 705.935, 1.15192 } },
+ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5598, 2429.14, 705.935, 1.0472 } },
+ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5594.04, 2424.87, 705.935, 1.15192 } },
+ { NPC_CHAMPION_1_ALLIANCE, NPC_CHAMPION_1_HORDE, { 5597.89, 2421.54, 705.935, 0.610865 } },
+ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE, { 5598.57, 2434.62, 705.935, 1.13446 } },
+ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE, { 5585.46, 2417.99, 705.935, 1.06465 } },
+ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE, { 5605.81, 2428.42, 705.935, 0.820305 } },
+ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE, { 5591.61, 2412.66, 705.935, 0.925025 } },
+ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE, { 5593.9, 2410.64, 705.935, 0.872665 } },
+ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_2_HORDE, { 5586.76, 2416.73, 705.935, 0.942478 } },
+ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE, { 5592.23, 2419.14, 705.935, 0.855211 } },
+ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE, { 5594.61, 2416.87, 705.935, 0.907571 } },
+ { NPC_CHAMPION_2_ALLIANCE, NPC_CHAMPION_3_HORDE, { 5589.77, 2421.03, 705.935, 0.855211 } },
+
+ { NPC_KORELN, NPC_LORALEN, { 5602.58, 2435.95, 705.935, 0.959931 } },
+ { NPC_ELANDRA, NPC_KALIRA, { 5606.13, 2433.16, 705.935, 0.785398 } },
+ { NPC_JAINA_PART2, NPC_SYLVANAS_PART2, { 5606.12, 2436.6, 705.935, 0.890118 } },
+
+ { 0, 0, { 0, 0, 0, 0 } }
+};
+
+struct boss_devourer_of_soulsAI : public ScriptedAI
+{
+ boss_devourer_of_soulsAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ bool bThreeFaceAchievement;
+
+ ScriptedInstance* pInstance;
+ EventMap events;
+
+ // wailing soul event
+ float beamAngle;
+ float beamAngleDiff;
+ int8 wailingSoulTick;
+
+ uint64 uiMirroredSoulTarget;
+
+ void Reset()
+ {
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ me->SetDisplayId(DISPLAY_ANGER);
+ me->SetReactState(REACT_AGGRESSIVE);
+
+ events.Reset();
+
+ bThreeFaceAchievement = true;
+ uiMirroredSoulTarget = 0;
+
+ if (pInstance)
+ pInstance->SetData(DATA_DEVOURER_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_DEVOURER_EVENT, IN_PROGRESS);
+
+ DoScriptText(RAND(SAY_FACE_ANGER_AGGRO,SAY_FACE_DESIRE_AGGRO), me);
+
+ events.ScheduleEvent(EVENT_PHANTOM_BLAST, 5000);
+ events.ScheduleEvent(EVENT_MIRRORED_SOUL, 8000);
+ events.ScheduleEvent(EVENT_WELL_OF_SOULS, 30000);
+ events.ScheduleEvent(EVENT_UNLEASHED_SOULS, 20000);
+ events.ScheduleEvent(EVENT_WAILING_SOULS, urand(60000,70000));
+ }
+
+ void DamageTaken(Unit * /*pDoneBy*/, uint32 &uiDamage)
+ {
+ if (uiMirroredSoulTarget && me->HasAura(SPELL_MIRRORED_SOUL))
+ {
+ if (Player *pPlayer = Unit::GetPlayer(uiMirroredSoulTarget))
+ {
+ if (Aura *pAura = pPlayer->GetAura(SPELL_MIRRORED_SOUL))
+ {
+ int32 mirrorDamage = (uiDamage * 45)/100;
+ me->CastCustomSpell(pPlayer, 69034, &mirrorDamage, 0, 0, true);
+// me->DealDamage(pPlayer, (uiDamage * 45)/100, 0, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_SHADOW);
+ }
+ else
+ uiMirroredSoulTarget = 0;
+ }
+ }
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(RAND(SAY_FACE_ANGER_SLAY_1,SAY_FACE_SORROW_SLAY_1,SAY_FACE_DESIRE_SLAY_1,
+ SAY_FACE_ANGER_SLAY_2,SAY_FACE_SORROW_SLAY_2,SAY_FACE_DESIRE_SLAY_2), me);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ Position spawnPoint = { 5618.139, 2451.873, 705.854 };
+
+ DoScriptText(RAND(SAY_FACE_SORROW_DEATH,SAY_FACE_DESIRE_DEATH), me);
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_DEVOURER_EVENT, DONE);
+
+ if (bThreeFaceAchievement && IsHeroic())
+ pInstance->DoCompleteAchievement(ACHIEV_THREE_FACED);
+
+ int32 entryIndex;
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
+ entryIndex = 0;
+ else
+ entryIndex = 1;
+
+ for (int8 i = 0; outroPositions[i].entry[entryIndex] != 0; ++i)
+ {
+ if (Creature *pSummon = me->SummonCreature(outroPositions[i].entry[entryIndex], spawnPoint, TEMPSUMMON_DEAD_DESPAWN))
+ {
+ pSummon->GetMotionMaster()->MovePoint(0, outroPositions[i].movePosition);
+
+ if (pSummon->GetEntry() == NPC_JAINA_PART2)
+ DoScriptText(SAY_JAINA_OUTRO, pSummon);
+ else if (pSummon->GetEntry() == NPC_SYLVANAS_PART2)
+ DoScriptText(SAY_SYLVANAS_OUTRO, pSummon);
+ }
+ }
+ }
+ }
+
+ void SpellHitTarget(Unit* /*pTarget*/, const SpellEntry *pSpell)
+ {
+ if (pSpell->Id == H_SPELL_PHANTOM_BLAST)
+ bThreeFaceAchievement = false;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ // Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_PHANTOM_BLAST:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_TOPAGGRO, 0))
+ DoCast(pTarget, SPELL_PHANTOM_BLAST);
+ events.ScheduleEvent(EVENT_PHANTOM_BLAST, 5000);
+ break;
+ case EVENT_MIRRORED_SOUL:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true))
+ {
+ uiMirroredSoulTarget = pTarget->GetGUID();
+ DoCast(pTarget, SPELL_MIRRORED_SOUL);
+ DoScriptText(EMOTE_MIRRORED_SOUL, me);
+ }
+ events.ScheduleEvent(EVENT_MIRRORED_SOUL, urand(15000,30000));
+ break;
+ case EVENT_WELL_OF_SOULS:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_WELL_OF_SOULS);
+ events.ScheduleEvent(EVENT_WELL_OF_SOULS, 20000);
+ break;
+ case EVENT_UNLEASHED_SOULS:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_UNLEASHED_SOULS);
+ me->SetDisplayId(DISPLAY_SORROW);
+ DoScriptText(RAND(SAY_FACE_ANGER_UNLEASH_SOUL,SAY_FACE_SORROW_UNLEASH_SOUL,SAY_FACE_DESIRE_UNLEASH_SOUL), me);
+ DoScriptText(EMOTE_UNLEASH_SOUL, me);
+ events.ScheduleEvent(EVENT_UNLEASHED_SOULS, 30000);
+ events.ScheduleEvent(EVENT_FACE_ANGER, 5000);
+ break;
+ case EVENT_FACE_ANGER:
+ me->SetDisplayId(DISPLAY_ANGER);
+ break;
+
+ case EVENT_WAILING_SOULS:
+ me->SetDisplayId(DISPLAY_DESIRE);
+ DoScriptText(RAND(SAY_FACE_ANGER_WAILING_SOUL,SAY_FACE_DESIRE_WAILING_SOUL), me);
+ DoScriptText(EMOTE_WAILING_SOUL, me);
+ DoCast(me, SPELL_WAILING_SOULS_STARTING);
+
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ me->SetOrientation(me->GetAngle(pTarget));
+ DoCast(me, SPELL_WAILING_SOULS_BEAM);
+ }
+
+ beamAngle = me->GetOrientation();
+
+ beamAngleDiff = PI/30.0f; // PI/2 in 15 sec = PI/30 per tick
+ if (RAND(true,false))
+ beamAngleDiff = -beamAngleDiff;
+
+ me->InterruptNonMeleeSpells(false);
+ me->SetReactState(REACT_PASSIVE);
+
+ //Remove any target
+ me->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+
+ me->GetMotionMaster()->Clear();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+
+ wailingSoulTick = 15;
+ events.DelayEvents(18000); // no other events during wailing souls
+ events.ScheduleEvent(EVENT_WAILING_SOULS_TICK, 3000); // first one after 3 secs.
+ break;
+
+ case EVENT_WAILING_SOULS_TICK:
+ beamAngle += beamAngleDiff;
+ me->SetOrientation(beamAngle);
+ me->StopMoving();
+
+ DoCast(me, SPELL_WAILING_SOULS);
+
+ if (--wailingSoulTick)
+ events.ScheduleEvent(EVENT_WAILING_SOULS_TICK, 1000);
+ else
+ {
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->SetDisplayId(DISPLAY_ANGER);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+ events.ScheduleEvent(EVENT_WAILING_SOULS, urand(60000,70000));
+ }
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_devourer_of_souls(Creature* pCreature)
+{
+ return new boss_devourer_of_soulsAI(pCreature);
+}
+
+void AddSC_boss_devourer_of_souls()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="boss_devourer_of_souls";
+ newscript->GetAI = &GetAI_boss_devourer_of_souls;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.cpp b/src/server/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.cpp
new file mode 100644
index 00000000000..5c85da69898
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.cpp
@@ -0,0 +1,899 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "forge_of_souls.h"
+
+enum Spells
+{
+ //Spiteful Apparition
+ SPELL_SPITE = 68895,
+ H_SPELL_SPITE = 70212,
+
+ //Spectral Warden
+ SPELL_VEIL_OF_SHADOWS = 69633,
+ SPELL_WAIL_OF_SOULS = 69148,
+ H_SPELL_WAIL_OF_SOULS = 70210,
+
+ //Soulguard Watchman
+ SPELL_SHROUD_OF_RUNES = 69056,
+ SPELL_UNHOLY_RAGE = 69053,
+
+ //Soulguard Reaper
+ SPELL_FROST_NOVA = 69060,
+ H_SPELL_FROST_NOVA = 70209,
+ SPELL_SHADOW_LANCE = 69058,
+
+ //Soulguard Bonecaster
+ SPELL_BONE_VOLLEY = 69080,
+ H_SPELL_BONE_VOLLEY = 70206,
+ SPELL_RAISE_DEAD = 69562,
+ SPELL_SHIELD_OF_BONES = 69069,
+ H_SPELL_SHIELD_OF_BONES = 70207,
+
+ //Soulguard Animator
+ // Raise dead 69562
+ SPELL_SHADOW_BOLT = 69068,
+ H_SPELL_SHADOW_BOLT = 70208,
+ SPELL_SOUL_SICKNESS = 69131,
+ SPELL_SOUL_SIPHON = 69128,
+
+ //Soulguard Adept
+ //Raise dead 69562
+ //Shadow Bolt 69068/70208
+ SPELL_DRAIN_LIFE = 69066,
+ H_SPELL_DRAIN_LIFE = 70213,
+ SPELL_SHADOW_MEND = 69564,
+ H_SPELL_SHADOW_MEND = 70205,
+
+ //Soul Horror
+ SPELL_SOUL_STRIKE = 69088,
+ H_SPELL_SOUL_STRIKE = 70211,
+};
+
+enum Events
+{
+ EVENT_NONE,
+
+ // Jaina/Sylvanas Intro
+ EVENT_INTRO_1,
+ EVENT_INTRO_2,
+ EVENT_INTRO_3,
+ EVENT_INTRO_4,
+ EVENT_INTRO_5,
+ EVENT_INTRO_6,
+ EVENT_INTRO_7,
+ EVENT_INTRO_8,
+
+ //Spiteful Apparition
+ EVENT_SPITE,
+
+ //Spectral Warden
+ EVENT_VEIL_OF_SHADOWS,
+ EVENT_WAIL_OF_SOULS,
+
+ //Soulguard Watchman
+ EVENT_SHROUD_OF_RUNES,
+ EVENT_UNHOLY_RAGE,
+
+ //Soulguard Reaper
+ EVENT_FROST_NOVA,
+ EVENT_SHADOW_LANCE,
+
+ //Soulguard Bonecaster
+ EVENT_BONE_VOLLEY,
+ EVENT_RAISE_DEAD,
+ EVENT_SHIELD_OF_BONES,
+
+ //Soulguard Animator
+ EVENT_SHADOW_BOLT,
+ EVENT_SOUL_SICKNESS,
+ EVENT_SOUL_SIPHON,
+
+ //Soulguard Adept
+ EVENT_DRAIN_LIFE,
+ EVENT_SHADOW_MEND,
+
+ //Soul Horror
+ EVENT_SOUL_STRIKE,
+};
+
+/****************************************SYLVANAS************************************/
+#define GOSSIP_SYLVANAS_ITEM "What would you have of me, Banshee Queen?"
+#define GOSSIP_JAINA_ITEM "What would you have of me, my lady?"
+
+enum Yells
+{
+ SAY_JAINA_INTRO_1 = -1632040,
+ SAY_JAINA_INTRO_2 = -1632041,
+ SAY_JAINA_INTRO_3 = -1632042,
+ SAY_JAINA_INTRO_4 = -1632043,
+ SAY_JAINA_INTRO_5 = -1632044,
+ SAY_JAINA_INTRO_6 = -1632045,
+ SAY_JAINA_INTRO_7 = -1632046,
+ SAY_JAINA_INTRO_8 = -1632047,
+
+ SAY_SYLVANAS_INTRO_1 = -1632050,
+ SAY_SYLVANAS_INTRO_2 = -1632051,
+ SAY_SYLVANAS_INTRO_3 = -1632052,
+ SAY_SYLVANAS_INTRO_4 = -1632053,
+ SAY_SYLVANAS_INTRO_5 = -1632054,
+ SAY_SYLVANAS_INTRO_6 = -1632055,
+};
+
+enum eSylvanas
+{
+ GOSSIP_SPEECHINTRO = 13525,
+ ACTION_INTRO,
+};
+
+enum Phase
+{
+ PHASE_NORMAL,
+ PHASE_INTRO,
+};
+
+struct npc_sylvanas_fosAI: public ScriptedAI
+{
+ npc_sylvanas_fosAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = me->GetInstanceData();
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ }
+
+ ScriptedInstance* pInstance;
+
+ EventMap events;
+ Phase phase;
+
+ void Reset()
+ {
+ events.Reset();
+ phase = PHASE_NORMAL;
+ }
+
+ void DoAction(const int32 actionId)
+ {
+ switch(actionId)
+ {
+ case ACTION_INTRO:
+ {
+ phase = PHASE_INTRO;
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ events.Reset();
+ events.ScheduleEvent(EVENT_INTRO_1, 1000);
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (phase == PHASE_INTRO)
+ {
+ if (!pInstance)
+ return;
+
+ events.Update(diff);
+ switch(events.ExecuteEvent())
+ {
+ case EVENT_INTRO_1:
+ DoScriptText(SAY_SYLVANAS_INTRO_1, me);
+ events.ScheduleEvent(EVENT_INTRO_2, 11500);
+ break;
+
+ case EVENT_INTRO_2:
+ DoScriptText(SAY_SYLVANAS_INTRO_2, me);
+ events.ScheduleEvent(EVENT_INTRO_3, 10500);
+ break;
+
+ case EVENT_INTRO_3:
+ DoScriptText(SAY_SYLVANAS_INTRO_3, me);
+ events.ScheduleEvent(EVENT_INTRO_4, 9500);
+ break;
+
+ case EVENT_INTRO_4:
+ DoScriptText(SAY_SYLVANAS_INTRO_4, me);
+ events.ScheduleEvent(EVENT_INTRO_5, 10500);
+ break;
+
+ case EVENT_INTRO_5:
+ DoScriptText(SAY_SYLVANAS_INTRO_5, me);
+ events.ScheduleEvent(EVENT_INTRO_6, 9500);
+ break;
+
+ case EVENT_INTRO_6:
+ DoScriptText(SAY_SYLVANAS_INTRO_6, me);
+ // End of Intro
+ phase = PHASE_NORMAL;
+ break;
+ }
+ }
+
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ //if (me->hasUnitState(UNIT_STAT_CASTING))
+ // return;
+
+ //while (uint32 eventId = events.ExecuteEvent())
+ //{
+ // switch(eventId)
+ // {
+ // }
+ //}
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct npc_jaina_fosAI: public ScriptedAI
+{
+ npc_jaina_fosAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = me->GetInstanceData();
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ }
+
+ ScriptedInstance* pInstance;
+
+ EventMap events;
+ Phase phase;
+
+ void Reset()
+ {
+ events.Reset();
+ phase = PHASE_NORMAL;
+ }
+
+ void DoAction(const int32 actionId)
+ {
+ switch(actionId)
+ {
+ case ACTION_INTRO:
+ {
+ phase = PHASE_INTRO;
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ events.Reset();
+ events.ScheduleEvent(EVENT_INTRO_1, 1000);
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (phase == PHASE_INTRO)
+ {
+ if (!pInstance)
+ return;
+
+ events.Update(diff);
+ switch(events.ExecuteEvent())
+ {
+ case EVENT_INTRO_1:
+ DoScriptText(SAY_JAINA_INTRO_1, me);
+ events.ScheduleEvent(EVENT_INTRO_2, 8000);
+ break;
+
+ case EVENT_INTRO_2:
+ DoScriptText(SAY_JAINA_INTRO_2, me);
+ events.ScheduleEvent(EVENT_INTRO_3, 8500);
+ break;
+
+ case EVENT_INTRO_3:
+ DoScriptText(SAY_JAINA_INTRO_3, me);
+ events.ScheduleEvent(EVENT_INTRO_4, 8000);
+ break;
+
+ case EVENT_INTRO_4:
+ DoScriptText(SAY_JAINA_INTRO_4, me);
+ events.ScheduleEvent(EVENT_INTRO_5, 10000);
+ break;
+
+ case EVENT_INTRO_5:
+ DoScriptText(SAY_JAINA_INTRO_5, me);
+ events.ScheduleEvent(EVENT_INTRO_6, 8000);
+ break;
+
+ case EVENT_INTRO_6:
+ DoScriptText(SAY_JAINA_INTRO_6, me);
+ events.ScheduleEvent(EVENT_INTRO_7, 12000);
+ break;
+
+ case EVENT_INTRO_7:
+ DoScriptText(SAY_JAINA_INTRO_7, me);
+ events.ScheduleEvent(EVENT_INTRO_8, 8000);
+ break;
+
+ case EVENT_INTRO_8:
+ DoScriptText(SAY_JAINA_INTRO_8, me);
+ // End of Intro
+ phase = PHASE_NORMAL;
+ break;
+ }
+ }
+
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ //if (me->hasUnitState(UNIT_STAT_CASTING))
+ // return;
+
+ //while (uint32 eventId = events.ExecuteEvent())
+ //{
+ // switch(eventId)
+ // {
+ // }
+ //}
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+bool GossipHello_npc_jaina_or_slyvanas_fos(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pCreature->GetEntry() == NPC_JAINA_PART1)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_JAINA_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ else
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SYLVANAS_ITEM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_jaina_or_slyvanas_fos(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->CLOSE_GOSSIP_MENU();
+
+ if (pCreature->AI())
+ pCreature->AI()->DoAction(ACTION_INTRO);
+ break;
+ }
+
+ return true;
+}
+
+struct mob_spiteful_apparitionAI: public ScriptedAI
+{
+ mob_spiteful_apparitionAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SPITE, 8000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SPITE:
+ DoCast(me->getVictim(), SPELL_SPITE);
+ events.RescheduleEvent(EVENT_SPITE, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_spectral_wardenAI: public ScriptedAI
+{
+ mob_spectral_wardenAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_VEIL_OF_SHADOWS, 5000);
+ events.ScheduleEvent(EVENT_WAIL_OF_SOULS, 10000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_VEIL_OF_SHADOWS:
+ DoCast(me->getVictim(), SPELL_VEIL_OF_SHADOWS);
+ events.RescheduleEvent(EVENT_VEIL_OF_SHADOWS, 10000);
+ return;
+ case EVENT_WAIL_OF_SOULS:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_WAIL_OF_SOULS);
+ events.RescheduleEvent(EVENT_WAIL_OF_SOULS, 5000);
+ return;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_soulguard_watchmanAI: public ScriptedAI
+{
+ mob_soulguard_watchmanAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SHROUD_OF_RUNES, 1000);
+ events.ScheduleEvent(EVENT_UNHOLY_RAGE, 1000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SHROUD_OF_RUNES:
+ DoCast(me, SPELL_SHROUD_OF_RUNES);
+ events.RescheduleEvent(EVENT_SHROUD_OF_RUNES, 5000);
+ return;
+ case EVENT_UNHOLY_RAGE:
+ DoCast(me, SPELL_UNHOLY_RAGE);
+ events.RescheduleEvent(EVENT_UNHOLY_RAGE, 99999);
+ return;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_soulguard_reaperAI: public ScriptedAI
+{
+ mob_soulguard_reaperAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_FROST_NOVA, 8000);
+ events.ScheduleEvent(EVENT_SHADOW_LANCE, 5000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_FROST_NOVA:
+ DoCast(me, SPELL_FROST_NOVA);
+ events.RescheduleEvent(EVENT_FROST_NOVA, 9600);
+ return;
+ case EVENT_SHADOW_LANCE:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SHADOW_LANCE);
+ events.RescheduleEvent(EVENT_SHADOW_LANCE, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_soulguard_bonecasterAI: public ScriptedAI
+{
+ mob_soulguard_bonecasterAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_BONE_VOLLEY, 6000);
+ events.ScheduleEvent(EVENT_RAISE_DEAD, 25000);
+ events.ScheduleEvent(EVENT_SHIELD_OF_BONES, 6000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_BONE_VOLLEY:
+ DoCastAOE(SPELL_BONE_VOLLEY);
+ events.RescheduleEvent(EVENT_BONE_VOLLEY, 7000);
+ return;
+ case EVENT_RAISE_DEAD:
+ DoCast(me, SPELL_RAISE_DEAD);
+ events.RescheduleEvent(EVENT_RAISE_DEAD, 25000);
+ return;
+ case EVENT_SHIELD_OF_BONES:
+ DoCast(me, SPELL_SHIELD_OF_BONES);
+ events.RescheduleEvent(EVENT_SHIELD_OF_BONES, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_soulguard_animatorAI: public ScriptedAI
+{
+ mob_soulguard_animatorAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_RAISE_DEAD, 25000);
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, 5000);
+ events.ScheduleEvent(EVENT_SOUL_SICKNESS, 8000);
+ events.ScheduleEvent(EVENT_SOUL_SIPHON, 10000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_RAISE_DEAD:
+ DoCast(me, SPELL_RAISE_DEAD);
+ events.RescheduleEvent(EVENT_RAISE_DEAD, 25000);
+ return;
+ case EVENT_SHADOW_BOLT:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SHADOW_BOLT);
+ events.RescheduleEvent(EVENT_SHADOW_BOLT, 5000);
+ return;
+ case EVENT_SOUL_SICKNESS:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SOUL_SICKNESS);
+ events.RescheduleEvent(EVENT_SOUL_SICKNESS, 10000);
+ return;
+ case EVENT_SOUL_SIPHON:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SOUL_SIPHON);
+ events.RescheduleEvent(EVENT_SOUL_SIPHON, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_soulguard_adeptAI: public ScriptedAI
+{
+ mob_soulguard_adeptAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_RAISE_DEAD, 25000);
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, 8000);
+ events.ScheduleEvent(EVENT_DRAIN_LIFE, 7000);
+ events.ScheduleEvent(EVENT_SHADOW_MEND, 35000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_RAISE_DEAD:
+ DoCast(me, SPELL_RAISE_DEAD);
+ events.RescheduleEvent(EVENT_RAISE_DEAD, 25000);
+ return;
+ case EVENT_SHADOW_BOLT:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SHADOW_BOLT);
+ events.RescheduleEvent(EVENT_SHADOW_BOLT, 4000);
+ return;
+ case EVENT_DRAIN_LIFE:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_DRAIN_LIFE);
+ events.RescheduleEvent(EVENT_DRAIN_LIFE, 9000);
+ return;
+ case EVENT_SHADOW_MEND:
+ DoCast(me, SPELL_SHADOW_MEND);
+ events.RescheduleEvent(EVENT_SHADOW_MEND, 20000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_soul_horrorAI: public ScriptedAI
+{
+ mob_soul_horrorAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SOUL_STRIKE, 6000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SOUL_STRIKE:
+ DoCast(me->getVictim(), SPELL_SOUL_STRIKE);
+ events.RescheduleEvent(EVENT_SOUL_STRIKE, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_jaina_fosAI(Creature* pCreature)
+{
+ return new npc_jaina_fosAI(pCreature);
+};
+
+CreatureAI* GetAI_npc_sylvanas_fosAI(Creature* pCreature)
+{
+ return new npc_sylvanas_fosAI(pCreature);
+};
+
+CreatureAI* GetAI_mob_spiteful_apparitionAI(Creature* pCreature)
+{
+ return new mob_spiteful_apparitionAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_spectral_wardenAI(Creature* pCreature)
+{
+ return new mob_spectral_wardenAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_soulguard_watchmanAI(Creature* pCreature)
+{
+ return new mob_soulguard_watchmanAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_soulguard_reaperAI(Creature* pCreature)
+{
+ return new mob_soulguard_reaperAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_soulguard_bonecasterAI(Creature* pCreature)
+{
+ return new mob_soulguard_bonecasterAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_soulguard_animatorAI(Creature* pCreature)
+{
+ return new mob_soulguard_animatorAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_soulguard_adeptAI(Creature* pCreature)
+{
+ return new mob_soulguard_adeptAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_soul_horrorAI(Creature* pCreature)
+{
+ return new mob_soul_horrorAI(pCreature);
+}
+
+void AddSC_forge_of_souls()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_sylvanas_fos";
+ newscript->GetAI = &GetAI_npc_sylvanas_fosAI;
+ newscript->pGossipHello = &GossipHello_npc_jaina_or_slyvanas_fos;
+ newscript->pGossipSelect = &GossipSelect_npc_jaina_or_slyvanas_fos;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_jaina_fos";
+ newscript->GetAI = &GetAI_npc_jaina_fosAI;
+ newscript->pGossipHello = &GossipHello_npc_jaina_or_slyvanas_fos;
+ newscript->pGossipSelect = &GossipSelect_npc_jaina_or_slyvanas_fos;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_spiteful_apparition";
+ newscript->GetAI = &GetAI_mob_spiteful_apparitionAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_spectral_warden";
+ newscript->GetAI = &GetAI_mob_spectral_wardenAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_soulguard_watchman";
+ newscript->GetAI = &GetAI_mob_soulguard_watchmanAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_soulguard_reaper";
+ newscript->GetAI = &GetAI_mob_soulguard_reaperAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_soulguard_bonecaster";
+ newscript->GetAI = &GetAI_mob_soulguard_bonecasterAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_soulguard_animator";
+ newscript->GetAI = &GetAI_mob_soulguard_animatorAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_soulguard_adept";
+ newscript->GetAI = &GetAI_mob_soulguard_adeptAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_soul_horror";
+ newscript->GetAI = &GetAI_mob_soul_horrorAI;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.h b/src/server/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.h
new file mode 100644
index 00000000000..e0479eb4d2b
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/forge_of_souls/forge_of_souls.h
@@ -0,0 +1,52 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DEF_FORGE_OF_SOULS_H
+#define DEF_FORGE_OF_SOULS_H
+
+enum Data
+{
+ DATA_BRONJAHM_EVENT,
+ DATA_DEVOURER_EVENT,
+ DATA_TEAM_IN_INSTANCE,
+};
+
+enum Data64
+{
+ DATA_BRONJAHM,
+ DATA_DEVOURER,
+};
+
+enum Creatures
+{
+ CREATURE_BRONJAHM = 36497,
+ CREATURE_DEVOURER = 36502,
+
+ NPC_SYLVANAS_PART1 = 37596,
+ NPC_SYLVANAS_PART2 = 38161,
+ NPC_JAINA_PART1 = 37597,
+ NPC_JAINA_PART2 = 38160,
+ NPC_KALIRA = 37583,
+ NPC_ELANDRA = 37774,
+ NPC_LORALEN = 37779,
+ NPC_KORELN = 37582,
+ NPC_CHAMPION_1_HORDE = 37584,
+ NPC_CHAMPION_2_HORDE = 37587,
+ NPC_CHAMPION_3_HORDE = 37588,
+ NPC_CHAMPION_1_ALLIANCE = 37496,
+ NPC_CHAMPION_2_ALLIANCE = 37497,
+};
+#endif
diff --git a/src/server/scripts/northrend/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp b/src/server/scripts/northrend/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp
new file mode 100644
index 00000000000..67a6cdb4579
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/forge_of_souls/instance_forge_of_souls.cpp
@@ -0,0 +1,168 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "forge_of_souls.h"
+
+#define MAX_ENCOUNTER 2
+
+/* Forge of Souls encounters:
+0- Bronjahm, The Godfather of Souls
+1- The Devourer of Souls
+*/
+
+struct instance_forge_of_souls : public ScriptedInstance
+{
+ instance_forge_of_souls(Map* pMap) : ScriptedInstance(pMap) {};
+
+ uint64 uiBronjahm;
+ uint64 uiDevourer;
+
+ uint32 uiEncounter[MAX_ENCOUNTER];
+ uint32 uiTeamInInstance;
+
+ void Initialize()
+ {
+ uiBronjahm = 0;
+ uiDevourer = 0;
+
+ uiTeamInInstance = 0;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ uiEncounter[i] = NOT_STARTED;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (uiEncounter[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool /*add*/)
+ {
+ Map::PlayerList const &players = instance->GetPlayers();
+
+ if (!players.isEmpty())
+ if (Player* pPlayer = players.begin()->getSource())
+ uiTeamInInstance = pPlayer->GetTeam();
+
+ switch(pCreature->GetEntry())
+ {
+ case CREATURE_BRONJAHM:
+ uiBronjahm = pCreature->GetGUID();
+ break;
+ case CREATURE_DEVOURER:
+ uiDevourer = pCreature->GetGUID();
+ break;
+ }
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_BRONJAHM_EVENT:
+ uiEncounter[0] = data;
+ break;
+ case DATA_DEVOURER_EVENT:
+ uiEncounter[1] = data;
+ break;
+ }
+
+ if (data == DONE)
+ SaveToDB();
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_BRONJAHM_EVENT: return uiEncounter[0];
+ case DATA_DEVOURER_EVENT: return uiEncounter[1];
+ case DATA_TEAM_IN_INSTANCE: return uiTeamInInstance;
+ }
+
+ return 0;
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_BRONJAHM: return uiBronjahm;
+ case DATA_DEVOURER: return uiBronjahm;
+ }
+
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "F S " << uiEncounter[0] << " " << uiEncounter[1];
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return saveStream.str();
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0, data1;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1;
+
+ if (dataHead1 == 'F' && dataHead2 == 'S')
+ {
+ uiEncounter[0] = data0;
+ uiEncounter[1] = data1;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (uiEncounter[i] == IN_PROGRESS)
+ uiEncounter[i] = NOT_STARTED;
+
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_forge_of_souls(Map* pMap)
+{
+ return new instance_forge_of_souls(pMap);
+}
+
+void AddSC_instance_forge_of_souls()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_forge_of_souls";
+ newscript->GetInstanceData = &GetInstanceData_instance_forge_of_souls;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/frozen_halls/halls_of_reflection/boss_falric.cpp b/src/server/scripts/northrend/frozen_halls/halls_of_reflection/boss_falric.cpp
new file mode 100644
index 00000000000..c9978faca6e
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/halls_of_reflection/boss_falric.cpp
@@ -0,0 +1,142 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "halls_of_reflection.h"
+
+enum Yells
+{
+ SAY_AGGRO = -1668050,
+ SAY_SLAY_1 = -1668051,
+ SAY_SLAY_2 = -1668052,
+ SAY_DEATH = -1668053,
+ SAY_IMPENDING_DESPAIR = -1668054,
+ SAY_DEFILING_HORROR = -1668055,
+};
+
+enum Spells
+{
+ SPELL_QUIVERING_STRIKE = 72422,
+ SPELL_IMPENDING_DESPAIR = 72426,
+ SPELL_DEFILING_HORROR = 72435,
+ SPELL_HOPELESSNESS = 72395,
+ H_SPELL_HOPELESSNESS = 72390, // TODO: not in dbc. Add in DB.
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_QUIVERING_STRIKE,
+ EVENT_IMPENDING_DESPAIR,
+ EVENT_DEFILING_HORROR,
+};
+
+struct boss_falricAI : public boss_horAI
+{
+ boss_falricAI(Creature *pCreature) : boss_horAI(pCreature) {}
+
+ uint8 uiHopelessnessCount;
+
+ void Reset()
+ {
+ boss_horAI::Reset();
+
+ uiHopelessnessCount = 0;
+
+ if (pInstance)
+ pInstance->SetData(DATA_FALRIC_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ if (pInstance)
+ pInstance->SetData(DATA_FALRIC_EVENT, IN_PROGRESS);
+
+ events.ScheduleEvent(EVENT_QUIVERING_STRIKE, 23000);
+ events.ScheduleEvent(EVENT_IMPENDING_DESPAIR, 9000);
+ events.ScheduleEvent(EVENT_DEFILING_HORROR, urand(25000,45000)); // TODO adjust timer.
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_FALRIC_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ // Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ switch (events.ExecuteEvent())
+ {
+ case EVENT_QUIVERING_STRIKE:
+ DoCast(SPELL_QUIVERING_STRIKE);
+ events.ScheduleEvent(EVENT_QUIVERING_STRIKE, 10000);
+ break;
+ case EVENT_IMPENDING_DESPAIR:
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ {
+ DoScriptText(SAY_IMPENDING_DESPAIR, me);
+ DoCast(pTarget, SPELL_IMPENDING_DESPAIR);
+ }
+ events.ScheduleEvent(EVENT_IMPENDING_DESPAIR, 13000);
+ break;
+ case EVENT_DEFILING_HORROR:
+ DoCast(SPELL_DEFILING_HORROR);
+ events.ScheduleEvent(EVENT_DEFILING_HORROR, urand(25000,45000)); // TODO adjust timer.
+ break;
+ }
+
+ if ((uiHopelessnessCount < 1 && HealthBelowPct(66))
+ || (uiHopelessnessCount < 2 && HealthBelowPct(33))
+ || (uiHopelessnessCount < 3 && HealthBelowPct(10)))
+ {
+ uiHopelessnessCount++;
+ DoCast(DUNGEON_MODE(SPELL_HOPELESSNESS,H_SPELL_HOPELESSNESS));
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_falric(Creature* pCreature)
+{
+ return new boss_falricAI(pCreature);
+}
+
+void AddSC_boss_falric()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="boss_falric";
+ newscript->GetAI = &GetAI_boss_falric;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp b/src/server/scripts/northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp
new file mode 100644
index 00000000000..95fb2737ce9
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp
@@ -0,0 +1,133 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "halls_of_reflection.h"
+
+enum Yells
+{
+ SAY_AGGRO = -1668060,
+ SAY_SLAY_1 = -1668061,
+ SAY_SLAY_2 = -1668062,
+ SAY_DEATH = -1668063,
+ SAY_CORRUPTED_FLESH_1 = -1668064,
+ SAY_CORRUPTED_FLESH_2 = -1668065,
+};
+
+enum Spells
+{
+ SPELL_OBLITERATE = 72360,
+ SPELL_WELL_OF_CORRUPTION = 72362,
+ SPELL_CORRUPTED_FLESH = 72363,
+ SPELL_SHARED_SUFFERING = 72368,
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_OBLITERATE,
+ EVENT_WELL_OF_CORRUPTION,
+ EVENT_CORRUPTED_FLESH,
+ EVENT_SHARED_SUFFERING,
+};
+
+struct boss_marwynAI : public boss_horAI
+{
+ boss_marwynAI(Creature *pCreature) : boss_horAI(pCreature) {}
+
+ void Reset()
+ {
+ boss_horAI::Reset();
+
+ if (pInstance)
+ pInstance->SetData(DATA_MARWYN_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ if (pInstance)
+ pInstance->SetData(DATA_MARWYN_EVENT, IN_PROGRESS);
+
+ events.ScheduleEvent(EVENT_OBLITERATE, 30000); // TODO Check timer
+ events.ScheduleEvent(EVENT_WELL_OF_CORRUPTION, 13000);
+ events.ScheduleEvent(EVENT_CORRUPTED_FLESH, 20000);
+ events.ScheduleEvent(EVENT_SHARED_SUFFERING, 20000); // TODO Check timer
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_MARWYN_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ // Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ switch (events.ExecuteEvent())
+ {
+ case EVENT_OBLITERATE:
+ DoCast(SPELL_OBLITERATE);
+ events.ScheduleEvent(EVENT_OBLITERATE, 30000);
+ break;
+ case EVENT_WELL_OF_CORRUPTION:
+ DoCast(SPELL_WELL_OF_CORRUPTION);
+ events.ScheduleEvent(EVENT_WELL_OF_CORRUPTION, 13000);
+ break;
+ case EVENT_CORRUPTED_FLESH:
+ DoScriptText(RAND(SAY_CORRUPTED_FLESH_1,SAY_CORRUPTED_FLESH_2), me);
+ DoCast(SPELL_CORRUPTED_FLESH);
+ events.ScheduleEvent(EVENT_CORRUPTED_FLESH, 20000);
+ break;
+ case EVENT_SHARED_SUFFERING:
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_SHARED_SUFFERING);
+ events.ScheduleEvent(EVENT_SHARED_SUFFERING, 20000);
+ break;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_marwyn(Creature* pCreature)
+{
+ return new boss_marwynAI(pCreature);
+}
+
+void AddSC_boss_marwyn()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="boss_marwyn";
+ newscript->GetAI = &GetAI_boss_marwyn;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp b/src/server/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp
new file mode 100644
index 00000000000..fb3d3d5d752
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp
@@ -0,0 +1,1022 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "halls_of_reflection.h"
+
+enum Yells
+{
+ SAY_JAINA_INTRO_1 = -1668001,
+ SAY_JAINA_INTRO_2 = -1668002,
+ SAY_JAINA_INTRO_3 = -1668003,
+ SAY_JAINA_INTRO_4 = -1668004,
+ SAY_UTHER_INTRO_A2_1 = -1668005,
+ SAY_JAINA_INTRO_5 = -1668006,
+ SAY_UTHER_INTRO_A2_2 = -1668007,
+ SAY_JAINA_INTRO_6 = -1668008,
+ SAY_UTHER_INTRO_A2_3 = -1668009,
+ SAY_JAINA_INTRO_7 = -1668010,
+ SAY_UTHER_INTRO_A2_4 = -1668011,
+ SAY_JAINA_INTRO_8 = -1668012,
+ SAY_UTHER_INTRO_A2_5 = -1668013,
+ SAY_JAINA_INTRO_9 = -1668014,
+ SAY_UTHER_INTRO_A2_6 = -1668015,
+ SAY_UTHER_INTRO_A2_7 = -1668016,
+ SAY_JAINA_INTRO_10 = -1668017,
+ SAY_UTHER_INTRO_A2_8 = -1668018,
+ SAY_JAINA_INTRO_11 = -1668019,
+ SAY_UTHER_INTRO_A2_9 = -1668020,
+
+ SAY_SYLVANAS_INTRO_1 = -1668021,
+ SAY_SYLVANAS_INTRO_2 = -1668022,
+ SAY_SYLVANAS_INTRO_3 = -1668023,
+ SAY_UTHER_INTRO_H2_1 = -1668024,
+ SAY_SYLVANAS_INTRO_4 = -1668025,
+ SAY_UTHER_INTRO_H2_2 = -1668026,
+ SAY_SYLVANAS_INTRO_5 = -1668027,
+ SAY_UTHER_INTRO_H2_3 = -1668028,
+ SAY_SYLVANAS_INTRO_6 = -1668029,
+ SAY_UTHER_INTRO_H2_4 = -1668030,
+ SAY_SYLVANAS_INTRO_7 = -1668031,
+ SAY_UTHER_INTRO_H2_5 = -1668032,
+ SAY_UTHER_INTRO_H2_6 = -1668033,
+ SAY_SYLVANAS_INTRO_8 = -1668034,
+ SAY_UTHER_INTRO_H2_7 = -1668035,
+
+ SAY_LK_INTRO_1 = -1668036,
+ SAY_LK_INTRO_2 = -1668037,
+ SAY_LK_INTRO_3 = -1668038,
+ SAY_FALRIC_INTRO_1 = -1668039,
+ SAY_MARWYN_INTRO_1 = -1668040,
+ SAY_FALRIC_INTRO_2 = -1668041,
+
+ SAY_JAINA_INTRO_END = -1668042,
+ SAY_SYLVANAS_INTRO_END = -1668043,
+};
+
+enum Events
+{
+ EVENT_NONE,
+
+ EVENT_START_INTRO,
+ EVENT_SKIP_INTRO,
+
+ EVENT_INTRO_A2_1,
+ EVENT_INTRO_A2_2,
+ EVENT_INTRO_A2_3,
+ EVENT_INTRO_A2_4,
+ EVENT_INTRO_A2_5,
+ EVENT_INTRO_A2_6,
+ EVENT_INTRO_A2_7,
+ EVENT_INTRO_A2_8,
+ EVENT_INTRO_A2_9,
+ EVENT_INTRO_A2_10,
+ EVENT_INTRO_A2_11,
+ EVENT_INTRO_A2_12,
+ EVENT_INTRO_A2_13,
+ EVENT_INTRO_A2_14,
+ EVENT_INTRO_A2_15,
+ EVENT_INTRO_A2_16,
+ EVENT_INTRO_A2_17,
+ EVENT_INTRO_A2_18,
+ EVENT_INTRO_A2_19,
+
+ EVENT_INTRO_H2_1,
+ EVENT_INTRO_H2_2,
+ EVENT_INTRO_H2_3,
+ EVENT_INTRO_H2_4,
+ EVENT_INTRO_H2_5,
+ EVENT_INTRO_H2_6,
+ EVENT_INTRO_H2_7,
+ EVENT_INTRO_H2_8,
+ EVENT_INTRO_H2_9,
+ EVENT_INTRO_H2_10,
+ EVENT_INTRO_H2_11,
+ EVENT_INTRO_H2_12,
+ EVENT_INTRO_H2_13,
+ EVENT_INTRO_H2_14,
+ EVENT_INTRO_H2_15,
+
+ EVENT_INTRO_LK_1,
+ EVENT_INTRO_LK_2,
+ EVENT_INTRO_LK_3,
+ EVENT_INTRO_LK_4,
+ EVENT_INTRO_LK_5,
+ EVENT_INTRO_LK_6,
+ EVENT_INTRO_LK_7,
+ EVENT_INTRO_LK_8,
+ EVENT_INTRO_LK_9,
+
+ EVENT_INTRO_END,
+};
+
+enum eEnum
+{
+ ACTION_START_INTRO,
+ ACTION_SKIP_INTRO,
+
+ QUEST_DELIVRANCE_FROM_THE_PIT_A2 = 24710,
+ QUEST_DELIVRANCE_FROM_THE_PIT_H2 = 24712,
+ QUEST_WRATH_OF_THE_LICH_KING_A2 = 24500,
+ QUEST_WRATH_OF_THE_LICH_KING_H2 = 24802,
+};
+
+static Position HallsofReflectionLocs[]=
+{
+ {5283.234863, 1990.946777, 707.695679, 0.929097}, // 2 Loralen Follows
+ {5408.031250, 2102.918213, 707.695251, 0.792756}, // 9 Sylvanas Follows
+ {5401.866699, 2110.837402, 707.695251, 0.800610}, // 10 Loralen follows
+};
+
+static Position SpawnPos = {5262.540527, 1949.693726, 707.695007, 0.808736}; // Jaina/Sylvanas Beginning Position
+static Position MoveThronePos = {5306.952148, 1998.499023, 709.341431, 1.277278}; // Jaina/Sylvanas walks to throne
+static Position UtherSpawnPos = {5308.310059, 2003.857178, 709.341431, 4.650315};
+static Position LichKingSpawnPos = {5362.917480, 2062.307129, 707.695374, 3.945812};
+static Position LichKingMoveThronePos = {5312.080566, 2009.172119, 709.341431, 3.973301}; // Lich King walks to throne
+static Position LichKingMoveAwayPos = {5400.069824, 2102.7131689, 707.69525, 0.843803}; // Lich King walks away
+
+// AI of Part1: handle the intro till start of gauntlet event.
+struct npc_jaina_or_sylvanas_horAI : public ScriptedAI
+{
+ npc_jaina_or_sylvanas_horAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = me->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+ uint64 uiUther;
+ uint64 uiLichKing;
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+
+ uiUther = 0;
+ uiLichKing = 0;
+
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ me->SetVisibility(VISIBILITY_ON);
+ }
+
+ void DoAction(const int32 actionId)
+ {
+ switch(actionId)
+ {
+ case ACTION_START_INTRO:
+ events.ScheduleEvent(EVENT_START_INTRO, 0);
+ break;
+ case ACTION_SKIP_INTRO:
+ events.ScheduleEvent(EVENT_SKIP_INTRO, 0);
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ events.Update(diff);
+ switch(events.ExecuteEvent())
+ {
+ case EVENT_START_INTRO:
+ me->GetMotionMaster()->MovePoint(0, MoveThronePos);
+ // Begining of intro is differents between factions as the speech sequence and timers are differents.
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
+ events.ScheduleEvent(EVENT_INTRO_A2_1, 0);
+ else
+ events.ScheduleEvent(EVENT_INTRO_H2_1, 0);
+ break;
+
+ // A2 Intro Events
+ case EVENT_INTRO_A2_1:
+ DoScriptText(SAY_JAINA_INTRO_3, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_2, 5000);
+ break;
+ case EVENT_INTRO_A2_2:
+ DoScriptText(SAY_JAINA_INTRO_4, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_3, 10000);
+ break;
+ case EVENT_INTRO_A2_3:
+ // TODO: she's doing some kind of spell casting emote
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_FROSTMOURNE), true);
+ events.ScheduleEvent(EVENT_INTRO_A2_4, 10000);
+ break;
+ case EVENT_INTRO_A2_4:
+ // spawn UTHER during speach 2
+ if (Creature* pUther = me->SummonCreature(NPC_UTHER, UtherSpawnPos, TEMPSUMMON_MANUAL_DESPAWN))
+ {
+ pUther->GetMotionMaster()->MoveIdle();
+ pUther->SetReactState(REACT_PASSIVE); // be sure he will not aggro arthas
+ uiUther = pUther->GetGUID();
+ }
+ events.ScheduleEvent(EVENT_INTRO_A2_5, 2000);
+ break;
+ case EVENT_INTRO_A2_5:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_A2_1, pUther);
+ events.ScheduleEvent(EVENT_INTRO_A2_6, 3000);
+ break;
+ case EVENT_INTRO_A2_6:
+ DoScriptText(SAY_JAINA_INTRO_5, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_7, 6000);
+ break;
+ case EVENT_INTRO_A2_7:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_A2_2, pUther);
+ events.ScheduleEvent(EVENT_INTRO_A2_8, 6500);
+ break;
+ case EVENT_INTRO_A2_8:
+ DoScriptText(SAY_JAINA_INTRO_6, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_9, 2000);
+ break;
+ case EVENT_INTRO_A2_9:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_A2_3, pUther);
+ events.ScheduleEvent(EVENT_INTRO_A2_10, 9000);
+ break;
+ case EVENT_INTRO_A2_10:
+ DoScriptText(SAY_JAINA_INTRO_7, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_11, 5000);
+ break;
+ case EVENT_INTRO_A2_11:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_A2_4, pUther);
+ events.ScheduleEvent(EVENT_INTRO_A2_12, 11000);
+ break;
+ case EVENT_INTRO_A2_12:
+ DoScriptText(SAY_JAINA_INTRO_8, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_13, 4000);
+ break;
+ case EVENT_INTRO_A2_13:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_A2_5, pUther);
+ events.ScheduleEvent(EVENT_INTRO_A2_14, 12500);
+ break;
+ case EVENT_INTRO_A2_14:
+ DoScriptText(SAY_JAINA_INTRO_9, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_15, 10000);
+ break;
+ case EVENT_INTRO_A2_15:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_A2_6, pUther);
+ events.ScheduleEvent(EVENT_INTRO_A2_16, 22000);
+ break;
+ case EVENT_INTRO_A2_16:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_A2_7, pUther);
+ events.ScheduleEvent(EVENT_INTRO_A2_17, 4000);
+ break;
+ case EVENT_INTRO_A2_17:
+ DoScriptText(SAY_JAINA_INTRO_10, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_18, 2000);
+ break;
+ case EVENT_INTRO_A2_18:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ {
+ pUther->HandleEmoteCommand(EMOTE_ONESHOT_NO);
+ DoScriptText(SAY_UTHER_INTRO_A2_8, pUther);
+ }
+ events.ScheduleEvent(EVENT_INTRO_A2_19, 11000);
+ break;
+ case EVENT_INTRO_A2_19:
+ DoScriptText(SAY_JAINA_INTRO_11, me);
+ events.ScheduleEvent(EVENT_INTRO_LK_1, 2000);
+ break;
+
+ // H2 Intro Events
+ case EVENT_INTRO_H2_1:
+ DoScriptText(SAY_SYLVANAS_INTRO_1, me);
+ events.ScheduleEvent(EVENT_INTRO_H2_2, 8000);
+ break;
+ case EVENT_INTRO_H2_2:
+ DoScriptText(SAY_SYLVANAS_INTRO_2, me);
+ events.ScheduleEvent(EVENT_INTRO_H2_3, 6000);
+ break;
+ case EVENT_INTRO_H2_3:
+ DoScriptText(SAY_SYLVANAS_INTRO_3, me);
+ // TODO: she's doing some kind of spell casting emote
+ events.ScheduleEvent(EVENT_INTRO_H2_4, 6000);
+ break;
+ case EVENT_INTRO_H2_4:
+ // spawn UTHER during speach 2
+ if (Creature* pUther = me->SummonCreature(NPC_UTHER, UtherSpawnPos, TEMPSUMMON_MANUAL_DESPAWN))
+ {
+ pUther->GetMotionMaster()->MoveIdle();
+ pUther->SetReactState(REACT_PASSIVE); // be sure he will not aggro arthas
+ uiUther = pUther->GetGUID();
+ }
+ events.ScheduleEvent(EVENT_INTRO_H2_5, 2000);
+ break;
+ case EVENT_INTRO_H2_5:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_H2_1, pUther);
+ events.ScheduleEvent(EVENT_INTRO_H2_6, 11000);
+ break;
+ case EVENT_INTRO_H2_6:
+ DoScriptText(SAY_SYLVANAS_INTRO_4, me);
+ events.ScheduleEvent(EVENT_INTRO_H2_7, 3000);
+ break;
+ case EVENT_INTRO_H2_7:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_H2_2, pUther);
+ events.ScheduleEvent(EVENT_INTRO_H2_8, 6000);
+ break;
+ case EVENT_INTRO_H2_8:
+ DoScriptText(SAY_SYLVANAS_INTRO_5, me);
+ events.ScheduleEvent(EVENT_INTRO_H2_9, 5000);
+ break;
+ case EVENT_INTRO_H2_9:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_H2_3, pUther);
+ events.ScheduleEvent(EVENT_INTRO_H2_10, 19000);
+ break;
+ case EVENT_INTRO_H2_10:
+ DoScriptText(SAY_SYLVANAS_INTRO_6, me);
+ events.ScheduleEvent(EVENT_INTRO_H2_11, 1500);
+ break;
+ case EVENT_INTRO_H2_11:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_H2_4, pUther);
+ events.ScheduleEvent(EVENT_INTRO_H2_12, 19500);
+ break;
+ case EVENT_INTRO_H2_12:
+ DoScriptText(SAY_SYLVANAS_INTRO_7, me);
+ events.ScheduleEvent(EVENT_INTRO_H2_13, 2000);
+ break;
+ case EVENT_INTRO_H2_13:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ {
+ pUther->HandleEmoteCommand(EMOTE_ONESHOT_NO);
+ DoScriptText(SAY_UTHER_INTRO_H2_5, pUther);
+ }
+ events.ScheduleEvent(EVENT_INTRO_H2_14, 12000);
+ break;
+ case EVENT_INTRO_H2_14:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_H2_6, pUther);
+ events.ScheduleEvent(EVENT_INTRO_H2_15, 8000);
+ break;
+ case EVENT_INTRO_H2_15:
+ DoScriptText(SAY_SYLVANAS_INTRO_8, me);
+ events.ScheduleEvent(EVENT_INTRO_LK_1, 2000);
+ break;
+
+ // Remaining Intro Events common for both faction
+ case EVENT_INTRO_LK_1:
+ // Spawn LK in front of door, and make him move to the sword.
+ if (Creature* pLichKing = me->SummonCreature(NPC_LICH_KING_EVENT, LichKingSpawnPos, TEMPSUMMON_MANUAL_DESPAWN))
+ {
+ pLichKing->GetMotionMaster()->MovePoint(0, LichKingMoveThronePos);
+ pLichKing->SetReactState(REACT_PASSIVE);
+ uiLichKing = pLichKing->GetGUID();
+ }
+
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
+ DoScriptText(SAY_UTHER_INTRO_A2_9, pUther);
+ else
+ DoScriptText(SAY_UTHER_INTRO_H2_7, pUther);
+
+ events.ScheduleEvent(EVENT_INTRO_LK_2, 11000);
+ break;
+
+ case EVENT_INTRO_LK_2:
+ if (Creature* pLichKing = me->GetCreature(*me, uiLichKing))
+ DoScriptText(SAY_LK_INTRO_1, pLichKing);
+ events.ScheduleEvent(EVENT_INTRO_LK_3, 2000);
+ break;
+
+ case EVENT_INTRO_LK_3:
+ // The Lich King banishes Uther to the abyss.
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ {
+ pUther->DisappearAndDie();
+ uiUther = 0;
+ }
+
+ // He steps forward and removes the runeblade from the heap of skulls.
+
+ events.ScheduleEvent(EVENT_INTRO_LK_4, 4000);
+ break;
+
+ case EVENT_INTRO_LK_4:
+ if (Creature* pLichKing = me->GetCreature(*me, uiLichKing))
+ DoScriptText(SAY_LK_INTRO_2, pLichKing);
+ events.ScheduleEvent(EVENT_INTRO_LK_5, 10000);
+ break;
+
+ case EVENT_INTRO_LK_5:
+ // summon Falric and Marwyn. then go back to the door
+ if (Creature* pFalric = me->GetCreature(*me, pInstance->GetData64(DATA_FALRIC)))
+ pFalric->SetVisibility(VISIBILITY_ON);
+ if (Creature* pMarwyn = me->GetCreature(*me, pInstance->GetData64(DATA_MARWYN)))
+ pMarwyn->SetVisibility(VISIBILITY_ON);
+
+ if (Creature* pLichKing = me->GetCreature(*me, uiLichKing))
+ {
+ pLichKing->GetMotionMaster()->MovePoint(0, LichKingSpawnPos);
+ DoScriptText(SAY_LK_INTRO_3, pLichKing);
+ }
+
+ events.ScheduleEvent(EVENT_INTRO_LK_6, 8000);
+ break;
+
+ case EVENT_INTRO_LK_6:
+ if (Creature* pFalric = me->GetCreature(*me, pInstance->GetData64(DATA_FALRIC)))
+ DoScriptText(SAY_FALRIC_INTRO_1, pFalric);
+
+ events.ScheduleEvent(EVENT_INTRO_LK_7, 2000);
+ break;
+
+ case EVENT_INTRO_LK_7:
+ if (Creature* pMarwyn = me->GetCreature(*me, pInstance->GetData64(DATA_MARWYN)))
+ DoScriptText(SAY_MARWYN_INTRO_1, pMarwyn);
+
+ events.ScheduleEvent(EVENT_INTRO_LK_8, 2000);
+ break;
+
+ case EVENT_INTRO_LK_8:
+ if (Creature* pFalric = me->GetCreature(*me, pInstance->GetData64(DATA_FALRIC)))
+ DoScriptText(SAY_FALRIC_INTRO_2, pFalric);
+
+ events.ScheduleEvent(EVENT_INTRO_LK_9, 5000);
+ break;
+
+ case EVENT_INTRO_LK_9:
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
+ DoScriptText(SAY_JAINA_INTRO_END, me);
+ else
+ DoScriptText(SAY_SYLVANAS_INTRO_END, me);
+
+ me->GetMotionMaster()->MovePoint(0, LichKingSpawnPos);
+ // TODO: Loralen/Koreln shall run also
+ events.ScheduleEvent(EVENT_INTRO_END, 10000);
+ break;
+
+ case EVENT_INTRO_END:
+ if (pInstance)
+ pInstance->SetData(DATA_WAVE_COUNT, SPECIAL); // start first wave
+
+ // Loralen or Koreln disappearAndDie()
+ me->DisappearAndDie();
+ break;
+
+ case EVENT_SKIP_INTRO:
+ // TODO: implement
+
+ if (Creature* pFalric = me->GetCreature(*me, pInstance->GetData64(DATA_FALRIC)))
+ pFalric->SetVisibility(VISIBILITY_ON);
+ if (Creature* pMarwyn = me->GetCreature(*me, pInstance->GetData64(DATA_MARWYN)))
+ pMarwyn->SetVisibility(VISIBILITY_ON);
+
+ me->GetMotionMaster()->MovePoint(0, LichKingSpawnPos);
+ // TODO: Loralen/Koreln shall run also
+
+ events.ScheduleEvent(EVENT_INTRO_END, 15000);
+ break;
+ }
+ }
+};
+
+bool GossipHello_npc_sylvanas_hor(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_DELIVRANCE_FROM_THE_PIT_H2) == QUEST_STATUS_COMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM( 0, "Can you remove the sword?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ // once last quest is completed, she offers this shortcut of the starting event
+ if (pPlayer->GetQuestStatus(QUEST_WRATH_OF_THE_LICH_KING_H2) == QUEST_STATUS_COMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM( 0, "Dark Lady, I think I hear Arthas coming. Whatever you're going to do, do it quickly.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+
+ pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipHello_npc_jaina_hor(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_DELIVRANCE_FROM_THE_PIT_A2) == QUEST_STATUS_COMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM( 0, "Can you remove the sword?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ // once last quest of the series is completed, she offers this shortcut of the starting event
+ if (pPlayer->GetQuestStatus(QUEST_WRATH_OF_THE_LICH_KING_A2) == QUEST_STATUS_COMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM( 0, "My Lady, I think I hear Arthas coming. Whatever you're going to do, do it quickly.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+
+ pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_jaina_or_sylvanas_hor(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ switch (uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ if (pCreature->AI())
+ pCreature->AI()->DoAction(ACTION_START_INTRO);
+ pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ if (pCreature->AI())
+ pCreature->AI()->DoAction(ACTION_SKIP_INTRO);
+ pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ break;
+ }
+
+ return true;
+}
+
+enum TrashSpells
+{
+ // Ghostly Priest
+ SPELL_SHADOW_WORD_PAIN = 72318,
+ SPELL_CIRCLE_OF_DESTRUCTION = 72320,
+ SPELL_COWER_IN_FEAR = 72321,
+ SPELL_DARK_MENDING = 72322,
+
+ // Phantom Mage
+ SPELL_FIREBALL = 72163,
+ SPELL_FLAMESTRIKE = 72169,
+ SPELL_FROSTBOLT = 72166,
+ SPELL_CHAINS_OF_ICE = 72121,
+ SPELL_HALLUCINATION = 72342,
+
+ // Phantom Hallucination (same as phantom mage + HALLUCINATION_2 when dies)
+ SPELL_HALLUCINATION_2 = 72344,
+
+ // Shadowy Mercenary
+ SPELL_SHADOW_STEP = 72326,
+ SPELL_DEADLY_POISON = 72329,
+ SPELL_ENVENOMED_DAGGER_THROW = 72333,
+ SPELL_KIDNEY_SHOT = 72335,
+
+ // Spectral Footman
+ SPELL_SPECTRAL_STRIKE = 72198,
+ SPELL_SHIELD_BASH = 72194,
+ SPELL_TORTURED_ENRAGE = 72203,
+
+ // Tortured Rifleman
+ SPELL_SHOOT = 72208,
+ SPELL_CURSED_ARROW = 72222,
+ SPELL_FROST_TRAP = 72215,
+ SPELL_ICE_SHOT = 72268,
+};
+
+enum TrashEvents
+{
+ EVENT_TRASH_NONE,
+
+ // Ghostly Priest
+ EVENT_SHADOW_WORD_PAIN,
+ EVENT_CIRCLE_OF_DESTRUCTION,
+ EVENT_COWER_IN_FEAR,
+ EVENT_DARK_MENDING,
+
+ // Phantom Mage
+ EVENT_FIREBALL,
+ EVENT_FLAMESTRIKE,
+ EVENT_FROSTBOLT,
+ EVENT_CHAINS_OF_ICE,
+ EVENT_HALLUCINATION,
+
+ // Shadowy Mercenary
+ EVENT_SHADOW_STEP,
+ EVENT_DEADLY_POISON,
+ EVENT_ENVENOMED_DAGGER_THROW,
+ EVENT_KIDNEY_SHOT,
+
+ // Spectral Footman
+ EVENT_SPECTRAL_STRIKE,
+ EVENT_SHIELD_BASH,
+ EVENT_TORTURED_ENRAGE,
+
+ // Tortured Rifleman
+ EVENT_SHOOT,
+ EVENT_CURSED_ARROW,
+ EVENT_FROST_TRAP,
+ EVENT_ICE_SHOT,
+};
+
+struct npc_ghostly_priestAI: public ScriptedAI
+{
+ npc_ghostly_priestAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000); // TODO: adjust timers
+ events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000);
+ events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000);
+ events.ScheduleEvent(EVENT_DARK_MENDING, 20000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SHADOW_WORD_PAIN:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_SHADOW_WORD_PAIN);
+ events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000);
+ return;
+ case EVENT_CIRCLE_OF_DESTRUCTION:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_CIRCLE_OF_DESTRUCTION);
+ events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000);
+ return;
+ case EVENT_COWER_IN_FEAR:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_COWER_IN_FEAR);
+ events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000);
+ return;
+ case EVENT_DARK_MENDING:
+ // find an ally with missing HP
+ if (Unit *pTarget = DoSelectLowestHpFriendly(40, DUNGEON_MODE(30000,50000)))
+ {
+ DoCast(pTarget, SPELL_DARK_MENDING);
+ events.ScheduleEvent(EVENT_DARK_MENDING, 20000);
+ }
+ else
+ {
+ // no friendly unit with missing hp. re-check in just 5 sec.
+ events.ScheduleEvent(EVENT_DARK_MENDING, 5000);
+ }
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct npc_phantom_mageAI: public ScriptedAI
+{
+ npc_phantom_mageAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_FIREBALL, 3000); // TODO: adjust timers
+ events.ScheduleEvent(EVENT_FLAMESTRIKE, 6000);
+ events.ScheduleEvent(EVENT_FROSTBOLT, 9000);
+ events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 12000);
+ events.ScheduleEvent(EVENT_HALLUCINATION, 40000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_FIREBALL:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_FIREBALL);
+ events.ScheduleEvent(EVENT_FIREBALL, 15000);
+ return;
+ case EVENT_FLAMESTRIKE:
+ DoCast(SPELL_FLAMESTRIKE);
+ events.ScheduleEvent(EVENT_FLAMESTRIKE, 15000);
+ return;
+ case EVENT_FROSTBOLT:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_FROSTBOLT);
+ events.ScheduleEvent(EVENT_FROSTBOLT, 15000);
+ return;
+ case EVENT_CHAINS_OF_ICE:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_CHAINS_OF_ICE);
+ events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 15000);
+ return;
+ case EVENT_HALLUCINATION:
+ DoCast(SPELL_HALLUCINATION);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct npc_phantom_hallucinationAI: public npc_phantom_mageAI
+{
+ npc_phantom_hallucinationAI(Creature *c) : npc_phantom_mageAI(c)
+ {
+ }
+
+ void JustDied(Unit * /*pWho*/)
+ {
+ DoCast(SPELL_HALLUCINATION_2);
+ }
+};
+
+struct npc_shadowy_mercenaryAI: public ScriptedAI
+{
+ npc_shadowy_mercenaryAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SHADOW_STEP, 8000); // TODO: adjust timers
+ events.ScheduleEvent(EVENT_DEADLY_POISON, 5000);
+ events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000);
+ events.ScheduleEvent(EVENT_KIDNEY_SHOT, 12000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SHADOW_STEP:
+ DoCast(SPELL_SHADOW_STEP);
+ events.ScheduleEvent(EVENT_SHADOW_STEP, 8000);
+ return;
+ case EVENT_DEADLY_POISON:
+ DoCast(me->getVictim(), SPELL_DEADLY_POISON);
+ events.ScheduleEvent(EVENT_DEADLY_POISON, 10000);
+ return;
+ case EVENT_ENVENOMED_DAGGER_THROW:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_ENVENOMED_DAGGER_THROW);
+ events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000);
+ return;
+ case EVENT_KIDNEY_SHOT:
+ DoCast(me->getVictim(), SPELL_KIDNEY_SHOT);
+ events.ScheduleEvent(EVENT_KIDNEY_SHOT, 10000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct npc_spectral_footmanAI: public ScriptedAI
+{
+ npc_spectral_footmanAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); // TODO: adjust timers
+ events.ScheduleEvent(EVENT_SHIELD_BASH, 10000);
+ events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SPECTRAL_STRIKE:
+ DoCast(me->getVictim(), SPELL_SPECTRAL_STRIKE);
+ events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000);
+ return;
+ case EVENT_SHIELD_BASH:
+ DoCast(me->getVictim(), SPELL_SHIELD_BASH);
+ events.ScheduleEvent(EVENT_SHIELD_BASH, 5000);
+ return;
+ case EVENT_TORTURED_ENRAGE:
+ DoCast(SPELL_TORTURED_ENRAGE);
+ events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct npc_tortured_riflemanAI : public ScriptedAI
+{
+ npc_tortured_riflemanAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SHOOT, 2000); // TODO: adjust timers
+ events.ScheduleEvent(EVENT_CURSED_ARROW, 10000);
+ events.ScheduleEvent(EVENT_FROST_TRAP, 1000);
+ events.ScheduleEvent(EVENT_ICE_SHOT, 15000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SHOOT:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_SHOOT);
+ events.ScheduleEvent(EVENT_SHOOT, 2000);
+ return;
+ case EVENT_CURSED_ARROW:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_CURSED_ARROW);
+ events.ScheduleEvent(EVENT_CURSED_ARROW, 10000);
+ return;
+ case EVENT_FROST_TRAP:
+ DoCast(SPELL_FROST_TRAP);
+ events.ScheduleEvent(EVENT_FROST_TRAP, 30000);
+ return;
+ case EVENT_ICE_SHOT:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_ICE_SHOT);
+ events.ScheduleEvent(EVENT_ICE_SHOT, 15000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_jaina_or_sylvanas_horAI(Creature* pCreature)
+{
+ return new npc_jaina_or_sylvanas_horAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_ghostly_priestAI(Creature* pCreature)
+{
+ return new npc_ghostly_priestAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_phantom_mageAI(Creature* pCreature)
+{
+ return new npc_phantom_mageAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_phantom_hallucinationAI(Creature* pCreature)
+{
+ return new npc_phantom_hallucinationAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_shadowy_mercenaryAI(Creature* pCreature)
+{
+ return new npc_shadowy_mercenaryAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_spectral_footmanAI(Creature* pCreature)
+{
+ return new npc_spectral_footmanAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_tortured_riflemanAI(Creature* pCreature)
+{
+ return new npc_tortured_riflemanAI(pCreature);
+}
+
+void AddSC_halls_of_reflection()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_sylvanas_hor_part1";
+ newscript->GetAI = &GetAI_npc_jaina_or_sylvanas_horAI;
+ newscript->pGossipHello = &GossipHello_npc_sylvanas_hor;
+ newscript->pGossipSelect = &GossipSelect_npc_jaina_or_sylvanas_hor;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_jaina_hor_part1";
+ newscript->GetAI = &GetAI_npc_jaina_or_sylvanas_horAI;
+ newscript->pGossipHello = &GossipHello_npc_jaina_hor;
+ newscript->pGossipSelect = &GossipSelect_npc_jaina_or_sylvanas_hor;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_ghostly_priest";
+ newscript->GetAI = &GetAI_npc_ghostly_priestAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_phantom_mage";
+ newscript->GetAI = &GetAI_npc_phantom_mageAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_phantom_hallucination";
+ newscript->GetAI = &GetAI_npc_phantom_hallucinationAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_shadowy_mercenary";
+ newscript->GetAI = &GetAI_npc_shadowy_mercenaryAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_spectral_footman";
+ newscript->GetAI = &GetAI_npc_spectral_footmanAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_tortured_rifleman";
+ newscript->GetAI = &GetAI_npc_tortured_riflemanAI;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h b/src/server/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h
new file mode 100644
index 00000000000..46ae0cb283c
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h
@@ -0,0 +1,156 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DEF_HALLS_OF_REFLECTION_H
+#define DEF_HALLS_OF_REFLECTION_H
+
+enum Data
+{
+ DATA_FALRIC_EVENT,
+ DATA_MARWYN_EVENT,
+ DATA_LICHKING_EVENT,
+ DATA_WAVE_COUNT,
+ DATA_TEAM_IN_INSTANCE,
+};
+
+enum Data64
+{
+ DATA_FALRIC,
+ DATA_MARWYN,
+ DATA_LICHKING,
+ DATA_FROSTMOURNE,
+};
+
+enum Creatures
+{
+ NPC_FALRIC = 38112,
+ NPC_MARWYN = 38113,
+ NPC_LICH_KING_EVENT = 37226,
+ NPC_LICH_KING_BOSS = 36954,
+
+ NPC_UTHER = 37225,
+ NPC_JAINA_PART1 = 37221,
+ NPC_JAINA_PART2 = 36955,
+ NPC_SYLVANAS_PART1 = 37223,
+ NPC_SYLVANAS_PART2 = 37554,
+
+ NPC_WAVE_MERCENARY = 38177,
+ NPC_WAVE_FOOTMAN = 38173,
+ NPC_WAVE_RIFLEMAN = 38176,
+ NPC_WAVE_PRIEST = 38175,
+ NPC_WAVE_MAGE = 38172,
+};
+
+enum GameObjects
+{
+ GO_FROSTMOURNE = 202302,
+ GO_FROSTMOURNE_ALTAR = 202236,
+ GO_FRONT_DOOR = 201976,
+ GO_ARTHAS_DOOR = 197341,
+};
+
+enum HorWorldStates
+{
+ WORLD_STATE_HOR = 4884,
+ WORLD_STATE_HOR_WAVE_COUNT = 4882,
+};
+
+// Common actions from Instance Script to Boss Script
+enum Actions
+{
+ ACTION_ENTER_COMBAT,
+};
+
+// Base class for FALRIC and MARWYN
+// handled the summonList and the notification events to/from the InstanceData
+struct boss_horAI : ScriptedAI
+{
+ boss_horAI(Creature *pCreature) : ScriptedAI(pCreature), summons(pCreature)
+ {
+ pInstance = me->GetInstanceData();
+ }
+
+ InstanceData* pInstance;
+ EventMap events;
+ SummonList summons;
+
+ void Reset()
+ {
+ events.Reset();
+ me->SetVisibility(VISIBILITY_OFF);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ void DamageTaken(Unit *pWho, uint32 &uiDamage)
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ uiDamage = 0;
+ }
+
+ void DoAction(const int32 actionID)
+ {
+ switch(actionID)
+ {
+ case ACTION_ENTER_COMBAT: // called by InstanceData when boss shall enter in combat.
+ // Just in case. Should have been done by InstanceData
+ me->SetVisibility(VISIBILITY_ON);
+
+ // Reset flags
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+
+ if (Unit *pUnit = me->SelectNearestTarget())
+ AttackStart(pUnit);
+
+ DoZoneInCombat();
+ break;
+ }
+ }
+
+ void JustSummoned(Creature *pSummoned)
+ {
+ summons.Summon(pSummoned);
+
+ if (Unit *pUnit = pSummoned->SelectNearestTarget())
+ {
+ if (pSummoned->AI())
+ pSummoned->AI()->AttackStart(pUnit);
+ else
+ {
+ pSummoned->GetMotionMaster()->MoveChase(pUnit);
+ pSummoned->Attack(pUnit, true);
+ }
+ }
+
+ if (pSummoned->AI())
+ pSummoned->AI()->DoZoneInCombat();
+ }
+
+ void SummonedCreatureDespawn(Creature *pSummoned)
+ {
+ summons.Despawn(pSummoned);
+ if (summons.empty())
+ {
+ if (pSummoned->isAlive())
+ pInstance->SetData(DATA_WAVE_COUNT, NOT_STARTED);
+ else
+ pInstance->SetData(DATA_WAVE_COUNT, SPECIAL);
+ }
+ }
+};
+
+#endif
diff --git a/src/server/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp b/src/server/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp
new file mode 100644
index 00000000000..7a5d2479b7c
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp
@@ -0,0 +1,431 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "halls_of_reflection.h"
+
+#define MAX_ENCOUNTER 3
+
+/* Halls of Reflection encounters:
+0- Falric
+1- Marwyn
+2- The Lich King
+*/
+
+enum eEnum
+{
+ ENCOUNTER_WAVE_MERCENARY = 6,
+ ENCOUNTER_WAVE_FOOTMAN = 10,
+ ENCOUNTER_WAVE_RIFLEMAN = 6,
+ ENCOUNTER_WAVE_PRIEST = 6,
+ ENCOUNTER_WAVE_MAGE = 6,
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_NEXT_WAVE,
+ EVENT_START_LICH_KING,
+};
+
+static Position PriestSpawnPos[ENCOUNTER_WAVE_PRIEST] =
+{
+ {5277.74,2016.88,707.778,5.96903},
+ {5295.88,2040.34,707.778,5.07891},
+ {5320.37,1980.13,707.778,2.00713},
+ {5280.51,1997.84,707.778,0.296706},
+ {5302.45,2042.22,707.778,4.90438},
+ {5306.57,1977.47,707.778,1.50098},
+};
+
+static Position MageSpawnPos[ENCOUNTER_WAVE_MAGE] =
+{
+ {5312.75,2037.12,707.778,4.59022},
+ {5309.58,2042.67,707.778,4.69494},
+ {5275.08,2008.72,707.778,6.21337},
+ {5279.65,2004.66,707.778,0.069813},
+ {5275.48,2001.14,707.778,0.174533},
+ {5316.7,2041.55,707.778,4.50295},
+};
+
+static Position MercenarySpawnPos[ENCOUNTER_WAVE_MERCENARY] =
+{
+ {5302.25,1972.41,707.778,1.37881},
+ {5311.03,1972.23,707.778,1.64061},
+ {5277.36,1993.23,707.778,0.401426},
+ {5318.7,2036.11,707.778,4.2237},
+ {5335.72,1996.86,707.778,2.74017},
+ {5299.43,1979.01,707.778,1.23918},
+};
+
+static Position FootmenSpawnPos[ENCOUNTER_WAVE_FOOTMAN] =
+{
+ {5306.06,2037,707.778,4.81711},
+ {5344.15,2007.17,707.778,3.15905},
+ {5337.83,2010.06,707.778,3.22886},
+ {5343.29,1999.38,707.778,2.9147},
+ {5340.84,1992.46,707.778,2.75762},
+ {5325.07,1977.6,707.778,2.07694},
+ {5336.6,2017.28,707.778,3.47321},
+ {5313.82,1978.15,707.778,1.74533},
+ {5280.63,2012.16,707.778,6.05629},
+ {5322.96,2040.29,707.778,4.34587},
+};
+
+static Position RiflemanSpawnPos[ENCOUNTER_WAVE_RIFLEMAN] =
+{
+ {5343.47,2015.95,707.778,3.49066},
+ {5337.86,2003.4,707.778,2.98451},
+ {5319.16,1974,707.778,1.91986},
+ {5299.25,2036,707.778,5.02655},
+ {5295.64,1973.76,707.778,1.18682},
+ {5282.9,2019.6,707.778,5.88176},
+};
+
+struct instance_halls_of_reflection : public ScriptedInstance
+{
+ instance_halls_of_reflection(Map* pMap) : ScriptedInstance(pMap) {};
+
+ uint64 uiFalric;
+ uint64 uiMarwyn;
+ uint64 uiLichKingEvent;
+ uint64 uiJainaPart1;
+ uint64 uiSylvanasPart1;
+
+ uint64 uiFrostmourne;
+ uint64 uiFrostmourneAltar;
+ uint64 uiArthasDoor;
+ uint64 uiFrontDoor;
+
+ uint32 uiEncounter[MAX_ENCOUNTER];
+ uint32 uiTeamInInstance;
+ uint32 uiWaveCount;
+ bool bIntroDone;
+
+ EventMap events;
+
+ void Initialize()
+ {
+ events.Reset();
+
+ uiFalric = 0;
+ uiMarwyn = 0;
+ uiLichKingEvent = 0;
+ uiJainaPart1 = 0;
+ uiSylvanasPart1 = 0;
+
+ uiFrostmourne = 0;
+ uiFrostmourneAltar = 0;
+ uiArthasDoor = 0;
+ uiFrontDoor = 0;
+ uiTeamInInstance = 0;
+ uiWaveCount = 0;
+ bIntroDone = false;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ uiEncounter[i] = NOT_STARTED;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool add)
+ {
+ if (!add)
+ return;
+
+ Map::PlayerList const &players = instance->GetPlayers();
+ if (!players.isEmpty())
+ if (Player* pPlayer = players.begin()->getSource())
+ uiTeamInInstance = pPlayer->GetTeam();
+
+ switch(pCreature->GetEntry())
+ {
+ case NPC_FALRIC:
+ uiFalric = pCreature->GetGUID();
+ break;
+ case NPC_MARWYN:
+ uiMarwyn = pCreature->GetGUID();
+ break;
+ case NPC_LICH_KING_EVENT:
+ uiLichKingEvent = pCreature->GetGUID();
+ break;
+ case NPC_JAINA_PART1:
+ uiJainaPart1 = pCreature->GetGUID();
+ break;
+ case NPC_SYLVANAS_PART1:
+ uiSylvanasPart1 = pCreature->GetGUID();
+ break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* pGo, bool add)
+ {
+ if (!add)
+ return;
+
+ // TODO: init state depending on encounters
+ switch(pGo->GetEntry())
+ {
+ case GO_FROSTMOURNE:
+ uiFrostmourne = pGo->GetGUID();
+ pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
+ HandleGameObject(0, false, pGo);
+ break;
+ case GO_FROSTMOURNE_ALTAR:
+ uiFrostmourneAltar = pGo->GetGUID();
+ pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
+ HandleGameObject(0, true, pGo);
+ break;
+ case GO_FRONT_DOOR:
+ uiFrontDoor = pGo->GetGUID();
+ pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
+ HandleGameObject(0, true, pGo);
+ break;
+ case GO_ARTHAS_DOOR:
+ uiArthasDoor = pGo->GetGUID();
+ pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
+
+ if (uiEncounter[1] == DONE)
+ HandleGameObject(0, true, pGo);
+ else
+ HandleGameObject(0, false, pGo);
+ break;
+ }
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ if (type == DATA_WAVE_COUNT && data == SPECIAL)
+ {
+ bIntroDone = true;
+ events.ScheduleEvent(EVENT_NEXT_WAVE, 10000);
+ return;
+ }
+
+
+ if (uiWaveCount && data == NOT_STARTED)
+ DoWipe();
+
+ switch(type)
+ {
+ case DATA_FALRIC_EVENT:
+ uiEncounter[0] = data;
+ if (data == DONE)
+ events.ScheduleEvent(EVENT_NEXT_WAVE, 60000);
+ break;
+ case DATA_MARWYN_EVENT:
+ uiEncounter[1] = data;
+ if (data == DONE)
+ HandleGameObject(uiArthasDoor, true);
+ break;
+ case DATA_LICHKING_EVENT:
+ uiEncounter[2] = data;
+ break;
+ }
+
+ if (data == DONE)
+ SaveToDB();
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_FALRIC_EVENT: return uiEncounter[0];
+ case DATA_MARWYN_EVENT: return uiEncounter[1];
+ case DATA_LICHKING_EVENT: return uiEncounter[2];
+ case DATA_WAVE_COUNT: return uiWaveCount;
+ case DATA_TEAM_IN_INSTANCE: return uiTeamInInstance;
+ }
+
+ return 0;
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_FALRIC: return uiFalric;
+ case DATA_MARWYN: return uiMarwyn;
+ case DATA_LICHKING: return uiLichKingEvent;
+ case DATA_FROSTMOURNE: return uiFrostmourne;
+ }
+
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "H R 1 " << uiEncounter[0] << " " << uiEncounter[1] << " " << uiEncounter[2];
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return saveStream.str();
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 version;
+ uint16 data0, data1, data2;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> version >> data0 >> data1 >> data2;
+
+ if (dataHead1 == 'H' && dataHead2 == 'R')
+ {
+ uiEncounter[0] = data0;
+ uiEncounter[1] = data1;
+ uiEncounter[2] = data2;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (uiEncounter[i] == IN_PROGRESS)
+ uiEncounter[i] = NOT_STARTED;
+
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ if (uiEncounter[0] == DONE || uiEncounter[1] == DONE)
+ bIntroDone = true;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+
+ void AddWave()
+ {
+ DoUpdateWorldState(WORLD_STATE_HOR, 1);
+ DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, uiWaveCount);
+
+ switch(uiWaveCount)
+ {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ if (Creature *pFalric = instance->GetCreature(uiFalric))
+ SpawnWave(pFalric);
+ break;
+ case 5:
+ if (GetData(DATA_FALRIC_EVENT) == DONE)
+ events.ScheduleEvent(EVENT_NEXT_WAVE, 10000);
+ else if (Creature *pFalric = instance->GetCreature(uiFalric))
+ if (pFalric->AI())
+ pFalric->AI()->DoAction(ACTION_ENTER_COMBAT);
+ break;
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ if (Creature *pMarwyn = instance->GetCreature(uiMarwyn))
+ SpawnWave(pMarwyn);
+ break;
+ case 10:
+ if (GetData(DATA_MARWYN_EVENT) != DONE) // wave should not have been started if DONE. Check anyway to avoid bug exploit!
+ if (Creature *pMarwyn = instance->GetCreature(uiMarwyn))
+ if (pMarwyn->AI())
+ pMarwyn->AI()->DoAction(ACTION_ENTER_COMBAT);
+ break;
+ }
+ }
+
+ // Wipe has been detected. Perform cleanup and reset.
+ void DoWipe()
+ {
+ uiWaveCount = 0;
+ events.Reset();
+ DoUpdateWorldState(WORLD_STATE_HOR, 1);
+ DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, uiWaveCount);
+ HandleGameObject(uiFrontDoor, true);
+
+ // TODO
+ // in case of wipe, the event is normally restarted by jumping into the center of the room.
+ // As I can't find a trigger area there, just respawn Jaina/Sylvanas so the event may be restarted.
+ if (Creature* pJaina = instance->GetCreature(uiJainaPart1))
+ pJaina->Respawn();
+ if (Creature* pSylvanas = instance->GetCreature(uiSylvanasPart1))
+ pSylvanas->Respawn();
+
+ if (Creature* pFalric = instance->GetCreature(uiFalric))
+ pFalric->SetVisibility(VISIBILITY_OFF);
+ if (Creature* pMarwyn = instance->GetCreature(uiMarwyn))
+ pMarwyn->SetVisibility(VISIBILITY_OFF);
+ }
+
+ // spawn a wave on behalf of the summoner.
+ void SpawnWave(Creature *pSummoner)
+ {
+ uint32 index;
+
+ pSummoner->SetVisibility(VISIBILITY_ON);
+
+ // TODO: do composition at random. # of spawn also depends on uiWaveCount
+ // As of now, it is just one of each.
+ index = urand(0,ENCOUNTER_WAVE_MERCENARY-1);
+ pSummoner->SummonCreature(NPC_WAVE_MERCENARY, MercenarySpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+
+ index = urand(0,ENCOUNTER_WAVE_FOOTMAN-1);
+ pSummoner->SummonCreature(NPC_WAVE_FOOTMAN, FootmenSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+
+ index = urand(0,ENCOUNTER_WAVE_RIFLEMAN-1);
+ pSummoner->SummonCreature(NPC_WAVE_RIFLEMAN, RiflemanSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+
+ index = urand(0,ENCOUNTER_WAVE_PRIEST-1);
+ pSummoner->SummonCreature(NPC_WAVE_PRIEST, PriestSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+
+ index = urand(0,ENCOUNTER_WAVE_MAGE-1);
+ pSummoner->SummonCreature(NPC_WAVE_MAGE, MageSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+ }
+
+ void Update(uint32 diff)
+ {
+ if (!instance->HavePlayers())
+ return;
+
+ events.Update(diff);
+
+ switch(uint32 eventId = events.ExecuteEvent())
+ {
+ case EVENT_NEXT_WAVE:
+ uiWaveCount++;
+ AddWave();
+ break;
+ case EVENT_START_LICH_KING:
+ // TODO
+ break;
+ }
+ }
+};
+
+InstanceData* GetInstanceData_instance_halls_of_reflection(Map* pMap)
+{
+ return new instance_halls_of_reflection(pMap);
+}
+
+void AddSC_instance_halls_of_reflection()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_halls_of_reflection";
+ newscript->GetInstanceData = &GetInstanceData_instance_halls_of_reflection;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp b/src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp
new file mode 100644
index 00000000000..25c78c4a0d3
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp
@@ -0,0 +1,209 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "pit_of_saron.h"
+
+enum Yells
+{
+ SAY_AGGRO = -1658001,
+ SAY_SLAY_1 = -1658002,
+ SAY_SLAY_2 = -1658003,
+ SAY_DEATH = -1658004,
+ SAY_PHASE2 = -1658005,
+ SAY_PHASE3 = -1658006,
+
+ SAY_TYRANNUS_DEATH = -1659007,
+};
+
+enum eEvents
+{
+ EVENT_NONE,
+ EVENT_PERMAFROST,
+ EVENT_THROW_SARONITE,
+ EVENT_CHILLINGWAVE,
+ EVENT_DEEPFREEZE,
+};
+
+enum Spells
+{
+ SPELL_PERMAFROST = 70326,
+ SPELL_PERMAFROST_TRIGGER = 68786, // triggered by PERMAFROST. Used to check aura
+ SPELL_THROW_SARONITE = 68788,
+ SPELL_THUNDERING_STOMP = 68771,
+ SPELL_CHILLING_WAVE = 68778,
+ H_SPELL_CHILLING_WAVE = 70333,
+ SPELL_DEEP_FREEZE = 70381,
+ H_SPELL_DEEP_FREEZE = 72930,
+ SPELL_FORGE_MACE = 68785,
+ H_SPELL_FORGE_MACE = 70335,
+ SPELL_FORGE_BLADE = 68774,
+ H_SPELL_FORGE_BLADE = 70334,
+};
+
+enum eEnums
+{
+ EQUIP_ID_SWORD = 49345,
+ EQUIP_ID_MACE = 49344,
+ ACHIEV_DOESNT_GO_TO_ELEVEN = 4524,
+};
+
+struct boss_garfrostAI : public ScriptedAI
+{
+ boss_garfrostAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ bool phase2;
+ bool phase3;
+ bool bAchievement;
+
+ ScriptedInstance* pInstance;
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+
+ phase2 = false;
+ phase3 = false;
+ bAchievement = true;
+
+ if (pInstance)
+ pInstance->SetData(DATA_GARFROST_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ DoCast(me, SPELL_PERMAFROST);
+
+ if (pInstance)
+ pInstance->SetData(DATA_GARFROST_EVENT, IN_PROGRESS);
+
+ events.ScheduleEvent(EVENT_THROW_SARONITE, 45000);
+ }
+
+ void DamageTaken(Unit* /*pDoneBy*/, uint32& /*uiDamage*/)
+ {
+ if (HealthBelowPct(66) && !phase2)
+ {
+ phase2 = true;
+ DoCast(me, SPELL_THUNDERING_STOMP);
+ // TODO: should go to a forge
+ DoCast(me, SPELL_FORGE_BLADE);
+ // TODO: should equip when spell completes
+ SetEquipmentSlots(false, EQUIP_ID_SWORD, -1, -1);
+ me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
+ events.ScheduleEvent(EVENT_CHILLINGWAVE, 10000);
+ }
+
+ if (HealthBelowPct(33) && !phase3)
+ {
+ phase3 = true;
+ DoCast(me, SPELL_THUNDERING_STOMP);
+ // TODO: should go to a forge
+ DoCast(me, SPELL_FORGE_MACE);
+ // TODO: should equip when spell completes
+ SetEquipmentSlots(false, EQUIP_ID_MACE, -1, -1);
+ me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
+ events.CancelEvent(EVENT_CHILLINGWAVE); // cast only in phase 2.
+ events.ScheduleEvent(EVENT_DEEPFREEZE, 10000);
+ }
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ if (pInstance)
+ {
+ if (Creature *pTyrannus = me->GetCreature(*me, pInstance->GetData64(DATA_TYRANNUS)))
+ DoScriptText(SAY_TYRANNUS_DEATH, pTyrannus);
+
+ pInstance->SetData(DATA_GARFROST_EVENT, DONE);
+ if (IsHeroic() && bAchievement)
+ pInstance->DoCompleteAchievement(ACHIEV_DOESNT_GO_TO_ELEVEN);
+ }
+ }
+
+ void SpellHitTarget(Unit* pTarget, const SpellEntry *spell)
+ {
+ if (spell->Id == SPELL_PERMAFROST_TRIGGER && bAchievement)
+ {
+ if (Aura *pAura = pTarget->GetAura(SPELL_PERMAFROST_TRIGGER))
+ if (pAura->GetStackAmount() > 10)
+ bAchievement = false;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_THROW_SARONITE:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_THROW_SARONITE);
+ events.RescheduleEvent(EVENT_THROW_SARONITE, 35000);
+ return;
+ case EVENT_DEEPFREEZE:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_DEEP_FREEZE);
+ events.RescheduleEvent(EVENT_DEEPFREEZE, 35000);
+ return;
+ case EVENT_CHILLINGWAVE:
+ DoCastAOE(SPELL_CHILLING_WAVE);
+ events.RescheduleEvent(EVENT_CHILLINGWAVE, 40000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_garfrost(Creature* pCreature)
+{
+ return new boss_garfrostAI (pCreature);
+}
+
+void AddSC_boss_garfrost()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="boss_garfrost";
+ newscript->GetAI = &GetAI_boss_garfrost;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp b/src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp
new file mode 100644
index 00000000000..8b8b03a3d4e
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp
@@ -0,0 +1,482 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "pit_of_saron.h"
+
+/*
+ * SDComment: Spell Explosive barrage is not working.
+ */
+
+enum Spells
+{
+ SPELL_PURSUED = 68987,
+ SPELL_CONFUSION = 69029,
+ SPELL_EXPLOSIVE_BARRAGE = 69263,
+ SPELL_MIGHTY_KICK = 69021,
+ SPELL_POISON_NOVA = 68989,
+ H_SPELL_POISON_NOVA = 70434,
+ SPELL_SHADOW_BOLT = 69028,
+ SPELL_TOXIC_WASTE = 69024,
+ H_SPELL_TOXIC_WASTE = 70436,
+};
+
+enum Yells
+{
+ // Krick
+ SAY_KRICK_AGGRO = -1658010,
+ SAY_KRICK_SLAY_1 = -1658011,
+ SAY_KRICK_SLAY_2 = -1658012,
+ SAY_KRICK_BARRAGE_1 = -1658013,
+ SAY_KRICK_BARRAGE_2 = -1658014,
+ SAY_KRICK_POISON_NOVA = -1658015,
+ SAY_KRICK_CHASE_1 = -1658016,
+ SAY_KRICK_CHASE_2 = -1658017,
+ SAY_KRICK_CHASE_3 = -1658018,
+
+ // Ick
+ SAY_ICK_POISON_NOVA = -1658020,
+ SAY_ICK_CHASE_1 = -1658021,
+
+ // OUTRO
+ SAY_KRICK_OUTRO_1 = -1658030,
+ SAY_JAYNA_OUTRO_2 = -1658031,
+ SAY_SYLVANAS_OUTRO_2 = -1658032,
+ SAY_KRICK_OUTRO_3 = -1658033,
+ SAY_JAYNA_OUTRO_4 = -1658034,
+ SAY_SYLVANAS_OUTRO_4 = -1658035,
+ SAY_KRICK_OUTRO_5 = -1658036,
+ SAY_TYRANNUS_OUTRO_7 = -1658037,
+ SAY_KRICK_OUTRO_8 = -1658038,
+ SAY_TYRANNUS_OUTRO_9 = -1658039,
+ SAY_JAYNA_OUTRO_10 = -1658040,
+ SAY_SYLVANAS_OUTRO_10 = -1658041,
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_PURSUE,
+ EVENT_MIGHTY_KICK,
+ EVENT_POISON_NOVA,
+ EVENT_EXPLOSIVE_BARRAGE,
+ EVENT_END_EXPLOSIVE_BARRAGE,
+
+ // Krick
+ EVENT_SHADOW_BOLT,
+ EVENT_TOXIC_WASTE,
+
+ // Krick OUTRO
+ EVENT_OUTRO_1,
+ EVENT_OUTRO_2,
+ EVENT_OUTRO_3,
+ EVENT_OUTRO_4,
+ EVENT_OUTRO_5,
+ EVENT_OUTRO_6,
+ EVENT_OUTRO_7,
+ EVENT_OUTRO_8,
+ EVENT_OUTRO_9,
+ EVENT_OUTRO_10,
+ EVENT_OUTRO_11,
+ EVENT_OUTRO_12,
+ EVENT_OUTRO_END,
+};
+
+enum KrickPhase
+{
+ PHASE_COMBAT,
+ PHASE_OUTRO,
+};
+
+enum Actions
+{
+ ACTION_OUTRO,
+};
+
+enum Misc
+{
+ SEAT_KRICK = 0,
+
+ // events GCD. Shall not be 0.
+ GCD_1 = 1,
+};
+
+// Krick is the Gnome.
+// Ick is the Mount
+// Common Events are handled/triggered by Ick that "drive" Krick through DoAction.
+
+struct boss_ickAI : public ScriptedAI
+{
+ boss_ickAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+
+ if (pInstance)
+ pInstance->SetData(DATA_KRICKANDICK_EVENT, NOT_STARTED);
+ }
+
+ Creature* GetKrick()
+ {
+ return me->GetCreature(*me, pInstance ? pInstance->GetData64(DATA_KRICK) : 0);
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_KRICKANDICK_EVENT, IN_PROGRESS);
+
+ Creature* pKrick = GetKrick();
+ if (!pKrick)
+ pKrick = me->SummonCreature(CREATURE_KRICK, *me, TEMPSUMMON_MANUAL_DESPAWN);
+
+ if (pKrick)
+ DoScriptText(SAY_KRICK_AGGRO, pKrick);
+
+ events.ScheduleEvent(EVENT_MIGHTY_KICK, 20000, GCD_1);
+ events.ScheduleEvent(EVENT_PURSUE, 30000, GCD_1);
+ events.ScheduleEvent(EVENT_POISON_NOVA, 30000, GCD_1);
+ events.ScheduleEvent(EVENT_EXPLOSIVE_BARRAGE, 35000);
+ events.ScheduleEvent(EVENT_TOXIC_WASTE, 5000);
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, 15000);
+ }
+
+ void EnterEvadeMode()
+ {
+ me->GetMotionMaster()->Clear();
+ ScriptedAI::EnterEvadeMode();
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ if (Creature* pKrick = GetKrick())
+ {
+ if (pKrick->AI())
+ pKrick->AI()->DoAction(ACTION_OUTRO);
+ }
+
+ if (pInstance)
+ pInstance->SetData(DATA_KRICKANDICK_EVENT, DONE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!me->isInCombat())
+ return;
+
+ if (!me->getVictim() && me->getThreatManager().isThreatListEmpty())
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ switch(events.ExecuteEvent())
+ {
+ case EVENT_PURSUE:
+ if (Creature* pKrick = GetKrick())
+ DoScriptText(RAND(SAY_KRICK_CHASE_1,SAY_KRICK_CHASE_2,SAY_KRICK_CHASE_3), pKrick);
+
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ me->Attack(pTarget,false);
+ DoScriptText(SAY_ICK_CHASE_1, me, pTarget);
+ DoCast(pTarget, SPELL_PURSUED);
+ }
+
+ DoCast(SPELL_CONFUSION);
+ events.ScheduleEvent(EVENT_PURSUE, 30000, GCD_1);
+ return;
+
+ case EVENT_MIGHTY_KICK:
+ DoCast(me->getVictim(), SPELL_MIGHTY_KICK);
+ events.ScheduleEvent(EVENT_MIGHTY_KICK, 25000, GCD_1);
+ return;
+
+ case EVENT_POISON_NOVA:
+ if (Creature* pKrick = GetKrick())
+ DoScriptText(SAY_KRICK_POISON_NOVA, pKrick);
+
+ DoScriptText(SAY_ICK_POISON_NOVA, me);
+ DoCastAOE(SPELL_POISON_NOVA);
+ events.ScheduleEvent(EVENT_POISON_NOVA, 30000, GCD_1);
+ return;
+
+ case EVENT_TOXIC_WASTE:
+ DoCast(me->getVictim(), SPELL_TOXIC_WASTE);
+ events.ScheduleEvent(EVENT_TOXIC_WASTE, 5000);
+ return;
+
+ case EVENT_SHADOW_BOLT:
+ DoCast(me->getVictim(), SPELL_SHADOW_BOLT);
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, 15000);
+ return;
+
+ case EVENT_EXPLOSIVE_BARRAGE:
+ if (Creature *pKrick = GetKrick())
+ {
+ DoScriptText(SAY_KRICK_BARRAGE_1, pKrick);
+ DoScriptText(SAY_KRICK_BARRAGE_2, pKrick);
+ }
+
+ DoCastAOE(SPELL_EXPLOSIVE_BARRAGE);
+ me->GetMotionMaster()->MoveIdle();
+ events.DelayEvents(20000, GCD_1); // 2 sec cast + 18 sec
+ events.ScheduleEvent(EVENT_END_EXPLOSIVE_BARRAGE, 20000);
+ return;
+
+ case EVENT_END_EXPLOSIVE_BARRAGE:
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+ events.ScheduleEvent(EVENT_EXPLOSIVE_BARRAGE, 25000);
+ break;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct boss_krickAI : public ScriptedAI
+{
+ boss_krickAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+ EventMap events;
+
+ KrickPhase phase;
+ uint64 uiNpcOutroDialog;
+ uint64 uiTyrannus;
+
+ void Reset()
+ {
+ uiNpcOutroDialog = 0;
+ uiTyrannus = 0;
+ phase = PHASE_COMBAT;
+
+ me->SetReactState(REACT_PASSIVE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetVisibility(VISIBILITY_OFF);
+ }
+
+ Creature* GetIck()
+ {
+ return me->GetCreature(*me, pInstance ? pInstance->GetData64(DATA_ICK) : 0);
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+
+ DoScriptText(RAND(SAY_KRICK_SLAY_1,SAY_KRICK_SLAY_2), me);
+ }
+
+ void DamageTaken(Unit * /*pDoneBy*/, uint32 &uiDamage)
+ {
+ // if killed whatever the reason, it breaks the outro
+ uiDamage = 0;
+ }
+
+ void DoAction(const int32 actionId)
+ {
+ switch(actionId)
+ {
+ case ACTION_OUTRO:
+ {
+ Position pos;
+ if (Creature* pIck = GetIck())
+ {
+ // TODO: tele on Ick then run some distance.
+ pIck->GetNearPosition(pos, 5.0f, 3.14);
+ me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), 0.0f);
+ }
+ me->SetVisibility(VISIBILITY_ON);
+
+ Creature* pJainaOrSylvanas = me->GetCreature(*me, pInstance->GetData64(DATA_JAINA_SYLVANAS_1));
+ if (pJainaOrSylvanas) {
+ Position pos;
+ me->GetNearPosition(pos, 5.0f, 0);
+ pJainaOrSylvanas->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(),
+ pos.GetAngle(me->GetPositionX(), me->GetPositionY()));
+ }
+ else {
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
+ pJainaOrSylvanas = me->SummonCreature(NPC_SYLVANAS_PART1, *me, TEMPSUMMON_MANUAL_DESPAWN);
+ else
+ pJainaOrSylvanas = me->SummonCreature(NPC_JAINA_PART1, *me, TEMPSUMMON_MANUAL_DESPAWN);
+ }
+
+ if (pJainaOrSylvanas)
+ {
+ pJainaOrSylvanas->SetOrientation(pJainaOrSylvanas->GetAngle(me->GetPositionX(), me->GetPositionY()));
+ me->SetOrientation(me->GetAngle(pJainaOrSylvanas->GetPositionX(), pJainaOrSylvanas->GetPositionY()));
+ uiNpcOutroDialog = pJainaOrSylvanas->GetGUID();
+ }
+
+ phase = PHASE_OUTRO;
+ events.Reset();
+ events.ScheduleEvent(EVENT_OUTRO_1, 1000);
+ break;
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (phase == PHASE_OUTRO)
+ {
+ if (!pInstance)
+ return;
+
+ events.Update(diff);
+ switch(events.ExecuteEvent())
+ {
+ case EVENT_OUTRO_1:
+ {
+ DoScriptText(SAY_KRICK_OUTRO_1, me);
+ events.ScheduleEvent(EVENT_OUTRO_2, 14000);
+ break;
+ }
+ case EVENT_OUTRO_2:
+ {
+ Creature* pNpcDialog = me->GetCreature(*me, uiNpcOutroDialog);
+ if (pNpcDialog)
+ {
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
+ DoScriptText(SAY_JAYNA_OUTRO_2, pNpcDialog);
+ else
+ DoScriptText(SAY_SYLVANAS_OUTRO_2, pNpcDialog);
+ }
+ events.ScheduleEvent(EVENT_OUTRO_3, 8500);
+ break;
+ }
+ case EVENT_OUTRO_3:
+ DoScriptText(SAY_KRICK_OUTRO_3, me);
+ events.ScheduleEvent(EVENT_OUTRO_4, 12000);
+ break;
+ case EVENT_OUTRO_4:
+ {
+ Creature* pNpcDialog = me->GetCreature(*me, uiNpcOutroDialog);
+ if (pNpcDialog)
+ {
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
+ DoScriptText(SAY_JAYNA_OUTRO_4, pNpcDialog);
+ else
+ DoScriptText(SAY_SYLVANAS_OUTRO_4, pNpcDialog);
+ }
+ events.ScheduleEvent(EVENT_OUTRO_5, 8000);
+ break;
+ }
+ case EVENT_OUTRO_5:
+ DoScriptText(SAY_KRICK_OUTRO_5, me);
+ events.ScheduleEvent(EVENT_OUTRO_6, 4000);
+ break;
+ case EVENT_OUTRO_6:
+ // TODO spawn Tyrannus at some distance and MovePoint near-by (flying on rimefang)
+ // store uiTyrannus
+ // Adjust timer so tyrannus has time to come
+ uiTyrannus = (pInstance ? pInstance->GetData64(DATA_TYRANNUS) : 0);
+ events.ScheduleEvent(EVENT_OUTRO_7, 1);
+ break;
+ case EVENT_OUTRO_7:
+ if (Creature *pTyrannus = me->GetCreature(*me, uiTyrannus))
+ DoScriptText(SAY_TYRANNUS_OUTRO_7, pTyrannus);
+ events.ScheduleEvent(EVENT_OUTRO_8, 7000);
+ break;
+ case EVENT_OUTRO_8:
+ DoScriptText(SAY_KRICK_OUTRO_8, me);
+ // TODO: Tyrannus starts killing Krick.
+ // there shall be some visual spell effect
+ events.ScheduleEvent(EVENT_OUTRO_9, 6000);
+ break;
+ case EVENT_OUTRO_9:
+ // tyrannus kills krick
+ me->SetStandState(UNIT_STAND_STATE_DEAD);
+ me->SetHealth(0);
+
+ if (Creature *pTyrannus = me->GetCreature(*me, uiTyrannus))
+ DoScriptText(SAY_TYRANNUS_OUTRO_9, pTyrannus);
+
+ events.ScheduleEvent(EVENT_OUTRO_10, 12000);
+ break;
+ case EVENT_OUTRO_10:
+ {
+ Creature* pNpcDialog = me->GetCreature(*me, uiNpcOutroDialog);
+ if (pNpcDialog)
+ {
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
+ DoScriptText(SAY_JAYNA_OUTRO_10, pNpcDialog);
+ else
+ DoScriptText(SAY_SYLVANAS_OUTRO_10, pNpcDialog);
+ }
+
+ // End of OUTRO. for now...
+ events.ScheduleEvent(EVENT_OUTRO_END, 8000);
+ break;
+ }
+ case EVENT_OUTRO_END:
+ {
+ Creature* pNpcDialog = me->GetCreature(*me, uiNpcOutroDialog);
+ if (pNpcDialog)
+ pNpcDialog->DisappearAndDie();
+
+ me->DisappearAndDie();
+ break;
+ }
+ }
+ return;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_ick(Creature* pCreature)
+{
+ return new boss_ickAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_krick(Creature* pCreature)
+{
+ return new boss_krickAI(pCreature);
+}
+
+void AddSC_boss_ick()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_ick";
+ newscript->GetAI = &GetAI_boss_ick;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_krick";
+ newscript->GetAI = &GetAI_boss_krick;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp
new file mode 100644
index 00000000000..55ffa0b4e4b
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp
@@ -0,0 +1,273 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "pit_of_saron.h"
+
+/*
+ * SDComment: TODO:
+ * - implement aura for spell Overlord Brand.
+ * - Intro/Outro
+ * - improve script of Rimefang
+ */
+
+enum Yells
+{
+ SAY_AMBUSH_1 = -1658050,
+ SAY_AMBUSH_2 = -1658051,
+ SAY_GAUNTLET_START = -1658052,
+ SAY_INTRO_1 = -1658053,
+ SAY_INTRO_2 = -1658054,
+
+ SAY_AGGRO = -1658055,
+ SAY_SLAY_1 = -1658056,
+ SAY_SLAY_2 = -1658057,
+ SAY_DEATH = -1658058,
+ SAY_MARK_RIMEFANG_1 = -1658059,
+ SAY_MARK_RIMEFANG_2 = -1658060,
+ SAY_DARK_MIGHT_1 = -1658061,
+ SAY_DARK_MIGHT_2 = -1658062,
+
+ SAY_GORKUN_OUTRO_1 = -1658063,
+ SAY_GORKUN_OUTRO_2 = -1658064,
+ SAY_JAYNA_OUTRO_3 = -1658065,
+ SAY_SYLVANAS_OUTRO_3 = -1658066,
+ SAY_JAYNA_OUTRO_4 = -1658067,
+ SAY_SYLVANAS_OUTRO_4 = -1658068,
+ SAY_JAYNA_OUTRO_5 = -1658069,
+};
+
+enum Spells
+{
+ SPELL_FORCEFUL_SMASH = 69155,
+ H_SPELL_FORCEFUL_SMASH = 69627,
+ SPELL_OVERLORDS_BRAND = 69172,
+ SPELL_DARK_MIGHT = 69167,
+ H_SPELL_DARK_MIGHT = 69629,
+ SPELL_HOARFROST = 69246,
+ SPELL_MARK_OF_RIMEFANG = 69275,
+ SPELL_ICY_BLAST = 69233,
+ H_SPELL_ICY_BLAST = 69646,
+ SPELL_ICY_BLAST_2 = 69238,
+ H_SPELL_ICY_BLAST_2 = 69628,
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_FORCEFUL_SMASH,
+ EVENT_OVERLORDS_BRAND,
+ EVENT_DARK_MIGHT,
+
+ // Rimefang
+ EVENT_MARK_OF_RIMEFANG,
+ EVENT_HOARFROST,
+ EVENT_ICY_BLAST,
+ EVENT_ICY_BLAST_2,
+};
+
+enum Misc
+{
+ SEAT_TYRANNUS = 0
+};
+
+struct boss_tyrannusAI : public ScriptedAI
+{
+ boss_tyrannusAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+
+ if (pInstance)
+ pInstance->SetData(DATA_TYRANNUS_EVENT, NOT_STARTED);
+ }
+
+ Creature* GetRimefang()
+ {
+ return me->GetCreature(*me, pInstance->GetData64(DATA_RIMEFANG));
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ me->ExitVehicle();
+
+ // restore health if any damage done during intro
+ me->SetHealth(me->GetMaxHealth());
+
+ if (pInstance)
+ pInstance->SetData(DATA_TYRANNUS_EVENT, IN_PROGRESS);
+
+ events.ScheduleEvent(EVENT_FORCEFUL_SMASH, 10000);
+ events.ScheduleEvent(EVENT_OVERLORDS_BRAND, 35000);
+ events.ScheduleEvent(EVENT_DARK_MIGHT, 40000);
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_TYRANNUS_EVENT, DONE);
+ if (Creature* pRimefang = GetRimefang())
+ pRimefang->ForcedDespawn();
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_FORCEFUL_SMASH:
+ DoCast(me->getVictim(), SPELL_FORCEFUL_SMASH);
+ events.ScheduleEvent(EVENT_FORCEFUL_SMASH, 10000);
+ return;
+ case EVENT_OVERLORDS_BRAND:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_OVERLORDS_BRAND);
+ events.ScheduleEvent(EVENT_OVERLORDS_BRAND, 45000);
+ return;
+ case EVENT_DARK_MIGHT:
+ DoScriptText(SAY_DARK_MIGHT_1, me);
+ DoScriptText(SAY_DARK_MIGHT_2, me);
+ DoCast(me, SPELL_DARK_MIGHT);
+ events.ScheduleEvent(EVENT_DARK_MIGHT, 60000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct boss_rimefangAI : public ScriptedAI
+{
+ boss_rimefangAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+ EventMap events;
+
+ void Reset()
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ me->InterruptSpell(CURRENT_GENERIC_SPELL);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
+ me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ me->InterruptSpell(CURRENT_GENERIC_SPELL);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
+ me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ events.ScheduleEvent(EVENT_MARK_OF_RIMEFANG, 25000);
+ events.ScheduleEvent(EVENT_ICY_BLAST, 35000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_MARK_OF_RIMEFANG:
+ DoScriptText(SAY_MARK_RIMEFANG_1, me);
+ DoScriptText(SAY_MARK_RIMEFANG_2, me);
+
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_MARK_OF_RIMEFANG);
+ events.ScheduleEvent(EVENT_HOARFROST, 5000);
+ return;
+ case EVENT_HOARFROST:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_HOARFROST);
+ events.ScheduleEvent(EVENT_MARK_OF_RIMEFANG, 20000);
+ return;
+ case EVENT_ICY_BLAST:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_ICY_BLAST);
+ events.ScheduleEvent(EVENT_ICY_BLAST_2, 5000);
+ return;
+ case EVENT_ICY_BLAST_2:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget->getVictim(), SPELL_ICY_BLAST_2);
+ events.ScheduleEvent(EVENT_ICY_BLAST, 30000);
+ return;
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_tyrannus(Creature* pCreature)
+{
+ return new boss_tyrannusAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_rimefang(Creature* pCreature)
+{
+ return new boss_rimefangAI(pCreature);
+}
+
+void AddSC_boss_tyrannus()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="boss_tyrannus";
+ newscript->GetAI = &GetAI_boss_tyrannus;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="boss_rimefang";
+ newscript->GetAI = &GetAI_boss_rimefang;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp b/src/server/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp
new file mode 100644
index 00000000000..8512eca24c1
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp
@@ -0,0 +1,236 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "pit_of_saron.h"
+
+#define MAX_ENCOUNTER 3
+
+/* Pit of Saron encounters:
+0- Forgemaster Garfrost
+1- Krick and Ick
+2- Scourgelord Tyrannus
+*/
+
+struct instance_pit_of_saron : public ScriptedInstance
+{
+ instance_pit_of_saron(Map* pMap) : ScriptedInstance(pMap) {};
+
+ uint64 uiKrick;
+ uint64 uiIck;
+ uint64 uiGarfrost;
+ uint64 uiTyrannus;
+ uint64 uiRimefang;
+
+ uint64 uiJainaOrSylvanas1;
+ uint64 uiJainaOrSylvanas2;
+
+ uint32 uiTeamInInstance;
+ uint32 uiEncounter[MAX_ENCOUNTER];
+
+ void Initialize()
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ uiEncounter[i] = NOT_STARTED;
+
+ uiGarfrost = 0;
+ uiKrick = 0;
+ uiIck = 0;
+ uiTyrannus = 0;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (uiEncounter[i] == IN_PROGRESS)
+ return true;
+
+ return false;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool /*add*/)
+ {
+ Map::PlayerList const &players = instance->GetPlayers();
+
+ if (!players.isEmpty())
+ {
+ if (Player* pPlayer = players.begin()->getSource())
+ uiTeamInInstance = pPlayer->GetTeam();
+ }
+
+ switch(pCreature->GetEntry())
+ {
+ case CREATURE_KRICK:
+ uiKrick = pCreature->GetGUID();
+ break;
+
+ case CREATURE_ICK:
+ uiIck = pCreature->GetGUID();
+ break;
+
+ case CREATURE_GARFROST:
+ uiGarfrost = pCreature->GetGUID();
+ break;
+
+ case CREATURE_TYRANNUS:
+ uiTyrannus = pCreature->GetGUID();
+ break;
+
+ case CREATURE_RIMEFANG:
+ uiRimefang = pCreature->GetGUID();
+ break;
+
+ case NPC_SYLVANAS_PART1:
+ if (uiTeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_JAINA_PART1, ALLIANCE);
+ uiJainaOrSylvanas1 = pCreature->GetGUID();
+ break;
+ case NPC_SYLVANAS_PART2:
+ if (uiTeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_JAINA_PART2, ALLIANCE);
+ uiJainaOrSylvanas2 = pCreature->GetGUID();
+ break;
+ case NPC_KILARA:
+ if (uiTeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_ELANDRA, ALLIANCE);
+ break;
+ case NPC_KORALEN:
+ if (uiTeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_KORLAEN, ALLIANCE);
+ break;
+ case NPC_CHAMPION_1_HORDE:
+ if (uiTeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_CHAMPION_1_ALLIANCE, ALLIANCE);
+ break;
+ case NPC_CHAMPION_2_HORDE:
+ if (uiTeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_CHAMPION_2_ALLIANCE, ALLIANCE);
+ break;
+ case NPC_CHAMPION_3_HORDE: // No 3rd set for Alliance?
+ if (uiTeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_CHAMPION_2_ALLIANCE, ALLIANCE);
+ break;
+ }
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_GARFROST: return uiGarfrost;
+ case DATA_KRICK: return uiKrick;
+ case DATA_ICK: return uiIck;
+ case DATA_TYRANNUS: return uiTyrannus;
+ case DATA_RIMEFANG: return uiRimefang;
+
+ case DATA_JAINA_SYLVANAS_1: return uiJainaOrSylvanas1;
+ case DATA_JAINA_SYLVANAS_2: return uiJainaOrSylvanas2;
+ }
+
+ return 0;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_GARFROST_EVENT:
+ uiEncounter[0] = data;
+ break;
+ case DATA_TYRANNUS_EVENT:
+ uiEncounter[1] = data;
+ break;
+ case DATA_KRICKANDICK_EVENT:
+ uiEncounter[2] = data;
+ break;
+ }
+
+ if (data == DONE)
+ SaveToDB();
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_GARFROST_EVENT: return uiEncounter[0];
+ case DATA_TYRANNUS_EVENT: return uiEncounter[1];
+ case DATA_KRICKANDICK_EVENT: return uiEncounter[2];
+ }
+
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::string str_data;
+
+ std::ostringstream saveStream;
+ saveStream << "P S " << uiEncounter[0] << " " << uiEncounter[1] << " " << uiEncounter[2];
+
+ str_data = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return str_data;
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0, data1, data2;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2;
+
+ if (dataHead1 == 'P' && dataHead2 == 'S')
+ {
+ uiEncounter[0] = data0;
+ uiEncounter[1] = data1;
+ uiEncounter[2] = data2;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (uiEncounter[i] == IN_PROGRESS)
+ uiEncounter[i] = NOT_STARTED;
+
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_pit_of_saron(Map* pMap)
+{
+ return new instance_pit_of_saron(pMap);
+}
+
+void AddSC_instance_pit_of_saron()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_pit_of_saron";
+ newscript->GetInstanceData = &GetInstanceData_instance_pit_of_saron;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp b/src/server/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp
new file mode 100644
index 00000000000..bc53efc7033
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp
@@ -0,0 +1,1101 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "pit_of_saron.h"
+
+/***************************************SPELLS*************************************/
+// Ymirjar Wrathbringer
+#define SPELL_BLIGHT DUNGEON_MODE(69603,70285)
+
+//Ymirjar Skycaller
+#define SPELL_FROSTBLADE 70291
+#define SPELL_GLACIAL_STRIKE 70292
+
+//Ymirjar Flamebearer
+#define SPELL_FIREBALL DUNGEON_MODE(69583,70282)
+#define SPELL_HELLFIRE DUNGEON_MODE(69586,70283)
+#define SPELL_TACTICAL_BLINK 69584
+
+//Ymirjar Deathbringer
+#define SPELL_EMPOWERED_SHADOW_BOLT DUNGEON_MODE(69528,70281)
+#define SPELL_SUMMON_UNDEAD 69516
+
+//Wrathbone Laborer
+#define SPELL_BLINDING_DIRT 70302
+#define SPELL_PUNCTURE_WOUND DUNGEON_MODE(70278,70279)
+#define SPELL_SHOVELLED DUNGEON_MODE(69572,70280)
+
+//Wrathbone Coldwraith
+#define SPELL_FREEZING_CIRCLE DUNGEON_MODE(69574,70276)
+#define SPELL_FROSTBOLT DUNGEON_MODE(69573,70277)
+
+//Stonespine Gargoyle
+#define SPELL_GARGOYLE_STRIKE DUNGEON_MODE(69520,70275)
+#define SPELL_STONEFORM 69575
+
+// Plagueborn Horror
+#define SPELL_BLIGHT_BOMB 69582
+#define SPELL_PUSTULANT_FLESH DUNGEON_MODE(69581,70273)
+#define SPELL_TOXIC_WASTE 70274
+
+//Iceborn Proto-Drake
+#define SPELL_FROST_BREATH DUNGEON_MODE(69527,70272)
+
+//Hungering Ghoul
+#define SPELL_DEVOUR_FLESH 70393
+
+//Fallen Warrior
+#define SPELL_ARCING_SLICE 69579
+#define SPELL_DEMORALIZING_SHOUT 61044
+#define SPELL_SHIELD_BLOCK 69580
+
+//Deathwhisper Torturer
+#define SPELL_BLACK_BRAND 70392
+#define SPELL_CURSE_OF_AGONY 70391
+
+//Deathwhisper Shadowcaster
+#define SPELL_SHADOW_BOLT DUNGEON_MODE(70386,70387)
+
+//Deathwhisper Necrolyte
+#define SPELL_CONVERSION_BEAM DUNGEON_MODE(69578,70269)
+#define SPELL_SHADOW_BOLT_2 DUNGEON_MODE(69577,70270)
+
+//Wrathbone Sorcerer
+#define SPELL_SHADOW_BOLT_3 DUNGEON_MODE(70386,70387)
+
+//Geist Ambusher
+#define SPELL_LEAPING_FACE_MAUL DUNGEON_MODE(69504,70271)
+
+/****************************************EVENTS************************************/
+enum eEvents
+{
+ EVENT_NONE,
+
+ // Ymirjar Wrathbringer
+ EVENT_BLIGHT,
+
+ // Ymirjar Skycaller
+ EVENT_FROSTBLADE,
+ EVENT_GLACIAL_STRIKE,
+
+ // Ymirjar Flamebearer
+ EVENT_FIREBALL,
+ EVENT_HELLFIRE,
+ EVENT_TACTICAL_BLINK,
+
+ //Ymirjar Deathbringer
+ EVENT_EMPOWERED_SHADOW_BOLT,
+ EVENT_SUMMON_UNDEAD,
+
+ //Wrathbone Laborer
+ EVENT_BLINDING_DIRT,
+ EVENT_PUNCTURE_WOUND,
+ EVENT_SHOVELLED,
+
+ //Wrathbone Coldwraith
+ EVENT_FREEZING_CIRCLE,
+ EVENT_FROSTBOLT,
+
+ //Stonespine Gargoyle
+ EVENT_GARGOYLE_STRIKE,
+ EVENT_STONEFORM,
+
+ //Plagueborn Horror
+ EVENT_BLIGHT_BOMB,
+ EVENT_PUSTULANT_FLESH,
+ EVENT_TOXIC_WASTE,
+
+ //Iceborn Proto-Drake
+ EVENT_FROST_BREATH,
+
+ //Hungering Ghoul
+ EVENT_DEVOUR_FLESH,
+
+ //Fallen Warrior
+ EVENT_ARCING_SLICE,
+ EVENT_DEMORALIZING_SHOUT,
+ EVENT_SHIELD_BLOCK,
+
+ //Deathwhisper Torturer
+ EVENT_BLACK_BRAND,
+ EVENT_CURSE_OF_AGONY,
+
+ //Deathwhisper Shadowcaster
+ EVENT_SHADOW_BOLT,
+
+ //Deathwhisper Necrolyte
+ EVENT_CONVERSION_BEAM,
+ EVENT_SHADOW_BOLT_2,
+
+ EVENT_SHADOW_BOLT_3,
+
+ //Geist Ambusher
+ EVENT_LEAPING_FACE_MAUL,
+};
+
+/****************************************AI****************************************/
+struct mob_ymirjar_wrathbringerAI : public ScriptedAI
+{
+ mob_ymirjar_wrathbringerAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_BLIGHT, 7000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_BLIGHT:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_BLIGHT);
+ events.RescheduleEvent(EVENT_BLIGHT, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_ymirjar_skyCallerAI: public ScriptedAI
+{
+ mob_ymirjar_skyCallerAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_FROSTBLADE, 1);
+ events.ScheduleEvent(EVENT_GLACIAL_STRIKE, 8000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_GLACIAL_STRIKE:
+ DoCast(me->getVictim(), SPELL_GLACIAL_STRIKE);
+ events.RescheduleEvent(EVENT_GLACIAL_STRIKE, 8000);
+ return;
+ case EVENT_FROSTBLADE:
+ DoCast(me, SPELL_FROSTBLADE);
+ events.CancelEvent(EVENT_FROSTBLADE);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_ymirjar_flamebearerAI: public ScriptedAI
+{
+ mob_ymirjar_flamebearerAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_FIREBALL, 4000);
+ events.ScheduleEvent(EVENT_HELLFIRE, 8000);
+ events.ScheduleEvent(EVENT_TACTICAL_BLINK, 15000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_FIREBALL:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_FIREBALL);
+ events.RescheduleEvent(EVENT_FIREBALL, 5000);
+ return;
+ case EVENT_HELLFIRE:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_HELLFIRE);
+ events.RescheduleEvent(EVENT_HELLFIRE, 10000);
+ return;
+ case EVENT_TACTICAL_BLINK:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_TACTICAL_BLINK);
+ events.RescheduleEvent(EVENT_TACTICAL_BLINK, 12000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_ymirjar_deathbringerAI: public ScriptedAI
+{
+ mob_ymirjar_deathbringerAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_EMPOWERED_SHADOW_BOLT, 8000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_EMPOWERED_SHADOW_BOLT:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_EMPOWERED_SHADOW_BOLT);
+ events.RescheduleEvent(EVENT_EMPOWERED_SHADOW_BOLT, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_wrathbone_laborerAI: public ScriptedAI
+{
+ mob_wrathbone_laborerAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_BLINDING_DIRT, 8000);
+ events.ScheduleEvent(EVENT_PUNCTURE_WOUND, 9000);
+ events.ScheduleEvent(EVENT_SHOVELLED, 5000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_BLINDING_DIRT:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_BLINDING_DIRT);
+ events.RescheduleEvent(EVENT_BLINDING_DIRT, 10000);
+ return;
+ case EVENT_PUNCTURE_WOUND:
+ DoCast(me->getVictim(), SPELL_PUNCTURE_WOUND);
+ events.RescheduleEvent(EVENT_PUNCTURE_WOUND, 9000);
+ return;
+ case EVENT_SHOVELLED:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SHOVELLED);
+ events.RescheduleEvent(EVENT_SHOVELLED, 7000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_wrathbone_coldwraithAI: public ScriptedAI
+{
+ mob_wrathbone_coldwraithAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_FREEZING_CIRCLE, 9000);
+ events.ScheduleEvent(EVENT_FROSTBOLT, 5000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_FREEZING_CIRCLE:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_FREEZING_CIRCLE);
+ events.RescheduleEvent(EVENT_FREEZING_CIRCLE, 9000);
+ return;
+ case EVENT_FROSTBOLT:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_FROSTBOLT);
+ events.RescheduleEvent(EVENT_FROSTBOLT, 5000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_stonespine_gargoyleAI: public ScriptedAI
+{
+ mob_stonespine_gargoyleAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_GARGOYLE_STRIKE, 5000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_GARGOYLE_STRIKE:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_GARGOYLE_STRIKE);
+ events.RescheduleEvent(EVENT_GARGOYLE_STRIKE, 6000);
+ return;
+ case EVENT_STONEFORM:
+ if (HealthBelowPct(10))
+ DoCast(me, SPELL_STONEFORM);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_plagueborn_horrorAI: public ScriptedAI
+{
+ mob_plagueborn_horrorAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_BLIGHT_BOMB, 999999);
+ events.ScheduleEvent(EVENT_PUSTULANT_FLESH, 5000);
+ events.ScheduleEvent(EVENT_TOXIC_WASTE, 8000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_BLIGHT_BOMB:
+ if (HealthBelowPct(15))
+ DoCast(me, SPELL_BLIGHT_BOMB);
+ return;
+ case EVENT_PUSTULANT_FLESH:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_PUSTULANT_FLESH);
+ events.RescheduleEvent(EVENT_PUSTULANT_FLESH, 10000);
+ return;
+ case EVENT_TOXIC_WASTE:
+ DoCast(me, SPELL_TOXIC_WASTE);
+ events.RescheduleEvent(EVENT_TOXIC_WASTE, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_iceborn_protodrakeAI: public ScriptedAI
+{
+ mob_iceborn_protodrakeAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_FROST_BREATH, 5000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_FROST_BREATH:
+ DoCast(me->getVictim(), SPELL_FROST_BREATH);
+ events.RescheduleEvent(EVENT_FROST_BREATH, 10000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_hungering_ghoulAI: public ScriptedAI
+{
+ mob_hungering_ghoulAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_DEVOUR_FLESH, 4000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_DEVOUR_FLESH:
+ DoCast(me->getVictim(), SPELL_DEVOUR_FLESH);
+ events.RescheduleEvent(EVENT_DEVOUR_FLESH, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_fallen_warriorAI: public ScriptedAI
+{
+ mob_fallen_warriorAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_ARCING_SLICE, 8000);
+ events.ScheduleEvent(EVENT_DEMORALIZING_SHOUT, 20000);
+ events.ScheduleEvent(EVENT_SHIELD_BLOCK, 8000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_ARCING_SLICE:
+ DoCast(me->getVictim(), SPELL_ARCING_SLICE);
+ events.RescheduleEvent(EVENT_ARCING_SLICE, 10000);
+ return;
+ case EVENT_DEMORALIZING_SHOUT:
+ DoCast(me, SPELL_DEMORALIZING_SHOUT);
+ events.RescheduleEvent(EVENT_DEMORALIZING_SHOUT, 20000);
+ return;
+ case EVENT_SHIELD_BLOCK:
+ DoCast(me->getVictim(), SPELL_SHIELD_BLOCK);
+ events.RescheduleEvent(EVENT_SHIELD_BLOCK, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_deathwhisper_torturerAI: public ScriptedAI
+{
+ mob_deathwhisper_torturerAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_BLACK_BRAND, 10000);
+ events.ScheduleEvent(EVENT_CURSE_OF_AGONY, 6000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_BLACK_BRAND:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_BLACK_BRAND);
+ events.RescheduleEvent(EVENT_BLACK_BRAND, 10000);
+ return;
+ case EVENT_CURSE_OF_AGONY:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_CURSE_OF_AGONY);
+ events.RescheduleEvent(EVENT_CURSE_OF_AGONY, 13000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_deathwhisper_shadowcasterAI: public ScriptedAI
+{
+ mob_deathwhisper_shadowcasterAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, 3000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SHADOW_BOLT:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SHADOW_BOLT);
+ events.RescheduleEvent(EVENT_SHADOW_BOLT, 5000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_deathwhisper_necrolyteAI: public ScriptedAI
+{
+ mob_deathwhisper_necrolyteAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_CONVERSION_BEAM, 12000);
+ events.ScheduleEvent(EVENT_SHADOW_BOLT_2, 4000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_CONVERSION_BEAM:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_CONVERSION_BEAM);
+ events.RescheduleEvent(EVENT_CONVERSION_BEAM, 12000);
+ return;
+ case EVENT_SHADOW_BOLT_2:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SHADOW_BOLT_2);
+ events.RescheduleEvent(EVENT_SHADOW_BOLT_2, 5000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_wrathbone_sorcererAI: public ScriptedAI
+{
+ mob_wrathbone_sorcererAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SHADOW_BOLT_3, 3000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SHADOW_BOLT_3:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SHADOW_BOLT_3);
+ events.RescheduleEvent(EVENT_SHADOW_BOLT_3, 5000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_geist_ambusherAI: public ScriptedAI
+{
+ mob_geist_ambusherAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ //Only here so when I figure out how to make it cast on an NPC i can do that.
+ events.ScheduleEvent(EVENT_LEAPING_FACE_MAUL, 99999);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ //Should only be used on NPCs
+ case EVENT_LEAPING_FACE_MAUL:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_LEAPING_FACE_MAUL);
+ events.CancelEvent(EVENT_LEAPING_FACE_MAUL);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_ymirjar_wrathbringerAI(Creature* pCreature)
+{
+ return new mob_ymirjar_wrathbringerAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_ymirjar_skyCallerAI(Creature* pCreature)
+{
+ return new mob_ymirjar_skyCallerAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_ymirjar_flamebearerAI(Creature* pCreature)
+{
+ return new mob_ymirjar_flamebearerAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_ymirjar_deathbringerAI(Creature* pCreature)
+{
+ return new mob_ymirjar_deathbringerAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_wrathbone_laborerAI(Creature* pCreature)
+{
+ return new mob_wrathbone_laborerAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_wrathbone_coldwraithAI(Creature* pCreature)
+{
+ return new mob_wrathbone_coldwraithAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_stonespine_gargoyleAI(Creature* pCreature)
+{
+ return new mob_stonespine_gargoyleAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_plagueborn_horrorAI(Creature* pCreature)
+{
+ return new mob_plagueborn_horrorAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_iceborn_protodrakeAI(Creature* pCreature)
+{
+ return new mob_iceborn_protodrakeAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_hungering_ghoulAI(Creature* pCreature)
+{
+ return new mob_hungering_ghoulAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_fallen_warriorAI(Creature* pCreature)
+{
+ return new mob_fallen_warriorAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_deathwhisper_torturerAI(Creature* pCreature)
+{
+ return new mob_deathwhisper_torturerAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_deathwhisper_shadowcasterAI(Creature* pCreature)
+{
+ return new mob_deathwhisper_shadowcasterAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_deathwhisper_necrolyteAI(Creature* pCreature)
+{
+ return new mob_deathwhisper_necrolyteAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_wrathbone_sorcererAI(Creature* pCreature)
+{
+ return new mob_wrathbone_sorcererAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_geist_ambusherAI(Creature* pCreature)
+{
+ return new mob_geist_ambusherAI(pCreature);
+}
+
+void AddSC_pit_of_saron()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="mob_ymirjar_wrathbringer";
+ newscript->GetAI = &GetAI_mob_ymirjar_wrathbringerAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_ymirjar_skycaller";
+ newscript->GetAI = &GetAI_mob_ymirjar_skyCallerAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_ymirjar_flamebearer";
+ newscript->GetAI = &GetAI_mob_ymirjar_flamebearerAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_ymirjar_deathbringer";
+ newscript->GetAI = &GetAI_mob_ymirjar_deathbringerAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_wrathbone_laborer";
+ newscript->GetAI = &GetAI_mob_wrathbone_laborerAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_wrathbone_coldwraith";
+ newscript->GetAI = &GetAI_mob_wrathbone_coldwraithAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_stonespine_gargoyle";
+ newscript->GetAI = &GetAI_mob_stonespine_gargoyleAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_plagueborn_horror";
+ newscript->GetAI = &GetAI_mob_plagueborn_horrorAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_iceborn_protodrake";
+ newscript->GetAI = &GetAI_mob_iceborn_protodrakeAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_hungering_ghoul";
+ newscript->GetAI = &GetAI_mob_hungering_ghoulAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_fallen_warrior";
+ newscript->GetAI = &GetAI_mob_fallen_warriorAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_deathwhisper_torturer";
+ newscript->GetAI = &GetAI_mob_deathwhisper_torturerAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_deathwhisper_shadowcaster";
+ newscript->GetAI = &GetAI_mob_deathwhisper_shadowcasterAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_deathwhisper_necrolyte";
+ newscript->GetAI = &GetAI_mob_deathwhisper_necrolyteAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_wrathbone_sorcerer";
+ newscript->GetAI = &GetAI_mob_wrathbone_sorcererAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_geist_ambusher";
+ newscript->GetAI = &GetAI_mob_geist_ambusherAI;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h b/src/server/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h
new file mode 100644
index 00000000000..4a221d17518
--- /dev/null
+++ b/src/server/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h
@@ -0,0 +1,63 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DEF_PIT_OF_SARON_H
+#define DEF_PIT_OF_SARON_H
+
+enum Data
+{
+ DATA_GARFROST_EVENT,
+ DATA_KRICKANDICK_EVENT,
+ DATA_TYRANNUS_EVENT,
+ DATA_TEAM_IN_INSTANCE,
+};
+
+enum Data64
+{
+ DATA_GARFROST,
+ DATA_KRICK,
+ DATA_ICK,
+ DATA_TYRANNUS,
+ DATA_RIMEFANG,
+
+ DATA_JAINA_SYLVANAS_1, // GUID of either Jaina or Sylvanas part 1, depending on team, as it's the same spawn.
+ DATA_JAINA_SYLVANAS_2, // GUID of either Jaina or Sylvanas part 2, depending on team, as it's the same spawn.
+};
+
+enum Creatures
+{
+ CREATURE_GARFROST = 36494,
+ CREATURE_KRICK = 36477,
+ CREATURE_ICK = 36476,
+ CREATURE_TYRANNUS = 36658,
+ CREATURE_RIMEFANG = 36661,
+
+ NPC_SYLVANAS_PART1 = 36990,
+ NPC_SYLVANAS_PART2 = 38189,
+ NPC_JAINA_PART1 = 36993,
+ NPC_JAINA_PART2 = 38188,
+ NPC_KILARA = 37583,
+ NPC_ELANDRA = 37774,
+ NPC_KORALEN = 37779,
+ NPC_KORLAEN = 37582,
+ NPC_CHAMPION_1_HORDE = 37584,
+ NPC_CHAMPION_2_HORDE = 37587,
+ NPC_CHAMPION_3_HORDE = 37588,
+ NPC_CHAMPION_1_ALLIANCE = 37496,
+ NPC_CHAMPION_2_ALLIANCE = 37497,
+};
+
+#endif
diff --git a/src/server/scripts/northrend/grizzly_hills.cpp b/src/server/scripts/northrend/grizzly_hills.cpp
new file mode 100644
index 00000000000..4b6d65a9764
--- /dev/null
+++ b/src/server/scripts/northrend/grizzly_hills.cpp
@@ -0,0 +1,625 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Grizzly_Hills
+SD%Complete: 80
+SDComment: Quest support: 12231, 12247
+SDCategory: Grizzly Hills
+EndScriptData */
+
+/* ContentData
+npc_orsonn_and_kodian
+EndContentData */
+
+#include "ScriptedPch.h"
+#include "ScriptedEscortAI.h"
+
+#define GOSSIP_ITEM1 "You're free to go Orsonn, but first tell me what's wrong with the furbolg."
+#define GOSSIP_ITEM2 "What happened then?"
+#define GOSSIP_ITEM3 "Thank you, Son of Ursoc. I'll see what can be done."
+#define GOSSIP_ITEM4 "Who was this stranger?"
+#define GOSSIP_ITEM5 "Thank you, Kodian. I'll do what I can."
+
+enum eEnums
+{
+ GOSSIP_TEXTID_ORSONN1 = 12793,
+ GOSSIP_TEXTID_ORSONN2 = 12794,
+ GOSSIP_TEXTID_ORSONN3 = 12796,
+
+ GOSSIP_TEXTID_KODIAN1 = 12797,
+ GOSSIP_TEXTID_KODIAN2 = 12798,
+
+ NPC_ORSONN = 27274,
+ NPC_KODIAN = 27275,
+
+ //trigger creatures
+ NPC_ORSONN_CREDIT = 27322,
+ NPC_KODIAN_CREDIT = 27321,
+
+ QUEST_CHILDREN_OF_URSOC = 12247,
+ QUEST_THE_BEAR_GODS_OFFSPRING = 12231
+};
+
+bool GossipHello_npc_orsonn_and_kodian(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_CHILDREN_OF_URSOC) == QUEST_STATUS_INCOMPLETE || pPlayer->GetQuestStatus(QUEST_THE_BEAR_GODS_OFFSPRING) == QUEST_STATUS_INCOMPLETE)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case NPC_ORSONN:
+ if (!pPlayer->GetReqKillOrCastCurrentCount(QUEST_CHILDREN_OF_URSOC, NPC_ORSONN_CREDIT) || !pPlayer->GetReqKillOrCastCurrentCount(QUEST_THE_BEAR_GODS_OFFSPRING, NPC_ORSONN_CREDIT))
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ORSONN1, pCreature->GetGUID());
+ return true;
+ }
+ break;
+ case NPC_KODIAN:
+ if (!pPlayer->GetReqKillOrCastCurrentCount(QUEST_CHILDREN_OF_URSOC, NPC_KODIAN_CREDIT) || !pPlayer->GetReqKillOrCastCurrentCount(QUEST_THE_BEAR_GODS_OFFSPRING, NPC_KODIAN_CREDIT))
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_KODIAN1, pCreature->GetGUID());
+ return true;
+ }
+ break;
+ }
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_orsonn_and_kodian(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ORSONN2, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ORSONN3, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+3:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->TalkedToCreature(NPC_ORSONN_CREDIT, pCreature->GetGUID());
+ break;
+
+ case GOSSIP_ACTION_INFO_DEF+4:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_KODIAN2, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+5:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->TalkedToCreature(NPC_KODIAN_CREDIT, pCreature->GetGUID());
+ break;
+ }
+
+ return true;
+}
+
+/*######
+## Quest 12027: Mr. Floppy's Perilous Adventure
+######*/
+
+enum eFloppy
+{
+ NPC_MRFLOPPY = 26589,
+ NPC_HUNGRY_WORG = 26586,
+ NPC_RAVENOUS_WORG = 26590, //RWORG
+ NPC_EMILY = 26588,
+
+ QUEST_PERILOUS_ADVENTURE = 12027,
+
+ SPELL_MRFLOPPY = 47184, //vehicle aura
+
+ SAY_WORGHAGGRO1 = -1800001, //Um... I think one of those wolves is back...
+ SAY_WORGHAGGRO2 = -1800002, //He's going for Mr. Floppy!
+ SAY_WORGRAGGRO3 = -1800003, //Oh, no! Look, it's another wolf, and it's a biiiiiig one!
+ SAY_WORGRAGGRO4 = -1800004, //He's gonna eat Mr. Floppy! You gotta help Mr. Floppy! You just gotta!
+ SAY_RANDOMAGGRO = -1800005, //There's a big meanie attacking Mr. Floppy! Help!
+ SAY_VICTORY1 = -1800006, //Let's get out of here before more wolves find us!
+ SAY_VICTORY2 = -1800007, //Don't go toward the light, Mr. Floppy!
+ SAY_VICTORY3 = -1800008, //Mr. Floppy, you're ok! Thank you so much for saving Mr. Floppy!
+ SAY_VICTORY4 = -1800009, //I think I see the camp! We're almost home, Mr. Floppy! Let's go!
+ TEXT_EMOTE_WP1 = -1800010, //Mr. Floppy revives
+ TEXT_EMOTE_AGGRO = -1800011, //The Ravenous Worg chomps down on Mr. Floppy
+ SAY_QUEST_ACCEPT = -1800012, //Are you ready, Mr. Floppy? Stay close to me and watch out for those wolves!
+ SAY_QUEST_COMPLETE = -1800013 //Thank you for helping me get back to the camp. Go tell Walter that I'm safe now!
+};
+
+//emily
+struct npc_emilyAI : public npc_escortAI
+{
+ npc_emilyAI(Creature* pCreature) : npc_escortAI(pCreature) { }
+
+ uint32 m_uiChatTimer;
+
+ uint64 RWORGGUID;
+ uint64 MrfloppyGUID;
+
+ bool Completed;
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ if (Creature* Mrfloppy = GetClosestCreatureWithEntry(me, NPC_MRFLOPPY, 50.0f))
+ pSummoned->AI()->AttackStart(Mrfloppy);
+ else
+ pSummoned->AI()->AttackStart(me->getVictim());
+ }
+
+ void WaypointReached(uint32 i)
+ {
+ Player* pPlayer = GetPlayerForEscort();
+ if (!pPlayer)
+ return;
+ switch (i)
+ {
+ case 9:
+ if (Creature *Mrfloppy = GetClosestCreatureWithEntry(me, NPC_MRFLOPPY, 100.0f))
+ MrfloppyGUID = Mrfloppy->GetGUID();
+ break;
+ case 10:
+ if (Creature *Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ {
+ DoScriptText(SAY_WORGHAGGRO1, me);
+ me->SummonCreature(NPC_HUNGRY_WORG,me->GetPositionX()+5,me->GetPositionY()+2,me->GetPositionZ()+1,3.229f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,120000);
+ }
+ break;
+ case 11:
+ if (Creature *Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ break;
+ case 17:
+ if (Creature *Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ Mrfloppy->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
+ DoScriptText(SAY_WORGRAGGRO3, me);
+ if (Creature *RWORG = me->SummonCreature(NPC_RAVENOUS_WORG,me->GetPositionX()+10,me->GetPositionY()+8,me->GetPositionZ()+2,3.229f,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,120000))
+ {
+ RWORG->setFaction(35);
+ RWORGGUID = RWORG->GetGUID();
+ }
+ break;
+ case 18:
+ if (Creature *Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ {
+ if (Creature *RWORG = Unit::GetCreature(*me, RWORGGUID))
+ RWORG->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ());
+ DoCast(Mrfloppy,SPELL_MRFLOPPY);
+ }
+ break;
+ case 19:
+ if (Creature *Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ {
+ if (Mrfloppy->HasAura(SPELL_MRFLOPPY, 0))
+ {
+ if (Creature *RWORG = Unit::GetCreature(*me, RWORGGUID))
+ Mrfloppy->EnterVehicle(RWORG);
+ }
+ }
+ break;
+ case 20:
+ if (Creature *RWORG = Unit::GetCreature(*me, RWORGGUID))
+ RWORG->HandleEmoteCommand(34);
+ break;
+ case 21:
+ if (Creature *Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ {
+ if (Creature *RWORG = Unit::GetCreature(*me, RWORGGUID))
+ {
+ RWORG->Kill(Mrfloppy);
+ Mrfloppy->ExitVehicle();
+ RWORG->setFaction(14);
+ RWORG->GetMotionMaster()->MovePoint(0, RWORG->GetPositionX()+10,RWORG->GetPositionY()+80,RWORG->GetPositionZ());
+ DoScriptText(SAY_VICTORY2, me);
+ }
+ }
+ break;
+ case 22:
+ if (Creature *Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ {
+ if (Mrfloppy->isDead())
+ {
+ if (Creature *RWORG = Unit::GetCreature(*me, RWORGGUID))
+ RWORG->DisappearAndDie();
+ me->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ());
+ Mrfloppy->setDeathState(ALIVE);
+ Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ DoScriptText(SAY_VICTORY3, me);
+ }
+ }
+ break;
+ case 24:
+ if (pPlayer)
+ {
+ Completed = true;
+ pPlayer->GroupEventHappens(QUEST_PERILOUS_ADVENTURE, me);
+ DoScriptText(SAY_QUEST_COMPLETE, me, pPlayer);
+ }
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ break;
+ case 25:
+ DoScriptText(SAY_VICTORY4, me);
+ break;
+ case 27:
+ me->DisappearAndDie();
+ if (Creature *Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ Mrfloppy->DisappearAndDie();
+ break;
+ }
+ }
+
+ void EnterCombat(Unit* /*Who*/)
+ {
+ DoScriptText(SAY_RANDOMAGGRO, me);
+ }
+
+ void Reset()
+ {
+ m_uiChatTimer = 4000;
+ MrfloppyGUID = 0;
+ RWORGGUID = 0;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ npc_escortAI::UpdateAI(uiDiff);
+
+ if (HasEscortState(STATE_ESCORT_ESCORTING))
+ {
+ if (m_uiChatTimer <= uiDiff)
+ {
+ m_uiChatTimer = 12000;
+ }
+ else
+ m_uiChatTimer -= uiDiff;
+ }
+ }
+};
+
+bool QuestAccept_npc_emily(Player* pPlayer, Creature* pCreature, Quest const* quest)
+{
+ if (quest->GetQuestId() == QUEST_PERILOUS_ADVENTURE)
+ {
+ DoScriptText(SAY_QUEST_ACCEPT, pCreature);
+ if (Creature* Mrfloppy = GetClosestCreatureWithEntry(pCreature, NPC_MRFLOPPY, 180.0f))
+ {
+ Mrfloppy->GetMotionMaster()->MoveFollow(pCreature, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ }
+
+ if (npc_escortAI* pEscortAI = CAST_AI(npc_emilyAI, (pCreature->AI())))
+ pEscortAI->Start(true, false, pPlayer->GetGUID());
+ }
+ return true;
+}
+
+CreatureAI* GetAI_npc_emily(Creature* pCreature)
+{
+ return new npc_emilyAI(pCreature);
+}
+
+//mrfloppy
+
+struct npc_mrfloppyAI : public ScriptedAI
+{
+ npc_mrfloppyAI(Creature *c) : ScriptedAI(c) {}
+
+ uint64 EmilyGUID;
+ uint64 RWORGGUID;
+ uint64 HWORGGUID;
+
+ void Reset() {}
+
+ void EnterCombat(Unit* Who)
+ {
+ if (Creature* Emily = GetClosestCreatureWithEntry(me, NPC_EMILY, 50.0f))
+ {
+ switch(Who->GetEntry())
+ {
+ case NPC_HUNGRY_WORG:
+ DoScriptText(SAY_WORGHAGGRO2, Emily);
+ break;
+ case NPC_RAVENOUS_WORG:
+ DoScriptText(SAY_WORGRAGGRO4, Emily);
+ break;
+ default:
+ DoScriptText(SAY_RANDOMAGGRO, Emily);
+ }
+ }
+ }
+
+ void EnterEvadeMode() {}
+
+ void MoveInLineOfSight(Unit * /*who*/) {}
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ if (!UpdateVictim())
+ return;
+ }
+};
+
+CreatureAI* GetAI_npc_mrfloppy(Creature* pCreature)
+{
+ return new npc_mrfloppyAI(pCreature);
+}
+
+// Outhouse Bunny
+
+enum eOuthouseBunny
+{
+ SPELL_OUTHOUSE_GROANS = 48382,
+ SPELL_CAMERA_SHAKE = 47533,
+ SPELL_DUST_FIELD = 48329
+};
+
+enum eSounds
+{
+ SOUND_FEMALE = 12671,
+ SOUND_MALE = 12670
+};
+struct npc_outhouse_bunnyAI : public ScriptedAI
+{
+ npc_outhouse_bunnyAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint8 m_counter;
+ uint8 m_gender;
+
+ void Reset()
+ {
+ m_counter = 0;
+ m_gender = 0;
+ }
+
+ void SetData(uint32 uiType, uint32 uiData)
+ {
+ if (uiType == 1)
+ m_gender = uiData;
+ }
+
+ void SpellHit(Unit* pCaster, const SpellEntry* pSpell)
+ {
+ if (pSpell->Id == SPELL_OUTHOUSE_GROANS)
+ {
+ ++m_counter;
+ if (m_counter < 5)
+ DoCast(pCaster, SPELL_CAMERA_SHAKE, true);
+ else
+ m_counter = 0;
+ DoCast(me, SPELL_DUST_FIELD, true);
+ switch (m_gender)
+ {
+ case GENDER_FEMALE: DoPlaySoundToSet(me, SOUND_FEMALE); break;
+ case GENDER_MALE: DoPlaySoundToSet(me, SOUND_MALE); break;
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_outhouse_bunny(Creature* pCreature)
+{
+ return new npc_outhouse_bunnyAI (pCreature);
+}
+
+// Tallhorn Stage
+
+enum etallhornstage
+{
+ OBJECT_HAUNCH = 188665
+};
+
+struct npc_tallhorn_stagAI : public ScriptedAI
+{
+ npc_tallhorn_stagAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint8 m_uiPhase;
+
+ void Reset()
+ {
+ m_uiPhase = 1;
+ }
+
+ void UpdateAI(const uint32 /*uiDiff*/)
+ {
+ if (m_uiPhase == 1)
+ {
+ if (GameObject* haunch = me->FindNearestGameObject(OBJECT_HAUNCH, 2.0f))
+ {
+ me->SetStandState(UNIT_STAND_STATE_DEAD);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
+ }
+ m_uiPhase = 0;
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_tallhorn_stag(Creature* pCreature)
+{
+ return new npc_tallhorn_stagAI (pCreature);
+}
+
+// Amberpine Woodsman
+
+enum eamberpinewoodsman
+{
+ TALLHORN_STAG = 26363
+};
+
+struct npc_amberpine_woodsmanAI : public ScriptedAI
+{
+ npc_amberpine_woodsmanAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint8 m_uiPhase;
+ uint32 m_uiTimer;
+
+ void Reset()
+ {
+ m_uiTimer = 0;
+ m_uiPhase = 1;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ // call this each update tick?
+ if (Creature* stag = me->FindNearestCreature(TALLHORN_STAG, 0.2f))
+ {
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USESTANDING);
+ }
+ else
+ if (m_uiPhase)
+ {
+ if (m_uiTimer <= uiDiff)
+ {
+ switch(m_uiPhase)
+ {
+ case 1:
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_LOOT);
+ m_uiTimer = 3000;
+ m_uiPhase = 2;
+ break;
+ case 2:
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACK1H);
+ m_uiTimer = 4000;
+ m_uiPhase = 1;
+ break;
+ }
+ }
+ else
+ m_uiTimer -= uiDiff;
+ }
+ ScriptedAI::UpdateAI(uiDiff);
+
+ UpdateVictim();
+ }
+};
+
+/*######
+## Quest 12288: Overwhelmed!
+######*/
+
+enum eSkirmisher
+{
+ SPELL_RENEW_SKIRMISHER = 48812,
+ CREDIT_NPC = 27466,
+
+ RANDOM_SAY_1 = -1800044, //Ahh..better..
+ RANDOM_SAY_2 = -1800045, //Whoa.. i nearly died there. Thank you, $Race!
+ RANDOM_SAY_3 = -1800046 //Thank you. $Class!
+};
+
+struct npc_wounded_skirmisherAI : public ScriptedAI
+{
+ npc_wounded_skirmisherAI(Creature *c) : ScriptedAI(c) {}
+
+ uint64 uiPlayerGUID;
+
+ uint32 DespawnTimer;
+
+ void Reset ()
+ {
+ DespawnTimer = 5000;
+ uiPlayerGUID = 0;
+ }
+
+ void MovementInform(uint32, uint32 id)
+ {
+ if (id == 1)
+ me->ForcedDespawn(DespawnTimer);
+ }
+
+ void SpellHit(Unit *caster, const SpellEntry *spell)
+ {
+ if (spell->Id == SPELL_RENEW_SKIRMISHER && caster->GetTypeId() == TYPEID_PLAYER
+ && caster->ToPlayer()->GetQuestStatus(12288) == QUEST_STATUS_INCOMPLETE)
+ {
+ caster->ToPlayer()->KilledMonsterCredit(CREDIT_NPC, 0);
+ DoScriptText(RAND(RANDOM_SAY_1,RANDOM_SAY_2,RANDOM_SAY_3),caster);
+ if(me->IsStandState())
+ me->GetMotionMaster()->MovePoint(1, me->GetPositionX()+7, me->GetPositionY()+7, me->GetPositionZ());
+ else
+ {
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ me->ForcedDespawn(DespawnTimer);
+ }
+
+ }
+ }
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ if (!UpdateVictim())
+ return;
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_wounded_skirmisher(Creature* pCreature)
+{
+ return new npc_wounded_skirmisherAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_amberpine_woodsman(Creature* pCreature)
+{
+ return new npc_amberpine_woodsmanAI (pCreature);
+}
+
+void AddSC_grizzly_hills()
+{
+ Script* newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_orsonn_and_kodian";
+ newscript->pGossipHello = &GossipHello_npc_orsonn_and_kodian;
+ newscript->pGossipSelect = &GossipSelect_npc_orsonn_and_kodian;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_emily";
+ newscript->GetAI = &GetAI_npc_emily;
+ newscript->pQuestAccept = &QuestAccept_npc_emily;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_mrfloppy";
+ newscript->GetAI = &GetAI_npc_mrfloppy;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_outhouse_bunny";
+ newscript->GetAI = &GetAI_npc_outhouse_bunny;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_tallhorn_stag";
+ newscript->GetAI = &GetAI_npc_tallhorn_stag;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_amberpine_woodsman";
+ newscript->GetAI = &GetAI_npc_amberpine_woodsman;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_wounded_skirmisher";
+ newscript->GetAI = &GetAI_npc_wounded_skirmisher;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/gundrak/boss_drakkari_colossus.cpp b/src/server/scripts/northrend/gundrak/boss_drakkari_colossus.cpp
new file mode 100644
index 00000000000..04603c68813
--- /dev/null
+++ b/src/server/scripts/northrend/gundrak/boss_drakkari_colossus.cpp
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Comment: The event with the Living Mojos is not implemented, just is done that when one of the mojos around the boss take damage will make the boss enter in combat!
+ */
+
+#include "ScriptedPch.h"
+#include "gundrak.h"
+
+enum Spells
+{
+ SPELL_EMERGE = 54850,
+ SPELL_MIGHTY_BLOW = 54719,
+ SPELL_MERGE = 54878,
+ SPELL_SURGE = 54801,
+ SPELL_FREEZE_ANIM = 16245,
+ SPELL_MOJO_PUDDLE = 55627,
+ H_SPELL_MOJO_PUDDLE = 58994,
+ SPELL_MOJO_WAVE = 55626,
+ H_SPELL_MOJO_WAVE = 58993
+};
+
+struct boss_drakkari_colossusAI : public ScriptedAI
+{
+ boss_drakkari_colossusAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ bool bHealth;
+ bool bHealth1;
+
+ uint32 MightyBlowTimer;
+
+ void Reset()
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_DRAKKARI_COLOSSUS_EVENT, NOT_STARTED);
+ if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE))
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->clearUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT);
+ me->SetReactState(REACT_PASSIVE);
+ MightyBlowTimer = 10*IN_MILISECONDS;
+ bHealth = false;
+ bHealth1 = false;
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_DRAKKARI_COLOSSUS_EVENT, IN_PROGRESS);
+ }
+
+ void CreatureState(Creature* pWho, bool bRestore = false)
+ {
+ if (!pWho)
+ return;
+
+ if (bRestore)
+ {
+ pWho->clearUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT);
+ pWho->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (pWho == me)
+ me->RemoveAura(SPELL_FREEZE_ANIM);
+ }else
+ {
+ pWho->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pWho->addUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT);
+ if (pWho == me)
+ DoCast(me,SPELL_FREEZE_ANIM);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (!bHealth && HealthBelowPct(50) && !HealthBelowPct(5))
+ {
+ CreatureState(me, false);
+ DoCast(me,SPELL_FREEZE_ANIM);
+ DoCast(me,SPELL_EMERGE);
+ bHealth = true;
+ }
+
+ if (!bHealth1 && HealthBelowPct(5))
+ {
+ DoCast(me,SPELL_EMERGE);
+ CreatureState(me, false);
+ bHealth1 = true;
+ me->RemoveAllAuras();
+ }
+
+ if (MightyBlowTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_MIGHTY_BLOW, true);
+ MightyBlowTimer = 10*IN_MILISECONDS;
+ } else MightyBlowTimer -= diff;
+
+ if (!me->hasUnitState(UNIT_STAT_STUNNED))
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_DRAKKARI_COLOSSUS_EVENT, DONE);
+ }
+
+ void JustSummoned(Creature* pSummon)
+ {
+ if (HealthBelowPct(5))
+ pSummon->DealDamage(pSummon, pSummon->GetHealth() * 0.5 , NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ pSummon->AI()->AttackStart(me->getVictim());
+ }
+};
+
+struct boss_drakkari_elementalAI : public ScriptedAI
+{
+ boss_drakkari_elementalAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiSurgeTimer;
+
+ bool bGoToColossus;
+
+ void Reset()
+ {
+ if (Creature *pColossus = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
+ CAST_AI(boss_drakkari_colossusAI, pColossus->AI())->CreatureState(me, true);
+ uiSurgeTimer = 7*IN_MILISECONDS;
+ bGoToColossus = false;
+ }
+
+ void EnterEvadeMode()
+ {
+ me->RemoveFromWorld();
+ }
+
+ void MovementInform(uint32 uiType, uint32 /*uiId*/)
+ {
+ if (uiType != POINT_MOTION_TYPE)
+ return;
+ if (Creature *pColossus = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
+ {
+ CAST_AI(boss_drakkari_colossusAI, pColossus->AI())->CreatureState(pColossus, true);
+ CAST_AI(boss_drakkari_colossusAI, pColossus->AI())->bHealth1 = false;
+ }
+ me->RemoveFromWorld();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (!bGoToColossus && HealthBelowPct(50))
+ {
+ if (Creature *pColossus = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
+ {
+ if (!CAST_AI(boss_drakkari_colossusAI,pColossus->AI())->HealthBelowPct(6))
+ {
+ me->InterruptNonMeleeSpells(true);
+ DoCast(pColossus, SPELL_MERGE);
+ bGoToColossus = true;
+ }
+ }
+ }
+
+ if (uiSurgeTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_SURGE);
+ uiSurgeTimer = 7*IN_MILISECONDS;
+ } else uiSurgeTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (Creature *pColossus = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
+ pColossus->Kill(pColossus);
+ }
+};
+
+struct npc_living_mojoAI : public ScriptedAI
+{
+ npc_living_mojoAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiMojoWaveTimer;
+ uint32 uiMojoPuddleTimer;
+
+ void Reset()
+ {
+ uiMojoWaveTimer = 2*IN_MILISECONDS;
+ uiMojoPuddleTimer = 7*IN_MILISECONDS;
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+
+ //Check if the npc is near of Drakkari Colossus.
+ if (Creature *pColossus = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
+ {
+ if (pColossus->isAlive() && me->IsInRange3d(pColossus->GetHomePosition().GetPositionX(),pColossus->GetHomePosition().GetPositionY(),pColossus->GetHomePosition().GetPositionZ(),0.0f,17.0f))
+ me->SetReactState(REACT_PASSIVE);
+ else
+ me->SetReactState(REACT_AGGRESSIVE);
+ }
+ }
+
+ void DamageTaken(Unit* pDone_by, uint32& /*uiDamage*/)
+ {
+ if (me->HasReactState(REACT_PASSIVE))
+ {
+ if (Creature *pColossus = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_DRAKKARI_COLOSSUS) : 0))
+ {
+ if (pColossus->isAlive() && !pColossus->isInCombat())
+ {
+ pColossus->RemoveAura(SPELL_FREEZE_ANIM);
+ pColossus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ pColossus->SetReactState(REACT_AGGRESSIVE);
+ if (pDone_by && pDone_by->isAlive())
+ pColossus->AI()->AttackStart(pDone_by);
+ EnterEvadeMode();
+ }
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiMojoWaveTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_MOJO_WAVE);
+ uiMojoWaveTimer = 15*IN_MILISECONDS;
+ } else uiMojoWaveTimer -= diff;
+
+ if (uiMojoPuddleTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_MOJO_PUDDLE);
+ uiMojoPuddleTimer = 18*IN_MILISECONDS;
+ } else uiMojoPuddleTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_drakkari_colossus(Creature* pCreature)
+{
+ return new boss_drakkari_colossusAI (pCreature);
+}
+
+CreatureAI* GetAI_boss_drakkari_elemental(Creature* pCreature)
+{
+ return new boss_drakkari_elementalAI (pCreature);
+}
+
+CreatureAI* GetAI_npc_living_mojo(Creature* pCreature)
+{
+ return new npc_living_mojoAI (pCreature);
+}
+
+void AddSC_boss_drakkari_colossus()
+{
+ Script* newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_drakkari_colossus";
+ newscript->GetAI = &GetAI_boss_drakkari_colossus;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_drakkari_elemental";
+ newscript->GetAI = &GetAI_boss_drakkari_elemental;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_living_mojo";
+ newscript->GetAI = &GetAI_npc_living_mojo;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/gundrak/boss_eck.cpp b/src/server/scripts/northrend/gundrak/boss_eck.cpp
new file mode 100644
index 00000000000..3bf1a33da5a
--- /dev/null
+++ b/src/server/scripts/northrend/gundrak/boss_eck.cpp
@@ -0,0 +1,168 @@
+/*
+* Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "gundrak.h"
+
+enum Spells
+{
+ SPELL_ECK_BERSERK = 55816, //Eck goes berserk, increasing his attack speed by 150% and all damage he deals by 500%.
+ SPELL_ECK_BITE = 55813, //Eck bites down hard, inflicting 150% of his normal damage to an enemy.
+ SPELL_ECK_SPIT = 55814, //Eck spits toxic bile at enemies in a cone in front of him, inflicting 2970 Nature damage and draining 220 mana every 1 sec for 3 sec.
+ SPELL_ECK_SPRING_1 = 55815, //Eck leaps at a distant target. --> Drops aggro and charges a random player. Tank can simply taunt him back.
+ SPELL_ECK_SPRING_2 = 55837 //Eck leaps at a distant target.
+};
+
+static Position EckSpawnPoint = { 1643.877930, 936.278015, 107.204948, 0.668432 };
+
+struct boss_eckAI : public ScriptedAI
+{
+ boss_eckAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiBerserkTimer;
+ uint32 uiBiteTimer;
+ uint32 uiSpitTimer;
+ uint32 uiSpringTimer;
+
+ bool bBerserk;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiBerserkTimer = urand(60*IN_MILISECONDS,90*IN_MILISECONDS); //60-90 secs according to wowwiki
+ uiBiteTimer = 5*IN_MILISECONDS;
+ uiSpitTimer = 10*IN_MILISECONDS;
+ uiSpringTimer = 8*IN_MILISECONDS;
+
+ bBerserk = false;
+
+ if (pInstance)
+ pInstance->SetData(DATA_ECK_THE_FEROCIOUS_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_ECK_THE_FEROCIOUS_EVENT, IN_PROGRESS);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiBiteTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_ECK_BITE);
+ uiBiteTimer = urand(8*IN_MILISECONDS,12*IN_MILISECONDS);
+ } else uiBiteTimer -= diff;
+
+ if (uiSpitTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_ECK_SPIT);
+ uiSpitTimer = urand(6*IN_MILISECONDS,14*IN_MILISECONDS);
+ } else uiSpitTimer -= diff;
+
+ if (uiSpringTimer <= diff)
+ {
+ Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,1);
+ if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER)
+ {
+ DoCast(pTarget, RAND(SPELL_ECK_SPRING_1, SPELL_ECK_SPRING_2));
+ uiSpringTimer = urand(5*IN_MILISECONDS,10*IN_MILISECONDS);
+ }
+ } else uiSpringTimer -= diff;
+
+ //Berserk on timer or 20% of health
+ if (!bBerserk)
+ {
+ if (uiBerserkTimer <= diff)
+ {
+ DoCast(me, SPELL_ECK_BERSERK);
+ bBerserk = true;
+ }
+ else
+ {
+ uiBerserkTimer -= diff;
+ if (HealthBelowPct(20))
+ {
+ DoCast(me, SPELL_ECK_BERSERK);
+ bBerserk = true;
+ }
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_ECK_THE_FEROCIOUS_EVENT, DONE);
+ }
+};
+
+CreatureAI* GetAI_boss_eck(Creature* pCreature)
+{
+ return new boss_eckAI (pCreature);
+}
+
+struct npc_ruins_dwellerAI : public ScriptedAI
+{
+ npc_ruins_dwellerAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ void JustDied(Unit * /*who*/)
+ {
+ if (pInstance)
+ {
+ pInstance->SetData64(DATA_RUIN_DWELLER_DIED,me->GetGUID());
+ if (pInstance->GetData(DATA_ALIVE_RUIN_DWELLERS) == 0)
+ me->SummonCreature(CREATURE_ECK, EckSpawnPoint, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300*IN_MILISECONDS);
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_ruins_dweller(Creature* pCreature)
+{
+ return new npc_ruins_dwellerAI (pCreature);
+}
+
+void AddSC_boss_eck()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_eck";
+ newscript->GetAI = &GetAI_boss_eck;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_ruins_dweller";
+ newscript->GetAI = &GetAI_npc_ruins_dweller;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/gundrak/boss_gal_darah.cpp b/src/server/scripts/northrend/gundrak/boss_gal_darah.cpp
new file mode 100644
index 00000000000..c87a6600783
--- /dev/null
+++ b/src/server/scripts/northrend/gundrak/boss_gal_darah.cpp
@@ -0,0 +1,288 @@
+/*
+* Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "gundrak.h"
+
+//Spells
+enum Spells
+{
+ SPELL_ENRAGE = 55285,
+ H_SPELL_ENRAGE = 59828,
+ SPELL_IMPALING_CHARGE = 54956,
+ H_SPELL_IMPALING_CHARGE = 59827,
+ SPELL_STOMP = 55292,
+ H_SPELL_STOMP = 59829,
+ SPELL_PUNCTURE = 55276,
+ H_SPELL_PUNCTURE = 59826,
+ SPELL_STAMPEDE = 55218,
+ SPELL_WHIRLING_SLASH = 55250,
+ H_SPELL_WHIRLING_SLASH = 59824,
+ SPELL_ECK_RESIDUE = 55817
+};
+
+//Yells
+enum Yells
+{
+ SAY_AGGRO = -1604000,
+ SAY_SLAY_1 = -1604001,
+ SAY_SLAY_2 = -1604002,
+ SAY_SLAY_3 = -1604003,
+ SAY_DEATH = -1604004,
+ SAY_SUMMON_RHINO_1 = -1604005,
+ SAY_SUMMON_RHINO_2 = -1604006,
+ SAY_SUMMON_RHINO_3 = -1604007,
+ SAY_TRANSFORM_1 = -1604008, //Phase change
+ SAY_TRANSFORM_2 = -1604009
+};
+
+enum Achievements
+{
+ ACHIEV_WHAT_THE_ECK = 1864,
+ ACHIEV_SHARE_THE_LOVE = 2152
+};
+
+enum Displays
+{
+ DISPLAY_RHINO = 26265,
+ DISPLAY_TROLL = 27061
+};
+
+enum CombatPhase
+{
+ TROLL,
+ RHINO
+};
+
+struct boss_gal_darahAI : public ScriptedAI
+{
+ boss_gal_darahAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiStampedeTimer;
+ uint32 uiWhirlingSlashTimer;
+ uint32 uiPunctureTimer;
+ uint32 uiEnrageTimer;
+ uint32 uiImpalingChargeTimer;
+ uint32 uiStompTimer;
+ uint32 uiTransformationTimer;
+ std::set<uint64> lImpaledPlayers;
+
+ CombatPhase Phase;
+
+ uint8 uiPhaseCounter;
+
+ bool bStartOfTransformation;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiStampedeTimer = 10*IN_MILISECONDS;
+ uiWhirlingSlashTimer = 21*IN_MILISECONDS;
+ uiPunctureTimer = 10*IN_MILISECONDS;
+ uiEnrageTimer = 15*IN_MILISECONDS;
+ uiImpalingChargeTimer = 21*IN_MILISECONDS;
+ uiStompTimer = 25*IN_MILISECONDS;
+ uiTransformationTimer = 9*IN_MILISECONDS;
+ uiPhaseCounter = 0;
+
+ lImpaledPlayers.clear();
+
+ bStartOfTransformation = true;
+
+ Phase = TROLL;
+
+ me->SetDisplayId(DISPLAY_TROLL);
+
+ if (pInstance)
+ pInstance->SetData(DATA_GAL_DARAH_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_GAL_DARAH_EVENT, IN_PROGRESS);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ switch (Phase)
+ {
+ case TROLL:
+ if (uiPhaseCounter == 2)
+ {
+ if (uiTransformationTimer <= diff)
+ {
+ me->SetDisplayId(DISPLAY_RHINO);
+ Phase = RHINO;
+ uiPhaseCounter = 0;
+ DoScriptText(SAY_TRANSFORM_1, me);
+ uiTransformationTimer = 5*IN_MILISECONDS;
+ bStartOfTransformation = true;
+ me->clearUnitState(UNIT_STAT_STUNNED|UNIT_STAT_ROOT);
+ me->SetReactState(REACT_AGGRESSIVE);
+ }
+ else
+ {
+ uiTransformationTimer -= diff;
+
+ if (bStartOfTransformation)
+ {
+ bStartOfTransformation = false;
+ me->addUnitState(UNIT_STAT_STUNNED|UNIT_STAT_ROOT);
+ me->SetReactState(REACT_PASSIVE);
+ }
+ }
+ }
+ else
+ {
+ if (uiStampedeTimer <= diff)
+ {
+ DoCast(me, SPELL_STAMPEDE);
+ DoScriptText(RAND(SAY_SUMMON_RHINO_1,SAY_SUMMON_RHINO_2,SAY_SUMMON_RHINO_3),me);
+ uiStampedeTimer = 15*IN_MILISECONDS;
+ } else uiStampedeTimer -= diff;
+
+ if (uiWhirlingSlashTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_WHIRLING_SLASH);
+ uiWhirlingSlashTimer = 21*IN_MILISECONDS;
+ ++uiPhaseCounter;
+ } else uiWhirlingSlashTimer -= diff;
+ }
+ break;
+ case RHINO:
+ if (uiPhaseCounter == 2)
+ {
+ if (uiTransformationTimer <= diff)
+ {
+ me->SetDisplayId(DISPLAY_TROLL);
+ Phase = TROLL;
+ uiPhaseCounter = 0;
+ DoScriptText(SAY_TRANSFORM_2, me);
+ uiTransformationTimer = 9*IN_MILISECONDS;
+ bStartOfTransformation = true;
+ me->clearUnitState(UNIT_STAT_STUNNED|UNIT_STAT_ROOT);
+ me->SetReactState(REACT_AGGRESSIVE);
+ }
+ else
+ {
+ uiTransformationTimer -= diff;
+
+ if (bStartOfTransformation)
+ {
+ bStartOfTransformation = false;
+ me->addUnitState(UNIT_STAT_STUNNED|UNIT_STAT_ROOT);
+ me->SetReactState(REACT_PASSIVE);
+ }
+ }
+ }
+ else
+ {
+ if (uiPunctureTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_PUNCTURE);
+ uiPunctureTimer = 8*IN_MILISECONDS;
+ } else uiPunctureTimer -= diff;
+
+ if (uiEnrageTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_ENRAGE);
+ uiEnrageTimer = 20*IN_MILISECONDS;
+ } else uiEnrageTimer -= diff;
+
+ if (uiStompTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_STOMP);
+ uiStompTimer = 20*IN_MILISECONDS;
+ } else uiStompTimer -= diff;
+
+ if (uiImpalingChargeTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ {
+ DoCast(pTarget, SPELL_IMPALING_CHARGE);
+ lImpaledPlayers.insert(pTarget->GetGUID());
+ }
+ uiImpalingChargeTimer = 31*IN_MILISECONDS;
+ ++uiPhaseCounter;
+ } else uiImpalingChargeTimer -= diff;
+ }
+ break;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ {
+ if (IsHeroic())
+ {
+ if (lImpaledPlayers.size() == 5)
+ pInstance->DoCompleteAchievement(ACHIEV_SHARE_THE_LOVE);
+
+ AchievementEntry const *achievWhatTheEck = GetAchievementStore()->LookupEntry(ACHIEV_WHAT_THE_ECK);
+ if (achievWhatTheEck)
+ {
+ Map::PlayerList const &players = pInstance->instance->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ if (itr->getSource()->HasAura(SPELL_ECK_RESIDUE))
+ itr->getSource()->CompletedAchievement(achievWhatTheEck);
+ }
+ }
+
+ pInstance->SetData(DATA_GAL_DARAH_EVENT, DONE);
+ }
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+};
+
+CreatureAI* GetAI_boss_gal_darah(Creature* pCreature)
+{
+ return new boss_gal_darahAI (pCreature);
+}
+
+void AddSC_boss_gal_darah()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_gal_darah";
+ newscript->GetAI = &GetAI_boss_gal_darah;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/gundrak/boss_moorabi.cpp b/src/server/scripts/northrend/gundrak/boss_moorabi.cpp
new file mode 100644
index 00000000000..84a7d8bc654
--- /dev/null
+++ b/src/server/scripts/northrend/gundrak/boss_moorabi.cpp
@@ -0,0 +1,175 @@
+/*
+* Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "gundrak.h"
+
+enum eSpells
+{
+ SPELL_DETERMINED_STAB = 55104,
+ SPELL_GROUND_TREMOR = 55142,
+ SPELL_NUMBING_SHOUT = 55106,
+ SPELL_DETERMINED_GORE = 55102,
+ H_SPELL_DETERMINED_GORE = 59444,
+ SPELL_QUAKE = 55101,
+ SPELL_NUMBING_ROAR = 55100,
+ SPELL_MOJO_FRENZY = 55163,
+ SPELL_TRANSFORMATION = 55098, //Periodic, The caster transforms into a powerful mammoth, increasing Physical damage done by 25% and granting immunity to Stun effects.
+};
+
+enum eArchivements
+{
+ ACHIEV_LESS_RABI = 2040
+};
+
+enum eSays
+{
+ SAY_AGGRO = -1604010,
+ //SAY_SLAY_1 = -1604011, // not in db
+ SAY_SLAY_2 = -1604012,
+ SAY_SLAY_3 = -1604013,
+ SAY_DEATH = -1604014,
+ SAY_TRANSFORM = -1604015,
+ SAY_QUAKE = -1604016,
+ EMOTE_TRANSFORM = -1604017
+};
+
+struct boss_moorabiAI : public ScriptedAI
+{
+ boss_moorabiAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ bool bPhase;
+
+ uint32 uiNumblingShoutTimer;
+ uint32 uiGroundTremorTimer;
+ uint32 uiDeterminedStabTimer;
+ uint32 uiTransformationTImer;
+
+ void Reset()
+ {
+ uiGroundTremorTimer = 18*IN_MILISECONDS;
+ uiNumblingShoutTimer = 10*IN_MILISECONDS;
+ uiDeterminedStabTimer = 20*IN_MILISECONDS;
+ uiTransformationTImer = 12*IN_MILISECONDS;
+ bPhase = false;
+
+ if (pInstance)
+ pInstance->SetData(DATA_MOORABI_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ DoCast(me, SPELL_MOJO_FRENZY, true);
+
+ if (pInstance)
+ pInstance->SetData(DATA_MOORABI_EVENT, IN_PROGRESS);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (!bPhase && me->HasAura(SPELL_TRANSFORMATION))
+ {
+ bPhase = true;
+ me->RemoveAura(SPELL_MOJO_FRENZY);
+ }
+
+ if (uiGroundTremorTimer <= uiDiff)
+ {
+ DoScriptText(SAY_QUAKE, me);
+ if (bPhase)
+ DoCast(me->getVictim(), SPELL_QUAKE, true);
+ else
+ DoCast(me->getVictim(), SPELL_GROUND_TREMOR, true);
+ uiGroundTremorTimer = 10*IN_MILISECONDS;
+ } else uiGroundTremorTimer -= uiDiff;
+
+ if (uiNumblingShoutTimer <= uiDiff)
+ {
+ if (bPhase)
+ DoCast(me->getVictim(), SPELL_NUMBING_ROAR, true);
+ else
+ DoCast(me->getVictim(), SPELL_NUMBING_SHOUT, true);
+ uiNumblingShoutTimer = 10*IN_MILISECONDS;
+ } else uiNumblingShoutTimer -=uiDiff;
+
+ if (uiDeterminedStabTimer <= uiDiff)
+ {
+ if (bPhase)
+ DoCast(me->getVictim(), SPELL_DETERMINED_GORE);
+ else
+ DoCast(me->getVictim(), SPELL_DETERMINED_STAB, true);
+ uiDeterminedStabTimer = 8*IN_MILISECONDS;
+ } else uiDeterminedStabTimer -=uiDiff;
+
+ if (!bPhase && uiTransformationTImer <= uiDiff)
+ {
+ DoScriptText(EMOTE_TRANSFORM, me);
+ DoScriptText(SAY_TRANSFORM, me);
+ DoCast(me, SPELL_TRANSFORMATION, false);
+ uiTransformationTImer = 10*IN_MILISECONDS;
+ } else uiTransformationTImer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_MOORABI_EVENT, DONE);
+
+ if (IsHeroic() && !bPhase)
+ pInstance->DoCompleteAchievement(ACHIEV_LESS_RABI);
+ }
+ }
+
+ void KilledUnit(Unit* pVictim)
+ {
+ if (pVictim == me)
+ return;
+
+ DoScriptText(RAND(SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+};
+
+CreatureAI* GetAI_boss_moorabi(Creature *pCreature)
+{
+ return new boss_moorabiAI(pCreature);
+}
+
+void AddSC_boss_moorabi()
+{
+ Script* newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_moorabi";
+ newscript->GetAI = &GetAI_boss_moorabi;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/gundrak/boss_slad_ran.cpp b/src/server/scripts/northrend/gundrak/boss_slad_ran.cpp
new file mode 100644
index 00000000000..1014beaeddd
--- /dev/null
+++ b/src/server/scripts/northrend/gundrak/boss_slad_ran.cpp
@@ -0,0 +1,266 @@
+/*
+* Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "gundrak.h"
+
+//Spells
+enum Spells
+{
+ SPELL_POISON_NOVA = 55081,
+ H_SPELL_POISON_NOVA = 59842,
+ SPELL_POWERFULL_BITE = 48287,
+ H_SPELL_POWERFULL_BITE = 59840,
+ SPELL_VENOM_BOLT = 54970,
+ H_SPELL_VENOM_BOLT = 59839
+};
+
+//Yell
+enum Yells
+{
+ SAY_AGGRO = -1604017,
+ SAY_SLAY_1 = -1604018,
+ SAY_SLAY_2 = -1604019,
+ SAY_SLAY_3 = -1604020,
+ SAY_DEATH = -1604021,
+ SAY_SUMMON_SNAKES = -1604022,
+ SAY_SUMMON_CONSTRICTORS = -1604023
+};
+
+//Creatures
+enum Creatures
+{
+ CREATURE_SNAKE = 29680,
+ CREATURE_CONSTRICTORS = 29713
+};
+
+//Creatures' spells
+enum ConstrictorSpells
+{
+ SPELL_GRIP_OF_SLAD_RAN = 55093,
+ SPELL_VENOMOUS_BITE = 54987,
+ H_SPELL_VENOMOUS_BITE = 58996
+};
+
+static Position SpawnLoc[]=
+{
+ {1783.81, 646.637, 133.948, 3.71755},
+ {1775.03, 606.586, 134.165, 1.43117},
+ {1717.39, 630.041, 129.282, 5.96903},
+ {1765.66, 646.542, 134.02, 5.11381},
+ {1716.76, 635.159, 129.282, 0.191986}
+};
+
+struct boss_slad_ranAI : public ScriptedAI
+{
+ boss_slad_ranAI(Creature *c) : ScriptedAI(c), lSummons(me)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiPoisonNovaTimer;
+ uint32 uiPowerfullBiteTimer;
+ uint32 uiVenomBoltTimer;
+ uint32 uiSpawnTimer;
+
+ uint8 uiPhase;
+
+ SummonList lSummons;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiPoisonNovaTimer = 10*IN_MILISECONDS;
+ uiPowerfullBiteTimer = 3*IN_MILISECONDS;
+ uiVenomBoltTimer = 15*IN_MILISECONDS;
+ uiSpawnTimer = 5*IN_MILISECONDS;
+ uiPhase = 0;
+
+ lSummons.DespawnAll();
+
+ if (pInstance)
+ pInstance->SetData(DATA_SLAD_RAN_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_SLAD_RAN_EVENT, IN_PROGRESS);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiPoisonNovaTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_POISON_NOVA);
+ uiPoisonNovaTimer = 15*IN_MILISECONDS;
+ } else uiPoisonNovaTimer -= diff;
+
+ if (uiPowerfullBiteTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_POWERFULL_BITE);
+ uiPowerfullBiteTimer = 10*IN_MILISECONDS;
+ } else uiPowerfullBiteTimer -= diff;
+
+ if (uiVenomBoltTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_VENOM_BOLT);
+ uiVenomBoltTimer = 10*IN_MILISECONDS;
+ } else uiVenomBoltTimer -= diff;
+
+ if (uiPhase)
+ {
+ if (uiSpawnTimer <= diff)
+ {
+ if (uiPhase == 1)
+ for (uint8 i = 0; i < DUNGEON_MODE(3, 5); ++i)
+ me->SummonCreature(CREATURE_SNAKE, SpawnLoc[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN,20*IN_MILISECONDS);
+ if (uiPhase == 2)
+ for (uint8 i = 0; i < DUNGEON_MODE(3, 5); ++i)
+ me->SummonCreature(CREATURE_CONSTRICTORS, SpawnLoc[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN,20*IN_MILISECONDS);
+ uiSpawnTimer = 5*IN_MILISECONDS;
+ } else uiSpawnTimer -= diff;
+ }
+
+ if (uiPhase == 0 && HealthBelowPct(30))
+ {
+ DoScriptText(SAY_SUMMON_SNAKES,me);
+ uiPhase = 1;
+ }
+
+ if (uiPhase == 1 && HealthBelowPct(25))
+ {
+ DoScriptText(SAY_SUMMON_CONSTRICTORS,me);
+ uiPhase = 2;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_SLAD_RAN_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ summoned->GetMotionMaster()->MovePoint(0,me->GetPositionX(),me->GetPositionY(),me->GetPositionZ());
+ lSummons.Summon(summoned);
+ }
+};
+
+struct mob_slad_ran_constrictorAI : public ScriptedAI
+{
+ mob_slad_ran_constrictorAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 uiGripOfSladRanTimer;
+
+ void Reset()
+ {
+ uiGripOfSladRanTimer = 1*IN_MILISECONDS;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+ if (uiGripOfSladRanTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_GRIP_OF_SLAD_RAN);
+ uiGripOfSladRanTimer = 5*IN_MILISECONDS;
+ } else uiGripOfSladRanTimer -= diff;
+ }
+
+ ScriptedInstance* pInstance;
+};
+
+struct mob_slad_ran_viperAI : public ScriptedAI
+{
+ mob_slad_ran_viperAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 uiVenomousBiteTimer;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiVenomousBiteTimer = 2*IN_MILISECONDS;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiVenomousBiteTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_VENOMOUS_BITE);
+ uiVenomousBiteTimer = 10*IN_MILISECONDS;
+ } else uiVenomousBiteTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_boss_slad_ran(Creature* pCreature)
+{
+ return new boss_slad_ranAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_slad_ran_constrictor(Creature* pCreature)
+{
+ return new mob_slad_ran_constrictorAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_slad_ran_viper(Creature* pCreature)
+{
+ return new mob_slad_ran_viperAI (pCreature);
+}
+
+void AddSC_boss_slad_ran()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_slad_ran";
+ newscript->GetAI = &GetAI_boss_slad_ran;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_slad_ran_constrictor";
+ newscript->GetAI = &GetAI_mob_slad_ran_constrictor;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_slad_ran_viper";
+ newscript->GetAI = &GetAI_mob_slad_ran_viper;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/gundrak/gundrak.h b/src/server/scripts/northrend/gundrak/gundrak.h
new file mode 100644
index 00000000000..a443aa4e698
--- /dev/null
+++ b/src/server/scripts/northrend/gundrak/gundrak.h
@@ -0,0 +1,54 @@
+/*
+* Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef DEF_GUNDRAK_H
+#define DEF_GUNDRAK_H
+
+enum Data
+{
+ DATA_SLAD_RAN_EVENT,
+ DATA_MOORABI_EVENT,
+ DATA_DRAKKARI_COLOSSUS_EVENT,
+ DATA_GAL_DARAH_EVENT,
+ DATA_ECK_THE_FEROCIOUS_EVENT,
+ DATA_ALIVE_RUIN_DWELLERS
+};
+
+enum Data64
+{
+ DATA_SLAD_RAN_ALTAR,
+ DATA_MOORABI_ALTAR,
+ DATA_DRAKKARI_COLOSSUS_ALTAR,
+ DATA_SLAD_RAN_STATUE,
+ DATA_MOORABI_STATUE,
+ DATA_DRAKKARI_COLOSSUS_STATUE,
+ DATA_DRAKKARI_COLOSSUS,
+ DATA_RUIN_DWELLER_DIED
+};
+
+enum mainCreatures
+{
+ CREATURE_RUIN_DWELLER = 29920,
+ CREATURE_SLAD_RAN = 29304,
+ CREATURE_MOORABI = 29305,
+ CREATURE_GALDARAH = 29306,
+ CREATURE_DRAKKARICOLOSSUS = 29307,
+ CREATURE_ECK = 29932
+};
+
+#endif
diff --git a/src/server/scripts/northrend/gundrak/instance_gundrak.cpp b/src/server/scripts/northrend/gundrak/instance_gundrak.cpp
new file mode 100644
index 00000000000..4dd896f74f2
--- /dev/null
+++ b/src/server/scripts/northrend/gundrak/instance_gundrak.cpp
@@ -0,0 +1,536 @@
+/*
+* Copyright (C) 2009 - 2010 TrinityCore <http://www.trinitycore.org/>
+*
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "gundrak.h"
+
+#define MAX_ENCOUNTER 5
+
+/* GunDrak encounters:
+0 - Slad'Ran
+1 - Moorabi
+2 - Drakkari Colossus
+3 - Gal'Darah
+4 - Eck the Ferocious
+*/
+
+struct instance_gundrak : public ScriptedInstance
+{
+ instance_gundrak(Map* pMap) : ScriptedInstance(pMap)
+ {
+ bHeroicMode = pMap->IsHeroic();
+ Initialize();
+ };
+
+ bool bHeroicMode;
+ bool spawnSupport;
+
+ uint32 timer;
+ uint32 phase;
+ uint64 toActivate;
+
+ uint64 uiSladRan;
+ uint64 uiMoorabi;
+ uint64 uiDrakkariColossus;
+ uint64 uiGalDarah;
+ uint64 uiEckTheFerocious;
+
+ uint64 uiSladRanAltar;
+ uint64 uiMoorabiAltar;
+ uint64 uiDrakkariColossusAltar;
+ uint64 uiSladRanStatue;
+ uint64 uiMoorabiStatue;
+ uint64 uiDrakkariColossusStatue;
+ uint64 uiGalDarahStatue;
+ uint64 uiEckTheFerociousDoor;
+ uint64 uiEckTheFerociousDoorBehind;
+ uint64 uiGalDarahDoor1;
+ uint64 uiGalDarahDoor2;
+ uint64 uiBridge;
+ uint64 uiCollision;
+
+ uint32 m_auiEncounter[MAX_ENCOUNTER];
+
+ GOState uiSladRanStatueState;
+ GOState uiMoorabiStatueState;
+ GOState uiDrakkariColossusStatueState;
+ GOState uiGalDarahStatueState;
+ GOState uiBridgeState;
+ GOState uiCollisionState;
+
+ std::set<uint64> DwellerGUIDs;
+
+ std::string str_data;
+
+ void Initialize()
+ {
+ spawnSupport = false;
+
+ timer = 0;
+ phase = 0;
+ toActivate = 0;
+
+ uiSladRan = 0;
+ uiMoorabi = 0;
+ uiDrakkariColossus = 0;
+ uiGalDarah = 0;
+ uiEckTheFerocious = 0;
+
+ uiSladRanAltar = 0;
+ uiMoorabiAltar = 0;
+ uiDrakkariColossusAltar = 0;
+
+ uiSladRanStatue = 0;
+ uiMoorabiStatue = 0;
+ uiDrakkariColossusStatue = 0;
+ uiGalDarahStatue = 0;
+
+ uiEckTheFerociousDoor = 0;
+ uiEckTheFerociousDoorBehind = 0;
+ uiGalDarahDoor1 = 0;
+ uiGalDarahDoor2 = 0;
+
+ uiBridge = 0;
+ uiCollision = 0;
+
+ uiSladRanStatueState = GO_STATE_ACTIVE;
+ uiMoorabiStatueState = GO_STATE_ACTIVE;
+ uiDrakkariColossusStatueState = GO_STATE_ACTIVE;
+ uiGalDarahStatueState = GO_STATE_READY;
+ uiBridgeState = GO_STATE_ACTIVE;
+ uiCollisionState = GO_STATE_READY;
+
+ DwellerGUIDs.clear();
+
+ memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool /*add*/)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case CREATURE_SLAD_RAN: uiSladRan = pCreature->GetGUID(); break;
+ case CREATURE_MOORABI: uiMoorabi = pCreature->GetGUID(); break;
+ case CREATURE_GALDARAH: uiGalDarah = pCreature->GetGUID(); break;
+ case CREATURE_DRAKKARICOLOSSUS: uiDrakkariColossus = pCreature->GetGUID(); break;
+ case CREATURE_ECK: uiEckTheFerocious = pCreature->GetGUID(); break;
+ case CREATURE_RUIN_DWELLER:
+ if (pCreature->isAlive())
+ DwellerGUIDs.insert(pCreature->GetGUID());
+ break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
+ {
+ switch(pGo->GetEntry())
+ {
+ case 192518:
+ uiSladRanAltar = pGo->GetGUID();
+ // Make sure that they start out as unusuable
+ pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
+ if (m_auiEncounter[0] == DONE)
+ {
+ if (uiSladRanStatueState == GO_STATE_ACTIVE)
+ pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
+ else
+ {
+ ++phase;
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ }
+ }
+ break;
+ case 192519:
+ uiMoorabiAltar = pGo->GetGUID();
+ // Make sure that they start out as unusuable
+ pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
+ if (m_auiEncounter[0] == DONE)
+ {
+ if (uiMoorabiStatueState == GO_STATE_ACTIVE)
+ pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
+ else
+ {
+ ++phase;
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ }
+ }
+ break;
+ case 192520:
+ uiDrakkariColossusAltar = pGo->GetGUID();
+ // Make sure that they start out as unusuable
+ pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
+ if (m_auiEncounter[0] == DONE)
+ {
+ if (uiDrakkariColossusStatueState == GO_STATE_ACTIVE)
+ pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
+ else
+ {
+ ++phase;
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ }
+ }
+ break;
+ case 192564:
+ uiSladRanStatue = pGo->GetGUID();
+ pGo->SetGoState(uiSladRanStatueState);
+ break;
+ case 192565:
+ uiMoorabiStatue = pGo->GetGUID();
+ pGo->SetGoState(uiMoorabiStatueState);
+ break;
+ case 192566:
+ uiGalDarahStatue = pGo->GetGUID();
+ pGo->SetGoState(uiGalDarahStatueState);
+ break;
+ case 192567:
+ uiDrakkariColossusStatue = pGo->GetGUID();
+ pGo->SetGoState(uiDrakkariColossusStatueState);
+ break;
+ case 192632:
+ uiEckTheFerociousDoor = pGo->GetGUID();
+ if (bHeroicMode && m_auiEncounter[1] == DONE)
+ HandleGameObject(NULL,true,pGo);
+ break;
+ case 192569:
+ uiEckTheFerociousDoorBehind = pGo->GetGUID();
+ if (bHeroicMode && m_auiEncounter[4] == DONE)
+ HandleGameObject(NULL,true,pGo);
+ case 193208:
+ uiGalDarahDoor1 = pGo->GetGUID();
+ if (m_auiEncounter[3] == DONE)
+ HandleGameObject(NULL,true,pGo);
+ break;
+ case 193209:
+ uiGalDarahDoor2 = pGo->GetGUID();
+ if (m_auiEncounter[3] == DONE)
+ HandleGameObject(NULL,true,pGo);
+ break;
+ case 193188:
+ uiBridge = pGo->GetGUID();
+ pGo->SetGoState(uiBridgeState);
+ break;
+ case 192633:
+ uiCollision = pGo->GetGUID();
+ pGo->SetGoState(uiCollisionState);
+
+ // Can't spawn here with SpawnGameObject because pGo isn't added to world yet...
+ if (uiCollisionState == GO_STATE_ACTIVE_ALTERNATIVE)
+ spawnSupport = true;
+ break;
+ }
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_SLAD_RAN_EVENT:
+ m_auiEncounter[0] = data;
+ if (data == DONE)
+ {
+ GameObject* pGo = instance->GetGameObject(uiSladRanAltar);
+ if (pGo)
+ pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
+ }
+ break;
+ case DATA_MOORABI_EVENT:
+ m_auiEncounter[1] = data;
+ if (data == DONE)
+ {
+ GameObject* pGo = instance->GetGameObject(uiMoorabiAltar);
+ if (pGo)
+ pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
+ if (bHeroicMode)
+ HandleGameObject(uiEckTheFerociousDoor,true);
+ }
+ break;
+ case DATA_DRAKKARI_COLOSSUS_EVENT:
+ m_auiEncounter[2] = data;
+ if (data == DONE)
+ {
+ GameObject* pGo = instance->GetGameObject(uiDrakkariColossusAltar);
+ if (pGo)
+ pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_UNK1);
+ }
+ break;
+ case DATA_GAL_DARAH_EVENT:
+ m_auiEncounter[3] = data;
+ if (data == DONE)
+ {
+ HandleGameObject(uiGalDarahDoor1,true);
+ HandleGameObject(uiGalDarahDoor2,true);
+ }
+ break;
+ case DATA_ECK_THE_FEROCIOUS_EVENT:
+ m_auiEncounter[4] = data;
+ if (bHeroicMode && data == DONE)
+ HandleGameObject(uiEckTheFerociousDoorBehind,true);
+ break;
+ }
+
+ if (data == DONE)
+ SaveToDB();
+ }
+
+ void SetData64(uint32 type, uint64 data)
+ {
+ if (type == DATA_RUIN_DWELLER_DIED)
+ DwellerGUIDs.erase(data);
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_SLAD_RAN_EVENT: return m_auiEncounter[0];
+ case DATA_MOORABI_EVENT: return m_auiEncounter[1];
+ case DATA_GAL_DARAH_EVENT: return m_auiEncounter[2];
+ case DATA_DRAKKARI_COLOSSUS_EVENT: return m_auiEncounter[3];
+ case DATA_ECK_THE_FEROCIOUS_EVENT: return m_auiEncounter[4];
+ case DATA_ALIVE_RUIN_DWELLERS: return DwellerGUIDs.size();
+ }
+
+ return 0;
+ }
+
+ uint64 GetData64(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_SLAD_RAN_ALTAR: return uiSladRanAltar;
+ case DATA_MOORABI_ALTAR: return uiMoorabiAltar;
+ case DATA_DRAKKARI_COLOSSUS_ALTAR: return uiDrakkariColossusAltar;
+ case DATA_SLAD_RAN_STATUE: return uiSladRanStatue;
+ case DATA_MOORABI_STATUE: return uiMoorabiStatue;
+ case DATA_DRAKKARI_COLOSSUS_STATUE: return uiDrakkariColossusStatue;
+ case DATA_DRAKKARI_COLOSSUS: return uiDrakkariColossus;
+ }
+
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "G D " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
+ << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " "
+ << (uiSladRanStatue ? GetObjState(uiSladRanStatue) : GO_STATE_ACTIVE) << " " << (uiMoorabiStatue ? GetObjState(uiMoorabiStatue) : GO_STATE_ACTIVE) << " "
+ << (uiDrakkariColossusStatue ? GetObjState(uiDrakkariColossusStatue) : GO_STATE_ACTIVE) << " " << (uiGalDarahStatue ? GetObjState(uiGalDarahStatue) : GO_STATE_READY) << " "
+ << (uiBridge ? GetObjState(uiBridge) : GO_STATE_ACTIVE) << " " << (uiCollision ? GetObjState(uiCollision) : GO_STATE_READY);
+
+
+ str_data = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return str_data;
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0, data1, data2, data3, data4, data5, data6, data7, data8, data9, data10;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3
+ >> data4 >> data5 >> data6 >> data7 >> data8 >> data9 >> data10;
+
+ if (dataHead1 == 'G' && dataHead2 == 'D')
+ {
+ m_auiEncounter[0] = data0;
+ m_auiEncounter[1] = data1;
+ m_auiEncounter[2] = data2;
+ m_auiEncounter[3] = data3;
+ m_auiEncounter[4] = data4;
+ uiSladRanStatueState = GOState(data5);
+ uiMoorabiStatueState = GOState(data6);
+ uiDrakkariColossusStatueState = GOState(data7);
+ uiGalDarahStatueState = GOState(data8);
+ uiBridgeState = GOState(data9);
+ uiCollisionState = GOState(data10);
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+
+ bool QueueActivation(uint64 guid, uint32 time)
+ {
+ if (timer)
+ return false;
+
+ toActivate = guid;
+ timer = time;
+ phase++;
+ return true;
+ }
+
+ void Update(uint32 diff)
+ {
+ // Spawn the support for the bridge if necessary
+ if (spawnSupport)
+ {
+ if (GameObject* pCollision = instance->GetGameObject(uiCollision))
+ pCollision->SummonGameObject(192743, pCollision->GetPositionX(), pCollision->GetPositionY(), pCollision->GetPositionZ(), pCollision->GetOrientation(), 0, 0, 0, 0, 0);
+ spawnSupport = false;
+ }
+
+ // If there is nothing to activate, then return
+ if (!toActivate)
+ return;
+
+ if (timer < diff)
+ {
+ timer = 0;
+ if (toActivate == uiBridge)
+ {
+ toActivate = 0;
+ GameObject* pBridge = instance->GetGameObject(uiBridge);
+ GameObject* pCollision = instance->GetGameObject(uiCollision);
+ GameObject* pSladRanStatue = instance->GetGameObject(uiSladRanStatue);
+ GameObject* pMoorabiStatue = instance->GetGameObject(uiMoorabiStatue);
+ GameObject* pDrakkariColossusStatue = instance->GetGameObject(uiDrakkariColossusStatue);
+ GameObject* pGalDarahStatue = instance->GetGameObject(uiGalDarahStatue);
+
+ if (pBridge && pCollision && pSladRanStatue && pMoorabiStatue && pDrakkariColossusStatue && pGalDarahStatue)
+ {
+ pBridge->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ pCollision->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ pSladRanStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ pMoorabiStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ pDrakkariColossusStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ pGalDarahStatue->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+
+ // Add the GO that solidifies the bridge so you can walk on it
+ spawnSupport = true;
+ SaveToDB();
+ }
+ }
+ else
+ {
+ uint32 spell = 0;
+ GameObject* pAltar = NULL;
+ if (toActivate == uiSladRanStatue)
+ {
+ spell = 57071;
+ pAltar = instance->GetGameObject(uiSladRanAltar);
+ } else if (toActivate == uiMoorabiStatue)
+ {
+ spell = 57068;
+ pAltar = instance->GetGameObject(uiMoorabiAltar);
+ } else if (toActivate == uiDrakkariColossusStatue)
+ {
+ spell = 57072;
+ pAltar = instance->GetGameObject(uiDrakkariColossusAltar);
+ }
+
+ // This is a workaround to make the beam cast properly. The caster should be ID 30298 but since the spells
+ // all are with scripted target for that same ID, it will hit itself.
+ if (pAltar)
+ if (Creature* trigger = pAltar->SummonCreature(18721, pAltar->GetPositionX(), pAltar->GetPositionY(), pAltar->GetPositionZ() + 3, pAltar->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 5000))
+ {
+ // Set the trigger model to invisible
+ trigger->SetDisplayId(11686);
+ trigger->CastSpell(trigger, spell, false);
+ }
+
+ if (GameObject* statueGO = instance->GetGameObject(toActivate))
+ statueGO->SetGoState(GO_STATE_READY);
+
+ toActivate = 0;
+
+ if (phase == 3)
+ QueueActivation(uiBridge, 3000);
+ else
+ SaveToDB(); // Don't save in between last statue and bridge turning in case of crash leading to stuck instance
+ }
+ } else timer -= diff;
+ }
+
+ GOState GetObjState(uint64 guid)
+ {
+ if (GameObject* go = instance->GetGameObject(guid))
+ return go->GetGoState();
+ return GO_STATE_ACTIVE;
+ }
+};
+
+bool GOHello_altar(Player * /*pPlayer*/, GameObject *pGO)
+{
+ ScriptedInstance *pInstance = pGO->GetInstanceData();
+ uint64 uiStatue = 0;
+
+ pGO->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ pGO->SetGoState(GO_STATE_ACTIVE);
+
+ if (pInstance)
+ {
+ switch(pGO->GetEntry())
+ {
+ case 192518: uiStatue = pInstance->GetData64(DATA_SLAD_RAN_STATUE); break;
+ case 192519: uiStatue = pInstance->GetData64(DATA_MOORABI_STATUE); break;
+ case 192520: uiStatue = pInstance->GetData64(DATA_DRAKKARI_COLOSSUS_STATUE); break;
+ }
+ if (((instance_gundrak*)pInstance)->QueueActivation(uiStatue, 3500))
+ {
+ pGO->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ pGO->SetGoState(GO_STATE_ACTIVE);
+ }
+ return true;
+ }
+ return false;
+}
+
+InstanceData* GetInstanceData_instance_gundrak(Map* pMap)
+{
+ return new instance_gundrak(pMap);
+}
+
+void AddSC_instance_gundrak()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_gundrak";
+ newscript->GetInstanceData = &GetInstanceData_instance_gundrak;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_gundrak_altar";
+ newscript->pGOHello = &GOHello_altar;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/howling_fjord.cpp b/src/server/scripts/northrend/howling_fjord.cpp
new file mode 100644
index 00000000000..172501e2faa
--- /dev/null
+++ b/src/server/scripts/northrend/howling_fjord.cpp
@@ -0,0 +1,338 @@
+/* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Sholazar_Basin
+SD%Complete: 100
+SDComment: Quest support: 11253, 11241.
+SDCategory: howling_fjord
+EndScriptData */
+
+/* ContentData
+npc_plaguehound_tracker
+npc_apothecary_hanes
+EndContentData */
+
+#include "ScriptedPch.h"
+#include "ScriptedEscortAI.h"
+
+/*######
+## npc_apothecary_hanes
+######*/
+enum Entries
+{
+ NPC_APOTHECARY_HANES = 23784,
+ FACTION_ESCORTEE_A = 774,
+ FACTION_ESCORTEE_H = 775,
+ NPC_HANES_FIRE_TRIGGER = 23968,
+ QUEST_TRAIL_OF_FIRE = 11241,
+ SPELL_COSMETIC_LOW_POLY_FIRE = 56274
+};
+
+bool QuestAccept_npc_apothecary_hanes(Player* pPlayer, Creature* pCreature, Quest const* quest)
+{
+ if (quest->GetQuestId() == QUEST_TRAIL_OF_FIRE)
+ {
+ switch (pPlayer->GetTeam())
+ {
+ case ALLIANCE:
+ pCreature->setFaction(FACTION_ESCORTEE_A);
+ break;
+ case HORDE:
+ pCreature->setFaction(FACTION_ESCORTEE_H);
+ break;
+ }
+ CAST_AI(npc_escortAI, (pCreature->AI()))->Start(true, false, pPlayer->GetGUID());
+ }
+ return true;
+}
+
+struct npc_Apothecary_HanesAI : public npc_escortAI
+{
+ npc_Apothecary_HanesAI(Creature* pCreature) : npc_escortAI(pCreature){}
+ uint32 PotTimer;
+
+ void Reset ()
+ {
+ SetDespawnAtFar(false);
+ PotTimer = 10000; //10 sec cooldown on potion
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (Player* pPlayer = GetPlayerForEscort())
+ pPlayer->FailQuest(QUEST_TRAIL_OF_FIRE);
+ }
+
+ void UpdateEscortAI(const uint32 diff)
+ {
+ if (HealthBelowPct(75))
+ {
+ if (PotTimer <= diff)
+ {
+ DoCast(me, 17534, true);
+ PotTimer = 10000;
+ } else PotTimer -= diff;
+ }
+ if (GetAttack() && UpdateVictim())
+ DoMeleeAttackIfReady();
+ }
+
+ void WaypointReached(uint32 i)
+ {
+ Player* pPlayer = GetPlayerForEscort();
+ if (!pPlayer)
+ return;
+ switch(i)
+ {
+ case 1:
+ me->SetReactState(REACT_AGGRESSIVE);
+ SetRun(true);
+ break;
+ case 23:
+ if (pPlayer)
+ pPlayer->GroupEventHappens(QUEST_TRAIL_OF_FIRE, me);
+ me->ForcedDespawn();
+ break;
+ case 5:
+ if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER,10.0f))
+ Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
+ SetRun(false);
+ break;
+ case 6:
+ if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER,10.0f))
+ Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
+ SetRun(true);
+ break;
+ case 8:
+ if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER,10.0f))
+ Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
+ SetRun(false);
+ break;
+ case 9:
+ if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER,10.0f))
+ Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
+ break;
+ case 10:
+ SetRun(true);
+ break;
+ case 13:
+ SetRun(false);
+ break;
+ case 14:
+ if (Unit* Trigger = me->FindNearestCreature(NPC_HANES_FIRE_TRIGGER,10.0f))
+ Trigger->CastSpell(Trigger, SPELL_COSMETIC_LOW_POLY_FIRE, false);
+ SetRun(true);
+ break;
+ }
+ }
+};
+CreatureAI* GetAI_npc_apothecary_hanes(Creature* pCreature)
+{
+ return new npc_Apothecary_HanesAI(pCreature);
+}
+/*######
+## npc_plaguehound_tracker
+######*/
+
+enum ePlaguehound
+{
+ QUEST_SNIFF_OUT_ENEMY = 11253
+};
+
+struct npc_plaguehound_trackerAI : public npc_escortAI
+{
+ npc_plaguehound_trackerAI(Creature* pCreature) : npc_escortAI(pCreature) { }
+
+ void Reset()
+ {
+ InitScriptData();
+ }
+
+ void InitScriptData()
+ {
+ Player* pPlayer = NULL;
+ if (me->isSummon())
+ if (Unit* summoner = CAST_SUM(me)->GetSummoner())
+ if (summoner->GetTypeId() == TYPEID_PLAYER)
+ pPlayer = CAST_PLR(summoner);
+
+ if (!pPlayer)
+ return;
+
+ me->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
+ Start(false, false, pPlayer->GetGUID());
+ }
+
+ void WaypointReached(uint32 i)
+ {
+ Player* pPlayer = NULL;
+ if (me->isSummon())
+ if (Unit* summoner = CAST_SUM(me)->GetSummoner())
+ if (summoner->GetTypeId() == TYPEID_PLAYER)
+ pPlayer = CAST_PLR(summoner);
+
+ if (!pPlayer)
+ return;
+
+ switch(i)
+ {
+ case 26:
+ me->ForcedDespawn();
+ break;
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_plaguehound_tracker(Creature* pCreature)
+{
+ return new npc_plaguehound_trackerAI(pCreature);
+}
+
+/*######
+## npc_razael_and_lyana
+######*/
+
+#define GOSSIP_RAZAEL_REPORT "High Executor Anselm wants a report on the situation."
+#define GOSSIP_LYANA_REPORT "High Executor Anselm requests your report."
+
+enum eRazael
+{
+ QUEST_REPORTS_FROM_THE_FIELD = 11221,
+ NPC_RAZAEL = 23998,
+ NPC_LYANA = 23778,
+ GOSSIP_TEXTID_RAZAEL1 = 11562,
+ GOSSIP_TEXTID_RAZAEL2 = 11564,
+ GOSSIP_TEXTID_LYANA1 = 11586,
+ GOSSIP_TEXTID_LYANA2 = 11588
+};
+
+bool GossipHello_npc_razael_and_lyana(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_REPORTS_FROM_THE_FIELD) == QUEST_STATUS_INCOMPLETE)
+ switch (pCreature->GetEntry())
+ {
+ case NPC_RAZAEL:
+ if (!pPlayer->GetReqKillOrCastCurrentCount(QUEST_REPORTS_FROM_THE_FIELD, NPC_RAZAEL))
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_RAZAEL_REPORT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_RAZAEL1, pCreature->GetGUID());
+ return true;
+ }
+ break;
+ case NPC_LYANA:
+ if (!pPlayer->GetReqKillOrCastCurrentCount(QUEST_REPORTS_FROM_THE_FIELD, NPC_LYANA))
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LYANA_REPORT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LYANA1, pCreature->GetGUID());
+ return true;
+ }
+ break;
+ }
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_razael_and_lyana(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch (uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_RAZAEL2, pCreature->GetGUID());
+ pPlayer->TalkedToCreature(NPC_RAZAEL, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LYANA2, pCreature->GetGUID());
+ pPlayer->TalkedToCreature(NPC_LYANA, pCreature->GetGUID());
+ break;
+ }
+ return true;
+}
+
+/*######
+## npc_mcgoyver
+######*/
+
+#define GOSSIP_ITEM_MG_I "Walt sent me to pick up some dark iron ingots."
+#define GOSSIP_ITEM_MG_II "Yarp."
+
+enum eMcGoyver
+{
+ QUEST_WE_CAN_REBUILD_IT = 11483,
+
+ SPELL_CREATURE_DARK_IRON_INGOTS = 44512,
+ SPELL_TAXI_EXPLORERS_LEAGUE = 44280,
+
+ GOSSIP_TEXTID_MCGOYVER = 12193
+};
+
+bool GossipHello_npc_mcgoyver(Player* pPlayer, Creature* pCreature)
+{
+ if (pPlayer->GetQuestStatus(QUEST_WE_CAN_REBUILD_IT) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MG_I, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_mcgoyver(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MG_II, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_MCGOYVER, pCreature->GetGUID());
+ pPlayer->CastSpell(pPlayer, SPELL_CREATURE_DARK_IRON_INGOTS, true);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->CastSpell(pPlayer, SPELL_TAXI_EXPLORERS_LEAGUE, true);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ }
+ return true;
+}
+
+void AddSC_howling_fjord()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_apothecary_hanes";
+ newscript->GetAI = &GetAI_npc_apothecary_hanes;
+ newscript->pQuestAccept = &QuestAccept_npc_apothecary_hanes;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_plaguehound_tracker";
+ newscript->GetAI = &GetAI_npc_plaguehound_tracker;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_razael_and_lyana";
+ newscript->pGossipHello = &GossipHello_npc_razael_and_lyana;
+ newscript->pGossipSelect = &GossipSelect_npc_razael_and_lyana;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_mcgoyver";
+ newscript->pGossipHello = &GossipHello_npc_mcgoyver;
+ newscript->pGossipSelect = &GossipSelect_npc_mcgoyver;
+ newscript->RegisterSelf();
+ }
diff --git a/src/server/scripts/northrend/icecrown.cpp b/src/server/scripts/northrend/icecrown.cpp
new file mode 100644
index 00000000000..76608bdb73d
--- /dev/null
+++ b/src/server/scripts/northrend/icecrown.cpp
@@ -0,0 +1,422 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Icecrown
+SD%Complete: 100
+SDComment: Quest support: 12807
+SDCategory: Icecrown
+EndScriptData */
+
+/* ContentData
+npc_arete
+EndContentData */
+
+#include "ScriptedPch.h"
+
+/*######
+## npc_arete
+######*/
+
+#define GOSSIP_ARETE_ITEM1 "Lord-Commander, I would hear your tale."
+#define GOSSIP_ARETE_ITEM2 "<You nod slightly but do not complete the motion as the Lord-Commander narrows his eyes before he continues.>"
+#define GOSSIP_ARETE_ITEM3 "I thought that they now called themselves the Scarlet Onslaught?"
+#define GOSSIP_ARETE_ITEM4 "Where did the grand admiral go?"
+#define GOSSIP_ARETE_ITEM5 "That's fine. When do I start?"
+#define GOSSIP_ARETE_ITEM6 "Let's finish this!"
+#define GOSSIP_ARETE_ITEM7 "That's quite a tale, Lord-Commander."
+
+enum eArete
+{
+ GOSSIP_TEXTID_ARETE1 = 13525,
+ GOSSIP_TEXTID_ARETE2 = 13526,
+ GOSSIP_TEXTID_ARETE3 = 13527,
+ GOSSIP_TEXTID_ARETE4 = 13528,
+ GOSSIP_TEXTID_ARETE5 = 13529,
+ GOSSIP_TEXTID_ARETE6 = 13530,
+ GOSSIP_TEXTID_ARETE7 = 13531,
+
+ QUEST_THE_STORY_THUS_FAR = 12807
+};
+
+bool GossipHello_npc_arete(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_THE_STORY_THUS_FAR) == QUEST_STATUS_INCOMPLETE)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE1, pCreature->GetGUID());
+ return true;
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_arete(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE2, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE3, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+3:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE4, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+4:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE5, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+5:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE6, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+6:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARETE_ITEM7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ARETE7, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+7:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->AreaExploredOrEventHappens(QUEST_THE_STORY_THUS_FAR);
+ break;
+ }
+
+ return true;
+}
+
+/*######
+## npc_dame_evniki_kapsalis
+######*/
+
+enum eDameEnvikiKapsalis
+{
+ TITLE_CRUSADER = 123
+};
+
+bool GossipHello_npc_dame_evniki_kapsalis(Player* pPlayer, Creature* pCreature)
+{
+ if (pPlayer->HasTitle(TITLE_CRUSADER))
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_dame_evniki_kapsalis(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_TRADE)
+ pPlayer->SEND_VENDORLIST(pCreature->GetGUID());
+ return true;
+}
+
+/*######
+## npc_squire_david
+######*/
+
+enum eSquireDavid
+{
+ QUEST_THE_ASPIRANT_S_CHALLENGE_H = 13680,
+ QUEST_THE_ASPIRANT_S_CHALLENGE_A = 13679,
+
+ NPC_ARGENT_VALIANT = 33448,
+
+ GOSSIP_TEXTID_SQUIRE = 14407
+};
+
+#define GOSSIP_SQUIRE_ITEM_1 "I am ready to fight!"
+#define GOSSIP_SQUIRE_ITEM_2 "How do the Argent Crusader raiders fight?"
+
+bool GossipHello_npc_squire_david(Player* pPlayer, Creature* pCreature)
+{
+ if (pPlayer->GetQuestStatus(QUEST_THE_ASPIRANT_S_CHALLENGE_H) == QUEST_STATUS_INCOMPLETE ||
+ pPlayer->GetQuestStatus(QUEST_THE_ASPIRANT_S_CHALLENGE_A) == QUEST_STATUS_INCOMPLETE)//We need more info about it.
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SQUIRE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SQUIRE_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_SQUIRE, pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_squire_david(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pCreature->SummonCreature(NPC_ARGENT_VALIANT,8575.451,952.472,547.554,0.38);
+ }
+ //else
+ //pPlayer->SEND_GOSSIP_MENU(???, pCreature->GetGUID()); Missing text
+ return true;
+}
+
+/*######
+## npc_argent_valiant
+######*/
+
+enum eArgentValiant
+{
+ SPELL_CHARGE = 63010,
+ SPELL_SHIELD_BREAKER = 65147,
+
+ NPC_ARGENT_VALIANT_CREDIT = 24108
+};
+
+struct npc_argent_valiantAI : public ScriptedAI
+{
+ npc_argent_valiantAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pCreature->GetMotionMaster()->MovePoint(0,8599.258,963.951,547.553);
+ pCreature->setFaction(35); //wrong faction in db?
+ }
+
+ uint32 uiChargeTimer;
+ uint32 uiShieldBreakerTimer;
+
+ void Reset()
+ {
+ uiChargeTimer = 7000;
+ uiShieldBreakerTimer = 10000;
+ }
+
+ void MovementInform(uint32 uiType, uint32 /*uiId*/)
+ {
+ if (uiType != POINT_MOTION_TYPE)
+ return;
+
+ me->setFaction(14);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32& uiDamage)
+ {
+ if (uiDamage > me->GetHealth() && pDoneBy->GetTypeId() == TYPEID_PLAYER)
+ {
+ uiDamage = 0;
+ CAST_PLR(pDoneBy)->KilledMonsterCredit(NPC_ARGENT_VALIANT_CREDIT,0);
+ me->setFaction(35);
+ me->ForcedDespawn(5000);
+ me->SetHomePosition(me->GetPositionX(),me->GetPositionY(),me->GetPositionZ(),me->GetOrientation());
+ EnterEvadeMode();
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiChargeTimer <= uiDiff)
+ {
+ DoCastVictim(SPELL_CHARGE);
+ uiChargeTimer = 7000;
+ } else uiChargeTimer -= uiDiff;
+
+ if (uiShieldBreakerTimer <= uiDiff)
+ {
+ DoCastVictim(SPELL_SHIELD_BREAKER);
+ uiShieldBreakerTimer = 10000;
+ } else uiShieldBreakerTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_argent_valiant(Creature* pCreature)
+{
+ return new npc_argent_valiantAI (pCreature);
+}
+
+/*######
+## npc_argent_tournament_post
+######*/
+
+enum eArgentTournamentPost
+{
+ SPELL_ROPE_BEAM = 63413,
+ NPC_GORMOK_THE_IMPALER = 35469,
+ NPC_ICEHOWL = 35470
+};
+
+struct npc_argent_tournament_postAI : public ScriptedAI
+{
+ npc_argent_tournament_postAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ void UpdateAI(const uint32 /*uiDiff*/)
+ {
+ if (me->IsNonMeleeSpellCasted(false))
+ return;
+
+ if (Creature* pTarget = me->FindNearestCreature(NPC_GORMOK_THE_IMPALER, 6.0f))
+ DoCast(pTarget, SPELL_ROPE_BEAM);
+
+ if (Creature* pTarget2 = me->FindNearestCreature(NPC_ICEHOWL, 6.0f))
+ DoCast(pTarget2, SPELL_ROPE_BEAM);
+
+ if (!UpdateVictim())
+ return;
+ }
+};
+
+CreatureAI* GetAI_npc_argent_tournament_post(Creature* pCreature)
+{
+ return new npc_argent_tournament_postAI (pCreature);
+}
+
+/*######
+## npc_alorah_and_grimmin
+######*/
+
+enum ealorah_and_grimmin
+{
+ SPELL_CHAIN = 68341,
+ NPC_FJOLA_LIGHTBANE = 36065,
+ NPC_EYDIS_DARKBANE = 36066,
+ NPC_PRIESTESS_ALORAH = 36101,
+ NPC_PRIEST_GRIMMIN = 36102
+};
+
+struct npc_alorah_and_grimminAI : public ScriptedAI
+{
+ npc_alorah_and_grimminAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ bool uiCast;
+
+ void Reset()
+ {
+ uiCast = false;
+ }
+
+ void UpdateAI(const uint32 /*uiDiff*/)
+ {
+ if (uiCast)
+ return;
+ uiCast = true;
+ Creature* pTarget = NULL;
+
+ switch(me->GetEntry())
+ {
+ case NPC_PRIESTESS_ALORAH:
+ pTarget = me->FindNearestCreature(NPC_EYDIS_DARKBANE, 10.0f);
+ break;
+ case NPC_PRIEST_GRIMMIN:
+ pTarget = me->FindNearestCreature(NPC_FJOLA_LIGHTBANE, 10.0f);
+ break;
+ }
+ if (pTarget)
+ DoCast(pTarget, SPELL_CHAIN);
+
+ if (!UpdateVictim())
+ return;
+ }
+};
+
+CreatureAI* GetAI_npc_alorah_and_grimmin(Creature* pCreature)
+{
+ return new npc_alorah_and_grimminAI (pCreature);
+}
+
+/*######
+## npc_guardian_pavilion
+######*/
+
+enum eGuardianPavilion
+{
+ SPELL_TRESPASSER_H = 63987,
+ AREA_SUNREAVER_PAVILION = 4676,
+
+ AREA_SILVER_COVENANT_PAVILION = 4677,
+ SPELL_TRESPASSER_A = 63986,
+};
+
+struct npc_guardian_pavilionAI : public Scripted_NoMovementAI
+{
+ npc_guardian_pavilionAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature) {}
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (me->GetAreaId() != AREA_SUNREAVER_PAVILION && me->GetAreaId() != AREA_SILVER_COVENANT_PAVILION)
+ return;
+
+ if (!pWho || pWho->GetTypeId() != TYPEID_PLAYER || !me->IsHostileTo(pWho) || !me->isInBackInMap(pWho, 5.0f))
+ return;
+
+ if (pWho->HasAura(SPELL_TRESPASSER_H) || pWho->HasAura(SPELL_TRESPASSER_A))
+ return;
+
+ if (pWho->ToPlayer()->GetTeamId() == TEAM_ALLIANCE)
+ pWho->CastSpell(pWho, SPELL_TRESPASSER_H, true);
+ else
+ pWho->CastSpell(pWho, SPELL_TRESPASSER_A, true);
+
+ }
+};
+
+CreatureAI* GetAI_npc_guardian_pavilion(Creature* pCreature)
+{
+ return new npc_guardian_pavilionAI (pCreature);
+}
+
+void AddSC_icecrown()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_arete";
+ newscript->pGossipHello = &GossipHello_npc_arete;
+ newscript->pGossipSelect = &GossipSelect_npc_arete;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_dame_evniki_kapsalis";
+ newscript->pGossipHello = &GossipHello_npc_dame_evniki_kapsalis;
+ newscript->pGossipSelect = &GossipSelect_npc_dame_evniki_kapsalis;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_squire_david";
+ newscript->pGossipHello = &GossipHello_npc_squire_david;
+ newscript->pGossipSelect = &GossipSelect_npc_squire_david;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_argent_valiant";
+ newscript->GetAI = &GetAI_npc_argent_valiant;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_argent_tournament_post";
+ newscript->GetAI = &GetAI_npc_argent_tournament_post;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_alorah_and_grimmin";
+ newscript->GetAI = &GetAI_npc_alorah_and_grimmin;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_guardian_pavilion";
+ newscript->GetAI = &GetAI_npc_guardian_pavilion;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/naxxramas/boss_anubrekhan.cpp b/src/server/scripts/northrend/naxxramas/boss_anubrekhan.cpp
new file mode 100644
index 00000000000..896eb068eb6
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_anubrekhan.cpp
@@ -0,0 +1,185 @@
+/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+#define SAY_GREET RAND(-1533000,-1533004,-1533005,-1533006,-1533007)
+#define SAY_AGGRO RAND(-1533001,-1533002,-1533003)
+#define SAY_SLAY -1533008
+
+#define MOB_CRYPT_GUARD 16573
+
+const Position GuardSummonPos = {3333.72, -3476.30, 287.1, 6.2801};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_IMPALE,
+ EVENT_LOCUST,
+ EVENT_SPAWN_GUARDIAN_NORMAL,
+ EVENT_BERSERK,
+};
+
+enum Spells
+{
+ SPELL_IMPALE_10 = 28783,
+ SPELL_IMPALE_25 = 56090,
+ SPELL_LOCUST_SWARM_10 = 28785,
+ SPELL_LOCUST_SWARM_25 = 54021,
+ SPELL_SUMMON_CORPSE_SCARABS_PLR = 29105, // This spawns 5 corpse scarabs on top of player
+ SPELL_SUMMON_CORPSE_SCARABS_MOB = 28864, // This spawns 10 corpse scarabs on top of dead guards
+ SPELL_BERSERK = 27680,
+};
+
+enum
+{
+ ACHIEV_TIMED_START_EVENT = 9891,
+};
+
+struct boss_anubrekhanAI : public BossAI
+{
+ boss_anubrekhanAI(Creature *c) : BossAI(c, BOSS_ANUBREKHAN) {}
+
+ bool hasTaunted;
+
+ void Reset()
+ {
+ _Reset();
+
+ hasTaunted = false;
+
+ if (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ {
+ Position pos;
+
+ // respawn guard using home position,
+ // otherwise, after a wipe, they respawn where boss was at wipe moment.
+ pos = me->GetHomePosition();
+ pos.m_positionY -= 10.0f;
+ me->SummonCreature(MOB_CRYPT_GUARD, pos, TEMPSUMMON_CORPSE_DESPAWN);
+
+ pos = me->GetHomePosition();
+ pos.m_positionY += 10.0f;
+ me->SummonCreature(MOB_CRYPT_GUARD, pos, TEMPSUMMON_CORPSE_DESPAWN);
+ }
+ }
+
+ void KilledUnit(Unit* victim)
+ {
+ //Force the player to spawn corpse scarabs via spell, TODO: Check percent chance for scarabs, 20% at the moment
+ if (!(rand()%5))
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ victim->CastSpell(victim, SPELL_SUMMON_CORPSE_SCARABS_PLR, true, NULL, NULL, me->GetGUID());
+
+ DoScriptText(SAY_SLAY, me);
+ }
+
+ void JustDied(Unit *)
+ {
+ _JustDied();
+
+ // start achievement timer (kill Maexna within 20 min)
+ if (instance)
+ instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ }
+ void EnterCombat(Unit * /*who*/)
+ {
+ _EnterCombat();
+ DoScriptText(SAY_AGGRO, me);
+ events.ScheduleEvent(EVENT_IMPALE, 10000 + rand()%10000);
+ events.ScheduleEvent(EVENT_LOCUST, 90000);
+ events.ScheduleEvent(EVENT_BERSERK, 600000);
+
+ if (getDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
+ events.ScheduleEvent(EVENT_SPAWN_GUARDIAN_NORMAL, urand(15000,20000));
+ }
+
+ void MoveInLineOfSight(Unit *who)
+ {
+ if (!hasTaunted && me->IsWithinDistInMap(who, 60.0f) && who->GetTypeId() == TYPEID_PLAYER)
+ {
+ DoScriptText(SAY_GREET, me);
+ hasTaunted = true;
+ }
+ ScriptedAI::MoveInLineOfSight(who);
+ }
+
+ void SummonedCreatureDespawn(Creature *summon)
+ {
+ BossAI::SummonedCreatureDespawn(summon);
+
+ // check if it is an actual killed guard
+ if (!me->isAlive() || summon->isAlive() || summon->GetEntry() != MOB_CRYPT_GUARD)
+ return;
+
+ summon->CastSpell(summon, SPELL_SUMMON_CORPSE_SCARABS_MOB, true, NULL, NULL, me->GetGUID());
+ }
+
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim() || !CheckInRoom())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_IMPALE:
+ //Cast Impale on a random target
+ //Do NOT cast it when we are afflicted by locust swarm
+ if (!me->HasAura(RAID_MODE(SPELL_LOCUST_SWARM_10,SPELL_LOCUST_SWARM_25)))
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, RAID_MODE(SPELL_IMPALE_10,SPELL_IMPALE_25));
+ events.ScheduleEvent(EVENT_IMPALE, urand(10000,20000));
+ break;
+ case EVENT_LOCUST:
+ // TODO : Add Text
+ DoCast(me, RAID_MODE(SPELL_LOCUST_SWARM_10,SPELL_LOCUST_SWARM_25));
+ DoSummon(MOB_CRYPT_GUARD, GuardSummonPos, 0, TEMPSUMMON_CORPSE_DESPAWN);
+ events.ScheduleEvent(EVENT_LOCUST, 90000);
+ break;
+ case EVENT_SPAWN_GUARDIAN_NORMAL:
+ // TODO : Add Text
+ DoSummon(MOB_CRYPT_GUARD, GuardSummonPos, 0, TEMPSUMMON_CORPSE_DESPAWN);
+ break;
+ case EVENT_BERSERK:
+ DoCast(me, SPELL_BERSERK, true);
+ events.ScheduleEvent(EVENT_BERSERK, 600000);
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_anubrekhan(Creature* pCreature)
+{
+ return new boss_anubrekhanAI (pCreature);
+}
+
+void AddSC_boss_anubrekhan()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_anubrekhan";
+ newscript->GetAI = &GetAI_boss_anubrekhan;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/naxxramas/boss_faerlina.cpp b/src/server/scripts/northrend/naxxramas/boss_faerlina.cpp
new file mode 100644
index 00000000000..aa5a940eb8f
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_faerlina.cpp
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+enum Yells
+{
+ SAY_GREET = -1533009,
+ SAY_AGGRO_1 = -1533010,
+ SAY_AGGRO_2 = -1533011,
+ SAY_AGGRO_3 = -1533012,
+ SAY_AGGRO_4 = -1533013,
+ SAY_SLAY_1 = -1533014,
+ SAY_SLAY_2 = -1533015,
+ SAY_DEATH = -1533016
+};
+//#define SOUND_RANDOM_AGGRO 8955 //soundId containing the 4 aggro sounds, we not using this
+
+enum Spells
+{
+ SPELL_POISON_BOLT_VOLLEY = 28796,
+ H_SPELL_POISON_BOLT_VOLLEY = 54098,
+ SPELL_RAIN_OF_FIRE = 28794,
+ H_SPELL_RAIN_OF_FIRE = 54099,
+ SPELL_FRENZY = 28798,
+ H_SPELL_FRENZY = 54100,
+ SPELL_WIDOWS_EMBRACE = 28732,
+ H_SPELL_WIDOWS_EMBRACE = 54097
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_POISON,
+ EVENT_FIRE,
+ EVENT_FRENZY
+};
+
+enum Achievements
+{
+ ACHIEVEMENT_MOMMA_SAID_KNOCK_YOU_OUT_10 = 1997,
+ ACHIEVEMENT_MOMMA_SAID_KNOCK_YOU_OUT_25 = 2140
+};
+
+struct boss_faerlinaAI : public BossAI
+{
+ boss_faerlinaAI(Creature *c) : BossAI(c, BOSS_FAERLINA), greet(false) {}
+
+ bool greet;
+ bool doDelayFrenzy;
+ bool bAchievement;
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ _EnterCombat();
+ DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3,SAY_AGGRO_4), me);
+ events.ScheduleEvent(EVENT_POISON, urand(10000,15000));
+ events.ScheduleEvent(EVENT_FIRE, urand(6000,18000));
+ events.ScheduleEvent(EVENT_FRENZY, urand(60000,80000));
+ }
+
+ void Reset()
+ {
+ doDelayFrenzy = false;
+ bAchievement = true;
+ _Reset();
+ }
+
+ void MoveInLineOfSight(Unit *who)
+ {
+ if (!greet && who->GetTypeId() == TYPEID_PLAYER)
+ {
+ DoScriptText(SAY_GREET, me);
+ greet = true;
+ }
+ BossAI::MoveInLineOfSight(who);
+ }
+
+ void KilledUnit(Unit* /*victim*/)
+ {
+ if (!(rand()%3))
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ _JustDied();
+ DoScriptText(SAY_DEATH, me);
+
+ if (instance && bAchievement)
+ instance->DoCompleteAchievement(RAID_MODE(ACHIEVEMENT_MOMMA_SAID_KNOCK_YOU_OUT_10,ACHIEVEMENT_MOMMA_SAID_KNOCK_YOU_OUT_25));
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (doDelayFrenzy && !me->HasAura(RAID_MODE(SPELL_WIDOWS_EMBRACE, H_SPELL_WIDOWS_EMBRACE)))
+ {
+ doDelayFrenzy = false;
+ DoCast(me, RAID_MODE(SPELL_FRENZY, H_SPELL_FRENZY), true);
+ }
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_POISON:
+ if (!me->HasAura(RAID_MODE(SPELL_WIDOWS_EMBRACE,H_SPELL_WIDOWS_EMBRACE)))
+ DoCastAOE(RAID_MODE(SPELL_POISON_BOLT_VOLLEY,H_SPELL_POISON_BOLT_VOLLEY));
+ events.ScheduleEvent(EVENT_POISON, urand(8000,15000));
+ break;
+ case EVENT_FIRE:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, RAID_MODE(SPELL_RAIN_OF_FIRE, H_SPELL_RAIN_OF_FIRE));
+ events.ScheduleEvent(EVENT_FIRE, urand(6000,18000));
+ break;
+ case EVENT_FRENZY:
+ // TODO : Add Text
+ if (!me->HasAura(RAID_MODE(SPELL_WIDOWS_EMBRACE,H_SPELL_WIDOWS_EMBRACE)))
+ DoCast(me, RAID_MODE(SPELL_FRENZY, H_SPELL_FRENZY));
+ else
+ doDelayFrenzy = true;
+
+ events.ScheduleEvent(EVENT_FRENZY, urand(60000,80000));
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void SpellHit(Unit* caster, const SpellEntry *spell)
+ {
+ if (spell->Id == SPELL_WIDOWS_EMBRACE || spell->Id == H_SPELL_WIDOWS_EMBRACE)
+ {
+ // TODO : Add Text
+ bAchievement = false;
+ doDelayFrenzy = true;
+ me->Kill(caster);
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_faerlina(Creature* pCreature)
+{
+ return new boss_faerlinaAI (pCreature);
+}
+
+struct mob_faerlina_addAI : public ScriptedAI
+{
+ mob_faerlina_addAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ if (getDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) {
+ me->ApplySpellImmune(0, IMMUNITY_MECHANIC, SPELL_EFFECT_BIND, true);
+ me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM, true);
+ }
+ }
+
+ void JustDied(Unit * /*killer*/)
+ {
+ if (pInstance && getDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
+ {
+ if (Creature *pFaerlina = pInstance->instance->GetCreature(pInstance->GetData64(DATA_FAERLINA)))
+ DoCast(pFaerlina, SPELL_WIDOWS_EMBRACE);
+ }
+ }
+};
+
+CreatureAI* GetAI_mob_faerlina_add(Creature* pCreature)
+{
+ return new mob_faerlina_addAI (pCreature);
+}
+
+void AddSC_boss_faerlina()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_faerlina";
+ newscript->GetAI = &GetAI_boss_faerlina;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_faerlina_add";
+ newscript->GetAI = &GetAI_mob_faerlina_add;
+ newscript->RegisterSelf();
+}
+
+
diff --git a/src/server/scripts/northrend/naxxramas/boss_four_horsemen.cpp b/src/server/scripts/northrend/naxxramas/boss_four_horsemen.cpp
new file mode 100644
index 00000000000..f04b39040db
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_four_horsemen.cpp
@@ -0,0 +1,397 @@
+/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+enum Horsemen
+{
+ HORSEMEN_THANE,
+ HORSEMEN_LADY,
+ HORSEMEN_BARON,
+ HORSEMEN_SIR,
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_MARK,
+ EVENT_CAST,
+ EVENT_BERSERK,
+};
+
+const Position WaypointPositions[12] =
+{
+ // Thane waypoints
+ {2542.3, -2984.1, 241.49, 5.362},
+ {2547.6, -2999.4, 241.34, 5.049},
+ {2542.9, -3015.0, 241.35, 4.654},
+ // Lady waypoints
+ {2498.3, -2961.8, 241.28, 3.267},
+ {2487.7, -2959.2, 241.28, 2.890},
+ {2469.4, -2947.6, 241.28, 2.576},
+ // Baron waypoints
+ {2553.8, -2968.4, 241.33, 5.757},
+ {2564.3, -2972.5, 241.33, 5.890},
+ {2583.9, -2971.67, 241.35, 0.008},
+ // Sir waypoints
+ {2534.5, -2921.7, 241.53, 1.363},
+ {2523.5, -2902.8, 241.28, 2.095},
+ {2517.8, -2896.6, 241.28, 2.315},
+};
+
+const uint32 MOB_HORSEMEN[] = {16064, 16065, 30549, 16063};
+const uint32 SPELL_MARK[] = {28832, 28833, 28834, 28835};
+#define SPELL_PRIMARY(i) RAID_MODE(SPELL_PRIMARY_N[i],SPELL_PRIMARY_H[i])
+const uint32 SPELL_PRIMARY_N[] = {28884, 28863, 28882, 28883};
+const uint32 SPELL_PRIMARY_H[] = {57467, 57463, 57369, 57466};
+#define SPELL_SECONDARY(i) RAID_MODE(SPELL_SECONDARY_N[i],SPELL_SECONDARY_H[i])
+const uint32 SPELL_SECONDARY_N[]= {0, 57374, 0, 57376};
+const uint32 SPELL_SECONDARY_H[]= {0, 57464, 0, 57465};
+const uint32 SPELL_PUNISH[] = {0, 57381, 0, 57377};
+#define SPELL_BERSERK 26662
+
+// used by 16063,16064,16065,30549, but signed for 16063
+const int32 SAY_AGGRO[] = {-1533051, -1533044, -1533065, -1533058};
+const int32 SAY_TAUNT[3][4] ={ {-1533052, -1533045, -1533071, -1533059},
+ {-1533053, -1533046, -1533072, -1533060},
+ {-1533054, -1533047, -1533073, -1533061},};
+const int32 SAY_SPECIAL[] = {-1533055, -1533048, -1533070, -1533062};
+const int32 SAY_SLAY[] = {-1533056, -1533049, -1533068, -1533063};
+const int32 SAY_DEATH[] = {-1533057, -1533050, -1533074, -1533064};
+
+#define SAY_BARON_AGGRO RAND(-1533065,-1533066,-1533067)
+#define SAY_BARON_SLAY RAND(-1533068,-1533069)
+
+struct boss_four_horsemenAI : public BossAI
+{
+ boss_four_horsemenAI(Creature *c) : BossAI(c, BOSS_HORSEMEN)
+ {
+ id = Horsemen(0);
+ for (uint8 i = 0; i < 4; ++i)
+ if (me->GetEntry() == MOB_HORSEMEN[i])
+ id = Horsemen(i);
+ caster = (id == HORSEMEN_LADY || id == HORSEMEN_SIR);
+ }
+
+ Horsemen id;
+ uint64 uiEventStarterGUID;
+ uint8 nextWP;
+ uint32 punishTimer;
+ bool caster;
+ bool nextMovementStarted;
+ bool movementCompleted;
+ bool movementStarted;
+ bool encounterActionAttack;
+ bool encounterActionReset;
+ bool doDelayPunish;
+
+ void Reset()
+ {
+ if (!encounterActionReset)
+ DoEncounterAction(NULL, false, true, false);
+
+ if (instance)
+ instance->SetData(DATA_HORSEMEN0 + id, NOT_STARTED);
+
+ me->SetReactState(REACT_AGGRESSIVE);
+ uiEventStarterGUID = 0;
+ nextWP = 0;
+ punishTimer = 2000;
+ nextMovementStarted = false;
+ movementCompleted = false;
+ movementStarted = false;
+ encounterActionAttack = false;
+ encounterActionReset = false;
+ doDelayPunish = false;
+ _Reset();
+ }
+
+ bool DoEncounterAction(Unit *who, bool attack, bool reset, bool checkAllDead)
+ {
+ if (!instance)
+ return false;
+
+ Creature *Thane = CAST_CRE(Unit::GetUnit(*me, instance->GetData64(DATA_THANE)));
+ Creature *Lady = CAST_CRE(Unit::GetUnit(*me, instance->GetData64(DATA_LADY)));
+ Creature *Baron = CAST_CRE(Unit::GetUnit(*me, instance->GetData64(DATA_BARON)));
+ Creature *Sir = CAST_CRE(Unit::GetUnit(*me, instance->GetData64(DATA_SIR)));
+
+ if (Thane && Lady && Baron && Sir)
+ {
+ if (attack && who)
+ {
+ CAST_AI(boss_four_horsemenAI, Thane->AI())->encounterActionAttack = true;
+ CAST_AI(boss_four_horsemenAI, Lady->AI())->encounterActionAttack = true;
+ CAST_AI(boss_four_horsemenAI, Baron->AI())->encounterActionAttack = true;
+ CAST_AI(boss_four_horsemenAI, Sir->AI())->encounterActionAttack = true;
+
+ CAST_AI(boss_four_horsemenAI, Thane->AI())->AttackStart(who);
+ CAST_AI(boss_four_horsemenAI, Lady->AI())->AttackStart(who);
+ CAST_AI(boss_four_horsemenAI, Baron->AI())->AttackStart(who);
+ CAST_AI(boss_four_horsemenAI, Sir->AI())->AttackStart(who);
+ }
+
+ if (reset)
+ {
+ if (instance->GetBossState(BOSS_HORSEMEN) != NOT_STARTED)
+ {
+ if (!Thane->isAlive())
+ Thane->Respawn();
+
+ if (!Lady->isAlive())
+ Lady->Respawn();
+
+ if (!Baron->isAlive())
+ Baron->Respawn();
+
+ if (!Sir->isAlive())
+ Sir->Respawn();
+
+ CAST_AI(boss_four_horsemenAI, Thane->AI())->encounterActionReset = true;
+ CAST_AI(boss_four_horsemenAI, Lady->AI())->encounterActionReset = true;
+ CAST_AI(boss_four_horsemenAI, Baron->AI())->encounterActionReset = true;
+ CAST_AI(boss_four_horsemenAI, Sir->AI())->encounterActionReset = true;
+
+ CAST_AI(boss_four_horsemenAI, Thane->AI())->EnterEvadeMode();
+ CAST_AI(boss_four_horsemenAI, Lady->AI())->EnterEvadeMode();
+ CAST_AI(boss_four_horsemenAI, Baron->AI())->EnterEvadeMode();
+ CAST_AI(boss_four_horsemenAI, Sir->AI())->EnterEvadeMode();
+ }
+ }
+
+ if (checkAllDead)
+ return !Thane->isAlive() && !Lady->isAlive() && !Baron->isAlive() && !Sir->isAlive();
+ }
+ return false;
+ }
+
+ void BeginFourHorsemenMovement()
+ {
+ movementStarted = true;
+ me->SetReactState(REACT_PASSIVE);
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ me->SetSpeed(MOVE_RUN, me->GetSpeedRate(MOVE_RUN), true);
+
+ switch(id)
+ {
+ case HORSEMEN_THANE:
+ me->GetMotionMaster()->MovePoint(0, WaypointPositions[0]);
+ break;
+ case HORSEMEN_LADY:
+ me->GetMotionMaster()->MovePoint(3, WaypointPositions[3]);
+ break;
+ case HORSEMEN_BARON:
+ me->GetMotionMaster()->MovePoint(6, WaypointPositions[6]);
+ break;
+ case HORSEMEN_SIR:
+ me->GetMotionMaster()->MovePoint(9, WaypointPositions[9]);
+ break;
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ if (id == 2 || id == 5 || id == 8 || id == 11)
+ {
+ movementCompleted = true;
+ me->SetReactState(REACT_AGGRESSIVE);
+
+ Unit *eventStarter = Unit::GetUnit(*me, uiEventStarterGUID);
+
+ if (eventStarter && me->canAttack(eventStarter))
+ AttackStart(eventStarter);
+ else if (!UpdateVictim())
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ if (caster)
+ {
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveIdle();
+ }
+
+ return;
+ }
+
+ nextMovementStarted = false;
+ nextWP = id + 1;
+ }
+
+ // switch to "who" if nearer than current target.
+ void SelectNearestTarget(Unit *who)
+ {
+ if (me->getVictim() && me->GetDistanceOrder(who, me->getVictim()) && me->canAttack(who))
+ {
+ me->getThreatManager().modifyThreatPercent(me->getVictim(), -100);
+ me->AddThreat(who, 1000000.0f);
+ }
+ }
+
+ void MoveInLineOfSight(Unit *who)
+ {
+ BossAI::MoveInLineOfSight(who);
+ if (caster)
+ SelectNearestTarget(who);
+ }
+
+ void AttackStart(Unit *who)
+ {
+ if (!movementCompleted && !movementStarted)
+ {
+ uiEventStarterGUID = who->GetGUID();
+ BeginFourHorsemenMovement();
+
+ if (!encounterActionAttack)
+ DoEncounterAction(who, true, false, false);
+ }
+ else if (movementCompleted && movementStarted)
+ {
+ if (caster)
+ me->Attack(who, false);
+ else
+ BossAI::AttackStart(who);
+ }
+ }
+
+ void KilledUnit(Unit* /*victim*/)
+ {
+ if (!(rand()%5))
+ {
+ if (id == HORSEMEN_BARON)
+ DoScriptText(SAY_BARON_SLAY, me);
+ else
+ DoScriptText(SAY_SLAY[id], me);
+ }
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ events.Reset();
+ summons.DespawnAll();
+
+ if (instance)
+ instance->SetData(DATA_HORSEMEN0 + id, DONE);
+
+ if (instance && DoEncounterAction(NULL, false, false, true))
+ {
+ instance->SetBossState(BOSS_HORSEMEN, DONE);
+ instance->SaveToDB();
+
+ // Achievements related to the 4-horsemen are given through spell 59450 which does not exist.
+ // There is thus no way it can be given by casting the spell on the players.
+ instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 59450);
+ }
+
+ DoScriptText(SAY_DEATH[id], me);
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ _EnterCombat();
+
+ if (id == HORSEMEN_BARON)
+ DoScriptText(SAY_BARON_AGGRO, me);
+ else
+ DoScriptText(SAY_AGGRO[id], me);
+
+ events.ScheduleEvent(EVENT_MARK, 15000);
+ events.ScheduleEvent(EVENT_CAST, 20000+rand()%5000);
+ events.ScheduleEvent(EVENT_BERSERK, 15*100*1000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (nextWP && movementStarted && !movementCompleted && !nextMovementStarted)
+ {
+ nextMovementStarted = true;
+ me->GetMotionMaster()->MovePoint(nextWP, WaypointPositions[nextWP]);
+ }
+
+ if (!UpdateVictim() || !CheckInRoom() || !movementCompleted)
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_MARK:
+ if (!(rand()%5))
+ DoScriptText(SAY_SPECIAL[id], me);
+ DoCastAOE(SPELL_MARK[id]);
+ events.ScheduleEvent(EVENT_MARK, 15000);
+ break;
+ case EVENT_CAST:
+ if (!(rand()%5))
+ DoScriptText(SAY_TAUNT[rand()%3][id], me);
+
+ if (caster)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f))
+ DoCast(pTarget, SPELL_PRIMARY(id));
+ }
+ else
+ DoCast(me->getVictim(), SPELL_PRIMARY(id));
+
+ events.ScheduleEvent(EVENT_CAST, 15000);
+ break;
+ case EVENT_BERSERK:
+ DoScriptText(SAY_SPECIAL[id], me);
+ DoCast(me, EVENT_BERSERK);
+ break;
+ }
+ }
+
+ if (punishTimer <= diff)
+ {
+ if (doDelayPunish)
+ {
+ DoCastAOE(SPELL_PUNISH[id], true);
+ doDelayPunish = false;
+ }
+ punishTimer = 2000;
+ } else punishTimer -= diff;
+
+ if (!caster)
+ DoMeleeAttackIfReady();
+ else if ((!DoSpellAttackIfReady(SPELL_SECONDARY(id)) || !me->IsWithinLOSInMap(me->getVictim())) && movementCompleted && !doDelayPunish)
+ doDelayPunish = true;
+ }
+};
+
+CreatureAI* GetAI_four_horsemen(Creature* pCreature)
+{
+ return new boss_four_horsemenAI (pCreature);
+}
+
+void AddSC_boss_four_horsemen()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_four_horsemen";
+ newscript->GetAI = &GetAI_four_horsemen;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/naxxramas/boss_gluth.cpp b/src/server/scripts/northrend/naxxramas/boss_gluth.cpp
new file mode 100644
index 00000000000..ab6fa6c46d3
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_gluth.cpp
@@ -0,0 +1,147 @@
+/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+#define SPELL_MORTAL_WOUND 25646
+#define SPELL_ENRAGE RAID_MODE(28371,54427)
+#define SPELL_DECIMATE RAID_MODE(28374,54426)
+#define SPELL_BERSERK 26662
+#define SPELL_INFECTED_WOUND 29306
+
+#define MOB_ZOMBIE 16360
+
+const Position PosSummon[3] =
+{
+ {3267.9, -3172.1, 297.42, 0.94},
+ {3253.2, -3132.3, 297.42, 0},
+ {3308.3, -3185.8, 297.42, 1.58},
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_WOUND,
+ EVENT_ENRAGE,
+ EVENT_DECIMATE,
+ EVENT_BERSERK,
+ EVENT_SUMMON,
+};
+
+#define EMOTE_NEARBY " spots a nearby zombie to devour!"
+
+struct boss_gluthAI : public BossAI
+{
+ boss_gluthAI(Creature *c) : BossAI(c, BOSS_GLUTH)
+ {
+ // Do not let Gluth be affected by zombies' debuff
+ me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_INFECTED_WOUND, true);
+ }
+
+ void MoveInLineOfSight(Unit *who)
+ {
+ if (who->GetEntry() == MOB_ZOMBIE && me->IsWithinDistInMap(who, 7))
+ {
+ SetGazeOn(who);
+ // TODO: use a script text
+ me->MonsterTextEmote(EMOTE_NEARBY, 0, true);
+ }
+ else
+ BossAI::MoveInLineOfSight(who);
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ _EnterCombat();
+ events.ScheduleEvent(EVENT_WOUND, 10000);
+ events.ScheduleEvent(EVENT_ENRAGE, 15000);
+ events.ScheduleEvent(EVENT_DECIMATE, 105000);
+ events.ScheduleEvent(EVENT_BERSERK, 8*60000);
+ events.ScheduleEvent(EVENT_SUMMON, 15000);
+ }
+
+ void JustSummoned(Creature *summon)
+ {
+ if (summon->GetEntry() == MOB_ZOMBIE)
+ summon->AI()->AttackStart(me);
+ summons.Summon(summon);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictimWithGaze() || !CheckInRoom())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_WOUND:
+ DoCast(me->getVictim(), SPELL_MORTAL_WOUND);
+ events.ScheduleEvent(EVENT_WOUND, 10000);
+ break;
+ case EVENT_ENRAGE:
+ // TODO : Add missing text
+ DoCast(me, SPELL_ENRAGE);
+ events.ScheduleEvent(EVENT_ENRAGE, 15000);
+ break;
+ case EVENT_DECIMATE:
+ // TODO : Add missing text
+ DoCastAOE(SPELL_DECIMATE);
+ events.ScheduleEvent(EVENT_DECIMATE, 105000);
+ break;
+ case EVENT_BERSERK:
+ DoCast(me, SPELL_BERSERK);
+ events.ScheduleEvent(EVENT_BERSERK, 5*60000);
+ break;
+ case EVENT_SUMMON:
+ for (uint32 i = 0; i < RAID_MODE(1,2); ++i)
+ DoSummon(MOB_ZOMBIE, PosSummon[rand()%3]);
+ events.ScheduleEvent(EVENT_SUMMON, 10000);
+ break;
+ }
+ }
+
+ if (me->getVictim() && me->getVictim()->GetEntry() == MOB_ZOMBIE)
+ {
+ if (me->IsWithinMeleeRange(me->getVictim()))
+ {
+ me->Kill(me->getVictim());
+ me->ModifyHealth(me->GetMaxHealth() * 0.05f);
+ }
+ }
+ else
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_gluth(Creature* pCreature)
+{
+ return new boss_gluthAI (pCreature);
+}
+
+void AddSC_boss_gluth()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_gluth";
+ newscript->GetAI = &GetAI_boss_gluth;
+ newscript->RegisterSelf();
+}
+
diff --git a/src/server/scripts/northrend/naxxramas/boss_gothik.cpp b/src/server/scripts/northrend/naxxramas/boss_gothik.cpp
new file mode 100644
index 00000000000..d958ff24951
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_gothik.cpp
@@ -0,0 +1,582 @@
+/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+enum Yells
+{
+ SAY_SPEECH = -1533040,
+ SAY_KILL = -1533041,
+ SAY_DEATH = -1533042,
+ SAY_TELEPORT = -1533043
+};
+//Gothik
+enum Spells
+{
+ SPELL_HARVEST_SOUL = 28679,
+ SPELL_SHADOW_BOLT = 29317,
+ H_SPELL_SHADOW_BOLT = 56405,
+ SPELL_INFORM_LIVE_TRAINEE = 27892,
+ SPELL_INFORM_LIVE_KNIGHT = 27928,
+ SPELL_INFORM_LIVE_RIDER = 27935,
+ SPELL_INFORM_DEAD_TRAINEE = 27915,
+ SPELL_INFORM_DEAD_KNIGHT = 27931,
+ SPELL_INFORM_DEAD_RIDER = 27937
+};
+enum Creatures
+{
+ MOB_LIVE_TRAINEE = 16124,
+ MOB_LIVE_KNIGHT = 16125,
+ MOB_LIVE_RIDER = 16126,
+ MOB_DEAD_TRAINEE = 16127,
+ MOB_DEAD_KNIGHT = 16148,
+ MOB_DEAD_RIDER = 16150,
+ MOB_DEAD_HORSE = 16149
+};
+
+struct Waves { uint32 entry, time, mode; };
+// wave setups are not the same in heroic and normal difficulty,
+// mode is 0 only normal, 1 both and 2 only heroic
+// but this is handled in DoGothikSummon function
+const Waves waves[] =
+{
+ {MOB_LIVE_TRAINEE, 20000, 1},
+ {MOB_LIVE_TRAINEE, 20000, 1},
+ {MOB_LIVE_TRAINEE, 10000, 1},
+ {MOB_LIVE_KNIGHT, 10000, 1},
+ {MOB_LIVE_TRAINEE, 15000, 1},
+ {MOB_LIVE_KNIGHT, 5000, 1},
+ {MOB_LIVE_TRAINEE, 20000, 1},
+ {MOB_LIVE_TRAINEE, 0, 1},
+ {MOB_LIVE_KNIGHT, 10000, 1},
+ {MOB_LIVE_TRAINEE, 10000, 2},
+ {MOB_LIVE_RIDER, 10000, 0},
+ {MOB_LIVE_RIDER, 5000, 2},
+ {MOB_LIVE_TRAINEE, 5000, 0},
+ {MOB_LIVE_TRAINEE, 15000, 2},
+ {MOB_LIVE_KNIGHT, 15000, 0},
+ {MOB_LIVE_TRAINEE, 0, 0},
+ {MOB_LIVE_RIDER, 10000, 1},
+ {MOB_LIVE_KNIGHT, 10000, 1},
+ {MOB_LIVE_TRAINEE, 10000, 0},
+ {MOB_LIVE_RIDER, 10000, 2},
+ {MOB_LIVE_TRAINEE, 0, 2},
+ {MOB_LIVE_RIDER, 5000, 1},
+ {MOB_LIVE_TRAINEE, 0, 2},
+ {MOB_LIVE_KNIGHT, 5000, 1},
+ {MOB_LIVE_RIDER, 0, 2},
+ {MOB_LIVE_TRAINEE, 20000, 1},
+ {MOB_LIVE_RIDER, 0, 1},
+ {MOB_LIVE_KNIGHT, 0, 1},
+ {MOB_LIVE_TRAINEE, 25000, 2},
+ {MOB_LIVE_TRAINEE, 15000, 0},
+ {MOB_LIVE_TRAINEE, 25000, 0},
+ {0, 0, 1},
+};
+
+#define POS_Y_GATE -3360.78f
+#define POS_Y_WEST -3285.0f
+#define POS_Y_EAST -3434.0f
+#define POS_X_NORTH 2750.49f
+#define POS_X_SOUTH 2633.84f
+
+#define IN_LIVE_SIDE(who) (who->GetPositionY() < POS_Y_GATE)
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_SUMMON,
+ EVENT_HARVEST,
+ EVENT_BOLT,
+ EVENT_TELEPORT
+};
+enum Pos
+{
+ POS_LIVE = 6,
+ POS_DEAD = 5
+};
+
+const Position PosSummonLive[POS_LIVE] =
+{
+ {2669.7, -3428.76, 268.56, 1.6},
+ {2692.1, -3428.76, 268.56, 1.6},
+ {2714.4, -3428.76, 268.56, 1.6},
+ {2669.7, -3431.67, 268.56, 1.6},
+ {2692.1, -3431.67, 268.56, 1.6},
+ {2714.4, -3431.67, 268.56, 1.6},
+};
+
+const Position PosSummonDead[POS_DEAD] =
+{
+ {2725.1, -3310.0, 268.85, 3.4},
+ {2699.3, -3322.8, 268.60, 3.3},
+ {2733.1, -3348.5, 268.84, 3.1},
+ {2682.8, -3304.2, 268.85, 3.9},
+ {2664.8, -3340.7, 268.23, 3.7},
+};
+
+const float PosGroundLiveSide[4] = {2691.2, -3387.0, 267.68, 1.52};
+const float PosGroundDeadSide[4] = {2693.5, -3334.6, 267.68, 4.67};
+const float PosPlatform[4] = {2640.5, -3360.6, 285.26, 0};
+
+// Predicate function to check that the r efzr unit is NOT on the same side as the source.
+struct NotOnSameSide : public std::unary_function<Unit *, bool> {
+ bool m_inLiveSide;
+ NotOnSameSide(Unit *pSource) : m_inLiveSide(IN_LIVE_SIDE(pSource)) {}
+ bool operator() (const Unit *pTarget) {
+ return (m_inLiveSide != IN_LIVE_SIDE(pTarget));
+ }
+};
+
+struct boss_gothikAI : public BossAI
+{
+ boss_gothikAI(Creature *c) : BossAI(c, BOSS_GOTHIK) {}
+
+ uint32 waveCount;
+ typedef std::vector<Creature*> TriggerVct;
+ TriggerVct liveTrigger, deadTrigger;
+ bool mergedSides;
+ bool phaseTwo;
+ bool thirtyPercentReached;
+
+ std::vector<uint64> LiveTriggerGUID;
+ std::vector<uint64> DeadTriggerGUID;
+
+ void Reset()
+ {
+ LiveTriggerGUID.clear();
+ DeadTriggerGUID.clear();
+
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_DISABLE_MOVE);
+ me->SetReactState(REACT_PASSIVE);
+ if (instance)
+ instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
+ _Reset();
+ mergedSides = false;
+ phaseTwo = false;
+ thirtyPercentReached = false;
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ for (uint32 i = 0; i < POS_LIVE; ++i)
+ if (Creature *trigger = DoSummon(WORLD_TRIGGER, PosSummonLive[i]))
+ LiveTriggerGUID.push_back(trigger->GetGUID());
+ for (uint32 i = 0; i < POS_DEAD; ++i)
+ if (Creature *trigger = DoSummon(WORLD_TRIGGER, PosSummonDead[i]))
+ DeadTriggerGUID.push_back(trigger->GetGUID());
+
+ if (LiveTriggerGUID.size() < POS_LIVE || DeadTriggerGUID.size() < POS_DEAD)
+ {
+ error_log("Script Gothik: cannot summon triggers!");
+ EnterEvadeMode();
+ return;
+ }
+
+ _EnterCombat();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_DISABLE_MOVE);
+ waveCount = 0;
+ events.ScheduleEvent(EVENT_SUMMON, 30000);
+ DoTeleportTo(PosPlatform);
+ DoScriptText(SAY_SPEECH, me);
+ if (instance)
+ instance->SetData(DATA_GOTHIK_GATE, GO_STATE_READY);
+ }
+
+ void JustSummoned(Creature *summon)
+ {
+ if (summon->GetEntry() == WORLD_TRIGGER)
+ summon->setActive(true);
+ else if (!mergedSides)
+ {
+ summon->AI()->DoAction(me->HasReactState(REACT_PASSIVE) ? 1 : 0);
+ summon->AI()->EnterEvadeMode();
+ }
+ else
+ {
+ summon->AI()->DoAction(0);
+ summon->AI()->DoZoneInCombat();
+ }
+ summons.Summon(summon);
+ }
+
+ void SummonedCreatureDespawn(Creature *summon)
+ {
+ summons.Despawn(summon);
+ }
+
+ void KilledUnit(Unit* /*victim*/)
+ {
+ if (!(rand()%5))
+ DoScriptText(SAY_KILL, me);
+ }
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ LiveTriggerGUID.clear();
+ DeadTriggerGUID.clear();
+ _JustDied();
+ DoScriptText(SAY_DEATH, me);
+ if (instance)
+ instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
+ }
+
+ void DoGothikSummon(uint32 entry)
+ {
+ if (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ {
+ switch(entry)
+ {
+ case MOB_LIVE_TRAINEE:
+ {
+ if (Creature *LiveTrigger0 = Unit::GetCreature(*me, LiveTriggerGUID[0]))
+ DoSummon(MOB_LIVE_TRAINEE, LiveTrigger0, 1);
+ if (Creature *LiveTrigger1 = Unit::GetCreature(*me, LiveTriggerGUID[1]))
+ DoSummon(MOB_LIVE_TRAINEE, LiveTrigger1, 1);
+ if (Creature *LiveTrigger2 = Unit::GetCreature(*me, LiveTriggerGUID[2]))
+ DoSummon(MOB_LIVE_TRAINEE, LiveTrigger2, 1);
+ break;
+ }
+ case MOB_LIVE_KNIGHT:
+ {
+ if (Creature *LiveTrigger3 = Unit::GetCreature(*me, LiveTriggerGUID[3]))
+ DoSummon(MOB_LIVE_KNIGHT, LiveTrigger3, 1);
+ if (Creature *LiveTrigger5 = Unit::GetCreature(*me, LiveTriggerGUID[5]))
+ DoSummon(MOB_LIVE_KNIGHT, LiveTrigger5, 1);
+ break;
+ }
+ case MOB_LIVE_RIDER:
+ {
+ if (Creature *LiveTrigger4 = Unit::GetCreature(*me, LiveTriggerGUID[4]))
+ DoSummon(MOB_LIVE_RIDER, LiveTrigger4, 1);
+ break;
+ }
+ }
+ }
+ else
+ {
+ switch(entry)
+ {
+ case MOB_LIVE_TRAINEE:
+ {
+ if (Creature *LiveTrigger0 = Unit::GetCreature(*me, LiveTriggerGUID[4]))
+ DoSummon(MOB_LIVE_TRAINEE, LiveTrigger0, 1);
+ if (Creature *LiveTrigger1 = Unit::GetCreature(*me, LiveTriggerGUID[4]))
+ DoSummon(MOB_LIVE_TRAINEE, LiveTrigger1, 1);
+ break;
+ }
+ case MOB_LIVE_KNIGHT:
+ {
+ if (Creature *LiveTrigger5 = Unit::GetCreature(*me, LiveTriggerGUID[4]))
+ DoSummon(MOB_LIVE_KNIGHT, LiveTrigger5, 1);
+ break;
+ }
+ case MOB_LIVE_RIDER:
+ {
+ if (Creature *LiveTrigger4 = Unit::GetCreature(*me, LiveTriggerGUID[4]))
+ DoSummon(MOB_LIVE_RIDER, LiveTrigger4, 1);
+ break;
+ }
+ }
+ }
+ }
+
+ bool CheckGroupSplitted()
+ {
+ bool checklife = false;
+ bool checkdead = false;
+
+ Map* pMap = me->GetMap();
+ if (pMap && pMap->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = pMap->GetPlayers();
+ if (!PlayerList.isEmpty())
+ {
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource() && i->getSource()->isAlive() &&
+ i->getSource()->GetPositionX() <= POS_X_NORTH &&
+ i->getSource()->GetPositionX() >= POS_X_SOUTH &&
+ i->getSource()->GetPositionY() <= POS_Y_GATE &&
+ i->getSource()->GetPositionY() >= POS_Y_EAST)
+ {
+ checklife = true;
+ }
+ else if (i->getSource() && i->getSource()->isAlive() &&
+ i->getSource()->GetPositionX() <= POS_X_NORTH &&
+ i->getSource()->GetPositionX() >= POS_X_SOUTH &&
+ i->getSource()->GetPositionY() >= POS_Y_GATE &&
+ i->getSource()->GetPositionY() <= POS_Y_WEST)
+ {
+ checkdead = true;
+ }
+
+ if (checklife && checkdead)
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ void SpellHit(Unit * /*caster*/, const SpellEntry *spell)
+ {
+ uint32 spellId = 0;
+ switch(spell->Id)
+ {
+ case SPELL_INFORM_LIVE_TRAINEE: spellId = SPELL_INFORM_DEAD_TRAINEE; break;
+ case SPELL_INFORM_LIVE_KNIGHT: spellId = SPELL_INFORM_DEAD_KNIGHT; break;
+ case SPELL_INFORM_LIVE_RIDER: spellId = SPELL_INFORM_DEAD_RIDER; break;
+ }
+ if (spellId && me->isInCombat())
+ {
+ me->HandleEmoteCommand(EMOTE_ONESHOT_SPELLCAST);
+ if (Creature *pRandomDeadTrigger = Unit::GetCreature(*me, DeadTriggerGUID[rand() % POS_DEAD]))
+ me->CastSpell(pRandomDeadTrigger, spellId, true);
+ }
+ }
+
+ void SpellHitTarget(Unit *pTarget, const SpellEntry *spell)
+ {
+ if (!me->isInCombat())
+ return;
+
+ switch(spell->Id)
+ {
+ case SPELL_INFORM_DEAD_TRAINEE:
+ DoSummon(MOB_DEAD_TRAINEE, pTarget, 0);
+ break;
+ case SPELL_INFORM_DEAD_KNIGHT:
+ DoSummon(MOB_DEAD_KNIGHT, pTarget, 0);
+ break;
+ case SPELL_INFORM_DEAD_RIDER:
+ DoSummon(MOB_DEAD_RIDER, pTarget, 1.0f);
+ DoSummon(MOB_DEAD_HORSE, pTarget, 1.0f);
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateCombatState() || !CheckInRoom())
+ return;
+
+ events.Update(diff);
+
+ if (!thirtyPercentReached && HealthBelowPct(30) && phaseTwo)
+ {
+ thirtyPercentReached = true;
+ if (instance)
+ instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
+ }
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SUMMON:
+ if (waves[waveCount].entry)
+ {
+ if ((waves[waveCount].mode == 2) && (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL))
+ DoGothikSummon(waves[waveCount].entry);
+ else if ((waves[waveCount].mode == 0) && (getDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL))
+ DoGothikSummon(waves[waveCount].entry);
+ else if (waves[waveCount].mode == 1)
+ DoGothikSummon(waves[waveCount].entry);
+
+ // if group is not splitted, open gate and merge both sides at ~ 2 minutes (wave 11)
+ if (waveCount == 11)
+ {
+ if (!CheckGroupSplitted())
+ {
+ if (instance)
+ instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
+ summons.DoAction(0, 0);
+ summons.DoZoneInCombat();
+ mergedSides = true;
+ }
+ }
+
+ if (waves[waveCount].mode == 1)
+ events.ScheduleEvent(EVENT_SUMMON,waves[waveCount].time);
+ else if ((waves[waveCount].mode == 2) && (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL))
+ events.ScheduleEvent(EVENT_SUMMON,waves[waveCount].time);
+ else if ((waves[waveCount].mode == 0) && (getDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL))
+ events.ScheduleEvent(EVENT_SUMMON,waves[waveCount].time);
+ else
+ events.ScheduleEvent(EVENT_SUMMON, 0);
+
+ ++waveCount;
+ }
+ else
+ {
+ phaseTwo = true;
+ DoScriptText(SAY_TELEPORT, me);
+ DoTeleportTo(PosGroundLiveSide);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ summons.DoAction(0, 0);
+ summons.DoZoneInCombat();
+ events.ScheduleEvent(EVENT_BOLT, 1000);
+ events.ScheduleEvent(EVENT_HARVEST, urand(3000,15000));
+ events.ScheduleEvent(EVENT_TELEPORT, 20000);
+ }
+ break;
+ case EVENT_BOLT:
+ DoCast(me->getVictim(), RAID_MODE(SPELL_SHADOW_BOLT, H_SPELL_SHADOW_BOLT));
+ events.ScheduleEvent(EVENT_BOLT, 1000);
+ break;
+ case EVENT_HARVEST:
+ DoCast(me->getVictim(), SPELL_HARVEST_SOUL, true);
+ events.ScheduleEvent(EVENT_HARVEST, urand(20000,25000));
+ break;
+ case EVENT_TELEPORT:
+ if (!thirtyPercentReached)
+ {
+ me->AttackStop();
+ if (IN_LIVE_SIDE(me))
+ {
+ DoTeleportTo(PosGroundDeadSide);
+ }
+ else
+ {
+ DoTeleportTo(PosGroundLiveSide);
+ }
+
+ me->getThreatManager().resetAggro(NotOnSameSide(me));
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_NEAREST, 0))
+ {
+ me->getThreatManager().addThreat(pTarget, 100.0f);
+ AttackStart(pTarget);
+ }
+
+ events.ScheduleEvent(EVENT_TELEPORT, 20000);
+ }
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_gothik_minionAI : public CombatAI
+{
+ mob_gothik_minionAI(Creature *c) : CombatAI(c)
+ {
+ liveSide = IN_LIVE_SIDE(me);
+ }
+
+ bool liveSide;
+ bool gateClose;
+
+ bool isOnSameSide(const Unit *pWho)
+ {
+ return (liveSide == IN_LIVE_SIDE(pWho));
+ }
+
+ void DoAction(const int32 param)
+ {
+ gateClose = param;
+ }
+
+ void DamageTaken(Unit *attacker, uint32 &damage)
+ {
+ if (gateClose && !isOnSameSide(attacker))
+ damage = 0;
+ }
+
+ void JustDied(Unit * /*killer*/)
+ {
+ if (me->isSummon())
+ {
+ if (Unit *owner = CAST_SUM(me)->GetSummoner())
+ CombatAI::JustDied(owner);
+ }
+ }
+
+ void EnterEvadeMode()
+ {
+ if (!gateClose)
+ {
+ CombatAI::EnterEvadeMode();
+ return;
+ }
+
+ if (!_EnterEvadeMode())
+ return;
+
+ Map* pMap = me->GetMap();
+ if (pMap->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = pMap->GetPlayers();
+ if (!PlayerList.isEmpty())
+ {
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource() && i->getSource()->isAlive() && isOnSameSide(i->getSource()))
+ {
+ AttackStart(i->getSource());
+ return;
+ }
+ }
+ }
+ }
+
+ me->GetMotionMaster()->MoveIdle();
+ Reset();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (gateClose && (!isOnSameSide(me) || me->getVictim() && !isOnSameSide(me->getVictim())))
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ CombatAI::UpdateAI(diff);
+ }
+};
+
+CreatureAI* GetAI_boss_gothik(Creature* pCreature)
+{
+ return new boss_gothikAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_gothik_minion(Creature* pCreature)
+{
+ return new mob_gothik_minionAI (pCreature);
+}
+
+void AddSC_boss_gothik()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_gothik";
+ newscript->GetAI = &GetAI_boss_gothik;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_gothik_minion";
+ newscript->GetAI = &GetAI_mob_gothik_minion;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/naxxramas/boss_grobbulus.cpp b/src/server/scripts/northrend/naxxramas/boss_grobbulus.cpp
new file mode 100644
index 00000000000..7df01e18483
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_grobbulus.cpp
@@ -0,0 +1,142 @@
+/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+#define SPELL_BOMBARD_SLIME 28280
+
+#define SPELL_POISON_CLOUD 28240
+#define SPELL_MUTATING_INJECTION 28169
+#define SPELL_SLIME_SPRAY RAID_MODE(28157,54364)
+#define SPELL_BERSERK 26662
+#define SPELL_POISON_CLOUD_ADD 59116
+
+#define EVENT_BERSERK 1
+#define EVENT_CLOUD 2
+#define EVENT_INJECT 3
+#define EVENT_SPRAY 4
+
+#define MOB_FALLOUT_SLIME 16290
+
+struct boss_grobbulusAI : public BossAI
+{
+ boss_grobbulusAI(Creature *c) : BossAI(c, BOSS_GROBBULUS)
+ {
+ me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_POISON_CLOUD_ADD, true);
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ _EnterCombat();
+ events.ScheduleEvent(EVENT_CLOUD, 15000);
+ events.ScheduleEvent(EVENT_INJECT, 20000);
+ events.ScheduleEvent(EVENT_SPRAY, 15000+rand()%15000); //not sure
+ events.ScheduleEvent(EVENT_BERSERK, 12*60000);
+ }
+
+ void SpellHitTarget(Unit *pTarget, const SpellEntry *spell)
+ {
+ if (spell->Id == uint32(SPELL_SLIME_SPRAY))
+ {
+ if (TempSummon *slime = me->SummonCreature(MOB_FALLOUT_SLIME, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0))
+ DoZoneInCombat(slime);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_CLOUD:
+ DoCastAOE(SPELL_POISON_CLOUD);
+ events.ScheduleEvent(EVENT_CLOUD, 15000);
+ return;
+ case EVENT_BERSERK:
+ DoCastAOE(SPELL_BERSERK);
+ return;
+ case EVENT_SPRAY:
+ DoCastAOE(SPELL_SLIME_SPRAY);
+ events.ScheduleEvent(EVENT_SPRAY, 15000+rand()%15000);
+ return;
+ case EVENT_INJECT:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1))
+ if (!pTarget->HasAura(SPELL_MUTATING_INJECTION))
+ DoCast(pTarget, SPELL_MUTATING_INJECTION);
+ events.ScheduleEvent(EVENT_INJECT, 8000 + 12000 * ((float)me->GetHealth() / me->GetMaxHealth()));
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct npc_grobbulus_poison_cloudAI : public Scripted_NoMovementAI
+{
+ npc_grobbulus_poison_cloudAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature)
+ {
+ Reset();
+ }
+
+ uint32 Cloud_Timer;
+
+ void Reset()
+ {
+ Cloud_Timer = 1000;
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (Cloud_Timer <= diff)
+ {
+ DoCast(me, SPELL_POISON_CLOUD_ADD);
+ Cloud_Timer = 10000;
+ } else Cloud_Timer -= diff;
+ }
+};
+
+CreatureAI* GetAI_boss_grobbulus(Creature* pCreature)
+{
+ return new boss_grobbulusAI (pCreature);
+}
+
+CreatureAI* GetAI_npc_grobbulus_poison_cloud(Creature* pCreature)
+{
+ return new npc_grobbulus_poison_cloudAI(pCreature);
+}
+
+void AddSC_boss_grobbulus()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_grobbulus";
+ newscript->GetAI = &GetAI_boss_grobbulus;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_grobbulus_poison_cloud";
+ newscript->GetAI = &GetAI_npc_grobbulus_poison_cloud;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/naxxramas/boss_heigan.cpp b/src/server/scripts/northrend/naxxramas/boss_heigan.cpp
new file mode 100644
index 00000000000..1de9c0e00c8
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_heigan.cpp
@@ -0,0 +1,149 @@
+/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+#define SAY_AGGRO RAND(-1533109,-1533110,-1533111)
+#define SAY_SLAY -1533112
+#define SAY_TAUNT RAND(-1533113,-1533114,-1533115,-1533116,-1533117)
+#define SAY_DEATH -1533118
+
+#define SPELL_SPELL_DISRUPTION 29310
+#define SPELL_DECREPIT_FEVER RAID_MODE(29998,55011)
+#define SPELL_PLAGUE_CLOUD 29350
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_DISRUPT,
+ EVENT_FEVER,
+ EVENT_ERUPT,
+ EVENT_PHASE,
+};
+
+enum Phases
+{
+ PHASE_FIGHT = 1,
+ PHASE_DANCE,
+};
+
+struct boss_heiganAI : public BossAI
+{
+ boss_heiganAI(Creature *c) : BossAI(c, BOSS_HEIGAN) {}
+
+ uint32 eruptSection;
+ bool eruptDirection;
+ Phases phase;
+
+ void KilledUnit(Unit* /*Victim*/)
+ {
+ if (!(rand()%5))
+ DoScriptText(SAY_SLAY, me);
+ }
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ _JustDied();
+ DoScriptText(SAY_DEATH, me);
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ _EnterCombat();
+ DoScriptText(SAY_AGGRO, me);
+ EnterPhase(PHASE_FIGHT);
+ }
+
+ void EnterPhase(Phases newPhase)
+ {
+ phase = newPhase;
+ events.Reset();
+ eruptSection = 3;
+ if (phase == PHASE_FIGHT)
+ {
+ events.ScheduleEvent(EVENT_DISRUPT, urand(10000, 25000));
+ events.ScheduleEvent(EVENT_FEVER, urand(15000, 20000));
+ events.ScheduleEvent(EVENT_PHASE, 90000);
+ events.ScheduleEvent(EVENT_ERUPT, 15000);
+ }
+ else
+ {
+ float x, y, z, o;
+ me->GetHomePosition(x, y, z, o);
+ me->NearTeleportTo(x, y, z, o);
+ DoCastAOE(SPELL_PLAGUE_CLOUD);
+ events.ScheduleEvent(EVENT_PHASE, 45000);
+ events.ScheduleEvent(EVENT_ERUPT, 8000);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim() || !CheckInRoom())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_DISRUPT:
+ DoCastAOE(SPELL_SPELL_DISRUPTION);
+ events.ScheduleEvent(EVENT_DISRUPT, urand(5000, 10000));
+ break;
+ case EVENT_FEVER:
+ DoCastAOE(SPELL_DECREPIT_FEVER);
+ events.ScheduleEvent(EVENT_FEVER, urand(20000, 25000));
+ break;
+ case EVENT_PHASE:
+ // TODO : Add missing texts for both phase switches
+ EnterPhase(phase == PHASE_FIGHT ? PHASE_DANCE : PHASE_FIGHT);
+ break;
+ case EVENT_ERUPT:
+ instance->SetData(DATA_HEIGAN_ERUPT, eruptSection);
+ TeleportCheaters();
+
+ if (eruptSection == 0)
+ eruptDirection = true;
+ else if (eruptSection == 3)
+ eruptDirection = false;
+
+ eruptDirection ? ++eruptSection : --eruptSection;
+
+ events.ScheduleEvent(EVENT_ERUPT, phase == PHASE_FIGHT ? 10000 : 3000);
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_heigan(Creature* pCreature)
+{
+ return new boss_heiganAI (pCreature);
+}
+
+void AddSC_boss_heigan()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_heigan";
+ newscript->GetAI = &GetAI_boss_heigan;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/naxxramas/boss_highlord_mograine.cpp b/src/server/scripts/northrend/naxxramas/boss_highlord_mograine.cpp
new file mode 100644
index 00000000000..4eb72a3780e
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_highlord_mograine.cpp
@@ -0,0 +1,179 @@
+/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Boss_Highlord_Mograine
+SD%Complete: 100
+SDComment: SCRIPT OBSOLETE
+SDCategory: Naxxramas
+EndScriptData */
+
+#include "precompiled.h"
+
+//All horsemen
+#define SPELL_SHIELDWALL 29061
+#define SPELL_BESERK 26662
+
+// highlord mograine
+#define SPELL_MARK_OF_MOGRAINE 28834
+#define SPELL_RIGHTEOUS_FIRE 28882 // Applied as a 25% chance on melee hit to proc. me->GetVictim()
+
+#define SAY_TAUNT1 "Enough prattling. Let them come! We shall grind their bones to dust."
+#define SAY_TAUNT2 "Conserve your anger! Harness your rage! You will all have outlets for your frustration soon enough."
+#define SAY_TAUNT3 "Life is meaningless. It is in death that we are truly tested."
+#define SAY_AGGRO1 "You seek death?"
+#define SAY_AGGRO2 "None shall pass!"
+#define SAY_AGGRO3 "Be still!"
+#define SAY_SLAY1 "You will find no peace in death."
+#define SAY_SLAY2 "The master's will is done."
+#define SAY_SPECIAL "Bow to the might of the Highlord!"
+#define SAY_DEATH "I... am... released! Perhaps it's not too late to - noo! I need... more time..."
+
+#define SOUND_TAUNT1 8842
+#define SOUND_TAUNT2 8843
+#define SOUND_TAUNT3 8844
+#define SOUND_AGGRO1 8835
+#define SOUND_AGGRO2 8836
+#define SOUND_AGGRO3 8837
+#define SOUND_SLAY1 8839
+#define SOUND_SLAY2 8840
+#define SOUND_SPECIAL 8841
+#define SOUND_DEATH 8838
+
+#define SPIRIT_OF_MOGRAINE 16775
+
+struct TRINITY_DLL_DECL boss_highlord_mograineAI : public ScriptedAI
+{
+ boss_highlord_mograineAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 Mark_Timer;
+ uint32 RighteousFire_Timer;
+ bool ShieldWall1;
+ bool ShieldWall2;
+
+ void Reset()
+ {
+ Mark_Timer = 20000; // First Horsemen Mark is applied at 20 sec.
+ RighteousFire_Timer = 2000; // applied approx 1 out of 4 attacks
+ ShieldWall1 = true;
+ ShieldWall2 = true;
+ }
+
+ void InitialYell()
+ {
+ if (!me->isInCombat())
+ {
+ switch(rand()%3)
+ {
+ case 0:
+ DoYell(SAY_AGGRO1,LANG_UNIVERSAL,NULL);
+ DoPlaySoundToSet(me,SOUND_AGGRO1);
+ break;
+ case 1:
+ DoYell(SAY_AGGRO2,LANG_UNIVERSAL,NULL);
+ DoPlaySoundToSet(me,SOUND_AGGRO2);
+ break;
+ case 2:
+ DoYell(SAY_AGGRO3,LANG_UNIVERSAL,NULL);
+ DoPlaySoundToSet(me,SOUND_AGGRO3);
+ break;
+ }
+ }
+ }
+
+ void KilledUnit()
+ {
+ switch(rand()%2)
+ {
+ case 0:
+ DoYell(SAY_SLAY1,LANG_UNIVERSAL,NULL);
+ DoPlaySoundToSet(me,SOUND_SLAY1);
+ break;
+ case 1:
+ DoYell(SAY_SLAY2,LANG_UNIVERSAL,NULL);
+ DoPlaySoundToSet(me,SOUND_SLAY2);
+ break;
+ }
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ DoYell(SAY_DEATH,LANG_UNIVERSAL,NULL);
+ DoPlaySoundToSet(me, SOUND_DEATH);
+ }
+
+ void Aggro(Unit *who)
+ {
+ InitialYell();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ // Mark of Mograine
+ if (Mark_Timer < diff)
+ {
+ DoCast(me->getVictim(),SPELL_MARK_OF_MOGRAINE);
+ Mark_Timer = 12000;
+ }else Mark_Timer -= diff;
+
+ // Shield Wall - All 4 horsemen will shield wall at 50% hp and 20% hp for 20 seconds
+ if (ShieldWall1 && (me->GetHealth()*100 / me->GetMaxHealth()) < 50)
+ {
+ if (ShieldWall1)
+ {
+ DoCast(me,SPELL_SHIELDWALL);
+ ShieldWall1 = false;
+ }
+ }
+ if (ShieldWall2 && (me->GetHealth()*100 / me->GetMaxHealth()) < 20)
+ {
+ if (ShieldWall2)
+ {
+ DoCast(me,SPELL_SHIELDWALL);
+ ShieldWall2 = false;
+ }
+ }
+
+ // Righteous Fire
+ if (RighteousFire_Timer < diff)
+ {
+ if (rand()%4 == 1) // 1/4
+ {
+ DoCast(me->getVictim(),SPELL_RIGHTEOUS_FIRE);
+ }
+ RighteousFire_Timer = 2000;
+ }else RighteousFire_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+CreatureAI* GetAI_boss_highlord_mograine(Creature* pCreature)
+{
+ return new boss_highlord_mograineAI (pCreature);
+}
+
+void AddSC_boss_highlord_mograine()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="boss_highlord_mograine";
+ newscript->GetAI = &GetAI_boss_highlord_mograine;
+ newscript->RegisterSelf();
+}
+
diff --git a/src/server/scripts/northrend/naxxramas/boss_kelthuzad.cpp b/src/server/scripts/northrend/naxxramas/boss_kelthuzad.cpp
new file mode 100644
index 00000000000..bfcd0636298
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_kelthuzad.cpp
@@ -0,0 +1,706 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Boss_KelThuzad
+SD%Complete: 80%
+SDComment: VERIFY SCRIPT
+SDCategory: Naxxramas
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+enum Yells
+{
+ //when shappiron dies. dialog between kel and lich king (in this order)
+ SAY_SAPP_DIALOG1 = -1533084, //not used
+ SAY_SAPP_DIALOG2_LICH = -1533085, //not used
+ SAY_SAPP_DIALOG3 = -1533086, //not used
+ SAY_SAPP_DIALOG4_LICH = -1533087, //not used
+ SAY_SAPP_DIALOG5 = -1533088, //not used
+ SAY_CAT_DIED = -1533089, //when cat dies, not used
+ //when each of the 4 wing bosses dies
+ SAY_TAUNT1 = -1533090, //not used
+ SAY_TAUNT2 = -1533091, //not used
+ SAY_TAUNT3 = -1533092, //not used
+ SAY_TAUNT4 = -1533093, //not used
+ SAY_SUMMON_MINIONS = -1533105, //start of phase 1
+ SAY_AGGRO_1 = -1533094, //start of phase 2
+ SAY_AGGRO_2 = -1533095,
+ SAY_AGGRO_3 = -1533096,
+ SAY_SLAY_1 = -1533097,
+ SAY_SLAY_2 = -1533098,
+ SAY_DEATH = -1533099,
+ SAY_CHAIN_1 = -1533100,
+ SAY_CHAIN_2 = -1533101,
+ SAY_FROST_BLAST = -1533102,
+ SAY_SPECIAL_1 = -1533106,
+ SAY_SPECIAL_2 = -1533107,
+ SAY_SPECIAL_3 = -1533108,
+ SAY_REQUEST_AID = -1533103, //start of phase 3
+ SAY_ANSWER_REQUEST = -1533104 //lich king answer
+};
+enum Event
+{
+ EVENT_NONE,
+ EVENT_BOLT,
+ EVENT_NOVA,
+ EVENT_CHAIN,
+ EVENT_CHAINED_SPELL,
+ EVENT_DETONATE,
+ EVENT_FISSURE,
+ EVENT_BLAST,
+
+ EVENT_WASTE,
+ EVENT_ABOMIN,
+ EVENT_WEAVER,
+ EVENT_ICECROWN,
+ EVENT_TRIGGER,
+
+ EVENT_PHASE,
+};
+
+enum Spells
+{
+ SPELL_FROST_BOLT = 28478,
+ H_SPELL_FROST_BOLT = 55802,
+ SPELL_FROST_BOLT_AOE = 28479,
+ H_SPELL_FROST_BOLT_AOE = 55807,
+ SPELL_SHADOW_FISURE = 27810,
+ SPELL_VOID_BLAST = 27812,
+ SPELL_MANA_DETONATION = 27819,
+ SPELL_FROST_BLAST = 27808,
+ SPELL_CHAINS_OF_KELTHUZAD = 28410, //28408 script effect
+ SPELL_KELTHUZAD_CHANNEL = 29423,
+ SPELL_BERSERK = 28498,
+
+ //spells for chained
+ //warlock
+ SPELL_CURSE_OF_AGONY = 47864,
+ SPELL_SHADOW_BOLT = 47809,
+ //shaman
+ SPELL_EARTH_SHOCK = 49231,
+ SPELL_HEALING_WAVE = 49273,
+ //mage
+ SPELL_FROST_FIREBOLT = 47610,
+ SPELL_ARCANE_MISSILES = 42846,
+ //rogue
+ SPELL_HEMORRHAGE = 48660,
+ SPELL_MUTILATE = 48666,
+ //paladin
+ SPELL_HOLY_SHOCK = 48825,
+ SPELL_HAMMER_OF_JUSTICE = 10308,
+ //priest
+ SPELL_VAMPIRIC_TOUCH = 48160,
+ SPELL_RENEW = 48068,
+ //hunter
+ SPELL_MULTI_SHOT = 49048,
+ SPELL_VOLLEY = 58434,
+ //warrior
+ SPELL_BLADESTORM = 46924,
+ SPELL_CLEAVE = 47520,
+ //druid
+ SPELL_MOONFIRE = 48463,
+ SPELL_LIFEBLOOM = 48451,
+ //death knight
+ SPELL_PLAGUE_STRIKE = 49921,
+ SPELL_HOWLING_BLAST = 51411,
+};
+
+enum Creatures
+{
+ NPC_WASTE = 16427, // Soldiers of the Frozen Wastes
+ NPC_ABOMINATION = 16428, // Unstoppable Abominations
+ NPC_WEAVER = 16429, // Soul Weavers
+ NPC_ICECROWN = 16441 // Guardians of Icecrown
+};
+
+const Position Pos[12] =
+{
+ {3783.272705, -5062.697266, 143.711203, 3.617599}, //LEFT_FAR
+ {3730.291260, -5027.239258, 143.956909, 4.461900}, //LEFT_MIDDLE
+ {3757.6, -5172.0, 143.7, 1.97}, //WINDOW_PORTAL05
+ {3759.355225, -5174.128418, 143.802383, 2.170104}, //RIGHT_FAR
+ {3700.724365, -5185.123047, 143.928024, 1.309310}, //RIGHT_MIDDLE
+ {3700.86, -5181.29, 143.928024, 1.42}, //WINDOW_PORTAL04
+ {3754.431396, -5080.727734, 142.036316, 3.736189}, //LEFT_FAR
+ {3724.396484, -5061.330566, 142.032700, 4.564785}, //LEFT_MIDDLE
+ {3732.02, -5028.53, 143.92, 4.49}, //WINDOW_PORTAL02
+ {3687.571777, -5126.831055, 142.017807, 0.604023}, //RIGHT_FAR
+ {3707.990733, -5151.450195, 142.032562, 1.376855}, //RIGHT_MIDDLE
+ {3782.76, -5062.97, 143.79, 3.82}, //WINDOW_PORTAL03
+};
+
+//creatures in corners
+//Unstoppable Abominations
+#define MAX_ABOMINATIONS 21
+const Position PosAbominations[MAX_ABOMINATIONS] =
+{
+ {3755.52, -5155.22, 143.480, 2.0},
+ {3744.35, -5164.03, 143.590, 2.00},
+ {3749.28, -5159.04, 143.190, 2.0},
+ {3774.47, -5076.28, 143.528, 2.15912},
+ {3765.94, -5074.15, 143.186, 3.77233},
+ {3763.15, -5063.36, 143.694, 3.77233},
+ {3737.81, -5045.69, 143.709, 4.9033},
+ {3728.13, -5045.01, 143.355, 1.45069},
+ {3721.56, -5048.35, 143.542, 1.45069},
+ {3689.55, -5049.66, 143.637, 5.2104},
+ {3681.71, -5053.03, 143.242, 2.47957},
+ {3677.64, -5061.44, 143.358, 2.47957},
+ {3654.2, -5090.87, 143.469, 1.0313},
+ {3650.39, -5097.45, 143.496, 2.5047},
+ {3658.7, -5103.59, 143.607, 3.3278},
+ {3659.02, -5133.97, 143.624, 3.84538},
+ {3666.33, -5139.34, 143.183, 3.84538},
+ {3669.74, -5149.63, 143.678, 0.528643},
+ {3695.53, -5169.53, 143.671, 2.11908},
+ {3701.98, -5166.51, 143.395, 1.24257},
+ {3709.62, -5169.15, 143.576, 5.97695},
+};
+
+//Soldiers of the Frozen Wastes
+#define MAX_WASTES 49
+const Position PosWastes[MAX_WASTES] =
+{
+ {3754.41, -5147.24, 143.204, 2.0},
+ {3754.68, -5156.17, 143.418, 2.0},
+ {3757.91, -5160.12, 143.503, 2.0},
+ {3752.67, -5164.6, 143.395, 2.0},
+ {3745.42, -5164.47, 143.565, 2.74587},
+ {3741.2, -5155.92, 143.17, 5.29134},
+ {3746.57, -5148.82, 143.176, 5.07772},
+ {3778.14, -5070.1, 143.568, 3.16208},
+ {3775.09, -5078.97, 143.65, 2.81022},
+ {3773.54, -5083.47, 143.758, 3.21549},
+ {3765, -5078.29, 143.176, 4.36688},
+ {3766.94, -5072.63, 143.184, 5.27951},
+ {3762.68, -5064.94, 143.635, 3.95297},
+ {3769.9, -5059.94, 143.74, 3.36549},
+ {3736.33, -5042.18, 143.643, 5.9471},
+ {3727.51, -5040.58, 143.502, 0.871859},
+ {3719.89, -5049.64, 143.58, 4.75172},
+ {3720.69, -5044.43, 143.662, 1.87245},
+ {3725.69, -5048.99, 143.363, 2.48271},
+ {3732.33, -5054.01, 143.44, 3.59405},
+ {3738.09, -5051.06, 143.718, 4.70931},
+ {3682.76, -5063.5, 143.175, 0.636238},
+ {3686.7, -5060.58, 143.18, 0.636238},
+ {3682.45, -5057.21, 143.184, 5.61252},
+ {3677.57, -5053.34, 143.369, 1.52531},
+ {3677.3, -5062.26, 143.369, 2.73482},
+ {3691.21, -5053.02, 143.421, 5.93218},
+ {3685.22, -5053.34, 143.314, 4.70303},
+ {3652.11, -5088.47, 143.555, 0.793317},
+ {3648.23, -5093.21, 143.311, 1.18837},
+ {3648.14, -5100.11, 143.632, 2.12221},
+ {3653.88, -5099.7, 143.558, 3.04348},
+ {3661.23, -5100.33, 143.42, 4.08335},
+ {3663.49, -5092.77, 143.346, 4.47134},
+ {3661.85, -5087.99, 143.571, 1.0148},
+ {3664.56, -5149.01, 143.532, 0.0762528},
+ {3665.01, -5142.04, 143.201, 1.72009},
+ {3671.15, -5142.92, 143.174, 4.81535},
+ {3670.18, -5134.38, 143.177, 5.37534},
+ {3664.33, -5131.69, 143.262, 5.39576},
+ {3658.21, -5133.63, 143.662, 1.3863},
+ {3659.7, -5144.49, 143.363, 2.32328},
+ {3705.71, -5179.63, 143.746, 1.06743},
+ {3696.77, -5177.45, 143.759, 5.36748},
+ {3700.97, -5173.13, 143.52, 3.26575},
+ {3708.53, -5172.19, 143.573, 3.26575},
+ {3712.49, -5167.62, 143.657, 5.63295},
+ {3704.89, -5161.84, 143.239, 5.63295},
+ {3695.66, -5164.63, 143.674, 1.54416},
+};
+
+//Soul Weavers
+#define MAX_WEAVERS 7
+const Position PosWeavers[MAX_WEAVERS] =
+{
+ {3752.45, -5168.35, 143.562, 1.6094},
+ {3772.2, -5070.04, 143.329, 1.93686},
+ {3732.28, -5032.88, 143.771, 3.08355},
+ {3689.05, -5055.7, 143.172, 6.09554},
+ {3649.45, -5093.17, 143.299, 2.51805},
+ {3659.7, -5144.49, 143.363, 4.08806},
+ {3704.71, -5175.96, 143.597, 3.36549},
+};
+
+// predicate function to select not charmed target
+struct NotCharmedTargetSelector : public std::unary_function<Unit *, bool> {
+ NotCharmedTargetSelector() {}
+
+ bool operator() (const Unit *pTarget) {
+ return (!pTarget->isCharmed());
+ }
+};
+
+struct boss_kelthuzadAI : public BossAI
+{
+ boss_kelthuzadAI(Creature* c) : BossAI(c, BOSS_KELTHUZAD), spawns(c)
+ {
+ uiFaction = me->getFaction();
+ }
+
+ uint32 Phase;
+ uint32 uiGuardiansOfIcecrownTimer;
+ uint32 uiFaction;
+
+ uint8 nGuardiansOfIcecrownCount;
+ uint8 nAbomination;
+ uint8 nWeaver;
+
+ std::map<uint64, float> chained;
+
+ uint64 PortalsGUID[4];
+ uint64 KTTriggerGUID;
+
+ SummonList spawns; // adds spawn by the trigger. kept in separated list (i.e. not in summons)
+
+ void Reset()
+ {
+ _Reset();
+
+ PortalsGUID[0] = PortalsGUID[1] = PortalsGUID[2] = PortalsGUID[3] = 0;
+ KTTriggerGUID = 0;
+
+ me->setFaction(35);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
+ std::map<uint64, float>::const_iterator itr;
+ for (itr = chained.begin(); itr != chained.end(); ++itr)
+ {
+ if (Player* charmed = Unit::GetPlayer((*itr).first))
+ charmed->SetFloatValue(OBJECT_FIELD_SCALE_X, (*itr).second);
+ }
+
+ chained.clear();
+ spawns.DespawnAll();
+
+ FindGameObjects();
+
+ if (GameObject *pKTTrigger = me->GetMap()->GetGameObject(KTTriggerGUID))
+ {
+ pKTTrigger->ResetDoorOrButton();
+ pKTTrigger->SetPhaseMask(1, true);
+ }
+
+ for (uint8 i = 0; i <= 3; ++i)
+ {
+ if (GameObject *pPortal = me->GetMap()->GetGameObject(PortalsGUID[i]))
+ {
+ if (!((pPortal->getLootState() == GO_READY) || (pPortal->getLootState() == GO_NOT_READY)))
+ pPortal->ResetDoorOrButton();
+ }
+ }
+
+ nGuardiansOfIcecrownCount = 0;
+ uiGuardiansOfIcecrownTimer = 5000; //5 seconds for summoning each Guardian of Icecrown in phase 3
+
+ Phase = 0;
+ nAbomination = 0;
+ nWeaver = 0;
+ }
+
+ void KilledUnit()
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ _JustDied();
+ DoScriptText(SAY_DEATH, me);
+
+ std::map<uint64, float>::const_iterator itr;
+ for (itr = chained.begin(); itr != chained.end(); ++itr)
+ {
+ if (Player* pPlayer = Unit::GetPlayer((*itr).first))
+ pPlayer->SetFloatValue(OBJECT_FIELD_SCALE_X, (*itr).second);
+ }
+ chained.clear();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ me->setFaction(uiFaction);
+
+ _EnterCombat();
+ FindGameObjects();
+ for (uint8 i = 0; i <= 3; ++i)
+ {
+ if (GameObject *pPortal = me->GetMap()->GetGameObject(PortalsGUID[i]))
+ pPortal->ResetDoorOrButton();
+ }
+ DoCast(me, SPELL_KELTHUZAD_CHANNEL, false);
+ DoScriptText(SAY_SUMMON_MINIONS, me);
+ Phase = 1;
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetFloatValue(UNIT_FIELD_COMBATREACH, 4);
+ me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 4);
+ events.ScheduleEvent(EVENT_TRIGGER, 5000);
+ events.ScheduleEvent(EVENT_WASTE, 15000);
+ events.ScheduleEvent(EVENT_ABOMIN, 30000);
+ events.ScheduleEvent(EVENT_WEAVER, 50000);
+ events.ScheduleEvent(EVENT_PHASE, 228000);
+ }
+
+ void FindGameObjects()
+ {
+ PortalsGUID[0] = instance ? instance->GetData64(DATA_KELTHUZAD_PORTAL01) : 0;
+ PortalsGUID[1] = instance ? instance->GetData64(DATA_KELTHUZAD_PORTAL02) : 0;
+ PortalsGUID[2] = instance ? instance->GetData64(DATA_KELTHUZAD_PORTAL03) : 0;
+ PortalsGUID[3] = instance ? instance->GetData64(DATA_KELTHUZAD_PORTAL04) : 0;
+ KTTriggerGUID = instance ? instance->GetData64(DATA_KELTHUZAD_TRIGGER) : 0;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateCombatState())
+ return;
+
+ events.Update(diff);
+
+ if (Phase == 1)
+ {
+ while (uint32 eventId = events.GetEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_WASTE:
+ DoSummon(NPC_WASTE, Pos[RAND(0,3,6,9)]);
+ events.RepeatEvent(urand(2000,5000));
+ break;
+ case EVENT_ABOMIN:
+ if (nAbomination < 8)
+ {
+ DoSummon(NPC_ABOMINATION, Pos[RAND(1,4,7,10)]);
+ nAbomination++;
+ events.RepeatEvent(20000);
+ }
+ else
+ events.PopEvent();
+ break;
+ case EVENT_WEAVER:
+ if (nWeaver < 8)
+ {
+ DoSummon(NPC_WEAVER, Pos[RAND(0,3,6,9)]);
+ nWeaver++;
+ events.RepeatEvent(25000);
+ }
+ else
+ events.PopEvent();
+ break;
+ case EVENT_TRIGGER:
+ if (GameObject *pKTTrigger = me->GetMap()->GetGameObject(KTTriggerGUID))
+ pKTTrigger->SetPhaseMask(2, true);
+ events.PopEvent();
+ break;
+ case EVENT_PHASE:
+ events.Reset();
+ DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me);
+ spawns.DespawnAll();
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
+ me->CastStop();
+
+ DoStartMovement(me->getVictim());
+ events.ScheduleEvent(EVENT_BOLT, urand(5000,10000));
+ events.ScheduleEvent(EVENT_NOVA, 15000);
+ events.ScheduleEvent(EVENT_DETONATE, urand(30000,40000));
+ events.ScheduleEvent(EVENT_FISSURE, urand(10000,30000));
+ events.ScheduleEvent(EVENT_BLAST, urand(60000,120000));
+ if (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ events.ScheduleEvent(EVENT_CHAIN, urand(30000,60000));
+ Phase = 2;
+ break;
+ default:
+ events.PopEvent();
+ break;
+ }
+ }
+ }
+ else
+ {
+ //start phase 3 when we are 45% health
+ if (Phase != 3)
+ {
+ if (HealthBelowPct(45))
+ {
+ Phase = 3 ;
+ DoScriptText(SAY_REQUEST_AID, me);
+ //here Lich King should respond to KelThuzad but I don't know which Creature to make talk
+ //so for now just make Kelthuzad says it.
+ DoScriptText(SAY_ANSWER_REQUEST, me);
+
+ for (uint8 i = 0; i <= 3; ++i)
+ {
+ if (GameObject *pPortal = me->GetMap()->GetGameObject(PortalsGUID[i]))
+ {
+ if (pPortal->getLootState() == GO_READY)
+ pPortal->UseDoorOrButton();
+ }
+ }
+ }
+ }
+ else if (nGuardiansOfIcecrownCount < RAID_MODE(2,4))
+ {
+ if (uiGuardiansOfIcecrownTimer <= diff)
+ {
+ // TODO : Add missing text
+ if (Creature* pGuardian = DoSummon(NPC_ICECROWN, Pos[RAND(2,5,8,11)]))
+ pGuardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2);
+ ++nGuardiansOfIcecrownCount;
+ uiGuardiansOfIcecrownTimer = 5000;
+ }
+ else uiGuardiansOfIcecrownTimer -= diff;
+ }
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ if (uint32 eventId = events.GetEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_BOLT:
+ DoCastVictim(RAID_MODE(SPELL_FROST_BOLT,H_SPELL_FROST_BOLT));
+ events.RepeatEvent(urand(5000,10000));
+ break;
+ case EVENT_NOVA:
+ DoCastAOE(RAID_MODE(SPELL_FROST_BOLT_AOE,H_SPELL_FROST_BOLT_AOE));
+ events.RepeatEvent(urand(15000,30000));
+ break;
+ case EVENT_CHAIN:
+ {
+ uint32 count = urand(1,3);
+ for (uint8 i = 1; i <= count; i++)
+ {
+ Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 200, true);
+ if (pTarget && !pTarget->isCharmed() && (chained.find(pTarget->GetGUID()) == chained.end()))
+ {
+ DoCast(pTarget, SPELL_CHAINS_OF_KELTHUZAD);
+ float scale = pTarget->GetFloatValue(OBJECT_FIELD_SCALE_X);
+ chained.insert(std::make_pair(pTarget->GetGUID(), scale));
+ pTarget->SetFloatValue(OBJECT_FIELD_SCALE_X, scale * 2);
+ events.ScheduleEvent(EVENT_CHAINED_SPELL, 2000); //core has 2000ms to set unit flag charm
+ }
+ }
+ if (!chained.empty())
+ DoScriptText(RAND(SAY_CHAIN_1,SAY_CHAIN_2), me);
+ events.RepeatEvent(urand(100000,180000));
+ break;
+ }
+ case EVENT_CHAINED_SPELL:
+ {
+ std::map<uint64, float>::iterator itr;
+ for (itr = chained.begin(); itr != chained.end();)
+ {
+ if (Unit* player = Unit::GetPlayer((*itr).first))
+ {
+ if (!player->isCharmed())
+ {
+ player->SetFloatValue(OBJECT_FIELD_SCALE_X, (*itr).second);
+ std::map<uint64, float>::iterator next = itr;
+ ++next;
+ chained.erase(itr);
+ itr = next;
+ continue;
+ }
+
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_TOPAGGRO, 0, NotCharmedTargetSelector()))
+ {
+ switch(player->getClass())
+ {
+ case CLASS_DRUID:
+ if (urand(0,1))
+ player->CastSpell(pTarget, SPELL_MOONFIRE, false);
+ else
+ player->CastSpell(me, SPELL_LIFEBLOOM, false);
+ break;
+ case CLASS_HUNTER:
+ player->CastSpell(pTarget, RAND(SPELL_MULTI_SHOT, SPELL_VOLLEY), false);
+ break;
+ case CLASS_MAGE:
+ player->CastSpell(pTarget, RAND(SPELL_FROST_FIREBOLT, SPELL_ARCANE_MISSILES), false);
+ break;
+ case CLASS_WARLOCK:
+ player->CastSpell(pTarget, RAND(SPELL_CURSE_OF_AGONY, SPELL_SHADOW_BOLT), true);
+ break;
+ case CLASS_WARRIOR:
+ player->CastSpell(pTarget, RAND(SPELL_BLADESTORM, SPELL_CLEAVE), false);
+ break;
+ case CLASS_PALADIN:
+ if (urand(0,1))
+ player->CastSpell(pTarget, SPELL_HAMMER_OF_JUSTICE, false);
+ else
+ player->CastSpell(me, SPELL_HOLY_SHOCK, false);
+ break;
+ case CLASS_PRIEST:
+ if (urand(0,1))
+ player->CastSpell(pTarget, SPELL_VAMPIRIC_TOUCH, false);
+ else
+ player->CastSpell(me, SPELL_RENEW, false);
+ break;
+ case CLASS_SHAMAN:
+ if (urand(0,1))
+ player->CastSpell(pTarget, SPELL_EARTH_SHOCK, false);
+ else
+ player->CastSpell(me, SPELL_HEALING_WAVE, false);
+ break;
+ case CLASS_ROGUE:
+ player->CastSpell(pTarget, RAND(SPELL_HEMORRHAGE, SPELL_MUTILATE), false);
+ break;
+ case CLASS_DEATH_KNIGHT:
+ if (urand(0,1))
+ player->CastSpell(pTarget, SPELL_PLAGUE_STRIKE, true);
+ else
+ player->CastSpell(pTarget, SPELL_HOWLING_BLAST, true);
+ break;
+ }
+ }
+ }
+ ++itr;
+ }
+
+ if (chained.empty())
+ events.PopEvent();
+ else
+ events.RepeatEvent(5000);
+
+ break;
+ }
+ case EVENT_DETONATE:
+ {
+ std::vector<Unit*> unitList;
+ std::list<HostileReference*> *threatList = &me->getThreatManager().getThreatList();
+ for (std::list<HostileReference*>::const_iterator itr = threatList->begin(); itr != threatList->end(); ++itr)
+ {
+ if ((*itr)->getTarget()->GetTypeId() == TYPEID_PLAYER
+ && (*itr)->getTarget()->getPowerType() == POWER_MANA
+ && (*itr)->getTarget()->GetPower(POWER_MANA))
+ unitList.push_back((*itr)->getTarget());
+ }
+
+ if (!unitList.empty())
+ {
+ std::vector<Unit*>::const_iterator itr = unitList.begin();
+ advance(itr, rand()%unitList.size());
+ DoCast(*itr, SPELL_MANA_DETONATION);
+ DoScriptText(RAND(SAY_SPECIAL_1,SAY_SPECIAL_2,SAY_SPECIAL_3), me);
+ }
+
+ events.RepeatEvent(urand(20000,50000));
+ break;
+ }
+ case EVENT_FISSURE:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
+ DoCast(pTarget, SPELL_SHADOW_FISURE);
+ events.RepeatEvent(urand(10000,45000));
+ break;
+ case EVENT_BLAST:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, RAID_MODE(1,0), 0, true))
+ DoCast(pTarget, SPELL_FROST_BLAST);
+ if (rand()%2)
+ DoScriptText(SAY_FROST_BLAST, me);
+ events.RepeatEvent(urand(30000,90000));
+ break;
+ default:
+ events.PopEvent();
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_kelthuzadAI(Creature* pCreature)
+{
+ return new boss_kelthuzadAI (pCreature);
+}
+
+bool AreaTrigger_at_kelthuzad_center(Player* pPlayer, const AreaTriggerEntry * /*at*/)
+{
+ if (pPlayer->isGameMaster())
+ return false;
+
+ ScriptedInstance* pInstance = pPlayer->GetInstanceData();
+ if (!pInstance || pInstance->IsEncounterInProgress() || pInstance->GetBossState(BOSS_KELTHUZAD) == DONE)
+ return false;
+
+ Creature* pKelthuzad = CAST_CRE(Unit::GetUnit(*pPlayer, pInstance->GetData64(DATA_KELTHUZAD)));
+ if (!pKelthuzad)
+ return false;
+
+ boss_kelthuzadAI* pKelthuzadAI = CAST_AI(boss_kelthuzadAI, pKelthuzad->AI());
+ if (!pKelthuzadAI)
+ return false;
+
+ pKelthuzadAI->AttackStart(pPlayer);
+ if (GameObject* trigger = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_KELTHUZAD_TRIGGER)))
+ {
+ if (trigger->getLootState() == GO_READY)
+ trigger->UseDoorOrButton();
+
+ // Note: summon must be done by trigger and not by KT.
+ // Otherwise, they attack immediately as KT is in combat.
+ for (uint8 i = 0; i <= MAX_ABOMINATIONS; ++i)
+ {
+ if (Creature* sum = trigger->SummonCreature(NPC_ABOMINATION, PosAbominations[i]))
+ {
+ pKelthuzadAI->spawns.Summon(sum);
+ sum->GetMotionMaster()->MoveRandom(9.0f);
+ sum->SetReactState(REACT_DEFENSIVE);
+ }
+ }
+ for (uint8 i = 0; i <= MAX_WASTES; ++i)
+ {
+ if (Creature* sum = trigger->SummonCreature(NPC_WASTE, PosWastes[i]))
+ {
+ pKelthuzadAI->spawns.Summon(sum);
+ sum->GetMotionMaster()->MoveRandom(5.0f);
+ sum->SetReactState(REACT_DEFENSIVE);
+ }
+ }
+ for (uint8 i = 0; i <= MAX_WEAVERS; ++i)
+ {
+ if (Creature* sum = trigger->SummonCreature(NPC_WEAVER, PosWeavers[i]))
+ {
+ pKelthuzadAI->spawns.Summon(sum);
+ sum->GetMotionMaster()->MoveRandom(9.0f);
+ sum->SetReactState(REACT_DEFENSIVE);
+ }
+ }
+ }
+
+ return true;
+}
+
+void AddSC_boss_kelthuzad()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_kelthuzad";
+ newscript->GetAI = &GetAI_boss_kelthuzadAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "at_kelthuzad_center";
+ newscript->pAreaTrigger = &AreaTrigger_at_kelthuzad_center;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/naxxramas/boss_loatheb.cpp b/src/server/scripts/northrend/naxxramas/boss_loatheb.cpp
new file mode 100644
index 00000000000..0b0c8f5e4c5
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_loatheb.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+enum Spells
+{
+ SPELL_NECROTIC_AURA = 55593,
+ SPELL_SUMMON_SPORE = 29234,
+ SPELL_DEATHBLOOM = 29865,
+ H_SPELL_DEATHBLOOM = 55053,
+ SPELL_INEVITABLE_DOOM = 29204,
+ H_SPELL_INEVITABLE_DOOM = 55052
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_AURA,
+ EVENT_BLOOM,
+ EVENT_DOOM,
+};
+
+struct boss_loathebAI : public BossAI
+{
+ boss_loathebAI(Creature *c) : BossAI(c, BOSS_LOATHEB) {}
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ _EnterCombat();
+ events.ScheduleEvent(EVENT_AURA, 10000);
+ events.ScheduleEvent(EVENT_BLOOM, 5000);
+ events.ScheduleEvent(EVENT_DOOM, 120000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_AURA:
+ DoCastAOE(SPELL_NECROTIC_AURA);
+ events.ScheduleEvent(EVENT_AURA, 20000);
+ break;
+ case EVENT_BLOOM:
+ // TODO : Add missing text
+ DoCastAOE(SPELL_SUMMON_SPORE, true);
+ DoCastAOE(RAID_MODE(SPELL_DEATHBLOOM,H_SPELL_DEATHBLOOM));
+ events.ScheduleEvent(EVENT_BLOOM, 30000);
+ break;
+ case EVENT_DOOM:
+ DoCastAOE(RAID_MODE(SPELL_INEVITABLE_DOOM,H_SPELL_INEVITABLE_DOOM));
+ events.ScheduleEvent(EVENT_DOOM, events.GetTimer() < 5*60000 ? 30000 : 15000);
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_loatheb(Creature* pCreature)
+{
+ return new boss_loathebAI (pCreature);
+}
+
+enum SporeSpells
+{
+ SPELL_FUNGAL_CREEP = 29232
+};
+
+struct mob_loatheb_sporeAI : public ScriptedAI
+{
+ mob_loatheb_sporeAI(Creature *c) : ScriptedAI(c) {}
+
+ void JustDied(Unit* killer)
+ {
+ DoCast(killer, SPELL_FUNGAL_CREEP);
+ }
+};
+
+CreatureAI* GetAI_mob_loatheb_spore(Creature* pCreature)
+{
+ return new mob_loatheb_sporeAI (pCreature);
+}
+
+void AddSC_boss_loatheb()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_loatheb";
+ newscript->GetAI = &GetAI_boss_loatheb;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_loatheb_spore";
+ newscript->GetAI = &GetAI_mob_loatheb_spore;
+ newscript->RegisterSelf();
+
+ // Fungal Creep
+ //GetAISpellInfo(29232)->condition = AICOND_DIE;
+}
+
diff --git a/src/server/scripts/northrend/naxxramas/boss_maexxna.cpp b/src/server/scripts/northrend/naxxramas/boss_maexxna.cpp
new file mode 100644
index 00000000000..71d9cb86102
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_maexxna.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+enum Spells
+{
+ SPELL_WEB_WRAP = 28622,
+ SPELL_WEB_SPRAY_10 = 29484,
+ SPELL_WEB_SPRAY_25 = 54125,
+ SPELL_POISON_SHOCK_10 = 28741,
+ SPELL_POISON_SHOCK_25 = 54122,
+ SPELL_NECROTIC_POISON_10 = 28776,
+ SPELL_NECROTIC_POISON_25 = 54121,
+ SPELL_FRENZY_10 = 54123,
+ SPELL_FRENZY_25 = 54124,
+};
+
+enum Creatures
+{
+ MOB_WEB_WRAP = 16486,
+ MOB_SPIDERLING = 17055,
+};
+
+#define MAX_POS_WRAP 3
+const Position PosWrap[MAX_POS_WRAP] =
+{
+ {3546.796, -3869.082, 296.450, 0.0},
+ {3531.271, -3847.424, 299.450, 0.0},
+ {3497.067, -3843.384, 302.384, 0.0},
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_SPRAY,
+ EVENT_SHOCK,
+ EVENT_POISON,
+ EVENT_WRAP,
+ EVENT_SUMMON,
+ EVENT_FRENZY,
+};
+
+struct boss_maexxnaAI : public BossAI
+{
+ boss_maexxnaAI(Creature *c) : BossAI(c, BOSS_MAEXXNA) {}
+
+ bool enraged;
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ _EnterCombat();
+ enraged = false;
+ events.ScheduleEvent(EVENT_WRAP, 20000);
+ events.ScheduleEvent(EVENT_SPRAY, 40000);
+ events.ScheduleEvent(EVENT_SHOCK, urand(5000,10000));
+ events.ScheduleEvent(EVENT_POISON, urand(10000,15000));
+ events.ScheduleEvent(EVENT_SUMMON, 30000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim() || !CheckInRoom())
+ return;
+
+ if (!enraged && HealthBelowPct(30))
+ {
+ enraged = true;
+ events.ScheduleEvent(EVENT_FRENZY, 0); // will be cast immediately
+ }
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_WRAP:
+ // TODO : Add missing text
+ for (uint8 i = 0; i < RAID_MODE(1,2); ++i)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 0, true, -SPELL_WEB_WRAP))
+ {
+ pTarget->RemoveAura(RAID_MODE(SPELL_WEB_SPRAY_10,SPELL_WEB_SPRAY_25));
+ uint8 pos = rand()%MAX_POS_WRAP;
+ pTarget->GetMotionMaster()->MoveJump(PosWrap[pos].GetPositionX(), PosWrap[pos].GetPositionY(), PosWrap[pos].GetPositionZ(), 20, 20);
+ if (Creature *wrap = DoSummon(MOB_WEB_WRAP, PosWrap[pos], 0, TEMPSUMMON_CORPSE_DESPAWN))
+ wrap->AI()->SetGUID(pTarget->GetGUID());
+ }
+ }
+ events.ScheduleEvent(EVENT_WRAP, 40000);
+ break;
+ case EVENT_SPRAY:
+ DoCastAOE(RAID_MODE(SPELL_WEB_SPRAY_10,SPELL_WEB_SPRAY_25));
+ events.ScheduleEvent(EVENT_SPRAY, 40000);
+ break;
+ case EVENT_SHOCK:
+ DoCastAOE(RAID_MODE(SPELL_POISON_SHOCK_10,SPELL_POISON_SHOCK_25));
+ events.ScheduleEvent(EVENT_SHOCK, urand(10000,20000));
+ break;
+ case EVENT_POISON:
+ DoCast(me->getVictim(), RAID_MODE(SPELL_NECROTIC_POISON_10,SPELL_NECROTIC_POISON_25));
+ events.ScheduleEvent(EVENT_POISON, urand(10000, 20000));
+ break;
+ case EVENT_FRENZY:
+ DoCast(me, RAID_MODE(SPELL_FRENZY_10,SPELL_FRENZY_25), true);
+ events.ScheduleEvent(EVENT_FRENZY, 600000);
+ break;
+ case EVENT_SUMMON:
+ // TODO : Add missing text
+ uint8 amount = urand(8,10);
+ for (uint8 i = 0; i < amount; ++i)
+ DoSummon(MOB_SPIDERLING, me, 0, TEMPSUMMON_CORPSE_DESPAWN);
+ events.ScheduleEvent(EVENT_SUMMON, 40000);
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_webwrapAI : public NullCreatureAI
+{
+ mob_webwrapAI(Creature *c) : NullCreatureAI(c), victimGUID(0) {}
+
+ uint64 victimGUID;
+
+ void SetGUID(const uint64 &guid, int32 /*param*/)
+ {
+ victimGUID = guid;
+ if (me->m_spells[0] && victimGUID)
+ if (Unit *victim = Unit::GetUnit(*me, victimGUID))
+ victim->CastSpell(victim, me->m_spells[0], true, NULL, NULL, me->GetGUID());
+ }
+
+ void JustDied(Unit * /*killer*/)
+ {
+ if (me->m_spells[0] && victimGUID)
+ if (Unit *victim = Unit::GetUnit(*me, victimGUID))
+ victim->RemoveAurasDueToSpell(me->m_spells[0], me->GetGUID());
+ }
+};
+
+CreatureAI* GetAI_boss_maexxna(Creature* pCreature)
+{
+ return new boss_maexxnaAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_webwrap(Creature* pCreature)
+{
+ return new mob_webwrapAI (pCreature);
+}
+
+void AddSC_boss_maexxna()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_maexxna";
+ newscript->GetAI = &GetAI_boss_maexxna;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_webwrap";
+ newscript->GetAI = &GetAI_mob_webwrap;
+ newscript->RegisterSelf();
+
+}
+
diff --git a/src/server/scripts/northrend/naxxramas/boss_noth.cpp b/src/server/scripts/northrend/naxxramas/boss_noth.cpp
new file mode 100644
index 00000000000..b0cd4018955
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_noth.cpp
@@ -0,0 +1,212 @@
+/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+#define SAY_AGGRO RAND(-1533075,-1533076,-1533077)
+#define SAY_SUMMON -1533078
+#define SAY_SLAY RAND(-1533079,-1533080)
+#define SAY_DEATH -1533081
+
+#define SOUND_DEATH 8848
+
+#define SPELL_CURSE_PLAGUEBRINGER RAID_MODE(29213,54835)
+#define SPELL_BLINK RAND(29208,29209,29210,29211)
+#define SPELL_CRIPPLE RAID_MODE(29212,54814)
+#define SPELL_TELEPORT 29216
+
+#define MOB_WARRIOR 16984
+#define MOB_CHAMPION 16983
+#define MOB_GUARDIAN 16981
+
+// Teleport position of Noth on his balcony
+#define TELE_X 2631.370
+#define TELE_Y -3529.680
+#define TELE_Z 274.040
+#define TELE_O 6.277
+
+#define MAX_SUMMON_POS 5
+
+const float SummonPos[MAX_SUMMON_POS][4] =
+{
+ {2728.12, -3544.43, 261.91, 6.04},
+ {2729.05, -3544.47, 261.91, 5.58},
+ {2728.24, -3465.08, 264.20, 3.56},
+ {2704.11, -3456.81, 265.53, 4.51},
+ {2663.56, -3464.43, 262.66, 5.20},
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_BERSERK,
+ EVENT_CURSE,
+ EVENT_BLINK,
+ EVENT_WARRIOR,
+ EVENT_BALCONY,
+ EVENT_WAVE,
+ EVENT_GROUND,
+};
+
+struct boss_nothAI : public BossAI
+{
+ boss_nothAI(Creature *c) : BossAI(c, BOSS_NOTH) {}
+
+ uint32 waveCount, balconyCount;
+
+ void Reset()
+ {
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ _Reset();
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ _EnterCombat();
+ DoScriptText(SAY_AGGRO, me);
+ balconyCount = 0;
+ EnterPhaseGround();
+ }
+
+ void EnterPhaseGround()
+ {
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ DoZoneInCombat();
+ if (me->getThreatManager().isThreatListEmpty())
+ EnterEvadeMode();
+ else
+ {
+ events.ScheduleEvent(EVENT_BALCONY, 110000);
+ events.ScheduleEvent(EVENT_CURSE, 10000+rand()%15000);
+ events.ScheduleEvent(EVENT_WARRIOR, 30000);
+ if (getDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ events.ScheduleEvent(EVENT_BLINK, 20000 + rand()%20000);
+ }
+ }
+
+ void KilledUnit(Unit* /*victim*/)
+ {
+ if (!(rand()%5))
+ DoScriptText(SAY_SLAY, me);
+ }
+
+ void JustSummoned(Creature *summon)
+ {
+ summons.Summon(summon);
+ summon->setActive(true);
+ summon->AI()->DoZoneInCombat();
+ }
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ _JustDied();
+ DoScriptText(SAY_DEATH, me);
+ }
+
+ void SummonUndead(uint32 entry, uint32 num)
+ {
+ for (uint32 i = 0; i < num; ++i)
+ {
+ uint32 pos = rand()%MAX_SUMMON_POS;
+ me->SummonCreature(entry, SummonPos[pos][0], SummonPos[pos][1], SummonPos[pos][2],
+ SummonPos[pos][3], TEMPSUMMON_CORPSE_DESPAWN, 60000);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateCombatState() || !CheckInRoom())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_CURSE:
+ DoCastAOE(SPELL_CURSE_PLAGUEBRINGER);
+ events.ScheduleEvent(EVENT_CURSE, 50000 + rand()%10000);
+ return;
+ case EVENT_WARRIOR:
+ DoScriptText(SAY_SUMMON, me);
+ SummonUndead(MOB_WARRIOR, RAID_MODE(2,3));
+ events.ScheduleEvent(EVENT_WARRIOR, 30000);
+ return;
+ case EVENT_BLINK:
+ DoCastAOE(SPELL_CRIPPLE, true);
+ DoCastAOE(SPELL_BLINK);
+ DoResetThreat();
+ events.ScheduleEvent(EVENT_BLINK, 40000);
+ return;
+ case EVENT_BALCONY:
+ me->SetReactState(REACT_PASSIVE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->AttackStop();
+ me->RemoveAllAuras();
+ me->NearTeleportTo(TELE_X, TELE_Y, TELE_Z, TELE_O);
+ events.Reset();
+ events.ScheduleEvent(EVENT_WAVE, 2000 + rand()%3000);
+ waveCount = 0;
+ return;
+ case EVENT_WAVE:
+ DoScriptText(SAY_SUMMON, me);
+ switch(balconyCount)
+ {
+ case 0: SummonUndead(MOB_CHAMPION, RAID_MODE(2,4)); break;
+ case 1: SummonUndead(MOB_CHAMPION, RAID_MODE(1,2));
+ SummonUndead(MOB_GUARDIAN, RAID_MODE(1,2)); break;
+ case 2: SummonUndead(MOB_GUARDIAN, RAID_MODE(2,4)); break;
+ default:SummonUndead(MOB_CHAMPION, RAID_MODE(5,10));
+ SummonUndead(MOB_GUARDIAN, RAID_MODE(5,10));break;
+ }
+ ++waveCount;
+ events.ScheduleEvent(waveCount < 2 ? EVENT_WAVE : EVENT_GROUND, 30000 + rand()%15000);
+ return;
+ case EVENT_GROUND:
+ {
+ ++balconyCount;
+ float x, y, z, o;
+ me->GetHomePosition(x, y, z, o);
+ me->NearTeleportTo(x, y, z, o);
+ events.ScheduleEvent(EVENT_BALCONY, 110000);
+ EnterPhaseGround();
+ return;
+ }
+ }
+ }
+
+ if (me->HasReactState(REACT_AGGRESSIVE))
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_noth(Creature* pCreature)
+{
+ return new boss_nothAI (pCreature);
+}
+
+void AddSC_boss_noth()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_noth";
+ newscript->GetAI = &GetAI_boss_noth;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/naxxramas/boss_patchwerk.cpp b/src/server/scripts/northrend/naxxramas/boss_patchwerk.cpp
new file mode 100644
index 00000000000..e4472b299ce
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_patchwerk.cpp
@@ -0,0 +1,159 @@
+/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+enum Spells
+{
+ SPELL_HATEFUL_STRIKE = 41926,
+ H_SPELL_HATEFUL_STRIKE = 59192,
+ SPELL_FRENZY = 28131,
+ SPELL_BERSERK = 26662,
+ SPELL_SLIME_BOLT = 32309,
+};
+
+enum Yells
+{
+ SAY_AGGRO_1 = -1533017,
+ SAY_AGGRO_2 = -1533018,
+ SAY_SLAY = -1533019,
+ SAY_DEATH = -1533020,
+ EMOTE_BERSERK = -1533021,
+ EMOTE_ENRAGE = -1533022,
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_BERSERK,
+ EVENT_HATEFUL,
+ EVENT_SLIME
+};
+
+enum
+{
+ ACHIEV_MAKE_QUICK_WERK_OF_HIM_STARTING_EVENT = 10286,
+};
+
+struct boss_patchwerkAI : public BossAI
+{
+ boss_patchwerkAI(Creature *c) : BossAI(c, BOSS_PATCHWERK) {}
+
+ bool Enraged;
+
+ void Reset()
+ {
+ _Reset();
+
+ if (instance)
+ instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_MAKE_QUICK_WERK_OF_HIM_STARTING_EVENT);
+ }
+
+ void KilledUnit(Unit* /*Victim*/)
+ {
+ if (!(rand()%5))
+ DoScriptText(SAY_SLAY, me);
+ }
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ _JustDied();
+ DoScriptText(SAY_DEATH, me);
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ _EnterCombat();
+ Enraged = false;
+ DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2), me);
+ events.ScheduleEvent(EVENT_HATEFUL, 1200);
+ events.ScheduleEvent(EVENT_BERSERK, 360000);
+
+ if (instance)
+ instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_MAKE_QUICK_WERK_OF_HIM_STARTING_EVENT);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_HATEFUL:
+ {
+ //Cast Hateful strike on the player with the highest
+ //amount of HP within melee distance
+ uint32 MostHP = 0;
+ Unit* pMostHPTarget = NULL;
+ std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
+ for (; i != me->getThreatManager().getThreatList().end(); ++i)
+ {
+ Unit *pTarget = (*i)->getTarget();
+ if (pTarget->isAlive() && pTarget->GetHealth() > MostHP && me->IsWithinMeleeRange(pTarget))
+ {
+ MostHP = pTarget->GetHealth();
+ pMostHPTarget = pTarget;
+ }
+ }
+
+ if (pMostHPTarget)
+ DoCast(pMostHPTarget, RAID_MODE(SPELL_HATEFUL_STRIKE,H_SPELL_HATEFUL_STRIKE), true);
+
+ events.ScheduleEvent(EVENT_HATEFUL, 1200);
+ break;
+ }
+ case EVENT_BERSERK:
+ DoCast(me, SPELL_BERSERK, true);
+ DoScriptText(EMOTE_BERSERK, me);
+ events.ScheduleEvent(EVENT_SLIME, 2000);
+ break;
+ case EVENT_SLIME:
+ DoCast(me->getVictim(), SPELL_SLIME_BOLT);
+ events.ScheduleEvent(EVENT_SLIME, 2000);
+ break;
+ }
+ }
+
+ if (!Enraged && HealthBelowPct(5))
+ {
+ DoCast(me, SPELL_FRENZY, true);
+ DoScriptText(EMOTE_ENRAGE, me);
+ Enraged = true;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_patchwerk(Creature* pCreature)
+{
+ return new boss_patchwerkAI (pCreature);
+}
+
+void AddSC_boss_patchwerk()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_patchwerk";
+ newscript->GetAI = &GetAI_boss_patchwerk;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/naxxramas/boss_razuvious.cpp b/src/server/scripts/northrend/naxxramas/boss_razuvious.cpp
new file mode 100644
index 00000000000..d507df86e83
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_razuvious.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+//Razuvious - NO TEXT sound only
+//8852 aggro01 - Hah hah, I'm just getting warmed up!
+//8853 aggro02 Stand and fight!
+//8854 aggro03 Show me what you've got!
+//8861 slay1 - You should've stayed home!
+//8863 slay2-
+//8858 cmmnd3 - You disappoint me, students!
+//8855 cmmnd1 - Do as I taught you!
+//8856 cmmnd2 - Show them no mercy!
+//8859 cmmnd4 - The time for practice is over! Show me what you've learned!
+//8861 Sweep the leg! Do you have a problem with that?
+//8860 death - An honorable... death...
+//8947 - Aggro Mixed? - ?
+
+#define SOUND_AGGRO RAND(8852,8853,8854)
+#define SOUND_SLAY RAND(8861,8863)
+#define SOUND_COMMND RAND(8855,8856,8858,8859,8861)
+#define SOUND_DEATH 8860
+#define SOUND_AGGROMIX 8847
+
+#define SPELL_UNBALANCING_STRIKE 26613
+#define SPELL_DISRUPTING_SHOUT RAID_MODE(29107,55543)
+#define SPELL_JAGGED_KNIFE 55550
+#define SPELL_HOPELESS 29125
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_STRIKE,
+ EVENT_SHOUT,
+ EVENT_KNIFE,
+ EVENT_COMMAND,
+};
+
+struct boss_razuviousAI : public BossAI
+{
+ boss_razuviousAI(Creature *c) : BossAI(c, BOSS_RAZUVIOUS) {}
+
+ void KilledUnit(Unit* /*victim*/)
+ {
+ if (!(rand()%3))
+ DoPlaySoundToSet(me, SOUND_SLAY);
+ }
+
+ void DamageTaken(Unit* pDone_by, uint32& uiDamage)
+ {
+ // Damage done by the controlled Death Knight understudies should also count toward damage done by players
+ if (pDone_by->GetTypeId() == TYPEID_UNIT && (pDone_by->GetEntry() == 16803 || pDone_by->GetEntry() == 29941))
+ {
+ me->LowerPlayerDamageReq(uiDamage);
+ }
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ _JustDied();
+ DoPlaySoundToSet(me, SOUND_DEATH);
+ me->CastSpell(me, SPELL_HOPELESS, true); // TODO: this may affect other creatures
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ _EnterCombat();
+ DoPlaySoundToSet(me, SOUND_AGGRO);
+ events.ScheduleEvent(EVENT_STRIKE, 30000);
+ events.ScheduleEvent(EVENT_SHOUT, 25000);
+ events.ScheduleEvent(EVENT_COMMAND, 40000);
+ events.ScheduleEvent(EVENT_KNIFE, 10000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_STRIKE:
+ DoCast(me->getVictim(), SPELL_UNBALANCING_STRIKE);
+ events.ScheduleEvent(EVENT_STRIKE, 30000);
+ return;
+ case EVENT_SHOUT:
+ DoCastAOE(SPELL_DISRUPTING_SHOUT);
+ events.ScheduleEvent(EVENT_SHOUT, 25000);
+ return;
+ case EVENT_KNIFE:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f))
+ DoCast(pTarget, SPELL_JAGGED_KNIFE);
+ events.ScheduleEvent(EVENT_KNIFE, 10000);
+ return;
+ case EVENT_COMMAND:
+ DoPlaySoundToSet(me, SOUND_COMMND);
+ events.ScheduleEvent(EVENT_COMMAND, 40000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_razuvious(Creature* pCreature)
+{
+ return new boss_razuviousAI (pCreature);
+}
+
+void AddSC_boss_razuvious()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_razuvious";
+ newscript->GetAI = &GetAI_boss_razuvious;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/naxxramas/boss_sapphiron.cpp b/src/server/scripts/northrend/naxxramas/boss_sapphiron.cpp
new file mode 100644
index 00000000000..d75b3ab78b0
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_sapphiron.cpp
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+#define EMOTE_BREATH -1533082
+#define EMOTE_ENRAGE -1533083
+
+#define SPELL_FROST_AURA RAID_MODE(28531,55799)
+#define SPELL_CLEAVE 19983
+#define SPELL_TAIL_SWEEP RAID_MODE(55697,55696)
+#define SPELL_SUMMON_BLIZZARD 28560
+#define SPELL_LIFE_DRAIN RAID_MODE(28542,55665)
+#define SPELL_ICEBOLT 28522
+#define SPELL_FROST_BREATH 29318
+#define SPELL_FROST_EXPLOSION 28524
+#define SPELL_FROST_MISSILE 30101
+#define SPELL_BERSERK 26662
+#define SPELL_DIES 29357
+
+#define SPELL_CHILL RAID_MODE(28547,55699)
+
+#define MOB_BLIZZARD 16474
+#define GO_ICEBLOCK 181247
+
+#define ACHIEVEMENT_THE_HUNDRED_CLUB RAID_MODE(2146, 2147)
+#define MAX_FROST_RESISTANCE 100
+
+enum Phases
+{
+ PHASE_NULL = 0,
+ PHASE_BIRTH,
+ PHASE_GROUND,
+ PHASE_FLIGHT,
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_BERSERK,
+ EVENT_CLEAVE,
+ EVENT_TAIL,
+ EVENT_DRAIN,
+ EVENT_BLIZZARD,
+ EVENT_FLIGHT,
+ EVENT_LIFTOFF,
+ EVENT_ICEBOLT,
+ EVENT_BREATH,
+ EVENT_EXPLOSION,
+ EVENT_LAND,
+ EVENT_GROUND,
+ EVENT_BIRTH,
+};
+
+typedef std::map<uint64, uint64> IceBlockMap;
+
+struct boss_sapphironAI : public BossAI
+{
+ boss_sapphironAI(Creature* c) : BossAI(c, BOSS_SAPPHIRON)
+ , phase(PHASE_NULL)
+ {
+ pMap = me->GetMap();
+ }
+
+ Phases phase;
+ uint32 iceboltCount;
+ IceBlockMap iceblocks;
+
+ bool CanTheHundredClub; // needed for achievement: The Hundred Club(2146, 2147)
+ uint32 CheckFrostResistTimer;
+ Map* pMap;
+
+ void InitializeAI()
+ {
+ float x, y, z;
+ me->GetPosition(x, y, z);
+ me->SummonGameObject(GO_BIRTH, x, y, z, 0, 0, 0, 0, 0, 0);
+ me->SetVisibility(VISIBILITY_OFF);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetReactState(REACT_PASSIVE);
+
+ ScriptedAI::InitializeAI();
+ }
+
+ void Reset()
+ {
+ _Reset();
+
+ if (phase == PHASE_FLIGHT)
+ ClearIceBlock();
+
+ phase = PHASE_NULL;
+
+ CanTheHundredClub = true;
+ CheckFrostResistTimer = 5000;
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ _EnterCombat();
+
+ me->CastSpell(me, SPELL_FROST_AURA, true);
+
+ events.ScheduleEvent(EVENT_BERSERK, 15*60000);
+ EnterPhaseGround();
+
+ CheckPlayersFrostResist();
+ }
+
+ void SpellHitTarget(Unit *pTarget, const SpellEntry *spell)
+ {
+ if (spell->Id == SPELL_ICEBOLT)
+ {
+ IceBlockMap::iterator itr = iceblocks.find(pTarget->GetGUID());
+ if (itr != iceblocks.end() && !itr->second)
+ {
+ if (GameObject *iceblock = me->SummonGameObject(GO_ICEBLOCK, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, 0, 0, 0, 0, 25000))
+ itr->second = iceblock->GetGUID();
+ }
+ }
+ }
+
+ void JustDied(Unit* /*who*/)
+ {
+ _JustDied();
+ me->CastSpell(me, SPELL_DIES, true);
+
+ CheckPlayersFrostResist();
+ if (CanTheHundredClub)
+ {
+ AchievementEntry const *AchievTheHundredClub = GetAchievementStore()->LookupEntry(ACHIEVEMENT_THE_HUNDRED_CLUB);
+ if (AchievTheHundredClub)
+ {
+ if (pMap && pMap->IsDungeon())
+ {
+ Map::PlayerList const &players = pMap->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ itr->getSource()->CompletedAchievement(AchievTheHundredClub);
+ }
+ }
+ }
+ }
+
+ void MovementInform(uint32, uint32 id)
+ {
+ if (id == 1)
+ events.ScheduleEvent(EVENT_LIFTOFF, 0);
+ }
+
+ void DoAction(const int32 param)
+ {
+ if (param == DATA_SAPPHIRON_BIRTH)
+ {
+ phase = PHASE_BIRTH;
+ events.ScheduleEvent(EVENT_BIRTH, 23000);
+ }
+ }
+
+ void CheckPlayersFrostResist()
+ {
+ if (CanTheHundredClub && pMap && pMap->IsDungeon())
+ {
+ Map::PlayerList const &players = pMap->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ {
+ if (itr->getSource()->GetResistance(SPELL_SCHOOL_FROST) > MAX_FROST_RESISTANCE)
+ {
+ CanTheHundredClub = false;
+ break;
+ }
+ }
+ }
+ }
+
+ void EnterPhaseGround()
+ {
+ phase = PHASE_GROUND;
+ me->SetReactState(REACT_AGGRESSIVE);
+ events.SetPhase(PHASE_GROUND);
+ events.ScheduleEvent(EVENT_CLEAVE, 5000+rand()%10000, 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_TAIL, 5000+rand()%10000, 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_DRAIN, 24000, 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_BLIZZARD, 5000+rand()%5000, 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_FLIGHT, 45000);
+ }
+
+ void ClearIceBlock()
+ {
+ for (IceBlockMap::const_iterator itr = iceblocks.begin(); itr != iceblocks.end(); ++itr)
+ {
+ if (Player* pPlayer = Unit::GetPlayer(itr->first))
+ pPlayer->RemoveAura(SPELL_ICEBOLT);
+ if (GameObject* pGo = GameObject::GetGameObject(*me, itr->second))
+ pGo->Delete();
+ }
+ iceblocks.clear();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!phase)
+ return;
+
+ events.Update(diff);
+
+ if (phase != PHASE_BIRTH && !UpdateCombatState() || !CheckInRoom())
+ return;
+
+ if (CanTheHundredClub)
+ {
+ if (CheckFrostResistTimer <= diff)
+ {
+ CheckPlayersFrostResist();
+ CheckFrostResistTimer = (rand() % 5 + 5) * 1000;
+ } else CheckFrostResistTimer -= diff;
+ }
+
+ if (phase == PHASE_GROUND)
+ {
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_BERSERK:
+ DoScriptText(EMOTE_ENRAGE, me);
+ DoCast(me, SPELL_BERSERK);
+ return;
+ case EVENT_CLEAVE:
+ DoCast(me->getVictim(), SPELL_CLEAVE);
+ events.ScheduleEvent(EVENT_CLEAVE, 5000+rand()%10000, 0, PHASE_GROUND);
+ return;
+ case EVENT_TAIL:
+ DoCastAOE(SPELL_TAIL_SWEEP);
+ events.ScheduleEvent(EVENT_TAIL, 5000+rand()%10000, 0, PHASE_GROUND);
+ return;
+ case EVENT_DRAIN:
+ DoCastAOE(SPELL_LIFE_DRAIN);
+ events.ScheduleEvent(EVENT_DRAIN, 24000, 0, PHASE_GROUND);
+ return;
+ case EVENT_BLIZZARD:
+ {
+ //DoCastAOE(SPELL_SUMMON_BLIZZARD);
+ if (Creature *pSummon = DoSummon(MOB_BLIZZARD, me, 0.0f, urand(25000,30000), TEMPSUMMON_TIMED_DESPAWN))
+ pSummon->GetMotionMaster()->MoveRandom(40);
+ events.ScheduleEvent(EVENT_BLIZZARD, RAID_MODE(20000,7000), 0, PHASE_GROUND);
+ break;
+ }
+ case EVENT_FLIGHT:
+ phase = PHASE_FLIGHT;
+ events.SetPhase(PHASE_FLIGHT);
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
+ float x, y, z, o;
+ me->GetHomePosition(x, y, z, o);
+ me->GetMotionMaster()->MovePoint(1, x, y, z);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ else
+ {
+ if (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_LIFTOFF:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
+ me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SendMovementFlagUpdate();
+ events.ScheduleEvent(EVENT_ICEBOLT, 1500);
+ iceboltCount = RAID_MODE(2,3);
+ return;
+ case EVENT_ICEBOLT:
+ {
+ std::vector<Unit*> targets;
+ std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
+ for (; i != me->getThreatManager().getThreatList().end(); ++i)
+ if ((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER && !(*i)->getTarget()->HasAura(SPELL_ICEBOLT))
+ targets.push_back((*i)->getTarget());
+
+ if (targets.empty())
+ iceboltCount = 0;
+ else
+ {
+ std::vector<Unit*>::const_iterator itr = targets.begin();
+ advance(itr, rand()%targets.size());
+ iceblocks.insert(std::make_pair((*itr)->GetGUID(), 0));
+ DoCast(*itr, SPELL_ICEBOLT);
+ --iceboltCount;
+ }
+
+ if (iceboltCount)
+ events.ScheduleEvent(EVENT_ICEBOLT, 1000);
+ else
+ events.ScheduleEvent(EVENT_BREATH, 1000);
+ return;
+ }
+ case EVENT_BREATH:
+ {
+ DoScriptText(EMOTE_BREATH, me);
+ DoCastAOE(SPELL_FROST_MISSILE);
+ events.ScheduleEvent(EVENT_EXPLOSION, 8000);
+ return;
+ }
+ case EVENT_EXPLOSION:
+ CastExplosion();
+ ClearIceBlock();
+ events.ScheduleEvent(EVENT_LAND, 3000);
+ return;
+ case EVENT_LAND:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SendMovementFlagUpdate();
+ events.ScheduleEvent(EVENT_GROUND, 1500);
+ return;
+ case EVENT_GROUND:
+ EnterPhaseGround();
+ return;
+ case EVENT_BIRTH:
+ me->SetVisibility(VISIBILITY_ON);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ return;
+ }
+ }//if (uint32 eventId = events.ExecuteEvent())
+ }//if (phase == PHASE_GROUND)
+ }
+
+ void CastExplosion()
+ {
+ DoZoneInCombat(); // make sure everyone is in threatlist
+ std::vector<Unit*> targets;
+ std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
+ for (; i != me->getThreatManager().getThreatList().end(); ++i)
+ {
+ Unit *pTarget = (*i)->getTarget();
+ if (pTarget->GetTypeId() != TYPEID_PLAYER)
+ continue;
+
+ if (pTarget->HasAura(SPELL_ICEBOLT))
+ {
+ pTarget->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true);
+ targets.push_back(pTarget);
+ continue;
+ }
+
+ for (IceBlockMap::const_iterator itr = iceblocks.begin(); itr != iceblocks.end(); ++itr)
+ {
+ if (GameObject* pGo = GameObject::GetGameObject(*me, itr->second))
+ {
+ if (pGo->IsInBetween(me, pTarget, 2.0f)
+ && me->GetExactDist2d(pTarget->GetPositionX(), pTarget->GetPositionY()) - me->GetExactDist2d(pGo->GetPositionX(), pGo->GetPositionY()) < 5.0f)
+ {
+ pTarget->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true);
+ targets.push_back(pTarget);
+ break;
+ }
+ }
+ }
+ }
+
+ me->CastSpell(me, SPELL_FROST_EXPLOSION, true);
+
+ for (std::vector<Unit*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ (*itr)->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, false);
+ }
+};
+
+CreatureAI* GetAI_boss_sapphiron(Creature* pCreature)
+{
+ return new boss_sapphironAI (pCreature);
+}
+
+void AddSC_boss_sapphiron()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_sapphiron";
+ newscript->GetAI = &GetAI_boss_sapphiron;
+ newscript->RegisterSelf();
+
+ // Chill
+ GetAISpellInfo(28547)->cooldown = 1000;
+ GetAISpellInfo(55699)->cooldown = 1000;
+}
diff --git a/src/server/scripts/northrend/naxxramas/boss_thaddius.cpp b/src/server/scripts/northrend/naxxramas/boss_thaddius.cpp
new file mode 100644
index 00000000000..350cd450510
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/boss_thaddius.cpp
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2008 - 2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+//Stalagg
+enum StalaggYells
+{
+ SAY_STAL_AGGRO = -1533023, //not used
+ SAY_STAL_SLAY = -1533024, //not used
+ SAY_STAL_DEATH = -1533025 //not used
+};
+
+enum StalagSpells
+{
+ SPELL_POWERSURGE = 28134,
+ H_SPELL_POWERSURGE = 54529,
+ SPELL_MAGNETIC_PULL = 28338,
+ SPELL_STALAGG_TESLA = 28097
+};
+
+//Feugen
+enum FeugenYells
+{
+ SAY_FEUG_AGGRO = -1533026, //not used
+ SAY_FEUG_SLAY = -1533027, //not used
+ SAY_FEUG_DEATH = -1533028 //not used
+};
+
+enum FeugenSpells
+{
+ SPELL_STATICFIELD = 28135,
+ H_SPELL_STATICFIELD = 54528,
+ SPELL_FEUGEN_TESLA = 28109
+};
+
+// Thaddius DoAction
+enum ThaddiusActions
+{
+ ACTION_FEUGEN_RESET,
+ ACTION_FEUGEN_DIED,
+ ACTION_STALAGG_RESET,
+ ACTION_STALAGG_DIED
+};
+
+//generic
+#define C_TESLA_COIL 16218 //the coils (emotes "Tesla Coil overloads!")
+
+//Thaddius
+enum ThaddiusYells
+{
+ SAY_GREET = -1533029, //not used
+ SAY_AGGRO_1 = -1533030,
+ SAY_AGGRO_2 = -1533031,
+ SAY_AGGRO_3 = -1533032,
+ SAY_SLAY = -1533033,
+ SAY_ELECT = -1533034, //not used
+ SAY_DEATH = -1533035,
+ SAY_SCREAM1 = -1533036, //not used
+ SAY_SCREAM2 = -1533037, //not used
+ SAY_SCREAM3 = -1533038, //not used
+ SAY_SCREAM4 = -1533039 //not used
+};
+
+enum ThaddiusSpells
+{
+ SPELL_POLARITY_SHIFT = 28089,
+ SPELL_BALL_LIGHTNING = 28299,
+ SPELL_CHAIN_LIGHTNING = 28167,
+ H_SPELL_CHAIN_LIGHTNING = 54531,
+ SPELL_BERSERK = 27680
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_SHIFT,
+ EVENT_CHAIN,
+ EVENT_BERSERK,
+};
+
+struct boss_thaddiusAI : public BossAI
+{
+ boss_thaddiusAI(Creature *c) : BossAI(c, BOSS_THADDIUS)
+ {
+ // init is a bit tricky because thaddius shall track the life of both adds, but not if there was a wipe
+ // and, in particular, if there was a crash after both adds were killed (should not respawn)
+
+ // Moreover, the adds may not yet be spawn. So just track down the status if mob is spawn
+ // and each mob will send its status at reset (meaning that it is alive)
+ checkFeugenAlive = false;
+ if (Creature *pFeugen = me->GetCreature(*me, instance->GetData64(DATA_FEUGEN)))
+ checkFeugenAlive = pFeugen->isAlive();
+
+ checkStalaggAlive = false;
+ if (Creature *pStalagg = me->GetCreature(*me, instance->GetData64(DATA_STALAGG)))
+ checkStalaggAlive = pStalagg->isAlive();
+
+ if (!checkFeugenAlive && !checkStalaggAlive)
+ {
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
+ me->SetReactState(REACT_AGGRESSIVE);
+ }
+ else
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
+ me->SetReactState(REACT_PASSIVE);
+ }
+ }
+
+ bool checkStalaggAlive;
+ bool checkFeugenAlive;
+ uint32 uiAddsTimer;
+
+ void KilledUnit(Unit* /*victim*/)
+ {
+ if (!(rand()%5))
+ DoScriptText(SAY_SLAY, me);
+ }
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ _JustDied();
+ DoScriptText(SAY_DEATH, me);
+ }
+
+ void DoAction(const int32 action)
+ {
+ switch(action)
+ {
+ case ACTION_FEUGEN_RESET:
+ checkFeugenAlive = true;
+ break;
+ case ACTION_FEUGEN_DIED:
+ checkFeugenAlive = false;
+ break;
+ case ACTION_STALAGG_RESET:
+ checkStalaggAlive = true;
+ break;
+ case ACTION_STALAGG_DIED:
+ checkStalaggAlive = false;
+ break;
+ }
+
+ if (!checkFeugenAlive && !checkStalaggAlive)
+ {
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
+ // REACT_AGGRESSIVE only reset when he takes damage.
+ DoZoneInCombat();
+ }
+ else
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
+ me->SetReactState(REACT_PASSIVE);
+ }
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ _EnterCombat();
+ DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me);
+ events.ScheduleEvent(EVENT_SHIFT, 30000);
+ events.ScheduleEvent(EVENT_CHAIN, urand(10000,20000));
+ events.ScheduleEvent(EVENT_BERSERK, 360000);
+ }
+
+ void DamageTaken(Unit * /*pDoneBy*/, uint32 & /*uiDamage*/)
+ {
+ me->SetReactState(REACT_AGGRESSIVE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (checkFeugenAlive && checkStalaggAlive)
+ uiAddsTimer = 0;
+
+ if (checkStalaggAlive != checkFeugenAlive)
+ {
+ uiAddsTimer += diff;
+ if (uiAddsTimer > 5000)
+ {
+ if (!checkStalaggAlive)
+ {
+ if (instance)
+ if (Creature *pStalagg = me->GetCreature(*me, instance->GetData64(DATA_STALAGG)))
+ pStalagg->Respawn();
+ }
+ else
+ {
+ if (instance)
+ if (Creature *pFeugen = me->GetCreature(*me, instance->GetData64(DATA_FEUGEN)))
+ pFeugen->Respawn();
+ }
+ }
+ }
+
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SHIFT:
+ DoCastAOE(SPELL_POLARITY_SHIFT);
+ events.ScheduleEvent(EVENT_SHIFT, 30000);
+ return;
+ case EVENT_CHAIN:
+ DoCast(me->getVictim(), RAID_MODE(SPELL_CHAIN_LIGHTNING, H_SPELL_CHAIN_LIGHTNING));
+ events.ScheduleEvent(EVENT_CHAIN, urand(10000,20000));
+ return;
+ case EVENT_BERSERK:
+ DoCast(me, SPELL_BERSERK);
+ return;
+ }
+ }
+
+ if (events.GetTimer() > 15000 && !me->IsWithinMeleeRange(me->getVictim()))
+ DoCast(me->getVictim(), SPELL_BALL_LIGHTNING);
+ else
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_thaddius(Creature* pCreature)
+{
+ return new boss_thaddiusAI (pCreature);
+}
+
+struct mob_stalaggAI : public ScriptedAI
+{
+ mob_stalaggAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 powerSurgeTimer;
+ uint32 magneticPullTimer;
+
+ void Reset()
+ {
+ if (pInstance)
+ if (Creature *pThaddius = me->GetCreature(*me, pInstance->GetData64(DATA_THADDIUS)))
+ if (pThaddius->AI())
+ pThaddius->AI()->DoAction(ACTION_STALAGG_RESET);
+ powerSurgeTimer = urand(20000,25000);
+ magneticPullTimer = 20000;
+ }
+
+ void EnterCombat(Unit * /*pWho*/)
+ {
+ DoCast(SPELL_STALAGG_TESLA);
+ }
+
+ void JustDied(Unit * /*killer*/)
+ {
+ if (pInstance)
+ if (Creature *pThaddius = me->GetCreature(*me, pInstance->GetData64(DATA_THADDIUS)))
+ if (pThaddius->AI())
+ pThaddius->AI()->DoAction(ACTION_STALAGG_DIED);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (magneticPullTimer <= uiDiff)
+ {
+ if (Creature *pFeugen = me->GetCreature(*me, pInstance->GetData64(DATA_FEUGEN)))
+ {
+ Unit* pStalaggVictim = me->getVictim();
+ Unit* pFeugenVictim = pFeugen->getVictim();
+
+ if (pFeugenVictim && pStalaggVictim)
+ {
+ // magnetic pull is not working. So just jump.
+
+ // reset aggro to be sure that feugen will not follow the jump
+ pFeugen->getThreatManager().modifyThreatPercent(pFeugenVictim, -100);
+ pFeugenVictim->JumpTo(me, 0.3f);
+
+ me->getThreatManager().modifyThreatPercent(pStalaggVictim, -100);
+ pStalaggVictim->JumpTo(pFeugen, 0.3f);
+ }
+ }
+
+ magneticPullTimer = 20000;
+ }
+ else magneticPullTimer -= uiDiff;
+
+ if (powerSurgeTimer <= uiDiff)
+ {
+ DoCast(me, RAID_MODE(SPELL_POWERSURGE, H_SPELL_POWERSURGE));
+ powerSurgeTimer = urand(15000,20000);
+ } else powerSurgeTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_stalagg(Creature* pCreature)
+{
+ return new mob_stalaggAI(pCreature);
+}
+
+struct mob_feugenAI : public ScriptedAI
+{
+ mob_feugenAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 staticFieldTimer;
+
+ void Reset()
+ {
+ if (pInstance)
+ if (Creature *pThaddius = me->GetCreature(*me, pInstance->GetData64(DATA_THADDIUS)))
+ if (pThaddius->AI())
+ pThaddius->AI()->DoAction(ACTION_FEUGEN_RESET);
+ staticFieldTimer = 5000;
+ }
+
+ void EnterCombat(Unit * /*pWho*/)
+ {
+ DoCast(SPELL_FEUGEN_TESLA);
+ }
+
+ void JustDied(Unit * /*killer*/)
+ {
+ if (pInstance)
+ if (Creature *pThaddius = me->GetCreature(*me, pInstance->GetData64(DATA_THADDIUS)))
+ if (pThaddius->AI())
+ pThaddius->AI()->DoAction(ACTION_FEUGEN_DIED);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (staticFieldTimer <= uiDiff)
+ {
+ DoCast(me, RAID_MODE(SPELL_STATICFIELD, H_SPELL_STATICFIELD));
+ staticFieldTimer = 5000;
+ } else staticFieldTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_feugen(Creature* pCreature)
+{
+ return new mob_feugenAI(pCreature);
+}
+
+void AddSC_boss_thaddius()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_thaddius";
+ newscript->GetAI = &GetAI_boss_thaddius;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_stalagg";
+ newscript->GetAI = &GetAI_mob_stalagg;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_feugen";
+ newscript->GetAI = &GetAI_mob_feugen;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/naxxramas/instance_naxxramas.cpp b/src/server/scripts/northrend/naxxramas/instance_naxxramas.cpp
new file mode 100644
index 00000000000..706789a73f1
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/instance_naxxramas.cpp
@@ -0,0 +1,324 @@
+/* Copyright (C) 2008 - 2010 Trinity <http://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "naxxramas.h"
+
+const DoorData doorData[] =
+{
+ {181126, BOSS_ANUBREKHAN,DOOR_TYPE_ROOM, BOUNDARY_S},
+ {181195, BOSS_ANUBREKHAN,DOOR_TYPE_PASSAGE, 0},
+ {194022, BOSS_FAERLINA, DOOR_TYPE_PASSAGE, 0},
+ {181209, BOSS_FAERLINA, DOOR_TYPE_PASSAGE, 0},
+ {181209, BOSS_MAEXXNA, DOOR_TYPE_ROOM, BOUNDARY_SW},
+ {181200, BOSS_NOTH, DOOR_TYPE_ROOM, BOUNDARY_N},
+ {181201, BOSS_NOTH, DOOR_TYPE_PASSAGE, BOUNDARY_E},
+ {181202, BOSS_NOTH, DOOR_TYPE_PASSAGE, 0},
+ {181202, BOSS_HEIGAN, DOOR_TYPE_ROOM, BOUNDARY_N},
+ {181203, BOSS_HEIGAN, DOOR_TYPE_PASSAGE, BOUNDARY_E},
+ {181241, BOSS_HEIGAN, DOOR_TYPE_PASSAGE, 0},
+ {181241, BOSS_LOATHEB, DOOR_TYPE_ROOM, BOUNDARY_W},
+ {181123, BOSS_PATCHWERK, DOOR_TYPE_PASSAGE, 0},
+ {181123, BOSS_GROBBULUS, DOOR_TYPE_ROOM, 0},
+ {181120, BOSS_GLUTH, DOOR_TYPE_PASSAGE, BOUNDARY_NW},
+ {181121, BOSS_GLUTH, DOOR_TYPE_PASSAGE, 0},
+ {181121, BOSS_THADDIUS, DOOR_TYPE_ROOM, 0},
+ {181124, BOSS_RAZUVIOUS, DOOR_TYPE_PASSAGE, 0},
+ {181124, BOSS_GOTHIK, DOOR_TYPE_ROOM, BOUNDARY_N},
+ {181125, BOSS_GOTHIK, DOOR_TYPE_PASSAGE, BOUNDARY_S},
+ {181119, BOSS_GOTHIK, DOOR_TYPE_PASSAGE, 0},
+ {181119, BOSS_HORSEMEN, DOOR_TYPE_ROOM, BOUNDARY_NE},
+ {181225, BOSS_SAPPHIRON, DOOR_TYPE_PASSAGE, BOUNDARY_W},
+ {181228, BOSS_KELTHUZAD, DOOR_TYPE_ROOM, BOUNDARY_S},
+ {0, 0, DOOR_TYPE_ROOM, 0}, // EOF
+};
+
+const MinionData minionData[] =
+{
+ //{16573, BOSS_ANUBREKHAN}, there is no spawn point in db, so we do not add them here
+ {16506, BOSS_FAERLINA},
+ {16803, BOSS_RAZUVIOUS},
+ {16063, BOSS_HORSEMEN},
+ {16064, BOSS_HORSEMEN},
+ {16065, BOSS_HORSEMEN},
+ {30549, BOSS_HORSEMEN},
+ {0, 0,}
+};
+
+enum eEnums
+{
+ GO_HORSEMEN_CHEST_HERO = 193426,
+ GO_HORSEMEN_CHEST = 181366, //four horsemen event, DoRespawnGameObject() when event == DONE
+ GO_GOTHIK_GATE = 181170,
+ GO_KELTHUZAD_PORTAL01 = 181402,
+ GO_KELTHUZAD_PORTAL02 = 181403,
+ GO_KELTHUZAD_PORTAL03 = 181404,
+ GO_KELTHUZAD_PORTAL04 = 181405,
+ GO_KELTHUZAD_TRIGGER = 181444,
+
+ SPELL_ERUPTION = 29371
+};
+
+const float HeiganPos[2] = {2796, -3707};
+const float HeiganEruptionSlope[3] =
+{
+ (-3685 - HeiganPos[1]) /(2724 - HeiganPos[0]),
+ (-3647 - HeiganPos[1]) /(2749 - HeiganPos[0]),
+ (-3637 - HeiganPos[1]) /(2771 - HeiganPos[0]),
+};
+
+// 0 H x
+// 1 ^
+// 2 |
+// 3 y<--o
+inline uint32 GetEruptionSection(float x, float y)
+{
+ y -= HeiganPos[1];
+ if (y < 1.0f)
+ return 0;
+
+ x -= HeiganPos[0];
+ if (x > -1.0f)
+ return 3;
+
+ float slope = y/x;
+ for (uint32 i = 0; i < 3; ++i)
+ if (slope > HeiganEruptionSlope[i])
+ return i;
+ return 3;
+}
+
+struct instance_naxxramas : public InstanceData
+{
+ instance_naxxramas(Map* pMap) : InstanceData(pMap)
+ {
+ SetBossNumber(MAX_BOSS_NUMBER);
+ LoadDoorData(doorData);
+ LoadMinionData(minionData);
+ }
+
+ std::set<uint64> HeiganEruptionGUID[4];
+ uint64 GothikGateGUID;
+ uint64 HorsemenChestGUID;
+ uint64 SapphironGUID;
+ uint64 uiFaerlina;
+ uint64 uiThane;
+ uint64 uiLady;
+ uint64 uiBaron;
+ uint64 uiSir;
+
+ uint64 uiThaddius;
+ uint64 uiFeugen;
+ uint64 uiStalagg;
+
+ uint64 uiKelthuzad;
+ uint64 uiKelthuzadTrigger;
+ uint64 uiPortals[4];
+
+ time_t minHorsemenDiedTime;
+ time_t maxHorsemenDiedTime;
+
+ void OnCreatureCreate(Creature* pCreature, bool add)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case 15989: SapphironGUID = add ? pCreature->GetGUID() : 0; return;
+ case 15953: uiFaerlina = pCreature->GetGUID(); return;
+ case 16064: uiThane = pCreature->GetGUID(); return;
+ case 16065: uiLady = pCreature->GetGUID(); return;
+ case 30549: uiBaron = pCreature->GetGUID(); return;
+ case 16063: uiSir = pCreature->GetGUID(); return;
+ case 15928: uiThaddius = pCreature->GetGUID(); return;
+ case 15930: uiFeugen = pCreature->GetGUID(); return;
+ case 15929: uiStalagg = pCreature->GetGUID(); return;
+ case 15990: uiKelthuzad = pCreature->GetGUID(); return;
+ }
+
+ AddMinion(pCreature, add);
+ }
+
+ void OnGameObjectCreate(GameObject* pGo, bool add)
+ {
+ if (pGo->GetGOInfo()->displayId == 6785 || pGo->GetGOInfo()->displayId == 1287)
+ {
+ uint32 section = GetEruptionSection(pGo->GetPositionX(), pGo->GetPositionY());
+ if (add)
+ HeiganEruptionGUID[section].insert(pGo->GetGUID());
+ else
+ HeiganEruptionGUID[section].erase(pGo->GetGUID());
+ return;
+ }
+
+ switch(pGo->GetEntry())
+ {
+ case GO_BIRTH:
+ if (!add && SapphironGUID)
+ {
+ if (Creature *pSapphiron = instance->GetCreature(SapphironGUID))
+ pSapphiron->AI()->DoAction(DATA_SAPPHIRON_BIRTH);
+ return;
+ }
+ case GO_GOTHIK_GATE: GothikGateGUID = add ? pGo->GetGUID() : 0; break;
+ case GO_HORSEMEN_CHEST: HorsemenChestGUID = add ? pGo->GetGUID() : 0; break;
+ case GO_HORSEMEN_CHEST_HERO: HorsemenChestGUID = add ? pGo->GetGUID() : 0; break;
+ case GO_KELTHUZAD_PORTAL01: uiPortals[0] = pGo->GetGUID(); break;
+ case GO_KELTHUZAD_PORTAL02: uiPortals[1] = pGo->GetGUID(); break;
+ case GO_KELTHUZAD_PORTAL03: uiPortals[2] = pGo->GetGUID(); break;
+ case GO_KELTHUZAD_PORTAL04: uiPortals[3] = pGo->GetGUID(); break;
+ case GO_KELTHUZAD_TRIGGER: uiKelthuzadTrigger = pGo->GetGUID(); break;
+ }
+
+ AddDoor(pGo, add);
+ }
+
+ void SetData(uint32 id, uint32 value)
+ {
+ switch(id)
+ {
+ case DATA_HEIGAN_ERUPT:
+ HeiganErupt(value);
+ break;
+ case DATA_GOTHIK_GATE:
+ if (GameObject *pGothikGate = instance->GetGameObject(GothikGateGUID))
+ pGothikGate->SetGoState(GOState(value));
+ break;
+
+ case DATA_HORSEMEN0:
+ case DATA_HORSEMEN1:
+ case DATA_HORSEMEN2:
+ case DATA_HORSEMEN3:
+ if (value == NOT_STARTED)
+ {
+ minHorsemenDiedTime = 0;
+ maxHorsemenDiedTime = 0;
+ }
+ else if (value == DONE)
+ {
+ time_t now = time(NULL);
+
+ if (minHorsemenDiedTime == 0)
+ minHorsemenDiedTime = now;
+
+ maxHorsemenDiedTime = now;
+ }
+ break;
+ }
+ }
+
+ uint64 GetData64(uint32 id)
+ {
+ switch(id)
+ {
+ case DATA_FAERLINA:
+ return uiFaerlina;
+ case DATA_THANE:
+ return uiThane;
+ case DATA_LADY:
+ return uiLady;
+ case DATA_BARON:
+ return uiBaron;
+ case DATA_SIR:
+ return uiSir;
+ case DATA_THADDIUS:
+ return uiThaddius;
+ case DATA_FEUGEN:
+ return uiFeugen;
+ case DATA_STALAGG:
+ return uiStalagg;
+ case DATA_KELTHUZAD:
+ return uiKelthuzad;
+ case DATA_KELTHUZAD_PORTAL01:
+ return uiPortals[0];
+ case DATA_KELTHUZAD_PORTAL02:
+ return uiPortals[1];
+ case DATA_KELTHUZAD_PORTAL03:
+ return uiPortals[2];
+ case DATA_KELTHUZAD_PORTAL04:
+ return uiPortals[3];
+ case DATA_KELTHUZAD_TRIGGER:
+ return uiKelthuzadTrigger;
+ }
+ return 0;
+ }
+
+ bool SetBossState(uint32 id, EncounterState state)
+ {
+ if (!InstanceData::SetBossState(id, state))
+ return false;
+
+ if (id == BOSS_HORSEMEN && state == DONE)
+ {
+ if (GameObject *pHorsemenChest = instance->GetGameObject(HorsemenChestGUID))
+ pHorsemenChest->SetRespawnTime(pHorsemenChest->GetRespawnDelay());
+ }
+
+ return true;
+ }
+
+ void HeiganErupt(uint32 section)
+ {
+ for (uint32 i = 0; i < 4; ++i)
+ {
+ if (i == section)
+ continue;
+
+ for (std::set<uint64>::const_iterator itr = HeiganEruptionGUID[i].begin(); itr != HeiganEruptionGUID[i].end(); ++itr)
+ {
+ if (GameObject *pHeiganEruption = instance->GetGameObject(*itr))
+ {
+ pHeiganEruption->SendCustomAnim();
+ pHeiganEruption->CastSpell(NULL, SPELL_ERUPTION);
+ }
+ }
+ }
+ }
+
+ bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target = NULL*/, uint32 /*miscvalue1 = 0*/)
+ {
+ switch(criteria_id)
+ {
+ case 7600: // Criteria for achievement 2176: And They Would All Go Down Together 15sec of each other 10-man
+ if (Difficulty(instance->GetSpawnMode()) == RAID_DIFFICULTY_10MAN_NORMAL && (maxHorsemenDiedTime - minHorsemenDiedTime) < 15)
+ return true;
+ return false;
+ case 7601: // Criteria for achievement 2177: And They Would All Go Down Together 15sec of each other 25-man
+ if (Difficulty(instance->GetSpawnMode()) == RAID_DIFFICULTY_25MAN_NORMAL && (maxHorsemenDiedTime - minHorsemenDiedTime) < 15)
+ return true;
+ return false;
+ case 13233: // Criteria for achievement 2186: The Immortal (25-man)
+ // TODO.
+ break;
+ case 13237: // Criteria for achievement 2187: The Undying (10-man)
+ // TODO.
+ break;
+ }
+ return false;
+ }
+};
+
+InstanceData* GetInstanceData_instance_naxxramas(Map* pMap)
+{
+ return new instance_naxxramas(pMap);
+}
+
+void AddSC_instance_naxxramas()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_naxxramas";
+ newscript->GetInstanceData = &GetInstanceData_instance_naxxramas;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/naxxramas/naxxramas.h b/src/server/scripts/northrend/naxxramas/naxxramas.h
new file mode 100644
index 00000000000..9b1fac2ff5b
--- /dev/null
+++ b/src/server/scripts/northrend/naxxramas/naxxramas.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008 - 2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DEF_NAXXRAMAS_H
+#define DEF_NAXXRAMAS_H
+
+enum Encounter
+{
+ BOSS_ANUBREKHAN,
+ BOSS_FAERLINA,
+ BOSS_MAEXXNA,
+ BOSS_NOTH,
+ BOSS_HEIGAN,
+ BOSS_LOATHEB,
+ BOSS_PATCHWERK,
+ BOSS_GROBBULUS,
+ BOSS_GLUTH,
+ BOSS_THADDIUS,
+ BOSS_RAZUVIOUS,
+ BOSS_GOTHIK,
+ BOSS_HORSEMEN,
+ BOSS_SAPPHIRON,
+ BOSS_KELTHUZAD,
+ MAX_BOSS_NUMBER
+};
+
+enum Data
+{
+ DATA_HEIGAN_ERUPT,
+ DATA_GOTHIK_GATE,
+ DATA_SAPPHIRON_BIRTH,
+
+ DATA_HORSEMEN0,
+ DATA_HORSEMEN1,
+ DATA_HORSEMEN2,
+ DATA_HORSEMEN3,
+};
+
+enum Data64
+{
+ DATA_FAERLINA,
+ DATA_THANE,
+ DATA_LADY,
+ DATA_BARON,
+ DATA_SIR,
+ DATA_THADDIUS,
+ DATA_FEUGEN,
+ DATA_STALAGG,
+ DATA_KELTHUZAD,
+ DATA_KELTHUZAD_PORTAL01,
+ DATA_KELTHUZAD_PORTAL02,
+ DATA_KELTHUZAD_PORTAL03,
+ DATA_KELTHUZAD_PORTAL04,
+ DATA_KELTHUZAD_TRIGGER,
+};
+
+#define GO_BIRTH 181356
+
+#endif
+
diff --git a/src/server/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp b/src/server/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp
new file mode 100644
index 00000000000..bbb1df2731d
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/eye_of_eternity/boss_malygos.cpp
@@ -0,0 +1,175 @@
+/* Script Data Start
+SDName: Boss malygos
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "ScriptedPch.h"
+
+//Spells
+#define SPELL_ARCANE_BREATH_N 56272
+#define SPELL_ARCANE_BREATH_H 60072
+#define SPELL_ARCANE_PULSE 57432
+#define SPELL_ARCANE_STORM_1 57459
+#define SPELL_ARCANE_STORM_2 61693
+#define SPELL_ARCANE_STORM_3 61694
+#define SPELL_STATIC_FIELD 57430
+#define SPELL_SURGE_OF_POWER_1 56505
+#define SPELL_SURGE_OF_POWER_2 57407
+#define SPELL_SURGE_OF_POWER_3 60936
+#define SPELL_VORTEX 56105
+
+//Dragon "mounts" spells in Phase3
+//they use Rugelike energy
+#define SPELL_DMOUNT_FLAME_SPIKE 56091 //maybe not accurate
+#define SPELL_DMOUNT_ENGULF_IN_FLAMES 61621
+#define SPELL_DMOUNT_REVIVIFY 57090
+#define SPELL_DMOUNT_LIFE_BURST 57143
+#define SPELL_DMOUNT_FLAME_SHIELD 57108
+//#define SPELL_DMOUNT_UNKNOWN XYZ //Increases your drake's flight speed by 500%.
+
+//not in db
+//Yell
+//-->Other
+#define SAY_ANTI_MAGIC_SHELL -1616000
+#define SAY_BREATH_ATTACK -1616001
+#define SAY_HIGH_DAMAGE_MODE -1616002
+#define SAY_MAGIC_BLAST -1616003
+//--> Generic Spells
+#define SAY_GENERIC_SPELL_1 -1616004
+#define SAY_GENERIC_SPELL_2 -1616005
+#define SAY_GENERIC_SPELL_3 -1616006
+#define SAY_DEATH -1616007
+//--> Prefight
+#define SAY_PREFIGHT_1 -1616008
+#define SAY_PREFIGHT_2 -1616009
+#define SAY_PREFIGHT_3 -1616010
+#define SAY_PREFIGHT_4 -1616011
+#define SAY_PREFIGHT_5 -1616012
+//--> Phase1
+#define SAY_PHASE1_AGGRO -1616013
+#define SAY_PHASE1_END -1616014
+#define SAY_PHASE1_SLAY_1 -1616015
+#define SAY_PHASE1_SLAY_2 -1616016
+#define SAY_PHASE1_SLAY_3 -1616017
+
+//--> Phase2 at 50% HP,
+
+/*Malygos himself is not targetable during this phase, it will end when the adds he spawns are all killed. However, he does continue to play a part in the encounter.
+During this phase he drops anti-magic zones onto the ground the raid MUST stand inside of, it reduces magical damage taken by 50%. They shrink over time, so it's important that your raid moves to each new one he drops.
+Throughout the phase, he will deep breath doing ~4k damage per second, unless you are standing inside of the anti-magic zone.
+The way the fight works during this phase is there are NPCs riding around on disks in the room. There are two types of mobs, Lords and Scions.
+The Lords will move down onto the group, and need to be tanked (They will one-shot a non-tank). After they die, they drop a disk that a raid member can mount onto, which allows them to fly, to attack the Scions that do not come down to the ground.
+It is recommended to let melee take the first disks, then ranged. As those mobs die, they also drop disks, which allows the rest of your dps to get onto them.
+The Scions will continually cast Arcane Blast on random targets on the floor, which is mitigated by the anti-magic zones. While mounted on a disk, you will not take damage.
+After all of the NPCs riding on the disks die, the players on the disks need to dismount as Phase 3 is about to begin.*/
+
+//not in db
+#define SAY_PHASE2_AGGRO -1616018
+#define SAY_PHASE2_END -1616019
+#define SAY_PHASE2_SLAY_1 -1616020
+#define SAY_PHASE2_SLAY_2 -1616021
+#define SAY_PHASE2_SLAY_3 -1616022
+//--> Phase3 Malygos destroys the floor, encounter continues on dragon "mounts"
+#define SAY_PHASE3_INTRO -1616023
+#define SAY_PHASE3_AGGRO -1616024
+#define SAY_PHASE3_SLAY_1 -1616025
+#define SAY_PHASE3_SLAY_2 -1616026
+#define SAY_PHASE3_SLAY_3 -1616027
+#define SAY_PHASE3_BIG_ATTACK -1616028
+
+enum
+{
+ ACHIEV_TIMED_START_EVENT = 20387,
+};
+
+struct boss_malygosAI : public ScriptedAI
+{
+ boss_malygosAI(Creature *c) : ScriptedAI(c)
+ {
+ instance = me->GetInstanceData();
+ }
+
+ InstanceData *instance;
+
+ uint32 phase;
+ uint32 enrage;
+
+ void Reset()
+ {
+ phase = 1;
+ enrage = 615000; //Source Deadly Boss Mod
+
+ if (instance)
+ instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ if (phase == 1)
+ {
+ DoScriptText(SAY_PHASE1_AGGRO, me);
+ if (instance)
+ instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ }
+
+ if (phase == 2)
+ DoScriptText(SAY_PHASE1_AGGRO, me);
+ if (phase == 3)
+ DoScriptText(SAY_PHASE1_AGGRO, me);
+ }
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (phase == 1 && HealthBelowPct(50)) {
+ phase = 2;
+ //spawn adds
+ //set malygos unatackable untill all adds spawned dead
+ //start phase3
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+
+ if (phase == 1)
+ DoScriptText(RAND(SAY_PHASE1_SLAY_1,SAY_PHASE1_SLAY_2,SAY_PHASE1_SLAY_3), me);
+ if (phase == 2)
+ DoScriptText(RAND(SAY_PHASE2_SLAY_1,SAY_PHASE2_SLAY_2,SAY_PHASE2_SLAY_3), me);
+ if (phase == 3)
+ DoScriptText(RAND(SAY_PHASE3_SLAY_1,SAY_PHASE3_SLAY_2,SAY_PHASE3_SLAY_3), me);
+ }
+};
+
+CreatureAI* GetAI_boss_malygos(Creature* pCreature)
+{
+ return new boss_malygosAI (pCreature);
+}
+
+void AddSC_boss_malygos()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_malygos";
+ newscript->GetAI = &GetAI_boss_malygos;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h b/src/server/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h
new file mode 100644
index 00000000000..caa82a92e95
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/eye_of_eternity/eye_of_eternity.h
@@ -0,0 +1,4 @@
+#ifndef DEF_EYE_OF_ETERNITY_H
+#define DEF_EYE_OF_ETERNITY_H
+
+#endif
diff --git a/src/server/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp b/src/server/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp
new file mode 100644
index 00000000000..d93ec415b42
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/eye_of_eternity/instance_eye_of_eternity.cpp
@@ -0,0 +1,21 @@
+#include "ScriptedPch.h"
+#include "eye_of_eternity.h"
+
+struct instance_eye_of_eternity : public ScriptedInstance
+{
+ instance_eye_of_eternity(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+};
+
+InstanceData* GetInstanceData_instance_eye_of_eternity(Map* pMap)
+{
+ return new instance_eye_of_eternity(pMap);
+}
+
+void AddSC_instance_eye_of_eternity()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_eye_of_eternity";
+ newscript->GetInstanceData = &GetInstanceData_instance_eye_of_eternity;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/nexus/boss_anomalus.cpp b/src/server/scripts/northrend/nexus/nexus/boss_anomalus.cpp
new file mode 100644
index 00000000000..02c39dc1232
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/nexus/boss_anomalus.cpp
@@ -0,0 +1,253 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "nexus.h"
+
+enum Spells
+{
+ //Spells
+ SPELL_SPARK = 47751,
+ H_SPELL_SPARK = 57062,
+ SPELL_RIFT_SHIELD = 47748,
+ SPELL_CHARGE_RIFT = 47747, //Works wrong (affect players, not rifts)
+ SPELL_CREATE_RIFT = 47743, //Don't work, using WA
+ SPELL_ARCANE_ATTRACTION = 57063, //No idea, when it's used
+};
+
+enum Adds
+{
+ MOB_CRAZED_MANA_WRAITH = 26746,
+ MOB_CHAOTIC_RIFT = 26918
+};
+enum Yells
+{
+ //Yell
+ SAY_AGGRO = -1576010,
+ SAY_DEATH = -1576011,
+ SAY_RIFT = -1576012,
+ SAY_SHIELD = -1576013
+};
+
+enum Achievs
+{
+ ACHIEV_CHAOS_THEORY = 2037
+};
+
+const Position RiftLocation[6] =
+{
+ {652.64, -273.70, -8.75},
+ {634.45, -265.94, -8.44},
+ {620.73, -281.17, -9.02},
+ {626.10, -304.67, -9.44},
+ {639.87, -314.11, -9.49},
+ {651.72, -297.44, -9.37}
+};
+
+struct boss_anomalusAI : public ScriptedAI
+{
+ boss_anomalusAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint8 Phase;
+ uint32 uiSparkTimer;
+ uint32 uiCreateRiftTimer;
+ uint64 uiChaoticRiftGUID;
+
+ bool bDeadChaoticRift; // needed for achievement: Chaos Theory(2037)
+
+ void Reset()
+ {
+ Phase = 0;
+ uiSparkTimer = 5*IN_MILISECONDS;
+ uiChaoticRiftGUID = 0;
+
+ bDeadChaoticRift = false;
+
+ if (pInstance)
+ pInstance->SetData(DATA_ANOMALUS_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_ANOMALUS_EVENT, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ {
+ if (IsHeroic() && !bDeadChaoticRift)
+ pInstance->DoCompleteAchievement(ACHIEV_CHAOS_THEORY);
+ pInstance->SetData(DATA_ANOMALUS_EVENT, DONE);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (me->GetDistance(me->GetHomePosition()) > 60.0f)
+ {
+ //Not blizzlike, hack to avoid an exploit
+ EnterEvadeMode();
+ return;
+ }
+
+ if (me->HasAura(SPELL_RIFT_SHIELD))
+ {
+ if (uiChaoticRiftGUID)
+ {
+ Unit* Rift = Unit::GetUnit((*me), uiChaoticRiftGUID);
+ if (Rift && Rift->isDead())
+ {
+ me->RemoveAurasDueToSpell(SPELL_RIFT_SHIELD);
+ uiChaoticRiftGUID = 0;
+ }
+ return;
+ }
+ } else
+ uiChaoticRiftGUID = 0;
+
+ if ((Phase == 0) && HealthBelowPct(50))
+ {
+ Phase = 1;
+ DoScriptText(SAY_SHIELD, me);
+ DoCast(me, SPELL_RIFT_SHIELD);
+ Creature* Rift = me->SummonCreature(MOB_CHAOTIC_RIFT, RiftLocation[urand(0,5)], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1*IN_MILISECONDS);
+ if (Rift)
+ {
+ //DoCast(Rift, SPELL_CHARGE_RIFT);
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ Rift->AI()->AttackStart(pTarget);
+ uiChaoticRiftGUID = Rift->GetGUID();
+ DoScriptText(SAY_RIFT , me);
+ }
+ }
+
+
+ if (uiSparkTimer <= diff)
+ {
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SPARK);
+ uiSparkTimer = 5*IN_MILISECONDS;
+ } else uiSparkTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_anomalus(Creature* pCreature)
+{
+ return new boss_anomalusAI (pCreature);
+}
+
+enum RiftSpells
+{
+ SPELL_CHAOTIC_ENERGY_BURST = 47688,
+ SPELL_CHARGED_CHAOTIC_ENERGY_BURST = 47737,
+ SPELL_ARCANEFORM = 48019 //Chaotic Rift visual
+};
+
+struct mob_chaotic_riftAI : public Scripted_NoMovementAI
+{
+ mob_chaotic_riftAI(Creature *c) : Scripted_NoMovementAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiChaoticEnergyBurstTimer;
+ uint32 uiSummonCrazedManaWraithTimer;
+
+ void Reset()
+ {
+ uiChaoticEnergyBurstTimer = 1*IN_MILISECONDS;
+ uiSummonCrazedManaWraithTimer = 5*IN_MILISECONDS;
+ //me->SetDisplayId(25206); //For some reason in DB models for ally and horde are different.
+ //Model for ally (1126) does not show auras. Horde model works perfect.
+ //Set model to horde number
+ DoCast(me, SPELL_ARCANEFORM, false);
+ }
+
+ void JustDied(Unit * /*killer*/)
+ {
+ if (Creature* pAnomalus = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_ANOMALUS) : 0))
+ CAST_AI(boss_anomalusAI,pAnomalus->AI())->bDeadChaoticRift = true;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiChaoticEnergyBurstTimer <= diff)
+ {
+ Unit* pAnomalus = Unit::GetUnit(*me, pInstance ? pInstance->GetData64(DATA_ANOMALUS) : 0);
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ if (pAnomalus && pAnomalus->HasAura(SPELL_RIFT_SHIELD))
+ DoCast(pTarget, SPELL_CHARGED_CHAOTIC_ENERGY_BURST);
+ else
+ DoCast(pTarget, SPELL_CHAOTIC_ENERGY_BURST);
+ uiChaoticEnergyBurstTimer = 1*IN_MILISECONDS;
+ } else uiChaoticEnergyBurstTimer -= diff;
+
+ if (uiSummonCrazedManaWraithTimer <= diff)
+ {
+ Creature* Wraith = me->SummonCreature(MOB_CRAZED_MANA_WRAITH, me->GetPositionX()+1, me->GetPositionY()+1, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1*IN_MILISECONDS);
+ if (Wraith)
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ Wraith->AI()->AttackStart(pTarget);
+ Unit* Anomalus = Unit::GetUnit(*me, pInstance ? pInstance->GetData64(DATA_ANOMALUS) : 0);
+ if (Anomalus && Anomalus->HasAura(SPELL_RIFT_SHIELD))
+ uiSummonCrazedManaWraithTimer = 5*IN_MILISECONDS;
+ else
+ uiSummonCrazedManaWraithTimer = 10*IN_MILISECONDS;
+ } else uiSummonCrazedManaWraithTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_chaotic_rift(Creature* pCreature)
+{
+ return new mob_chaotic_riftAI (pCreature);
+}
+
+void AddSC_boss_anomalus()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_anomalus";
+ newscript->GetAI = &GetAI_boss_anomalus;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_chaotic_rift";
+ newscript->GetAI = &GetAI_mob_chaotic_rift;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/nexus/boss_keristrasza.cpp b/src/server/scripts/northrend/nexus/nexus/boss_keristrasza.cpp
new file mode 100644
index 00000000000..ff633c55eac
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/nexus/boss_keristrasza.cpp
@@ -0,0 +1,247 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "nexus.h"
+
+enum Spells
+{
+ //Spells
+ SPELL_FROZEN_PRISON = 47854,
+ SPELL_TAIL_SWEEP = 50155,
+ SPELL_CRYSTAL_CHAINS = 50997,
+ SPELL_ENRAGE = 8599,
+ SPELL_CRYSTALFIRE_BREATH = 48096,
+ H_SPELL_CRYSTALFIRE_BREATH = 57091,
+ SPELL_CRYSTALIZE = 48179,
+ SPELL_INTENSE_COLD = 48094,
+ SPELL_INTENSE_COLD_TRIGGERED = 48095
+};
+enum Yells
+{
+ //Yell
+ SAY_AGGRO = -1576040,
+ SAY_SLAY = -1576041,
+ SAY_ENRAGE = -1576042,
+ SAY_DEATH = -1576043,
+ SAY_CRYSTAL_NOVA = -1576044
+};
+enum Achievements
+{
+ ACHIEV_INTENSE_COLD = 2036
+};
+enum Misc
+{
+ DATA_CONTAINMENT_SPHERES = 3
+};
+
+struct boss_keristraszaAI : public ScriptedAI
+{
+ boss_keristraszaAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiCrystalfireBreathTimer;
+ uint32 uiCrystalChainsCrystalizeTimer;
+ uint32 uiTailSweepTimer;
+ bool bEnrage;
+
+ uint64 auiContainmentSphereGUIDs[DATA_CONTAINMENT_SPHERES];
+
+ uint32 uiCheckIntenseColdTimer;
+ bool bMoreThanTwoIntenseCold; // needed for achievement: Intense Cold(2036)
+
+ void Reset()
+ {
+ uiCrystalfireBreathTimer = 14*IN_MILISECONDS;
+ uiCrystalChainsCrystalizeTimer = DUNGEON_MODE(30*IN_MILISECONDS,11*IN_MILISECONDS);
+ uiTailSweepTimer = 5*IN_MILISECONDS;
+ bEnrage = false;
+
+ uiCheckIntenseColdTimer = 2*IN_MILISECONDS;
+ bMoreThanTwoIntenseCold = false;
+
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
+
+ RemovePrison(CheckContainmentSpheres());
+
+ if (pInstance)
+ pInstance->SetData(DATA_KERISTRASZA_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ DoCastAOE(SPELL_INTENSE_COLD);
+
+ if (pInstance)
+ pInstance->SetData(DATA_KERISTRASZA_EVENT, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ {
+ if (IsHeroic() && !bMoreThanTwoIntenseCold)
+ pInstance->DoCompleteAchievement(ACHIEV_INTENSE_COLD);
+ pInstance->SetData(DATA_KERISTRASZA_EVENT, DONE);
+ }
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(SAY_SLAY, me);
+ }
+
+ bool CheckContainmentSpheres(bool remove_prison = false)
+ {
+ if (!pInstance)
+ return false;
+
+ auiContainmentSphereGUIDs[0] = pInstance->GetData64(ANOMALUS_CONTAINMET_SPHERE);
+ auiContainmentSphereGUIDs[1] = pInstance->GetData64(ORMOROKS_CONTAINMET_SPHERE);
+ auiContainmentSphereGUIDs[2] = pInstance->GetData64(TELESTRAS_CONTAINMET_SPHERE);
+
+ GameObject *ContainmentSpheres[DATA_CONTAINMENT_SPHERES];
+
+ for (uint8 i = 0; i < DATA_CONTAINMENT_SPHERES; ++i)
+ {
+ ContainmentSpheres[i] = pInstance->instance->GetGameObject(auiContainmentSphereGUIDs[i]);
+ if (!ContainmentSpheres[i])
+ return false;
+ if (ContainmentSpheres[i]->GetGoState() != GO_STATE_ACTIVE)
+ return false;
+ }
+ if (remove_prison)
+ RemovePrison(true);
+ return true;
+ }
+
+ void RemovePrison(bool remove)
+ {
+ if (remove)
+ {
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (me->HasAura(SPELL_FROZEN_PRISON))
+ me->RemoveAurasDueToSpell(SPELL_FROZEN_PRISON);
+ }
+ else
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ DoCast(me, SPELL_FROZEN_PRISON, false);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiCheckIntenseColdTimer < diff && !bMoreThanTwoIntenseCold)
+ {
+ std::list<HostileReference*> ThreatList = me->getThreatManager().getThreatList();
+ for (std::list<HostileReference*>::const_iterator itr = ThreatList.begin(); itr != ThreatList.end(); ++itr)
+ {
+ Unit *pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid());
+ if (!pTarget || pTarget->GetTypeId() != TYPEID_PLAYER)
+ continue;
+
+ Aura *AuraIntenseCold = pTarget->GetAura(SPELL_INTENSE_COLD_TRIGGERED);
+ if (AuraIntenseCold && AuraIntenseCold->GetStackAmount() > 2)
+ {
+ bMoreThanTwoIntenseCold = true;
+ break;
+ }
+ }
+ uiCheckIntenseColdTimer = 2*IN_MILISECONDS;
+ } else uiCheckIntenseColdTimer -= diff;
+
+ if (!bEnrage && HealthBelowPct(25))
+ {
+ DoScriptText(SAY_ENRAGE, me);
+ DoCast(me, SPELL_ENRAGE);
+ bEnrage = true;
+ }
+
+ if (uiCrystalfireBreathTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_CRYSTALFIRE_BREATH);
+ uiCrystalfireBreathTimer = 14*IN_MILISECONDS;
+ } else uiCrystalfireBreathTimer -= diff;
+
+ if (uiTailSweepTimer <= diff)
+ {
+ DoCast(me, SPELL_TAIL_SWEEP);
+ uiTailSweepTimer = 5*IN_MILISECONDS;
+ } else uiTailSweepTimer -= diff;
+
+ if (uiCrystalChainsCrystalizeTimer <= diff)
+ {
+ DoScriptText(SAY_CRYSTAL_NOVA, me);
+ if (IsHeroic())
+ DoCast(me, SPELL_CRYSTALIZE);
+ else if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_CRYSTAL_CHAINS);
+ uiCrystalChainsCrystalizeTimer = DUNGEON_MODE(30*IN_MILISECONDS,11*IN_MILISECONDS);
+ } else uiCrystalChainsCrystalizeTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_keristrasza(Creature* pCreature)
+{
+ return new boss_keristraszaAI (pCreature);
+}
+
+bool GOHello_containment_sphere(Player * /*pPlayer*/, GameObject *pGO)
+{
+ ScriptedInstance *pInstance = pGO->GetInstanceData();
+
+ Creature *pKeristrasza = Unit::GetCreature(*pGO, pInstance ? pInstance->GetData64(DATA_KERISTRASZA) : 0);
+ if (pKeristrasza && pKeristrasza->isAlive())
+ {
+ // maybe these are hacks :(
+ pGO->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ pGO->SetGoState(GO_STATE_ACTIVE);
+
+ CAST_AI(boss_keristraszaAI, pKeristrasza->AI())->CheckContainmentSpheres(true);
+ }
+ return true;
+}
+
+void AddSC_boss_keristrasza()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_keristrasza";
+ newscript->GetAI = &GetAI_boss_keristrasza;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "containment_sphere";
+ newscript->pGOHello = &GOHello_containment_sphere;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/nexus/boss_magus_telestra.cpp b/src/server/scripts/northrend/nexus/nexus/boss_magus_telestra.cpp
new file mode 100644
index 00000000000..0bf9fb07bb7
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/nexus/boss_magus_telestra.cpp
@@ -0,0 +1,327 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "nexus.h"
+
+enum Spells
+{
+ SPELL_ICE_NOVA = 47772,
+ H_SPELL_ICE_NOVA = 56935,
+ SPELL_FIREBOMB = 47773,
+ H_SPELL_FIREBOMB = 56934,
+ SPELL_GRAVITY_WELL = 47756,
+ SPELL_TELESTRA_BACK = 47714,
+
+ SPELL_FIRE_MAGUS_VISUAL = 47705,
+ SPELL_FROST_MAGUS_VISUAL = 47706,
+ SPELL_ARCANE_MAGUS_VISUAL = 47704
+};
+enum Creatures
+{
+ MOB_FIRE_MAGUS = 26928,
+ MOB_FROST_MAGUS = 26930,
+ MOB_ARCANE_MAGUS = 26929
+};
+enum Yells
+{
+ SAY_AGGRO = -1576000,
+ SAY_KILL = -1576001,
+ SAY_DEATH = -1576002,
+ SAY_MERGE = -1576003,
+ SAY_SPLIT_1 = -1576004,
+ SAY_SPLIT_2 = -1576005,
+};
+enum Achievements
+{
+ ACHIEV_SPLIT_PERSONALITY = 2150,
+ ACHIEV_TIMER = 5*IN_MILISECONDS
+};
+
+const Position CenterOfRoom = {504.80, 89.07, -16.12, 6.27};
+
+struct boss_magus_telestraAI : public ScriptedAI
+{
+ boss_magus_telestraAI(Creature* c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint64 uiFireMagusGUID;
+ uint64 uiFrostMagusGUID;
+ uint64 uiArcaneMagusGUID;
+
+ bool bFireMagusDead;
+ bool bFrostMagusDead;
+ bool bArcaneMagusDead;
+ bool bIsWaitingToAppear;
+ bool bIsAchievementTimerRunning;
+
+ uint32 uiIsWaitingToAppearTimer;
+ uint32 uiIceNovaTimer;
+ uint32 uiFireBombTimer;
+ uint32 uiGravityWellTimer;
+ uint32 uiCooldown;
+ uint32 uiAchievementTimer;
+
+ uint8 Phase;
+ uint8 uiAchievementProgress;
+
+ void Reset()
+ {
+ Phase = 0;
+ //These times are probably wrong
+ uiIceNovaTimer = 7*IN_MILISECONDS;
+ uiFireBombTimer = 0;
+ uiGravityWellTimer = 15*IN_MILISECONDS;
+ uiCooldown = 0;
+
+ uiFireMagusGUID = 0;
+ uiFrostMagusGUID = 0;
+ uiArcaneMagusGUID = 0;
+
+ uiAchievementProgress = 0;
+ uiAchievementTimer = 0;
+
+ bIsAchievementTimerRunning = false;
+ bIsWaitingToAppear = false;
+
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetVisibility(VISIBILITY_ON);
+
+ if (pInstance)
+ pInstance->SetData(DATA_MAGUS_TELESTRA_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_MAGUS_TELESTRA_EVENT, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ {
+ if (IsHeroic() && uiAchievementProgress == 2)
+ pInstance->DoCompleteAchievement(ACHIEV_SPLIT_PERSONALITY);
+ pInstance->SetData(DATA_MAGUS_TELESTRA_EVENT, DONE);
+ }
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(SAY_KILL, me);
+ }
+
+ uint64 SplitPersonality(uint32 entry)
+ {
+ if (Creature* Summoned = me->SummonCreature(entry, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1*IN_MILISECONDS))
+ {
+ switch (entry)
+ {
+ case MOB_FIRE_MAGUS:
+ {
+ Summoned->CastSpell(Summoned, SPELL_FIRE_MAGUS_VISUAL, false);
+ break;
+ }
+ case MOB_FROST_MAGUS:
+ {
+ Summoned->CastSpell(Summoned, SPELL_FROST_MAGUS_VISUAL, false);
+ break;
+ }
+ case MOB_ARCANE_MAGUS:
+ {
+ Summoned->CastSpell(Summoned, SPELL_ARCANE_MAGUS_VISUAL, false);
+ break;
+ }
+ }
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ Summoned->AI()->AttackStart(pTarget);
+ return Summoned->GetGUID();
+ }
+ return 0;
+ }
+
+ void SummonedCreatureDespawn(Creature *summon)
+ {
+ if (summon->isAlive())
+ return;
+
+ if (summon->GetGUID() == uiFireMagusGUID)
+ {
+ bFireMagusDead = true;
+ bIsAchievementTimerRunning = true;
+ }
+ else if (summon->GetGUID() == uiFrostMagusGUID)
+ {
+ bFrostMagusDead = true;
+ bIsAchievementTimerRunning = true;
+ }
+ else if (summon->GetGUID() == uiArcaneMagusGUID)
+ {
+ bArcaneMagusDead = true;
+ bIsAchievementTimerRunning = true;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (bIsWaitingToAppear)
+ {
+ me->StopMoving();
+ me->AttackStop();
+ if (uiIsWaitingToAppearTimer <= diff)
+ {
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ bIsWaitingToAppear = false;
+ } else uiIsWaitingToAppearTimer -= diff;
+ return;
+ }
+
+ if ((Phase == 1) ||(Phase == 3))
+ {
+ if (bIsAchievementTimerRunning)
+ uiAchievementTimer += diff;
+ if (bFireMagusDead && bFrostMagusDead && bArcaneMagusDead)
+ {
+ if (uiAchievementTimer <= ACHIEV_TIMER)
+ uiAchievementProgress +=1;
+ me->GetMotionMaster()->Clear();
+ me->GetMap()->CreatureRelocation(me, CenterOfRoom.GetPositionX(), CenterOfRoom.GetPositionY(), CenterOfRoom.GetPositionZ(), CenterOfRoom.GetOrientation());
+ DoCast(me, SPELL_TELESTRA_BACK);
+ me->SetVisibility(VISIBILITY_ON);
+ if (Phase == 1)
+ Phase = 2;
+ if (Phase == 3)
+ Phase = 4;
+ uiFireMagusGUID = 0;
+ uiFrostMagusGUID = 0;
+ uiArcaneMagusGUID = 0;
+ bIsWaitingToAppear = true;
+ uiIsWaitingToAppearTimer = 4*IN_MILISECONDS;
+ DoScriptText(SAY_MERGE, me);
+ bIsAchievementTimerRunning = false;
+ uiAchievementTimer = 0;
+ }
+ else
+ return;
+ }
+
+ if ((Phase == 0) && HealthBelowPct(50))
+ {
+ Phase = 1;
+ me->CastStop();
+ me->RemoveAllAuras();
+ me->SetVisibility(VISIBILITY_OFF);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ uiFireMagusGUID = SplitPersonality(MOB_FIRE_MAGUS);
+ uiFrostMagusGUID = SplitPersonality(MOB_FROST_MAGUS);
+ uiArcaneMagusGUID = SplitPersonality(MOB_ARCANE_MAGUS);
+ bFireMagusDead = false;
+ bFrostMagusDead = false;
+ bArcaneMagusDead = false;
+ DoScriptText(RAND(SAY_SPLIT_1,SAY_SPLIT_2), me);
+ return;
+ }
+
+ if (IsHeroic() && (Phase == 2) && HealthBelowPct(10))
+ {
+ Phase = 3;
+ me->CastStop();
+ me->RemoveAllAuras();
+ me->SetVisibility(VISIBILITY_OFF);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ uiFireMagusGUID = SplitPersonality(MOB_FIRE_MAGUS);
+ uiFrostMagusGUID = SplitPersonality(MOB_FROST_MAGUS);
+ uiArcaneMagusGUID = SplitPersonality(MOB_ARCANE_MAGUS);
+ bFireMagusDead = false;
+ bFrostMagusDead = false;
+ bArcaneMagusDead = false;
+ DoScriptText(RAND(SAY_SPLIT_1,SAY_SPLIT_2), me);
+ return;
+ }
+
+ if (uiCooldown)
+ {
+ if (uiCooldown <= diff)
+ uiCooldown = 0;
+ else
+ {
+ uiCooldown -= diff;
+ return;
+ }
+ }
+
+ if (uiIceNovaTimer <= diff)
+ {
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ DoCast(pTarget, SPELL_ICE_NOVA, false);
+ uiCooldown = 1.5*IN_MILISECONDS;
+ }
+ uiIceNovaTimer = 15*IN_MILISECONDS;
+ } else uiIceNovaTimer -= diff;
+
+ if (uiGravityWellTimer <= diff)
+ {
+ if (Unit *pTarget = me->getVictim())
+ {
+ DoCast(pTarget, SPELL_GRAVITY_WELL);
+ uiCooldown = 6*IN_MILISECONDS;
+ }
+ uiGravityWellTimer = 15*IN_MILISECONDS;
+ } else uiGravityWellTimer -= diff;
+
+ if (uiFireBombTimer <= diff)
+ {
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ DoCast(pTarget, SPELL_FIREBOMB, false);
+ uiCooldown = 2*IN_MILISECONDS;
+ }
+ uiFireBombTimer = 2*IN_MILISECONDS;
+ } else uiFireBombTimer -=diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_magus_telestra(Creature* pCreature)
+{
+ return new boss_magus_telestraAI (pCreature);
+}
+
+void AddSC_boss_magus_telestra()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_magus_telestra";
+ newscript->GetAI = &GetAI_boss_magus_telestra;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/nexus/boss_ormorok.cpp b/src/server/scripts/northrend/nexus/nexus/boss_ormorok.cpp
new file mode 100644
index 00000000000..1304f95c7ac
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/nexus/boss_ormorok.cpp
@@ -0,0 +1,298 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "nexus.h"
+
+enum Spells
+{
+ SPELL_CRYSTAL_SPIKES = 47958, //Don't work, using walkaround
+ H_SPELL_CRYSTAL_SPIKES = 57082, //Don't work, using walkaround
+ SPELL_CRYSTALL_SPIKE_DAMAGE = 47944,
+ H_SPELL_CRYSTALL_SPIKE_DAMAGE = 57067,
+ SPELL_CRYSTAL_SPIKE_PREVISUAL = 50442,
+ MOB_CRYSTAL_SPIKE = 27099,
+ SPELL_SPELL_REFLECTION = 47981,
+ SPELL_TRAMPLE = 48016,
+ H_SPELL_TRAMPLE = 57066,
+ SPELL_FRENZY = 48017,
+ SPELL_SUMMON_CRYSTALLINE_TANGLER = 61564, //summons npc 32665
+ SPELL_ROOTS = 28858 //proper spell id is unknown
+};
+enum Yells
+{
+ SAY_AGGRO = -1576020,
+ SAY_DEATH = -1576021,
+ SAY_REFLECT = -1576022,
+ SAY_CRYSTAL_SPIKES = -1576023,
+ SAY_KILL = -1576024
+};
+enum Creatures
+{
+ MOB_CRYSTALLINE_TANGLER = 32665
+};
+
+#define SPIKE_DISTANCE 5.0f
+
+struct boss_ormorokAI : public ScriptedAI
+{
+ boss_ormorokAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ bool bFrenzy;
+ bool bCrystalSpikes;
+ uint8 uiCrystalSpikesCount;
+ float fBaseX;
+ float fBaseY;
+ float fBaseZ;
+ float fBaseO;
+ float fSpikeXY[4][2];
+
+ uint32 uiCrystalSpikesTimer;
+ uint32 uiCrystalSpikesTimer2;
+ uint32 uiTrampleTimer;
+ uint32 uiFrenzyTimer;
+ uint32 uiSpellReflectionTimer;
+ uint32 uiSummonCrystallineTanglerTimer;
+
+ void Reset()
+ {
+ uiCrystalSpikesTimer = 12*IN_MILISECONDS;
+ uiTrampleTimer = 10*IN_MILISECONDS;
+ uiSpellReflectionTimer = 30*IN_MILISECONDS;
+ uiSummonCrystallineTanglerTimer = 17*IN_MILISECONDS;
+ bFrenzy = false;
+ bCrystalSpikes = false;
+
+ if (pInstance)
+ pInstance->SetData(DATA_ORMOROK_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_ORMOROK_EVENT, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_ORMOROK_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(SAY_KILL, me);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ {
+ return;
+ }
+ if (bCrystalSpikes)
+ if (uiCrystalSpikesTimer2 <= diff)
+ {
+ fSpikeXY[0][0] = fBaseX+(SPIKE_DISTANCE*uiCrystalSpikesCount*cos(fBaseO));
+ fSpikeXY[0][1] = fBaseY+(SPIKE_DISTANCE*uiCrystalSpikesCount*sin(fBaseO));
+ fSpikeXY[1][0] = fBaseX-(SPIKE_DISTANCE*uiCrystalSpikesCount*cos(fBaseO));
+ fSpikeXY[1][1] = fBaseY-(SPIKE_DISTANCE*uiCrystalSpikesCount*sin(fBaseO));
+ fSpikeXY[2][0] = fBaseX+(SPIKE_DISTANCE*uiCrystalSpikesCount*cos(fBaseO-(M_PI/2)));
+ fSpikeXY[2][1] = fBaseY+(SPIKE_DISTANCE*uiCrystalSpikesCount*sin(fBaseO-(M_PI/2)));
+ fSpikeXY[3][0] = fBaseX-(SPIKE_DISTANCE*uiCrystalSpikesCount*cos(fBaseO-(M_PI/2)));
+ fSpikeXY[3][1] = fBaseY-(SPIKE_DISTANCE*uiCrystalSpikesCount*sin(fBaseO-(M_PI/2)));
+ for (uint8 i = 0; i < 4; ++i)
+ me->SummonCreature(MOB_CRYSTAL_SPIKE, fSpikeXY[i][0], fSpikeXY[i][1], fBaseZ, 0, TEMPSUMMON_TIMED_DESPAWN, 7*IN_MILISECONDS);
+ if (++uiCrystalSpikesCount >= 13)
+ bCrystalSpikes = false;
+ uiCrystalSpikesTimer2 = 200;
+ } else uiCrystalSpikesTimer2 -= diff;
+
+ if (!bFrenzy && (me->GetHealth() < me->GetMaxHealth() * 0.25))
+ {
+ DoCast(me, SPELL_FRENZY);
+ bFrenzy = true;
+ }
+
+ if (uiTrampleTimer <= diff)
+ {
+ DoCast(me, SPELL_TRAMPLE);
+ uiTrampleTimer = 10*IN_MILISECONDS;
+ } else uiTrampleTimer -= diff;
+
+ if (uiSpellReflectionTimer <= diff)
+ {
+ DoScriptText(SAY_REFLECT, me);
+ DoCast(me, SPELL_SPELL_REFLECTION);
+ uiSpellReflectionTimer = 30*IN_MILISECONDS;
+ } else uiSpellReflectionTimer -= diff;
+
+ if (uiCrystalSpikesTimer <= diff)
+ {
+ DoScriptText(SAY_CRYSTAL_SPIKES, me);
+ bCrystalSpikes = true;
+ uiCrystalSpikesCount = 1;
+ uiCrystalSpikesTimer2 = 0;
+ fBaseX = me->GetPositionX();
+ fBaseY = me->GetPositionY();
+ fBaseZ = me->GetPositionZ();
+ fBaseO = me->GetOrientation();
+ uiCrystalSpikesTimer = 20*IN_MILISECONDS;
+ } else uiCrystalSpikesTimer -= diff;
+
+ if (IsHeroic() && (uiSummonCrystallineTanglerTimer <= diff))
+ {
+ Creature* Crystalline_Tangler = me->SummonCreature(MOB_CRYSTALLINE_TANGLER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000);
+ if (Crystalline_Tangler)
+ {
+ Unit *pTarget = NULL;
+ uint8 Healer = 0;
+ for (uint8 j = 1; j <= 4; j++)
+ {
+ switch (j)
+ {
+ case 1: Healer = CLASS_PRIEST; break;
+ case 2: Healer = CLASS_PALADIN; break;
+ case 3: Healer = CLASS_DRUID; break;
+ case 4: Healer = CLASS_SHAMAN; break;
+ }
+ std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
+ for (; i != me->getThreatManager().getThreatList().end(); ++i)
+ {
+ Unit* pTemp = Unit::GetUnit((*me),(*i)->getUnitGuid());
+ if (pTemp && pTemp->GetTypeId() == TYPEID_PLAYER && pTemp->getClass() == Healer)
+ {
+ pTarget = pTemp;
+ break;
+ }
+ }
+ if (pTarget)
+ break;
+ }
+ if (!pTarget)
+ pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ if (pTarget)
+ {
+ Crystalline_Tangler->AI()->AttackStart(pTarget);
+ Crystalline_Tangler->getThreatManager().addThreat(pTarget, 1000000000.0f);
+ }
+ }
+ uiSummonCrystallineTanglerTimer = 17*IN_MILISECONDS;
+ } else uiSummonCrystallineTanglerTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_crystal_spikeAI : public Scripted_NoMovementAI
+{
+ mob_crystal_spikeAI(Creature *c) : Scripted_NoMovementAI(c)
+ {
+ }
+
+ uint32 SpellCrystalSpikeDamageTimer;
+ uint32 SpellCrystalSpikePrevisualTimer;
+
+ void Reset()
+ {
+ SpellCrystalSpikeDamageTimer = 3.7*IN_MILISECONDS;
+ SpellCrystalSpikePrevisualTimer = 1*IN_MILISECONDS;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (SpellCrystalSpikePrevisualTimer <= diff)
+ {
+ DoCast(me, SPELL_CRYSTAL_SPIKE_PREVISUAL);
+ SpellCrystalSpikePrevisualTimer = 10*IN_MILISECONDS;
+ } else SpellCrystalSpikePrevisualTimer -= diff;
+
+ if (SpellCrystalSpikeDamageTimer <= diff)
+ {
+ DoCast(me, SPELL_CRYSTALL_SPIKE_DAMAGE);
+ SpellCrystalSpikeDamageTimer = 10*IN_MILISECONDS;
+ } else SpellCrystalSpikeDamageTimer -= diff;
+ }
+};
+
+struct mob_crystalline_tanglerAI : public ScriptedAI
+{
+ mob_crystalline_tanglerAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 uiRootsTimer;
+
+ void Reset()
+ {
+ uiRootsTimer = 1*IN_MILISECONDS;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (uiRootsTimer <= diff)
+ {
+ if (me->IsWithinDist(me->getVictim(), 5.0f, false))
+ {
+ DoCast(me->getVictim(), SPELL_ROOTS);
+ uiRootsTimer = 15*IN_MILISECONDS;
+ }
+ } else uiRootsTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_crystal_spike(Creature* pCreature)
+{
+ return new mob_crystal_spikeAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_crystalline_tangler(Creature* pCreature)
+{
+ return new mob_crystalline_tanglerAI (pCreature);
+}
+
+CreatureAI* GetAI_boss_ormorok(Creature* pCreature)
+{
+ return new boss_ormorokAI (pCreature);
+}
+
+void AddSC_boss_ormorok()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_ormorok";
+ newscript->GetAI = &GetAI_boss_ormorok;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_crystal_spike";
+ newscript->GetAI = &GetAI_mob_crystal_spike;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_crystalline_tangler";
+ newscript->GetAI = &GetAI_mob_crystalline_tangler;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/nexus/commander_kolurg.cpp b/src/server/scripts/northrend/nexus/nexus/commander_kolurg.cpp
new file mode 100644
index 00000000000..4bd9f55a013
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/nexus/commander_kolurg.cpp
@@ -0,0 +1,58 @@
+/* Script Data Start
+SDName: Boss Commander Kolurg
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment: Only Alliance Heroic
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_commander_kolurg' where entry = '';
+*** SQL END ***/
+#include "ScriptedPch.h"
+
+#define SPELL_BATTLE_SHOUT 31403
+#define SPELL_CHARGE 60067
+#define SPELL_FRIGHTENING_SHOUT 19134
+#define SPELL_WHIRLWIND_1 38619
+#define SPELL_WHIRLWIND_2 38618
+
+//not used
+//Yell
+#define SAY_AGGRO -1576024
+#define SAY_KILL -1576025
+#define SAY_DEATH -1576026
+
+struct boss_commander_kolurgAI : public ScriptedAI
+{
+ boss_commander_kolurgAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* /*who*/) {}
+ void AttackStart(Unit* /*who*/) {}
+ void MoveInLineOfSight(Unit* /*who*/) {}
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* /*killer*/) {}
+};
+
+CreatureAI* GetAI_boss_commander_kolurg(Creature* pCreature)
+{
+ return new boss_commander_kolurgAI (pCreature);
+}
+
+void AddSC_boss_commander_kolurg()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_commander_kolurg";
+ newscript->GetAI = &GetAI_boss_commander_kolurg;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/nexus/commander_stoutbeard.cpp b/src/server/scripts/northrend/nexus/nexus/commander_stoutbeard.cpp
new file mode 100644
index 00000000000..ef02baa38e6
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/nexus/commander_stoutbeard.cpp
@@ -0,0 +1,64 @@
+/* Script Data Start
+SDName: Boss Commander Stoutbeard
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment: Only Horde Heroic
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_commander_stoutbeard' where entry = '';
+*** SQL END ***/
+#include "ScriptedPch.h"
+
+#define SPELL_BATTLE_SHOUT 31403
+#define SPELL_CHARGE 60067
+#define SPELL_FRIGHTENING_SHOUT 19134
+#define SPELL_WHIRLWIND_1 38619
+#define SPELL_WHIRLWIND_2 38618
+
+//not used
+//Yell
+#define SAY_AGGRO -1576021
+#define SAY_KILL -1576022
+#define SAY_DEATH -1576023
+
+struct boss_commander_stoutbeardAI : public ScriptedAI
+{
+ boss_commander_stoutbeardAI(Creature *c) : ScriptedAI(c) {}
+
+ void Reset() {}
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ }
+ void AttackStart(Unit* /*who*/) {}
+ void MoveInLineOfSight(Unit* /*who*/) {}
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ }
+};
+
+CreatureAI* GetAI_boss_commander_stoutbeard(Creature* pCreature)
+{
+ return new boss_commander_stoutbeardAI (pCreature);
+}
+
+void AddSC_boss_commander_stoutbeard()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_commander_stoutbeard";
+ newscript->GetAI = &GetAI_boss_commander_stoutbeard;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/nexus/instance_nexus.cpp b/src/server/scripts/northrend/nexus/nexus/instance_nexus.cpp
new file mode 100644
index 00000000000..db70245e3a4
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/nexus/instance_nexus.cpp
@@ -0,0 +1,259 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "nexus.h"
+
+#define NUMBER_OF_ENCOUNTERS 4
+
+enum Factions
+{
+ FACTION_HOSTILE_FOR_ALL = 16
+};
+
+struct instance_nexus : public ScriptedInstance
+{
+ instance_nexus(Map *pMap) : ScriptedInstance(pMap) { Initialize(); }
+
+ uint32 m_auiEncounter[NUMBER_OF_ENCOUNTERS];
+
+ uint64 Anomalus;
+ uint64 Keristrasza;
+
+ uint64 AnomalusContainmentSphere;
+ uint64 OrmoroksContainmentSphere;
+ uint64 TelestrasContainmentSphere;
+
+ std::string strInstData;
+
+ void Initialize()
+ {
+ memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+
+ Anomalus = 0;
+ Keristrasza = 0;
+ }
+
+ void OnCreatureCreate(Creature *pCreature, bool /*bAdd*/)
+ {
+ Map::PlayerList const &players = instance->GetPlayers();
+ uint32 TeamInInstance = 0;
+
+ if (!players.isEmpty())
+ {
+ if (Player* pPlayer = players.begin()->getSource())
+ TeamInInstance = pPlayer->GetTeam();
+ }
+ switch (pCreature->GetEntry())
+ {
+ case 26763:
+ Anomalus = pCreature->GetGUID();
+ break;
+ case 26723:
+ Keristrasza = pCreature->GetGUID();
+ break;
+ // Alliance npcs are spawned by default, if you are alliance, you will fight against horde npcs.
+ case 26800:
+ {
+ if (ServerAllowsTwoSideGroups())
+ pCreature->setFaction(FACTION_HOSTILE_FOR_ALL);
+ if (TeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(26799, HORDE);
+ break;
+ }
+ case 26802:
+ {
+ if (ServerAllowsTwoSideGroups())
+ pCreature->setFaction(FACTION_HOSTILE_FOR_ALL);
+ if (TeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(26801, HORDE);
+ break;
+ }
+ case 26805:
+ {
+ if (ServerAllowsTwoSideGroups())
+ pCreature->setFaction(FACTION_HOSTILE_FOR_ALL);
+ if (TeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(26803, HORDE);
+ break;
+ }
+ case 27949:
+ {
+ if (ServerAllowsTwoSideGroups())
+ pCreature->setFaction(FACTION_HOSTILE_FOR_ALL);
+ if (TeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(27947, HORDE);
+ break;
+ }
+ case 26796:
+ {
+ if (ServerAllowsTwoSideGroups())
+ pCreature->setFaction(FACTION_HOSTILE_FOR_ALL);
+ if (TeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(26798, HORDE);
+ break;
+ }
+ }
+ }
+
+ void OnGameObjectCreate(GameObject *pGo, bool /*bAdd*/)
+ {
+ switch (pGo->GetEntry())
+ {
+ case 188527:
+ {
+ AnomalusContainmentSphere = pGo->GetGUID();
+ if (m_auiEncounter[1] == DONE)
+ pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ break;
+ }
+ case 188528:
+ {
+ OrmoroksContainmentSphere = pGo->GetGUID();
+ if (m_auiEncounter[2] == DONE)
+ pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ break;
+ }
+ case 188526:
+ {
+ TelestrasContainmentSphere = pGo->GetGUID();
+ if (m_auiEncounter[0] == DONE)
+ pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ break;
+ }
+ }
+ }
+
+ uint32 GetData(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_MAGUS_TELESTRA_EVENT: return m_auiEncounter[0];
+ case DATA_ANOMALUS_EVENT: return m_auiEncounter[1];
+ case DATA_ORMOROK_EVENT: return m_auiEncounter[2];
+ case DATA_KERISTRASZA_EVENT: return m_auiEncounter[3];
+ }
+ return 0;
+ }
+
+ void SetData(uint32 identifier, uint32 data)
+ {
+ switch (identifier)
+ {
+ case DATA_MAGUS_TELESTRA_EVENT:
+ {
+ if (data == DONE)
+ {
+ GameObject *Sphere = instance->GetGameObject(TelestrasContainmentSphere);
+ if (Sphere)
+ Sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ }
+ m_auiEncounter[0] = data;
+ break;
+ }
+ case DATA_ANOMALUS_EVENT:
+ {
+ if (data == DONE)
+ {
+ if (GameObject *Sphere = instance->GetGameObject(AnomalusContainmentSphere))
+ Sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ }
+ m_auiEncounter[1] = data;
+ break;
+ }
+ case DATA_ORMOROK_EVENT:
+ {
+ if (data == DONE)
+ {
+ if (GameObject *Sphere = instance->GetGameObject(OrmoroksContainmentSphere))
+ Sphere->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ }
+ m_auiEncounter[2] = data;
+ break;
+ }
+ case DATA_KERISTRASZA_EVENT:
+ m_auiEncounter[3] = data;
+ break;
+ }
+
+ if (data == DONE)
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
+ << m_auiEncounter[3];
+
+ strInstData = saveStream.str();
+
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
+ }
+
+ uint64 GetData64(uint32 uiIdentifier)
+ {
+ switch(uiIdentifier)
+ {
+ case DATA_ANOMALUS: return Anomalus;
+ case DATA_KERISTRASZA: return Keristrasza;
+ case ANOMALUS_CONTAINMET_SPHERE: return AnomalusContainmentSphere;
+ case ORMOROKS_CONTAINMET_SPHERE: return OrmoroksContainmentSphere;
+ case TELESTRAS_CONTAINMET_SPHERE: return TelestrasContainmentSphere;
+ }
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ return strInstData;
+ }
+
+ void Load(const char *chrIn)
+ {
+ if (!chrIn)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(chrIn);
+
+ std::istringstream loadStream(chrIn);
+ loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3];
+
+ for (uint8 i = 0; i < NUMBER_OF_ENCOUNTERS; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData *GetInstanceData_instance_nexus(Map *pMap)
+{
+ return new instance_nexus(pMap);
+}
+
+void AddSC_instance_nexus()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_nexus";
+ newscript->GetInstanceData = &GetInstanceData_instance_nexus;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/nexus/nexus.h b/src/server/scripts/northrend/nexus/nexus/nexus.h
new file mode 100644
index 00000000000..66902bece30
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/nexus/nexus.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DEF_NEXUS_H
+#define DEF_NEXUS_H
+
+enum eTypes
+{
+ DATA_MAGUS_TELESTRA_EVENT,
+ DATA_ANOMALUS_EVENT,
+ DATA_ORMOROK_EVENT,
+ DATA_KERISTRASZA_EVENT,
+
+ DATA_ANOMALUS,
+ DATA_KERISTRASZA,
+
+ ANOMALUS_CONTAINMET_SPHERE,
+ ORMOROKS_CONTAINMET_SPHERE,
+ TELESTRAS_CONTAINMET_SPHERE
+};
+
+#endif
diff --git a/src/server/scripts/northrend/nexus/oculus/boss_drakos.cpp b/src/server/scripts/northrend/nexus/oculus/boss_drakos.cpp
new file mode 100644
index 00000000000..7d276206339
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/oculus/boss_drakos.cpp
@@ -0,0 +1,218 @@
+/* Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org>
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "oculus.h"
+
+enum Spells
+{
+ SPELL_MAGIC_PULL = 51336,
+ SPELL_MAGIC_PULL_EFFECT = 50770,
+ SPELL_THUNDERING_STOMP = 50774,
+ SPELL_THUNDERING_STOMP_H = 59370,
+ SPELL_UNSTABLE_SPHERE_PASSIVE = 50756,
+ SPELL_UNSTABLE_SPHERE_PULSE = 50757,
+ SPELL_UNSTABLE_SPHERE_TIMER = 50758,
+ NPC_UNSTABLE_SPHERE = 28166,
+};
+
+//not in db
+enum Yells
+{
+ SAY_AGGRO = -1578000,
+ SAY_KILL_1 = -1578001,
+ SAY_KILL_2 = -1578002,
+ SAY_KILL_3 = -1578003,
+ SAY_DEATH = -1578004,
+ SAY_PULL_1 = -1578005,
+ SAY_PULL_2 = -1578006,
+ SAY_PULL_3 = -1578007,
+ SAY_PULL_4 = -1578008,
+ SAY_STOMP_1 = -1578009,
+ SAY_STOMP_2 = -1578010,
+ SAY_STOMP_3 = -1578011
+};
+
+enum
+{
+ ACHIEV_TIMED_START_EVENT = 18153,
+};
+
+struct boss_drakosAI : public ScriptedAI
+{
+ boss_drakosAI(Creature* pCreature) : ScriptedAI(pCreature), lSummons(me)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ uint32 uiMagicPullTimer;
+ uint32 uiStompTimer;
+ uint32 uiBombSummonTimer;
+
+ bool bPostPull;
+
+ ScriptedInstance* pInstance;
+ SummonList lSummons;
+
+ void Reset()
+ {
+ lSummons.DespawnAll();
+ uiMagicPullTimer = 15000;
+ uiStompTimer = 17000;
+ uiBombSummonTimer = 2000;
+
+ bPostPull = false;
+
+ if (pInstance)
+ pInstance->SetData(DATA_DRAKOS_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_DRAKOS_EVENT, IN_PROGRESS);
+ }
+
+ void JustSummoned(Creature* pSummon)
+ {
+ lSummons.Summon(pSummon);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiBombSummonTimer <= uiDiff)
+ {
+ Position pPosition;
+ me->GetPosition(&pPosition);
+
+ if (bPostPull)
+ {
+ for (uint8 uiI = 0; uiI >= 3; uiI++)
+ {
+ me->GetRandomNearPosition(pPosition, float(urand(0,10)));
+ me->SummonCreature(NPC_UNSTABLE_SPHERE, pPosition);
+ }
+ }
+ else
+ {
+ me->GetRandomNearPosition(pPosition, float(urand(0,10)));
+ me->SummonCreature(NPC_UNSTABLE_SPHERE, pPosition);
+ }
+
+ uiBombSummonTimer = 2000;
+ } else uiBombSummonTimer -= uiDiff;
+
+ if (uiMagicPullTimer <= uiDiff)
+ {
+ DoCast(SPELL_MAGIC_PULL);
+
+ bPostPull = true;
+
+ uiMagicPullTimer = 15000;
+ } else uiMagicPullTimer -= uiDiff;
+
+ if (uiStompTimer <= uiDiff)
+ {
+ DoScriptText(RAND(SAY_STOMP_1,SAY_STOMP_2,SAY_STOMP_3), me);
+ DoCast(SPELL_THUNDERING_STOMP);
+ uiStompTimer = 17000;
+ } else uiStompTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_DRAKOS_EVENT, DONE);
+ // start achievement timer (kill Eregos within 20 min)
+ pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ }
+
+ lSummons.DespawnAll();
+ }
+ void KilledUnit(Unit* /*victim*/)
+ {
+ DoScriptText(RAND(SAY_KILL_1,SAY_KILL_2,SAY_KILL_3), me);
+ }
+};
+
+CreatureAI* GetAI_boss_drakos(Creature* pCreature)
+{
+ return new boss_drakosAI (pCreature);
+}
+
+struct npc_unstable_sphereAI : public ScriptedAI
+{
+ npc_unstable_sphereAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint32 uiPulseTimer;
+ uint32 uiDeathTimer;
+
+ void Reset()
+ {
+ me->SetReactState(REACT_PASSIVE);
+ me->GetMotionMaster()->MoveRandom(40.0f);
+
+ me->AddAura(SPELL_UNSTABLE_SPHERE_PASSIVE, me);
+ me->AddAura(SPELL_UNSTABLE_SPHERE_TIMER, me);
+
+ uiPulseTimer = 3000;
+ uiDeathTimer = 19000;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (uiPulseTimer <= uiDiff)
+ {
+ DoCast(SPELL_UNSTABLE_SPHERE_PULSE);
+ uiPulseTimer = 3*IN_MILISECONDS;
+ } else uiPulseTimer -= uiDiff;
+
+ if (uiDeathTimer <= uiDiff)
+ me->DisappearAndDie();
+ else uiDeathTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_npc_unstable_sphere(Creature* pCreature)
+{
+ return new npc_unstable_sphereAI (pCreature);
+}
+
+void AddSC_boss_drakos()
+{
+ Script* newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_drakos";
+ newscript->GetAI = &GetAI_boss_drakos;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_unstable_sphere";
+ newscript->GetAI = &GetAI_npc_unstable_sphere;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/oculus/boss_eregos.cpp b/src/server/scripts/northrend/nexus/oculus/boss_eregos.cpp
new file mode 100644
index 00000000000..94fb90ab206
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/oculus/boss_eregos.cpp
@@ -0,0 +1,129 @@
+/* Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org>
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "oculus.h"
+
+//Types of drake mounts: Ruby(Tank), Amber(DPS), Emerald(Healer)
+//Two Repeating phases
+
+enum Spells
+{
+ SPELL_ARCANE_BARRAGE = 50804,
+ H_SPELL_ARCANE_BARRAGE = 59381,
+ SPELL_ARCANE_VOLLEY = 51153,
+ H_SPELL_ARCANE_VOLLEY = 59382,
+ SPELL_ENRAGED_ASSAULT = 51170,
+ SPELL_PLANAR_ANOMALIES = 57959,
+ SPELL_PLANAR_SHIFT = 51162,
+};
+/*Ruby Drake ,
+(npc 27756) (item 37860)
+(summoned by spell Ruby Essence = 37860 ---> Call Amber Drake == 49462 ---> Summon 27756)
+*/
+enum RubyDrake
+{
+ NPC_RUBY_DRAKE_VEHICLE = 27756,
+ SPELL_RIDE_RUBY_DRAKE_QUE = 49463, //Apply Aura: Periodic Trigger, Interval: 3 seconds ---> 49464
+ SPELL_RUBY_DRAKE_SADDLE = 49464, //Allows you to ride on the back of an Amber Drake. ---> Dummy
+ SPELL_RUBY_SEARING_WRATH = 50232, //(60 yds) - Instant - Breathes a stream of fire at an enemy dragon, dealing 6800 to 9200 Fire damage and then jumping to additional dragons within 30 yards. Each jump increases the damage by 50%. Affects up to 5 total targets
+ SPELL_RUBY_EVASIVE_AURA = 50248, //Instant - Allows the Ruby Drake to generate Evasive Charges when hit by hostile attacks and spells.
+ SPELL_RUBY_EVASIVE_MANEUVERS = 50240, //Instant - 5 sec. cooldown - Allows your drake to dodge all incoming attacks and spells. Requires Evasive Charges to use. Each attack or spell dodged while this ability is active burns one Evasive Charge. Lasts 30 sec. or until all charges are exhausted.
+ //you do not have acces to until you kill Mage-Lord Urom
+ SPELL_RUBY_MARTYR = 50253 //Instant - 10 sec. cooldown - Redirect all harmful spells cast at friendly drakes to yourself for 10 sec.
+};
+/*Amber Drake,
+(npc 27755) (item 37859)
+(summoned by spell Amber Essence = 37859 ---> Call Amber Drake == 49461 ---> Summon 27755)
+*/
+enum AmberDrake
+{
+ NPC_AMBER_DRAKE_VEHICLE = 27755,
+ SPELL_RIDE_AMBER_DRAKE_QUE = 49459, //Apply Aura: Periodic Trigger, Interval: 3 seconds ---> 49460
+ SPELL_AMBER_DRAKE_SADDLE = 49460, //Allows you to ride on the back of an Amber Drake. ---> Dummy
+ SPELL_AMBER_SHOCK_LANCE = 49840, //(60 yds) - Instant - Deals 4822 to 5602 Arcane damage and detonates all Shock Charges on an enemy dragon. Damage is increased by 6525 for each detonated.
+// SPELL_AMBER_STOP_TIME //Instant - 1 min cooldown - Halts the passage of time, freezing all enemy dragons in place for 10 sec. This attack applies 5 Shock Charges to each affected target.
+ //you do not have access to until you kill the Mage-Lord Urom.
+ SPELL_AMBER_TEMPORAL_RIFT = 49592 //(60 yds) - Channeled - Channels a temporal rift on an enemy dragon for 10 sec. While trapped in the rift, all damage done to the target is increased by 100%. In addition, for every 15,000 damage done to a target affected by Temporal Rift, 1 Shock Charge is generated.
+};
+/*Emerald Drake,
+(npc 27692) (item 37815),
+ (summoned by spell Emerald Essence = 37815 ---> Call Emerald Drake == 49345 ---> Summon 27692)
+*/
+enum EmeraldDrake
+{
+ NPC_EMERALD_DRAKE_VEHICLE = 27692,
+ SPELL_RIDE_EMERALD_DRAKE_QUE = 49427, //Apply Aura: Periodic Trigger, Interval: 3 seconds ---> 49346
+ SPELL_EMERALD_DRAKE_SADDLE = 49346, //Allows you to ride on the back of an Amber Drake. ---> Dummy
+ SPELL_EMERALD_LEECHING_POISON = 50328, //(60 yds) - Instant - Poisons the enemy dragon, leeching 1300 to the caster every 2 sec. for 12 sec. Stacks up to 3 times.
+ SPELL_EMERALD_TOUCH_THE_NIGHTMARE = 50341, //(60 yds) - Instant - Consumes 30% of the caster's max health to inflict 25,000 nature damage to an enemy dragon and reduce the damage it deals by 25% for 30 sec.
+ // you do not have access to until you kill the Mage-Lord Urom
+ SPELL_EMERALD_DREAM_FUNNEL = 50344 //(60 yds) - Channeled - Transfers 5% of the caster's max health to a friendly drake every second for 10 seconds as long as the caster channels.
+};
+
+struct boss_eregosAI : public ScriptedAI
+{
+ boss_eregosAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_EREGOS_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_EREGOS_EVENT, IN_PROGRESS);
+ }
+
+ void AttackStart(Unit* /*who*/) {}
+ void MoveInLineOfSight(Unit* /*who*/) {}
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_EREGOS_EVENT, DONE);
+ }
+};
+
+CreatureAI* GetAI_boss_eregos(Creature* pCreature)
+{
+ return new boss_eregosAI (pCreature);
+}
+
+void AddSC_boss_eregos()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_eregos";
+ newscript->GetAI = &GetAI_boss_eregos;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/oculus/boss_urom.cpp b/src/server/scripts/northrend/nexus/oculus/boss_urom.cpp
new file mode 100644
index 00000000000..29435441d00
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/oculus/boss_urom.cpp
@@ -0,0 +1,356 @@
+/* Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org>
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* ScriptData
+SDName: Urom
+SD%Complete: 80
+SDComment: Is not working SPELL_ARCANE_SHIELD. SPELL_FROSTBOMB has some issues, the damage aura should not stack.
+SDCategory: Instance Script
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "oculus.h"
+
+enum Spells
+{
+
+ SPELL_ARCANE_SHIELD = 53813, //Dummy --> Channeled, shields the caster from damage.
+ SPELL_EMPOWERED_ARCANE_EXPLOSION = 51110,
+ SPELL_EMPOWERED_ARCANE_EXPLOSION_2 = 59377,
+ SPELL_FROSTBOMB = 51103, //Urom throws a bomb, hitting its target with the highest aggro which inflict directly 650 frost damage and drops a frost zone on the ground. This zone deals 650 frost damage per second and reduce the movement speed by 35%. Lasts 1 minute.
+ SPELL_SUMMON_MENAGERIE = 50476, //Summons an assortment of creatures and teleports the caster to safety.
+ SPELL_SUMMON_MENAGERIE_2 = 50495,
+ SPELL_SUMMON_MENAGERIE_3 = 50496,
+ SPELL_TELEPORT = 51112, //Teleports to the center of Oculus
+ SPELL_TIME_BOMB = 51121, //Deals arcane damage to a random player, and after 6 seconds, deals zone damage to nearby equal to the health missing of the target afflicted by the debuff.
+ SPELL_TIME_BOMB_2 = 59376
+};
+
+enum Yells
+{
+ SAY_AGGRO_1 = -1578000,
+ SAY_AGGRO_2 = -1578001,
+ SAY_AGGRO_3 = -1578002,
+ SAY_AGGRO_4 = -1578003,
+ SAY_TELEPORT = -1578004,
+};
+
+enum eCreature
+{
+ NPC_PHANTASMAL_CLOUDSCRAPER = 27645,
+ NPC_PHANTASMAL_MAMMOTH = 27642,
+ NPC_PHANTASMAL_WOLF = 27644,
+
+ NPC_PHANTASMAL_AIR = 27650,
+ NPC_PHANTASMAL_FIRE = 27651,
+ NPC_PHANTASMAL_WATER = 27653,
+
+ NPC_PHANTASMAL_MURLOC = 27649,
+ NPC_PHANTASMAL_NAGAL = 27648,
+ NPC_PHANTASMAL_OGRE = 27647
+};
+
+struct Summons
+{
+ uint32 uiEntry[4];
+};
+
+static Summons Group[]=
+{
+ {NPC_PHANTASMAL_CLOUDSCRAPER,NPC_PHANTASMAL_CLOUDSCRAPER,NPC_PHANTASMAL_MAMMOTH,NPC_PHANTASMAL_WOLF},
+ {NPC_PHANTASMAL_AIR,NPC_PHANTASMAL_AIR,NPC_PHANTASMAL_WATER,NPC_PHANTASMAL_FIRE},
+ {NPC_PHANTASMAL_OGRE,NPC_PHANTASMAL_OGRE,NPC_PHANTASMAL_NAGAL,NPC_PHANTASMAL_MURLOC}
+};
+
+static uint32 TeleportSpells[]=
+{
+ SPELL_SUMMON_MENAGERIE,SPELL_SUMMON_MENAGERIE_2,SPELL_SUMMON_MENAGERIE_3
+};
+
+static int32 SayAggro[]=
+{
+ SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3,SAY_AGGRO_4
+};
+
+struct boss_uromAI : public ScriptedAI
+{
+ boss_uromAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ float x,y;
+
+ bool bCanCast;
+ bool bCanGoBack;
+
+ uint8 uiGroup[3];
+
+ uint32 uiTeleportTimer;
+ uint32 uiArcaneExplosionTimer;
+ uint32 uiCastArcaneExplosionTimer;
+ uint32 uiFrostBombTimer;
+ uint32 uiTimeBombTimer;
+
+ void Reset()
+ {
+ if (pInstance && pInstance->GetData(DATA_VAROS_EVENT) != DONE)
+ DoCast(SPELL_ARCANE_SHIELD);
+
+ if (pInstance)
+ pInstance->SetData(DATA_UROM_EVENT, NOT_STARTED);
+
+ if (pInstance && pInstance->GetData(DATA_UROM_PLATAFORM) == 0)
+ {
+ uiGroup[0] = 0;
+ uiGroup[1] = 0;
+ uiGroup[2] = 0;
+ }
+
+ x,y = 0.0f;
+ bCanCast = false;
+ bCanGoBack = false;
+
+ me->GetMotionMaster()->MoveIdle();
+
+ uiTeleportTimer = urand(30000,35000);
+ uiArcaneExplosionTimer = 9000;
+ uiCastArcaneExplosionTimer = 2000;
+ uiFrostBombTimer = urand(5000,8000);
+ uiTimeBombTimer = urand(20000,25000);
+ }
+
+ void EnterCombat(Unit* pWho)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_UROM_EVENT, IN_PROGRESS);
+
+ SetGroups();
+ SummonGroups();
+ CastTeleport();
+
+ if (pInstance && pInstance->GetData(DATA_UROM_PLATAFORM) != 3)
+ pInstance->SetData(DATA_UROM_PLATAFORM,pInstance->GetData(DATA_UROM_PLATAFORM)+1);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (me->GetPositionZ() > 518.63)
+ DoStartNoMovement(pWho);
+
+ if (me->GetPositionZ() < 518.63)
+ {
+ if (me->Attack(pWho, true))
+ {
+ DoScriptText(SayAggro[3],me);
+
+ me->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(me);
+
+ me->GetMotionMaster()->MoveChase(pWho, 0,0);
+ }
+ }
+ }
+
+ void SetGroups()
+ {
+ if (!pInstance || pInstance->GetData(DATA_UROM_PLATAFORM) != 0)
+ return;
+
+ while (uiGroup[0] == uiGroup[1] || uiGroup[0] == uiGroup[2] || uiGroup[1] == uiGroup[2])
+ {
+ uiGroup[0] = urand(0,2);
+ uiGroup[1] = urand(0,2);
+ uiGroup[2] = urand(0,2);
+ }
+ }
+
+ void SetPosition(uint8 uiI)
+ {
+ switch(uiI)
+ {
+ case 0:
+ x = me->GetPositionX() + 4;
+ y = me->GetPositionY() - 4;
+ break;
+ case 1:
+ x = me->GetPositionX() + 4;
+ y = me->GetPositionY() + 4;
+ break;
+ case 2:
+ x = me->GetPositionX() - 4;
+ y = me->GetPositionY() + 4;
+ break;
+ case 3:
+ x = me->GetPositionX() - 4;
+ y = me->GetPositionY() - 4;
+ break;
+ default:
+ break;
+ }
+ }
+
+ void SummonGroups()
+ {
+ if (!pInstance || pInstance->GetData(DATA_UROM_PLATAFORM) > 2)
+ return;
+
+ for (uint8 uiI = 0; uiI < 4 ; uiI++)
+ {
+ SetPosition(uiI);
+ me->SummonCreature(Group[uiGroup[pInstance->GetData(DATA_UROM_PLATAFORM)]].uiEntry[uiI],x,y,me->GetPositionZ(),me->GetOrientation());
+ }
+ }
+
+ void CastTeleport()
+ {
+ if (!pInstance || pInstance->GetData(DATA_UROM_PLATAFORM) > 2)
+ return;
+
+ DoScriptText(SayAggro[pInstance->GetData(DATA_UROM_PLATAFORM)],me);
+ DoCast(TeleportSpells[pInstance->GetData(DATA_UROM_PLATAFORM)]);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (!pInstance || pInstance->GetData(DATA_UROM_PLATAFORM) < 2)
+ return;
+
+ if (uiTeleportTimer <= uiDiff)
+ {
+ me->InterruptNonMeleeSpells(false);
+ DoScriptText(SAY_TELEPORT,me);
+ me->GetMotionMaster()->MoveIdle();
+ DoCast(SPELL_TELEPORT);
+ uiTeleportTimer = urand(30000,35000);
+
+ } else uiTeleportTimer -= uiDiff;
+
+ if (bCanCast && !me->FindCurrentSpellBySpellId(SPELL_EMPOWERED_ARCANE_EXPLOSION))
+ {
+ if (uiCastArcaneExplosionTimer <= uiDiff)
+ {
+ bCanCast = false;
+ bCanGoBack = true;
+ DoCastAOE(SPELL_EMPOWERED_ARCANE_EXPLOSION);
+ uiCastArcaneExplosionTimer = 2000;
+ }else uiCastArcaneExplosionTimer -= uiDiff;
+ }
+
+ if (bCanGoBack)
+ {
+ if (uiArcaneExplosionTimer <= uiDiff)
+ {
+ Position pPos;
+ me->getVictim()->GetPosition(&pPos);
+
+ me->NearTeleportTo(pPos.GetPositionX(),pPos.GetPositionY(),pPos.GetPositionZ(),pPos.GetOrientation());
+ me->GetMotionMaster()->MoveChase(me->getVictim(),0,0);
+ me->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
+
+ bCanCast = false;
+ bCanGoBack = false;
+ uiArcaneExplosionTimer = 9000;
+ } else uiArcaneExplosionTimer -= uiDiff;
+ }
+
+ if (!me->IsNonMeleeSpellCasted(false, true, true))
+ {
+ if (uiFrostBombTimer <= uiDiff)
+ {
+ DoCastVictim(SPELL_FROSTBOMB);
+ uiFrostBombTimer = urand(5000,8000);
+ } else uiFrostBombTimer -= uiDiff;
+
+ if (uiTimeBombTimer <= uiDiff)
+ {
+ if (Unit* pUnit = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pUnit,SPELL_TIME_BOMB);
+
+ uiTimeBombTimer = urand(20000,25000);
+ } else uiTimeBombTimer -= uiDiff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_UROM_EVENT, DONE);
+ }
+
+ void JustSummoned(Creature* pSummon)
+ {
+ pSummon->SetInCombatWithZone();
+ }
+
+ void LeaveCombat()
+ {
+ me->RemoveAllAuras();
+ me->CombatStop(false);
+ me->DeleteThreatList();
+ }
+
+ void SpellHit(Unit* pCaster, const SpellEntry* pSpell)
+ {
+ switch(pSpell->Id)
+ {
+ case SPELL_SUMMON_MENAGERIE:
+ me->SetHomePosition(968.66,1042.53,527.32,0.077);
+ LeaveCombat();
+ break;
+ case SPELL_SUMMON_MENAGERIE_2:
+ me->SetHomePosition(1164.02,1170.85,527.321,3.66);
+ LeaveCombat();
+ break;
+ case SPELL_SUMMON_MENAGERIE_3:
+ me->SetHomePosition(1118.31,1080.377,508.361,4.25);
+ LeaveCombat();
+ break;
+ case SPELL_TELEPORT:
+ me->AddUnitMovementFlag(MOVEMENTFLAG_FLY_MODE); // with out it the npc will fall down while is casting
+ bCanCast = true;
+ break;
+ default:
+ break;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_urom(Creature* pCreature)
+{
+ return new boss_uromAI (pCreature);
+}
+
+void AddSC_boss_urom()
+{
+ Script* newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_urom";
+ newscript->GetAI = &GetAI_boss_urom;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/oculus/boss_varos.cpp b/src/server/scripts/northrend/nexus/oculus/boss_varos.cpp
new file mode 100644
index 00000000000..79034250a43
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/oculus/boss_varos.cpp
@@ -0,0 +1,105 @@
+/* Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org>
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "oculus.h"
+
+enum Spells
+{
+ SPELL_ENERGIZE_CORES = 50785, //Damage 5938 to 6562, effec2 Triggers 54069, effect3 Triggers 56251
+ SPELL_ENERGIZE_CORES_TRIGGER_1 = 54069,
+ SPELL_ENERGIZE_CORES_TRIGGER_2 = 56251,
+ SPELL_ENERGIZE_CORES_2 = 59372, //Damage 9025 to 9975, effect2 Triggers 54069, effect 56251
+ SPELL_CALL_AZURE_RING_CAPTAIN = 51002, //Effect Send Event (12229)
+ SPELL_CALL_AZURE_RING_CAPTAIN_2 = 51006, //Effect Send Event (10665)
+ SPELL_CALL_AZURE_RING_CAPTAIN_3 = 51007, //Effect Send Event (18454)
+ SPELL_CALL_AZURE_RING_CAPTAIN_4 = 51008, //Effect Send Event (18455)
+ SPELL_CALL_AMPLIFY_MAGIC = 51054,
+ SPELL_CALL_AMPLIFY_MAGIC_2 = 59371
+};
+//not in db
+enum Yells
+{
+ SAY_AGGRO = -1578022,
+ SAY_KILL_1 = -1578023,
+ SAY_KILL_2 = -1578024,
+ SAY_DEATH = -1578025,
+ SAY_STRIKE_1 = -1578026,
+ SAY_STRIKE_2 = -1578027,
+ SAY_STRIKE_3 = -1578028,
+ SAY_SPAWN = -1578029
+};
+
+struct boss_varosAI : public ScriptedAI
+{
+ boss_varosAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_VAROS_EVENT, NOT_STARTED);
+ }
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_VAROS_EVENT, IN_PROGRESS);
+ }
+ void AttackStart(Unit* /*who*/) {}
+ void MoveInLineOfSight(Unit* /*who*/) {}
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_VAROS_EVENT, DONE);
+ }
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+ DoScriptText(RAND(SAY_KILL_1,SAY_KILL_2), me);
+ }
+};
+
+CreatureAI* GetAI_boss_varos(Creature* pCreature)
+{
+ return new boss_varosAI (pCreature);
+}
+
+void AddSC_boss_varos()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_varos";
+ newscript->GetAI = &GetAI_boss_varos;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/oculus/instance_oculus.cpp b/src/server/scripts/northrend/nexus/oculus/instance_oculus.cpp
new file mode 100644
index 00000000000..49be2385a3c
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/oculus/instance_oculus.cpp
@@ -0,0 +1,205 @@
+/* Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org>
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "oculus.h"
+
+#define MAX_ENCOUNTER 4
+
+/* The Occulus encounters:
+0 - Drakos the Interrogator
+1 - Varos Cloudstrider
+2 - Mage-Lord Urom
+3 - Ley-Guardian Eregos */
+
+struct instance_oculus : public ScriptedInstance
+{
+ instance_oculus(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+
+ uint64 uiDrakos;
+ uint64 uiVaros;
+ uint64 uiUrom;
+ uint64 uiEregos;
+
+ uint8 uiPlataformUrom;
+
+ uint8 m_auiEncounter[MAX_ENCOUNTER];
+ std::string str_data;
+
+ std::list<uint64> GameObjectList;
+
+ void Initialize()
+ {
+ uiPlataformUrom = 0;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool /*add*/)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case CREATURE_DRAKOS:
+ uiDrakos = pCreature->GetGUID();
+ break;
+ case CREATURE_VAROS:
+ uiVaros = pCreature->GetGUID();
+ break;
+ case CREATURE_UROM:
+ uiUrom = pCreature->GetGUID();
+ break;
+ case CREATURE_EREGOS:
+ uiEregos = pCreature->GetGUID();
+ break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* pGO, bool bAdd)
+ {
+ if (pGO->GetEntry() == GO_DRAGON_CAGE_DOOR)
+ {
+ if (DATA_DRAKOS_EVENT == DONE)
+ pGO->SetGoState(GO_STATE_ACTIVE);
+ else
+ pGO->SetGoState(GO_STATE_READY);
+
+ GameObjectList.push_back(pGO->GetGUID());
+ }
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_DRAKOS_EVENT:
+ m_auiEncounter[0] = data;
+ if (data == DONE)
+ OpenCageDoors();
+ break;
+ case DATA_VAROS_EVENT:
+ m_auiEncounter[1] = data;
+ break;
+ case DATA_UROM_EVENT:
+ m_auiEncounter[2] = data;
+ break;
+ case DATA_EREGOS_EVENT:
+ m_auiEncounter[3] = data;
+ break;
+ case DATA_UROM_PLATAFORM:
+ uiPlataformUrom = data;
+ break;
+ }
+
+ if (data == DONE)
+ SaveToDB();
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_DRAKOS_EVENT: return m_auiEncounter[0];
+ case DATA_VAROS_EVENT: return m_auiEncounter[1];
+ case DATA_UROM_EVENT: return m_auiEncounter[2];
+ case DATA_EREGOS_EVENT: return m_auiEncounter[3];
+ case DATA_UROM_PLATAFORM: return uiPlataformUrom;
+ }
+
+ return 0;
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_DRAKOS: return uiDrakos;
+ case DATA_VAROS: return uiVaros;
+ case DATA_UROM: return uiUrom;
+ case DATA_EREGOS: return uiEregos;
+ }
+
+ return 0;
+ }
+
+ void OpenCageDoors()
+ {
+ if (GameObjectList.empty())
+ return;
+
+ for (std::list<uint64>::const_iterator itr = GameObjectList.begin(); itr != GameObjectList.end(); ++itr)
+ {
+ if (GameObject* pGO = instance->GetGameObject(*itr))
+ pGO->SetGoState(GO_STATE_ACTIVE);
+ }
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "T O " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3];
+
+ str_data = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return str_data;
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0, data1, data2, data3;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;
+
+ if (dataHead1 == 'T' && dataHead2 == 'O')
+ {
+ m_auiEncounter[0] = data0;
+ m_auiEncounter[1] = data1;
+ m_auiEncounter[2] = data2;
+ m_auiEncounter[3] = data3;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_oculus(Map* pMap)
+{
+ return new instance_oculus(pMap);
+}
+
+void AddSC_instance_oculus()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_oculus";
+ newscript->GetInstanceData = &GetInstanceData_instance_oculus;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/oculus/oculus.cpp b/src/server/scripts/northrend/nexus/oculus/oculus.cpp
new file mode 100644
index 00000000000..685583532d5
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/oculus/oculus.cpp
@@ -0,0 +1,174 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <http://www.trinitycore.org>
+* 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 2 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "ScriptedPch.h"
+#include "oculus.h"
+
+#define GOSSIP_ITEM_DRAKES "So where do we go from here?"
+#define GOSSIP_ITEM_BELGARISTRASZ1 "I want to fly on the wings of the Red Flight"
+#define GOSSIP_ITEM_BELGARISTRASZ2 "What abilities do Ruby Drakes have?"
+#define GOSSIP_ITEM_VERDISA1 "I want to fly on the wings of the Green Flight"
+#define GOSSIP_ITEM_VERDISA2 "What abilities do Emerald Drakes have?"
+#define GOSSIP_ITEM_ETERNOS1 "I want to fly on the wings of the Bronze Flight"
+#define GOSSIP_ITEM_ETERNOS2 "What abilities do Amber Drakes have?"
+
+#define HAS_ESSENCE(a) ((a)->HasItemCount(ITEM_EMERALD_ESSENCE,1) || (a)->HasItemCount(ITEM_AMBER_ESSENCE,1) || (a)->HasItemCount(ITEM_RUBY_ESSENCE,1))
+
+enum Drakes
+{
+ GOSSIP_TEXTID_DRAKES = 13267,
+ GOSSIP_TEXTID_BELGARISTRASZ1 = 12916,
+ GOSSIP_TEXTID_BELGARISTRASZ2 = 13466,
+ GOSSIP_TEXTID_BELGARISTRASZ3 = 13254,
+ GOSSIP_TEXTID_VERDISA1 = 1,
+ GOSSIP_TEXTID_VERDISA2 = 1,
+ GOSSIP_TEXTID_VERDISA3 = 1,
+ GOSSIP_TEXTID_ETERNOS1 = 1,
+ GOSSIP_TEXTID_ETERNOS2 = 1,
+ GOSSIP_TEXTID_ETERNOS3 = 13256,
+
+ ITEM_EMERALD_ESSENCE = 37815,
+ ITEM_AMBER_ESSENCE = 37859,
+ ITEM_RUBY_ESSENCE = 37860,
+
+ NPC_VERDISA = 27657,
+ NPC_BELGARISTRASZ = 27658,
+ NPC_ETERNOS = 27659
+};
+
+bool GossipHello_npc_oculus_drake(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pCreature->GetInstanceData()->GetData(DATA_DRAKOS_EVENT) == DONE)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_DRAKES, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_DRAKES, pCreature->GetGUID());
+ }
+
+ return true;
+}
+
+bool GossipSelect_npc_oculus_drake(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch(pCreature->GetEntry())
+ {
+ case NPC_VERDISA: //Verdisa
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ if (!HAS_ESSENCE(pPlayer))
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA1, pCreature->GetGUID());
+ }
+ else
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA2, pCreature->GetGUID());
+ }
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ {
+ ItemPosCountVec dest;
+ uint8 msg = pPlayer->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_EMERALD_ESSENCE, 1);
+ if (msg == EQUIP_ERR_OK)
+ pPlayer->StoreNewItem(dest, ITEM_EMERALD_ESSENCE, true);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ }
+ case GOSSIP_ACTION_INFO_DEF + 3:
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA3, pCreature->GetGUID());
+ break;
+ }
+ break;
+ case NPC_BELGARISTRASZ: //Belgaristrasz
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ if (!HAS_ESSENCE(pPlayer))
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ1, pCreature->GetGUID());
+ }
+ else
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ2, pCreature->GetGUID());
+ }
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ {
+ ItemPosCountVec dest;
+ uint8 msg = pPlayer->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_RUBY_ESSENCE, 1);
+ if (msg == EQUIP_ERR_OK)
+ pPlayer->StoreNewItem(dest, ITEM_RUBY_ESSENCE, true);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ }
+ case GOSSIP_ACTION_INFO_DEF + 3:
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ3, pCreature->GetGUID());
+ break;
+ }
+ break;
+ case NPC_ETERNOS: //Eternos
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ if (!HAS_ESSENCE(pPlayer))
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS1, pCreature->GetGUID());
+ }
+ else
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS2, pCreature->GetGUID());
+ }
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ {
+ ItemPosCountVec dest;
+ uint8 msg = pPlayer->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_AMBER_ESSENCE, 1);
+ if (msg == EQUIP_ERR_OK)
+ pPlayer->StoreNewItem(dest, ITEM_AMBER_ESSENCE, true);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ }
+ case GOSSIP_ACTION_INFO_DEF + 3:
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS3, pCreature->GetGUID());
+ break;
+ }
+ break;
+ }
+
+ return true;
+}
+
+void AddSC_oculus()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_oculus_drake";
+ newscript->pGossipHello = &GossipHello_npc_oculus_drake;
+ newscript->pGossipSelect = &GossipSelect_npc_oculus_drake;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/nexus/oculus/oculus.h b/src/server/scripts/northrend/nexus/oculus/oculus.h
new file mode 100644
index 00000000000..b212c9b8b6a
--- /dev/null
+++ b/src/server/scripts/northrend/nexus/oculus/oculus.h
@@ -0,0 +1,34 @@
+#ifndef DEF_OCULUS_H
+#define DEF_OCULUS_H
+
+enum Data
+{
+ DATA_DRAKOS_EVENT,
+ DATA_VAROS_EVENT,
+ DATA_UROM_EVENT,
+ DATA_EREGOS_EVENT,
+ DATA_UROM_PLATAFORM
+};
+
+enum Data64
+{
+ DATA_DRAKOS,
+ DATA_VAROS,
+ DATA_UROM,
+ DATA_EREGOS
+};
+
+enum Bosses
+{
+ CREATURE_DRAKOS = 27654,
+ CREATURE_VAROS = 27447,
+ CREATURE_UROM = 27655,
+ CREATURE_EREGOS = 27656
+};
+
+enum GameObjects
+{
+ GO_DRAGON_CAGE_DOOR = 193995
+};
+
+#endif
diff --git a/src/server/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp b/src/server/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp
new file mode 100644
index 00000000000..3e24aaeb6c0
--- /dev/null
+++ b/src/server/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp
@@ -0,0 +1,1421 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * Copyright (C) 2006 - 2010 TrinityCore <http://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "obsidian_sanctum.h"
+
+enum eEnums
+{
+ //Sartharion Yell
+ SAY_SARTHARION_AGGRO = -1615018,
+ SAY_SARTHARION_BERSERK = -1615019,
+ SAY_SARTHARION_BREATH = -1615020,
+ SAY_SARTHARION_CALL_SHADRON = -1615021,
+ SAY_SARTHARION_CALL_TENEBRON = -1615022,
+ SAY_SARTHARION_CALL_VESPERON = -1615023,
+ SAY_SARTHARION_DEATH = -1615024,
+ SAY_SARTHARION_SPECIAL_1 = -1615025,
+ SAY_SARTHARION_SPECIAL_2 = -1615026,
+ SAY_SARTHARION_SPECIAL_3 = -1615027,
+ SAY_SARTHARION_SPECIAL_4 = -1615028,
+ SAY_SARTHARION_SLAY_1 = -1615029,
+ SAY_SARTHARION_SLAY_2 = -1615030,
+ SAY_SARTHARION_SLAY_3 = -1615031,
+
+ WHISPER_LAVA_CHURN = -1615032,
+
+ WHISPER_SHADRON_DICIPLE = -1615008,
+ WHISPER_VESPERON_DICIPLE = -1615041,
+ WHISPER_HATCH_EGGS = -1615017,
+ WHISPER_OPEN_PORTAL = -1615042, // whisper, shared by two dragons
+
+ //Sartharion Spells
+ SPELL_BERSERK = 61632, // Increases the caster's attack speed by 150% and all damage it deals by 500% for 5 min.
+ SPELL_CLEAVE = 56909, // Inflicts 35% weapon damage to an enemy and its nearest allies, affecting up to 10 targets.
+ SPELL_FLAME_BREATH = 56908, // Inflicts 8750 to 11250 Fire damage to enemies in a cone in front of the caster.
+ SPELL_FLAME_BREATH_H = 58956, // Inflicts 10938 to 14062 Fire damage to enemies in a cone in front of the caster.
+ SPELL_TAIL_LASH = 56910, // A sweeping tail strike hits all enemies behind the caster, inflicting 3063 to 3937 damage and stunning them for 2 sec.
+ SPELL_TAIL_LASH_H = 58957, // A sweeping tail strike hits all enemies behind the caster, inflicting 4375 to 5625 damage and stunning them for 2 sec.
+ SPELL_WILL_OF_SARTHARION = 61254, // Sartharion's presence bolsters the resolve of the Twilight Drakes, increasing their total health by 25%. This effect also increases Sartharion's health by 25%.
+ SPELL_LAVA_STRIKE = 57571, // (Real spell casted should be 57578) 57571 then trigger visual missile, then summon Lava Blaze on impact(spell 57572)
+ SPELL_TWILIGHT_REVENGE = 60639,
+
+ SPELL_PYROBUFFET = 56916, // currently used for hard enrage after 15 minutes
+ SPELL_PYROBUFFET_RANGE = 58907, // possibly used when player get too far away from dummy creatures (2x Creature entry 30494)
+
+ SPELL_TWILIGHT_SHIFT_ENTER = 57620, // enter phase. Player get this when click GO
+ SPELL_TWILIGHT_SHIFT = 57874, // Twilight Shift Aura
+ SPELL_TWILIGHT_SHIFT_REMOVAL = 61187, // leave phase
+ SPELL_TWILIGHT_SHIFT_REMOVAL_ALL = 61190, // leave phase (probably version to make all leave)
+
+ //Mini bosses common spells
+ SPELL_TWILIGHT_RESIDUE = 61885, // makes immune to shadow damage, applied when leave phase
+
+ //Miniboses (Vesperon, Shadron, Tenebron)
+ SPELL_SHADOW_BREATH_H = 59126, // Inflicts 8788 to 10212 Fire damage to enemies in a cone in front of the caster.
+ SPELL_SHADOW_BREATH = 57570, // Inflicts 6938 to 8062 Fire damage to enemies in a cone in front of the caster.
+
+ SPELL_SHADOW_FISSURE_H = 59127, // Deals 9488 to 13512 Shadow damage to any enemy within the Shadow fissure after 5 sec.
+ SPELL_SHADOW_FISSURE = 57579, // Deals 6188 to 8812 Shadow damage to any enemy within the Shadow fissure after 5 sec.
+
+ //Vesperon
+ //In portal is a disciple, when disciple killed remove Power_of_vesperon, portal open multiple times
+ NPC_ACOLYTE_OF_VESPERON = 31219, // Acolyte of Vesperon
+ SPELL_POWER_OF_VESPERON = 61251, // Vesperon's presence decreases the maximum health of all enemies by 25%.
+ SPELL_TWILIGHT_TORMENT_VESP = 57948, // (Shadow only) trigger 57935 then 57988
+ SPELL_TWILIGHT_TORMENT_VESP_ACO = 58853, // (Fire and Shadow) trigger 58835 then 57988
+
+ //Shadron
+ //In portal is a disciple, when disciple killed remove Power_of_vesperon, portal open multiple times
+ NPC_ACOLYTE_OF_SHADRON = 31218, // Acolyte of Shadron
+ SPELL_POWER_OF_SHADRON = 58105, // Shadron's presence increases Fire damage taken by all enemies by 100%.
+ SPELL_GIFT_OF_TWILIGTH_SHA = 57835, // TARGET_SCRIPT shadron
+ SPELL_GIFT_OF_TWILIGTH_SAR = 58766, // TARGET_SCRIPT sartharion
+ SPELL_VOID_BLAST = 57581, // Twilight Fissure
+ SPELL_VOID_BLAST_H = 59128,
+
+ //Tenebron
+ //in the portal spawns 6 eggs, if not killed in time (approx. 20s) they will hatch, whelps can cast 60708
+ SPELL_POWER_OF_TENEBRON = 61248, // Tenebron's presence increases Shadow damage taken by all enemies by 100%.
+ //Tenebron, dummy spell
+ SPELL_SUMMON_TWILIGHT_WHELP = 58035, // doesn't work, will spawn NPC_TWILIGHT_WHELP
+ SPELL_SUMMON_SARTHARION_TWILIGHT_WHELP = 58826, // doesn't work, will spawn NPC_SHARTHARION_TWILIGHT_WHELP
+
+ SPELL_HATCH_EGGS_H = 59189,
+ SPELL_HATCH_EGGS = 58542,
+ SPELL_HATCH_EGGS_EFFECT_H = 59190,
+ SPELL_HATCH_EGGS_EFFECT = 58685,
+ NPC_TWILIHT_WHELP = 31214,
+ NPC_TWILIGHT_EGG = 30882,
+
+ //Whelps
+ NPC_TWILIGHT_WHELP = 30890,
+ NPC_SHARTHARION_TWILIGHT_WHELP = 31214,
+ SPELL_FADE_ARMOR = 60708, // Reduces the armor of an enemy by 1500 for 15s
+
+ //flame tsunami
+ SPELL_FLAME_TSUNAMI = 57494, // the visual dummy
+ SPELL_FLAME_TSUNAMI_LEAP = 60241, // SPELL_EFFECT_138 some leap effect, causing caster to move in direction
+ SPELL_FLAME_TSUNAMI_DMG_AURA = 57492, // periodic damage, npc has this aura
+
+ NPC_FLAME_TSUNAMI = 30616, // for the flame waves
+ NPC_LAVA_BLAZE = 30643, // adds spawning from flame strike
+
+ //using these custom points for dragons start and end
+ POINT_ID_INIT = 100,
+ POINT_ID_LAND = 200,
+
+ //Achievements
+ ACHIEV_TWILIGHT_ASSIST = 2049,
+ H_ACHIEV_TWILIGHT_ASSIST = 2052,
+ ACHIEV_TWILIGHT_DUO = 2050,
+ H_ACHIEV_TWILIGHT_DUO = 2053,
+ ACHIEV_TWILIGHT_ZONE = 2051,
+ H_ACHIEV_TWILIGHT_ZONE = 2054
+};
+
+struct Waypoint
+{
+ float m_fX, m_fY, m_fZ;
+};
+struct Location
+{
+ float x,y,z;
+};
+struct Locations
+{
+ float x,y,z;
+};
+
+//each dragons special points. First where fly to before connect to connon, second where land point is.
+Waypoint m_aTene[]=
+{
+ {3212.854, 575.597, 109.856}, //init
+ {3246.425, 565.367, 61.249} //end
+};
+
+Waypoint m_aShad[]=
+{
+ {3293.238, 472.223, 106.968},
+ {3271.669, 526.907, 61.931}
+};
+
+Waypoint m_aVesp[]=
+{
+ {3193.310, 472.861, 102.697},
+ {3227.268, 533.238, 59.995}
+};
+
+#define MAX_WAYPOINT 6
+//points around raid "isle", counter clockwise. should probably be adjusted to be more alike
+Waypoint m_aDragonCommon[MAX_WAYPOINT]=
+{
+ {3214.012, 468.932, 98.652},
+ {3244.950, 468.427, 98.652},
+ {3283.520, 496.869, 98.652},
+ {3287.316, 555.875, 98.652},
+ {3250.479, 585.827, 98.652},
+ {3209.969, 566.523, 98.652}
+};
+static Location FlameRight1Spawn = { 3197.59, 495.336, 57.8462 };
+static Location FlameRight1Direction = { 3289.28, 521.569, 55.1526 };
+static Location FlameRight2Spawn = { 3201.94, 543.324, 56.7209 };
+static Location FlameRight2Direction = { 3288.98, 549.291, 55.1232 };
+static Location FlameLeft1Spawn = { 3290.24, 521.725, 55.1238 };
+static Location FlameLeft1Direction = { 3199.94, 516.891, 57.5112 };
+static Location FlameLeft2Spawn = { 3290.33, 586.51, 55.063 };
+static Location FlameLeft2Direction = { 3195.03, 479.135, 55.6331 };
+
+static Location AcolyteofShadron = { 3363.92, 534.703, 97.2683 };
+static Location AcolyteofShadron2 = { 3246.57, 551.263, 58.6164 };
+static Location AcolyteofVesperon = { 3145.68, 520.71, 89.7 };
+static Location AcolyteofVesperon2 = { 3246.57, 551.263, 58.6164 };
+
+Locations TwilightEggs[] =
+{
+ {3219.28, 669.121 , 88.5549},
+ {3221.55, 682.852 , 90.5361},
+ {3239.77, 685.94 , 90.3168},
+ {3250.33, 669.749 , 88.7637},
+ {3246.6, 642.365 , 84.8752},
+ {3233.68, 653.117 , 85.7051}
+};
+Locations TwilightEggsSarth[] =
+{
+ {3261.75, 539.14 , 58.6082},
+ {3257.41, 512.939 , 58.5432},
+ {3231.04, 498.281 , 58.6439}
+};
+
+/*######
+## Boss Sartharion
+######*/
+
+struct boss_sartharionAI : public ScriptedAI
+{
+ boss_sartharionAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ bool m_bIsBerserk;
+ bool m_bIsSoftEnraged;
+
+ uint32 m_uiEnrageTimer;
+ bool m_bIsHardEnraged;
+
+ uint32 m_uiTenebronTimer;
+ uint32 m_uiShadronTimer;
+ uint32 m_uiVesperonTimer;
+
+ uint32 m_uiFlameTsunamiTimer;
+ uint32 m_uiFlameBreathTimer;
+ uint32 m_uiTailSweepTimer;
+ uint32 m_uiCleaveTimer;
+ uint32 m_uiLavaStrikeTimer;
+
+ bool m_bHasCalledTenebron;
+ bool m_bHasCalledShadron;
+ bool m_bHasCalledVesperon;
+
+ uint32 achievProgress;
+
+ void Reset()
+ {
+ m_bIsBerserk = false;
+ m_bIsSoftEnraged = false;
+
+ m_uiEnrageTimer = 15*MINUTE*IN_MILISECONDS;
+ m_bIsHardEnraged = false;
+
+ m_uiTenebronTimer = 30000;
+ m_uiShadronTimer = 75000;
+ m_uiVesperonTimer = 120000;
+
+ m_uiFlameTsunamiTimer = 30000;
+ m_uiFlameBreathTimer = 20000;
+ m_uiTailSweepTimer = 20000;
+ m_uiCleaveTimer = 7000;
+ m_uiLavaStrikeTimer = 5000;
+
+ m_bHasCalledTenebron = false;
+ m_bHasCalledShadron = false;
+ m_bHasCalledVesperon = false;
+
+ if (me->HasAura(SPELL_TWILIGHT_REVENGE))
+ me->RemoveAurasDueToSpell(SPELL_TWILIGHT_REVENGE);
+
+ me->ResetLootMode();
+
+ achievProgress = 0;
+ }
+
+ void JustReachedHome()
+ {
+ if (pInstance)
+ pInstance->SetData(TYPE_SARTHARION_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_SARTHARION_AGGRO,me);
+ DoZoneInCombat();
+
+ if (pInstance)
+ {
+ pInstance->SetData(TYPE_SARTHARION_EVENT, IN_PROGRESS);
+ FetchDragons();
+ }
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ DoScriptText(SAY_SARTHARION_DEATH,me);
+
+ if (pInstance)
+ {
+ if (achievProgress >= 1)
+ pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_TWILIGHT_ASSIST,H_ACHIEV_TWILIGHT_ASSIST));
+ else if (achievProgress >= 2)
+ pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_TWILIGHT_DUO,H_ACHIEV_TWILIGHT_DUO));
+ else if (achievProgress == 3)
+ pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_TWILIGHT_ZONE,H_ACHIEV_TWILIGHT_ZONE));
+
+ pInstance->SetData(TYPE_SARTHARION_EVENT, DONE);
+ }
+ }
+
+ void KilledUnit(Unit* /*pVictim*/)
+ {
+ DoScriptText(RAND(SAY_SARTHARION_SLAY_1,SAY_SARTHARION_SLAY_2,SAY_SARTHARION_SLAY_3), me);
+ }
+
+ // me->ResetLootMode() is called from Reset()
+ // AddDrakeLootMode() should only ever be called from FetchDragons(), which is called from Aggro()
+ void AddDrakeLootMode()
+ {
+ if (me->HasLootMode(LOOT_MODE_HARD_MODE_2)) // Has two Drake loot modes
+ me->AddLootMode(LOOT_MODE_HARD_MODE_3); // Add 3rd Drake loot mode
+ else if (me->HasLootMode(LOOT_MODE_HARD_MODE_1)) // Has one Drake loot mode
+ me->AddLootMode(LOOT_MODE_HARD_MODE_2); // Add 2nd Drake loot mode
+ else // Has no Drake loot modes
+ me->AddLootMode(LOOT_MODE_HARD_MODE_1); // Add 1st Drake loot mode
+ }
+
+ void FetchDragons()
+ {
+ if (!pInstance)
+ return;
+ Creature* pFetchTene = Unit::GetCreature(*me, pInstance->GetData64(DATA_TENEBRON));
+ Creature* pFetchShad = Unit::GetCreature(*me, pInstance->GetData64(DATA_SHADRON));
+ Creature* pFetchVesp = Unit::GetCreature(*me, pInstance->GetData64(DATA_VESPERON));
+
+ //if at least one of the dragons are alive and are being called
+ bool bCanUseWill = false;
+
+ if (pFetchTene && pFetchTene->isAlive() && !pFetchTene->getVictim())
+ {
+ bCanUseWill = true;
+ pFetchTene->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aTene[0].m_fX, m_aTene[0].m_fY, m_aTene[0].m_fZ);
+
+ if (!pFetchTene->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ pFetchTene->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ if (pFetchShad && pFetchShad->isAlive() && !pFetchShad->getVictim())
+ {
+ bCanUseWill = true;
+ pFetchShad->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aShad[0].m_fX, m_aShad[0].m_fY, m_aShad[0].m_fZ);
+
+ if (!pFetchShad->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ pFetchShad->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ if (pFetchVesp && pFetchVesp->isAlive() && !pFetchVesp->getVictim())
+ {
+ bCanUseWill = true;
+ pFetchVesp->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aVesp[0].m_fX, m_aVesp[0].m_fY, m_aVesp[0].m_fZ);
+
+ if (!pFetchVesp->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ pFetchVesp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ if (bCanUseWill)
+ DoCast(me, SPELL_WILL_OF_SARTHARION);
+ }
+
+ void CallDragon(uint32 uiDataId)
+ {
+ if (pInstance)
+ {
+ if (Creature *pTemp = Unit::GetCreature(*me,pInstance->GetData64(uiDataId)))
+ {
+ if (pTemp->isAlive() && !pTemp->getVictim())
+ {
+ if (pTemp->HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE))
+ pTemp->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+
+ if (pTemp->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ int32 iTextId = 0;
+ AddDrakeLootMode();
+
+ achievProgress++;
+
+ switch(pTemp->GetEntry())
+ {
+ case NPC_TENEBRON:
+ iTextId = SAY_SARTHARION_CALL_TENEBRON;
+ pTemp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aTene[1].m_fX, m_aTene[1].m_fY, m_aTene[1].m_fZ);
+ break;
+ case NPC_SHADRON:
+ iTextId = SAY_SARTHARION_CALL_SHADRON;
+ pTemp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aShad[1].m_fX, m_aShad[1].m_fY, m_aShad[1].m_fZ);
+ break;
+ case NPC_VESPERON:
+ iTextId = SAY_SARTHARION_CALL_VESPERON;
+ pTemp->GetMotionMaster()->MovePoint(POINT_ID_LAND, m_aVesp[1].m_fX, m_aVesp[1].m_fY, m_aVesp[1].m_fZ);
+ break;
+ }
+
+ DoScriptText(iTextId, me);
+ }
+ }
+ }
+ }
+
+ void SendFlameTsunami()
+ {
+ if (Map* pMap = me->GetMap())
+ if (pMap->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = pMap->GetPlayers();
+
+ if (!PlayerList.isEmpty())
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ if (i->getSource() && i->getSource()->isAlive())
+ DoScriptText(WHISPER_LAVA_CHURN, me, i->getSource());
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ Unit* pTene = Unit::GetUnit(*me, pInstance ? pInstance->GetData64(DATA_TENEBRON) : 0);
+ Unit* pShad = Unit::GetUnit(*me, pInstance ? pInstance->GetData64(DATA_SHADRON) : 0);
+ Unit* pVesp = Unit::GetUnit(*me, pInstance ? pInstance->GetData64(DATA_VESPERON) : 0);
+
+ //spell will target dragons, if they are still alive at 35%
+ if (!m_bIsBerserk && (me->GetHealth()*100 / me->GetMaxHealth()) <= 35
+ && ((pTene && pTene->isAlive()) || (pShad && pShad->isAlive()) || (pVesp && pVesp->isAlive())))
+ {
+ DoScriptText(SAY_SARTHARION_BERSERK, me);
+ DoCast(me, SPELL_BERSERK);
+ m_bIsBerserk = true;
+ }
+
+ //soft enrage
+ if (!m_bIsSoftEnraged && (me->GetHealth()*100 / me->GetMaxHealth()) <= 10)
+ {
+ // TODO
+ m_bIsSoftEnraged = true;
+ }
+
+ // hard enrage
+ if (!m_bIsHardEnraged)
+ {
+ if (m_uiEnrageTimer <= uiDiff)
+ {
+ DoCast(me, SPELL_PYROBUFFET, true);
+ m_bIsHardEnraged = true;
+ }
+ else
+ m_uiEnrageTimer -= uiDiff;
+ }
+
+ // flame tsunami
+ if (m_uiFlameTsunamiTimer <= uiDiff)
+ {
+ SendFlameTsunami();
+ switch(urand(0,1))
+ {
+ case 0:
+ {
+ if (Creature *Right1 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameRight1Spawn.x, FlameRight1Spawn.y , FlameRight1Spawn.z, 0, TEMPSUMMON_TIMED_DESPAWN,12000))
+ Right1->GetMotionMaster()->MovePoint(0, FlameRight1Direction.x, FlameRight1Direction.y, FlameRight1Direction.z);
+ if (Creature *Right2 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameRight2Spawn.x, FlameRight2Spawn.y , FlameRight2Spawn.z, 0, TEMPSUMMON_TIMED_DESPAWN,12000))
+ Right2->GetMotionMaster()->MovePoint(0, FlameRight2Direction.x, FlameRight2Direction.y, FlameRight2Direction.z);
+ break;
+ }
+ case 1:
+ {
+ if (Creature *Left1 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameLeft1Spawn.x, FlameLeft1Spawn.y , FlameLeft1Spawn.z, 0, TEMPSUMMON_TIMED_DESPAWN,12000))
+ Left1->GetMotionMaster()->MovePoint(0, FlameLeft1Direction.x, FlameLeft1Direction.y, FlameLeft1Direction.z);
+ if (Creature *Left2 = me->SummonCreature(NPC_FLAME_TSUNAMI, FlameLeft2Spawn.x, FlameLeft2Spawn.y , FlameLeft2Spawn.z, 0, TEMPSUMMON_TIMED_DESPAWN,12000))
+ Left2->GetMotionMaster()->MovePoint(0, FlameLeft2Direction.x, FlameLeft2Direction.y, FlameLeft2Direction.z);
+ break;
+ }
+ }
+
+ m_uiFlameTsunamiTimer = 30000;
+ }
+ else
+ m_uiFlameTsunamiTimer -= uiDiff;
+
+ // flame breath
+ if (m_uiFlameBreathTimer <= uiDiff)
+ {
+ DoScriptText(SAY_SARTHARION_BREATH, me);
+ DoCast(me->getVictim(), RAID_MODE(SPELL_FLAME_BREATH, SPELL_FLAME_BREATH_H));
+ m_uiFlameBreathTimer = urand(25000,35000);
+ }
+ else
+ m_uiFlameBreathTimer -= uiDiff;
+
+ // Tail Sweep
+ if (m_uiTailSweepTimer <= uiDiff)
+ {
+ DoCast(me->getVictim(), RAID_MODE(SPELL_TAIL_LASH, SPELL_TAIL_LASH_H));
+ m_uiTailSweepTimer = urand(15000,20000);
+ }
+ else
+ m_uiTailSweepTimer -= uiDiff;
+
+ // Cleave
+ if (m_uiCleaveTimer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_CLEAVE);
+ m_uiCleaveTimer = urand(7000,10000);
+ }
+ else
+ m_uiCleaveTimer -= uiDiff;
+
+ // Lavas Strike
+ if (m_uiLavaStrikeTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ DoCast(pTarget, SPELL_LAVA_STRIKE);
+
+ if (urand(0,4) == 4)
+ DoScriptText(RAND(SAY_SARTHARION_SPECIAL_1,SAY_SARTHARION_SPECIAL_2,SAY_SARTHARION_SPECIAL_3), me);
+ }
+ m_uiLavaStrikeTimer = urand(5000,20000);
+ }
+ else
+ m_uiLavaStrikeTimer -= uiDiff;
+
+ // call tenebron
+ if (!m_bHasCalledTenebron && m_uiTenebronTimer <= uiDiff)
+ {
+ CallDragon(DATA_TENEBRON);
+ m_bHasCalledTenebron = true;
+ }
+ else
+ m_uiTenebronTimer -= uiDiff;
+
+ // call shadron
+ if (!m_bHasCalledShadron && m_uiShadronTimer <= uiDiff)
+ {
+ CallDragon(DATA_SHADRON);
+ m_bHasCalledShadron = true;
+ }
+ else
+ m_uiShadronTimer -= uiDiff;
+
+ // call vesperon
+ if (!m_bHasCalledVesperon && m_uiVesperonTimer <= uiDiff)
+ {
+ CallDragon(DATA_VESPERON);
+ m_bHasCalledVesperon = true;
+ }
+ else
+ m_uiVesperonTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+
+ EnterEvadeIfOutOfCombatArea(uiDiff);
+ }
+};
+
+CreatureAI* GetAI_boss_sartharion(Creature* pCreature)
+{
+ return new boss_sartharionAI(pCreature);
+}
+
+enum TeneText
+{
+ SAY_TENEBRON_AGGRO = -1615009,
+ SAY_TENEBRON_SLAY_1 = -1615010,
+ SAY_TENEBRON_SLAY_2 = -1615011,
+ SAY_TENEBRON_DEATH = -1615012,
+ SAY_TENEBRON_BREATH = -1615013,
+ SAY_TENEBRON_RESPOND = -1615014,
+ SAY_TENEBRON_SPECIAL_1 = -1615015,
+ SAY_TENEBRON_SPECIAL_2 = -1615016
+};
+
+enum ShadText
+{
+ SAY_SHADRON_AGGRO = -1615000,
+ SAY_SHADRON_SLAY_1 = -1615001,
+ SAY_SHADRON_SLAY_2 = -1615002,
+ SAY_SHADRON_DEATH = -1615003,
+ SAY_SHADRON_BREATH = -1615004,
+ SAY_SHADRON_RESPOND = -1615005,
+ SAY_SHADRON_SPECIAL_1 = -1615006,
+ SAY_SHADRON_SPECIAL_2 = -1615007
+};
+
+enum VespText
+{
+ SAY_VESPERON_AGGRO = -1615033,
+ SAY_VESPERON_SLAY_1 = -1615034,
+ SAY_VESPERON_SLAY_2 = -1615035,
+ SAY_VESPERON_DEATH = -1615036,
+ SAY_VESPERON_BREATH = -1615037,
+ SAY_VESPERON_RESPOND = -1615038,
+ SAY_VESPERON_SPECIAL_1 = -1615039,
+ SAY_VESPERON_SPECIAL_2 = -1615040
+};
+
+//to control each dragons common abilities
+struct dummy_dragonAI : public ScriptedAI
+{
+ dummy_dragonAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 m_uiWaypointId;
+ uint32 m_uiMoveNextTimer;
+ int32 m_iPortalRespawnTime;
+ bool m_bCanMoveFree;
+
+ void Reset()
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ if (GameObject* TwilightPortal = GameObject::GetGameObject((*me), pInstance->GetData64(GO_TWILIGHT_PORTAL)))
+ TwilightPortal->SetGoState(GO_STATE_READY);
+
+ m_uiWaypointId = 0;
+ m_uiMoveNextTimer = 500;
+ m_iPortalRespawnTime = 30000;
+ m_bCanMoveFree = false;
+ }
+
+ void MovementInform(uint32 uiType, uint32 uiPointId)
+ {
+ if (!pInstance || uiType != POINT_MOTION_TYPE)
+ return;
+
+ debug_log("dummy_dragonAI: %s reached point %u", me->GetName(), uiPointId);
+
+ //if healers messed up the raid and we was already initialized
+ if (pInstance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS)
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ //this is end, if we reach this, don't do much
+ if (uiPointId == POINT_ID_LAND)
+ {
+ me->GetMotionMaster()->Clear();
+ m_bCanMoveFree = false;
+ return;
+ }
+
+ //get amount of common points
+ uint32 uiCommonWPCount = sizeof(m_aDragonCommon)/sizeof(Waypoint);
+
+ //increase
+ m_uiWaypointId = uiPointId+1;
+
+ //if we have reached a point bigger or equal to count, it mean we must reset to point 0
+ if (m_uiWaypointId >= uiCommonWPCount)
+ {
+ if (!m_bCanMoveFree)
+ m_bCanMoveFree = true;
+
+ m_uiWaypointId = 0;
+ }
+
+ m_uiMoveNextTimer = 500;
+ }
+
+ //used when open portal and spawn mobs in phase
+ void DoRaidWhisper(int32 iTextId)
+ {
+ Map* pMap = me->GetMap();
+
+ if (pMap && pMap->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = pMap->GetPlayers();
+
+ if (!PlayerList.isEmpty())
+ {
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ DoScriptText(iTextId, me, i->getSource());
+ }
+ }
+ }
+
+ //"opens" the portal and does the "opening" whisper
+ void OpenPortal()
+ {
+ int32 iTextId = 0;
+
+ //there are 4 portal spawn locations, each are expected to be spawned with negative spawntimesecs in database
+
+ //using a grid search here seem to be more efficient than caching all four guids
+ //in instance script and calculate range to each.
+ GameObject* pPortal = me->FindNearestGameObject(GO_TWILIGHT_PORTAL,50.0f);
+ if (GameObject* TwilightPortal = GameObject::GetGameObject((*me), pInstance->GetData64(GO_TWILIGHT_PORTAL)))
+ TwilightPortal->SetGoState(GO_STATE_ACTIVE);
+
+ switch(me->GetEntry())
+ {
+ case NPC_TENEBRON:
+ {
+ iTextId = WHISPER_HATCH_EGGS;
+ if (pInstance && pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
+ me->SummonCreature(NPC_TWILIGHT_EGG, TwilightEggs[0].x, TwilightEggs[0].y, TwilightEggs[0].z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
+ else
+ me->SummonCreature(NPC_TWILIGHT_EGG, TwilightEggsSarth[0].x, TwilightEggsSarth[0].y, TwilightEggsSarth[0].z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
+ break;
+ }
+ case NPC_SHADRON:
+ {
+ iTextId = WHISPER_OPEN_PORTAL;
+ if (pInstance && !pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
+ me->SummonCreature(NPC_ACOLYTE_OF_SHADRON, AcolyteofShadron.x, AcolyteofShadron.y , AcolyteofShadron.z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
+ else
+ me->SummonCreature(NPC_ACOLYTE_OF_SHADRON, AcolyteofShadron2.x, AcolyteofShadron2.y , AcolyteofShadron2.z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
+
+ break;
+ }
+ case NPC_VESPERON:
+ {
+ if (pInstance && !pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
+ me->SummonCreature(NPC_ACOLYTE_OF_VESPERON, AcolyteofVesperon.x, AcolyteofVesperon.y , AcolyteofVesperon.z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
+ else
+ me->SummonCreature(NPC_ACOLYTE_OF_VESPERON, AcolyteofVesperon2.x, AcolyteofVesperon2.y , AcolyteofVesperon2.z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN,20000);
+
+ iTextId = WHISPER_OPEN_PORTAL;
+ break;
+ }
+ }
+
+ DoRaidWhisper(iTextId);
+
+ //By using SetRespawnTime() we will actually "spawn" the object with our defined time.
+ //Once time is up, portal will disappear again.
+ if (pPortal && !pPortal->isSpawned())
+ pPortal->SetRespawnTime(m_iPortalRespawnTime);
+
+ //Unclear what are expected to happen if one drake has a portal open already
+ //Refresh respawnTime so time again are set to 30secs?
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ int32 iTextId = 0;
+ uint32 uiSpellId = 0;
+
+ switch(me->GetEntry())
+ {
+ case NPC_TENEBRON:
+ iTextId = SAY_TENEBRON_DEATH;
+ uiSpellId = SPELL_POWER_OF_TENEBRON;
+ break;
+ case NPC_SHADRON:
+ iTextId = SAY_SHADRON_DEATH;
+ uiSpellId = SPELL_POWER_OF_SHADRON;
+ break;
+ case NPC_VESPERON:
+ iTextId = SAY_VESPERON_DEATH;
+ uiSpellId = SPELL_POWER_OF_VESPERON;
+ break;
+ }
+
+ DoScriptText(iTextId, me);
+
+ me->RemoveOwnedAura(uiSpellId);
+
+ if (pInstance)
+ {
+ // not if solo mini-boss fight
+ if (pInstance->GetData(TYPE_SARTHARION_EVENT) != IN_PROGRESS)
+ return;
+
+ // Twilight Revenge to main boss
+ if (Unit* pSartharion = Unit::GetUnit((*me), pInstance->GetData64(DATA_SARTHARION)))
+ if (pSartharion->isAlive())
+ DoCast(pSartharion, SPELL_TWILIGHT_REVENGE, true);
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_bCanMoveFree && m_uiMoveNextTimer)
+ {
+ if (m_uiMoveNextTimer <= uiDiff)
+ {
+ if (m_uiWaypointId < MAX_WAYPOINT)
+ me->GetMotionMaster()->MovePoint(m_uiWaypointId,
+ m_aDragonCommon[m_uiWaypointId].m_fX, m_aDragonCommon[m_uiWaypointId].m_fY, m_aDragonCommon[m_uiWaypointId].m_fZ);
+
+ debug_log("dummy_dragonAI: %s moving to point %u", me->GetName(), m_uiWaypointId);
+ m_uiMoveNextTimer = 0;
+ }
+ else
+ m_uiMoveNextTimer -= uiDiff;
+ }
+ }
+};
+
+/*######
+## Mob Tenebron
+######*/
+
+struct mob_tenebronAI : public dummy_dragonAI
+{
+ mob_tenebronAI(Creature* pCreature) : dummy_dragonAI(pCreature) {}
+
+ uint32 m_uiShadowBreathTimer;
+ uint32 m_uiShadowFissureTimer;
+ uint32 m_uiHatchEggTimer;
+
+ void Reset()
+ {
+ m_uiShadowBreathTimer = 20000;
+ m_uiShadowFissureTimer = 5000;
+ m_uiHatchEggTimer = 30000;
+ }
+
+ void Aggro(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_TENEBRON_AGGRO, me);
+ DoZoneInCombat();
+ DoCast(me, SPELL_POWER_OF_TENEBRON);
+ }
+
+ void KilledUnit(Unit* /*pVictim*/)
+ {
+ DoScriptText(RAND(SAY_TENEBRON_SLAY_1,SAY_TENEBRON_SLAY_2), me);
+ /*if (pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
+ achievProgress = 1;*/
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //if no target, update dummy and return
+ if (!UpdateVictim())
+ {
+ dummy_dragonAI::UpdateAI(uiDiff);
+ return;
+ }
+
+ // shadow fissure
+ if (m_uiShadowFissureTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, RAID_MODE(SPELL_SHADOW_FISSURE, SPELL_SHADOW_FISSURE));
+
+ m_uiShadowFissureTimer = urand(15000,20000);
+ }
+ else
+ m_uiShadowFissureTimer -= uiDiff;
+
+ // Hach Egg
+ if (m_uiHatchEggTimer <= uiDiff)
+ {
+ OpenPortal();
+ m_uiHatchEggTimer = 30000;
+ }
+ else
+ m_uiHatchEggTimer -= uiDiff;
+
+ // shadow breath
+ if (m_uiShadowBreathTimer <= uiDiff)
+ {
+ DoScriptText(SAY_TENEBRON_BREATH, me);
+ DoCast(me->getVictim(), RAID_MODE(SPELL_SHADOW_BREATH, SPELL_SHADOW_BREATH_H));
+ m_uiShadowBreathTimer = urand(20000,25000);
+ }
+ else
+ m_uiShadowBreathTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_tenebron(Creature* pCreature)
+{
+ return new mob_tenebronAI(pCreature);
+}
+
+/*######
+## Mob Shadron
+######*/
+
+struct mob_shadronAI : public dummy_dragonAI
+{
+ mob_shadronAI(Creature* pCreature) : dummy_dragonAI(pCreature) {}
+
+ uint32 m_uiShadowBreathTimer;
+ uint32 m_uiShadowFissureTimer;
+ uint32 m_uiAcolyteShadronTimer;
+
+ void Reset()
+ {
+ m_uiShadowBreathTimer = 20000;
+ m_uiShadowFissureTimer = 5000;
+ m_uiAcolyteShadronTimer = 60000;
+
+ if (me->HasAura(SPELL_TWILIGHT_TORMENT_VESP))
+ me->RemoveAurasDueToSpell(SPELL_TWILIGHT_TORMENT_VESP);
+
+ if (me->HasAura(SPELL_GIFT_OF_TWILIGTH_SHA))
+ me->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SHA);
+ }
+
+ void Aggro(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_SHADRON_AGGRO,me);
+ DoZoneInCombat();
+ DoCast(me, SPELL_POWER_OF_SHADRON);
+ }
+
+ void KilledUnit(Unit* /*pVictim*/)
+ {
+ DoScriptText(RAND(SAY_SHADRON_SLAY_1,SAY_SHADRON_SLAY_2), me);
+ /*if (pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
+ achievProgress = 2;*/
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //if no target, update dummy and return
+ if (!UpdateVictim())
+ {
+ dummy_dragonAI::UpdateAI(uiDiff);
+ return;
+ }
+
+ // shadow fissure
+ if (m_uiShadowFissureTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, RAID_MODE(SPELL_SHADOW_FISSURE, SPELL_SHADOW_FISSURE_H));
+
+ m_uiShadowFissureTimer = urand(15000,20000);
+ }
+ else
+ m_uiShadowFissureTimer -= uiDiff;
+
+ // Portal Event
+ if (m_uiAcolyteShadronTimer <= uiDiff)
+ {
+ if (me->HasAura(SPELL_GIFT_OF_TWILIGTH_SHA))
+ return;
+
+ OpenPortal();
+ m_uiAcolyteShadronTimer = urand(60000,65000);
+ }
+ else
+ m_uiAcolyteShadronTimer -= uiDiff;
+
+ // shadow breath
+ if (m_uiShadowBreathTimer <= uiDiff)
+ {
+ DoScriptText(SAY_SHADRON_BREATH, me);
+ DoCast(me->getVictim(), RAID_MODE(SPELL_SHADOW_BREATH, SPELL_SHADOW_BREATH_H));
+ m_uiShadowBreathTimer = urand(20000,25000);
+ }
+ else
+ m_uiShadowBreathTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_shadron(Creature* pCreature)
+{
+ return new mob_shadronAI(pCreature);
+}
+
+/*######
+## Mob Vesperon
+######*/
+
+struct mob_vesperonAI : public dummy_dragonAI
+{
+ mob_vesperonAI(Creature* pCreature) : dummy_dragonAI(pCreature) {}
+
+ uint32 m_uiShadowBreathTimer;
+ uint32 m_uiShadowFissureTimer;
+ uint32 m_uiAcolyteVesperonTimer;
+
+ void Reset()
+ {
+ m_uiShadowBreathTimer = 20000;
+ m_uiShadowFissureTimer = 5000;
+ m_uiAcolyteVesperonTimer = 60000;
+ }
+
+ void Aggro(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_VESPERON_AGGRO,me);
+ DoZoneInCombat();
+ DoCast(me, SPELL_POWER_OF_VESPERON);
+ }
+
+ void KilledUnit(Unit* /*pVictim*/)
+ {
+ DoScriptText(RAND(SAY_VESPERON_SLAY_1,SAY_VESPERON_SLAY_2), me);
+ /*if (pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
+ achievProgress = 3;*/
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //if no target, update dummy and return
+ if (!UpdateVictim())
+ {
+ dummy_dragonAI::UpdateAI(uiDiff);
+ return;
+ }
+
+ // shadow fissure
+ if (m_uiShadowFissureTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, RAID_MODE(SPELL_SHADOW_FISSURE, SPELL_SHADOW_FISSURE_H));
+
+ m_uiShadowFissureTimer = urand(15000,20000);
+ }
+ else
+ m_uiShadowFissureTimer -= uiDiff;
+
+ // Portal Event
+ if (m_uiAcolyteVesperonTimer <= uiDiff)
+ {
+ OpenPortal();
+ DoCast(me->getVictim(), SPELL_TWILIGHT_TORMENT_VESP);
+ m_uiAcolyteVesperonTimer = urand(60000,70000);
+ }
+ else
+ m_uiAcolyteVesperonTimer -= uiDiff;
+
+ // shadow breath
+ if (m_uiShadowBreathTimer <= uiDiff)
+ {
+ DoScriptText(SAY_VESPERON_BREATH, me);
+ DoCast(me->getVictim(), RAID_MODE(SPELL_SHADOW_BREATH, SPELL_SHADOW_BREATH_H));
+ m_uiShadowBreathTimer = urand(20000,25000);
+ }
+ else
+ m_uiShadowBreathTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_vesperon(Creature* pCreature)
+{
+ return new mob_vesperonAI(pCreature);
+}
+
+/*######
+## Mob Acolyte of Shadron
+######*/
+
+struct mob_acolyte_of_shadronAI : public ScriptedAI
+{
+ mob_acolyte_of_shadronAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+ uint32 uiShiftEffectTimer;
+
+ void Reset()
+ {
+ uiShiftEffectTimer = 1000;
+ if (pInstance)
+ {
+ Unit *pTarget = SelectTarget(SELECT_TARGET_TOPAGGRO, 0, 999, true);
+
+ Creature* pSartharion = Unit::GetCreature(*me, pInstance->GetData64(DATA_SARTHARION));
+ if (Creature* pShadron = Unit::GetCreature(*me, pInstance->GetData64(DATA_SHADRON)))
+ //if not solo figth, buff main boss, else place debuff on mini-boss. both spells TARGET_SCRIPT
+ if (pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
+ pSartharion->CastSpell(me, SPELL_GIFT_OF_TWILIGTH_SAR, true);
+ else
+ {
+ pShadron->CastSpell(me, SPELL_GIFT_OF_TWILIGTH_SHA,true);
+ pShadron->AddThreat(pTarget, 100.0f);
+ AttackStart(pShadron->getVictim());
+ }
+ }
+ me->AddAura(SPELL_TWILIGHT_SHIFT_ENTER,me);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ {
+ //Creature* pDebuffTarget = NULL;
+ Map *map = me->GetMap();
+ if (map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource()->isAlive() && i->getSource()->HasAura(SPELL_TWILIGHT_SHIFT,0) && !i->getSource()->getVictim())
+ {
+ i->getSource()->CastSpell(i->getSource(),SPELL_TWILIGHT_SHIFT_REMOVAL_ALL,true);
+ i->getSource()->CastSpell(i->getSource(),SPELL_TWILIGHT_RESIDUE,true);
+ i->getSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT);
+ i->getSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT_ENTER);
+ }
+ }
+ }
+
+ if (pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
+ {
+ //not solo fight, so main boss has deduff
+ Creature* pDebuffTarget = Unit::GetCreature(*me, pInstance->GetData64(DATA_SARTHARION));
+ if (pDebuffTarget && pDebuffTarget->isAlive() && pDebuffTarget->HasAura(SPELL_GIFT_OF_TWILIGTH_SAR))
+ pDebuffTarget->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SAR);
+ }
+ else
+ {
+ //event not in progress, then solo fight and must remove debuff mini-boss
+ Creature* pDebuffTarget = Unit::GetCreature(*me, pInstance->GetData64(DATA_SHADRON));
+ if (pDebuffTarget && pDebuffTarget->isAlive() && pDebuffTarget->HasAura(SPELL_GIFT_OF_TWILIGTH_SHA))
+ pDebuffTarget->RemoveAurasDueToSpell(SPELL_GIFT_OF_TWILIGTH_SHA);
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 /*uiDiff*/)
+ {
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_acolyte_of_shadron(Creature* pCreature)
+{
+ return new mob_acolyte_of_shadronAI(pCreature);
+}
+
+/*######
+## Mob Acolyte of Vesperon
+######*/
+
+struct mob_acolyte_of_vesperonAI : public ScriptedAI
+{
+ mob_acolyte_of_vesperonAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ if (pInstance)
+ {
+ me->AddAura(SPELL_TWILIGHT_SHIFT_ENTER,me);
+ }
+ DoCast(me, SPELL_TWILIGHT_TORMENT_VESP_ACO);
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ // remove twilight torment on Vesperon
+ if (pInstance)
+ {
+ Creature* pVesperon = Unit::GetCreature(*me, pInstance->GetData64(DATA_VESPERON));
+
+ if (pVesperon && pVesperon->isAlive() && pVesperon->HasAura(SPELL_TWILIGHT_TORMENT_VESP))
+ pVesperon->RemoveAurasDueToSpell(SPELL_TWILIGHT_TORMENT_VESP);
+
+ Map *map = me->GetMap();
+ if (map->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if (i->getSource()->isAlive() && i->getSource()->HasAura(SPELL_TWILIGHT_SHIFT,0) && !i->getSource()->getVictim())
+ {
+ i->getSource()->CastSpell(i->getSource(),SPELL_TWILIGHT_SHIFT_REMOVAL_ALL,true);
+ i->getSource()->CastSpell(i->getSource(),SPELL_TWILIGHT_RESIDUE,true);
+ i->getSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT);
+ i->getSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT_ENTER);
+ }
+ if (i->getSource()->isAlive() && i->getSource()->HasAura(SPELL_TWILIGHT_TORMENT_VESP,0) && !i->getSource()->getVictim())
+ i->getSource()->RemoveAurasDueToSpell(SPELL_TWILIGHT_SHIFT);
+ }
+ }
+
+ }
+ }
+
+ void UpdateAI(const uint32 /*uiDiff*/)
+ {
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_acolyte_of_vesperon(Creature* pCreature)
+{
+ return new mob_acolyte_of_vesperonAI(pCreature);
+}
+
+/*######
+## Mob Twilight Eggs
+######*/
+
+struct mob_twilight_eggsAI : public Scripted_NoMovementAI
+{
+ mob_twilight_eggsAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+ uint32 m_uiFadeArmorTimer;
+ uint32 m_uiHatchEggTimer;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ m_uiHatchEggTimer = 20000;
+ m_uiFadeArmorTimer = 1000;
+ }
+ void SpawnWhelps()
+ {
+ if (!pInstance->GetData(TYPE_SARTHARION_EVENT) == IN_PROGRESS)
+ me->SummonCreature(NPC_TWILIGHT_WHELP, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
+ else
+ me->SummonCreature(NPC_SHARTHARION_TWILIGHT_WHELP, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
+ me->DealDamage(me, me->GetHealth());
+ }
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_uiHatchEggTimer <= uiDiff)
+ {
+ SpawnWhelps();
+ }
+ else
+ m_uiHatchEggTimer -= uiDiff;
+ }
+ void AttackStart(Unit* /*pWho*/) {}
+ void MoveInLineOfSight(Unit* /*pWho*/) {}
+};
+
+CreatureAI* GetAI_mob_twilight_eggs(Creature* pCreature)
+{
+ return new mob_twilight_eggsAI(pCreature);
+}
+
+/*######
+## Flame Tzunami
+######*/
+struct npc_flame_tsunamiAI : public ScriptedAI
+{
+ npc_flame_tsunamiAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ me->HasAura(SPELL_FLAME_TSUNAMI_DMG_AURA);
+ DoCast(me, SPELL_FLAME_TSUNAMI);
+ }
+
+ uint32 Tsunami_Timer;
+
+ void Reset()
+ {
+ Tsunami_Timer = 100;
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (Tsunami_Timer <= diff)
+ {
+ DoCast(me, SPELL_FLAME_TSUNAMI_DMG_AURA);
+ Tsunami_Timer = 1000;
+ } else Tsunami_Timer -= diff;
+ }
+};
+// Twilight Fissure
+struct npc_twilight_fissureAI : public Scripted_NoMovementAI
+{
+ npc_twilight_fissureAI(Creature* pCreature) : Scripted_NoMovementAI(pCreature)
+ {
+ Reset();
+ }
+
+ uint32 VoidBlast_Timer;
+
+ void Reset()
+ {
+ VoidBlast_Timer = 5000;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (VoidBlast_Timer <= diff)
+ {
+ DoCast(me->getVictim(), RAID_MODE(SPELL_VOID_BLAST, SPELL_VOID_BLAST_H));
+ VoidBlast_Timer = 9000;
+ me->Kill(me);
+ } else VoidBlast_Timer -= diff;
+ }
+};
+
+
+CreatureAI* GetAI_npc_flame_tsunami(Creature* pCreature)
+{
+ return new npc_flame_tsunamiAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_twilight_fissure(Creature* pCreature)
+{
+ return new npc_twilight_fissureAI(pCreature);
+}
+
+/*######
+## Mob Twilight Whelps
+######*/
+
+struct mob_twilight_whelpAI : public ScriptedAI
+{
+ mob_twilight_whelpAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint32 m_uiFadeArmorTimer;
+
+ void Reset()
+ {
+ m_uiFadeArmorTimer = 1000;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ // twilight torment
+ if (m_uiFadeArmorTimer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_FADE_ARMOR);
+ m_uiFadeArmorTimer = urand(5000,10000);
+ }
+ else
+ m_uiFadeArmorTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_twilight_whelp(Creature* pCreature)
+{
+ return new mob_twilight_whelpAI(pCreature);
+}
+
+void AddSC_boss_sartharion()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_sartharion";
+ newscript->GetAI = &GetAI_boss_sartharion;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_vesperon";
+ newscript->GetAI = &GetAI_mob_vesperon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_shadron";
+ newscript->GetAI = &GetAI_mob_shadron;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_tenebron";
+ newscript->GetAI = &GetAI_mob_tenebron;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_acolyte_of_shadron";
+ newscript->GetAI = &GetAI_mob_acolyte_of_shadron;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_acolyte_of_vesperon";
+ newscript->GetAI = &GetAI_mob_acolyte_of_vesperon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_twilight_eggs";
+ newscript->GetAI = &GetAI_mob_twilight_eggs;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_flame_tsunami";
+ newscript->GetAI = &GetAI_npc_flame_tsunami;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_twilight_fissure";
+ newscript->GetAI = &GetAI_npc_twilight_fissure;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_twilight_whelp";
+ newscript->GetAI = &GetAI_mob_twilight_whelp;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp b/src/server/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp
new file mode 100644
index 00000000000..7ef8e03c779
--- /dev/null
+++ b/src/server/scripts/northrend/obsidian_sanctum/instance_obsidian_sanctum.cpp
@@ -0,0 +1,97 @@
+#include "ScriptedPch.h"
+#include "obsidian_sanctum.h"
+
+#define MAX_ENCOUNTER 1
+
+/* Obsidian Sanctum encounters:
+0 - Sartharion
+*/
+
+struct instance_obsidian_sanctum : public ScriptedInstance
+{
+ instance_obsidian_sanctum(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+
+ uint32 m_auiEncounter[MAX_ENCOUNTER];
+ uint64 m_uiSartharionGUID;
+ uint64 m_uiTenebronGUID;
+ uint64 m_uiShadronGUID;
+ uint64 m_uiVesperonGUID;
+
+ void Initialize()
+ {
+ memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+
+ m_uiSartharionGUID = 0;
+ m_uiTenebronGUID = 0;
+ m_uiShadronGUID = 0;
+ m_uiVesperonGUID = 0;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool /*add*/)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case NPC_SARTHARION:
+ m_uiSartharionGUID = pCreature->GetGUID();
+ break;
+ //three dragons below set to active state once created.
+ //we must expect bigger raid to encounter main boss, and then three dragons must be active due to grid differences
+ case NPC_TENEBRON:
+ m_uiTenebronGUID = pCreature->GetGUID();
+ pCreature->setActive(true);
+ break;
+ case NPC_SHADRON:
+ m_uiShadronGUID = pCreature->GetGUID();
+ pCreature->setActive(true);
+ break;
+ case NPC_VESPERON:
+ m_uiVesperonGUID = pCreature->GetGUID();
+ pCreature->setActive(true);
+ break;
+ }
+ }
+
+ void SetData(uint32 uiType, uint32 uiData)
+ {
+ if (uiType == TYPE_SARTHARION_EVENT)
+ m_auiEncounter[0] = uiData;
+ }
+
+ uint32 GetData(uint32 uiType)
+ {
+ if (uiType == TYPE_SARTHARION_EVENT)
+ return m_auiEncounter[0];
+
+ return 0;
+ }
+
+ uint64 GetData64(uint32 uiData)
+ {
+ switch(uiData)
+ {
+ case DATA_SARTHARION:
+ return m_uiSartharionGUID;
+ case DATA_TENEBRON:
+ return m_uiTenebronGUID;
+ case DATA_SHADRON:
+ return m_uiShadronGUID;
+ case DATA_VESPERON:
+ return m_uiVesperonGUID;
+ }
+ return 0;
+ }
+};
+
+InstanceData* GetInstanceData_instance_obsidian_sanctum(Map* pMap)
+{
+ return new instance_obsidian_sanctum(pMap);
+}
+
+void AddSC_instance_obsidian_sanctum()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_obsidian_sanctum";
+ newscript->GetInstanceData = &GetInstanceData_instance_obsidian_sanctum;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/obsidian_sanctum/obsidian_sanctum.h b/src/server/scripts/northrend/obsidian_sanctum/obsidian_sanctum.h
new file mode 100644
index 00000000000..59013174795
--- /dev/null
+++ b/src/server/scripts/northrend/obsidian_sanctum/obsidian_sanctum.h
@@ -0,0 +1,20 @@
+#ifndef DEF_OBSIDIAN_SANCTUM_H
+#define DEF_OBSIDIAN_SANCTUM_H
+
+enum eTypes
+{
+ TYPE_SARTHARION_EVENT = 1,
+
+ DATA_SARTHARION = 10,
+ DATA_TENEBRON = 11,
+ DATA_SHADRON = 12,
+ DATA_VESPERON = 13,
+
+ NPC_SARTHARION = 28860,
+ NPC_TENEBRON = 30452,
+ NPC_SHADRON = 30451,
+ NPC_VESPERON = 30449,
+ GO_TWILIGHT_PORTAL = 193988
+};
+
+#endif
diff --git a/src/server/scripts/northrend/sholazar_basin.cpp b/src/server/scripts/northrend/sholazar_basin.cpp
new file mode 100644
index 00000000000..b5df8998b4a
--- /dev/null
+++ b/src/server/scripts/northrend/sholazar_basin.cpp
@@ -0,0 +1,449 @@
+/* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Sholazar_Basin
+SD%Complete: 100
+SDComment: Quest support: 12570, 12573, 12621.
+SDCategory: Sholazar_Basin
+EndScriptData */
+
+/* ContentData
+npc_injured_rainspeaker_oracle
+npc_vekjik
+avatar_of_freya
+EndContentData */
+
+#include "ScriptedPch.h"
+#include "ScriptedEscortAI.h"
+
+/*######
+## npc_injured_rainspeaker_oracle
+######*/
+
+#define GOSSIP_ITEM1 "I am ready to travel to your village now."
+
+enum eRainspeaker
+{
+ SAY_START_IRO = -1571000,
+ SAY_QUEST_ACCEPT_IRO = -1571001,
+ SAY_END_IRO = -1571002,
+
+ QUEST_FORTUNATE_MISUNDERSTANDINGS = 12570,
+ FACTION_ESCORTEE_A = 774,
+ FACTION_ESCORTEE_H = 775
+};
+
+struct npc_injured_rainspeaker_oracleAI : public npc_escortAI
+{
+ npc_injured_rainspeaker_oracleAI(Creature* c) : npc_escortAI(c) { c_guid = c->GetGUID(); }
+
+ uint64 c_guid;
+
+ void Reset()
+ {
+ me->RestoreFaction();
+ // if we will have other way to assign this to only one npc remove this part
+ if (GUID_LOPART(me->GetGUID()) != 101030)
+ {
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ }
+ }
+
+ void WaypointReached(uint32 i)
+ {
+ Player* pPlayer = GetPlayerForEscort();
+
+ if (!pPlayer)
+ return;
+
+ switch(i)
+ {
+ case 1: SetRun(); break;
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ case 17:
+ case 18:
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_JUMPING);
+ me->SetSpeed(MOVE_SWIM, 0.85f, true);
+ me->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_LEVITATING);
+ break;
+ case 19:
+ me->SetUnitMovementFlags(MOVEMENTFLAG_JUMPING);
+ break;
+ case 28:
+ if (Player* pPlayer = GetPlayerForEscort())
+ pPlayer->GroupEventHappens(QUEST_FORTUNATE_MISUNDERSTANDINGS, me);
+ // me->RestoreFaction();
+ DoScriptText(SAY_END_IRO,me);
+ SetRun(false);
+ break;
+ }
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (!HasEscortState(STATE_ESCORT_ESCORTING))
+ return;
+
+ if (Player* pPlayer = GetPlayerForEscort())
+ {
+ if (pPlayer->GetQuestStatus(QUEST_FORTUNATE_MISUNDERSTANDINGS) != QUEST_STATUS_COMPLETE)
+ pPlayer->FailQuest(QUEST_FORTUNATE_MISUNDERSTANDINGS);
+ }
+ }
+};
+
+bool GossipHello_npc_injured_rainspeaker_oracle(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_FORTUNATE_MISUNDERSTANDINGS) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_injured_rainspeaker_oracle(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ CAST_AI(npc_escortAI, (pCreature->AI()))->Start(true, false, pPlayer->GetGUID());
+ CAST_AI(npc_escortAI, (pCreature->AI()))->SetMaxPlayerDistance(35.0f);
+ pCreature->SetUnitMovementFlags(MOVEMENTFLAG_JUMPING);
+ DoScriptText(SAY_START_IRO, pCreature);
+
+ switch (pPlayer->GetTeam()){
+ case ALLIANCE:
+ pCreature->setFaction(FACTION_ESCORTEE_A);
+ break;
+ case HORDE:
+ pCreature->setFaction(FACTION_ESCORTEE_H);
+ break;
+ }
+ }
+ return true;
+}
+
+bool QuestAccept_npc_injured_rainspeaker_oracle(Player* /*pPlayer*/, Creature* pCreature, Quest const * /*_Quest*/)
+{
+ DoScriptText(SAY_QUEST_ACCEPT_IRO, pCreature);
+ return false;
+}
+
+CreatureAI* GetAI_npc_injured_rainspeaker_oracle(Creature* pCreature)
+{
+ return new npc_injured_rainspeaker_oracleAI(pCreature);
+}
+
+/*######
+## npc_vekjik
+######*/
+
+#define GOSSIP_VEKJIK_ITEM1 "Shaman Vekjik, I have spoken with the big-tongues and they desire peace. I have brought this offering on their behalf."
+#define GOSSIP_VEKJIK_ITEM2 "No no... I had no intentions of betraying your people. I was only defending myself. it was all a misunderstanding."
+
+enum eVekjik
+{
+ GOSSIP_TEXTID_VEKJIK1 = 13137,
+ GOSSIP_TEXTID_VEKJIK2 = 13138,
+
+ SAY_TEXTID_VEKJIK1 = -1000208,
+
+ SPELL_FREANZYHEARTS_FURY = 51469,
+
+ QUEST_MAKING_PEACE = 12573
+};
+
+bool GossipHello_npc_vekjik(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_MAKING_PEACE) == QUEST_STATUS_INCOMPLETE)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_VEKJIK_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VEKJIK1, pCreature->GetGUID());
+ return true;
+ }
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_vekjik(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_VEKJIK_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VEKJIK2, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ DoScriptText(SAY_TEXTID_VEKJIK1, pCreature, pPlayer);
+ pPlayer->AreaExploredOrEventHappens(QUEST_MAKING_PEACE);
+ pCreature->CastSpell(pPlayer, SPELL_FREANZYHEARTS_FURY, false);
+ break;
+ }
+
+ return true;
+}
+
+/*######
+## avatar_of_freya
+######*/
+
+#define GOSSIP_ITEM_AOF1 "I want to stop the Scourge as much as you do. How can I help?"
+#define GOSSIP_ITEM_AOF2 "You can trust me. I am no friend of the Lich King."
+#define GOSSIP_ITEM_AOF3 "I will not fail."
+
+enum eFreya
+{
+ QUEST_FREYA_PACT = 12621,
+
+ SPELL_FREYA_CONVERSATION = 52045,
+
+ GOSSIP_TEXTID_AVATAR1 = 13303,
+ GOSSIP_TEXTID_AVATAR2 = 13304,
+ GOSSIP_TEXTID_AVATAR3 = 13305
+};
+
+bool GossipHello_npc_avatar_of_freya(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_FREYA_PACT) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR1, pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_avatar_of_freya(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch (uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ pPlayer->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR2, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AOF3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
+ pPlayer->PlayerTalkClass->SendGossipMenu(GOSSIP_TEXTID_AVATAR3, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+3:
+ pPlayer->CastSpell(pPlayer, SPELL_FREYA_CONVERSATION, true);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ break;
+ }
+ return true;
+}
+
+/*######
+## npc_geezle
+######*/
+
+struct npc_bushwhackerAI : public ScriptedAI
+{
+ npc_bushwhackerAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ MoveToSummoner();
+ }
+
+ void MoveToSummoner()
+ {
+ if (me->isSummon())
+ if (Unit* pSummoner = CAST_SUM(me)->GetSummoner())
+ if (pSummoner)
+ me->GetMotionMaster()->MovePoint(0,pSummoner->GetPositionX(),pSummoner->GetPositionY(),pSummoner->GetPositionZ());
+ }
+
+ void UpdateAI(const uint32 /*uiDiff*/)
+ {
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_bushwhacker(Creature* pCreature)
+{
+ return new npc_bushwhackerAI(pCreature);
+}
+
+/*######
+## npc_engineer_helice
+######*/
+
+enum eEnums
+{
+ SPELL_EXPLODE_CRYSTAL = 62487,
+ SPELL_FLAMES = 64561,
+
+ SAY_WP_7 = -1800047,
+ SAY_WP_6 = -1800048,
+ SAY_WP_5 = -1800049,
+ SAY_WP_4 = -1800050,
+ SAY_WP_3 = -1800051,
+ SAY_WP_2 = -1800052,
+ SAY_WP_1 = -1800053,
+
+ QUEST_DISASTER = 12688
+};
+
+struct npc_engineer_heliceAI : public npc_escortAI
+{
+ npc_engineer_heliceAI(Creature* pCreature) : npc_escortAI(pCreature) { }
+
+ uint32 m_uiChatTimer;
+
+ void WaypointReached(uint32 i)
+ {
+ Player* pPlayer = GetPlayerForEscort();
+ switch (i)
+ {
+ case 0:
+ DoScriptText(SAY_WP_2, me);
+ break;
+ case 1:
+ DoScriptText(SAY_WP_3, me);
+ me->CastSpell(5918.33, 5372.91, -98.770, SPELL_EXPLODE_CRYSTAL, true);
+ me->SummonGameObject(184743, 5918.33, 5372.91, -98.770, 0, 0, 0, 0, 0, TEMPSUMMON_MANUAL_DESPAWN); //approx 3 to 4 seconds
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH);
+ break;
+ case 2:
+ DoScriptText(SAY_WP_4, me);
+ break;
+ case 7:
+ DoScriptText(SAY_WP_5, me);
+ break;
+ case 8:
+ me->CastSpell(5887.37, 5379.39, -91.289, SPELL_EXPLODE_CRYSTAL, true);
+ me->SummonGameObject(184743, 5887.37, 5379.39, -91.289, 0, 0, 0, 0, 0, TEMPSUMMON_MANUAL_DESPAWN); //approx 3 to 4 seconds
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH);
+ break;
+ case 9:
+ DoScriptText(SAY_WP_6, me);
+ break;
+ case 13:
+ if (pPlayer)
+ {
+ pPlayer->GroupEventHappens(QUEST_DISASTER, me);
+ DoScriptText(SAY_WP_7, me);
+ }
+ break;
+ }
+ }
+
+ void Reset()
+ {
+ m_uiChatTimer = 4000;
+ }
+ void JustDied(Unit* /*pKiller*/)
+ {
+ Player* pPlayer = GetPlayerForEscort();
+ if (HasEscortState(STATE_ESCORT_ESCORTING))
+ {
+ if (pPlayer)
+ pPlayer->FailQuest(QUEST_DISASTER);
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ npc_escortAI::UpdateAI(uiDiff);
+
+ if (HasEscortState(STATE_ESCORT_ESCORTING))
+ {
+ if (m_uiChatTimer <= uiDiff)
+ {
+ m_uiChatTimer = 12000;
+ }
+ else
+ m_uiChatTimer -= uiDiff;
+ }
+ }
+};
+
+CreatureAI* GetAI_npc_engineer_helice(Creature* pCreature)
+{
+ return new npc_engineer_heliceAI(pCreature);
+}
+
+bool QuestAccept_npc_engineer_helice(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
+{
+ if (pQuest->GetQuestId() == QUEST_DISASTER)
+ {
+ if (npc_engineer_heliceAI* pEscortAI = CAST_AI(npc_engineer_heliceAI, pCreature->AI()))
+ {
+ pCreature->GetMotionMaster()->MoveJumpTo(0, 0.4, 0.4);
+ pCreature->setFaction(113);
+
+ pEscortAI->Start(false, false, pPlayer->GetGUID());
+ DoScriptText(SAY_WP_1, pCreature);
+ }
+ }
+ return true;
+}
+
+void AddSC_sholazar_basin()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "npc_injured_rainspeaker_oracle";
+ newscript->GetAI = &GetAI_npc_injured_rainspeaker_oracle;
+ newscript->pGossipHello = &GossipHello_npc_injured_rainspeaker_oracle;
+ newscript->pGossipSelect = &GossipSelect_npc_injured_rainspeaker_oracle;
+ newscript->pQuestAccept = &QuestAccept_npc_injured_rainspeaker_oracle;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_vekjik";
+ newscript->pGossipHello = &GossipHello_npc_vekjik;
+ newscript->pGossipSelect = &GossipSelect_npc_vekjik;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_avatar_of_freya";
+ newscript->pGossipHello = &GossipHello_npc_avatar_of_freya;
+ newscript->pGossipSelect = &GossipSelect_npc_avatar_of_freya;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_bushwhacker";
+ newscript->GetAI = &GetAI_npc_bushwhacker;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_engineer_helice";
+ newscript->GetAI = &GetAI_npc_engineer_helice;
+ newscript->pQuestAccept = &QuestAccept_npc_engineer_helice;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/storm_peaks.cpp b/src/server/scripts/northrend/storm_peaks.cpp
new file mode 100644
index 00000000000..9275e24bd2f
--- /dev/null
+++ b/src/server/scripts/northrend/storm_peaks.cpp
@@ -0,0 +1,491 @@
+/* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "ScriptedEscortAI.h"
+
+/*######
+## npc_agnetta_tyrsdottar
+######*/
+
+#define SAY_AGGRO -1571003
+#define GOSSIP_AGNETTA "Skip the warmup, sister... or are you too scared to face soemeone your own size?"
+
+enum eAgnetta
+{
+ QUEST_ITS_THAT_YOUR_GOBLIN = 12969,
+ FACTION_HOSTILE_AT1 = 45
+};
+
+struct npc_agnetta_tyrsdottarAI : public ScriptedAI
+{
+ npc_agnetta_tyrsdottarAI(Creature* pCreature) : ScriptedAI(pCreature) { }
+
+ void Reset()
+ {
+ me->RestoreFaction();
+ }
+};
+
+CreatureAI* GetAI_npc_agnetta_tyrsdottar(Creature* pCreature)
+{
+ return new npc_agnetta_tyrsdottarAI(pCreature);
+}
+
+bool GossipHello_npc_agnetta_tyrsdottar(Player* pPlayer, Creature* pCreature)
+{
+ if (pPlayer->GetQuestStatus(QUEST_ITS_THAT_YOUR_GOBLIN) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_AGNETTA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ pPlayer->SEND_GOSSIP_MENU(13691, pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_agnetta_tyrsdottar(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ DoScriptText(SAY_AGGRO, pCreature);
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pCreature->setFaction(FACTION_HOSTILE_AT1);
+ pCreature->AI()->AttackStart(pPlayer);
+ }
+
+ return true;
+}
+
+/*######
+## npc_frostborn_scout
+######*/
+
+#define GOSSIP_ITEM1 "Are you okay? I've come to take you back to Frosthold if you can stand."
+#define GOSSIP_ITEM2 "I'm sorry that I didn't get here sooner. What happened?"
+#define GOSSIP_ITEM3 "I'll go get some help. Hang in there."
+
+enum eFrostbornScout
+{
+ QUEST_MISSING_SCOUTS = 12864
+};
+
+bool GossipHello_npc_frostborn_scout(Player* pPlayer, Creature* pCreature)
+{
+
+ if (pPlayer->GetQuestStatus(QUEST_MISSING_SCOUTS) == QUEST_STATUS_INCOMPLETE)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->PlayerTalkClass->SendGossipMenu(13611, pCreature->GetGUID());
+ }
+
+ return true;
+}
+
+bool GossipSelect_npc_frostborn_scout(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch (uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ pPlayer->PlayerTalkClass->SendGossipMenu(13612, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
+ pPlayer->PlayerTalkClass->SendGossipMenu(13613, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+3:
+ pPlayer->PlayerTalkClass->SendGossipMenu(13614, pCreature->GetGUID());
+ pPlayer->AreaExploredOrEventHappens(QUEST_MISSING_SCOUTS);
+ break;
+ }
+
+ return true;
+}
+
+/*######
+## npc_thorim
+######*/
+
+#define GOSSIP_HN "Thorim?"
+#define GOSSIP_SN1 "Can you tell me what became of Sif?"
+#define GOSSIP_SN2 "He did more than that, Thorim. He controls Ulduar now."
+#define GOSSIP_SN3 "It needn't end this way."
+
+enum eThorim
+{
+ QUEST_SIBLING_RIVALRY = 13064,
+ NPC_THORIM = 29445,
+ GOSSIP_TEXTID_THORIM1 = 13799,
+ GOSSIP_TEXTID_THORIM2 = 13801,
+ GOSSIP_TEXTID_THORIM3 = 13802,
+ GOSSIP_TEXTID_THORIM4 = 13803
+};
+
+bool GossipHello_npc_thorim(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_SIBLING_RIVALRY) == QUEST_STATUS_INCOMPLETE) {
+ pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_HN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM1, pCreature->GetGUID());
+ return true;
+ }
+ return false;
+}
+
+bool GossipSelect_npc_thorim(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch (uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_SN1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM2, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_SN2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM3, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+3:
+ pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_SN3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_THORIM4, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+4:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CompleteQuest(QUEST_SIBLING_RIVALRY);
+ break;
+ }
+ return true;
+}
+
+/*######
+## npc_goblin_prisoner
+######*/
+
+enum eGoblinPrisoner
+{
+ GO_RUSTY_CAGE = 191544
+};
+
+struct npc_goblin_prisonerAI : public ScriptedAI
+{
+ npc_goblin_prisonerAI(Creature* pCreature) : ScriptedAI (pCreature){}
+
+ void Reset()
+ {
+ me->SetReactState(REACT_PASSIVE);
+
+ if (GameObject* pGO = me->FindNearestGameObject(GO_RUSTY_CAGE,5.0f))
+ {
+ if (pGO->GetGoState() == GO_STATE_ACTIVE)
+ pGO->SetGoState(GO_STATE_READY);
+ }
+ }
+
+};
+
+CreatureAI* GetAI_npc_goblin_prisoner(Creature* pCreature)
+{
+ return new npc_goblin_prisonerAI(pCreature);
+}
+
+/*######
+## npc_victorious_challenger
+######*/
+
+#define GOSSIP_CHALLENGER "Let's do this, sister."
+
+enum eVictoriousChallenger
+{
+ QUEST_TAKING_ALL_CHALLENGERS = 12971,
+ QUEST_DEFENDING_YOUR_TITLE = 13423,
+
+ SPELL_SUNDER_ARMOR = 11971,
+ SPELL_REND_VC = 11977
+};
+
+struct npc_victorious_challengerAI : public ScriptedAI
+{
+ npc_victorious_challengerAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint32 SunderArmorTimer;
+ uint32 RendTimer;
+
+ void Reset()
+ {
+ me->RestoreFaction();
+
+ SunderArmorTimer = 10000;
+ RendTimer = 15000;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (RendTimer < diff)
+ {
+ DoCast(me->getVictim(), SPELL_REND_VC, true);
+ RendTimer = 15000;
+ }else RendTimer -= diff;
+
+ if (SunderArmorTimer < diff)
+ {
+ DoCast(me->getVictim(), SPELL_SUNDER_ARMOR, true);
+ SunderArmorTimer = 10000;
+ }else SunderArmorTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void KilledUnit(Unit* /*victim*/)
+ {
+ me->RestoreFaction();
+ }
+
+};
+
+bool GossipHello_npc_victorious_challenger(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_TAKING_ALL_CHALLENGERS) == QUEST_STATUS_INCOMPLETE || pPlayer->GetQuestStatus(QUEST_DEFENDING_YOUR_TITLE) == QUEST_STATUS_INCOMPLETE)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CHALLENGER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+ }
+
+ return false;
+}
+
+bool GossipSelect_npc_victorious_challenger(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pCreature->setFaction(14);
+ pCreature->AI()->AttackStart(pPlayer);
+ }
+
+ return true;
+}
+
+CreatureAI* GetAI_npc_victorious_challenger(Creature* pCreature)
+{
+ return new npc_victorious_challengerAI(pCreature);
+}
+
+/*######
+## npc_loklira_crone
+######*/
+
+#define GOSSIP_LOKLIRACRONE "Tell me about this proposal"
+#define GOSSIP_LOKLIRACRONE1 "What happened then?"
+#define GOSSIP_LOKLIRACRONE2 "You want me to take part in the Hyldsmeet to end the war?"
+#define GOSSIP_LOKLIRACRONE3 "Very well. I'll take part in this competition."
+
+enum eLokliraCrone
+{
+ QUEST_HYLDSMEET = 12970,
+
+ GOSSIP_TEXTID_LOK1 = 13778,
+ GOSSIP_TEXTID_LOK2 = 13779,
+ GOSSIP_TEXTID_LOK3 = 13780
+};
+
+bool GossipHello_npc_loklira_crone(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_HYLDSMEET) == QUEST_STATUS_INCOMPLETE)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+ return true;
+ }
+ return false;
+}
+
+bool GossipSelect_npc_loklira_crone(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch (uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LOK1, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LOK2, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+3:
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LOKLIRACRONE3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_TEXTID_LOK3, pCreature->GetGUID());
+ break;
+ case GOSSIP_ACTION_INFO_DEF+4:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CompleteQuest(QUEST_HYLDSMEET);
+ break;
+ }
+ return true;
+}
+
+/////////////////////
+///npc_injured_goblin
+/////////////////////
+
+enum eInjuredGoblin
+{
+ QUEST_BITTER_DEPARTURE = 12832,
+ SAY_QUEST_ACCEPT = -1800042,
+ SAY_END_WP_REACHED = -1800043
+};
+
+#define GOSSIP_ITEM_1 "I am ready, lets get you out of here"
+
+struct npc_injured_goblinAI : public npc_escortAI
+{
+ npc_injured_goblinAI(Creature* pCreature) : npc_escortAI(pCreature) { }
+
+ void WaypointReached(uint32 i)
+ {
+ Player* pPlayer = GetPlayerForEscort();
+ switch (i)
+ {
+ case 26:
+ DoScriptText(SAY_END_WP_REACHED, me, pPlayer);
+ break;
+ case 27:
+ if (pPlayer)
+ pPlayer->GroupEventHappens(QUEST_BITTER_DEPARTURE, me);
+ break;
+ }
+ }
+
+ void EnterCombat(Unit* /*pWho*/) {}
+
+ void Reset() {}
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ Player* pPlayer = GetPlayerForEscort();
+ if (HasEscortState(STATE_ESCORT_ESCORTING) && pPlayer)
+ pPlayer->FailQuest(QUEST_BITTER_DEPARTURE);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ npc_escortAI::UpdateAI(uiDiff);
+ if (!UpdateVictim())
+ return;
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_injured_goblin(Creature* pCreature)
+{
+ return new npc_injured_goblinAI(pCreature);
+}
+
+bool GossipHello_npc_injured_goblin(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_BITTER_DEPARTURE) == QUEST_STATUS_INCOMPLETE)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(0, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->PlayerTalkClass->SendGossipMenu(9999999, pCreature->GetGUID());
+ }
+ else
+ pPlayer->SEND_GOSSIP_MENU(999999, pCreature->GetGUID());
+ return true;
+}
+
+bool QuestAccept_npc_injured_goblin(Player* /*pPlayer*/, Creature* pCreature, Quest const *quest)
+{
+ if (quest->GetQuestId() == QUEST_BITTER_DEPARTURE)
+ DoScriptText(SAY_QUEST_ACCEPT, pCreature);
+
+ return false;
+}
+
+bool GossipSelect_npc_injured_goblin(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ npc_escortAI* pEscortAI = CAST_AI(npc_injured_goblinAI, pCreature->AI());
+
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ pEscortAI->Start(true, true, pPlayer->GetGUID());
+ pCreature->setFaction(113);
+ }
+ return true;
+}
+
+
+void AddSC_storm_peaks()
+{
+ Script* newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_agnetta_tyrsdottar";
+ newscript->GetAI = &GetAI_npc_agnetta_tyrsdottar;
+ newscript->pGossipHello = &GossipHello_npc_agnetta_tyrsdottar;
+ newscript->pGossipSelect = &GossipSelect_npc_agnetta_tyrsdottar;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_frostborn_scout";
+ newscript->pGossipHello = &GossipHello_npc_frostborn_scout;
+ newscript->pGossipSelect = &GossipSelect_npc_frostborn_scout;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_thorim";
+ newscript->pGossipHello = &GossipHello_npc_thorim;
+ newscript->pGossipSelect = &GossipSelect_npc_thorim;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_goblin_prisoner";
+ newscript->GetAI = &GetAI_npc_goblin_prisoner;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_victorious_challenger";
+ newscript->GetAI = &GetAI_npc_victorious_challenger;
+ newscript->pGossipHello = &GossipHello_npc_victorious_challenger;
+ newscript->pGossipSelect = &GossipSelect_npc_victorious_challenger;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_loklira_crone";
+ newscript->pGossipHello = &GossipHello_npc_loklira_crone;
+ newscript->pGossipSelect = &GossipSelect_npc_loklira_crone;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_injured_goblin";
+ newscript->GetAI = &GetAI_npc_injured_goblin;
+ newscript->pGossipHello = &GossipHello_npc_injured_goblin;
+ newscript->pGossipSelect = &GossipSelect_npc_injured_goblin;
+ newscript->pQuestAccept = &QuestAccept_npc_injured_goblin;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp b/src/server/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp
new file mode 100644
index 00000000000..c2da2a24e71
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/halls_of_lightning/boss_bjarngrim.cpp
@@ -0,0 +1,432 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Boss General Bjarngrim
+SD%Complete: 70%
+SDComment: Waypoint needed, we expect boss to always have 2x Stormforged Lieutenant following
+SDCategory: Halls of Lightning
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "halls_of_lightning.h"
+
+enum eEnums
+{
+ //Yell
+ SAY_AGGRO = -1602000,
+ SAY_SLAY_1 = -1602001,
+ SAY_SLAY_2 = -1602002,
+ SAY_SLAY_3 = -1602003,
+ SAY_DEATH = -1602004,
+ SAY_BATTLE_STANCE = -1602005,
+ EMOTE_BATTLE_STANCE = -1602006,
+ SAY_BERSEKER_STANCE = -1602007,
+ EMOTE_BERSEKER_STANCE = -1602008,
+ SAY_DEFENSIVE_STANCE = -1602009,
+ EMOTE_DEFENSIVE_STANCE = -1602010,
+
+ SPELL_DEFENSIVE_STANCE = 53790,
+ //SPELL_DEFENSIVE_AURA = 41105,
+ SPELL_SPELL_REFLECTION = 36096,
+ SPELL_PUMMEL = 12555,
+ SPELL_KNOCK_AWAY = 52029,
+ SPELL_IRONFORM = 52022,
+
+ SPELL_BERSEKER_STANCE = 53791,
+ //SPELL_BERSEKER_AURA = 41107,
+ SPELL_INTERCEPT = 58769,
+ SPELL_WHIRLWIND = 52027,
+ SPELL_CLEAVE = 15284,
+
+ SPELL_BATTLE_STANCE = 53792,
+ //SPELL_BATTLE_AURA = 41106,
+ SPELL_MORTAL_STRIKE = 16856,
+ SPELL_SLAM = 52026,
+
+ //OTHER SPELLS
+ //SPELL_CHARGE_UP = 52098, // only used when starting walk from one platform to the other
+ //SPELL_TEMPORARY_ELECTRICAL_CHARGE = 52092, // triggered part of above
+
+ NPC_STORMFORGED_LIEUTENANT = 29240,
+ SPELL_ARC_WELD = 59085,
+ SPELL_RENEW_STEEL_N = 52774,
+ SPELL_RENEW_STEEL_H = 59160,
+
+ EQUIP_SWORD = 37871,
+ EQUIP_SHIELD = 35642,
+ EQUIP_MACE = 43623,
+
+ STANCE_DEFENSIVE = 0,
+ STANCE_BERSERKER = 1,
+ STANCE_BATTLE = 2
+};
+
+/*######
+## boss_bjarngrim
+######*/
+
+struct boss_bjarngrimAI : public ScriptedAI
+{
+ boss_bjarngrimAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = pCreature->GetInstanceData();
+ m_uiStance = STANCE_DEFENSIVE;
+ memset(&m_auiStormforgedLieutenantGUID, 0, sizeof(m_auiStormforgedLieutenantGUID));
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ bool m_bIsChangingStance;
+
+ uint8 m_uiChargingStatus;
+ uint8 m_uiStance;
+
+ uint32 m_uiCharge_Timer;
+ uint32 m_uiChangeStance_Timer;
+
+ uint32 m_uiReflection_Timer;
+ uint32 m_uiKnockAway_Timer;
+ uint32 m_uiPummel_Timer;
+ uint32 m_uiIronform_Timer;
+
+ uint32 m_uiIntercept_Timer;
+ uint32 m_uiWhirlwind_Timer;
+ uint32 m_uiCleave_Timer;
+
+ uint32 m_uiMortalStrike_Timer;
+ uint32 m_uiSlam_Timer;
+
+ uint64 m_auiStormforgedLieutenantGUID[2];
+
+ void Reset()
+ {
+ m_bIsChangingStance = false;
+
+ m_uiChargingStatus = 0;
+ m_uiCharge_Timer = 1000;
+
+ m_uiChangeStance_Timer = 20000 + rand()%5000;
+
+ m_uiReflection_Timer = 8000;
+ m_uiKnockAway_Timer = 20000;
+ m_uiPummel_Timer = 10000;
+ m_uiIronform_Timer = 25000;
+
+ m_uiIntercept_Timer = 5000;
+ m_uiWhirlwind_Timer = 10000;
+ m_uiCleave_Timer = 8000;
+
+ m_uiMortalStrike_Timer = 8000;
+ m_uiSlam_Timer = 10000;
+
+ for (uint8 i = 0; i < 2; ++i)
+ {
+ if (Creature* pStormforgedLieutenant = (Unit::GetCreature((*me), m_auiStormforgedLieutenantGUID[i])))
+ {
+ if (!pStormforgedLieutenant->isAlive())
+ pStormforgedLieutenant->Respawn();
+ }
+ }
+
+ if (m_uiStance != STANCE_DEFENSIVE)
+ {
+ DoRemoveStanceAura(m_uiStance);
+ DoCast(me, SPELL_DEFENSIVE_STANCE);
+ m_uiStance = STANCE_DEFENSIVE;
+ }
+
+ SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_BJARNGRIM, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ //must get both lieutenants here and make sure they are with him
+ me->CallForHelp(30.0f);
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_BJARNGRIM, IN_PROGRESS);
+ }
+
+ void KilledUnit(Unit* /*pVictim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_BJARNGRIM, DONE);
+ }
+
+ //TODO: remove when removal is done by the core
+ void DoRemoveStanceAura(uint8 uiStance)
+ {
+ switch(uiStance)
+ {
+ case STANCE_DEFENSIVE:
+ me->RemoveAurasDueToSpell(SPELL_DEFENSIVE_STANCE);
+ break;
+ case STANCE_BERSERKER:
+ me->RemoveAurasDueToSpell(SPELL_BERSEKER_STANCE);
+ break;
+ case STANCE_BATTLE:
+ me->RemoveAurasDueToSpell(SPELL_BATTLE_STANCE);
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ // Change stance
+ if (m_uiChangeStance_Timer <= uiDiff)
+ {
+ //wait for current spell to finish before change stance
+ if (me->IsNonMeleeSpellCasted(false))
+ return;
+
+ DoRemoveStanceAura(m_uiStance);
+
+ int uiTempStance = rand()%(3-1);
+
+ if (uiTempStance >= m_uiStance)
+ ++uiTempStance;
+
+ m_uiStance = uiTempStance;
+
+ switch(m_uiStance)
+ {
+ case STANCE_DEFENSIVE:
+ DoScriptText(SAY_DEFENSIVE_STANCE, me);
+ DoScriptText(EMOTE_DEFENSIVE_STANCE, me);
+ DoCast(me, SPELL_DEFENSIVE_STANCE);
+ SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
+ break;
+ case STANCE_BERSERKER:
+ DoScriptText(SAY_BERSEKER_STANCE, me);
+ DoScriptText(EMOTE_BERSEKER_STANCE, me);
+ DoCast(me, SPELL_BERSEKER_STANCE);
+ SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SWORD, EQUIP_NO_CHANGE);
+ break;
+ case STANCE_BATTLE:
+ DoScriptText(SAY_BATTLE_STANCE, me);
+ DoScriptText(EMOTE_BATTLE_STANCE, me);
+ DoCast(me, SPELL_BATTLE_STANCE);
+ SetEquipmentSlots(false, EQUIP_MACE, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
+ break;
+ }
+
+ m_uiChangeStance_Timer = 20000 + rand()%5000;
+ return;
+ }
+ else
+ m_uiChangeStance_Timer -= uiDiff;
+
+ switch(m_uiStance)
+ {
+ case STANCE_DEFENSIVE:
+ {
+ if (m_uiReflection_Timer <= uiDiff)
+ {
+ DoCast(me, SPELL_SPELL_REFLECTION);
+ m_uiReflection_Timer = 8000 + rand()%1000;
+ }
+ else
+ m_uiReflection_Timer -= uiDiff;
+
+ if (m_uiKnockAway_Timer <= uiDiff)
+ {
+ DoCast(me, SPELL_KNOCK_AWAY);
+ m_uiKnockAway_Timer = 20000 + rand()%1000;
+ }
+ else
+ m_uiKnockAway_Timer -= uiDiff;
+
+ if (m_uiPummel_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_PUMMEL);
+ m_uiPummel_Timer = 10000 + rand()%1000;
+ }
+ else
+ m_uiPummel_Timer -= uiDiff;
+
+ if (m_uiIronform_Timer <= uiDiff)
+ {
+ DoCast(me, SPELL_IRONFORM);
+ m_uiIronform_Timer = 25000 + rand()%1000;
+ }
+ else
+ m_uiIronform_Timer -= uiDiff;
+
+ break;
+ }
+ case STANCE_BERSERKER:
+ {
+ if (m_uiIntercept_Timer <= uiDiff)
+ {
+ //not much point is this, better random target and more often?
+ DoCast(me->getVictim(), SPELL_INTERCEPT);
+ m_uiIntercept_Timer = 45000 + rand()%1000;
+ }
+ else
+ m_uiIntercept_Timer -= uiDiff;
+
+ if (m_uiWhirlwind_Timer <= uiDiff)
+ {
+ DoCast(me, SPELL_WHIRLWIND);
+ m_uiWhirlwind_Timer = 10000 + rand()%1000;
+ }
+ else
+ m_uiWhirlwind_Timer -= uiDiff;
+
+ if (m_uiCleave_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_CLEAVE);
+ m_uiCleave_Timer = 8000 + rand()%1000;
+ }
+ else
+ m_uiCleave_Timer -= uiDiff;
+
+ break;
+ }
+ case STANCE_BATTLE:
+ {
+ if (m_uiMortalStrike_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_MORTAL_STRIKE);
+ m_uiMortalStrike_Timer = 20000 + rand()%1000;
+ }
+ else
+ m_uiMortalStrike_Timer -= uiDiff;
+
+ if (m_uiSlam_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_SLAM);
+ m_uiSlam_Timer = 15000 + rand()%1000;
+ }
+ else
+ m_uiSlam_Timer -= uiDiff;
+
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+/*######
+## mob_stormforged_lieutenant
+######*/
+
+struct mob_stormforged_lieutenantAI : public ScriptedAI
+{
+ mob_stormforged_lieutenantAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ uint32 m_uiArcWeld_Timer;
+ uint32 m_uiRenewSteel_Timer;
+
+ void Reset()
+ {
+ m_uiArcWeld_Timer = 20000 + rand()%1000;
+ m_uiRenewSteel_Timer = 10000 + rand()%1000;
+ }
+
+ void EnterCombat(Unit* pWho)
+ {
+ if (m_pInstance)
+ {
+ if (Creature* pBjarngrim = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_BJARNGRIM)))
+ {
+ if (pBjarngrim->isAlive() && !pBjarngrim->getVictim())
+ pBjarngrim->AI()->AttackStart(pWho);
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (m_uiArcWeld_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_ARC_WELD);
+ m_uiArcWeld_Timer = 20000 + rand()%1000;
+ }
+ else
+ m_uiArcWeld_Timer -= uiDiff;
+
+ if (m_uiRenewSteel_Timer <= uiDiff)
+ {
+ if (m_pInstance)
+ {
+ if (Creature* pBjarngrim = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_BJARNGRIM)))
+ {
+ if (pBjarngrim->isAlive())
+ DoCast(pBjarngrim, SPELL_RENEW_STEEL_N);
+ }
+ }
+ m_uiRenewSteel_Timer = 10000 + rand()%4000;
+ }
+ else
+ m_uiRenewSteel_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_bjarngrim(Creature* pCreature)
+{
+ return new boss_bjarngrimAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_stormforged_lieutenant(Creature* pCreature)
+{
+ return new mob_stormforged_lieutenantAI(pCreature);
+}
+
+void AddSC_boss_bjarngrim()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_bjarngrim";
+ newscript->GetAI = &GetAI_boss_bjarngrim;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_stormforged_lieutenant";
+ newscript->GetAI = &GetAI_mob_stormforged_lieutenant;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp b/src/server/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp
new file mode 100644
index 00000000000..ecf61188b3e
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/halls_of_lightning/boss_ionar.cpp
@@ -0,0 +1,388 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Comment: Timer check pending
+ */
+
+#include "ScriptedPch.h"
+#include "halls_of_lightning.h"
+
+enum Spells
+{
+ SPELL_BALL_LIGHTNING = 52780,
+ H_SPELL_BALL_LIGHTNING = 59800,
+ SPELL_STATIC_OVERLOAD = 52658,
+ H_SPELL_STATIC_OVERLOAD = 59795,
+
+ SPELL_DISPERSE = 52770,
+ SPELL_SUMMON_SPARK = 52746,
+ SPELL_SPARK_DESPAWN = 52776,
+
+ //Spark of Ionar
+ SPELL_SPARK_VISUAL_TRIGGER = 52667,
+ H_SPELL_SPARK_VISUAL_TRIGGER = 59833
+};
+
+enum Yells
+{
+ SAY_AGGRO = -1602011,
+ SAY_SLAY_1 = -1602012,
+ SAY_SLAY_2 = -1602013,
+ SAY_SLAY_3 = -1602014,
+ SAY_DEATH = -1602015,
+ SAY_SPLIT_1 = -1602016,
+ SAY_SPLIT_2 = -1602017
+};
+
+enum Creatures
+{
+ NPC_SPARK_OF_IONAR = 28926
+};
+
+enum Misc
+{
+ DATA_MAX_SPARKS = 5,
+ DATA_MAX_SPARK_DISTANCE = 90, // Distance to boss - prevent runs through the whole instance
+ DATA_POINT_CALLBACK = 0
+};
+
+/*######
+## Boss Ionar
+######*/
+
+struct boss_ionarAI : public ScriptedAI
+{
+ boss_ionarAI(Creature *pCreature) : ScriptedAI(pCreature), lSparkList(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ SummonList lSparkList;
+
+ bool bIsSplitPhase;
+ bool bHasDispersed;
+
+ uint32 uiSplitTimer;
+
+ uint32 uiStaticOverloadTimer;
+ uint32 uiBallLightningTimer;
+
+ uint32 uiDisperseHealth;
+
+ void Reset()
+ {
+ lSparkList.DespawnAll();
+
+ bIsSplitPhase = true;
+ bHasDispersed = false;
+
+ uiSplitTimer = 25*IN_MILISECONDS;
+
+ uiStaticOverloadTimer = urand(5*IN_MILISECONDS, 6*IN_MILISECONDS);
+ uiBallLightningTimer = urand(10*IN_MILISECONDS, 11*IN_MILISECONDS);
+
+ uiDisperseHealth = 45 + urand(0,10);
+
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_DISABLE_MOVE);
+
+ if (me->GetVisibility() == VISIBILITY_OFF)
+ me->SetVisibility(VISIBILITY_ON);
+
+ if (pInstance)
+ pInstance->SetData(TYPE_IONAR, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ pInstance->SetData(TYPE_IONAR, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ lSparkList.DespawnAll();
+
+ if (pInstance)
+ pInstance->SetData(TYPE_IONAR, DONE);
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+
+ //make sparks come back
+ void CallBackSparks()
+ {
+ //should never be empty here, but check
+ if (lSparkList.empty())
+ return;
+
+ Position pos;
+ me->GetPosition(&pos);
+
+ for (std::list<uint64>::const_iterator itr = lSparkList.begin(); itr != lSparkList.end(); ++itr)
+ {
+ if (Creature* pSpark = Unit::GetCreature(*me, *itr))
+ {
+ if (pSpark->isAlive())
+ {
+ pSpark->SetSpeed(MOVE_RUN, 2.0f);
+ pSpark->GetMotionMaster()->Clear();
+ pSpark->GetMotionMaster()->MovePoint(DATA_POINT_CALLBACK, pos);
+ }
+ else
+ pSpark->ForcedDespawn();
+ }
+ }
+ }
+
+ void DamageTaken(Unit * /*pDoneBy*/, uint32 &uiDamage)
+ {
+ if (me->GetVisibility() == VISIBILITY_OFF)
+ uiDamage = 0;
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ if (pSummoned->GetEntry() == NPC_SPARK_OF_IONAR)
+ {
+ lSparkList.Summon(pSummoned);
+
+ pSummoned->CastSpell(pSummoned, DUNGEON_MODE(SPELL_SPARK_VISUAL_TRIGGER,H_SPELL_SPARK_VISUAL_TRIGGER), true);
+
+ Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ if (pTarget)
+ {
+ pSummoned->SetInCombatWith(pTarget);
+ pSummoned->GetMotionMaster()->Clear();
+ pSummoned->GetMotionMaster()->MoveFollow(pTarget, 0.0f, 0.0f);
+ }
+ }
+ }
+
+ void SummonedCreatureDespawn(Creature *pSummoned)
+ {
+ if (pSummoned->GetEntry() == NPC_SPARK_OF_IONAR)
+ lSparkList.Despawn(pSummoned);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ // Splitted
+ if (me->GetVisibility() == VISIBILITY_OFF)
+ {
+ if (uiSplitTimer <= uiDiff)
+ {
+ uiSplitTimer = 2.5*IN_MILISECONDS;
+
+ // Return sparks to where Ionar splitted
+ if (bIsSplitPhase)
+ {
+ CallBackSparks();
+ bIsSplitPhase = false;
+ }
+ // Lightning effect and restore Ionar
+ else if (lSparkList.empty())
+ {
+ me->SetVisibility(VISIBILITY_ON);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_DISABLE_MOVE);
+
+ DoCast(me, SPELL_SPARK_DESPAWN, false);
+
+ uiSplitTimer = 25*IN_MILISECONDS;
+ bIsSplitPhase = true;
+
+ if (me->getVictim())
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+ }
+ }
+ else
+ uiSplitTimer -= uiDiff;
+
+ return;
+ }
+
+ if (uiStaticOverloadTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_STATIC_OVERLOAD);
+
+ uiStaticOverloadTimer = urand(5*IN_MILISECONDS, 6*IN_MILISECONDS);
+ }
+ else
+ uiStaticOverloadTimer -= uiDiff;
+
+ if (uiBallLightningTimer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_BALL_LIGHTNING);
+ uiBallLightningTimer = urand(10*IN_MILISECONDS, 11*IN_MILISECONDS);
+ }
+ else
+ uiBallLightningTimer -= uiDiff;
+
+ // Health check
+ if (!bHasDispersed && HealthBelowPct(uiDisperseHealth))
+ {
+ bHasDispersed = true;
+
+ DoScriptText(RAND(SAY_SPLIT_1,SAY_SPLIT_2), me);
+
+ if (me->IsNonMeleeSpellCasted(false))
+ me->InterruptNonMeleeSpells(false);
+
+ DoCast(me, SPELL_DISPERSE, true);
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_ionar(Creature* pCreature)
+{
+ return new boss_ionarAI(pCreature);
+}
+
+bool EffectDummyCreature_boss_ionar(Unit* /*pCaster*/, uint32 uiSpellId, uint32 uiEffIndex, Creature* pCreatureTarget)
+{
+ //always check spellid and effectindex
+ if (uiSpellId == SPELL_DISPERSE && uiEffIndex == 0)
+ {
+ if (pCreatureTarget->GetEntry() != NPC_IONAR)
+ return true;
+
+ for (uint8 i = 0; i < DATA_MAX_SPARKS; ++i)
+ pCreatureTarget->CastSpell(pCreatureTarget, SPELL_SUMMON_SPARK, true);
+
+ pCreatureTarget->AttackStop();
+ pCreatureTarget->SetVisibility(VISIBILITY_OFF);
+ pCreatureTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_DISABLE_MOVE);
+
+ pCreatureTarget->GetMotionMaster()->Clear();
+ pCreatureTarget->GetMotionMaster()->MoveIdle();
+
+ //always return true when we are handling this spell and effect
+ return true;
+ }
+ return false;
+}
+
+/*######
+## mob_spark_of_ionar
+######*/
+
+struct mob_spark_of_ionarAI : public ScriptedAI
+{
+ mob_spark_of_ionarAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiCheckTimer;
+
+ void Reset()
+ {
+ uiCheckTimer = 2*IN_MILISECONDS;
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ void MovementInform(uint32 uiType, uint32 uiPointId)
+ {
+ if (uiType != POINT_MOTION_TYPE || !pInstance)
+ return;
+
+ if (uiPointId == DATA_POINT_CALLBACK)
+ me->ForcedDespawn();
+ }
+
+ void DamageTaken(Unit * /*pDoneBy*/, uint32 &uiDamage)
+ {
+ uiDamage = 0;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ // Despawn if the encounter is not running
+ if (pInstance && pInstance->GetData(TYPE_IONAR) != IN_PROGRESS)
+ {
+ me->ForcedDespawn();
+ return;
+ }
+
+ // Prevent them to follow players through the whole instance
+ if (uiCheckTimer <= uiDiff)
+ {
+ if (pInstance)
+ {
+ Creature* pIonar = pInstance->instance->GetCreature(pInstance->GetData64(DATA_IONAR));
+ if (pIonar && pIonar->isAlive())
+ {
+ if (me->GetDistance(pIonar) > DATA_MAX_SPARK_DISTANCE)
+ {
+ Position pos;
+ pIonar->GetPosition(&pos);
+
+ me->SetSpeed(MOVE_RUN, 2.0f);
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MovePoint(DATA_POINT_CALLBACK, pos);
+ }
+ }
+ else
+ me->ForcedDespawn();
+ }
+ uiCheckTimer = 2*IN_MILISECONDS;
+ }
+ else
+ uiCheckTimer -= uiDiff;
+
+ // No melee attack at all!
+ }
+};
+
+CreatureAI* GetAI_mob_spark_of_ionar(Creature* pCreature)
+{
+ return new mob_spark_of_ionarAI(pCreature);
+}
+
+void AddSC_boss_ionar()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_ionar";
+ newscript->GetAI = &GetAI_boss_ionar;
+ newscript->pEffectDummyCreature = &EffectDummyCreature_boss_ionar;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_spark_of_ionar";
+ newscript->GetAI = &GetAI_mob_spark_of_ionar;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp b/src/server/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp
new file mode 100644
index 00000000000..f08c19efca2
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/halls_of_lightning/boss_loken.cpp
@@ -0,0 +1,222 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Boss Loken
+SD%Complete: 60%
+SDComment: Missing intro. Remove hack of Pulsing Shockwave when core supports. Aura is not working (59414)
+SDCategory: Halls of Lightning
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "halls_of_lightning.h"
+
+enum eEnums
+{
+ ACHIEV_TIMELY_DEATH_START_EVENT = 20384,
+
+ SAY_AGGRO = -1602018,
+ SAY_INTRO_1 = -1602019,
+ SAY_INTRO_2 = -1602020,
+ SAY_SLAY_1 = -1602021,
+ SAY_SLAY_2 = -1602022,
+ SAY_SLAY_3 = -1602023,
+ SAY_DEATH = -1602024,
+ SAY_NOVA_1 = -1602025,
+ SAY_NOVA_2 = -1602026,
+ SAY_NOVA_3 = -1602027,
+ SAY_75HEALTH = -1602028,
+ SAY_50HEALTH = -1602029,
+ SAY_25HEALTH = -1602030,
+ EMOTE_NOVA = -1602031,
+
+ SPELL_ARC_LIGHTNING = 52921,
+ SPELL_LIGHTNING_NOVA_N = 52960,
+ SPELL_LIGHTNING_NOVA_H = 59835,
+
+ SPELL_PULSING_SHOCKWAVE_N = 52961,
+ SPELL_PULSING_SHOCKWAVE_H = 59836,
+ SPELL_PULSING_SHOCKWAVE_AURA = 59414
+};
+
+/*######
+## Boss Loken
+######*/
+
+struct boss_lokenAI : public ScriptedAI
+{
+ boss_lokenAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ bool m_bIsAura;
+
+ uint32 m_uiArcLightning_Timer;
+ uint32 m_uiLightningNova_Timer;
+ uint32 m_uiPulsingShockwave_Timer;
+ uint32 m_uiResumePulsingShockwave_Timer;
+
+ uint32 m_uiHealthAmountModifier;
+
+ void Reset()
+ {
+ m_bIsAura = false;
+
+ m_uiArcLightning_Timer = 15000;
+ m_uiLightningNova_Timer = 20000;
+ m_uiPulsingShockwave_Timer = 2000;
+ m_uiResumePulsingShockwave_Timer = 15000;
+
+ m_uiHealthAmountModifier = 1;
+
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_LOKEN, NOT_STARTED);
+ m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMELY_DEATH_START_EVENT);
+ }
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(TYPE_LOKEN, IN_PROGRESS);
+ m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMELY_DEATH_START_EVENT);
+ }
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_LOKEN, DONE);
+ }
+
+ void KilledUnit(Unit* /*pVictim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (m_bIsAura)
+ {
+ // workaround for PULSING_SHOCKWAVE
+ if (m_uiPulsingShockwave_Timer <= uiDiff)
+ {
+ Map* pMap = me->GetMap();
+ if (pMap->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = pMap->GetPlayers();
+
+ if (PlayerList.isEmpty())
+ return;
+
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ if (i->getSource() && i->getSource()->isAlive() && i->getSource()->isTargetableForAttack())
+ {
+ int32 dmg;
+ float m_fDist = me->GetExactDist(i->getSource()->GetPositionX(), i->getSource()->GetPositionY(), i->getSource()->GetPositionZ());
+
+ dmg = DUNGEON_MODE(100, 150); // need to correct damage
+ if (m_fDist > 1.0f) // Further from 1 yard
+ dmg *= m_fDist;
+
+ me->CastCustomSpell(i->getSource(), DUNGEON_MODE(52942, 59837), &dmg, 0, 0, false);
+ }
+ }
+ m_uiPulsingShockwave_Timer = 2000;
+ } else m_uiPulsingShockwave_Timer -= uiDiff;
+ }
+ else
+ {
+ if (m_uiResumePulsingShockwave_Timer <= uiDiff)
+ {
+ //breaks at movement, can we assume when it's time, this spell is casted and also must stop movement?
+ DoCast(me, SPELL_PULSING_SHOCKWAVE_AURA, true);
+
+ DoCast(me, SPELL_PULSING_SHOCKWAVE_N); // need core support
+ m_bIsAura = true;
+ m_uiResumePulsingShockwave_Timer = 0;
+ }
+ else
+ m_uiResumePulsingShockwave_Timer -= uiDiff;
+ }
+
+ if (m_uiArcLightning_Timer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_ARC_LIGHTNING);
+
+ m_uiArcLightning_Timer = 15000 + rand()%1000;
+ }
+ else
+ m_uiArcLightning_Timer -= uiDiff;
+
+ if (m_uiLightningNova_Timer <= uiDiff)
+ {
+ DoScriptText(RAND(SAY_NOVA_1,SAY_NOVA_2,SAY_NOVA_3), me);
+ DoScriptText(EMOTE_NOVA, me);
+ DoCast(me, SPELL_LIGHTNING_NOVA_N);
+
+ m_bIsAura = false;
+ m_uiResumePulsingShockwave_Timer = DUNGEON_MODE(5000, 4000); // Pause Pulsing Shockwave aura
+ m_uiLightningNova_Timer = 20000 + rand()%1000;
+ }
+ else
+ m_uiLightningNova_Timer -= uiDiff;
+
+ // Health check
+ if ((me->GetHealth()*100 / me->GetMaxHealth()) < (100-(25*m_uiHealthAmountModifier)))
+ {
+ switch(m_uiHealthAmountModifier)
+ {
+ case 1: DoScriptText(SAY_75HEALTH, me); break;
+ case 2: DoScriptText(SAY_50HEALTH, me); break;
+ case 3: DoScriptText(SAY_25HEALTH, me); break;
+ }
+
+ ++m_uiHealthAmountModifier;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_loken(Creature* pCreature)
+{
+ return new boss_lokenAI(pCreature);
+}
+
+void AddSC_boss_loken()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_loken";
+ newscript->GetAI = &GetAI_boss_loken;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp b/src/server/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp
new file mode 100644
index 00000000000..184050e3103
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/halls_of_lightning/boss_volkhan.cpp
@@ -0,0 +1,478 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Boss Volkhan
+SD%Complete: 60%
+SDComment: Not considered complete. Some events may fail and need further development
+SDCategory: Halls of Lightning
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "halls_of_lightning.h"
+
+enum eEnums
+{
+ SAY_AGGRO = -1602032,
+ SAY_SLAY_1 = -1602033,
+ SAY_SLAY_2 = -1602034,
+ SAY_SLAY_3 = -1602035,
+ SAY_DEATH = -1602036,
+ SAY_STOMP_1 = -1602037,
+ SAY_STOMP_2 = -1602038,
+ SAY_FORGE_1 = -1602039,
+ SAY_FORGE_2 = -1602040,
+ EMOTE_TO_ANVIL = -1602041,
+ EMOTE_SHATTER = -1602042,
+
+ SPELL_HEAT_N = 52387,
+ SPELL_HEAT_H = 59528,
+ SPELL_SHATTERING_STOMP_N = 52237,
+ SPELL_SHATTERING_STOMP_H = 59529,
+
+ //unclear how "directions" of spells must be. Last, summoning GO, what is it for? Script depend on:
+ SPELL_TEMPER = 52238, //TARGET_SCRIPT boss->anvil
+ SPELL_TEMPER_DUMMY = 52654, //TARGET_SCRIPT anvil->boss
+
+ //SPELL_TEMPER_VISUAL = 52661, //summons GO
+
+ SPELL_SUMMON_MOLTEN_GOLEM = 52405,
+
+ //Molten Golem
+ SPELL_BLAST_WAVE = 23113,
+ SPELL_IMMOLATION_STRIKE_N = 52433,
+ SPELL_IMMOLATION_STRIKE_H = 59530,
+ SPELL_SHATTER_N = 52429,
+ SPELL_SHATTER_H = 59527,
+
+ NPC_VOLKHAN_ANVIL = 28823,
+ NPC_MOLTEN_GOLEM = 28695,
+ NPC_BRITTLE_GOLEM = 28681,
+
+ POINT_ID_ANVIL = 0,
+ MAX_GOLEM = 2,
+
+ ACHIEVEMENT_SHATTER_RESISTANT = 2042
+};
+
+/*######
+## Boss Volkhan
+######*/
+
+struct boss_volkhanAI : public ScriptedAI
+{
+ boss_volkhanAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ std::list<uint64> m_lGolemGUIDList;
+
+ bool m_bHasTemper;
+ bool m_bIsStriking;
+ bool m_bCanShatterGolem;
+
+ uint8 GolemsShattered;
+ uint32 m_uiPause_Timer;
+ uint32 m_uiShatteringStomp_Timer;
+ uint32 m_uiShatter_Timer;
+
+ uint32 m_uiHealthAmountModifier;
+
+ void Reset()
+ {
+ m_bIsStriking = false;
+ m_bHasTemper = false;
+ m_bCanShatterGolem = false;
+
+ m_uiPause_Timer = 3500;
+ m_uiShatteringStomp_Timer = 0;
+ m_uiShatter_Timer = 5000;
+ GolemsShattered = 0;
+
+ m_uiHealthAmountModifier = 1;
+
+ DespawnGolem();
+ m_lGolemGUIDList.clear();
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_VOLKHAN, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_VOLKHAN, IN_PROGRESS);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (me->Attack(pWho, true))
+ {
+ me->AddThreat(pWho, 0.0f);
+ me->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(me);
+
+ if (!m_bHasTemper)
+ me->GetMotionMaster()->MoveChase(pWho);
+ }
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ DespawnGolem();
+
+ if (m_pInstance)
+ m_pInstance->SetData(TYPE_VOLKHAN, DONE);
+
+ if (IsHeroic() && GolemsShattered < 5)
+ {
+ AchievementEntry const *AchievShatterResistant = GetAchievementStore()->LookupEntry(ACHIEVEMENT_SHATTER_RESISTANT);
+ if (AchievShatterResistant)
+ {
+ Map* pMap = me->GetMap();
+ if (pMap && pMap->IsDungeon())
+ {
+ Map::PlayerList const &players = pMap->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ itr->getSource()->CompletedAchievement(AchievShatterResistant);
+ }
+ }
+ }
+ }
+
+ void KilledUnit(Unit* /*pVictim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+
+ void DespawnGolem()
+ {
+ if (m_lGolemGUIDList.empty())
+ return;
+
+ for (std::list<uint64>::const_iterator itr = m_lGolemGUIDList.begin(); itr != m_lGolemGUIDList.end(); ++itr)
+ {
+ if (Creature* pTemp = Unit::GetCreature(*me, *itr))
+ {
+ if (pTemp->isAlive())
+ pTemp->ForcedDespawn();
+ }
+ }
+
+ m_lGolemGUIDList.clear();
+ }
+
+ void ShatterGolem()
+ {
+ if (m_lGolemGUIDList.empty())
+ return;
+
+ for (std::list<uint64>::const_iterator itr = m_lGolemGUIDList.begin(); itr != m_lGolemGUIDList.end(); ++itr)
+ {
+ if (Creature* pTemp = Unit::GetCreature(*me, *itr))
+ {
+ // only shatter brittle golems
+ if (pTemp->isAlive() && pTemp->GetEntry() == NPC_BRITTLE_GOLEM)
+ {
+ pTemp->CastSpell(pTemp, DUNGEON_MODE(SPELL_SHATTER_N, SPELL_SHATTER_H), false);
+ GolemsShattered += 1;
+ }
+ }
+ }
+ }
+
+ void SpellHit(Unit* /*pCaster*/, const SpellEntry* pSpell)
+ {
+ if (pSpell->Id == SPELL_TEMPER_DUMMY)
+ m_bIsStriking = true;
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ if (pSummoned->GetEntry() == NPC_MOLTEN_GOLEM)
+ {
+ m_lGolemGUIDList.push_back(pSummoned->GetGUID());
+
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ pSummoned->AI()->AttackStart(pTarget);
+
+ //why healing when just summoned?
+ pSummoned->CastSpell(pSummoned, DUNGEON_MODE(SPELL_HEAT_N, SPELL_HEAT_H), false, NULL, NULL, me->GetGUID());
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (m_bIsStriking)
+ {
+ if (m_uiPause_Timer <= uiDiff)
+ {
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
+ {
+ if (me->getVictim())
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+ }
+
+ m_bHasTemper = false;
+ m_bIsStriking = false;
+ m_uiPause_Timer = 3500;
+ }
+ else
+ m_uiPause_Timer -= uiDiff;
+
+ return;
+ }
+
+ // When to start shatter? After 60, 40 or 20% hp?
+ if (!m_bHasTemper && m_uiHealthAmountModifier >= 3)
+ {
+ if (m_uiShatteringStomp_Timer <= uiDiff)
+ {
+ //should he stomp even if he has no brittle golem to shatter?
+
+ DoScriptText(RAND(SAY_STOMP_1,SAY_STOMP_2), me);
+
+ DoCast(me, SPELL_SHATTERING_STOMP_N);
+
+ DoScriptText(EMOTE_SHATTER, me);
+
+ m_uiShatteringStomp_Timer = 30000;
+ m_bCanShatterGolem = true;
+ }
+ else
+ m_uiShatteringStomp_Timer -= uiDiff;
+ }
+
+ // Shatter Golems 3 seconds after Shattering Stomp
+ if (m_bCanShatterGolem)
+ {
+ if (m_uiShatter_Timer <= uiDiff)
+ {
+ ShatterGolem();
+ m_uiShatter_Timer = 3000;
+ m_bCanShatterGolem = false;
+ }
+ else
+ m_uiShatter_Timer -= uiDiff;
+ }
+
+ // Health check
+ if (!m_bCanShatterGolem && (me->GetHealth()*100 / me->GetMaxHealth()) < (100-(20*m_uiHealthAmountModifier)))
+ {
+ ++m_uiHealthAmountModifier;
+
+ if (me->IsNonMeleeSpellCasted(false))
+ me->InterruptNonMeleeSpells(false);
+
+ DoScriptText(RAND(SAY_FORGE_1,SAY_FORGE_2), me);
+
+ m_bHasTemper = true;
+
+ DoCast(me, SPELL_TEMPER, false);
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_volkhan(Creature* pCreature)
+{
+ return new boss_volkhanAI(pCreature);
+}
+
+bool EffectDummyCreature_boss_volkhan(Unit* pCaster, uint32 uiSpellId, uint32 uiEffIndex, Creature* pCreatureTarget)
+{
+ //always check spellid and effectindex
+ if (uiSpellId == SPELL_TEMPER_DUMMY && uiEffIndex == 0)
+ {
+ if (pCaster->GetEntry() != NPC_VOLKHAN_ANVIL || pCreatureTarget->GetEntry() != NPC_VOLKHAN)
+ return true;
+
+ for (uint8 i = 0; i < MAX_GOLEM; ++i)
+ {
+ pCreatureTarget->CastSpell(pCaster, SPELL_SUMMON_MOLTEN_GOLEM, true);
+ }
+
+ //always return true when we are handling this spell and effect
+ return true;
+ }
+
+ return false;
+}
+
+/*######
+## npc_volkhan_anvil
+######*/
+
+bool EffectDummyCreature_npc_volkhan_anvil(Unit* pCaster, uint32 uiSpellId, uint32 uiEffIndex, Creature* pCreatureTarget)
+{
+ //always check spellid and effectindex
+ if (uiSpellId == SPELL_TEMPER && uiEffIndex == 0)
+ {
+ if (pCaster->GetEntry() != NPC_VOLKHAN || pCreatureTarget->GetEntry() != NPC_VOLKHAN_ANVIL)
+ return true;
+
+ Creature *cre = CAST_CRE(pCaster);
+
+ DoScriptText(EMOTE_TO_ANVIL, pCaster);
+
+ float fX, fY, fZ;
+ pCreatureTarget->GetContactPoint(pCaster, fX, fY, fZ, INTERACTION_DISTANCE);
+
+ pCaster->AttackStop();
+
+ if (pCaster->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
+ pCaster->GetMotionMaster()->MovementExpired();
+
+ cre->GetMap()->CreatureRelocation(cre, fX, fY, fZ, pCreatureTarget->GetOrientation());
+ cre->SendMonsterMove(fX, fY, fZ, 0, cre->GetUnitMovementFlags(), 1);
+
+ pCreatureTarget->CastSpell(pCaster, SPELL_TEMPER_DUMMY, false);
+
+ //always return true when we are handling this spell and effect
+ return true;
+ }
+
+ return false;
+}
+
+/*######
+## mob_molten_golem
+######*/
+
+struct mob_molten_golemAI : public ScriptedAI
+{
+ mob_molten_golemAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ }
+
+ bool m_bIsFrozen;
+
+ uint32 m_uiBlast_Timer;
+ uint32 m_uiDeathDelay_Timer;
+ uint32 m_uiImmolation_Timer;
+
+ void Reset()
+ {
+ m_bIsFrozen = false;
+
+ m_uiBlast_Timer = 20000;
+ m_uiDeathDelay_Timer = 0;
+ m_uiImmolation_Timer = 5000;
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (me->Attack(pWho, true))
+ {
+ me->AddThreat(pWho, 0.0f);
+ me->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(me);
+
+ if (!m_bIsFrozen)
+ me->GetMotionMaster()->MoveChase(pWho);
+ }
+ }
+
+ void DamageTaken(Unit* /*pDoneBy*/, uint32 &uiDamage)
+ {
+ if (uiDamage > me->GetHealth())
+ {
+ me->UpdateEntry(NPC_BRITTLE_GOLEM);
+ me->SetHealth(1);
+ uiDamage = 0;
+ me->RemoveAllAuras();
+ me->AttackStop();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
+ if (me->IsNonMeleeSpellCasted(false))
+ me->InterruptNonMeleeSpells(false);
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
+ me->GetMotionMaster()->MovementExpired();
+ m_bIsFrozen = true;
+ }
+ }
+
+ void SpellHit(Unit* /*pCaster*/, const SpellEntry* pSpell)
+ {
+ //this is the dummy effect of the spells
+ if (pSpell->Id == SPELL_SHATTER_N || pSpell->Id == SPELL_SHATTER_H)
+ {
+ if (me->GetEntry() == NPC_BRITTLE_GOLEM)
+ me->ForcedDespawn();
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target or if we are frozen
+ if (!UpdateVictim() || m_bIsFrozen)
+ return;
+
+ if (m_uiBlast_Timer <= uiDiff)
+ {
+ DoCast(me, SPELL_BLAST_WAVE);
+ m_uiBlast_Timer = 20000;
+ }
+ else
+ m_uiBlast_Timer -= uiDiff;
+
+ if (m_uiImmolation_Timer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_IMMOLATION_STRIKE_N);
+ m_uiImmolation_Timer = 5000;
+ }
+ else
+ m_uiImmolation_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_molten_golem(Creature* pCreature)
+{
+ return new mob_molten_golemAI(pCreature);
+}
+
+void AddSC_boss_volkhan()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_volkhan";
+ newscript->GetAI = &GetAI_boss_volkhan;
+ newscript->pEffectDummyCreature = &EffectDummyCreature_boss_volkhan;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_volkhan_anvil";
+ newscript->pEffectDummyCreature = &EffectDummyCreature_npc_volkhan_anvil;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_molten_golem";
+ newscript->GetAI = &GetAI_mob_molten_golem;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h b/src/server/scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h
new file mode 100644
index 00000000000..d9739fdf888
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/halls_of_lightning/halls_of_lightning.h
@@ -0,0 +1,34 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
+
+#ifndef DEF_HALLS_OF_LIGHTNING_H
+#define DEF_HALLS_OF_LIGHTNING_H
+
+enum eTypes
+{
+ MAX_ENCOUNTER = 4,
+
+ DATA_BJARNGRIM = 1,
+ DATA_IONAR = 2,
+ DATA_LOKEN = 3,
+ DATA_VOLKHAN = 4,
+
+ TYPE_BJARNGRIM = 10,
+ TYPE_IONAR = 11,
+ TYPE_LOKEN = 12,
+ TYPE_VOLKHAN = 13,
+
+ NPC_BJARNGRIM = 28586,
+ NPC_VOLKHAN = 28587,
+ NPC_IONAR = 28546,
+ NPC_LOKEN = 28923,
+
+ GO_BJARNGRIM_DOOR = 191416, //_doors10
+ GO_VOLKHAN_DOOR = 191325, //_doors07
+ GO_IONAR_DOOR = 191326, //_doors05
+ GO_LOKEN_DOOR = 191324, //_doors02
+ GO_LOKEN_THRONE = 192654
+};
+
+#endif
diff --git a/src/server/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp b/src/server/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp
new file mode 100644
index 00000000000..46cd5c9cccc
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/halls_of_lightning/instance_halls_of_lightning.cpp
@@ -0,0 +1,248 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Instance_Halls_of_Lightning
+SD%Complete: 90%
+SDComment: All ready.
+SDCategory: Halls of Lightning
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "halls_of_lightning.h"
+
+/* Halls of Lightning encounters:
+0 - General Bjarngrim
+1 - Volkhan
+2 - Ionar
+3 - Loken
+*/
+
+struct instance_halls_of_lightning : public ScriptedInstance
+{
+ instance_halls_of_lightning(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+
+ uint32 m_auiEncounter[MAX_ENCOUNTER];
+
+ uint64 m_uiGeneralBjarngrimGUID;
+ uint64 m_uiIonarGUID;
+ uint64 m_uiLokenGUID;
+ uint64 m_uiVolkhanGUID;
+
+ uint64 m_uiBjarngrimDoorGUID;
+ uint64 m_uiVolkhanDoorGUID;
+ uint64 m_uiIonarDoorGUID;
+ uint64 m_uiLokenDoorGUID;
+ uint64 m_uiLokenGlobeGUID;
+
+ void Initialize()
+ {
+ memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+
+ m_uiGeneralBjarngrimGUID = 0;
+ m_uiVolkhanGUID = 0;
+ m_uiIonarGUID = 0;
+ m_uiLokenGUID = 0;
+
+ m_uiBjarngrimDoorGUID = 0;
+ m_uiVolkhanDoorGUID = 0;
+ m_uiIonarDoorGUID = 0;
+ m_uiLokenDoorGUID = 0;
+ m_uiLokenGlobeGUID = 0;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool /*add*/)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case NPC_BJARNGRIM:
+ m_uiGeneralBjarngrimGUID = pCreature->GetGUID();
+ break;
+ case NPC_VOLKHAN:
+ m_uiVolkhanGUID = pCreature->GetGUID();
+ break;
+ case NPC_IONAR:
+ m_uiIonarGUID = pCreature->GetGUID();
+ break;
+ case NPC_LOKEN:
+ m_uiLokenGUID = pCreature->GetGUID();
+ break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
+ {
+ switch(pGo->GetEntry())
+ {
+ case GO_BJARNGRIM_DOOR:
+ m_uiBjarngrimDoorGUID = pGo->GetGUID();
+ if (m_auiEncounter[0] == DONE)
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ else
+ pGo->SetGoState(GO_STATE_READY);
+ break;
+ case GO_VOLKHAN_DOOR:
+ m_uiVolkhanDoorGUID = pGo->GetGUID();
+ if (m_auiEncounter[1] == DONE)
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ else
+ pGo->SetGoState(GO_STATE_READY);
+ break;
+ case GO_IONAR_DOOR:
+ m_uiIonarDoorGUID = pGo->GetGUID();
+ if (m_auiEncounter[2] == DONE)
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ else
+ pGo->SetGoState(GO_STATE_READY);
+ break;
+ case GO_LOKEN_DOOR:
+ m_uiLokenDoorGUID = pGo->GetGUID();
+ if (m_auiEncounter[3] == DONE)
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ else
+ pGo->SetGoState(GO_STATE_READY);
+ break;
+ case GO_LOKEN_THRONE:
+ m_uiLokenGlobeGUID = pGo->GetGUID();
+ break;
+ }
+ }
+
+ void SetData(uint32 uiType, uint32 uiData)
+ {
+ switch(uiType)
+ {
+ case TYPE_BJARNGRIM:
+ if (uiData == DONE)
+ DoUseDoorOrButton(m_uiBjarngrimDoorGUID);
+ m_auiEncounter[0] = uiData;
+ break;
+ case TYPE_VOLKHAN:
+ if (uiData == DONE)
+ DoUseDoorOrButton(m_uiVolkhanDoorGUID);
+ m_auiEncounter[1] = uiData;
+ break;
+ case TYPE_IONAR:
+ if (uiData == DONE)
+ DoUseDoorOrButton(m_uiIonarDoorGUID);
+ m_auiEncounter[2] = uiData;
+ break;
+ case TYPE_LOKEN:
+ if (uiData == DONE)
+ {
+ DoUseDoorOrButton(m_uiLokenDoorGUID);
+
+ //Appears to be type 5 GO with animation. Need to figure out how this work, code below only placeholder
+ if (GameObject* pGlobe = instance->GetGameObject(m_uiLokenGlobeGUID))
+ pGlobe->SetGoState(GO_STATE_ACTIVE);
+ }
+ m_auiEncounter[3] = uiData;
+ break;
+ }
+
+ if (uiData == DONE)
+ SaveToDB();
+ }
+
+ uint32 GetData(uint32 uiType)
+ {
+ switch(uiType)
+ {
+ case TYPE_BJARNGRIM:
+ return m_auiEncounter[0];
+ case TYPE_VOLKHAN:
+ return m_auiEncounter[1];
+ case TYPE_IONAR:
+ return m_auiEncounter[2];
+ case TYPE_LOKEN:
+ return m_auiEncounter[3];
+ }
+ return 0;
+ }
+
+ uint64 GetData64(uint32 uiData)
+ {
+ switch(uiData)
+ {
+ case DATA_BJARNGRIM:
+ return m_uiGeneralBjarngrimGUID;
+ case DATA_VOLKHAN:
+ return m_uiVolkhanGUID;
+ case DATA_IONAR:
+ return m_uiIonarGUID;
+ case DATA_LOKEN:
+ return m_uiLokenGUID;
+ }
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "H L " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
+ << m_auiEncounter[2] << " " << m_auiEncounter[3];
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return saveStream.str();
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0, data1, data2, data3;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;
+
+ if (dataHead1 == 'H' && dataHead2 == 'L')
+ {
+ m_auiEncounter[0] = data0;
+ m_auiEncounter[1] = data1;
+ m_auiEncounter[2] = data2;
+ m_auiEncounter[3] = data3;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_halls_of_lightning(Map* pMap)
+{
+ return new instance_halls_of_lightning(pMap);
+}
+
+void AddSC_instance_halls_of_lightning()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_halls_of_lightning";
+ newscript->GetInstanceData = &GetInstanceData_instance_halls_of_lightning;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp b/src/server/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp
new file mode 100644
index 00000000000..0674b7c79eb
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/halls_of_stone/boss_krystallus.cpp
@@ -0,0 +1,148 @@
+/* Script Data Start
+SDName: Boss krystallus
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_krystallus' where entry = '';
+*** SQL END ***/
+#include "ScriptedPch.h"
+#include "halls_of_stone.h"
+
+enum Spells
+{
+ SPELL_BOULDER_TOSS = 50843,
+ H_SPELL_BOULDER_TOSS = 59742,
+ SPELL_GROUND_SPIKE = 59750,
+ SPELL_GROUND_SLAM = 50827,
+ SPELL_SHATTER = 50810,
+ H_SPELL_SHATTER = 61546,
+ SPELL_STOMP = 48131,
+ H_SPELL_STOMP = 59744
+};
+
+enum Yells
+{
+ SAY_AGGRO = -1599007,
+ SAY_KILL = -1599008,
+ SAY_DEATH = -1599009,
+ SAY_SHATTER = -1599010
+};
+
+struct boss_krystallusAI : public ScriptedAI
+{
+ boss_krystallusAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiBoulderTossTimer;
+ uint32 uiGroundSpikeTimer;
+ uint32 uiGroundSlamTimer;
+ uint32 uiShatterTimer;
+ uint32 uiStompTimer;
+
+ bool bIsSlam;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ bIsSlam = false;
+
+ uiBoulderTossTimer = 3000 + rand()%6000;
+ uiGroundSpikeTimer = 9000 + rand()%5000;
+ uiGroundSlamTimer = 15000 + rand()%3000;
+ uiStompTimer = 20000 + rand()%9000;
+ uiShatterTimer = 0;
+
+ if (pInstance)
+ pInstance->SetData(DATA_KRYSTALLUS_EVENT, NOT_STARTED);
+ }
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_KRYSTALLUS_EVENT, IN_PROGRESS);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiBoulderTossTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_BOULDER_TOSS);
+ uiBoulderTossTimer = 9000 + rand()%6000;
+ } else uiBoulderTossTimer -= diff;
+
+ if (uiGroundSpikeTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_GROUND_SPIKE);
+ uiGroundSpikeTimer = 12000 + rand()%5000;
+ } else uiGroundSpikeTimer -= diff;
+
+ if (uiStompTimer <= diff)
+ {
+ DoCast(me, SPELL_STOMP);
+ uiStompTimer = 20000 + rand()%9000;
+ } else uiStompTimer -= diff;
+
+ if (uiGroundSlamTimer <= diff)
+ {
+ DoCast(me, SPELL_GROUND_SLAM);
+ bIsSlam = true;
+ uiShatterTimer = 10000;
+ uiGroundSlamTimer = 15000 + rand()%3000;
+ } else uiGroundSlamTimer -= diff;
+
+ if (bIsSlam)
+ {
+ if (uiShatterTimer <= diff)
+ {
+ DoCast(me, SPELL_SHATTER);
+ bIsSlam = false;
+ } else uiShatterTimer -= diff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_KRYSTALLUS_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+ DoScriptText(SAY_KILL, me);
+ }
+};
+
+CreatureAI* GetAI_boss_krystallus(Creature* pCreature)
+{
+ return new boss_krystallusAI (pCreature);
+}
+
+void AddSC_boss_krystallus()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_krystallus";
+ newscript->GetAI = &GetAI_boss_krystallus;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp b/src/server/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp
new file mode 100644
index 00000000000..b3c3c675347
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/halls_of_stone/boss_maiden_of_grief.cpp
@@ -0,0 +1,166 @@
+/* Script Data Start
+SDName: Boss maiden_of_grief
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_maiden_of_grief' where entry = '';
+*** SQL END ***/
+#include "ScriptedPch.h"
+#include "halls_of_stone.h"
+
+enum Spells
+{
+ SPELL_PARTING_SORROW = 59723,
+ SPELL_STORM_OF_GRIEF_N = 50752,
+ SPELL_STORM_OF_GRIEF_H = 59772,
+ SPELL_SHOCK_OF_SORROW_N = 50760,
+ SPELL_SHOCK_OF_SORROW_H = 59726,
+ SPELL_PILLAR_OF_WOE_N = 50761,
+ SPELL_PILLAR_OF_WOE_H = 59727
+};
+
+enum Yells
+{
+ SAY_AGGRO = -1599000,
+ SAY_SLAY_1 = -1599001,
+ SAY_SLAY_2 = -1599002,
+ SAY_SLAY_3 = -1599003,
+ SAY_SLAY_4 = -1599004,
+ SAY_DEATH = -1599005,
+ SAY_STUN = -1599006
+};
+
+enum Achievements
+{
+ ACHIEV_GOOD_GRIEF_START_EVENT = 20383,
+};
+
+struct boss_maiden_of_griefAI : public ScriptedAI
+{
+ boss_maiden_of_griefAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = me->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 PartingSorrowTimer;
+ uint32 StormOfGriefTimer;
+ uint32 ShockOfSorrowTimer;
+ uint32 PillarOfWoeTimer;
+
+ void Reset()
+ {
+ PartingSorrowTimer = 25000 + rand()%5000;
+ StormOfGriefTimer = 10000;
+ ShockOfSorrowTimer = 20000+rand()%5000;
+ PillarOfWoeTimer = 5000 + rand()%10000;
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_MAIDEN_OF_GRIEF_EVENT, NOT_STARTED);
+ pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_GOOD_GRIEF_START_EVENT);
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ {
+ if (GameObject *pDoor = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_MAIDEN_DOOR)))
+ if (pDoor->GetGoState() == GO_STATE_READY)
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ pInstance->SetData(DATA_MAIDEN_OF_GRIEF_EVENT, IN_PROGRESS);
+ pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_GOOD_GRIEF_START_EVENT);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (IsHeroic())
+ {
+ if (PartingSorrowTimer <= diff)
+ {
+ Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
+
+ if (pTarget)
+ DoCast(pTarget, SPELL_PARTING_SORROW);
+
+ PartingSorrowTimer = 30000 + rand()%10000;
+ } else PartingSorrowTimer -= diff;
+ }
+
+ if (StormOfGriefTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_STORM_OF_GRIEF_N, true);
+ StormOfGriefTimer = 15000 + rand()%5000;
+ } else StormOfGriefTimer -= diff;
+
+ if (ShockOfSorrowTimer <= diff)
+ {
+ DoResetThreat();
+ DoScriptText(SAY_STUN, me);
+ DoCast(me, SPELL_SHOCK_OF_SORROW_N);
+ ShockOfSorrowTimer = 20000 + rand()%10000;
+ } else ShockOfSorrowTimer -= diff;
+
+ if (PillarOfWoeTimer <= diff)
+ {
+ Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
+
+ if (pTarget)
+ DoCast(pTarget, SPELL_PILLAR_OF_WOE_N);
+ else
+ DoCast(me->getVictim(), SPELL_PILLAR_OF_WOE_N);
+
+ PillarOfWoeTimer = 5000 + rand()%20000;
+ } else PillarOfWoeTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_MAIDEN_OF_GRIEF_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3,SAY_SLAY_4), me);
+ }
+};
+
+CreatureAI* GetAI_boss_maiden_of_grief(Creature* pCreature)
+{
+ return new boss_maiden_of_griefAI (pCreature);
+}
+
+void AddSC_boss_maiden_of_grief()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_maiden_of_grief";
+ newscript->GetAI = &GetAI_boss_maiden_of_grief;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp b/src/server/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp
new file mode 100644
index 00000000000..68c3e34e6bf
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/halls_of_stone/boss_sjonnir.cpp
@@ -0,0 +1,300 @@
+/* Script Data Start
+SDName: Boss sjonnir
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_sjonnir' where entry = '';
+*** SQL END ***/
+#include "ScriptedPch.h"
+#include "halls_of_stone.h"
+
+enum Spells
+{
+ SPELL_LIGHTING_RING = 51849, //Periodic Trigger (interval 2s) spell = 50841
+ H_SPELL_LIGHTING_RING = 59861, //Periodic Trigger (interval 2s) spell = 59849
+ SPELL_LIGHTING_RING_1 = 50840, //Periodic Trigger (interval 2s) spell = 50841
+ H_SPELL_LIGHTING_RING_1 = 59848, //Periodic Trigger (interval 2s) spell = 59849
+ SPELL_STATIC_CHARGE = 50834, //Periodic Trigger 2s interval, spell =50835
+ H_SPELL_STATIC_CHARGE = 59846, //Periodic Trigger 2s interval, spell =50847
+ SPELL_CHAIN_LIGHTING = 50830,
+ H_SPELL_CHAIN_LIGHTING = 59844,
+ SPELL_LIGHTING_SHIELD = 50831,
+ H_SPELL_LIGHTING_SHIELD = 59845,
+ SPELL_FRENZY = 28747
+};
+
+enum Yells
+{
+ SAY_AGGRO = -1599011,
+ SAY_SLAY_1 = -1599012,
+ SAY_SLAY_2 = -1599013,
+ SAY_SLAY_3 = -1599014,
+ SAY_DEATH = -1599015
+};
+
+#define EMOTE_GENERIC_FRENZY -1000002
+
+enum SjonnirCreatures
+{
+ CREATURE_FORGED_IRON_TROGG = 27979,
+ CREATURE_MALFORMED_OOZE = 27981,
+ CREATURE_FORGED_IRON_DWARF = 27982,
+ CREATURE_IRON_SLUDGE = 28165
+};
+
+enum Misc
+{
+ DATA_TIME_BEFORE_OOZE = 150000, //2min 30 secs
+ ACHIEV_ABUSE_THE_OOZE = 2155
+};
+
+struct Locations
+{
+ float x, y, z;
+};
+
+static Locations PipeLocations[] =
+{
+ {1295.44, 734.07, 200.3}, //left
+ {1297.7, 595.6, 199.9} //right
+};
+
+static Locations CenterPoint = {1295.21, 667.157, 189.691};
+
+struct boss_sjonnirAI : public ScriptedAI
+{
+ boss_sjonnirAI(Creature *c) : ScriptedAI(c), lSummons(me)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ bool bIsFrenzy;
+
+ uint32 uiChainLightningTimer;
+ uint32 uiLightningShieldTimer;
+ uint32 uiStaticChargeTimer;
+ uint32 uiLightningRingTimer;
+ uint32 uiSummonTimer;
+ uint32 uiFrenzyTimer;
+ uint32 uiEncounterTimer;
+ uint32 uiKilledIronSludges;
+
+ SummonList lSummons;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ bIsFrenzy = false;
+
+ uiEncounterTimer = 0;
+ uiChainLightningTimer = 3000 + rand()%5000;
+ uiLightningShieldTimer = 20000 + rand()%5000;
+ uiStaticChargeTimer = 20000 + rand()%5000;
+ uiLightningRingTimer = 30000 + rand()%5000;
+ uiSummonTimer = 5000;
+ uiFrenzyTimer = 300000; //5 minutes
+ uiKilledIronSludges = 0;
+
+ lSummons.DespawnAll();
+
+ if (pInstance)
+ pInstance->SetData(DATA_SJONNIR_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ uiEncounterTimer = 0;
+
+ if (pInstance)
+ {
+ if (GameObject *pDoor = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_SJONNIR_DOOR)))
+ if (pDoor->GetGoState() == GO_STATE_READY)
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ pInstance->SetData(DATA_SJONNIR_EVENT, IN_PROGRESS);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiChainLightningTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_CHAIN_LIGHTING);
+ uiChainLightningTimer = 10000 + rand()%5000;
+ } else uiChainLightningTimer -= diff;
+
+ if (uiLightningShieldTimer <= diff)
+ {
+ DoCast(me, SPELL_LIGHTING_SHIELD);
+ uiLightningShieldTimer -= diff;
+ }
+
+ if (uiStaticChargeTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_STATIC_CHARGE);
+ uiStaticChargeTimer = 20000 + rand()%5000;
+ } uiStaticChargeTimer -= diff;
+
+ if (uiLightningRingTimer <= diff)
+ {
+ if (me->IsNonMeleeSpellCasted(false))
+ me->InterruptNonMeleeSpells(false);
+ DoCast(me, SPELL_LIGHTING_RING);
+ uiLightningRingTimer = 30000 + rand()%5000;
+ } else uiLightningRingTimer -= diff;
+
+ if (uiSummonTimer <= diff)
+ {
+ uint32 uiSummonPipe = rand()%2;
+ me->SummonCreature(uiEncounterTimer > DATA_TIME_BEFORE_OOZE ? CREATURE_MALFORMED_OOZE :
+ RAND(CREATURE_FORGED_IRON_DWARF,CREATURE_FORGED_IRON_TROGG),
+ PipeLocations[uiSummonPipe].x, PipeLocations[uiSummonPipe].y, PipeLocations[uiSummonPipe].z, 0.0f,
+ TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
+ uiSummonTimer = 20000;
+ } else uiSummonTimer -= diff;
+
+ if (!bIsFrenzy)
+ {
+ if (uiFrenzyTimer <= diff)
+ {
+ DoCast(me, SPELL_FRENZY);
+ bIsFrenzy = true;
+ }
+ else uiFrenzyTimer -= diff;
+ }
+
+ uiEncounterTimer +=diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ summon->GetMotionMaster()->MovePoint(0, CenterPoint.x, CenterPoint.y, CenterPoint.z);
+ /*if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ summon->AI()->AttackStart(pTarget);*/
+ lSummons.Summon(summon);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ lSummons.DespawnAll();
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_SJONNIR_EVENT, DONE);
+ if (IsHeroic() && uiKilledIronSludges > 4)
+ pInstance->DoCompleteAchievement(ACHIEV_ABUSE_THE_OOZE);
+ }
+ }
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+
+ void KilledIronSludge()
+ {
+ ++uiKilledIronSludges;
+ }
+};
+
+CreatureAI* GetAI_boss_sjonnir(Creature* pCreature)
+{
+ return new boss_sjonnirAI (pCreature);
+}
+
+struct mob_malformed_oozeAI : public ScriptedAI
+{
+ mob_malformed_oozeAI(Creature *c) : ScriptedAI(c) {}
+
+ uint32 uiMergeTimer;
+
+ void Reset()
+ {
+ uiMergeTimer = 10000;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (uiMergeTimer <= diff)
+ {
+ if (Creature* pTemp = me->FindNearestCreature(CREATURE_MALFORMED_OOZE, 3.0f, true))
+ {
+ DoSpawnCreature(CREATURE_IRON_SLUDGE, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000);
+ pTemp->DisappearAndDie();
+ me->DisappearAndDie();
+ }
+ uiMergeTimer = 3000;
+ } else uiMergeTimer -= diff;
+
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_malformed_ooze(Creature* pCreature)
+{
+ return new mob_malformed_oozeAI(pCreature);
+}
+
+struct mob_iron_sludgeAI : public ScriptedAI
+{
+ mob_iron_sludgeAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ if (pInstance)
+ if (Creature* pSjonnir = Unit::GetCreature(*me, pInstance->GetData64(DATA_SJONNIR)))
+ CAST_AI(boss_sjonnirAI, pSjonnir->AI())->KilledIronSludge();
+ }
+};
+
+CreatureAI* GetAI_mob_iron_sludge(Creature* pCreature)
+{
+ return new mob_iron_sludgeAI(pCreature);
+}
+
+void AddSC_boss_sjonnir()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_sjonnir";
+ newscript->GetAI = &GetAI_boss_sjonnir;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_malformed_ooze";
+ newscript->GetAI = &GetAI_mob_malformed_ooze;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_iron_sludge";
+ newscript->GetAI = &GetAI_mob_iron_sludge;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp b/src/server/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp
new file mode 100644
index 00000000000..8febdaab879
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.cpp
@@ -0,0 +1,724 @@
+#include "ScriptedPch.h"
+#include "ScriptedEscortAI.h"
+#include "halls_of_stone.h"
+
+enum Texts
+{
+ SAY_KILL_1 = -1599016,
+ SAY_KILL_2 = -1599017,
+ SAY_KILL_3 = -1599018,
+ SAY_LOW_HEALTH = -1599019,
+ SAY_DEATH = -1599020,
+ SAY_PLAYER_DEATH_1 = -1599021,
+ SAY_PLAYER_DEATH_2 = -1599022,
+ SAY_PLAYER_DEATH_3 = -1599023,
+ SAY_ESCORT_START = -1599024,
+
+ SAY_SPAWN_DWARF = -1599025,
+ SAY_SPAWN_TROGG = -1599026,
+ SAY_SPAWN_OOZE = -1599027,
+ SAY_SPAWN_EARTHEN = -1599028,
+
+ SAY_EVENT_INTRO_1 = -1599029,
+ SAY_EVENT_INTRO_2 = -1599030,
+ SAY_EVENT_INTRO_3_ABED = -1599031,
+
+ SAY_EVENT_A_1 = -1599032,
+ SAY_EVENT_A_2_KADD = -1599033,
+ SAY_EVENT_A_3 = -1599034,
+
+ SAY_EVENT_B_1 = -1599035,
+ SAY_EVENT_B_2_MARN = -1599036,
+ SAY_EVENT_B_3 = -1599037,
+
+ SAY_EVENT_C_1 = -1599038,
+ SAY_EVENT_C_2_ABED = -1599039,
+ SAY_EVENT_C_3 = -1599040,
+
+ SAY_EVENT_D_1 = -1599041,
+ SAY_EVENT_D_2_ABED = -1599042,
+ SAY_EVENT_D_3 = -1599043,
+ SAY_EVENT_D_4_ABED = -1599044,
+
+ SAY_EVENT_END_01 = -1599045,
+ SAY_EVENT_END_02 = -1599046,
+ SAY_EVENT_END_03_ABED = -1599047,
+ SAY_EVENT_END_04 = -1599048,
+ SAY_EVENT_END_05_ABED = -1599049,
+ SAY_EVENT_END_06 = -1599050,
+ SAY_EVENT_END_07_ABED = -1599051,
+ SAY_EVENT_END_08 = -1599052,
+ SAY_EVENT_END_09_KADD = -1599053,
+ SAY_EVENT_END_10 = -1599054,
+ SAY_EVENT_END_11_KADD = -1599055,
+ SAY_EVENT_END_12 = -1599056,
+ SAY_EVENT_END_13_KADD = -1599057,
+ SAY_EVENT_END_14 = -1599058,
+ SAY_EVENT_END_15_MARN = -1599059,
+ SAY_EVENT_END_16 = -1599060,
+ SAY_EVENT_END_17_MARN = -1599061,
+ SAY_EVENT_END_18 = -1599062,
+ SAY_EVENT_END_19_MARN = -1599063,
+ SAY_EVENT_END_20 = -1599064,
+ SAY_EVENT_END_21_ABED = -1599065,
+
+ SAY_VICTORY_SJONNIR_1 = -1599066,
+ SAY_VICTORY_SJONNIR_2 = -1599067,
+
+ SAY_ENTRANCE_MEET = -1599068,
+
+ TEXT_ID_START = 13100,
+ TEXT_ID_PROGRESS = 13101
+};
+
+enum BrannCreatures
+{
+ CREATURE_TRIBUNAL_OF_THE_AGES = 28234,
+ CREATURE_BRANN_BRONZEBEARD = 28070,
+ CREATURE_DARK_MATTER_TARGET = 28237,
+ CREATURE_SEARING_GAZE_TARGET = 28265,
+ CREATURE_DARK_RUNE_PROTECTOR = 27983,
+ CREATURE_DARK_RUNE_STORMCALLER = 27984,
+ CREATURE_IRON_GOLEM_CUSTODIAN = 27985,
+};
+
+enum Spells
+{
+ SPELL_STEALTH = 58506,
+ //Kadrak
+ SPELL_GLARE_OF_THE_TRIBUNAL = 50988,
+ H_SPELL_GLARE_OF_THE_TRIBUNAL = 59868,
+ //Marnak
+ SPELL_DARK_MATTER = 51012,
+ H_SPELL_DARK_MATTER = 59868,
+ //Abedneum
+ SPELL_SEARING_GAZE = 51136,
+ H_SPELL_SEARING_GAZE = 59867
+};
+
+enum Quests
+{
+ QUEST_HALLS_OF_STONE = 13207
+};
+
+enum Achievements
+{
+ ACHIEV_BRANN_SPANKIN_NEW = 2154
+};
+
+#define GOSSIP_ITEM_START "Brann, it would be our honor!"
+#define GOSSIP_ITEM_PROGRESS "Let's move Brann, enough of the history lessons!"
+
+static Position SpawnLocations[]=
+{
+ {946.992, 397.016, 208.374},
+ {960.748, 382.944, 208.374},
+};
+
+struct mob_tribuna_controllerAI : public ScriptedAI
+{
+ mob_tribuna_controllerAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ SetCombatMovement(false);
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiKaddrakEncounterTimer;
+ uint32 uiMarnakEncounterTimer;
+ uint32 uiAbedneumEncounterTimer;
+
+ bool bKaddrakActivated;
+ bool bMarnakActivated;
+ bool bAbedneumActivated;
+
+ std::list<uint64> KaddrakGUIDList;
+
+ void Reset()
+ {
+ uiKaddrakEncounterTimer = 1500;
+ uiMarnakEncounterTimer = 10000;
+ uiAbedneumEncounterTimer = 10000;
+
+ bKaddrakActivated = false;
+ bMarnakActivated = false;
+ bAbedneumActivated = false;
+
+ if (pInstance)
+ {
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_KADDRAK),false);
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_MARNAK),false);
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_ABEDNEUM),false);
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_SKY_FLOOR),false);
+ }
+
+ KaddrakGUIDList.clear();
+ }
+
+ void UpdateFacesList()
+ {
+ /*GetCreatureListWithEntryInGrid(lKaddrakGUIDList, me, CREATURE_KADDRAK, 50.0f);
+ if (!lKaddrakGUIDList.empty())
+ {
+ uint32 uiPositionCounter = 0;
+ for (std::list<Creature*>::const_iterator itr = lKaddrakGUIDList.begin(); itr != lKaddrakGUIDList.end(); ++itr)
+ {
+ if ((*itr)->isAlive())
+ {
+ if (uiPositionCounter == 0)
+ {
+ (*itr)->GetMap()->CreatureRelocation((*itr), 927.265, 333.200, 218.780, (*itr)->GetOrientation());
+ (*itr)->SendMonsterMove(927.265, 333.200, 218.780, 0, (*itr)->GetMovementFlags(), 1);
+ }
+ else
+ {
+ (*itr)->GetMap()->CreatureRelocation((*itr), 921.745, 328.076, 218.780, (*itr)->GetOrientation());
+ (*itr)->SendMonsterMove(921.745, 328.076, 218.780, 0, (*itr)->GetMovementFlags(), 1);
+ }
+ }
+ ++uiPositionCounter;
+ }
+ }*/
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (bKaddrakActivated)
+ {
+ if (uiKaddrakEncounterTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ if (!KaddrakGUIDList.empty())
+ for (std::list<uint64>::const_iterator itr = KaddrakGUIDList.begin(); itr != KaddrakGUIDList.end(); ++itr)
+ {
+ if (Creature *pKaddrak = Unit::GetCreature(*me, *itr))
+ {
+ if (pKaddrak->isAlive())
+ pKaddrak->CastSpell(pTarget, DUNGEON_MODE(SPELL_GLARE_OF_THE_TRIBUNAL, H_SPELL_GLARE_OF_THE_TRIBUNAL), true);
+ }
+ }
+ uiKaddrakEncounterTimer = 1500;
+ } else uiKaddrakEncounterTimer -= diff;
+ }
+ if (bMarnakActivated)
+ {
+ if (uiMarnakEncounterTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ {
+ if (Creature* pSummon = me->SummonCreature(CREATURE_DARK_MATTER_TARGET, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1000))
+ {
+ pSummon->SetDisplayId(11686);
+ pSummon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pSummon->CastSpell(pTarget, DUNGEON_MODE(SPELL_DARK_MATTER, H_SPELL_DARK_MATTER), true);
+ }
+ }
+ uiMarnakEncounterTimer = 30000 + rand()%1000;
+ } else uiMarnakEncounterTimer -= diff;
+ }
+ if (bAbedneumActivated)
+ {
+ if (uiAbedneumEncounterTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ {
+ if (Creature* pSummon = me->SummonCreature(CREATURE_SEARING_GAZE_TARGET, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1000))
+ {
+ pSummon->SetDisplayId(11686);
+ pSummon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pSummon->CastSpell(pTarget, DUNGEON_MODE(SPELL_SEARING_GAZE, H_SPELL_SEARING_GAZE), true);
+ }
+ }
+ uiAbedneumEncounterTimer = 30000 + rand()%1000;
+ } else uiAbedneumEncounterTimer -= diff;
+ }
+ }
+};
+
+struct npc_brann_hosAI : public npc_escortAI
+{
+ npc_brann_hosAI(Creature *c) : npc_escortAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiStep;
+ uint32 uiPhaseTimer;
+
+ uint64 uiControllerGUID;
+ std::list<uint64> lDwarfGUIDList;
+
+ ScriptedInstance* pInstance;
+
+ bool bIsBattle;
+ bool bIsLowHP;
+ bool bHasBeenDamaged;
+
+ void Reset()
+ {
+ if (!HasEscortState(STATE_ESCORT_ESCORTING))
+ {
+ bIsLowHP = false;
+ bIsBattle = false;
+ bHasBeenDamaged = false;
+ uiStep = 0;
+ uiPhaseTimer = 0;
+ uiControllerGUID = 0;
+
+ DespawnDwarf();
+
+ if (pInstance)
+ pInstance->SetData(DATA_BRANN_EVENT, NOT_STARTED);
+ }
+ }
+
+ void DespawnDwarf()
+ {
+ if (lDwarfGUIDList.empty())
+ return;
+ for (std::list<uint64>::const_iterator itr = lDwarfGUIDList.begin(); itr != lDwarfGUIDList.end(); ++itr)
+ {
+ Creature* pTemp = Unit::GetCreature(*me, pInstance ? (*itr) : 0);
+ if (pTemp && pTemp->isAlive())
+ pTemp->ForcedDespawn();
+ }
+ lDwarfGUIDList.clear();
+ }
+
+ void WaypointReached(uint32 uiPointId)
+ {
+ switch(uiPointId)
+ {
+ case 7:
+ if (Creature* pCreature = GetClosestCreatureWithEntry(me, CREATURE_TRIBUNAL_OF_THE_AGES, 100.0f))
+ {
+ if (!pCreature->isAlive())
+ pCreature->Respawn();
+ CAST_AI(mob_tribuna_controllerAI, pCreature->AI())->UpdateFacesList();
+ uiControllerGUID = pCreature->GetGUID();
+ }
+ break;
+ case 13:
+ DoScriptText(SAY_EVENT_INTRO_1, me);
+ SetEscortPaused(true);
+ JumpToNextStep(20000);
+ break;
+ case 17:
+ DoScriptText(SAY_EVENT_INTRO_2, me);
+ if (pInstance)
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_TRIBUNAL_CONSOLE),true);
+ me->SetStandState(UNIT_STAND_STATE_KNEEL);
+ SetEscortPaused(true);
+ JumpToNextStep(8500);
+ break;
+ case 18:
+ SetEscortPaused(true);
+ break;
+ }
+ }
+
+ void SpawnDwarf(uint32 uiType)
+ {
+ switch(uiType)
+ {
+ case 1:
+ {
+ uint32 uiSpawnNumber = DUNGEON_MODE(2,3);
+ for (uint8 i = 0; i < uiSpawnNumber; ++i)
+ me->SummonCreature(CREATURE_DARK_RUNE_PROTECTOR, SpawnLocations[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
+ me->SummonCreature(CREATURE_DARK_RUNE_STORMCALLER, SpawnLocations[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
+ break;
+ }
+ case 2:
+ for (uint8 i = 0; i < 2; ++i)
+ me->SummonCreature(CREATURE_DARK_RUNE_STORMCALLER, SpawnLocations[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
+ break;
+ case 3:
+ me->SummonCreature(CREATURE_IRON_GOLEM_CUSTODIAN, SpawnLocations[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
+ break;
+ }
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ lDwarfGUIDList.push_back(pSummoned->GetGUID());
+ pSummoned->AddThreat(me, 0.0f);
+ pSummoned->AI()->AttackStart(me);
+ }
+
+ void JumpToNextStep(uint32 uiTimer)
+ {
+ uiPhaseTimer = uiTimer;
+ ++uiStep;
+ }
+
+ void StartWP()
+ {
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ SetEscortPaused(false);
+ uiStep = 1;
+ Start();
+ }
+
+ void DamageTaken(Unit* /*done_by*/, uint32 & /*damage*/)
+ {
+ if (!bHasBeenDamaged)
+ bHasBeenDamaged = true;
+ }
+
+ void UpdateEscortAI(const uint32 uiDiff)
+ {
+ if (uiPhaseTimer <= uiDiff)
+ {
+ switch(uiStep)
+ {
+ case 1:
+ if (pInstance)
+ {
+ if (pInstance->GetData(DATA_BRANN_EVENT) != NOT_STARTED)
+ return;
+ pInstance->SetData(DATA_BRANN_EVENT, IN_PROGRESS);
+ }
+ bIsBattle = false;
+ DoScriptText(SAY_ESCORT_START, me);
+ SetRun(true);
+ JumpToNextStep(0);
+ break;
+ case 3:
+ SetEscortPaused(false);
+ JumpToNextStep(0);
+ break;
+ case 5:
+ if (pInstance)
+ if (Creature* pTemp = (Unit::GetCreature(*me, pInstance->GetData64(DATA_ABEDNEUM))))
+ DoScriptText(SAY_EVENT_INTRO_3_ABED, pTemp);
+ JumpToNextStep(8500);
+ break;
+ case 6:
+ DoScriptText(SAY_EVENT_A_1, me);
+ JumpToNextStep(6500);
+ break;
+ case 7:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_KADDRAK)))
+ DoScriptText(SAY_EVENT_A_2_KADD, pTemp);
+ JumpToNextStep(12500);
+ break;
+ case 8:
+ DoScriptText(SAY_EVENT_A_3, me);
+ if (pInstance)
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_KADDRAK),true);
+ if (Creature* pTemp = Unit::GetCreature(*me, uiControllerGUID))
+ CAST_AI(mob_tribuna_controllerAI, pTemp->AI())->bKaddrakActivated = true;
+ JumpToNextStep(5000);
+ break;
+ case 9:
+ me->SetReactState(REACT_PASSIVE);
+ SpawnDwarf(1);
+ JumpToNextStep(20000);
+ break;
+ case 10:
+ DoScriptText(SAY_EVENT_B_1, me);
+ JumpToNextStep(6000);
+ break;
+ case 11:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_MARNAK)))
+ DoScriptText(SAY_EVENT_B_2_MARN, pTemp);
+ SpawnDwarf(1);
+ JumpToNextStep(20000);
+ break;
+ case 12:
+ DoScriptText(SAY_EVENT_B_3, me);
+ if (pInstance)
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_MARNAK),true);
+ if (Creature* pTemp = Unit::GetCreature(*me, uiControllerGUID))
+ CAST_AI(mob_tribuna_controllerAI, pTemp->AI())->bMarnakActivated = true;
+ JumpToNextStep(10000);
+ break;
+ case 13:
+ SpawnDwarf(1);
+ JumpToNextStep(10000);
+ break;
+ case 14:
+ SpawnDwarf(2);
+ JumpToNextStep(20000);
+ break;
+ case 15:
+ DoScriptText(SAY_EVENT_C_1, me);
+ SpawnDwarf(1);
+ JumpToNextStep(10000);
+ break;
+ case 16:
+ SpawnDwarf(2);
+ JumpToNextStep(20000);
+ break;
+ case 17:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_C_2_ABED, pTemp);
+ SpawnDwarf(1);
+ JumpToNextStep(20000);
+ break;
+ case 18:
+ DoScriptText(SAY_EVENT_C_3, me);
+ if (pInstance)
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_ABEDNEUM),true);
+ if (Creature* pTemp = Unit::GetCreature(*me, uiControllerGUID))
+ CAST_AI(mob_tribuna_controllerAI, pTemp->AI())->bAbedneumActivated = true;
+ JumpToNextStep(5000);
+ break;
+ case 19:
+ SpawnDwarf(2);
+ JumpToNextStep(10000);
+ break;
+ case 20:
+ SpawnDwarf(1);
+ JumpToNextStep(15000);
+ break;
+ case 21:
+ DoScriptText(SAY_EVENT_D_1, me);
+ SpawnDwarf(3);
+ JumpToNextStep(20000);
+ break;
+ case 22:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_D_2_ABED, pTemp);
+ SpawnDwarf(1);
+ JumpToNextStep(5000);
+ break;
+ case 23:
+ SpawnDwarf(2);
+ JumpToNextStep(15000);
+ break;
+ case 24:
+ DoScriptText(SAY_EVENT_D_3, me);
+ SpawnDwarf(3);
+ JumpToNextStep(5000);
+ break;
+ case 25:
+ SpawnDwarf(1);
+ JumpToNextStep(5000);
+ break;
+ case 26:
+ SpawnDwarf(2);
+ JumpToNextStep(10000);
+ break;
+ case 27:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_D_4_ABED, pTemp);
+ SpawnDwarf(1);
+ JumpToNextStep(10000);
+ break;
+ case 28:
+ me->SetReactState(REACT_DEFENSIVE);
+ DoScriptText(SAY_EVENT_END_01, me);
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ if (pInstance)
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_SKY_FLOOR),true);
+ if (Creature* pTemp = Unit::GetCreature(*me, uiControllerGUID))
+ pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ bIsBattle = true;
+ SetEscortPaused(false);
+ JumpToNextStep(6500);
+ break;
+ case 29:
+ DoScriptText(SAY_EVENT_END_02, me);
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_BRANN_EVENT, DONE);
+
+ // Achievement criteria is with spell 59046 which does not exist.
+ // There is thus no way it can be given by casting the spell on the players.
+ pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 59046);
+
+ if (!bHasBeenDamaged)
+ pInstance->DoCompleteAchievement(ACHIEV_BRANN_SPANKIN_NEW);
+ }
+
+ JumpToNextStep(5500);
+ break;
+ case 30:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_END_03_ABED, pTemp);
+ JumpToNextStep(8500);
+ break;
+ case 31:
+ DoScriptText(SAY_EVENT_END_04, me);
+ JumpToNextStep(11500);
+ break;
+ case 32:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_END_05_ABED, pTemp);
+ JumpToNextStep(11500);
+ break;
+ case 33:
+ DoScriptText(SAY_EVENT_END_06, me);
+ JumpToNextStep(4500);
+ break;
+ case 34:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_END_07_ABED, pTemp);
+ JumpToNextStep(22500);
+ break;
+ case 35:
+ DoScriptText(SAY_EVENT_END_08, me);
+ JumpToNextStep(7500);
+ break;
+ case 36:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_KADDRAK)))
+ DoScriptText(SAY_EVENT_END_09_KADD, pTemp);
+ JumpToNextStep(18500);
+ break;
+ case 37:
+ DoScriptText(SAY_EVENT_END_10, me);
+ JumpToNextStep(5500);
+ break;
+ case 38:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_KADDRAK)))
+ DoScriptText(SAY_EVENT_END_11_KADD, pTemp);
+ JumpToNextStep(20500);
+ break;
+ case 39:
+ DoScriptText(SAY_EVENT_END_12, me);
+ JumpToNextStep(2500);
+ break;
+ case 40:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_KADDRAK)))
+ DoScriptText(SAY_EVENT_END_13_KADD, pTemp);
+ JumpToNextStep(19500);
+ break;
+ case 41:
+ DoScriptText(SAY_EVENT_END_14, me);
+ JumpToNextStep(10500);
+ break;
+ case 42:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_MARNAK)))
+ DoScriptText(SAY_EVENT_END_15_MARN, pTemp);
+ JumpToNextStep(6500);
+ break;
+ case 43:
+ DoScriptText(SAY_EVENT_END_16, me);
+ JumpToNextStep(6500);
+ break;
+ case 44:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_MARNAK)))
+ DoScriptText(SAY_EVENT_END_17_MARN, pTemp);
+ JumpToNextStep(25500);
+ break;
+ case 45:
+ DoScriptText(SAY_EVENT_END_18, me);
+ JumpToNextStep(23500);
+ break;
+ case 46:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_MARNAK)))
+ DoScriptText(SAY_EVENT_END_19_MARN, pTemp);
+ JumpToNextStep(3500);
+ break;
+ case 47:
+ DoScriptText(SAY_EVENT_END_20, me);
+ JumpToNextStep(8500);
+ break;
+ case 48:
+ if (pInstance)
+ if (Creature* pTemp = Unit::GetCreature(*me, pInstance->GetData64(DATA_ABEDNEUM)))
+ DoScriptText(SAY_EVENT_END_21_ABED, pTemp);
+ JumpToNextStep(5500);
+ break;
+ case 49:
+ {
+ if (pInstance)
+ {
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_KADDRAK),false);
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_MARNAK),false);
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_ABEDNEUM),false);
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_SKY_FLOOR),false);
+ }
+ Player* pPlayer = GetPlayerForEscort();
+ if (pPlayer)
+ pPlayer->GroupEventHappens(QUEST_HALLS_OF_STONE, me);
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ JumpToNextStep(180000);
+ break;
+ }
+ case 50:
+ SetEscortPaused(false);
+ break;
+ }
+ } else uiPhaseTimer -= uiDiff;
+
+ if (!bIsLowHP && HealthBelowPct(30))
+ {
+ DoScriptText(SAY_LOW_HEALTH, me);
+ bIsLowHP = true;
+ }
+ else if (bIsLowHP && !HealthBelowPct(30))
+ bIsLowHP = false;
+
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+bool GossipHello_npc_brann_hos(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_START, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(TEXT_ID_START, pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipSelect_npc_brann_hos(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1 || uiAction == GOSSIP_ACTION_INFO_DEF+2)
+ {
+ pPlayer->CLOSE_GOSSIP_MENU();
+ CAST_AI(npc_brann_hosAI, pCreature->AI())->StartWP();
+ }
+
+ return true;
+}
+
+CreatureAI* GetAI_mob_tribuna_controller(Creature* pCreature)
+{
+ return new mob_tribuna_controllerAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_brann_hos(Creature* pCreature)
+{
+ return new npc_brann_hosAI(pCreature);
+}
+
+void AddSC_halls_of_stone()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_brann_hos";
+ newscript->GetAI = &GetAI_npc_brann_hos;
+ newscript->pGossipHello = &GossipHello_npc_brann_hos;
+ newscript->pGossipSelect = &GossipSelect_npc_brann_hos;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_tribuna_controller";
+ newscript->GetAI = &GetAI_mob_tribuna_controller;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h b/src/server/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h
new file mode 100644
index 00000000000..b61e7057ddc
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/halls_of_stone/halls_of_stone.h
@@ -0,0 +1,48 @@
+#ifndef DEF_HALLS_OF_STONE_H
+#define DEF_HALLS_OF_STONE_H
+enum Data
+{
+ DATA_KRYSTALLUS_EVENT,
+ DATA_MAIDEN_OF_GRIEF_EVENT,
+ DATA_SJONNIR_EVENT,
+ DATA_BRANN_EVENT
+};
+enum Data64
+{
+ DATA_KRYSTALLUS,
+ DATA_MAIDEN_OF_GRIEF,
+ DATA_SJONNIR,
+ DATA_KADDRAK,
+ DATA_MARNAK,
+ DATA_ABEDNEUM,
+ DATA_GO_TRIBUNAL_CONSOLE,
+ DATA_GO_KADDRAK,
+ DATA_GO_MARNAK,
+ DATA_GO_ABEDNEUM,
+ DATA_GO_SKY_FLOOR,
+ DATA_SJONNIR_DOOR,
+ DATA_MAIDEN_DOOR
+};
+enum Creatures
+{
+ CREATURE_MAIDEN = 27975,
+ CREATURE_KRYSTALLUS = 27977,
+ CREATURE_SJONNIR = 27978,
+ CREATURE_MARNAK = 30897,
+ CREATURE_KADDRAK = 30898,
+ CREATURE_ABEDNEUM = 30899,
+ CREATURE_BRANN = 28070
+};
+enum GameObjects
+{
+ GO_ABEDNEUM = 191669,
+ GO_MARNAK = 192170,
+ GO_KADDRAK = 192171,
+ GO_MAIDEN_DOOR = 191292,
+ GO_BRANN_DOOR = 191295,
+ GO_SJONNIR_DOOR = 191296,
+ GO_TRIBUNAL_CONSOLE = 193907,
+ GO_TRIBUNAL_CHEST = 190586,
+ GO_TRIBUNAL_CHEST_HERO = 193996
+};
+#endif
diff --git a/src/server/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp b/src/server/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp
new file mode 100644
index 00000000000..69bb3779e70
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/halls_of_stone/instance_halls_of_stone.cpp
@@ -0,0 +1,254 @@
+#include "ScriptedPch.h"
+#include "halls_of_stone.h"
+
+#define MAX_ENCOUNTER 4
+
+/* Halls of Stone encounters:
+0- Krystallus
+1- Maiden of Grief
+2- Escort Event
+3- Sjonnir The Ironshaper
+*/
+
+struct instance_halls_of_stone : public ScriptedInstance
+{
+ instance_halls_of_stone(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+
+ uint64 uiMaidenOfGrief;
+ uint64 uiKrystallus;
+ uint64 uiSjonnir;
+
+ uint64 uiKaddrak;
+ uint64 uiAbedneum;
+ uint64 uiMarnak;
+ uint64 uiBrann;
+
+ uint64 uiMaidenOfGriefDoor;
+ uint64 uiSjonnirDoor;
+ uint64 uiBrannDoor;
+ uint64 uiTribunalConsole;
+ uint64 uiTribunalChest;
+ uint64 uiTribunalSkyFloor;
+ uint64 uiKaddrakGo;
+ uint64 uiAbedneumGo;
+ uint64 uiMarnakGo;
+
+ uint32 m_auiEncounter[MAX_ENCOUNTER];
+
+ std::string str_data;
+
+ void Initialize()
+ {
+ uiMaidenOfGrief = 0;
+ uiKrystallus = 0;
+ uiSjonnir = 0;
+
+ uiKaddrak = 0;
+ uiMarnak = 0;
+ uiAbedneum = 0;
+ uiBrann = 0;
+
+ uiMaidenOfGriefDoor = 0;
+ uiSjonnirDoor = 0;
+ uiBrannDoor = 0;
+ uiKaddrakGo = 0;
+ uiMarnakGo = 0;
+ uiAbedneumGo = 0;
+ uiTribunalConsole = 0;
+ uiTribunalChest = 0;
+ uiTribunalSkyFloor = 0;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ m_auiEncounter[i] = NOT_STARTED;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool /*add*/)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case CREATURE_MAIDEN: uiMaidenOfGrief = pCreature->GetGUID(); break;
+ case CREATURE_KRYSTALLUS: uiKrystallus = pCreature->GetGUID(); break;
+ case CREATURE_SJONNIR: uiSjonnir = pCreature->GetGUID(); break;
+ case CREATURE_MARNAK: uiMarnak = pCreature->GetGUID(); break;
+ case CREATURE_KADDRAK: uiKaddrak = pCreature->GetGUID(); break;
+ case CREATURE_ABEDNEUM: uiAbedneum = pCreature->GetGUID(); break;
+ case CREATURE_BRANN: uiBrann = pCreature->GetGUID(); break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
+ {
+ switch(pGo->GetEntry())
+ {
+ case GO_ABEDNEUM:
+ uiAbedneumGo = pGo->GetGUID();
+ break;
+ case GO_MARNAK:
+ uiMarnakGo = pGo->GetGUID();
+ break;
+ case GO_KADDRAK:
+ uiKaddrakGo = pGo->GetGUID();
+ break;
+ case GO_MAIDEN_DOOR:
+ uiMaidenOfGriefDoor = pGo->GetGUID();
+ if (m_auiEncounter[0] == DONE)
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ else
+ pGo->SetGoState(GO_STATE_READY);
+ break;
+ case GO_BRANN_DOOR:
+ uiBrannDoor = pGo->GetGUID();
+ if (m_auiEncounter[1] == DONE)
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ else
+ pGo->SetGoState(GO_STATE_READY);
+ break;
+ case GO_SJONNIR_DOOR:
+ uiSjonnirDoor = pGo->GetGUID();
+ if (m_auiEncounter[2] == DONE)
+ pGo->SetGoState(GO_STATE_ACTIVE);
+ else
+ pGo->SetGoState(GO_STATE_READY);
+ break;
+ case GO_TRIBUNAL_CONSOLE:
+ uiTribunalConsole = pGo->GetGUID();
+ break;
+ case GO_TRIBUNAL_CHEST:
+ case GO_TRIBUNAL_CHEST_HERO:
+ uiTribunalChest = pGo->GetGUID();
+ if (m_auiEncounter[2] == DONE)
+ pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
+ break;
+ case 191527:
+ uiTribunalSkyFloor = pGo->GetGUID();
+ break;
+ }
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_MAIDEN_OF_GRIEF_EVENT:
+ m_auiEncounter[1] = data;
+ if (m_auiEncounter[1] == DONE)
+ HandleGameObject(uiBrannDoor,true);
+ break;
+ case DATA_KRYSTALLUS_EVENT:
+ m_auiEncounter[0] = data;
+ if (m_auiEncounter[0] == DONE)
+ HandleGameObject(uiMaidenOfGriefDoor,true);
+ break;
+ case DATA_SJONNIR_EVENT:
+ m_auiEncounter[3] = data;
+ break;
+ case DATA_BRANN_EVENT:
+ m_auiEncounter[2] = data;
+ if (m_auiEncounter[2] == DONE)
+ {
+ HandleGameObject(uiSjonnirDoor,true);
+ GameObject *pGo = instance->GetGameObject(uiTribunalChest);
+ if (pGo)
+ pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
+ }
+ break;
+ }
+
+ if (data == DONE)
+ SaveToDB();
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_KRYSTALLUS_EVENT: return m_auiEncounter[0];
+ case DATA_MAIDEN_OF_GRIEF_EVENT: return m_auiEncounter[1];
+ case DATA_SJONNIR_EVENT: return m_auiEncounter[2];
+ case DATA_BRANN_EVENT: return m_auiEncounter[3];
+ }
+
+ return 0;
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_MAIDEN_OF_GRIEF: return uiMaidenOfGrief;
+ case DATA_KRYSTALLUS: return uiKrystallus;
+ case DATA_SJONNIR: return uiSjonnir;
+ case DATA_KADDRAK: return uiKaddrak;
+ case DATA_MARNAK: return uiMarnak;
+ case DATA_ABEDNEUM: return uiAbedneum;
+ case DATA_GO_TRIBUNAL_CONSOLE: return uiTribunalConsole;
+ case DATA_GO_KADDRAK: return uiKaddrakGo;
+ case DATA_GO_ABEDNEUM: return uiAbedneumGo;
+ case DATA_GO_MARNAK: return uiMarnakGo;
+ case DATA_GO_SKY_FLOOR: return uiTribunalSkyFloor;
+ case DATA_SJONNIR_DOOR: return uiSjonnirDoor;
+ case DATA_MAIDEN_DOOR: return uiMaidenOfGriefDoor;
+ }
+
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "H S " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3];
+
+ str_data = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return str_data;
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0, data1, data2, data3;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;
+
+ if (dataHead1 == 'H' && dataHead2 == 'S')
+ {
+ m_auiEncounter[0] = data0;
+ m_auiEncounter[1] = data1;
+ m_auiEncounter[2] = data2;
+ m_auiEncounter[3] = data3;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_halls_of_stone(Map* pMap)
+{
+ return new instance_halls_of_stone(pMap);
+}
+
+void AddSC_instance_halls_of_stone()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_halls_of_stone";
+ newscript->GetInstanceData = &GetInstanceData_instance_halls_of_stone;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/ulduar/boss_algalon.cpp b/src/server/scripts/northrend/ulduar/ulduar/boss_algalon.cpp
new file mode 100644
index 00000000000..e944543fb9e
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/boss_algalon.cpp
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2008 - 2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+
+#define GAMEOBJECT_GIVE_OF_THE_OBSERVER 194821
+
+enum Spells
+{
+ SPELL_ASCEND = 64487,
+ SPELL_BERSERK = 47008,
+ SPELL_BIG_BANG = 64443,
+ H_SPELL_BIG_BANG = 64584,
+ SPELL_COSMIC_SMASH = 62301,
+ H_SPELL_COSMIC_SMASH = 64598,
+ SPELL_PHASE_PUNCH = 64412,
+ SPELL_QUANTUM_STRIKE = 64395,
+ H_SPELL_QUANTUM_STRIKE = 64592,
+ SPELL_BLACK_HOLE_EXPLOSION = 64122,
+ SPELL_ARCANE_BARAGE = 64599,
+ H_SPELL_ARCANE_BARAGE = 64607
+};
+
+enum Creatures
+{
+ CREATURE_COLLAPSING_STAR = 32955,
+ CREATURE_BLACK_HOLE = 32953,
+ CREATURE_LIVING_CONSTELLATION = 33052,
+ CREATURE_DARK_MATTER = 33089
+};
+
+#define NORDRASSIL_X 1614.288574
+#define NORDRASSIL_Y -320.713287
+#define NORDRASSIL_Z 417.321167
+#define NORDRASSIL_X 1614.276245
+#define NORDRASSIL_Y -287.016632
+#define NORDRASSIL_Z 417.321106
+#define NORDRASSIL_X 1650.428467
+#define NORDRASSIL_Y -292.331390
+#define NORDRASSIL_Z 417.321167
+#define NORDRASSIL_X 1649.501831
+#define NORDRASSIL_Y -324.609222
+#define NORDRASSIL_Z 417.322174
+
+enum Yells
+{
+ SAY_AGGRO = -1603000,
+ SAY_SLAY_1 = -1603001,
+ SAY_SLAY_2 = -1603002,
+ SAY_ENGADED_FOR_FIRTS_TIME = -1603003,
+ SAY_PHASE_2 = -1603004,
+ SAY_SUMMON_COLLAPSING_STAR = -1603005,
+ SAY_DEATH_1 = -1603006,
+ SAY_DEATH_2 = -1603007,
+ SAY_DEATH_3 = -1603008,
+ SAY_DEATH_4 = -1603009,
+ SAY_DEATH_5 = -1603010,
+ SAY_BERSERK = -1603011,
+ SAY_BIG_BANG_1 = -1603012,
+ SAY_BIG_BANG_2 = -1603013,
+ SAY_TIMER_1 = -1603014,
+ SAY_TIMER_2 = -1603015,
+ SAY_TIMER_3 = -1603016,
+ SAY_SUMMON_1 = -1603017,
+ SAY_SUMMON_2 = -1603018,
+ SAY_SUMMON_3 = -1603019,
+};
+
+struct boss_algalonAI : public ScriptedAI
+{
+ boss_algalonAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ Summon = false; // not in reset. intro speech done only once.
+ }
+
+ ScriptedInstance* pInstance;
+
+ std::list<uint64> m_lCollapsingStarGUIDList;
+
+ uint32 Phase;
+ uint32 Ascend_Timer;
+ uint32 Berserk_Timer;
+ uint32 BigBang_Timer;
+ uint32 CosmicSmash_Timer;
+ uint32 PhasePunch_Timer;
+ uint32 QuantumStrike_Timer;
+ uint32 CollapsingStar_Timer;
+ uint32 uiPhase_timer;
+ uint32 uiStep;
+
+ uint64 BlackHoleGUID;
+
+ bool Enrage;
+ bool Summon;
+
+ void EnterCombat(Unit* who)
+ {
+ if (Summon)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ me->InterruptSpell(CURRENT_CHANNELED_SPELL);
+ DoZoneInCombat(who->ToCreature());
+ }
+ else
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetReactState(REACT_PASSIVE);
+ uiStep = 1;
+ }
+
+ if (pInstance)
+ pInstance->SetData(TYPE_ALGALON, IN_PROGRESS);
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void Reset()
+ {
+ Phase = 1;
+
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ if (pInstance)
+ pInstance->SetData(TYPE_ALGALON, NOT_STARTED);
+
+ BlackHoleGUID = 0;
+
+ uiPhase_timer = 0;
+ Ascend_Timer = 480000; //8 minutes
+ QuantumStrike_Timer = 4000 + rand()%10000;
+ Berserk_Timer = 360000; //6 minutes
+ CollapsingStar_Timer = urand(15000, 20000); //Spawns between 15 to 20 seconds
+ BigBang_Timer = 90000;
+ PhasePunch_Timer = 8000;
+ CosmicSmash_Timer = urand(30000, 60000);
+ Enrage = false;
+ }
+
+ void JumpToNextStep(uint32 uiTimer)
+ {
+ uiPhase_timer = uiTimer;
+ ++uiStep;
+ }
+
+ void DespawnCollapsingStar()
+ {
+ if (m_lCollapsingStarGUIDList.empty())
+ return;
+
+ for (std::list<uint64>::const_iterator itr = m_lCollapsingStarGUIDList.begin(); itr != m_lCollapsingStarGUIDList.end(); ++itr)
+ {
+ if (Creature* pTemp = Unit::GetCreature(*me, *itr))
+ {
+ if (pTemp->isAlive())
+ pTemp->ForcedDespawn();
+ }
+ }
+ m_lCollapsingStarGUIDList.clear();
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ if (pSummoned->GetEntry() == CREATURE_COLLAPSING_STAR)
+ {
+ Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ if (me->getVictim())
+ pSummoned->AI()->AttackStart(pTarget ? pTarget : me->getVictim());
+ m_lCollapsingStarGUIDList.push_back(pSummoned->GetGUID());
+ }
+ }
+
+ void SummonCollapsingStar(Unit* target)
+ {
+ DoScriptText(SAY_SUMMON_COLLAPSING_STAR, me);
+ me->SummonCreature(CREATURE_COLLAPSING_STAR,target->GetPositionX()+15.0,target->GetPositionY()+15.0,target->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN, 100000);
+ me->SummonCreature(CREATURE_BLACK_HOLE,target->GetPositionX()+15.0,target->GetPositionY()+15.0,target->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN, 27000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (Phase == 1 && HealthBelowPct(20))
+ {
+ Phase = 2;
+ DoScriptText(SAY_PHASE_2, me);
+ }
+
+ if (HealthBelowPct(2))
+ {
+ me->SummonGameObject(GAMEOBJECT_GIVE_OF_THE_OBSERVER, 1634.258667, -295.101166,417.321381,0,0,0,0,0,0);
+
+ // All of them. or random?
+ DoScriptText(SAY_DEATH_1, me);
+ DoScriptText(SAY_DEATH_2, me);
+ DoScriptText(SAY_DEATH_3, me);
+ DoScriptText(SAY_DEATH_4, me);
+ DoScriptText(SAY_DEATH_5, me);
+
+ me->DisappearAndDie();
+
+ if (pInstance)
+ pInstance->SetData(TYPE_ALGALON, DONE);
+
+ return;
+ }
+
+ if (Phase == 1)
+ {
+ if (!Summon)
+ {
+ if (uiPhase_timer <= diff)
+ {
+ switch(uiStep)
+ {
+ case 1:
+ DoScriptText(SAY_SUMMON_1, me);
+ JumpToNextStep(3000);
+ break;
+ case 2:
+ DoScriptText(SAY_SUMMON_2, me);
+ JumpToNextStep(3000);
+ break;
+ case 3:
+ DoScriptText(SAY_SUMMON_3, me);
+ JumpToNextStep(3000);
+ break;
+ case 4:
+ DoScriptText(SAY_ENGADED_FOR_FIRTS_TIME, me);
+ JumpToNextStep(3000);
+ break;
+ case 5:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ Summon = true;
+ break;
+ }
+ } else uiPhase_timer -= diff;
+
+ return;
+ }
+
+ if (QuantumStrike_Timer <= diff)
+ {
+ DoCast(me->getVictim(), RAID_MODE(SPELL_QUANTUM_STRIKE,H_SPELL_QUANTUM_STRIKE), true);
+
+ QuantumStrike_Timer = urand(4000, 14000);
+ } else QuantumStrike_Timer -= diff;
+
+ if (BigBang_Timer <= diff)
+ {
+ DoScriptText(RAND(SAY_BIG_BANG_1,SAY_BIG_BANG_2), me);
+ DoCast(me->getVictim(), RAID_MODE(SPELL_BIG_BANG,H_SPELL_BIG_BANG), true);
+
+ BigBang_Timer = 90000;
+ } else BigBang_Timer -= diff;
+
+ if (Ascend_Timer <= diff)
+ {
+ DoCast(me->getVictim(),SPELL_ASCEND, true);
+
+ Ascend_Timer = 480000;
+ } else Ascend_Timer -= diff;
+
+ if (PhasePunch_Timer <= diff)
+ {
+ DoCast(me->getVictim(),SPELL_PHASE_PUNCH, true);
+
+ PhasePunch_Timer = 8000;
+ } else PhasePunch_Timer -= diff;
+
+ if (CosmicSmash_Timer <= diff)
+ {
+ DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), RAID_MODE(SPELL_COSMIC_SMASH,H_SPELL_COSMIC_SMASH), true);
+
+ CosmicSmash_Timer = urand(30000, 60000);
+ } else CosmicSmash_Timer -= diff;
+
+ if (Berserk_Timer <= diff)
+ {
+ DoScriptText(SAY_BERSERK, me);
+ DoCast(me->getVictim(),SPELL_BERSERK, true);
+
+ Berserk_Timer = 360000;
+ } else Berserk_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+
+ EnterEvadeIfOutOfCombatArea(diff);
+ }
+
+ if (Phase == 2)
+ {
+ if (Enrage)
+ {
+ if (Ascend_Timer <= diff)
+ {
+ DoCast(me, SPELL_ASCEND);
+ DoScriptText(SAY_BERSERK, me);
+ Ascend_Timer = urand(360000,365000);
+ Enrage = false;
+ } else Ascend_Timer -= diff;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+//Collapsing Star
+struct mob_collapsing_starAI : public ScriptedAI
+{
+ mob_collapsing_starAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 BlackHoleExplosion_Timer;
+
+ void Reset()
+ {
+ BlackHoleExplosion_Timer = 0;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (BlackHoleExplosion_Timer <= diff)
+ {
+ me->CastSpell(me, SPELL_BLACK_HOLE_EXPLOSION, false);
+ BlackHoleExplosion_Timer = 0;
+ } else BlackHoleExplosion_Timer -= diff;
+ }
+};
+
+CreatureAI* GetAI_boss_algalon(Creature* pCreature)
+{
+ return new boss_algalonAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_collapsing_star(Creature* pCreature)
+{
+ return new mob_collapsing_starAI(pCreature);
+}
+
+void AddSC_boss_Algalon()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_algalon";
+ newscript->GetAI = &GetAI_boss_algalon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_collapsing_star";
+ newscript->GetAI = &GetAI_mob_collapsing_star;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/ulduar/boss_assembly_of_iron.cpp b/src/server/scripts/northrend/ulduar/ulduar/boss_assembly_of_iron.cpp
new file mode 100644
index 00000000000..8d3ae4d3431
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/boss_assembly_of_iron.cpp
@@ -0,0 +1,589 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Assembly of Iron encounter
+SD%Complete: 60%
+SDComment: Runes need DB support, chain lightning won't cast, supercharge won't cast (pTarget error?) - it worked before during debugging.
+SDCategory: Ulduar - Ulduar
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+
+// Any boss
+#define SPELL_SUPERCHARGE 61920
+#define SPELL_BERSERK 47008 // Hard enrage, don't know the correct ID.
+
+// Steelbreaker
+#define SPELL_HIGH_VOLTAGE 61890
+#define SPELL_HIGH_VOLTAGE_H 63498
+#define SPELL_FUSION_PUNCH 61903
+#define SPELL_FUSION_PUNCH_H 63493
+#define SPELL_STATIC_DISRUPTION 44008
+#define SPELL_STATIC_DISRUPTION_H 63494
+#define SPELL_OVERWHELMING_POWER_H 61888
+#define SPELL_OVERWHELMING_POWER 64637
+#define SPELL_ELECTRICAL_CHARGE 61902
+
+// Runemaster Molgeim
+#define SPELL_SHIELD_OF_RUNES 62274
+#define SPELL_SHIELD_OF_RUNES_H 63489
+#define SPELL_RUNE_OF_POWER 64320
+#define SPELL_RUNE_OF_DEATH 62269
+#define SPELL_RUNE_OF_SUMMONING 62273
+#define SPELL_LIGHTNING_BLAST 62054
+#define SPELL_LIGHTNING_BLAST_H 63491
+#define CREATURE_RUNE_OF_SUMMONING 33051
+
+// Stormcaller Brundir
+#define SPELL_CHAIN_LIGHTNING_N 61879
+#define SPELL_CHAIN_LIGHTNING_H 63479
+#define SPELL_OVERLOAD 61869
+#define SPELL_OVERLOAD_H 63481
+#define SPELL_LIGHTNING_WHIRL 61915
+#define SPELL_LIGHTNING_WHIRL_H 63483
+#define SPELL_LIGHTNING_TENDRILS 61887
+#define SPELL_LIGHTNING_TENDRILS_H 63486
+#define SPELL_STORMSHIELD 64187
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_ENRAGE,
+ // Steelbreaker
+ EVENT_FUSION_PUNCH,
+ EVENT_STATIC_DISRUPTION,
+ EVENT_OVERWHELMING_POWER,
+ // Molgeim
+ EVENT_RUNE_OF_POWER,
+ EVENT_SHIELD_OF_RUNES,
+ EVENT_RUNE_OF_DEATH,
+ EVENT_RUNE_OF_SUMMONING,
+ EVENT_LIGHTNING_BLAST,
+ // Brundir
+ EVENT_CHAIN_LIGHTNING,
+ EVENT_OVERLOAD,
+ EVENT_LIGHTNING_WHIRL,
+ EVENT_LIGHTNING_TENDRILS,
+ EVENT_STORMSHIELD,
+};
+
+enum Yells
+{
+ SAY_STEELBREAKER_AGGRO = -1603020,
+ SAY_STEELBREAKER_SLAY_1 = -1603021,
+ SAY_STEELBREAKER_SLAY_2 = -1603022,
+ SAY_STEELBREAKER_POWER = -1603023,
+ SAY_STEELBREAKER_DEATH_1 = -1603024,
+ SAY_STEELBREAKER_DEATH_2 = -1603025,
+ SAY_STEELBREAKER_BERSERK = -1603026,
+
+ SAY_MOLGEIM_AGGRO = -1603030,
+ SAY_MOLGEIM_SLAY_1 = -1603031,
+ SAY_MOLGEIM_SLAY_2 = -1603032,
+ SAY_MOLGEIM_RUNE_DEATH = -1603033,
+ SAY_MOLGEIM_SUMMON = -1603034,
+ SAY_MOLGEIM_DEATH_1 = -1603035,
+ SAY_MOLGEIM_DEATH_2 = -1603036,
+ SAY_MOLGEIM_BERSERK = -1603037,
+
+ SAY_BRUNDIR_AGGRO = -1603040,
+ SAY_BRUNDIR_SLAY_1 = -1603041,
+ SAY_BRUNDIR_SLAY_2 = -1603042,
+ SAY_BRUNDIR_SPECIAL = -1603043,
+ SAY_BRUNDIR_FLIGHT = -1603044,
+ SAY_BRUNDIR_DEATH_1 = -1603045,
+ SAY_BRUNDIR_DEATH_2 = -1603046,
+ SAY_BRUNDIR_BERSERK = -1603047,
+};
+
+bool IsEncounterComplete(ScriptedInstance* pInstance, Creature* me)
+{
+ if (!pInstance || !me)
+ return false;
+
+ for (uint8 i = 0; i < 3; ++i)
+ {
+ uint64 guid = pInstance->GetData64(DATA_STEELBREAKER+i);
+ if (!guid)
+ return false;
+
+ if (Creature *boss = Unit::GetCreature(*me, guid))
+ {
+ if (boss->isAlive())
+ return false;
+ }
+ else
+ return false;
+ }
+ return true;
+}
+
+struct boss_steelbreakerAI : public ScriptedAI
+{
+ boss_steelbreakerAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ void Reset()
+ {
+ events.Reset();
+ phase = 0;
+ me->RemoveAllAuras();
+ if (pInstance)
+ pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
+ }
+
+ EventMap events;
+ ScriptedInstance* pInstance;
+ uint32 phase;
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ DoScriptText(SAY_STEELBREAKER_AGGRO, me);
+ DoZoneInCombat();
+ DoCast(me, RAID_MODE(SPELL_HIGH_VOLTAGE, SPELL_HIGH_VOLTAGE_H));
+ events.ScheduleEvent(EVENT_ENRAGE, 900000);
+ UpdatePhase();
+ }
+
+ void UpdatePhase()
+ {
+ ++phase;
+ events.SetPhase(phase);
+ events.RescheduleEvent(EVENT_FUSION_PUNCH, 15000);
+ if (phase >= 2)
+ events.RescheduleEvent(EVENT_STATIC_DISRUPTION, 30000);
+ if (phase >= 3)
+ events.RescheduleEvent(EVENT_OVERWHELMING_POWER, rand()%5000);
+ }
+
+ void DamageTaken(Unit* /*pKiller*/, uint32 &damage)
+ {
+ if (damage >= me->GetHealth())
+ {
+ if (Creature* Brundir = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_STORMCALLER_BRUNDIR) : 0))
+ if (Brundir->isAlive())
+ Brundir->SetHealth(Brundir->GetMaxHealth());
+
+ if (Creature* Molgeim = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_RUNEMASTER_MOLGEIM) : 0))
+ if (Molgeim->isAlive())
+ Molgeim->SetHealth(Molgeim->GetMaxHealth());
+
+ DoCast(SPELL_SUPERCHARGE);
+ }
+ }
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ DoScriptText(RAND(SAY_STEELBREAKER_DEATH_1,SAY_STEELBREAKER_DEATH_2), me);
+ if (IsEncounterComplete(pInstance, me) && pInstance)
+ pInstance->SetData(TYPE_ASSEMBLY, DONE);
+ }
+
+ void KilledUnit(Unit * /*who*/)
+ {
+ DoScriptText(RAND(SAY_STEELBREAKER_SLAY_1,SAY_STEELBREAKER_SLAY_2), me);
+
+ if (phase == 3)
+ DoCast(me, SPELL_ELECTRICAL_CHARGE);
+ }
+
+ void SpellHit(Unit * /*from*/, const SpellEntry *spell)
+ {
+ if (spell->Id == SPELL_SUPERCHARGE)
+ UpdatePhase();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_ENRAGE:
+ DoScriptText(SAY_STEELBREAKER_BERSERK, me);
+ DoCast(SPELL_BERSERK);
+ break;
+ case EVENT_FUSION_PUNCH:
+ DoCast(me->getVictim(), RAID_MODE(SPELL_FUSION_PUNCH, SPELL_FUSION_PUNCH_H));
+ events.ScheduleEvent(EVENT_FUSION_PUNCH, urand(13000, 22000));
+ break;
+ case EVENT_STATIC_DISRUPTION:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, RAID_MODE(SPELL_STATIC_DISRUPTION, SPELL_STATIC_DISRUPTION_H));
+ events.ScheduleEvent(EVENT_STATIC_DISRUPTION, urand(20000, 40000));
+ break;
+ case EVENT_OVERWHELMING_POWER:
+ DoScriptText(SAY_STEELBREAKER_POWER, me);
+ DoCast(me->getVictim(), RAID_MODE(SPELL_OVERWHELMING_POWER, SPELL_OVERWHELMING_POWER_H));
+ events.ScheduleEvent(EVENT_OVERWHELMING_POWER, RAID_MODE(60000, 35000));
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct boss_runemaster_molgeimAI : public ScriptedAI
+{
+ boss_runemaster_molgeimAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ void Reset()
+ {
+ if (pInstance)
+ pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
+ events.Reset();
+ me->RemoveAllAuras();
+ phase = 0;
+ }
+
+ ScriptedInstance* pInstance;
+ EventMap events;
+ uint32 phase;
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_MOLGEIM_AGGRO, me);
+ DoZoneInCombat();
+ events.ScheduleEvent(EVENT_ENRAGE, 900000);
+ UpdatePhase();
+ }
+
+ void UpdatePhase()
+ {
+ ++phase;
+ events.SetPhase(phase);
+ events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 27000);
+ events.RescheduleEvent(EVENT_RUNE_OF_POWER, 60000);
+ if (phase >= 2)
+ events.RescheduleEvent(EVENT_RUNE_OF_DEATH, 30000);
+ if (phase >= 3)
+ events.RescheduleEvent(EVENT_RUNE_OF_SUMMONING, urand(20000,30000));
+ }
+
+ void DamageTaken(Unit* /*pKiller*/, uint32 &damage)
+ {
+ if (damage >= me->GetHealth())
+ {
+ if (Creature* Steelbreaker = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_STEELBREAKER) : 0))
+ if (Steelbreaker->isAlive())
+ Steelbreaker->SetHealth(Steelbreaker->GetMaxHealth());
+
+ if (Creature* Brundir = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_STORMCALLER_BRUNDIR) : 0))
+ if (Brundir->isAlive())
+ Brundir->SetHealth(Brundir->GetMaxHealth());
+
+ DoCast(me, SPELL_SUPERCHARGE);
+ }
+ }
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ DoScriptText(RAND(SAY_MOLGEIM_DEATH_1,SAY_MOLGEIM_DEATH_2), me);
+ if (IsEncounterComplete(pInstance, me) && pInstance)
+ pInstance->SetData(TYPE_ASSEMBLY, DONE);
+ }
+
+ void KilledUnit(Unit * /*who*/)
+ {
+ DoScriptText(RAND(SAY_MOLGEIM_SLAY_1,SAY_MOLGEIM_SLAY_2), me);
+ }
+
+ void SpellHit(Unit * /*from*/, const SpellEntry *spell)
+ {
+ if (spell->Id == SPELL_SUPERCHARGE)
+ UpdatePhase();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_ENRAGE:
+ DoScriptText(SAY_MOLGEIM_BERSERK, me);
+ DoCast(SPELL_BERSERK);
+ break;
+ case EVENT_RUNE_OF_POWER: // Improve target selection; random alive friendly
+ {
+ Unit *pTarget = DoSelectLowestHpFriendly(60);
+ if (!pTarget || (pTarget && !pTarget->isAlive()))
+ pTarget = me;
+ DoCast(pTarget, SPELL_RUNE_OF_POWER);
+ events.ScheduleEvent(EVENT_RUNE_OF_POWER, 60000);
+ break;
+ }
+ case EVENT_SHIELD_OF_RUNES:
+ DoCast(me, RAID_MODE(SPELL_SHIELD_OF_RUNES, SPELL_SHIELD_OF_RUNES_H));
+ events.ScheduleEvent(EVENT_SHIELD_OF_RUNES, urand(27000,34000));
+ break;
+ case EVENT_RUNE_OF_DEATH:
+ DoScriptText(SAY_MOLGEIM_RUNE_DEATH, me);
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_RUNE_OF_DEATH);
+ events.ScheduleEvent(EVENT_RUNE_OF_DEATH, urand(30000,40000));
+ break;
+ case EVENT_RUNE_OF_SUMMONING:
+ DoScriptText(SAY_MOLGEIM_SUMMON, me);
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_RUNE_OF_SUMMONING);
+ events.ScheduleEvent(EVENT_RUNE_OF_SUMMONING, urand(20000,30000));
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_lightning_elementalAI : public ScriptedAI
+{
+ mob_lightning_elementalAI(Creature *c) : ScriptedAI(c)
+ {
+ Charge();
+ }
+
+ void Charge()
+ {
+ Unit* pTarget = me->SelectNearestTarget();
+ me->AddThreat(pTarget, 5000000.0f);
+ AttackStart(pTarget);
+ }
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ if (!me->isInCombat())
+ return;
+
+ if (!UpdateVictim())
+ return;
+
+ if (me->IsWithinMeleeRange(me->getVictim()))
+ {
+ DoCast(me->getVictim(), RAID_MODE(SPELL_LIGHTNING_BLAST, SPELL_LIGHTNING_BLAST_H));
+ me->Kill(me); // hack until spell works
+ }
+
+ me->GetMotionMaster()->MoveChase(me->getVictim()); // needed at every update?
+ }
+};
+
+struct mob_rune_of_summoningAI : public ScriptedAI
+{
+ mob_rune_of_summoningAI(Creature *c) : ScriptedAI(c)
+ {
+ SummonLightningElemental();
+ }
+
+ void SummonLightningElemental()
+ {
+ me->SummonCreature(CREATURE_RUNE_OF_SUMMONING, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN);
+ me->DealDamage(me, me->GetHealth());
+ }
+};
+
+struct boss_stormcaller_brundirAI : public ScriptedAI
+{
+ boss_stormcaller_brundirAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ void Reset()
+ {
+ if (pInstance)
+ pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
+ me->RemoveAllAuras();
+ events.Reset();
+ phase = 0;
+ }
+
+ EventMap events;
+ ScriptedInstance* pInstance;
+ uint32 phase;
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_BRUNDIR_AGGRO, me);
+ DoZoneInCombat();
+ events.ScheduleEvent(EVENT_ENRAGE, 900000);
+ UpdatePhase();
+ }
+
+ void UpdatePhase()
+ {
+ ++phase;
+ events.SetPhase(phase);
+ events.RescheduleEvent(EVENT_CHAIN_LIGHTNING, urand(9000,17000));
+ events.RescheduleEvent(EVENT_OVERLOAD, urand(60000,125000));
+ if (phase >= 2)
+ events.RescheduleEvent(EVENT_LIGHTNING_WHIRL, urand(20000,40000));
+ if (phase >= 3)
+ {
+ DoCast(me, SPELL_STORMSHIELD);
+ events.RescheduleEvent(EVENT_LIGHTNING_TENDRILS, urand(40000,80000));
+ }
+ }
+
+ void DamageTaken(Unit* /*pKiller*/, uint32 &damage)
+ {
+ if (damage >= me->GetHealth())
+ {
+ if (Creature* Steelbreaker = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_STEELBREAKER) : 0))
+ if (Steelbreaker->isAlive())
+ Steelbreaker->SetHealth(Steelbreaker->GetMaxHealth());
+
+ if (Creature* Molgeim = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_RUNEMASTER_MOLGEIM) : 0))
+ if (Molgeim->isAlive())
+ Molgeim->SetHealth(Molgeim->GetMaxHealth());
+
+ DoCast(SPELL_SUPERCHARGE);
+ }
+ }
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ DoScriptText(RAND(SAY_BRUNDIR_DEATH_1,SAY_BRUNDIR_DEATH_2), me);
+ if (IsEncounterComplete(pInstance, me) && pInstance)
+ pInstance->SetData(TYPE_ASSEMBLY, DONE);
+ }
+
+ void KilledUnit(Unit * /*who*/)
+ {
+ DoScriptText(RAND(SAY_BRUNDIR_SLAY_1,SAY_BRUNDIR_SLAY_2), me);
+ }
+
+ void SpellHit(Unit * /*from*/, const SpellEntry *spell)
+ {
+ if (spell->Id == SPELL_SUPERCHARGE)
+ UpdatePhase();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_ENRAGE:
+ DoScriptText(SAY_BRUNDIR_BERSERK, me);
+ DoCast(SPELL_BERSERK);
+ break;
+ case EVENT_CHAIN_LIGHTNING:
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
+ DoCast(pTarget, RAID_MODE(SPELL_CHAIN_LIGHTNING_N , SPELL_CHAIN_LIGHTNING_H));
+ events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, urand(9000,17000));
+ break;
+ case EVENT_OVERLOAD:
+ DoCast(RAID_MODE(SPELL_OVERLOAD , SPELL_OVERLOAD_H));
+ events.ScheduleEvent(EVENT_OVERLOAD, urand(60000,125000));
+ break;
+ case EVENT_LIGHTNING_WHIRL:
+ DoCast(RAID_MODE(SPELL_LIGHTNING_WHIRL , SPELL_LIGHTNING_WHIRL_H));
+ events.ScheduleEvent(EVENT_LIGHTNING_WHIRL, urand(20000,40000));
+ break;
+ case EVENT_LIGHTNING_TENDRILS:
+ DoCast(RAID_MODE(SPELL_LIGHTNING_TENDRILS, SPELL_LIGHTNING_TENDRILS_H));
+ events.DelayEvents(15000, 5000);
+ DoResetThreat();
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_steelbreaker(Creature* pCreature)
+{
+ return new boss_steelbreakerAI (pCreature);
+}
+
+CreatureAI* GetAI_boss_runemaster_molgeim(Creature* pCreature)
+{
+ return new boss_runemaster_molgeimAI (pCreature);
+}
+
+CreatureAI* GetAI_boss_stormcaller_brundir(Creature* pCreature)
+{
+ return new boss_stormcaller_brundirAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_lightning_elemental(Creature* pCreature)
+{
+ return new mob_lightning_elementalAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_rune_of_summoning(Creature* pCreature)
+{
+ return new mob_rune_of_summoningAI (pCreature);
+}
+
+void AddSC_boss_assembly_of_iron()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_steelbreaker";
+ newscript->GetAI = &GetAI_boss_steelbreaker;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_runemaster_molgeim";
+ newscript->GetAI = &GetAI_boss_runemaster_molgeim;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_stormcaller_brundir";
+ newscript->GetAI = &GetAI_boss_stormcaller_brundir;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_lightning_elemental";
+ newscript->GetAI = &GetAI_mob_lightning_elemental;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_rune_of_summoning";
+ newscript->GetAI = &GetAI_mob_rune_of_summoning;
+ newscript->RegisterSelf();
+
+}
diff --git a/src/server/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp b/src/server/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp
new file mode 100644
index 00000000000..41c0f317f4e
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/boss_auriaya.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+
+//boss_auriaya
+#define SPELL_TERRIFYING_SCREECH 64386
+#define SPELL_SETINEL_BLAST 64679
+#define SPELL_SONIC_SCREECH 64422
+#define SPELL_SUMMON_SWARMING_GUARDIAN 64397
+
+enum Yells
+{
+ SAY_AGGRO = -1603050,
+ SAY_SLAY_1 = -1603051,
+ SAY_SLAY_2 = -1603052,
+ SAY_DEATH = -1603053,
+ SAY_BERSERK = -1603054,
+};
+
+struct boss_auriaya_AI : public BossAI
+{
+ boss_auriaya_AI(Creature *pCreature) : BossAI(pCreature, TYPE_AURIAYA)
+ {
+ }
+
+ uint32 TERRIFYING_SCREECH_Timer;
+ uint32 SONIC_SCREECH_Timer;
+
+ void Reset()
+ {
+ _Reset();
+ TERRIFYING_SCREECH_Timer = 180000;
+ SONIC_SCREECH_Timer = 30000;
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ _EnterCombat();
+ DoScriptText(SAY_AGGRO,me);
+ }
+
+ void KilledUnit(Unit* /*victim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void JustDied(Unit * /*victim*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ _JustDied();
+ }
+
+ void MoveInLineOfSight(Unit* /*who*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (TERRIFYING_SCREECH_Timer <= diff)
+ {
+ DoCast(SPELL_TERRIFYING_SCREECH);
+ TERRIFYING_SCREECH_Timer = 180000;
+ } else TERRIFYING_SCREECH_Timer -= diff;
+
+ if (SONIC_SCREECH_Timer <= diff)
+ {
+ DoCastVictim(SPELL_SONIC_SCREECH);
+ SONIC_SCREECH_Timer = 30000;
+ } else SONIC_SCREECH_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_auriaya(Creature* pCreature)
+{
+ return new boss_auriaya_AI (pCreature);
+}
+
+void AddSC_boss_auriaya()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_auriaya";
+ newscript->GetAI = &GetAI_boss_auriaya;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp b/src/server/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp
new file mode 100644
index 00000000000..b50f12805a4
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/boss_flame_leviathan.cpp
@@ -0,0 +1,574 @@
+/*
+ * Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Comment: Tower Event support is not finished, there is missing code on triggers and
+ * Lore Keeper and Brann Bronzebeard are not scripted yet. Lore Keeper's script
+ * should activate the hard mode so is not possible to play hard-mode yet. Add a call to
+ * Leviathan's DoAction(0) from Lore Keeper's script to activate hard-mode
+ */
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+#include "Vehicle.h"
+
+enum Spells
+{
+ SPELL_PURSUED = 62374,
+ SPELL_GATHERING_SPEED = 62375,
+ SPELL_BATTERING_RAM = 62376,
+ SPELL_FLAME_VENTS = 62396,
+ SPELL_MISSILE_BARRAGE = 62400,
+ SPELL_SYSTEMS_SHUTDOWN = 62475,
+
+ SPELL_FLAME_CANNON = 62395,
+// SPELL_FLAME_CANNON = 64692, trigger the same spell
+
+ SPELL_OVERLOAD_CIRCUIT = 62399,
+ SPELL_SEARING_FLAME = 62402,
+ SPELL_BLAZE = 62292,
+ SPELL_SMOKE_TRAIL = 63575,
+ SPELL_ELECTROSHOCK = 62522,
+ //TOWER BUFF SPELLS
+ SPELL_THORIM_S_HAMMER = 62912, // Tower of Storms
+ SPELL_MIMIRON_S_INFERNO = 62910, // Tower of Flames
+ SPELL_HODIR_S_FURY = 62297, // Tower of Frost
+ SPELL_FREYA_S_WARD = 62906 // Tower of Nature
+};
+
+enum Creatures
+{
+ MOB_MECHANOLIFT = 33214,
+ MOB_LIQUID = 33189,
+ MOB_CONTAINER = 33218,
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_PURSUE,
+ EVENT_MISSILE,
+ EVENT_VENT,
+ EVENT_SPEED,
+ EVENT_SUMMON,
+ EVENT_THORIM_S_HAMMER, // Tower of Storms
+ EVENT_MIMIRON_S_INFERNO, // Tower of Flames
+ EVENT_HODIR_S_FURY, // Tower of Frost
+ EVENT_FREYA_S_WARD // Tower of Nature
+};
+
+enum Seats
+{
+ SEAT_PLAYER = 0,
+ SEAT_TURRET = 1,
+ SEAT_DEVICE = 2,
+};
+
+enum Yells
+{
+ SAY_AGGRO = -1603060,
+ SAY_SLAY = -1603061,
+ SAY_DEATH = -1603062,
+ SAY_TARGET_1 = -1603063,
+ SAY_TARGET_2 = -1603064,
+ SAY_TARGET_3 = -1603065,
+ SAY_HARDMODE = -1603066,
+ SAY_TOWER_NONE = -1603067,
+ SAY_TOWER_FROST = -1603068,
+ SAY_TOWER_FLAME = -1603069,
+ SAY_TOWER_NATURE = -1603070,
+ SAY_TOWER_STORM = -1603071,
+ SAY_PLAYER_RIDING = -1603072,
+ SAY_OVERLOAD_1 = -1603073,
+ SAY_OVERLOAD_2 = -1603074,
+ SAY_OVERLOAD_3 = -1603075,
+};
+
+enum eAchievementData
+{
+ //ACHIEV_CHAMPION_OF_ULDUAR = 10042,
+ //ACHIEV_CONQUEROR_OF_ULDUAR = 10352,
+ ACHIEV_10_NUKED_FROM_ORBIT = 10058,
+ ACHIEV_25_NUKED_FROM_ORBIT = 10060,
+ ACHIEV_10_ORBITAL_BOMBARDMENT = 10056,
+ ACHIEV_25_ORBITAL_BOMBARDMENT = 10061,
+ ACHIEV_10_ORBITAL_DEVASTATION = 10057,
+ ACHIEV_25_ORBITAL_DEVASTATION = 10059,
+ ACHIEV_10_ORBIT_UARY = 10218,
+ ACHIEV_25_ORBIT_UARY = 10219,
+ ACHIEV_10_SHUTOUT = 10054,
+ ACHIEV_25_SHUTOUT = 10055,
+ ACHIEV_10_SIEGE_OF_ULDUAR = 9999,
+ ACHIEV_25_SIEGE_OF_ULDUAR = 10003,
+ //ACHIEV_10_THREE_CAR_GARAGE = 10046, 10047, 10048,
+ //ACHIEV_25_THREE_CAR_GARAGE = 10049, 10050, 10051,
+ ACHIEV_10_UNBROKEN = 10044,
+ ACHIEV_25_UNBROKEN = 10045,
+};
+
+static Position Center[]=
+{
+ {354.8771, -12.90240, 409.803650},
+};
+
+struct boss_flame_leviathanAI : public BossAI
+{
+ boss_flame_leviathanAI(Creature* pCreature) : BossAI(pCreature, TYPE_LEVIATHAN), vehicle(pCreature->GetVehicleKit())
+ {
+ assert(vehicle);
+
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ Vehicle* vehicle;
+ uint8 uiActiveTowers;
+
+ void Reset()
+ {
+ _Reset();
+ assert(vehicle);
+ uiActiveTowers = 0;
+ me->SetReactState(REACT_AGGRESSIVE);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ _EnterCombat();
+ DoScriptText(SAY_AGGRO, me);
+ me->SetReactState(REACT_DEFENSIVE);
+ events.ScheduleEvent(EVENT_PURSUE, 0);
+ events.ScheduleEvent(EVENT_MISSILE, 1500);
+ events.ScheduleEvent(EVENT_VENT, 20000);
+ events.ScheduleEvent(EVENT_SPEED, 15000);
+ events.ScheduleEvent(EVENT_SUMMON, 0);
+
+ if (Creature *turret = CAST_CRE(vehicle->GetPassenger(SEAT_TURRET)))
+ turret->AI()->DoZoneInCombat();
+ }
+
+ // TODO: effect 0 and effect 1 may be on different target
+ void SpellHitTarget(Unit* pTarget, const SpellEntry* pSpell)
+ {
+ if (pSpell->Id == SPELL_PURSUED)
+ AttackStart(pTarget);
+ }
+
+ void JustDied(Unit* /*victim*/)
+ {
+ _JustDied();
+ DoScriptText(SAY_DEATH, me);
+ if (pInstance)
+ {
+ if (uiActiveTowers)
+ {
+ switch (uiActiveTowers)
+ {
+ case 4:
+ pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_10_ORBIT_UARY, ACHIEV_25_ORBIT_UARY));
+ break;
+ case 3:
+ pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_10_NUKED_FROM_ORBIT, ACHIEV_25_NUKED_FROM_ORBIT));
+ break;
+ case 2:
+ pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_10_ORBITAL_DEVASTATION, ACHIEV_25_ORBITAL_DEVASTATION));
+ break;
+ case 1:
+ pInstance->DoCompleteAchievement(RAID_MODE(ACHIEV_10_ORBITAL_BOMBARDMENT, ACHIEV_25_ORBITAL_BOMBARDMENT));
+ break;
+ }
+ }
+ }
+ }
+
+ void SpellHit(Unit* /*caster*/, const SpellEntry* pSpell)
+ {
+ if (pSpell->Id == 62472)
+ vehicle->InstallAllAccessories();
+ else if (pSpell->Id == SPELL_ELECTROSHOCK)
+ me->InterruptSpell(CURRENT_CHANNELED_SPELL);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!me->isInCombat())
+ return;
+
+ if (me->getThreatManager().isThreatListEmpty())
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ uint32 eventId = events.GetEvent();
+ if (!me->getVictim())
+ eventId = EVENT_PURSUE;
+
+ switch(eventId)
+ {
+ case 0: break; // this is a must
+ case EVENT_PURSUE:
+ DoCastAOE(SPELL_PURSUED, true);
+ //events.RepeatEvent(35000); // this should not be used because eventId may be overriden
+ events.RescheduleEvent(EVENT_PURSUE, 35000);
+ if (!me->getVictim()) // all siege engines and demolishers are dead
+ UpdateVictim(); // begin to kill other things
+ return;
+ case EVENT_MISSILE:
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_MISSILE_BARRAGE);
+ events.RepeatEvent(1500);
+ return;
+ case EVENT_VENT:
+ DoCastAOE(SPELL_FLAME_VENTS);
+ events.RepeatEvent(20000);
+ return;
+ case EVENT_SPEED:
+ DoCastAOE(SPELL_GATHERING_SPEED);
+ events.RepeatEvent(15000);
+ return;
+ case EVENT_SUMMON:
+ if (summons.size() < 15) // 4seat+1turret+10lift
+ if (Creature* pLift = DoSummonFlyer(MOB_MECHANOLIFT, me, urand(20,40), 50, 0))
+ pLift->GetMotionMaster()->MoveRandom(100);
+ events.RepeatEvent(2000);
+ return;
+ case EVENT_THORIM_S_HAMMER: // Tower of Storms
+ DoCast(me, SPELL_THORIM_S_HAMMER);
+ events.RepeatEvent(urand(60000, 120000));
+ return;
+ case EVENT_MIMIRON_S_INFERNO: // Tower of Flames
+ DoCast(me->getVictim(), SPELL_MIMIRON_S_INFERNO);
+ events.RepeatEvent(urand(60000, 120000));
+ return;
+ case EVENT_HODIR_S_FURY: // Tower of Frost
+ DoCast(me->getVictim(), SPELL_HODIR_S_FURY);
+ events.RepeatEvent(urand(60000, 120000));
+ return;
+ case EVENT_FREYA_S_WARD: // Tower of Nature
+ DoCast(me, SPELL_FREYA_S_WARD);
+ events.RepeatEvent(urand(60000, 120000));
+ return;
+ default:
+ events.PopEvent();
+ break;
+ }
+ DoSpellAttackIfReady(SPELL_BATTERING_RAM);
+ }
+
+ void DoAction(const int32 uiAction)
+ {
+ // Start encounter
+ if (uiAction == 10)
+ {
+ me->GetMotionMaster()->MovePoint(0, Center[0]);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ return;
+ }
+ /*
+ Tower event triggers
+ General TODO:
+ Yells
+
+ Actions:
+ DoAction(0): Activate hard-mode. Buff up leviathan's AP & health, schedule all the tower spells.
+ Should be triggered on Lore Keeper's script
+ DoAction(1-4): A tower have been destroyed, debuff leviathan's AP & health
+ DoAction(1); Tower of Storms has been destroyed, deschedule spell Thorim's Hammer
+ DoAction(2): Tower of Flames has been destroyed, deschedule spell Mimiron's Inferno
+ DoAction(3): Tower of Frost has been destroyed, deschedule spell Hodir's Fury
+ DoAction(4): Tower of Nature has been destroyed, deschedule spell Freya's Ward
+ */
+
+ if (uiAction) // Tower destruction, debuff leviathan AP & health
+ {
+ --uiActiveTowers;
+ }
+
+ switch (uiAction)
+ {
+ case 0: // Activate hard-mode
+ events.ScheduleEvent(EVENT_THORIM_S_HAMMER, urand(30000,60000));
+ events.ScheduleEvent(EVENT_MIMIRON_S_INFERNO, urand(30000,60000));
+ events.ScheduleEvent(EVENT_HODIR_S_FURY, urand(30000,60000));
+ events.ScheduleEvent(EVENT_FREYA_S_WARD, urand(30000,60000));
+ uiActiveTowers=4;
+ break;
+ case 1: // Tower of Storms destroyed
+ events.CancelEvent(EVENT_THORIM_S_HAMMER);
+ break;
+ case 2: // Tower of Flames destroyed
+ events.CancelEvent(EVENT_MIMIRON_S_INFERNO);
+ break;
+ case 3: // Tower of Frost destroyed
+ events.CancelEvent(EVENT_HODIR_S_FURY);
+ break;
+ case 4: // Tower of Nature destroyed
+ events.CancelEvent(EVENT_FREYA_S_WARD);
+ break;
+ }
+ }
+};
+
+//#define BOSS_DEBUG
+
+struct boss_flame_leviathan_seatAI : public PassiveAI
+{
+ boss_flame_leviathan_seatAI(Creature *c) : PassiveAI(c), vehicle(c->GetVehicleKit())
+ {
+ assert(vehicle);
+#ifdef BOSS_DEBUG
+ me->SetReactState(REACT_AGGRESSIVE);
+#endif
+ }
+
+ Vehicle* vehicle;
+
+#ifdef BOSS_DEBUG
+ void MoveInLineOfSight(Unit *who)
+ {
+ if (who->GetTypeId() == TYPEID_PLAYER && CAST_PLR(who)->isGameMaster()
+ && !who->GetVehicle() && vehicle->GetPassenger(SEAT_TURRET))
+ who->EnterVehicle(vehicle, SEAT_PLAYER);
+ }
+#endif
+
+ void PassengerBoarded(Unit* who, int8 seatId, bool apply)
+ {
+ if (!me->GetVehicle())
+ return;
+
+ if (seatId == SEAT_PLAYER)
+ {
+ if (!apply)
+ return;
+
+ if (Creature* turret = CAST_CRE(vehicle->GetPassenger(SEAT_TURRET)))
+ {
+ turret->setFaction(me->GetVehicleBase()->getFaction());
+ turret->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable
+ turret->AI()->AttackStart(who);
+ }
+ if (Unit* device = vehicle->GetPassenger(SEAT_DEVICE))
+ {
+ device->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ device->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
+ }
+ else if (seatId == SEAT_TURRET)
+ {
+ if (apply)
+ return;
+
+ if (Unit* device = vehicle->GetPassenger(SEAT_DEVICE))
+ {
+ device->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ device->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable
+ }
+ }
+ }
+};
+
+struct boss_flame_leviathan_defense_turretAI : public TurretAI
+{
+ boss_flame_leviathan_defense_turretAI(Creature *c) : TurretAI(c) {}
+
+ void DamageTaken(Unit* who, uint32 &damage)
+ {
+ if (!CanAIAttack(who))
+ damage = 0;
+ }
+
+ bool CanAIAttack(const Unit *who) const
+ {
+ if (who->GetTypeId() != TYPEID_PLAYER || !who->GetVehicle() || who->GetVehicleBase()->GetEntry() != 33114)
+ return false;
+ return true;
+ }
+};
+
+struct boss_flame_leviathan_overload_deviceAI : public PassiveAI
+{
+ boss_flame_leviathan_overload_deviceAI(Creature* pCreature) : PassiveAI(pCreature) {}
+
+ void DoAction(const int32 param)
+ {
+ if (param == EVENT_SPELLCLICK)
+ {
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ if (me->GetVehicle())
+ {
+ if (Unit* pPlayer = me->GetVehicle()->GetPassenger(SEAT_PLAYER))
+ {
+ pPlayer->ExitVehicle();
+ me->GetVehicleBase()->CastSpell(pPlayer, SPELL_SMOKE_TRAIL, true);
+ if (Unit* leviathan = me->GetVehicleBase()->GetVehicleBase())
+ pPlayer->GetMotionMaster()->MoveKnockbackFrom(leviathan->GetPositionX(), leviathan->GetPositionY(), 30, 30);
+ }
+ }
+ }
+ }
+};
+
+struct boss_flame_leviathan_safety_containerAI : public PassiveAI
+{
+ boss_flame_leviathan_safety_containerAI(Creature *c) : PassiveAI(c) {}
+
+ void MovementInform(uint32 /*type*/, uint32 id)
+ {
+ if (id == me->GetEntry())
+ {
+ if (Creature* pLiquid = DoSummon(MOB_LIQUID, me, 0))
+ pLiquid->CastSpell(pLiquid, 62494, true);
+ me->DisappearAndDie(); // this will relocate creature to sky
+ }
+ }
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ if (!me->GetVehicle() && me->isSummon() && me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)
+ me->GetMotionMaster()->MoveFall(409.8f, me->GetEntry());
+ }
+};
+
+struct spell_pool_of_tarAI : public TriggerAI
+{
+ spell_pool_of_tarAI(Creature *c) : TriggerAI(c)
+ {
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
+
+ void DamageTaken(Unit * /*who*/, uint32 &damage)
+ {
+ damage = 0;
+ }
+
+ void SpellHit(Unit* /*caster*/, const SpellEntry *spell)
+ {
+ if (spell->SchoolMask & SPELL_SCHOOL_MASK_FIRE && !me->HasAura(SPELL_BLAZE))
+ me->CastSpell(me, SPELL_BLAZE, true);
+ }
+};
+
+struct npc_colossusAI : public ScriptedAI
+{
+ npc_colossusAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance *pInstance;
+ Position pPos;
+
+ void JustDied(Unit* /*Who*/)
+ {
+ if (me->GetHomePosition().IsInDist(Center,50.f))
+ {
+ if (pInstance)
+ pInstance->SetData(TYPE_COLOSSUS,pInstance->GetData(TYPE_COLOSSUS)+1);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+ }
+};
+
+CreatureAI* GetAI_boss_flame_leviathan(Creature* pCreature)
+{
+ return new boss_flame_leviathanAI (pCreature);
+}
+
+CreatureAI* GetAI_boss_flame_leviathan_seat(Creature* pCreature)
+{
+ return new boss_flame_leviathan_seatAI (pCreature);
+}
+
+CreatureAI* GetAI_boss_flame_leviathan_defense_turret(Creature* pCreature)
+{
+ return new boss_flame_leviathan_defense_turretAI (pCreature);
+}
+
+CreatureAI* GetAI_boss_flame_leviathan_overload_device(Creature* pCreature)
+{
+ return new boss_flame_leviathan_overload_deviceAI (pCreature);
+}
+
+CreatureAI* GetAI_boss_flame_leviathan_safety_containerAI(Creature* pCreature)
+{
+ return new boss_flame_leviathan_safety_containerAI(pCreature);
+}
+
+CreatureAI* GetAI_spell_pool_of_tar(Creature* pCreature)
+{
+ return new spell_pool_of_tarAI (pCreature);
+}
+
+CreatureAI* GetAI_npc_colossus(Creature* pCreature)
+{
+ return new npc_colossusAI(pCreature);
+}
+
+void AddSC_boss_flame_leviathan()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_flame_leviathan";
+ newscript->GetAI = &GetAI_boss_flame_leviathan;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_flame_leviathan_seat";
+ newscript->GetAI = &GetAI_boss_flame_leviathan_seat;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_flame_leviathan_defense_turret";
+ newscript->GetAI = &GetAI_boss_flame_leviathan_defense_turret;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_flame_leviathan_overload_device";
+ newscript->GetAI = &GetAI_boss_flame_leviathan_overload_device;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_flame_leviathan_safety_container";
+ newscript->GetAI = &GetAI_boss_flame_leviathan_safety_containerAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "spell_pool_of_tar";
+ newscript->GetAI = &GetAI_spell_pool_of_tar;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_colossus";
+ newscript->GetAI = &GetAI_npc_colossus;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/ulduar/boss_freya.cpp b/src/server/scripts/northrend/ulduar/ulduar/boss_freya.cpp
new file mode 100644
index 00000000000..ee995878a0e
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/boss_freya.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+
+enum Yells
+{
+ SAY_AGGRO = -1603180,
+ SAY_AGGRO_WITH_ELDER = -1603181,
+ SAY_SLAY_1 = -1603182,
+ SAY_SLAY_2 = -1603183,
+ SAY_DEATH = -1603184,
+ SAY_BERSERK = -1603185,
+ SAY_SUMMON_CONSERVATOR = -1603186,
+ SAY_SUMMON_TRIO = -1603187,
+ SAY_SUMMON_LASHERS = -1603188,
+ SAY_YS_HELP = -1603189,
+
+ // Elder Brightleaf
+ SAY_BRIGHTLEAF_AGGRO = -1603190,
+ SAY_BRIGHTLEAF_SLAY_1 = -1603191,
+ SAY_BRIGHTLEAF_SLAY_2 = -1603192,
+ SAY_BRIGHTLEAF_DEATH = -1603193,
+
+ // Elder Ironbranch
+ SAY_IRONBRANCH_AGGRO = -1603194,
+ SAY_IRONBRANCH_SLAY_1 = -1603195,
+ SAY_IRONBRANCH_SLAY_2 = -1603196,
+ SAY_IRONBRANCH_DEATH = -1603197,
+
+ // Elder Stonebark
+ SAY_STONEBARK_AGGRO = -1603198,
+ SAY_STONEBARK_SLAY_1 = -1603199,
+ SAY_STONEBARK_SLAY_2 = -1603200,
+ SAY_STONEBARK_DEATH = -1603201,
+};
+
+enum
+{
+ // Con-speed-atory timed achievement.
+ // TODO Should be started when 1st trash is killed.
+ ACHIEV_CON_SPEED_ATORY_START_EVENT = 21597,
+ SPELL_ACHIEVEMENT_CHECK = 65074,
+
+ // Lumberjacked timed achievement.
+ // TODO should be started when 1st elder is killed.
+ // Spell should be casted when 3rd elder is killed.
+ ACHIEV_LUMBERJACKED = 21686,
+ SPELL_LUMBERJACKED_ACHIEVEMENT_CHECK = 65296,
+};
+
+struct boss_freyaAI : public BossAI
+{
+ boss_freyaAI(Creature* pCreature) : BossAI(pCreature, TYPE_FREYA)
+ {
+ }
+
+ void Reset()
+ {
+ _Reset();
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void JustDied(Unit * /*victim*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ _JustDied();
+
+ // cast is not rewarding the achievement.
+ // DoCast(SPELL_ACHIEVEMENT_CHECK);
+ instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_ACHIEVEMENT_CHECK);
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ _EnterCombat();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+//SPELLS TODO:
+
+//
+ DoMeleeAttackIfReady();
+
+ EnterEvadeIfOutOfCombatArea(diff);
+ }
+};
+
+CreatureAI* GetAI_boss_freya(Creature* pCreature)
+{
+ return new boss_freyaAI(pCreature);
+}
+
+void AddSC_boss_freya()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_freya";
+ newscript->GetAI = &GetAI_boss_freya;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp b/src/server/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp
new file mode 100644
index 00000000000..f84c638d3e3
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/boss_general_vezax.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+
+enum Yells
+{
+ SAY_AGGRO = -1603290,
+ SAY_SLAY_1 = -1603291,
+ SAY_SLAY_2 = -1603292,
+ SAY_KITE = -1603293,
+ SAY_DEATH = -1603294,
+ SAY_BERSERK = -1603295,
+ SAY_HARDMODE_ON = -1603296,
+};
diff --git a/src/server/scripts/northrend/ulduar/ulduar/boss_hodir.cpp b/src/server/scripts/northrend/ulduar/ulduar/boss_hodir.cpp
new file mode 100644
index 00000000000..6facd8ac639
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/boss_hodir.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+
+enum Yells
+{
+ SAY_AGGRO = -1603210,
+ SAY_SLAY_1 = -1603211,
+ SAY_SLAY_2 = -1603212,
+ SAY_FLASH_FREEZE = -1603213,
+ SAY_STALACTITE = -1603214,
+ SAY_DEATH = -1603215,
+ SAY_BERSERK = -1603216,
+ SAY_YS_HELP = -1603217,
+ SAY_HARD_MODE_MISSED = -1603218,
+};
+
+struct boss_hodirAI : public BossAI
+{
+ boss_hodirAI(Creature *pCreature) : BossAI(pCreature, TYPE_HODIR)
+ {
+ }
+
+ void Reset()
+ {
+ _Reset();
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void JustDied(Unit * /*victim*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ _JustDied();
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ _EnterCombat();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+//SPELLS TODO:
+
+//
+ DoMeleeAttackIfReady();
+
+ EnterEvadeIfOutOfCombatArea(diff);
+ }
+};
+
+CreatureAI* GetAI_boss_hodir(Creature* pCreature)
+{
+ return new boss_hodirAI(pCreature);
+}
+
+void AddSC_boss_hodir()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_hodir";
+ newscript->GetAI = &GetAI_boss_hodir;
+ newscript->RegisterSelf();
+
+}
diff --git a/src/server/scripts/northrend/ulduar/ulduar/boss_ignis.cpp b/src/server/scripts/northrend/ulduar/ulduar/boss_ignis.cpp
new file mode 100644
index 00000000000..05f9ecd3c66
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/boss_ignis.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+
+#define SPELL_FLAME_JETS 62680
+#define SPELL_SCORCH 62546
+#define SPELL_SLAG_POT 62717
+
+enum Yells
+{
+ SAY_AGGRO = -1603220,
+ SAY_SLAY_1 = -1603221,
+ SAY_SLAY_2 = -1603222,
+ SAY_DEATH = -1603223,
+ SAY_SUMMON = -1603224,
+ SAY_SLAG_POT = -1603225,
+ SAY_SCORCH_1 = -1603226,
+ SAY_SCORCH_2 = -1603227,
+ SAY_BERSERK = -1603228,
+};
+
+enum
+{
+ ACHIEV_TIMED_START_EVENT = 20951,
+};
+
+struct boss_ignis_AI : public BossAI
+{
+ boss_ignis_AI(Creature *pCreature) : BossAI(pCreature, TYPE_IGNIS) {}
+
+ uint32 uiFlameJetsTimer;
+ uint32 uiScorchTimer;
+ uint32 uiSlagPotTimer;
+
+ void Reset()
+ {
+ _Reset();
+ uiFlameJetsTimer = 32000;
+ uiScorchTimer = 100;
+ uiSlagPotTimer = 100;
+
+ if (instance)
+ instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO,me);
+ _EnterCombat();
+
+ if (instance)
+ instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ }
+
+ void KilledUnit(Unit* /*victim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void JustDied(Unit * /*victim*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ _JustDied();
+ }
+
+ void MoveInLineOfSight(Unit* /*who*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (me->GetPositionY() < 150 || me->GetPositionX() < 450) // Not Blizzlike, anti-exploit to prevent players from pulling bosses to vehicles.
+ {
+ me->RemoveAllAuras();
+ me->DeleteThreatList();
+ me->CombatStop(false);
+ me->GetMotionMaster()->MoveTargetedHome();
+ }
+
+ if (uiFlameJetsTimer <= diff)
+ {
+ DoCast(SPELL_FLAME_JETS);
+ uiFlameJetsTimer = 25000;
+ } else uiFlameJetsTimer -= diff;
+
+ if (uiScorchTimer <= diff)
+ {
+ DoScriptText(RAND(SAY_SCORCH_1,SAY_SCORCH_2), me);
+ DoCast(SPELL_SCORCH);
+ uiScorchTimer = 20000;
+ } else uiScorchTimer -= diff;
+
+ if (uiSlagPotTimer <= diff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ {
+ DoScriptText(SAY_SLAG_POT, me);
+ DoCast(pTarget, SPELL_SLAG_POT);
+ }
+ uiSlagPotTimer = 30000;
+ } else uiSlagPotTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_ignis(Creature* pCreature)
+{
+ return new boss_ignis_AI (pCreature);
+}
+void AddSC_boss_ignis()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_ignis";
+ newscript->GetAI = &GetAI_boss_ignis;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp b/src/server/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp
new file mode 100644
index 00000000000..2080b458a1b
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/boss_kologarn.cpp
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+#include "Vehicle.h"
+
+#define SPELL_ARM_DEAD_DAMAGE RAID_MODE(63629,63979)
+#define SPELL_TWO_ARM_SMASH RAID_MODE(63356,64003)
+#define SPELL_ONE_ARM_SMASH RAID_MODE(63573,64006)
+#define SPELL_STONE_SHOUT RAID_MODE(63716,64005)
+#define SPELL_PETRIFY_BREATH RAID_MODE(62030,63980)
+
+#define SPELL_STONE_GRIP RAID_MODE(62166,63981)
+#define SPELL_ARM_SWEEP RAID_MODE(63766,63983)
+
+enum Events
+{
+ EVENT_NONE = 0,
+ EVENT_SMASH,
+ EVENT_GRIP,
+ EVENT_SWEEP,
+};
+
+enum Yells
+{
+ SAY_AGGRO = -1603230,
+ SAY_SLAY_1 = -1603231,
+ SAY_SLAY_2 = -1603232,
+ SAY_LEFT_ARM_GONE = -1603233,
+ SAY_RIGHT_ARM_GONE = -1603234,
+ SAY_SHOCKWAVE = -1603235,
+ SAY_GRAB_PLAYER = -1603236,
+ SAY_DEATH = -1603237,
+ SAY_BERSERK = -1603238,
+};
+
+enum
+{
+ ACHIEV_DISARMED_START_EVENT = 21687,
+};
+
+struct boss_kologarnAI : public BossAI
+{
+ boss_kologarnAI(Creature *pCreature) : BossAI(pCreature, TYPE_KOLOGARN), vehicle(pCreature->GetVehicleKit()),
+ left(false), right(false)
+ {
+ assert(vehicle);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); // i think this is a hack, but there is no other way to disable his rotation
+ }
+
+ Vehicle *vehicle;
+ bool left, right;
+
+ void AttackStart(Unit *who)
+ {
+ me->Attack(who, true);
+ }
+
+ void JustDied(Unit * /*victim*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ _JustDied();
+ }
+
+ void KilledUnit(Unit* /*who*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_2,SAY_SLAY_2), me);
+ }
+
+ void PassengerBoarded(Unit *who, int8 /*seatId*/, bool apply)
+ {
+ if (who->GetTypeId() == TYPEID_UNIT)
+ {
+ if (who->GetEntry() == 32933)
+ left = apply;
+ else if (who->GetEntry() == 32934)
+ right = apply;
+
+ if (!apply && instance)
+ instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_DISARMED_START_EVENT);
+
+ who->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
+ CAST_CRE(who)->SetReactState(REACT_PASSIVE);
+ }
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ _EnterCombat();
+ events.ScheduleEvent(EVENT_SMASH, 5000);
+ events.ScheduleEvent(EVENT_SWEEP, 10000);
+ events.ScheduleEvent(EVENT_GRIP, 15000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ // TODO: because we are using hack, he is stunned and cannot cast, so we use triggered for every spell
+ switch(events.GetEvent())
+ {
+ case EVENT_NONE:
+ break;
+ case EVENT_SMASH:
+ if (left && right)
+ DoCastVictim(SPELL_TWO_ARM_SMASH, true);
+ else if (left || right)
+ DoCastVictim(SPELL_ONE_ARM_SMASH, true);
+ events.RepeatEvent(15000);
+ break;
+ case EVENT_SWEEP:
+ if (left)
+ DoCastAOE(SPELL_ARM_SWEEP, true);
+ events.RepeatEvent(15000);
+ break;
+ case EVENT_GRIP:
+ if (right)
+ DoCastAOE(SPELL_STONE_GRIP, true);
+ events.RepeatEvent(15000);
+ break;
+ default:
+ events.PopEvent();
+ break;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_kologarn(Creature* pCreature)
+{
+ return new boss_kologarnAI (pCreature);
+}
+
+void AddSC_boss_kologarn()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_kologarn";
+ newscript->GetAI = &GetAI_boss_kologarn;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp b/src/server/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp
new file mode 100644
index 00000000000..2b9994d5d9b
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/boss_mimiron.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+
+enum Yells
+{
+ SAY_AGGRO = -1603240,
+ SAY_HARDMODE_ON = -1603241,
+ SAY_MKII_ACTIVATE = -1603242,
+ SAY_MKII_SLAY_1 = -1603243,
+ SAY_MKII_SLAY_2 = -1603244,
+ SAY_MKII_DEATH = -1603245,
+ SAY_VX001_ACTIVATE = -1603246,
+ SAY_VX001_SLAY_1 = -1603247,
+ SAY_VX001_SLAY_2 = -1603248,
+ SAY_VX001_DEATH = -1603249,
+ SAY_AERIAL_ACTIVATE = -1603250,
+ SAY_AERIAL_SLAY_1 = -1603251,
+ SAY_AERIAL_SLAY_2 = -1603252,
+ SAY_AERIAL_DEATH = -1603253,
+ SAY_V07TRON_ACTIVATE = -1603254,
+ SAY_V07TRON_SLAY_1 = -1603255,
+ SAY_V07TRON_SLAY_2 = -1603256,
+ SAY_V07TRON_DEATH = -1603257,
+ SAY_BERSERK = -1603258,
+ SAY_YS_HELP = -1603259,
+};
diff --git a/src/server/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp b/src/server/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp
new file mode 100644
index 00000000000..c61f1046474
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/boss_razorscale.cpp
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: razorscale
+SDAuthor: MaXiMiUS
+SD%Complete: 65
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+
+//not in db
+#define SAY_AGGRO -2000000
+#define SAY_KILL -2000001
+#define SAY_PHASE_2_TRANS -2000002
+#define SAY_PHASE_3_TRANS -2000003
+#define EMOTE_BREATH -2000004
+
+enum Spells
+{
+ SPELL_FLAMEBUFFET = 64016,
+ SPELL_FIREBALL = 62796,
+
+ SPELL_WINGBUFFET = 62666,
+ SPELL_FLAMEBREATH = 63317,
+ SPELL_FUSEARMOR = 64771,
+ SPELL_DEVOURINGFLAME = 63014
+};
+
+enum Mobs
+{
+ NPC_DARK_RUNE_SENTINEL = 33846
+};
+
+struct boss_razorscaleAI : public BossAI
+{
+ boss_razorscaleAI(Creature *pCreature) : BossAI(pCreature, TYPE_RAZORSCALE) {}
+
+ uint8 Phase;
+
+ uint32 FlameBreathTimer;
+ uint32 FuseArmorTimer;
+ uint32 DevouringFlameTimer;
+ uint32 FlameBuffetTimer;
+ uint32 SummonAddsTimer;
+ uint32 WingBuffetTimer;
+ uint32 FireballTimer;
+ //uint32 StunTimer;
+ //uint32 CastSpellsTimer;
+
+ bool InitialSpawn;
+ bool IsFlying;
+
+ void Reset()
+ {
+ Phase = 1;
+
+ FlyPhase(Phase, 0);
+
+ FlameBreathTimer = 20000;
+ DevouringFlameTimer = 2000;
+ FuseArmorTimer = 15000;
+ FlameBuffetTimer = 3000;
+ SummonAddsTimer = 45000;
+ WingBuffetTimer = 17000;
+ FireballTimer = 18000;
+ //StunTimer = 30000;
+ //CastSpellsTimer = 0;
+
+ InitialSpawn = true;
+ IsFlying = true;
+
+ me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+ me->ApplySpellImmune(1, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ DoZoneInCombat();
+ }
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(SAY_KILL, me);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (me->GetPositionY() > -60 || me->GetPositionX() < 450) // Not Blizzlike, anti-exploit to prevent players from pulling bosses to vehicles.
+ {
+ me->RemoveAllAuras();
+ me->DeleteThreatList();
+ me->CombatStop(false);
+ me->GetMotionMaster()->MoveTargetedHome();
+ }
+
+ // Victim is not controlled by a player (should never happen)
+ if (me->getVictim() && !me->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself())
+ me->Kill(me->getVictim());
+
+ if ((me->GetHealth()*100 / me->GetMaxHealth()) < 99 && Phase == 1) // TODO: Only land (exit Phase 1) if brought down with harpoon guns! This is important!
+ {
+ Phase = 2;
+ DoScriptText(SAY_PHASE_2_TRANS, me); // Audio: "Move quickly! She won't remain grounded for long!"
+ }
+
+ if ((me->GetHealth()*100 / me->GetMaxHealth()) < 33 && Phase == 2) // Health under 33%, Razorscale can't fly anymore.
+ {
+ Phase = 3;
+ DoScriptText(SAY_PHASE_3_TRANS, me); // "Razorscale lands permanently!"
+ // TODO: Cast Devouring Flame on all harpoon guns simultaneously, briefly after Phase 3 starts (lasts until the harpoon guns are destroyed)
+ }
+
+ /*
+ if (Phase == 2 && CastSpellsTimer > 0) // 5 seconds of spell casting, after stun breaks, during Phase 2
+ {
+ if (CastSpellsTimer <= diff) // 5 seconds are up
+ Phase = 1; // Return to phase 1
+ else
+ CastSpellsTimer -= diff;
+ }*/
+
+ FlyPhase(Phase, diff);
+
+ if (Phase >= 2) // Ground Phase (Phase 3 = permanent ground phase)
+ {
+ if (FuseArmorTimer <= diff)
+ {
+ DoCastVictim(SPELL_FUSEARMOR);
+ FuseArmorTimer = 10000;
+ } else FuseArmorTimer -= diff;
+
+ if (WingBuffetTimer <= diff)
+ {
+ DoCast(SPELL_WINGBUFFET);
+ WingBuffetTimer = urand(7000,14000);
+ } else WingBuffetTimer -= diff;
+
+ if (FireballTimer <= diff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
+ {
+ me->SetInFront(pTarget);
+ DoCast(pTarget, SPELL_FIREBALL);
+ }
+
+ FireballTimer = 18000;
+ } else FireballTimer -= diff;
+
+ if (FlameBreathTimer <= diff)
+ {
+ DoScriptText(EMOTE_BREATH, me); // TODO: "Razorscale takes a deep breath..."
+ DoCastVictim(SPELL_FLAMEBREATH);
+ FlameBreathTimer = 15000;
+ WingBuffetTimer = 0;
+ } else FlameBreathTimer -= diff;
+
+ if (Phase == 3)
+ {
+ if (FlameBuffetTimer <= diff)
+ {
+ DoScriptText(EMOTE_BREATH, me);
+ std::list<Unit*> pTargets;
+ SelectTargetList(pTargets, RAID_MODE(3,9), SELECT_TARGET_RANDOM, 100, true);
+ uint8 i = 0;
+ for (std::list<Unit*>::const_iterator itr = pTargets.begin(); itr != pTargets.end();)
+ {
+ if (me->HasInArc(M_PI, *itr))
+ {
+ DoCast(*itr, SPELL_FLAMEBUFFET, true);
+ ++i;
+ }
+ if (++itr == pTargets.end() || i == RAID_MODE(3,9))
+ {
+ AttackStart(*--itr); // seems to attack targets randomly during perma-ground phase..
+ break;
+ }
+ }
+ FlameBuffetTimer = 25000;
+ } else FlameBuffetTimer -= diff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ else if (Phase == 1) //Flying Phase
+ {
+ if (InitialSpawn)
+ SummonAdds();
+
+ InitialSpawn = false;
+
+ if (FireballTimer <= diff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
+ {
+ me->SetInFront(pTarget);
+ DoCast(pTarget, SPELL_FIREBALL);
+ }
+
+ FireballTimer = 18000;
+ } else FireballTimer -= diff;
+
+ if (DevouringFlameTimer <= diff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
+ {
+ me->SetInFront(pTarget);
+ DoCast(pTarget, SPELL_DEVOURINGFLAME);
+ }
+
+ DevouringFlameTimer = 10000;
+ } else DevouringFlameTimer -= diff;
+
+ if (SummonAddsTimer <= diff)
+ SummonAdds();
+ else SummonAddsTimer -= diff;
+ }
+ }
+
+ void SummonAdds()
+ {
+ // TODO: Adds will come in waves from mole machines. One mole can spawn a Dark Rune Watcher
+ // with 1-2 Guardians, or a lone Sentinel. Up to 4 mole machines can spawn adds at any given time.
+ uint8 random = urand(1,4);
+ for (uint8 i = 0; i < random; ++i)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
+ {
+ float x = std::max(500.0f, std::min(650.0f, pTarget->GetPositionX() + irand(-20,20))); // Safe range is between 500 and 650
+ float y = std::max(-235.0f, std::min(-145.0f, pTarget->GetPositionY() + irand(-20,20))); // Safe range is between -235 and -145
+ float z = me->GetBaseMap()->GetHeight(x, y, MAX_HEIGHT); // Ground level
+ // TODO: Spawn drillers, then spawn adds 5 seconds later
+ if (Creature *pAdd = me->SummonCreature(NPC_DARK_RUNE_SENTINEL, x, y, z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000))
+ pAdd->AI()->AttackStart(pTarget);
+ }
+ }
+ SummonAddsTimer = 45000;
+ }
+
+ void FlyPhase(uint8 Phase, const uint32 /*diff*/)
+ {
+ const float x = 587.54;
+ const float y = -174.92;
+ const float GroundLevel = me->GetBaseMap()->GetHeight(x, y, MAX_HEIGHT);
+ const float FlightHeight = GroundLevel + 4.0f; // TODO: Fly out of range of attacks (442 is sufficient height for this), minus ~(10*number of harpoon gun chains attached to Razorscale)
+
+ if (Phase == 1) // Always flying during Phase 1
+ IsFlying = true;
+
+ me->SetFlying(IsFlying);
+ me->SendMovementFlagUpdate();
+ me->SetSpeed(MOVE_WALK, IsFlying ? 7.0f : 2.5f, IsFlying);
+
+ if (Phase == 1) // Flying Phase
+ {
+ if (me->GetPositionZ() > FlightHeight) // Correct height, stop moving
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ else // Incorrect height
+ {
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ me->GetMotionMaster()->MovePoint(0, x, y, FlightHeight + 0.5f); // Fly to slightly above (x, y, FlightHeight)
+ }
+ }
+ else // Ground Phases
+ {
+ const float CurrentGroundLevel = me->GetBaseMap()->GetHeight(me->GetPositionX(), me->GetPositionY(), MAX_HEIGHT);
+ //if (StunTimer == 30000) // Only fly around if not stunned.
+ //{
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ if (IsFlying && me->GetPositionZ() > CurrentGroundLevel) // Fly towards the ground
+ me->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), CurrentGroundLevel);
+ // TODO: Swoop up just before landing
+ else
+ IsFlying = false; // Landed, no longer flying
+ //}
+
+ //if (!IsFlying &&Phase == 2 && CastSpellsTimer == 0 && StunTimer >= diff) // No longer flying, non-permanent ground phase, and not casting spells
+ //{
+ // TODO: Add stun here. 30 second stun after Razorscale is grounded by harpoon guns
+ //StunTimer -= diff;
+ //}
+ //else if (StunTimer != 30000 && (StunTimer < 0 || Phase == 3)) // Stun is active, and needs to end. Note: Stun breaks instantly if Phase 3 starts
+ //{
+ // TODO: Remove stun here.
+ //DoCast(SPELL_WINGBUFFET); // "Used in the beginning of the phase."
+ //WingBuffetTimer = urand(7000,14000);
+ //StunTimer = 30000; // Reinitialize the stun timer
+ //if (Phase == 2) // Non-permanent ground phase
+ // CastSpellsTimer = 5000; // Five seconds of casting before returning to Phase 1
+ //}
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_razorscale(Creature* pCreature)
+{
+ return new boss_razorscaleAI (pCreature);
+}
+
+void AddSC_boss_razorscale()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_razorscale";
+ newscript->GetAI = &GetAI_boss_razorscale;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/ulduar/boss_thorim.cpp b/src/server/scripts/northrend/ulduar/ulduar/boss_thorim.cpp
new file mode 100644
index 00000000000..bbab077e10e
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/boss_thorim.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+
+enum Yells
+{
+ SAY_AGGRO_1 = -1603270,
+ SAY_AGGRO_2 = -1603271,
+ SAY_SPECIAL_1 = -1603272,
+ SAY_SPECIAL_2 = -1603273,
+ SAY_SPECIAL_3 = -1603274,
+ SAY_JUMPDOWN = -1603275,
+ SAY_SLAY_1 = -1603276,
+ SAY_SLAY_2 = -1603277,
+ SAY_BERSERK = -1603278,
+ SAY_WIPE = -1603279,
+ SAY_DEATH = -1603280,
+ SAY_END_NORMAL_1 = -1603281,
+ SAY_END_NORMAL_2 = -1603282,
+ SAY_END_NORMAL_3 = -1603283,
+ SAY_END_HARD_1 = -1603284,
+ SAY_END_HARD_2 = -1603285,
+ SAY_END_HARD_3 = -1603286,
+ SAY_YS_HELP = -1603287,
+};
+
+struct boss_thorimAI : public BossAI
+{
+ boss_thorimAI(Creature* pCreature) : BossAI(pCreature, TYPE_THORIM)
+ {
+ }
+
+ void Reset()
+ {
+ _Reset();
+ }
+
+ void EnterEvadeMode()
+ {
+ DoScriptText(SAY_WIPE, me);
+ _EnterEvadeMode();
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void JustDied(Unit * /*victim*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ _JustDied();
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2), me);
+ _EnterCombat();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+//SPELLS TODO:
+
+//
+ DoMeleeAttackIfReady();
+
+ EnterEvadeIfOutOfCombatArea(diff);
+ }
+};
+
+CreatureAI* GetAI_boss_thorim(Creature* pCreature)
+{
+ return new boss_thorimAI(pCreature);
+}
+
+void AddSC_boss_thorim()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_thorim";
+ newscript->GetAI = &GetAI_boss_thorim;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/ulduar/boss_xt002.cpp b/src/server/scripts/northrend/ulduar/ulduar/boss_xt002.cpp
new file mode 100644
index 00000000000..58123951d2f
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/boss_xt002.cpp
@@ -0,0 +1,850 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ TODO:
+ Add achievments
+ Boombot explosion only hurt allies to the npc at the moment
+ Boombot explosion visual
+ Test the enrage timer
+ Fix gravity bomb - tractor beam.
+ Fix void zone spell
+ If the boss is to close to a scrap pile -> no summon
+ make the life sparks visible...
+*/
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+
+enum Spells
+{
+ SPELL_TYMPANIC_TANTRUM = 62776,
+ SPELL_SEARING_LIGHT_10 = 63018,
+ SPELL_SEARING_LIGHT_25 = 65121,
+
+ SPELL_GRAVITY_BOMB_10 = 63024,
+ SPELL_GRAVITY_BOMB_25 = 63234,
+ SPELL_GRAVITY_BOMB_AURA_10 = 63025,
+ SPELL_GRAVITY_BOMB_AURA_25 = 63233,
+
+ SPELL_HEARTBREAK_10 = 65737,
+ SPELL_HEARTBREAK_25 = 64193,
+
+ SPELL_ENRAGE = 26662,
+
+ //------------------VOID ZONE--------------------
+ SPELL_VOID_ZONE_10 = 64203,
+ SPELL_VOID_ZONE_25 = 64235,
+
+ // Life Spark
+ SPELL_STATIC_CHARGED_10 = 64227,
+ SPELL_STATIC_CHARGED_25 = 64236,
+ SPELL_SHOCK = 64230,
+
+ //----------------XT-002 HEART-------------------
+ SPELL_EXPOSED_HEART = 63849,
+
+ //---------------XM-024 PUMMELLER----------------
+ SPELL_ARCING_SMASH = 8374,
+ SPELL_TRAMPLE = 5568,
+ SPELL_UPPERCUT = 10966,
+
+ //------------------BOOMBOT-----------------------
+ SPELL_BOOM = 62834,
+};
+
+enum Timers
+{
+ TIMER_TYMPANIC_TANTRUM_MIN = 32000,
+ TIMER_TYMPANIC_TANTRUM_MAX = 36000,
+ TIMER_SEARING_LIGHT = 20000,
+ TIMER_SPAWN_LIFE_SPARK = 9000,
+ TIMER_GRAVITY_BOMB = 20000,
+ TIMER_HEART_PHASE = 30000,
+ TIMER_ENRAGE = 600000,
+ TIMER_GRAVITY_BOMB_AURA = 8900,
+
+ TIMER_VOID_ZONE = 3000,
+
+ // Life Spark
+ TIMER_SHOCK = 12000,
+
+ // Pummeller
+ // Timers may be off
+ TIMER_ARCING_SMASH = 27000,
+ TIMER_TRAMPLE = 22000,
+ TIMER_UPPERCUT = 17000,
+
+ TIMER_SPAWN_ADD = 12000,
+};
+
+enum Creatures
+{
+ NPC_VOID_ZONE = 34001,
+ NPC_LIFE_SPARK = 34004,
+ NPC_XT002_HEART = 33329,
+ NPC_XS013_SCRAPBOT = 33343,
+ NPC_XM024_PUMMELLER = 33344,
+ NPC_XE321_BOOMBOT = 33346,
+};
+
+enum Actions
+{
+ ACTION_ENTER_HARD_MODE = 0,
+};
+
+enum XT002Data
+{
+ DATA_TRANSFERED_HEALTH = 0,
+};
+
+enum Yells
+{
+ SAY_AGGRO = -1603300,
+ SAY_HEART_OPENED = -1603301,
+ SAY_HEART_CLOSED = -1603302,
+ SAY_TYMPANIC_TANTRUM = -1603303,
+ SAY_SLAY_1 = -1603304,
+ SAY_SLAY_2 = -1603305,
+ SAY_BERSERK = -1603306,
+ SAY_DEATH = -1603307,
+ SAY_SUMMON = -1603308,
+};
+
+enum
+{
+ ACHIEV_TIMED_START_EVENT = 21027,
+};
+
+//#define GRAVITY_BOMB_DMG_MIN_10 11700
+//#define GRAVITY_BOMB_DMG_MAX_10 12300
+//#define GRAVITY_BOMB_DMG_MIN_25 14625
+//#define GRAVITY_BOMB_DMG_MAX_25 15375
+//#define GRAVITY_BOMB_RADIUS 12
+
+//#define VOID_ZONE_DMG_10 5000
+//#define VOID_ZONE_DMG_25 7500
+//#define VOID_ZONE_RADIUS
+
+
+/************************************************
+-----------------SPAWN LOCATIONS-----------------
+************************************************/
+//Shared Z-level
+#define SPAWN_Z 412
+//Lower right
+#define LR_X 796
+#define LR_Y -94
+//Lower left
+#define LL_X 796
+#define LL_Y 57
+//Upper right
+#define UR_X 890
+#define UR_Y -82
+//Upper left
+#define UL_X 894
+#define UL_Y 62
+
+/*-------------------------------------------------------
+ *
+ * XT-002 DECONSTRUCTOR
+ *
+ *///----------------------------------------------------
+struct boss_xt002_AI : public BossAI
+{
+ boss_xt002_AI(Creature *pCreature) : BossAI(pCreature, TYPE_XT002)
+ {
+ }
+
+ uint32 uiSearingLightTimer;
+ uint32 uiSpawnLifeSparkTimer;
+ uint32 uiGravityBombTimer;
+ uint32 uiGravityBombAuraTimer;
+ uint32 uiTympanicTantrumTimer;
+ uint32 uiHeartPhaseTimer;
+ uint32 uiSpawnAddTimer;
+ uint32 uiEnrageTimer;
+
+ bool searing_light_active;
+ uint64 uiSearingLightTarget;
+
+ bool gravity_bomb_active;
+ uint64 uiGravityBombTarget;
+
+ uint8 phase;
+ uint8 heart_exposed;
+ bool enraged;
+
+ uint32 transferHealth;
+ bool enterHardMode;
+ bool hardMode;
+
+ void Reset()
+ {
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
+
+ //Makes XT-002 to cast a light bomb 10 seconds after aggro.
+ uiSearingLightTimer = TIMER_SEARING_LIGHT/2;
+ uiSpawnLifeSparkTimer = TIMER_SPAWN_LIFE_SPARK;
+ uiGravityBombTimer = TIMER_GRAVITY_BOMB;
+ uiGravityBombAuraTimer = TIMER_GRAVITY_BOMB_AURA;
+ uiHeartPhaseTimer = TIMER_HEART_PHASE;
+ uiSpawnAddTimer = TIMER_SPAWN_ADD;
+ uiEnrageTimer = TIMER_ENRAGE;
+
+ //Tantrum is casted a bit slower the first time.
+ uiTympanicTantrumTimer = urand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX) * 2;
+
+ searing_light_active = false;
+ gravity_bomb_active = false;
+ enraged = false;
+ hardMode = false;
+ enterHardMode = false;
+
+ phase = 1;
+ heart_exposed = 0;
+
+ if (instance)
+ instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ _EnterCombat();
+
+ if (instance)
+ instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ }
+
+ void DoAction(const int32 action)
+ {
+ switch (action)
+ {
+ case ACTION_ENTER_HARD_MODE:
+ if (!hardMode)
+ {
+ hardMode = true;
+
+ // Enter hard mode
+ enterHardMode = true;
+
+ // set max health
+ me->SetHealth(me->GetMaxHealth());
+
+ // Get his heartbreak buff
+ me->CastSpell(me, RAID_MODE(SPELL_HEARTBREAK_10, SPELL_HEARTBREAK_25), true);
+ }
+ break;
+ }
+ }
+
+ void SetData(uint32 id, uint32 value)
+ {
+ switch(id)
+ {
+ case DATA_TRANSFERED_HEALTH:
+ transferHealth = value;
+ break;
+ }
+ }
+
+ void KilledUnit(Unit* /*victim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void JustDied(Unit * /*victim*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ _JustDied();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (enterHardMode)
+ {
+ SetPhaseOne();
+ enterHardMode = false;
+ }
+
+ // Handles spell casting. These spells only occur during phase 1 and hard mode
+ if (phase == 1 || hardMode)
+ {
+ if (uiSearingLightTimer <= diff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ DoCast(pTarget, RAID_MODE(SPELL_SEARING_LIGHT_10, SPELL_SEARING_LIGHT_25));
+ uiSearingLightTarget = pTarget->GetGUID();
+ }
+ uiSpawnLifeSparkTimer = TIMER_SPAWN_LIFE_SPARK;
+ if (hardMode)
+ searing_light_active = true;
+ uiSearingLightTimer = TIMER_SEARING_LIGHT;
+ } else uiSearingLightTimer -= diff;
+
+ if (uiGravityBombTimer <= diff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ DoCast(pTarget, RAID_MODE(SPELL_GRAVITY_BOMB_10,SPELL_GRAVITY_BOMB_25));
+ uiGravityBombTarget = pTarget->GetGUID();
+ }
+ uiGravityBombTimer = TIMER_GRAVITY_BOMB;
+ gravity_bomb_active = true;
+ } else uiGravityBombTimer -= diff;
+
+ if (uiTympanicTantrumTimer <= 0)
+ {
+ DoScriptText(SAY_TYMPANIC_TANTRUM, me);
+ DoCast(SPELL_TYMPANIC_TANTRUM);
+ uiTympanicTantrumTimer = urand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX);
+ } else uiTympanicTantrumTimer -= diff;
+ }
+
+ if (!hardMode)
+ {
+ if (phase == 1)
+ {
+ if (HealthBelowPct(75) && heart_exposed == 0)
+ {
+ exposeHeart();
+ }
+ else if (HealthBelowPct(50) && heart_exposed == 1)
+ {
+ exposeHeart();
+ }
+ else if (HealthBelowPct(25) && heart_exposed == 2)
+ {
+ exposeHeart();
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ else
+ {
+ //Stop moving
+ me->StopMoving();
+
+ //Start summoning adds
+ if (uiSpawnAddTimer <= diff)
+ {
+ DoScriptText(SAY_SUMMON, me);
+
+ // Spawn Pummeller
+ switch (rand() % 4)
+ {
+ case 0: me->SummonCreature(NPC_XM024_PUMMELLER, LR_X, LR_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
+ case 1: me->SummonCreature(NPC_XM024_PUMMELLER, LL_X, LL_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
+ case 2: me->SummonCreature(NPC_XM024_PUMMELLER, UR_X, UR_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
+ case 3: me->SummonCreature(NPC_XM024_PUMMELLER, UL_X, UL_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
+ }
+
+ // Spawn 5 Bombs
+ for (int8 n = 0; n < 5; n++)
+ {
+ //Some randomes are added so they wont spawn in a pile
+ switch(rand() % 4)
+ {
+ case 0: me->SummonCreature(NPC_XS013_SCRAPBOT, irand(LR_X - 3, LR_X + 3), irand(LR_Y - 3, LR_Y + 3), SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
+ case 1: me->SummonCreature(NPC_XS013_SCRAPBOT, irand(LL_X - 3, LL_X + 3), irand(LL_Y - 3, LL_Y + 3), SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
+ case 2: me->SummonCreature(NPC_XS013_SCRAPBOT, irand(UR_X - 3, UR_X + 3), irand(UR_Y - 3, UR_Y + 3), SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
+ case 3: me->SummonCreature(NPC_XS013_SCRAPBOT, irand(UL_X - 3, UL_X + 3), irand(UL_Y - 3, UL_Y + 3), SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
+ }
+ }
+
+ //Spawn 5 Scrapbots
+ switch (rand() % 4)
+ {
+ case 0: me->SummonCreature(NPC_XE321_BOOMBOT, LR_X, LR_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
+ case 1: me->SummonCreature(NPC_XE321_BOOMBOT, LL_X, LL_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
+ case 2: me->SummonCreature(NPC_XE321_BOOMBOT, UR_X, UR_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
+ case 3: me->SummonCreature(NPC_XE321_BOOMBOT, UL_X, UL_Y, SPAWN_Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); break;
+ }
+
+ uiSpawnAddTimer = TIMER_SPAWN_ADD;
+ } else uiSpawnAddTimer -= diff;
+
+ // Is the phase over?
+ if (uiHeartPhaseTimer <= diff)
+ {
+ DoScriptText(SAY_HEART_CLOSED, me);
+ SetPhaseOne();
+ }
+ else
+ uiHeartPhaseTimer -= diff;
+ }
+ }
+ else
+ {
+ // Adding life sparks when searing light debuff runs out if hard mode
+ if (searing_light_active)
+ {
+ if (uiSpawnLifeSparkTimer <= diff)
+ {
+ if (Unit *pSearingLightTarget = me->GetUnit(*me, uiSearingLightTarget))
+ pSearingLightTarget->SummonCreature(NPC_LIFE_SPARK, pSearingLightTarget->GetPositionX(), pSearingLightTarget->GetPositionY(), pSearingLightTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000);
+ uiSpawnLifeSparkTimer = TIMER_SPAWN_LIFE_SPARK;
+ searing_light_active = false;
+ } else uiSpawnLifeSparkTimer -= diff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ if (gravity_bomb_active)
+ {
+ if (uiGravityBombAuraTimer <= diff)
+ {
+ if (Unit *pGravityBombTarget = me->GetUnit(*me, uiGravityBombTarget))
+ {
+ pGravityBombTarget->RemoveAurasDueToSpell(RAID_MODE(SPELL_GRAVITY_BOMB_10,SPELL_GRAVITY_BOMB_25));
+ if (hardMode)
+ {
+ //Remains spawned for 3 minutes
+ pGravityBombTarget->SummonCreature(NPC_VOID_ZONE, pGravityBombTarget->GetPositionX(), pGravityBombTarget->GetPositionY(), pGravityBombTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 180000);
+ }
+ }
+
+ gravity_bomb_active = false;
+ uiGravityBombAuraTimer = TIMER_GRAVITY_BOMB_AURA;
+ //gravityBomb();
+ } else uiGravityBombAuraTimer -= diff;
+ }
+
+ //Enrage stuff
+ if (!enraged)
+ if (uiEnrageTimer <= diff)
+ {
+ DoScriptText(SAY_BERSERK, me);
+ DoCast(me, SPELL_ENRAGE);
+ enraged = true;
+ } else uiEnrageTimer -= diff;
+ }
+
+ void exposeHeart()
+ {
+ //Make untargetable
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+
+ //Summon the heart npc
+ me->SummonCreature(NPC_XT002_HEART, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 7, 0, TEMPSUMMON_TIMED_DESPAWN, TIMER_HEART_PHASE);
+
+ // Start "end of phase 2 timer"
+ uiHeartPhaseTimer = TIMER_HEART_PHASE;
+
+ //Phase 2 has offically started
+ phase = 2;
+ heart_exposed++;
+
+ //Reset the add spawning timer
+ uiSpawnAddTimer = TIMER_SPAWN_ADD;
+
+ DoScriptText(SAY_HEART_OPENED, me);
+ }
+
+ void SetPhaseOne()
+ {
+ uiSearingLightTimer = TIMER_SEARING_LIGHT / 2;
+ uiGravityBombTimer = TIMER_GRAVITY_BOMB;
+ uiTympanicTantrumTimer = urand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX);
+ uiSpawnAddTimer = TIMER_SPAWN_ADD;
+
+ if (!hardMode)
+ me->ModifyHealth(-((int32)transferHealth));
+
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ phase = 1;
+ }
+
+ // TODO: put in comment and kept for reference. The spell should be fixed properly in spell system, if necessary.
+ ////Have to do this the custom way since the original spell messes up player movement
+ //void gravityBomb()
+ //{
+ // uint32 maxDamage = RAID_MODE(GRAVITY_BOMB_DMG_MAX_10, GRAVITY_BOMB_DMG_MAX_25);
+ // uint32 minDamage = RAID_MODE(GRAVITY_BOMB_DMG_MIN_10, GRAVITY_BOMB_DMG_MIN_25);
+ // uint16 range = GRAVITY_BOMB_RADIUS;
+ // Map* pMap = me->GetMap();
+ // if (pMap && pMap->IsDungeon())
+ // {
+ // Map::PlayerList const &PlayerList = pMap->GetPlayers();
+ // for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ // {
+ // //If a player is within the range of the spell
+ // if (i->getSource() && i->getSource()->GetDistance2d(pGravityBombTarget) <= range)
+ // {
+ // //Deal damage to the victim
+ // int32 damage = urand(minDamage, maxDamage);
+ // i->getSource()->ModifyHealth(-damage);
+ // me->SendSpellNonMeleeDamageLog(i->getSource(), SPELL_GRAVITY_BOMB_AURA_10, damage, SPELL_SCHOOL_MASK_SHADOW, 0, 0, false, 0);
+
+ // //Replacing the tractor beam effect
+ // i->getSource()->JumpTo(pGravityBombTarget, 5);
+ // }
+ // }
+ // }
+ //}
+};
+
+CreatureAI* GetAI_boss_xt002(Creature* pCreature)
+{
+ return new boss_xt002_AI(pCreature);
+}
+
+/*-------------------------------------------------------
+ *
+ * XT-002 HEART
+ *
+ *///----------------------------------------------------
+struct mob_xt002_heartAI : public ScriptedAI
+{
+ mob_xt002_heartAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = pCreature->GetInstanceData();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_STUNNED);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(me, SPELL_EXPOSED_HEART);
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void JustDied(Unit * /*victim*/)
+ {
+ if (m_pInstance)
+ if (Creature* pXT002 = me->GetCreature(*me, m_pInstance->GetData64(TYPE_XT002)))
+ if (pXT002->AI())
+ pXT002->AI()->DoAction(ACTION_ENTER_HARD_MODE);
+
+ //removes the aura
+ me->RemoveAurasDueToSpell(SPELL_EXPOSED_HEART);
+ }
+
+ void DamageTaken(Unit * /*pDone*/, uint32 &damage)
+ {
+ if (Creature* pXT002 = me->GetCreature(*me, m_pInstance->GetData64(TYPE_XT002)))
+ if (pXT002->AI())
+ {
+ uint32 health = me->GetHealth();
+ health -= damage;
+ if (health < 0)
+ health = 0;
+
+ pXT002->AI()->SetData(DATA_TRANSFERED_HEALTH, me->GetMaxHealth() - health);
+ }
+ }
+};
+
+CreatureAI* GetAI_mob_xt002_heart(Creature* pCreature)
+{
+ return new mob_xt002_heartAI(pCreature);
+}
+
+/*-------------------------------------------------------
+ *
+ * XS-013 SCRAPBOT
+ *
+ *///----------------------------------------------------
+struct mob_scrapbotAI : public ScriptedAI
+{
+ mob_scrapbotAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = me->GetInstanceData();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ me->SetReactState(REACT_PASSIVE);
+
+ if (Creature* pXT002 = me->GetCreature(*me, m_pInstance->GetData64(TYPE_XT002)))
+ me->GetMotionMaster()->MoveChase(pXT002);
+ }
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ if (Creature* pXT002 = me->GetCreature(*me, m_pInstance->GetData64(TYPE_XT002)))
+ {
+ if (me->GetDistance2d(pXT002) <= 0.5)
+ {
+ // TODO Send raid message
+
+ // Increase health with 1 percent
+ pXT002->ModifyHealth(pXT002->GetMaxHealth() * 0.01);
+
+ // Despawns the scrapbot
+ me->ForcedDespawn();
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_mob_scrapbot(Creature* pCreature)
+{
+ return new mob_scrapbotAI(pCreature);
+}
+
+/*-------------------------------------------------------
+ *
+ * XM-024 PUMMELLER
+ *
+ *///----------------------------------------------------
+struct mob_pummellerAI : public ScriptedAI
+{
+ mob_pummellerAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* m_pInstance;
+ int32 uiArcingSmashTimer;
+ int32 uiTrampleTimer;
+ int32 uiUppercutTimer;
+
+ void Reset()
+ {
+ uiArcingSmashTimer = TIMER_ARCING_SMASH;
+ uiTrampleTimer = TIMER_TRAMPLE;
+ uiUppercutTimer = TIMER_UPPERCUT;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (me->IsWithinMeleeRange(me->getVictim()))
+ {
+ if (uiArcingSmashTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_ARCING_SMASH);
+ uiArcingSmashTimer = TIMER_ARCING_SMASH;
+ } else uiArcingSmashTimer -= diff;
+
+ if (uiTrampleTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_TRAMPLE);
+ uiTrampleTimer = TIMER_TRAMPLE;
+ } else uiTrampleTimer -= diff;
+
+ if (uiUppercutTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_UPPERCUT);
+ uiUppercutTimer = TIMER_UPPERCUT;
+ } else uiUppercutTimer -= diff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_pummeller(Creature* pCreature)
+{
+ return new mob_pummellerAI(pCreature);
+}
+
+/*-------------------------------------------------------
+ *
+ * XE-321 BOOMBOT
+ *
+ *///----------------------------------------------------
+struct mob_boombotAI : public ScriptedAI
+{
+ mob_boombotAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* m_pInstance;
+
+ void Reset()
+ {
+ me->SetReactState(REACT_PASSIVE);
+
+ if (Creature* pXT002 = me->GetCreature(*me, m_pInstance->GetData64(TYPE_XT002)))
+ me->GetMotionMaster()->MoveChase(pXT002);
+ }
+
+ void JustDied(Unit * /*killer*/)
+ {
+ DoCast(SPELL_BOOM);
+ }
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ if (Creature* pXT002 = me->GetCreature(*me, m_pInstance->GetData64(TYPE_XT002)))
+ {
+ if (me->GetDistance2d(pXT002) <= 0.5)
+ {
+ //Explosion
+ DoCast(me, SPELL_BOOM);
+
+ //Despawns the boombot
+ me->ForcedDespawn();
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_mob_boombot(Creature* pCreature)
+{
+ return new mob_boombotAI(pCreature);
+}
+
+/*-------------------------------------------------------
+ *
+ * VOID ZONE
+ *
+ *///----------------------------------------------------
+struct mob_void_zoneAI : public ScriptedAI
+{
+ mob_void_zoneAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = pCreature->GetInstanceData();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 uiVoidZoneTimer;
+
+ void Reset()
+ {
+ uiVoidZoneTimer = TIMER_VOID_ZONE;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (uiVoidZoneTimer <= diff)
+ {
+ //voidZone();
+ uiVoidZoneTimer = TIMER_VOID_ZONE;
+ } else uiVoidZoneTimer -= diff;
+ }
+
+ // TODO: put in comment and kept for reference. The spell should be fixed properly in spell system, if necessary.
+ //void voidZone()
+ //{
+ // Map* pMap = me->GetMap();
+ // if (pMap && pMap->IsDungeon())
+ // {
+ // Map::PlayerList const &PlayerList = pMap->GetPlayers();
+ // for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ // {
+ // // If a player is within the range of the spell
+ // if (i->getSource() && i->getSource()->GetDistance2d(me) <= 16)
+ // {
+ // // Deal damage to the victim
+ // int32 damage = RAID_MODE(VOID_ZONE_DMG_10, VOID_ZONE_DMG_25);
+ // me->DealDamage(i->getSource(), damage, NULL, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_SHADOW);
+ // }
+ // }
+ // }
+ //}
+};
+
+CreatureAI* GetAI_mob_void_zone(Creature* pCreature)
+{
+ return new mob_void_zoneAI(pCreature);
+}
+
+/*-------------------------------------------------------
+ *
+ * LIFE SPARK
+ *
+ *///----------------------------------------------------
+struct mob_life_sparkAI : public ScriptedAI
+{
+ mob_life_sparkAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ m_pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* m_pInstance;
+ uint32 uiShockTimer;
+
+ void Reset()
+ {
+ DoCast(me, RAID_MODE(SPELL_STATIC_CHARGED_10, SPELL_STATIC_CHARGED_25));
+ uiShockTimer = 0; // first one is immediate.
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (uiShockTimer <= diff)
+ {
+ if (me->IsWithinMeleeRange(me->getVictim()))
+ {
+ DoCast(me->getVictim(), SPELL_SHOCK);
+ uiShockTimer = TIMER_SHOCK;
+ }
+ }
+ else uiShockTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_life_spark(Creature* pCreature)
+{
+ return new mob_life_sparkAI(pCreature);
+}
+
+void AddSC_boss_xt002()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_xt002";
+ newscript->GetAI = &GetAI_boss_xt002;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_xt002_heart";
+ newscript->GetAI = &GetAI_mob_xt002_heart;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_scrapbot";
+ newscript->GetAI = &GetAI_mob_scrapbot;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_pummeller";
+ newscript->GetAI = &GetAI_mob_pummeller;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_boombot";
+ newscript->GetAI = &GetAI_mob_boombot;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_void_zone";
+ newscript->GetAI = &GetAI_mob_void_zone;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_life_spark";
+ newscript->GetAI = &GetAI_mob_life_spark;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/ulduar/boss_yoggsaron.cpp b/src/server/scripts/northrend/ulduar/ulduar/boss_yoggsaron.cpp
new file mode 100644
index 00000000000..8f42f289204
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/boss_yoggsaron.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+
+enum Sara_Yells
+{
+ SAY_SARA_PREFIGHT_1 = -1603310,
+ SAY_SARA_PREFIGHT_2 = -1603311,
+ SAY_SARA_AGGRO_1 = -1603312,
+ SAY_SARA_AGGRO_2 = -1603313,
+ SAY_SARA_AGGRO_3 = -1603314,
+ SAY_SARA_SLAY_1 = -1603315,
+ SAY_SARA_SLAY_2 = -1603316,
+ WHISP_SARA_INSANITY = -1603317,
+ SAY_SARA_PHASE2_1 = -1603318,
+ SAY_SARA_PHASE2_2 = -1603319,
+};
+
+enum YoggSaron_Yells
+{
+ SAY_PHASE2_1 = -1603330,
+ SAY_PHASE2_2 = -1603331,
+ SAY_PHASE2_3 = -1603332,
+ SAY_PHASE2_4 = -1603333,
+ SAY_PHASE2_5 = -1603334,
+ SAY_PHASE3 = -1603335,
+ SAY_VISION = -1603336,
+ SAY_SLAY_1 = -1603337,
+ SAY_SLAY_2 = -1603338,
+ WHISP_INSANITY_1 = -1603339,
+ WHISP_INSANITY_2 = -1603340,
+ SAY_DEATH = -1603341,
+};
+
+enum
+{
+ ACHIEV_TIMED_START_EVENT = 21001,
+};
diff --git a/src/server/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp b/src/server/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp
new file mode 100644
index 00000000000..692dbf72473
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/instance_ulduar.cpp
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "ulduar.h"
+
+enum eGameObjects
+{
+ GO_KOLOGARN_CHEST_HERO = 195047,
+ GO_KOLOGARN_CHEST = 195046,
+ GO_THORIM_CHEST_HERO = 194315,
+ GO_THORIM_CHEST = 194314,
+ GO_HODIR_CHEST_HERO = 194308,
+ GO_HODIR_CHEST = 194307,
+ GO_FREYA_CHEST_HERO = 194325,
+ GO_FREYA_CHEST = 194324,
+ GO_LEVIATHAN_DOOR = 194905,
+ GO_LEVIATHAN_GATE = 194630
+};
+
+struct instance_ulduar : public ScriptedInstance
+{
+ instance_ulduar(Map* pMap) : ScriptedInstance(pMap) { Initialize(); };
+
+ uint32 uiEncounter[MAX_ENCOUNTER];
+ std::string m_strInstData;
+ uint8 flag;
+
+ uint64 uiLeviathanGUID;
+ uint64 uiIgnisGUID;
+ uint64 uiRazorscaleGUID;
+ uint64 uiXT002GUID;
+ uint64 uiAssemblyGUIDs[3];
+ uint64 uiKologarnGUID;
+ uint64 uiAuriayaGUID;
+ uint64 uiMimironGUID;
+ uint64 uiHodirGUID;
+ uint64 uiThorimGUID;
+ uint64 uiFreyaGUID;
+ uint64 uiVezaxGUID;
+ uint64 uiYoggSaronGUID;
+ uint64 uiAlgalonGUID;
+ uint64 uiLeviathanDoor[7];
+ uint64 uiLeviathanGateGUID;
+
+ uint64 uiKologarnChestGUID;
+ uint64 uiThorimChestGUID;
+ uint64 uiHodirChestGUID;
+ uint64 uiFreyaChestGUID;
+
+ void Initialize()
+ {
+ uiLeviathanGUID = 0;
+ uiIgnisGUID = 0;
+ uiRazorscaleGUID = 0;
+ uiXT002GUID = 0;
+ uiKologarnGUID = 0;
+ uiAuriayaGUID = 0;
+ uiMimironGUID = 0;
+ uiHodirGUID = 0;
+ uiThorimGUID = 0;
+ uiFreyaGUID = 0;
+ uiVezaxGUID = 0;
+ uiYoggSaronGUID = 0;
+ uiAlgalonGUID = 0;
+ uiKologarnChestGUID = 0;
+ uiKologarnChestGUID = 0;
+ uiHodirChestGUID = 0;
+ uiFreyaChestGUID = 0;
+ uiLeviathanGateGUID = 0;
+ flag = 0;
+
+ memset(&uiEncounter, 0, sizeof(uiEncounter));
+ memset(&uiAssemblyGUIDs, 0, sizeof(uiAssemblyGUIDs));
+ memset(&uiLeviathanDoor, 0, sizeof(uiLeviathanDoor));
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ {
+ if (uiEncounter[i] == IN_PROGRESS)
+ return true;
+ }
+
+ return false;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool /*add*/)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case NPC_LEVIATHAN:
+ uiLeviathanGUID = pCreature->GetGUID();
+ break;
+ case NPC_IGNIS:
+ uiIgnisGUID = pCreature->GetGUID();
+ break;
+ case NPC_RAZORSCALE:
+ uiRazorscaleGUID = pCreature->GetGUID();
+ break;
+ case NPC_XT002:
+ uiXT002GUID = pCreature->GetGUID();
+ break;
+
+ // Assembly of Iron
+ case NPC_STEELBREAKER:
+ uiAssemblyGUIDs[0] = pCreature->GetGUID();
+ break;
+ case NPC_MOLGEIM:
+ uiAssemblyGUIDs[1] = pCreature->GetGUID();
+ break;
+ case NPC_BRUNDIR:
+ uiAssemblyGUIDs[2] = pCreature->GetGUID();
+ break;
+
+ case NPC_KOLOGARN:
+ uiKologarnGUID = pCreature->GetGUID();
+ break;
+ case NPC_AURIAYA:
+ uiAuriayaGUID = pCreature->GetGUID();
+ break;
+ case NPC_MIMIRON:
+ uiMimironGUID = pCreature->GetGUID();
+ break;
+ case NPC_HODIR:
+ uiHodirGUID = pCreature->GetGUID();
+ break;
+ case NPC_THORIM:
+ uiThorimGUID = pCreature->GetGUID();
+ break;
+ case NPC_FREYA:
+ uiFreyaGUID = pCreature->GetGUID();
+ break;
+ case NPC_VEZAX:
+ uiVezaxGUID = pCreature->GetGUID();
+ break;
+ case NPC_YOGGSARON:
+ uiYoggSaronGUID = pCreature->GetGUID();
+ break;
+ case NPC_ALGALON:
+ uiAlgalonGUID = pCreature->GetGUID();
+ break;
+ }
+
+ }
+
+ void OnGameObjectCreate(GameObject* pGO, bool add)
+ {
+ switch(pGO->GetEntry())
+ {
+ case GO_KOLOGARN_CHEST_HERO:
+ case GO_KOLOGARN_CHEST:
+ uiKologarnChestGUID = add ? pGO->GetGUID() : NULL;
+ break;
+ case GO_THORIM_CHEST_HERO:
+ case GO_THORIM_CHEST:
+ uiThorimChestGUID = add ? pGO->GetGUID() : NULL;
+ break;
+ case GO_HODIR_CHEST_HERO:
+ case GO_HODIR_CHEST:
+ uiHodirChestGUID = add ? pGO->GetGUID() : NULL;
+ break;
+ case GO_FREYA_CHEST_HERO:
+ case GO_FREYA_CHEST:
+ uiFreyaChestGUID = add ? pGO->GetGUID() : NULL;
+ break;
+ case GO_LEVIATHAN_DOOR:
+ uiLeviathanDoor[flag] = pGO->GetGUID();
+ HandleGameObject(NULL, true, pGO);
+ flag++;
+ if (flag == 7)
+ flag =0;
+ break;
+ case GO_LEVIATHAN_GATE:
+ uiLeviathanGateGUID = pGO->GetGUID();
+ HandleGameObject(NULL, false, pGO);
+ break;
+ }
+ }
+
+ void ProcessEvent(GameObject* pGO, uint32 uiEventId)
+ {
+ // Flame Leviathan's Tower Event triggers
+ Creature* pFlameLeviathan = instance->GetCreature(NPC_LEVIATHAN);
+ if (pFlameLeviathan && pFlameLeviathan->isAlive()) //No leviathan, no event triggering ;)
+ switch(uiEventId)
+ {
+ case EVENT_TOWER_OF_STORM_DESTROYED:
+ pFlameLeviathan->AI()->DoAction(1);
+ break;
+ case EVENT_TOWER_OF_FROST_DESTROYED:
+ pFlameLeviathan->AI()->DoAction(2);
+ break;
+ case EVENT_TOWER_OF_FLAMES_DESTROYED:
+ pFlameLeviathan->AI()->DoAction(3);
+ break;
+ case EVENT_TOWER_OF_NATURE_DESTROYED:
+ pFlameLeviathan->AI()->DoAction(4);
+ break;
+ }
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ if (type != TYPE_COLOSSUS)
+ uiEncounter[type] = data;
+
+ switch(type)
+ {
+ /*case TYPE_IGNIS:
+ case TYPE_RAZORSCALE:
+ case TYPE_XT002:
+ case TYPE_ASSEMBLY:
+ case TYPE_AURIAYA:
+ case TYPE_MIMIRON:
+ case TYPE_VEZAX:
+ case TYPE_YOGGSARON:
+ break;*/
+ case TYPE_LEVIATHAN:
+ if (data == IN_PROGRESS)
+ {
+ for (uint8 uiI = 0; uiI < 7; uiI++)
+ HandleGameObject(uiLeviathanDoor[uiI],false);
+ }
+ else
+ {
+ for (uint8 uiI = 0; uiI < 7; uiI++)
+ HandleGameObject(uiLeviathanDoor[uiI],true);
+ }
+ break;
+ case TYPE_KOLOGARN:
+ if (data == DONE)
+ if (GameObject* pGO = instance->GetGameObject(uiKologarnChestGUID))
+ pGO->SetRespawnTime(pGO->GetRespawnDelay());
+ break;
+ case TYPE_HODIR:
+ if (data == DONE)
+ if (GameObject* pGO = instance->GetGameObject(uiHodirChestGUID))
+ pGO->SetRespawnTime(pGO->GetRespawnDelay());
+ break;
+ case TYPE_THORIM:
+ if (data == DONE)
+ if (GameObject* pGO = instance->GetGameObject(uiThorimChestGUID))
+ pGO->SetRespawnTime(pGO->GetRespawnDelay());
+ break;
+ case TYPE_FREYA:
+ if (data == DONE)
+ if (GameObject* pGO = instance->GetGameObject(uiFreyaChestGUID))
+ pGO->SetRespawnTime(pGO->GetRespawnDelay());
+ break;
+ case TYPE_COLOSSUS:
+ if (data == 2)
+ {
+ if (Creature* pBoss = instance->GetCreature(uiLeviathanGUID))
+ pBoss->AI()->DoAction(10);
+ if (GameObject* pGate = instance->GetGameObject(uiLeviathanGateGUID))
+ pGate->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (data == DONE)
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ saveStream << uiEncounter[i] << " ";
+
+ m_strInstData = saveStream.str();
+
+ SaveToDB();
+ OUT_SAVE_INST_DATA_COMPLETE;
+ }
+ }
+
+ uint64 GetData64(uint32 data)
+ {
+ switch(data)
+ {
+ case TYPE_LEVIATHAN: return uiLeviathanGUID;
+ case TYPE_IGNIS: return uiIgnisGUID;
+ case TYPE_RAZORSCALE: return uiRazorscaleGUID;
+ case TYPE_XT002: return uiXT002GUID;
+ case TYPE_KOLOGARN: return uiKologarnGUID;
+ case TYPE_AURIAYA: return uiAuriayaGUID;
+ case TYPE_MIMIRON: return uiMimironGUID;
+ case TYPE_HODIR: return uiMimironGUID;
+ case TYPE_THORIM: return uiThorimGUID;
+ case TYPE_FREYA: return uiFreyaGUID;
+ case TYPE_VEZAX: return uiVezaxGUID;
+ case TYPE_YOGGSARON: return uiYoggSaronGUID;
+ case TYPE_ALGALON: return uiAlgalonGUID;
+
+ // Assembly of Iron
+ case DATA_STEELBREAKER: return uiAssemblyGUIDs[0];
+ case DATA_MOLGEIM: return uiAssemblyGUIDs[1];
+ case DATA_BRUNDIR: return uiAssemblyGUIDs[2];
+ }
+
+ return 0;
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case TYPE_LEVIATHAN:
+ case TYPE_IGNIS:
+ case TYPE_RAZORSCALE:
+ case TYPE_XT002:
+ case TYPE_ASSEMBLY:
+ case TYPE_KOLOGARN:
+ case TYPE_AURIAYA:
+ case TYPE_MIMIRON:
+ case TYPE_HODIR:
+ case TYPE_THORIM:
+ case TYPE_FREYA:
+ case TYPE_VEZAX:
+ case TYPE_YOGGSARON:
+ case TYPE_ALGALON:
+ case TYPE_COLOSSUS:
+ return uiEncounter[type];
+ }
+
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "U U " << uiEncounter[0] << " " << uiEncounter[1] << " " << uiEncounter[2] << " " << uiEncounter[3]
+ << uiEncounter[4] << " " << uiEncounter[5] << " " << uiEncounter[6] << " " << uiEncounter[7]
+ << uiEncounter[8] << " " << uiEncounter[9] << " " << uiEncounter[10] << " " << uiEncounter[11]
+ << uiEncounter[12] << " " << uiEncounter[13] << " " << uiEncounter[14];
+
+ m_strInstData = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return m_strInstData;
+ }
+
+ void Load(const char* strIn)
+ {
+ if (!strIn)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(strIn);
+
+ char dataHead1, dataHead2;
+ uint32 data0, data1, data2, data3, data4, data5, data6,
+ data7, data8, data9, data10, data11, data12, data13, data14;
+
+ std::istringstream loadStream(strIn);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4 >> data5 >> data6
+ >> data7 >> data8 >> data9 >> data10 >> data11 >> data12 >> data13 >> data14;
+
+ if (dataHead1 == 'U' && dataHead2 == 'U')
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ {
+ loadStream >> uiEncounter[i];
+
+ if (uiEncounter[i] == IN_PROGRESS)
+ uiEncounter[i] = NOT_STARTED;
+ }
+ }
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_ulduar(Map* pMap)
+{
+ return new instance_ulduar(pMap);
+}
+
+void AddSC_instance_ulduar()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_ulduar";
+ newscript->GetInstanceData = &GetInstanceData_instance_ulduar;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/ulduar/ulduar/ulduar.h b/src/server/scripts/northrend/ulduar/ulduar/ulduar.h
new file mode 100644
index 00000000000..cb11bcb579c
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/ulduar.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DEF_ULDUAR_H
+#define DEF_ULDUAR_H
+
+enum eTypes
+{
+ MAX_ENCOUNTER = 15,
+
+ TYPE_LEVIATHAN = 0,
+ TYPE_IGNIS = 1,
+ TYPE_RAZORSCALE = 2,
+ TYPE_XT002 = 3,
+ TYPE_ASSEMBLY = 4,
+ TYPE_KOLOGARN = 5,
+ TYPE_AURIAYA = 6,
+ TYPE_MIMIRON = 7,
+ TYPE_HODIR = 8,
+ TYPE_THORIM = 9,
+ TYPE_FREYA = 10,
+ TYPE_VEZAX = 11,
+ TYPE_YOGGSARON = 12,
+ TYPE_ALGALON = 13,
+ TYPE_COLOSSUS = 14,
+
+ DATA_STEELBREAKER = 20,
+ DATA_MOLGEIM = 21,
+ DATA_BRUNDIR = 22,
+ DATA_RUNEMASTER_MOLGEIM = 23,
+ DATA_STORMCALLER_BRUNDIR = 24,
+
+ NPC_LEVIATHAN = 33113,
+ NPC_IGNIS = 33118,
+ NPC_RAZORSCALE = 33186,
+ NPC_XT002 = 33293,
+ NPC_STEELBREAKER = 32867,
+ NPC_MOLGEIM = 32927,
+ NPC_BRUNDIR = 32857,
+ NPC_KOLOGARN = 32930,
+ NPC_AURIAYA = 33515,
+ NPC_MIMIRON = 33350,
+ NPC_HODIR = 32845,
+ NPC_THORIM = 32865,
+ NPC_FREYA = 32906,
+ NPC_VEZAX = 33271,
+ NPC_YOGGSARON = 33288,
+ NPC_ALGALON = 32871,
+
+ EVENT_TOWER_OF_STORM_DESTROYED = 21031,
+ EVENT_TOWER_OF_FROST_DESTROYED = 21032,
+ EVENT_TOWER_OF_FLAMES_DESTROYED = 21033,
+ EVENT_TOWER_OF_NATURE_DESTROYED = 21030
+};
+
+#endif
diff --git a/src/server/scripts/northrend/ulduar/ulduar/ulduar_teleporter.cpp b/src/server/scripts/northrend/ulduar/ulduar/ulduar_teleporter.cpp
new file mode 100644
index 00000000000..44f9e86b69c
--- /dev/null
+++ b/src/server/scripts/northrend/ulduar/ulduar/ulduar_teleporter.cpp
@@ -0,0 +1,92 @@
+#include "ScriptedPch.h"
+#include "ulduar.h"
+
+/*
+The teleporter appears to be active and stable.
+
+- Expedition Base Camp
+- Formation Grounds
+- Colossal Forge
+- Scrapyard
+- Antechamber of Ulduar
+- Shattered Walkway
+- Conservatory of Life
+*/
+
+#define BASE_CAMP 200
+#define GROUNDS 201
+#define FORGE 202
+#define SCRAPYARD 203
+#define ANTECHAMBER 204
+#define WALKWAY 205
+#define CONSERVATORY 206
+
+bool GoHello_ulduar_teleporter(Player *pPlayer, GameObject *pGO)
+{
+ ScriptedInstance *pInstance = pGO->GetInstanceData();
+ if (!pInstance) return true;
+
+ pPlayer->ADD_GOSSIP_ITEM(0, "Teleport to the Expedition Base Camp", GOSSIP_SENDER_MAIN, BASE_CAMP);
+ pPlayer->ADD_GOSSIP_ITEM(0, "Teleport to the Formation Grounds", GOSSIP_SENDER_MAIN, GROUNDS);
+ if (pInstance->GetData(TYPE_LEVIATHAN) == DONE)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(0, "Teleport to the Colossal Forge", GOSSIP_SENDER_MAIN, FORGE);
+ if (pInstance->GetData(TYPE_XT002) == DONE)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(0, "Teleport to the Scrapyard", GOSSIP_SENDER_MAIN, SCRAPYARD);
+ pPlayer->ADD_GOSSIP_ITEM(0, "Teleport to the Antechamber of Ulduar", GOSSIP_SENDER_MAIN, ANTECHAMBER);
+ if (pInstance->GetData(TYPE_KOLOGARN) == DONE)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(0, "Teleport to the Shattered Walkway", GOSSIP_SENDER_MAIN, WALKWAY);
+ if (pInstance->GetData(TYPE_AURIAYA) == DONE)
+ pPlayer->ADD_GOSSIP_ITEM(0, "Teleport to the Conservatory of Life", GOSSIP_SENDER_MAIN, CONSERVATORY);
+ }
+ }
+ }
+ pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pGO->GetGUID());
+
+ return true;
+}
+
+bool GOSelect_ulduar_teleporter(Player *pPlayer, GameObject * /*pGO*/, uint32 sender, uint32 action)
+{
+ if (sender != GOSSIP_SENDER_MAIN) return true;
+ if (!pPlayer->getAttackers().empty()) return true;
+
+ switch(action)
+ {
+ case BASE_CAMP:
+ pPlayer->TeleportTo(603, -706.122, -92.6024, 429.876, 0);
+ pPlayer->CLOSE_GOSSIP_MENU(); break;
+ case GROUNDS:
+ pPlayer->TeleportTo(603, 131.248, -35.3802, 409.804, 0);
+ pPlayer->CLOSE_GOSSIP_MENU(); break;
+ case FORGE:
+ pPlayer->TeleportTo(603, 553.233, -12.3247, 409.679, 0);
+ pPlayer->CLOSE_GOSSIP_MENU(); break;
+ case SCRAPYARD:
+ pPlayer->TeleportTo(603, 926.292, -11.4635, 418.595, 0);
+ pPlayer->CLOSE_GOSSIP_MENU(); break;
+ case ANTECHAMBER:
+ pPlayer->TeleportTo(603, 1498.09, -24.246, 420.967, 0);
+ pPlayer->CLOSE_GOSSIP_MENU(); break;
+ case WALKWAY:
+ pPlayer->TeleportTo(603, 1859.45, -24.1, 448.9, 0);
+ pPlayer->CLOSE_GOSSIP_MENU(); break;
+ case CONSERVATORY:
+ pPlayer->TeleportTo(603, 2086.27, -24.3134, 421.239, 0);
+ pPlayer->CLOSE_GOSSIP_MENU(); break;
+ }
+
+ return true;
+}
+
+void AddSC_ulduar_teleporter()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "ulduar_teleporter";
+ newscript->pGOHello = &GoHello_ulduar_teleporter;
+ newscript->pGOSelect = &GOSelect_ulduar_teleporter;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp
new file mode 100644
index 00000000000..77f824c48d5
--- /dev/null
+++ b/src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_ingvar_the_plunderer.cpp
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Boss_Ingvar_The_Plunderer
+SD%Complete: 95
+SDComment: Some Problems with Annhylde Movement, Blizzlike Timers
+SDCategory: Udgarde Keep
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "utgarde_keep.h"
+
+enum Yells
+{
+ //Yells Ingvar
+ YELL_AGGRO_1 = -1574005,
+ YELL_AGGRO_2 = -1574006,
+
+ YELL_DEAD_1 = -1574007,
+ YELL_DEAD_2 = -1574008,
+
+ YELL_KILL_1 = -1574009,
+ YELL_KILL_2 = -1574010,
+};
+
+enum Creatures
+{
+ MOB_INGVAR_HUMAN = 23954,
+ MOB_ANNHYLDE_THE_CALLER = 24068,
+ MOB_INGVAR_UNDEAD = 23980,
+};
+
+enum Spells
+{
+ //Ingvar Spells human form
+ SPELL_CLEAVE = 42724,
+ SPELL_SMASH = 42669,
+ H_SPELL_SMASH = 59706,
+ SPELL_STAGGERING_ROAR = 42708,
+ H_SPELL_STAGGERING_ROAR = 59708,
+ SPELL_ENRAGE = 42705,
+ H_SPELL_ENRAGE = 59707,
+
+ SPELL_INGVAR_FEIGN_DEATH = 42795,
+ SPELL_SUMMON_BANSHEE = 42912,
+ SPELL_SCOURG_RESURRECTION = 42863, // Spawn resurrect effect around Ingvar
+
+ //Ingvar Spells undead form
+ SPELL_DARK_SMASH = 42723,
+ SPELL_DREADFUL_ROAR = 42729,
+ H_SPELL_DREADFUL_ROAR = 59734,
+ SPELL_WOE_STRIKE = 42730,
+ H_SPELL_WOE_STRIKE = 59735,
+
+ ENTRY_THROW_TARGET = 23996,
+ SPELL_SHADOW_AXE_SUMMON = 42749
+};
+
+struct boss_ingvar_the_plundererAI : public ScriptedAI
+{
+ boss_ingvar_the_plundererAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ bool bIsUndead;
+ bool bEventInProgress;
+
+ uint32 uiCleaveTimer;
+ uint32 uiSmashTimer;
+ uint32 uiEnrageTimer;
+ uint32 uiRoarTimer;
+ uint32 uiSpawnResTimer;
+
+ void Reset()
+ {
+ if (bIsUndead)
+ me->UpdateEntry(MOB_INGVAR_HUMAN);
+
+ bIsUndead = false;
+ bEventInProgress = false;
+
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+
+ uiCleaveTimer = 2000;
+ uiSmashTimer = 5000;
+ uiEnrageTimer = 10000;
+ uiRoarTimer = 15000;
+
+ uiSpawnResTimer = 3000;
+
+ if (pInstance)
+ pInstance->SetData(DATA_INGVAR_EVENT, NOT_STARTED);
+ }
+
+ void DamageTaken(Unit * /*done_by*/, uint32 &damage)
+ {
+ if (damage >= me->GetHealth() && !bIsUndead)
+ {
+ //DoCast(me, SPELL_INGVAR_FEIGN_DEATH, true); // Dont work ???
+ // visuel hack
+ me->SetHealth(0);
+ me->InterruptNonMeleeSpells(true);
+ me->RemoveAllAuras();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->GetMotionMaster()->MovementExpired(false);
+ me->GetMotionMaster()->MoveIdle();
+ me->SetStandState(UNIT_STAND_STATE_DEAD);
+ // visuel hack end
+
+ bEventInProgress = true;
+ bIsUndead = true;
+
+ DoScriptText(YELL_DEAD_1,me);
+ }
+
+ if (bEventInProgress)
+ {
+ damage = 0;
+ }
+ }
+
+ void StartZombiePhase()
+ {
+ bIsUndead = true;
+ bEventInProgress = false;
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->UpdateEntry(MOB_INGVAR_UNDEAD);
+ me->SetInCombatWith(me->getVictim());
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+
+ DoScriptText(YELL_AGGRO_2,me);
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ DoScriptText(YELL_AGGRO_1,me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_INGVAR_EVENT, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(YELL_DEAD_2,me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_INGVAR_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ if (bIsUndead)
+ DoScriptText(YELL_KILL_1,me);
+ else
+ DoScriptText(YELL_KILL_2,me);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (bEventInProgress)
+ {
+ if (uiSpawnResTimer)
+ if (uiSpawnResTimer <= diff)
+ {
+ DoCast(me, SPELL_SUMMON_BANSHEE); // Summons directly on caster position
+ // DoCast(me, SPELL_SCOURG_RESURRECTION, true); // Not needed ?
+ uiSpawnResTimer = 0;
+ } else uiSpawnResTimer -= diff;
+
+ return;
+ }
+
+ if (uiCleaveTimer <= diff)
+ {
+ if (!me->hasUnitState(UNIT_STAT_CASTING))
+ {
+ if (bIsUndead)
+ DoCast(me->getVictim(), SPELL_WOE_STRIKE);
+ else
+ DoCast(me->getVictim(), SPELL_CLEAVE);
+ uiCleaveTimer = rand()%5000 + 2000;
+ }
+ } else uiCleaveTimer -= diff;
+
+ if (uiSmashTimer <= diff)
+ {
+ if (!me->hasUnitState(UNIT_STAT_CASTING))
+ {
+ if (bIsUndead)
+ DoCast(me->getVictim(), SPELL_DARK_SMASH);
+ else
+ DoCast(me->getVictim(), SPELL_SMASH);
+ uiSmashTimer = 10000;
+ }
+ } else uiSmashTimer -= diff;
+
+ if (!bIsUndead)
+ {
+ if (uiEnrageTimer <= diff)
+ {
+ DoCast(me, SPELL_ENRAGE);
+ uiEnrageTimer = 10000;
+ } else uiEnrageTimer -= diff;
+ } else // In Undead form used to summon weapon
+ {
+ if (uiEnrageTimer <= diff)
+ {
+ if (!me->hasUnitState(UNIT_STAT_CASTING))
+ {
+ // Spawn target for Axe
+ Unit *pTarget = SelectUnit(SELECT_TARGET_TOPAGGRO, 1);
+ if (pTarget)
+ {
+ me->SummonCreature(ENTRY_THROW_TARGET,pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,2000);
+
+ DoCast(me, SPELL_SHADOW_AXE_SUMMON);
+ }
+ uiEnrageTimer = 30000;
+ }
+ } else uiEnrageTimer -= diff;
+ }
+
+ if (uiRoarTimer <= diff)
+ {
+ if (!me->hasUnitState(UNIT_STAT_CASTING))
+ {
+ if (bIsUndead)
+ DoCast(me, SPELL_DREADFUL_ROAR);
+ else
+ DoCast(me, SPELL_STAGGERING_ROAR);
+ uiRoarTimer = 10000;
+ }
+ } else uiRoarTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_ingvar_the_plunderer(Creature* pCreature)
+{
+ return new boss_ingvar_the_plundererAI(pCreature);
+}
+
+enum eSpells
+{
+//we don't have that text in db so comment it until we get this text
+// YELL_RESSURECT = -1574025,
+
+//Spells for Annhylde
+ SPELL_SCOURG_RESURRECTION_HEAL = 42704, //Heal Max + DummyAura
+ SPELL_SCOURG_RESURRECTION_BEAM = 42857, //Channeling Beam of Annhylde
+ SPELL_SCOURG_RESURRECTION_DUMMY = 42862, //Some Emote Dummy?
+ SPELL_INGVAR_TRANSFORM = 42796
+};
+
+struct mob_annhylde_the_callerAI : public ScriptedAI
+{
+ mob_annhylde_the_callerAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ float x,y,z;
+ ScriptedInstance* pInstance;
+ uint32 uiResurectTimer;
+ uint32 uiResurectPhase;
+
+ void Reset()
+ {
+ me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_HOVER);
+ me->SetSpeed(MOVE_SWIM , 1.0f);
+ me->SetSpeed(MOVE_RUN , 1.0f);
+ me->SetSpeed(MOVE_WALK , 1.0f);
+ //me->SetSpeed(MOVE_FLIGHT , 1.0f);
+
+ me->GetPosition(x,y,z);
+ DoTeleportTo(x+1,y,z+30);
+
+ Unit* ingvar = Unit::GetUnit(*me, pInstance ? pInstance->GetData64(DATA_INGVAR) : 0);
+ if (ingvar)
+ {
+ me->GetMotionMaster()->MovePoint(1,x,y,z+15);
+
+// DoScriptText(YELL_RESSURECT,me);
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+ Unit* ingvar = Unit::GetUnit((*me), pInstance ? pInstance->GetData64(DATA_INGVAR) : 0);
+ if (ingvar)
+ {
+ switch (id)
+ {
+ case 1:
+ ingvar->RemoveAura(SPELL_SUMMON_BANSHEE);
+ ingvar->CastSpell(ingvar,SPELL_SCOURG_RESURRECTION_DUMMY,true);
+ DoCast(ingvar, SPELL_SCOURG_RESURRECTION_BEAM);
+ uiResurectTimer = 8000;
+ uiResurectPhase = 1;
+ break;
+ case 2:
+ me->SetVisibility(VISIBILITY_OFF);
+ me->DealDamage(me,me->GetHealth());
+ me->RemoveCorpse();
+ break;
+ }
+ }
+ }
+
+ void AttackStart(Unit* /*who*/) {}
+ void MoveInLineOfSight(Unit* /*who*/) {}
+ void EnterCombat(Unit * /*who*/) {}
+ void UpdateAI(const uint32 diff)
+ {
+ if (uiResurectTimer)
+ if (uiResurectTimer <= diff)
+ {
+ if (uiResurectPhase == 1)
+ {
+ Unit* ingvar = Unit::GetUnit(*me, pInstance ? pInstance->GetData64(DATA_INGVAR) : 0);
+ if (ingvar)
+ {
+ ingvar->SetStandState(UNIT_STAND_STATE_STAND);
+ ingvar->CastSpell(ingvar,SPELL_SCOURG_RESURRECTION_HEAL,false);
+ }
+ uiResurectTimer = 3000;
+ uiResurectPhase = 2;
+ }
+ else if (uiResurectPhase == 2)
+ {
+ if (Creature* ingvar = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_INGVAR) : 0))
+ {
+ ingvar->RemoveAurasDueToSpell(SPELL_SCOURG_RESURRECTION_DUMMY);
+
+ if (boss_ingvar_the_plundererAI* pAI = CAST_AI(boss_ingvar_the_plundererAI, ingvar->AI()))
+ pAI->StartZombiePhase();
+
+ me->GetMotionMaster()->MovePoint(2,x+1,y,z+30);
+ ++uiResurectPhase;
+ uiResurectTimer = 0;
+ }
+ }
+
+ } else uiResurectTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_annhylde_the_caller(Creature* pCreature)
+{
+ return new mob_annhylde_the_callerAI (pCreature);
+}
+
+enum eShadowAxe
+{
+ SPELL_SHADOW_AXE_DAMAGE = 42750,
+ H_SPELL_SHADOW_AXE_DAMAGE = 59719
+};
+
+struct mob_ingvar_throw_dummyAI : public ScriptedAI
+{
+ mob_ingvar_throw_dummyAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ uint32 uiDespawnTimer;
+
+ void Reset()
+ {
+ Unit *pTarget = me->FindNearestCreature(ENTRY_THROW_TARGET,50);
+ if (pTarget)
+ {
+ DoCast(me, SPELL_SHADOW_AXE_DAMAGE);
+ float x,y,z;
+ pTarget->GetPosition(x,y,z);
+ me->GetMotionMaster()->MovePoint(0,x,y,z);
+ }
+ uiDespawnTimer = 7000;
+ }
+ void AttackStart(Unit* /*who*/) {}
+ void MoveInLineOfSight(Unit* /*who*/) {}
+ void EnterCombat(Unit * /*who*/) {}
+ void UpdateAI(const uint32 diff)
+ {
+ if (uiDespawnTimer <= diff)
+ {
+ me->DealDamage(me,me->GetHealth());
+ me->RemoveCorpse();
+ uiDespawnTimer = 0;
+ } else uiDespawnTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_ingvar_throw_dummy(Creature* pCreature)
+{
+ return new mob_ingvar_throw_dummyAI (pCreature);
+}
+
+void AddSC_boss_ingvar_the_plunderer()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_ingvar_the_plunderer";
+ newscript->GetAI = &GetAI_boss_ingvar_the_plunderer;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_annhylde_the_caller";
+ newscript->GetAI = &GetAI_mob_annhylde_the_caller;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_ingvar_throw_dummy";
+ newscript->GetAI = &GetAI_mob_ingvar_throw_dummy;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp b/src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp
new file mode 100644
index 00000000000..d69f0eee846
--- /dev/null
+++ b/src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_keleseth.cpp
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Boss_Prince_Keleseth
+SD%Complete: 90
+SDComment: Needs Prince Movements, Needs adjustments to blizzlike timers, Needs Shadowbolt castbar, Needs right Ressurect Visual, Needs Some Heroic Spells
+SDCategory: Utgarde Keep
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "utgarde_keep.h"
+
+enum eEnums
+{
+ ACHIEVEMENT_ON_THE_ROCKS = 1919,
+
+ SPELL_SHADOWBOLT = 43667,
+ SPELL_SHADOWBOLT_HEROIC = 59389,
+ SPELL_FROST_TOMB = 48400,
+ SPELL_FROST_TOMB_SUMMON = 42714,
+ SPELL_DECREPIFY = 42702,
+ SPELL_SCOURGE_RESSURRECTION = 42704,
+ CREATURE_FROSTTOMB = 23965,
+ CREATURE_SKELETON = 23970,
+
+ SAY_AGGRO = -1574000,
+ SAY_FROST_TOMB = -1574001,
+ SAY_SKELETONS = -1574002,
+ SAY_KILL = -1574003,
+ SAY_DEATH = -1574004
+};
+
+#define SKELETONSPAWN_Z 42.8668
+
+float SkeletonSpawnPoint[5][5]=
+{
+ {156.2559, 259.2093},
+ {156.2559, 259.2093},
+ {156.2559, 259.2093},
+ {156.2559, 259.2093},
+ {156.2559, 259.2093},
+};
+
+float AttackLoc[3]={197.636, 194.046, 40.8164};
+
+bool ShatterFrostTomb; // needed for achievement: On The Rocks(1919)
+
+struct mob_frost_tombAI : public ScriptedAI
+{
+ mob_frost_tombAI(Creature *c) : ScriptedAI(c)
+ {
+ FrostTombGUID = 0;
+ }
+
+ uint64 FrostTombGUID;
+
+ void SetPrisoner(Unit* uPrisoner)
+ {
+ FrostTombGUID = uPrisoner->GetGUID();
+ }
+
+ void Reset(){ FrostTombGUID = 0; }
+ void EnterCombat(Unit* /*who*/) {}
+ void AttackStart(Unit* /*who*/) {}
+ void MoveInLineOfSight(Unit* /*who*/) {}
+
+ void JustDied(Unit *killer)
+ {
+ if (killer->GetGUID() != me->GetGUID())
+ ShatterFrostTomb = true;
+
+ if (FrostTombGUID)
+ {
+ Unit* FrostTomb = Unit::GetUnit((*me),FrostTombGUID);
+ if (FrostTomb)
+ FrostTomb->RemoveAurasDueToSpell(SPELL_FROST_TOMB);
+ }
+ }
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ Unit* temp = Unit::GetUnit((*me),FrostTombGUID);
+ if ((temp && temp->isAlive() && !temp->HasAura(SPELL_FROST_TOMB)) || !temp)
+ me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+};
+
+struct boss_kelesethAI : public ScriptedAI
+{
+ boss_kelesethAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 FrostTombTimer;
+ uint32 SummonSkeletonsTimer;
+ uint32 RespawnSkeletonsTimer;
+ uint32 ShadowboltTimer;
+ uint64 SkeletonGUID[5];
+ bool Skeletons;
+ bool RespawnSkeletons;
+
+ void Reset()
+ {
+ ShadowboltTimer = 0;
+ Skeletons = false;
+
+ ShatterFrostTomb = false;
+
+ ResetTimer();
+
+ if (pInstance)
+ pInstance->SetData(DATA_PRINCEKELESETH_EVENT, NOT_STARTED);
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+
+ DoScriptText(SAY_KILL, me);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (IsHeroic() && !ShatterFrostTomb)
+ {
+ AchievementEntry const *AchievOnTheRocks = GetAchievementStore()->LookupEntry(ACHIEVEMENT_ON_THE_ROCKS);
+ if (AchievOnTheRocks)
+ {
+ Map* pMap = me->GetMap();
+ if (pMap && pMap->IsDungeon())
+ {
+ Map::PlayerList const &players = pMap->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ itr->getSource()->CompletedAchievement(AchievOnTheRocks);
+ }
+ }
+ }
+
+ if (pInstance)
+ pInstance->SetData(DATA_PRINCEKELESETH_EVENT, DONE);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ DoZoneInCombat();
+
+ if (pInstance)
+ pInstance->SetData(DATA_PRINCEKELESETH_EVENT, IN_PROGRESS);
+ }
+
+ void ResetTimer(uint32 inc = 0)
+ {
+ SummonSkeletonsTimer = 5000 + inc;
+ FrostTombTimer = 28000 + inc;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (ShadowboltTimer <= diff)
+ {
+ Unit *pTarget = SelectUnit(SELECT_TARGET_TOPAGGRO, 0);
+ if (pTarget && pTarget->isAlive() && pTarget->GetTypeId() == TYPEID_PLAYER)
+ me->CastSpell(pTarget, DUNGEON_MODE(SPELL_SHADOWBOLT, SPELL_SHADOWBOLT_HEROIC), true);
+ ShadowboltTimer = 10000;
+ } else ShadowboltTimer -= diff;
+
+ if (!Skeletons)
+ if ((SummonSkeletonsTimer <= diff))
+ {
+ Creature* Skeleton;
+ DoScriptText(SAY_SKELETONS, me);
+ for (uint8 i = 0; i < 5; ++i)
+ {
+ Skeleton = me->SummonCreature(CREATURE_SKELETON, SkeletonSpawnPoint[i][0], SkeletonSpawnPoint[i][1] , SKELETONSPAWN_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
+ if (Skeleton)
+ {
+ Skeleton->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ Skeleton->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY() , me->GetPositionZ());
+ Skeleton->AddThreat(me->getVictim(), 0.0f);
+ DoZoneInCombat(Skeleton);
+ }
+ }
+ Skeletons = true;
+ } else SummonSkeletonsTimer -= diff;
+
+ if (FrostTombTimer <= diff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ if (pTarget->isAlive())
+ {
+ //DoCast(pTarget, SPELL_FROST_TOMB_SUMMON, true);
+ if (Creature *pChains = me->SummonCreature(CREATURE_FROSTTOMB, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 20000))
+ {
+ CAST_AI(mob_frost_tombAI, pChains->AI())->SetPrisoner(pTarget);
+ pChains->CastSpell(pTarget, SPELL_FROST_TOMB, true);
+
+ DoScriptText(SAY_FROST_TOMB, me);
+ }
+ }
+ FrostTombTimer = 15000;
+ } else FrostTombTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_vrykul_skeletonAI : public ScriptedAI
+{
+ mob_vrykul_skeletonAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance *pInstance;
+ uint32 Respawn_Time;
+ uint64 Target_Guid;
+ uint32 Decrepify_Timer;
+
+ bool isDead;
+
+ void Reset()
+ {
+ Respawn_Time = 12000;
+ Decrepify_Timer = urand(10000,20000);
+ isDead = false;
+ }
+
+ void EnterCombat(Unit * /*who*/){}
+ void DamageTaken(Unit *done_by, uint32 &damage)
+ {
+ if (done_by->GetGUID() == me->GetGUID())
+ return;
+
+ if (damage >= me->GetHealth())
+ {
+ PretendToDie();
+ damage = 0;
+ }
+ }
+
+ void PretendToDie()
+ {
+ isDead = true;
+ me->InterruptNonMeleeSpells(true);
+ me->RemoveAllAuras();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->GetMotionMaster()->MovementExpired(false);
+ me->GetMotionMaster()->MoveIdle();
+ me->SetStandState(UNIT_STAND_STATE_DEAD);
+ };
+
+ void Resurrect()
+ {
+ isDead = false;
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ DoCast(me, SPELL_SCOURGE_RESSURRECTION, true);
+
+ if (me->getVictim())
+ {
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+ me->AI()->AttackStart(me->getVictim());
+ }
+ else
+ me->GetMotionMaster()->Initialize();
+ };
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (pInstance && pInstance->GetData(DATA_PRINCEKELESETH_EVENT) == IN_PROGRESS)
+ {
+ if (isDead)
+ {
+ if (Respawn_Time <= diff)
+ {
+ Resurrect();
+ Respawn_Time = 12000;
+ } else Respawn_Time -= diff;
+ }
+ else
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (Decrepify_Timer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_DECREPIFY);
+ Decrepify_Timer = 30000;
+ } else Decrepify_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+ }else
+ {
+ if (me->isAlive())
+ me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+
+ }
+};
+
+CreatureAI* GetAI_mob_frost_tomb(Creature* pCreature)
+{
+ return new mob_frost_tombAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_keleseth(Creature* pCreature)
+{
+ return new boss_kelesethAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_vrykul_skeleton(Creature* pCreature)
+{
+ return new mob_vrykul_skeletonAI (pCreature);
+}
+
+void AddSC_boss_keleseth()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_keleseth";
+ newscript->GetAI = &GetAI_boss_keleseth;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_frost_tomb";
+ newscript->GetAI = &GetAI_mob_frost_tomb;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_vrykul_skeleton";
+ newscript->GetAI = &GetAI_mob_vrykul_skeleton;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp b/src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp
new file mode 100644
index 00000000000..2146d37635b
--- /dev/null
+++ b/src/server/scripts/northrend/utgarde_keep/utgarde_keep/boss_skarvald_dalronn.cpp
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Boss_Skarvald_Dalronn
+SD%Complete: 95
+SDComment: Needs adjustments to blizzlike timers, Yell Text + Sound to DB
+SDCategory: Utgarde Keep
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "utgarde_keep.h"
+
+enum eEnums
+{
+ //signed for 24200, but used by 24200,27390
+ YELL_SKARVALD_AGGRO = -1574011,
+ YELL_SKARVALD_DAL_DIED = -1574012,
+ YELL_SKARVALD_SKA_DIEDFIRST = -1574013,
+ YELL_SKARVALD_KILL = -1574014,
+ YELL_SKARVALD_DAL_DIEDFIRST = -1574015,
+
+ //signed for 24201, but used by 24201,27389
+ YELL_DALRONN_AGGRO = -1574016,
+ YELL_DALRONN_SKA_DIED = -1574017,
+ YELL_DALRONN_DAL_DIEDFIRST = -1574018,
+ YELL_DALRONN_KILL = -1574019,
+ YELL_DALRONN_SKA_DIEDFIRST = -1574020,
+
+//Spells of Skarvald and his Ghost
+ MOB_SKARVALD_THE_CONSTRUCTOR = 24200,
+ SPELL_CHARGE = 43651,
+ SPELL_STONE_STRIKE = 48583,
+ SPELL_SUMMON_SKARVALD_GHOST = 48613,
+ MOB_SKARVALD_GHOST = 27390,
+//Spells of Dalronn and his Ghost
+ MOB_DALRONN_THE_CONTROLLER = 24201,
+ SPELL_SHADOW_BOLT = 43649,
+ H_SPELL_SHADOW_BOLT = 59575,
+ H_SPELL_SUMMON_SKELETONS = 52611,
+ SPELL_DEBILITATE = 43650,
+ SPELL_SUMMON_DALRONN_GHOST = 48612,
+ MOB_DALRONN_GHOST = 27389
+};
+
+struct boss_skarvald_the_constructorAI : public ScriptedAI
+{
+ boss_skarvald_the_constructorAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ bool ghost;
+ uint32 Charge_Timer;
+ uint32 StoneStrike_Timer;
+ uint32 Response_Timer;
+ uint32 Check_Timer;
+ bool Dalronn_isDead;
+
+ void Reset()
+ {
+ Charge_Timer = 5000;
+ StoneStrike_Timer = 10000;
+ Dalronn_isDead = false;
+ Check_Timer = 5000;
+
+ ghost = (me->GetEntry() == MOB_SKARVALD_GHOST);
+ if (!ghost && pInstance)
+ {
+ Unit* dalronn = Unit::GetUnit((*me),pInstance->GetData64(DATA_DALRONN));
+ if (dalronn && dalronn->isDead())
+ CAST_CRE(dalronn)->Respawn();
+
+ pInstance->SetData(DATA_SKARVALD_DALRONN_EVENT, NOT_STARTED);
+ }
+ }
+
+ void EnterCombat(Unit * who)
+ {
+ if (!ghost && pInstance)
+ {
+ DoScriptText(YELL_SKARVALD_AGGRO,me);
+
+ Unit* dalronn = Unit::GetUnit((*me),pInstance->GetData64(DATA_DALRONN));
+ if (dalronn && dalronn->isAlive() && !dalronn->getVictim())
+ dalronn->getThreatManager().addThreat(who,0.0f);
+
+ pInstance->SetData(DATA_SKARVALD_DALRONN_EVENT, IN_PROGRESS);
+ }
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ if (!ghost && pInstance)
+ {
+ Unit* dalronn = Unit::GetUnit((*me),pInstance->GetData64(DATA_DALRONN));
+ if (dalronn)
+ {
+ if (dalronn->isDead())
+ {
+ DoScriptText(YELL_SKARVALD_DAL_DIED,me);
+
+ pInstance->SetData(DATA_SKARVALD_DALRONN_EVENT, DONE);
+ }
+ else
+ {
+ DoScriptText(YELL_SKARVALD_SKA_DIEDFIRST,me);
+
+ me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ //DoCast(me, SPELL_SUMMON_SKARVALD_GHOST, true);
+ Creature* temp = me->SummonCreature(MOB_SKARVALD_GHOST,me->GetPositionX(),me->GetPositionY(),me->GetPositionZ(),0,TEMPSUMMON_CORPSE_DESPAWN,5000);
+ if (temp)
+ {
+ temp->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE);
+ temp->AI()->AttackStart(Killer);
+ }
+ }
+ }
+ }
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ if (!ghost)
+ {
+ DoScriptText(YELL_SKARVALD_KILL,me);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (ghost)
+ {
+ if (pInstance && pInstance->GetData(DATA_SKARVALD_DALRONN_EVENT) != IN_PROGRESS)
+ me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+
+ if (!UpdateVictim())
+ return;
+
+ if (!ghost)
+ {
+ if (Check_Timer)
+ if (Check_Timer <= diff)
+ {
+ Check_Timer = 5000;
+ Unit* dalronn = Unit::GetUnit(*me, pInstance ? pInstance->GetData64(DATA_DALRONN) : 0);
+ if (dalronn && dalronn->isDead())
+ {
+ Dalronn_isDead = true;
+ Response_Timer = 2000;
+ Check_Timer = 0;
+ }
+ } else Check_Timer -= diff;
+
+ if (Response_Timer)
+ if (Dalronn_isDead)
+ if (Response_Timer <= diff)
+ {
+ DoScriptText(YELL_SKARVALD_DAL_DIEDFIRST,me);
+
+ Response_Timer = 0;
+ } else Response_Timer -= diff;
+ }
+
+ if (Charge_Timer <= diff)
+ {
+ DoCast(SelectUnit(SELECT_TARGET_RANDOM, 1), SPELL_CHARGE);
+ Charge_Timer = 5000+rand()%5000;
+ } else Charge_Timer -= diff;
+
+ if (StoneStrike_Timer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_STONE_STRIKE);
+ StoneStrike_Timer = 5000+rand()%5000;
+ } else StoneStrike_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_skarvald_the_constructor(Creature* pCreature)
+{
+ return new boss_skarvald_the_constructorAI (pCreature);
+}
+
+struct boss_dalronn_the_controllerAI : public ScriptedAI
+{
+ boss_dalronn_the_controllerAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ bool ghost;
+ uint32 ShadowBolt_Timer;
+ uint32 Debilitate_Timer;
+ uint32 Summon_Timer;
+
+ uint32 Response_Timer;
+ uint32 Check_Timer;
+ uint32 AggroYell_Timer;
+ bool Skarvald_isDead;
+
+ void Reset()
+ {
+ ShadowBolt_Timer = 1000;
+ Debilitate_Timer = 5000;
+ Summon_Timer = 10000;
+ Check_Timer = 5000;
+ Skarvald_isDead = false;
+ AggroYell_Timer = 0;
+
+ ghost = me->GetEntry() == MOB_DALRONN_GHOST;
+ if (!ghost && pInstance)
+ {
+ Unit* skarvald = Unit::GetUnit((*me),pInstance->GetData64(DATA_SKARVALD));
+ if (skarvald && skarvald->isDead())
+ CAST_CRE(skarvald)->Respawn();
+
+ pInstance->SetData(DATA_SKARVALD_DALRONN_EVENT, NOT_STARTED);
+ }
+ }
+
+ void EnterCombat(Unit * who)
+ {
+ if (!ghost && pInstance)
+ {
+ Unit* skarvald = Unit::GetUnit((*me),pInstance->GetData64(DATA_SKARVALD));
+ if (skarvald && skarvald->isAlive() && !skarvald->getVictim())
+ skarvald->getThreatManager().addThreat(who,0.0f);
+
+ AggroYell_Timer = 5000;
+
+ if (pInstance)
+ pInstance->SetData(DATA_SKARVALD_DALRONN_EVENT, IN_PROGRESS);
+ }
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ if (!ghost && pInstance)
+ {
+ Unit* skarvald = Unit::GetUnit((*me),pInstance->GetData64(DATA_SKARVALD));
+ if (skarvald)
+ if (skarvald->isDead())
+ {
+ DoScriptText(YELL_DALRONN_SKA_DIED,me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_SKARVALD_DALRONN_EVENT, DONE);
+ }
+ else
+ {
+ DoScriptText(YELL_DALRONN_DAL_DIEDFIRST,me);
+
+ me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ //DoCast(me, SPELL_SUMMON_DALRONN_GHOST, true);
+ Creature* temp = me->SummonCreature(MOB_DALRONN_GHOST,me->GetPositionX(),me->GetPositionY(),me->GetPositionZ(),0,TEMPSUMMON_CORPSE_DESPAWN,5000);
+ if (temp)
+ {
+ temp->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_NON_ATTACKABLE);
+ temp->AI()->AttackStart(Killer);
+ }
+ }
+ }
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ if (!ghost)
+ {
+ DoScriptText(YELL_DALRONN_KILL,me);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (ghost)
+ {
+ if (pInstance && pInstance->GetData(DATA_SKARVALD_DALRONN_EVENT) != IN_PROGRESS)
+ me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+
+ if (!UpdateVictim())
+ return;
+
+ if (AggroYell_Timer)
+ if (AggroYell_Timer <= diff)
+ {
+ DoScriptText(YELL_DALRONN_AGGRO,me);
+
+ AggroYell_Timer = 0;
+ } else AggroYell_Timer -= diff;
+
+ if (!ghost)
+ {
+ if (Check_Timer)
+ if (Check_Timer <= diff)
+ {
+ Check_Timer = 5000;
+ Unit* skarvald = Unit::GetUnit(*me, pInstance ? pInstance->GetData64(DATA_SKARVALD) : 0);
+ if (skarvald && skarvald->isDead())
+ {
+ Skarvald_isDead = true;
+ Response_Timer = 2000;
+ Check_Timer = 0;
+ }
+ } else Check_Timer -= diff;
+
+ if (Response_Timer)
+ if (Skarvald_isDead)
+ if (Response_Timer <= diff)
+ {
+ DoScriptText(YELL_DALRONN_SKA_DIEDFIRST,me);
+
+ Response_Timer = 0;
+ } else Response_Timer -= diff;
+ }
+
+ if (ShadowBolt_Timer <= diff)
+ {
+ if (!me->IsNonMeleeSpellCasted(false))
+ {
+ DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_SHADOW_BOLT);
+ ShadowBolt_Timer = 2100;//give a 100ms pause to try cast other spells
+ }
+ } else ShadowBolt_Timer -= diff;
+
+ if (Debilitate_Timer <= diff)
+ {
+ if (!me->IsNonMeleeSpellCasted(false))
+ {
+ DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DEBILITATE);
+ Debilitate_Timer = 5000+rand()%5000;
+ }
+ } else Debilitate_Timer -= diff;
+
+ if (IsHeroic())
+ if (Summon_Timer <= diff)
+ {
+ if (!me->IsNonMeleeSpellCasted(false))
+ {
+ DoCast(me, H_SPELL_SUMMON_SKELETONS);
+ Summon_Timer = (rand()%10000) + 20000;
+ }
+ } else Summon_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_dalronn_the_controller(Creature* pCreature)
+{
+ return new boss_dalronn_the_controllerAI (pCreature);
+}
+
+void AddSC_boss_skarvald_dalronn()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_skarvald_the_constructor";
+ newscript->GetAI = &GetAI_boss_skarvald_the_constructor;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_dalronn_the_controller";
+ newscript->GetAI = &GetAI_boss_dalronn_the_controller;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp b/src/server/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp
new file mode 100644
index 00000000000..03f97b1d27e
--- /dev/null
+++ b/src/server/scripts/northrend/utgarde_keep/utgarde_keep/instance_utgarde_keep.cpp
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* ScriptData
+SDName: Instance_Utgarde_Keep
+SD%Complete: 90
+SDComment: Instance Data Scripts and functions to acquire mobs and set encounter status for use in various Utgarde Keep Scripts
+SDCategory: Utgarde Keep
+EndScriptData */
+
+#include "ScriptedPch.h"
+#include "utgarde_keep.h"
+
+#define MAX_ENCOUNTER 3
+
+#define ENTRY_BELLOW_1 186688
+#define ENTRY_BELLOW_2 186689
+#define ENTRY_BELLOW_3 186690
+
+#define ENTRY_FORGEFIRE_1 186692
+#define ENTRY_FORGEFIRE_2 186693
+#define ENTRY_FORGEFIRE_3 186691
+
+#define ENTRY_GLOWING_ANVIL_1 186609
+#define ENTRY_GLOWING_ANVIL_2 186610
+#define ENTRY_GLOWING_ANVIL_3 186611
+
+#define ENTRY_GIANT_PORTCULLIS_1 186756
+#define ENTRY_GIANT_PORTCULLIS_2 186694
+
+/* Utgarde Keep encounters:
+0 - Prince Keleseth
+1 - Skarvald Dalronn
+2 - Ingvar the Plunderer
+*/
+
+struct instance_utgarde_keep : public ScriptedInstance
+{
+ instance_utgarde_keep(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+
+ uint64 Keleseth;
+ uint64 Skarvald;
+ uint64 Dalronn;
+ uint64 Ingvar;
+
+ uint64 forge_bellow[3];
+ uint64 forge_fire[3];
+ uint64 forge_anvil[3];
+ uint64 portcullis[2];
+
+ uint32 m_auiEncounter[MAX_ENCOUNTER];
+ uint32 forge_event[3];
+ std::string str_data;
+
+ void Initialize()
+ {
+ memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+
+ Keleseth = 0;
+ Skarvald = 0;
+ Dalronn = 0;
+ Ingvar = 0;
+
+ for (uint8 i = 0; i < 3; ++i)
+ {
+ forge_bellow[i] = 0;
+ forge_fire[i] = 0;
+ forge_anvil[i] = 0;
+ forge_event[i] = NOT_STARTED;
+ }
+
+ portcullis[0] = 0;
+ portcullis[1] = 0;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+ Player* GetPlayerInMap()
+ {
+ Map::PlayerList const& players = instance->GetPlayers();
+
+ if (!players.isEmpty())
+ {
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ {
+ if (Player* plr = itr->getSource())
+ return plr;
+ }
+ }
+
+ debug_log("TSCR: Instance Utgarde Keep: GetPlayerInMap, but PlayerList is empty!");
+ return NULL;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool /*add*/)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case 23953: Keleseth = pCreature->GetGUID(); break;
+ case 24201: Dalronn = pCreature->GetGUID(); break;
+ case 24200: Skarvald = pCreature->GetGUID(); break;
+ case 23954: Ingvar = pCreature->GetGUID(); break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
+ {
+ switch(pGo->GetEntry())
+ {
+ //door and object id
+ case ENTRY_BELLOW_1: forge_bellow[0] = pGo->GetGUID();
+ if (forge_event[0] != NOT_STARTED)HandleGameObject(NULL,true,pGo);break;
+ case ENTRY_BELLOW_2: forge_bellow[1] = pGo->GetGUID();
+ if (forge_event[1] != NOT_STARTED)HandleGameObject(NULL,true,pGo);break;
+ case ENTRY_BELLOW_3: forge_bellow[2] = pGo->GetGUID();
+ if (forge_event[2] != NOT_STARTED)HandleGameObject(NULL,true,pGo);break;
+ case ENTRY_FORGEFIRE_1: forge_fire[0] = pGo->GetGUID();
+ if (forge_event[0] != NOT_STARTED)HandleGameObject(NULL,true,pGo);break;
+ case ENTRY_FORGEFIRE_2: forge_fire[1] = pGo->GetGUID();
+ if (forge_event[1] != NOT_STARTED)HandleGameObject(NULL,true,pGo);break;
+ case ENTRY_FORGEFIRE_3: forge_fire[2] = pGo->GetGUID();
+ if (forge_event[2] != NOT_STARTED)HandleGameObject(NULL,true,pGo);break;
+ case ENTRY_GLOWING_ANVIL_1: forge_anvil[0] = pGo->GetGUID();
+ if (forge_event[0] != NOT_STARTED)HandleGameObject(NULL,true,pGo);break;
+ case ENTRY_GLOWING_ANVIL_2: forge_anvil[1] = pGo->GetGUID();
+ if (forge_event[1] != NOT_STARTED)HandleGameObject(NULL,true,pGo);break;
+ case ENTRY_GLOWING_ANVIL_3: forge_anvil[2] = pGo->GetGUID();
+ if (forge_event[2] != NOT_STARTED)HandleGameObject(NULL,true,pGo);break;
+ case ENTRY_GIANT_PORTCULLIS_1: portcullis[0] = pGo->GetGUID();
+ if (m_auiEncounter[2] == DONE)HandleGameObject(NULL,true,pGo);break;
+ case ENTRY_GIANT_PORTCULLIS_2: portcullis[1] = pGo->GetGUID();
+ if (m_auiEncounter[2] == DONE)HandleGameObject(NULL,true,pGo);break;
+ }
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_PRINCEKELESETH: return Keleseth;
+ case DATA_DALRONN: return Dalronn;
+ case DATA_SKARVALD: return Skarvald;
+ case DATA_INGVAR: return Ingvar;
+ }
+
+ return 0;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_PRINCEKELESETH_EVENT:
+ m_auiEncounter[0] = data;
+ break;
+ case DATA_SKARVALD_DALRONN_EVENT:
+ m_auiEncounter[1] = data;
+ break;
+ case DATA_INGVAR_EVENT:
+ if (data == DONE)
+ {
+ HandleGameObject(portcullis[0], true);
+ HandleGameObject(portcullis[1], true);
+ }
+ m_auiEncounter[2] = data;
+ break;
+ case EVENT_FORGE_1:
+ if (data == NOT_STARTED)
+ {
+ HandleGameObject(forge_bellow[0],false);
+ HandleGameObject(forge_fire[0],false);
+ HandleGameObject(forge_anvil[0],false);
+ }else
+ {
+ HandleGameObject(forge_bellow[0],true);
+ HandleGameObject(forge_fire[0],true);
+ HandleGameObject(forge_anvil[0],true);
+ }
+ forge_event[0] = data;
+ break;
+ case EVENT_FORGE_2:
+ if (data == NOT_STARTED)
+ {
+ HandleGameObject(forge_bellow[1],false);
+ HandleGameObject(forge_fire[1],false);
+ HandleGameObject(forge_anvil[1],false);
+ }else
+ {
+ HandleGameObject(forge_bellow[1],true);
+ HandleGameObject(forge_fire[1],true);
+ HandleGameObject(forge_anvil[1],true);
+ }
+ forge_event[1] = data;
+ break;
+ case EVENT_FORGE_3:
+ if (data == NOT_STARTED)
+ {
+ HandleGameObject(forge_bellow[2],false);
+ HandleGameObject(forge_fire[2],false);
+ HandleGameObject(forge_anvil[2],false);
+ }else
+ {
+ HandleGameObject(forge_bellow[2],true);
+ HandleGameObject(forge_fire[2],true);
+ HandleGameObject(forge_anvil[2],true);
+ }
+ forge_event[2] = data;
+ break;
+ }
+
+ if (data == DONE)
+ {
+ SaveToDB();
+ }
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_PRINCEKELESETH_EVENT: return m_auiEncounter[0];
+ case DATA_SKARVALD_DALRONN_EVENT: return m_auiEncounter[1];
+ case DATA_INGVAR_EVENT: return m_auiEncounter[2];
+ }
+
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "U K " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
+ << m_auiEncounter[2] << " " << forge_event[0] << " " << forge_event[1] << " " << forge_event[2];
+
+ str_data = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return str_data;
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0, data1, data2, data3, data4, data5;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4 >> data5;
+
+ if (dataHead1 == 'U' && dataHead2 == 'K')
+ {
+ m_auiEncounter[0] = data0;
+ m_auiEncounter[1] = data1;
+ m_auiEncounter[2] = data2;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+
+ forge_event[0] = data3;
+ forge_event[1] = data4;
+ forge_event[2] = data5;
+
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_utgarde_keep(Map* pMap)
+{
+ return new instance_utgarde_keep(pMap);
+}
+
+void AddSC_instance_utgarde_keep()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_utgarde_keep";
+ newscript->GetInstanceData = &GetInstanceData_instance_utgarde_keep;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp b/src/server/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp
new file mode 100644
index 00000000000..95825aa49b6
--- /dev/null
+++ b/src/server/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "utgarde_keep.h"
+
+uint32 entry_search[3] =
+{
+ 186609,
+ 186610,
+ 186611
+};
+
+struct npc_dragonflayer_forge_masterAI : public ScriptedAI
+{
+ npc_dragonflayer_forge_masterAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ fm_Type = 0;
+ }
+
+ ScriptedInstance* pInstance;
+ uint8 fm_Type;
+
+ void Reset()
+ {
+ if (fm_Type == 0) fm_Type = GetForgeMasterType();
+ CheckForge();
+ }
+
+ void CheckForge()
+ {
+ if (pInstance)
+ {
+ switch(fm_Type)
+ {
+ case 1:
+ pInstance->SetData(EVENT_FORGE_1,me->isAlive() ? NOT_STARTED : DONE);
+ break;
+ case 2:
+ pInstance->SetData(EVENT_FORGE_2,me->isAlive() ? NOT_STARTED : DONE);
+ break;
+ case 3:
+ pInstance->SetData(EVENT_FORGE_3,me->isAlive() ? NOT_STARTED : DONE);
+ break;
+ }
+ }
+ }
+
+ void JustDied(Unit * /*killer*/)
+ {
+ if (fm_Type == 0) fm_Type = GetForgeMasterType();
+ if (pInstance)
+ {
+ switch(fm_Type)
+ {
+ case 1:
+ pInstance->SetData(EVENT_FORGE_1,DONE);
+ break;
+ case 2:
+ pInstance->SetData(EVENT_FORGE_2,DONE);
+ break;
+ case 3:
+ pInstance->SetData(EVENT_FORGE_3,DONE);
+ break;
+ }
+ }
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ if (fm_Type == 0) fm_Type = GetForgeMasterType();
+ if (pInstance)
+ {
+ switch(fm_Type)
+ {
+ case 1:
+ pInstance->SetData(EVENT_FORGE_1,IN_PROGRESS);
+ break;
+ case 2:
+ pInstance->SetData(EVENT_FORGE_2,IN_PROGRESS);
+ break;
+ case 3:
+ pInstance->SetData(EVENT_FORGE_3,IN_PROGRESS);
+ break;
+ }
+ }
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE ,EMOTE_ONESHOT_NONE);
+ }
+
+ uint8 GetForgeMasterType()
+ {
+ float diff = 30.0f;
+ int near_f = 0;
+
+ for (uint8 i = 0; i < 3 ; ++i)
+ {
+ GameObject* temp;
+ temp = me->FindNearestGameObject(entry_search[i],30);
+ if (temp)
+ {
+ if (me->IsWithinDist(temp,diff,false))
+ {
+ near_f = i + 1;
+ diff = me->GetDistance2d(temp);
+
+ }
+ }
+ }
+
+ switch (near_f)
+ {
+ case 1: return 1;
+ case 2: return 2;
+ case 3: return 3;
+ default: return 0;
+ }
+ }
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ if (fm_Type == 0)
+ fm_Type = GetForgeMasterType();
+
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_dragonflayer_forge_master(Creature* pCreature)
+{
+ return new npc_dragonflayer_forge_masterAI(pCreature);
+}
+
+void AddSC_utgarde_keep()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_dragonflayer_forge_master";
+ newscript->GetAI = &GetAI_npc_dragonflayer_forge_master;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h b/src/server/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h
new file mode 100644
index 00000000000..b630e156564
--- /dev/null
+++ b/src/server/scripts/northrend/utgarde_keep/utgarde_keep/utgarde_keep.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DEF_UTGARDE_KEEP_H
+#define DEF_UTGARDE_KEEP_H
+
+#define DATA_PRINCEKELESETH 1
+#define DATA_SKARVALD 3
+#define DATA_DALRONN 4
+#define DATA_INGVAR 6
+
+#define DATA_PRINCEKELESETH_EVENT 2
+#define DATA_SKARVALD_DALRONN_EVENT 5
+#define DATA_INGVAR_EVENT 7
+
+#define EVENT_FORGE_1 8
+#define EVENT_FORGE_2 9
+#define EVENT_FORGE_3 10
+
+#endif
diff --git a/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp b/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp
new file mode 100644
index 00000000000..297fe37b7d8
--- /dev/null
+++ b/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_palehoof.cpp
@@ -0,0 +1,830 @@
+/* Script Data Start
+SDName: Boss palehoof
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_palehoof' where entry = '';
+*** SQL END ***/
+#include "ScriptedPch.h"
+#include "utgarde_pinnacle.h"
+
+enum Spells
+{
+ SPELL_ARCING_SMASH = 48260,
+ SPELL_IMPALE = 48261,
+ H_SPELL_IMPALE = 59268,
+ SPELL_WITHERING_ROAR = 48256,
+ H_SPELL_WITHERING_ROAR = 59267,
+ SPELL_FREEZE = 16245
+};
+
+//Orb spells
+enum OrbSpells
+{
+ SPELL_ORB_VISUAL = 48044,
+ SPELL_ORB_CHANNEL = 48048
+};
+
+//not in db
+enum Yells
+{
+ SAY_AGGRO = -1575000,
+ SAY_SLAY_1 = -1575001,
+ SAY_SLAY_2 = -1575002,
+ SAY_DEATH = -1575003
+};
+
+enum Creatures
+{
+ MOB_STASIS_CONTROLLER = 26688
+};
+
+struct Locations
+{
+ float x, y, z;
+};
+
+struct Locations moveLocs[]=
+{
+ {261.6,-449.3,109.5},
+ {263.3,-454.0,109.5},
+ {291.5,-450.4,109.5},
+ {291.5,-454.0,109.5},
+ {310.0,-453.4,109.5},
+ {238.6,-460.7,109.5}
+};
+
+enum Phase
+{
+ PHASE_FRENZIED_WORGEN,
+ PHASE_RAVENOUS_FURLBORG,
+ PHASE_MASSIVE_JORMUNGAR,
+ PHASE_FEROCIOUS_RHINO,
+ PHASE_GORTOK_PALEHOOF,
+ PHASE_NONE
+};
+
+struct boss_palehoofAI : public ScriptedAI
+{
+ boss_palehoofAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiArcingSmashTimer;
+ uint32 uiImpaleTimer;
+ uint32 uiWhiteringRoarTimer;
+ uint32 uiWaitingTimer;
+ Phase currentPhase;
+ uint8 AddCount;
+ bool DoneAdds[4];
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ uiArcingSmashTimer = 15000;
+ uiImpaleTimer = 12000;
+ uiWhiteringRoarTimer = 10000;
+
+ me->GetMotionMaster()->MoveTargetedHome();
+
+ for (uint32 i=0;i<4;i++)
+ DoneAdds[i]=false;
+ AddCount=0;
+
+ currentPhase=PHASE_NONE;
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_GORTOK_PALEHOOF_EVENT, NOT_STARTED);
+
+ Creature* pTemp = Unit::GetCreature((*me), pInstance->GetData64(DATA_MOB_FRENZIED_WORGEN));
+ if (pTemp && !pTemp->isAlive())
+ pTemp->Respawn();
+
+ pTemp = Unit::GetCreature((*me), pInstance->GetData64(DATA_MOB_FEROCIOUS_RHINO));
+ if (pTemp && !pTemp->isAlive())
+ pTemp->Respawn();
+
+ pTemp = Unit::GetCreature((*me), pInstance->GetData64(DATA_MOB_MASSIVE_JORMUNGAR));
+ if (pTemp && !pTemp->isAlive())
+ pTemp->Respawn();
+
+ pTemp = Unit::GetCreature((*me), pInstance->GetData64(DATA_MOB_RAVENOUS_FURBOLG));
+ if (pTemp && !pTemp->isAlive())
+ pTemp->Respawn();
+
+ GameObject* pGo = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_GORTOK_PALEHOOF_SPHERE));
+ if (pGo)
+ {
+ pGo->SetGoState(GO_STATE_READY);
+ pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ }
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if (!who)
+ return;
+
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (me->Attack(who, true))
+ {
+ me->AddThreat(who, 0.0f);
+ me->SetInCombatWith(who);
+ who->SetInCombatWith(me);
+ DoStartMovement(who);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (currentPhase != PHASE_GORTOK_PALEHOOF)
+ return;
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ Creature* pTemp = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_MOB_ORB) : 0);
+ if (pTemp && pTemp->isAlive())
+ pTemp->DisappearAndDie();
+
+ if (uiArcingSmashTimer <= diff)
+ {
+ DoCast(me, SPELL_ARCING_SMASH);
+ uiArcingSmashTimer = urand(13000,17000);
+ } else uiArcingSmashTimer -= diff;
+
+ if (uiImpaleTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_IMPALE);
+ uiImpaleTimer = urand(8000,12000);
+ } else uiImpaleTimer -= diff;
+
+ if (uiWhiteringRoarTimer <= diff)
+ {
+ DoCast(me, SPELL_WITHERING_ROAR);
+ uiWhiteringRoarTimer = urand(8000,12000);
+ } else uiWhiteringRoarTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ if (pInstance)
+ pInstance->SetData(DATA_GORTOK_PALEHOOF_EVENT, DONE);
+ Creature* pTemp = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_MOB_ORB) : 0);
+ if (pTemp && pTemp->isAlive())
+ pTemp->DisappearAndDie();
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void NextPhase()
+ {
+ if (currentPhase == PHASE_NONE)
+ {
+ pInstance->SetData(DATA_GORTOK_PALEHOOF_EVENT, IN_PROGRESS);
+ me->SummonCreature(MOB_STASIS_CONTROLLER,moveLocs[5].x,moveLocs[5].y,moveLocs[5].z,0,TEMPSUMMON_CORPSE_DESPAWN);
+ }
+ Phase move = PHASE_NONE;
+ if (AddCount >= DUNGEON_MODE(2,4))
+ move = PHASE_GORTOK_PALEHOOF;
+ else
+ {
+ //select random not yet defeated add
+ uint8 next = urand(0,3);
+ for (uint8 i=0; i < 16; i++)
+ {
+ if (!DoneAdds[i%4] && next == 0)
+ {
+ move = (Phase)(i%4);
+ break;
+ } else if (!DoneAdds[i%4] && next > 0)
+ --next;
+ }
+ ++AddCount;
+ DoneAdds[move] = true;
+ move = (Phase)(move%4);
+ }
+ //send orb to summon spot
+ Creature *pOrb = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_MOB_ORB) : 0);
+ if (pOrb && pOrb->isAlive())
+ {
+ if (currentPhase == PHASE_NONE)
+ pOrb->CastSpell(me,SPELL_ORB_VISUAL,true);
+ pOrb->GetMotionMaster()->MovePoint(move,moveLocs[move].x,moveLocs[move].y,moveLocs[move].z);
+ }
+ currentPhase = move;
+ }
+
+ void JustReachedHome()
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NOT_ATTACKABLE_1|UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ DoCast(me, SPELL_FREEZE);
+ }
+};
+
+CreatureAI* GetAI_boss_palehoof(Creature* pCreature)
+{
+ return new boss_palehoofAI (pCreature);
+}
+
+//ravenous furbolg's spells
+enum RavenousSpells
+{
+ SPELL_CHAIN_LIGHTING = 48140,
+ H_SPELL_CHAIN_LIGHTING = 59273,
+ SPELL_CRAZED = 48139,
+ SPELL_TERRIFYING_ROAR = 48144
+};
+
+struct mob_ravenous_furbolgAI : public ScriptedAI
+{
+ mob_ravenous_furbolgAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiChainLightingTimer;
+ uint32 uiCrazedTimer;
+ uint32 uiTerrifyingRoarTimer;
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ uiChainLightingTimer = 5000;
+ uiCrazedTimer = 10000;
+ uiTerrifyingRoarTimer = 15000;
+
+ me->GetMotionMaster()->MoveTargetedHome();
+
+ if (pInstance)
+ if (pInstance->GetData(DATA_GORTOK_PALEHOOF_EVENT) == IN_PROGRESS)
+ {
+ Creature *pPalehoof = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
+ if (pPalehoof && pPalehoof->isAlive())
+ CAST_AI(boss_palehoofAI, pPalehoof->AI())->Reset();
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiChainLightingTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_CHAIN_LIGHTING);
+ uiChainLightingTimer = 5000 + rand()%5000;
+ } else uiChainLightingTimer -= diff;
+
+ if (uiCrazedTimer <= diff)
+ {
+ DoCast(me, SPELL_CRAZED);
+ uiCrazedTimer = 8000 + rand()%4000;
+ } else uiCrazedTimer -= diff;
+
+ if (uiTerrifyingRoarTimer <= diff)
+ {
+ DoCast(me, SPELL_TERRIFYING_ROAR);
+ uiTerrifyingRoarTimer = 10000 + rand()%10000;
+ } else uiTerrifyingRoarTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if (!who)
+ return;
+
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (me->Attack(who, true))
+ {
+ me->AddThreat(who, 0.0f);
+ me->SetInCombatWith(who);
+ who->SetInCombatWith(me);
+ DoStartMovement(who);
+ }
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ {
+ Creature *pPalehoof = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
+ if (pPalehoof)
+ CAST_AI(boss_palehoofAI, pPalehoof->AI())->NextPhase();
+ }
+ }
+
+ void JustReachedHome()
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NOT_ATTACKABLE_1|UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ DoCast(me, SPELL_FREEZE);
+ }
+};
+
+CreatureAI* GetAI_mob_ravenous_furbolg(Creature* pCreature)
+{
+ return new mob_ravenous_furbolgAI (pCreature);
+}
+
+//frenzied worgen's spells
+enum FrenziedSpells
+{
+ SPELL_MORTAL_WOUND = 48137,
+ H_SPELL_MORTAL_WOUND = 59265,
+ SPELL_ENRAGE_1 = 48138,
+ SPELL_ENRAGE_2 = 48142
+};
+
+struct mob_frenzied_worgenAI : public ScriptedAI
+{
+ mob_frenzied_worgenAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiMortalWoundTimer;
+ uint32 uiEnrage1Timer;
+ uint32 uiEnrage2Timer;
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ uiMortalWoundTimer = 5000;
+ uiEnrage1Timer = 15000;
+ uiEnrage2Timer = 10000;
+
+ me->GetMotionMaster()->MoveTargetedHome();
+
+ if (pInstance)
+ if (pInstance->GetData(DATA_GORTOK_PALEHOOF_EVENT) == IN_PROGRESS)
+ {
+ Creature *pPalehoof = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
+ if (pPalehoof && pPalehoof->isAlive())
+ CAST_AI(boss_palehoofAI, pPalehoof->AI())->Reset();
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiMortalWoundTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_MORTAL_WOUND);
+ uiMortalWoundTimer = 3000 + rand()%4000;
+ } else uiMortalWoundTimer -= diff;
+
+ if (uiEnrage1Timer <= diff)
+ {
+ DoCast(me, SPELL_ENRAGE_1);
+ uiEnrage1Timer = 15000;
+ } else uiEnrage1Timer -= diff;
+
+ if (uiEnrage2Timer <= diff)
+ {
+ DoCast(me, SPELL_ENRAGE_2);
+ uiEnrage2Timer = 10000;
+ } else uiEnrage2Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if (!who)
+ return;
+
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (me->Attack(who, true))
+ {
+ me->AddThreat(who, 0.0f);
+ me->SetInCombatWith(who);
+ who->SetInCombatWith(me);
+ DoStartMovement(who);
+ }
+ if (pInstance)
+ pInstance->SetData(DATA_GORTOK_PALEHOOF_EVENT, IN_PROGRESS);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ {
+ Creature *pPalehoof = Unit::GetCreature((*me), pInstance->GetData64(DATA_GORTOK_PALEHOOF));
+ if (pPalehoof)
+ CAST_AI(boss_palehoofAI, pPalehoof->AI())->NextPhase();
+ }
+ }
+
+ void JustReachedHome()
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NOT_ATTACKABLE_1|UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ DoCast(me, SPELL_FREEZE);
+ }
+};
+
+CreatureAI* GetAI_mob_frenzied_worgen(Creature* pCreature)
+{
+ return new mob_frenzied_worgenAI (pCreature);
+}
+
+//ferocious rhino's spells
+enum FerociousSpells
+{
+ SPELL_GORE = 48130,
+ H_SPELL_GORE = 59264,
+ SPELL_GRIEVOUS_WOUND = 48105,
+ H_SPELL_GRIEVOUS_WOUND = 59263,
+ SPELL_STOMP = 48131
+};
+
+struct mob_ferocious_rhinoAI : public ScriptedAI
+{
+ mob_ferocious_rhinoAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiStompTimer;
+ uint32 uiGoreTimer;
+ uint32 uiGrievousWoundTimer;
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ uiStompTimer = 10000;
+ uiGoreTimer = 15000;
+ uiGrievousWoundTimer = 20000;
+
+ me->GetMotionMaster()->MoveTargetedHome();
+
+ if (pInstance)
+ if (pInstance->GetData(DATA_GORTOK_PALEHOOF_EVENT) == IN_PROGRESS)
+ {
+ Creature *pPalehoof = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
+ if (pPalehoof && pPalehoof->isAlive())
+ CAST_AI(boss_palehoofAI, pPalehoof->AI())->Reset();
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiStompTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_STOMP);
+ uiStompTimer = 8000 + rand()%4000;
+ } else uiStompTimer -= diff;
+
+ if (uiGoreTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_GORE);
+ uiGoreTimer = 13000 + rand()%4000;
+ } else uiGoreTimer -= diff;
+
+ if (uiGrievousWoundTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_GRIEVOUS_WOUND);
+ uiGrievousWoundTimer = 18000 + rand()%4000;
+ } else uiGrievousWoundTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if (!who)
+ return;
+
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (me->Attack(who, true))
+ {
+ me->AddThreat(who, 0.0f);
+ me->SetInCombatWith(who);
+ who->SetInCombatWith(me);
+ DoStartMovement(who);
+ }
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ {
+ Creature *pPalehoof = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
+ if (pPalehoof)
+ CAST_AI(boss_palehoofAI, pPalehoof->AI())->NextPhase();
+ }
+ }
+
+ void JustReachedHome()
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NOT_ATTACKABLE_1|UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ DoCast(me, SPELL_FREEZE);
+ }
+};
+
+CreatureAI* GetAI_mob_ferocious_rhino(Creature* pCreature)
+{
+ return new mob_ferocious_rhinoAI (pCreature);
+}
+
+//massive jormungar's spells
+enum MassiveSpells
+{
+ SPELL_ACID_SPIT = 48132,
+ SPELL_ACID_SPLATTER = 48136,
+ H_SPELL_ACID_SPLATTER = 59272,
+ SPELL_POISON_BREATH = 48133,
+ H_SPELL_POISON_BREATH = 59271
+};
+
+enum MassiveAdds
+{
+ CREATURE_JORMUNGAR_WORM = 27228
+};
+
+struct mob_massive_jormungarAI : public ScriptedAI
+{
+ mob_massive_jormungarAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiAcidSpitTimer;
+ uint32 uiAcidSplatterTimer;
+ uint32 uiPoisonBreathTimer;
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ uiAcidSpitTimer = 3000;
+ uiAcidSplatterTimer = 12000;
+ uiPoisonBreathTimer = 10000;
+
+ me->GetMotionMaster()->MoveTargetedHome();
+
+ if (pInstance)
+ if (pInstance->GetData(DATA_GORTOK_PALEHOOF_EVENT) == IN_PROGRESS)
+ {
+ Creature *pPalehoof = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
+ if (pPalehoof && pPalehoof->isAlive())
+ CAST_AI(boss_palehoofAI, pPalehoof->AI())->Reset();
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiAcidSpitTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_ACID_SPIT);
+ uiAcidSpitTimer = 2000 + rand()%2000;
+ } else uiAcidSpitTimer -= diff;
+
+ if (uiAcidSplatterTimer <= diff)
+ {
+ DoCast(me, SPELL_POISON_BREATH);
+ uiAcidSplatterTimer = 10000 + rand()%4000;
+ } else uiAcidSplatterTimer -= diff;
+
+ if (uiPoisonBreathTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_POISON_BREATH);
+ uiPoisonBreathTimer = 8000 + rand()%4000;
+ } else uiPoisonBreathTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void AttackStart(Unit* who)
+ {
+ if (!who)
+ return;
+
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (me->Attack(who, true))
+ {
+ me->AddThreat(who, 0.0f);
+ me->SetInCombatWith(who);
+ who->SetInCombatWith(me);
+ DoStartMovement(who);
+ }
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ {
+ Creature *pPalehoof = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
+ if (pPalehoof)
+ CAST_AI(boss_palehoofAI,pPalehoof->AI())->NextPhase();
+ }
+ }
+
+ void JustReachedHome()
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NOT_ATTACKABLE_1|UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ DoCast(me, SPELL_FREEZE);
+ }
+};
+
+CreatureAI* GetAI_mob_massive_jormungar(Creature* pCreature)
+{
+ return new mob_massive_jormungarAI (pCreature);
+}
+
+
+struct mob_palehoof_orbAI : public ScriptedAI
+{
+ mob_palehoof_orbAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance *pInstance;
+ uint32 SummonTimer;
+ Phase currentPhase;
+
+ void Reset()
+ {
+ currentPhase=PHASE_NONE;
+ SummonTimer=5000;
+ me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING);
+ me->RemoveAurasDueToSpell(SPELL_ORB_VISUAL);
+ me->SetSpeed(MOVE_FLIGHT , 0.5f);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (currentPhase == PHASE_NONE)
+ return;
+
+ if (SummonTimer <= diff)
+ {
+ if (currentPhase<5&&currentPhase >= 0)
+ {
+ Creature *pNext = NULL;
+ switch(currentPhase)
+ {
+ case PHASE_FRENZIED_WORGEN: pNext = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_MOB_FRENZIED_WORGEN) : 0); break;
+ case PHASE_RAVENOUS_FURLBORG: pNext = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_MOB_RAVENOUS_FURBOLG) : 0); break;
+ case PHASE_MASSIVE_JORMUNGAR: pNext = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_MOB_MASSIVE_JORMUNGAR) : 0); break;
+ case PHASE_FEROCIOUS_RHINO: pNext = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_MOB_FEROCIOUS_RHINO) : 0); break;
+ case PHASE_GORTOK_PALEHOOF: pNext = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0); break;
+ }
+
+ if (pNext)
+ {
+ pNext->RemoveAurasDueToSpell(SPELL_FREEZE);
+ pNext->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_ATTACKABLE_1|UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ pNext->SetStandState(UNIT_STAND_STATE_STAND);
+ pNext->SetInCombatWithZone();
+ pNext->Attack(pNext->SelectNearestTarget(100),true);
+
+ }
+ currentPhase=PHASE_NONE;
+ }
+ } else SummonTimer-=diff;
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+ if (id<0 || id>4)
+ return;
+ Creature *pNext = NULL;
+ switch(id)
+ {
+ case PHASE_FRENZIED_WORGEN: pNext = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_MOB_FRENZIED_WORGEN) : 0); break;
+ case PHASE_RAVENOUS_FURLBORG: pNext = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_MOB_RAVENOUS_FURBOLG) : 0); break;
+ case PHASE_MASSIVE_JORMUNGAR: pNext = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_MOB_MASSIVE_JORMUNGAR) : 0); break;
+ case PHASE_FEROCIOUS_RHINO: pNext = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_MOB_FEROCIOUS_RHINO) : 0); break;
+ case PHASE_GORTOK_PALEHOOF: pNext = Unit::GetCreature((*me), pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0); break;
+ }
+ if (pNext)
+ DoCast(pNext, SPELL_ORB_CHANNEL, false);
+ currentPhase=(Phase)id;
+ SummonTimer=5000;
+ }
+};
+
+CreatureAI* GetAI_mob_palehoof_orb(Creature* pCreature)
+{
+ return new mob_palehoof_orbAI (pCreature);
+}
+
+
+
+bool GOHello_palehoof_sphere(Player * /*pPlayer*/, GameObject *pGO)
+{
+ ScriptedInstance *pInstance = pGO->GetInstanceData();
+
+ Creature *pPalehoof = Unit::GetCreature(*pGO, pInstance ? pInstance->GetData64(DATA_GORTOK_PALEHOOF) : 0);
+ if (pPalehoof && pPalehoof->isAlive())
+ {
+ // maybe these are hacks :(
+ pGO->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ pGO->SetGoState(GO_STATE_ACTIVE);
+
+ CAST_AI(boss_palehoofAI, pPalehoof->AI())->NextPhase();
+ }
+ return true;
+}
+
+
+
+void AddSC_boss_palehoof()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_palehoof";
+ newscript->GetAI = &GetAI_boss_palehoof;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_ravenous_furbolg";
+ newscript->GetAI = &GetAI_mob_ravenous_furbolg;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_frenzied_worgen";
+ newscript->GetAI = &GetAI_mob_frenzied_worgen;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_ferocious_rhino";
+ newscript->GetAI = &GetAI_mob_ferocious_rhino;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_massive_jormungar";
+ newscript->GetAI = &GetAI_mob_massive_jormungar;
+ newscript->RegisterSelf();
+
+
+ newscript = new Script;
+ newscript->Name = "mob_palehoof_orb";
+ newscript->GetAI = &GetAI_mob_palehoof_orb;
+ newscript->RegisterSelf();
+
+
+ newscript = new Script;
+ newscript->Name = "go_palehoof_sphere";
+ newscript->pGOHello=&GOHello_palehoof_sphere;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp b/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp
new file mode 100644
index 00000000000..a75eb3465be
--- /dev/null
+++ b/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_skadi.cpp
@@ -0,0 +1,477 @@
+/* Copyright (C) 2008 - 2010 Trinity <http://www.trinitycore.org/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Script Data Start
+SDName: Boss_Skadi
+SDAuthor: LordVanMartin, JohnHoliver
+SD%Complete: 90%
+SDComment: <Known Bugs>
+ After Unmount() he appears to still be flying even with SetFlying(false)
+ </Known Bugs>
+SDCategory: Utgarde Pinnacle
+Script Data End */
+
+#include "ScriptedPch.h"
+#include "utgarde_pinnacle.h"
+
+//Yell
+enum eYells
+{
+ SAY_AGGRO = -1575004,
+ SAY_KILL_1 = -1575005,
+ SAY_KILL_2 = -1575006,
+ EMOTE_RANGE = -1575007, //Skadi
+ SAY_DEATH = -1575008,
+ SAY_DRAKE_DEATH = -1575009,
+ EMOTE_BREATH = -1575010, //Grauf
+ SAY_DRAKE_BREATH_1 = -1575011,
+ SAY_DRAKE_BREATH_2 = -1575012,
+ SAY_DRAKE_BREATH_3 = -1575013,
+};
+
+static Position SpawnLoc = {468.931, -513.555, 104.723};
+static Position Location[]=
+{
+ // Boss
+ {341.740997, -516.955017, 104.66900}, // 0
+ {293.299, -505.95, 142.03}, // 1
+ {301.664, -535.164, 146.097}, // 2
+ {521.031006, -544.667847, 128.80064}, // 3
+ {477.311981, -509.296814, 104.72308}, // 4
+ {341.740997, -516.955017, 104.66900}, // 5
+ {341.740997, -516.955017, 104.66900}, // 6
+ {341.740997, -516.955017, 104.66900}, // 7
+ // Triggers Left
+ {469.661, -484.546, 104.712}, // 8
+ {483.315, -485.028, 104.718}, // 9
+ {476.87, -487.994, 104.735}, //10
+ {477.512, -497.772, 104.728}, //11
+ {486.287, -500.759, 104.722}, //12
+ {480.1, -503.895, 104.722}, //13
+ {472.391, -505.103, 104.723}, //14
+ {478.885, -510.803, 104.723}, //15
+ {489.529, -508.615, 104.723}, //16
+ {484.272, -508.589, 104.723}, //17
+ {465.328, -506.495, 104.427}, //18
+ {456.885, -508.104, 104.447}, //19
+ {450.177, -507.989, 105.247}, //20
+ {442.273, -508.029, 104.813}, //21
+ {434.225, -508.19, 104.787}, //22
+ {423.902, -508.525, 104.274}, //23
+ {414.551, -508.645, 105.136}, //24
+ {405.787, -508.755, 104.988}, //25
+ {398.812, -507.224, 104.82}, //26
+ {389.702, -506.846, 104.729}, //27
+ {381.856, -506.76, 104.756}, //28
+ {372.881, -507.254, 104.779}, //29
+ {364.978, -508.182, 104.673}, //30
+ {357.633, -508.075, 104.647}, //31
+ {350.008, -506.826, 104.588}, //32
+ {341.69, -506.77, 104.499}, //33
+ {335.31, -505.745, 105.18}, //34
+ {471.178, -510.74, 104.723}, //35
+ {461.759, -510.365, 104.199}, //36
+ {424.07287, -510.082916, 104.711082}, //37
+ // Triggers Right
+ {489.46, -513.297, 105.413}, //38
+ {485.706, -517.175, 104.724}, //39
+ {480.98, -519.313, 104.724}, //40
+ {475.05, -520.52, 104.724}, //41
+ {482.97, -512.099, 104.724}, //42
+ {477.082, -514.172, 104.724}, //43
+ {468.991, -516.691, 104.724}, //44
+ {461.722, -517.063, 104.627}, //45
+ {455.88, -517.681, 104.707}, //46
+ {450.499, -519.099, 104.701}, //47
+ {444.889, -518.963, 104.82}, //48
+ {440.181, -518.893, 104.861}, //49
+ {434.393, -518.758, 104.891}, //50
+ {429.328, -518.583, 104.904}, //51
+ {423.844, -518.394, 105.004}, //52
+ {418.707, -518.266, 105.135}, //53
+ {413.377, -518.085, 105.153}, //54
+ {407.277, -517.844, 104.893}, //55
+ {401.082, -517.443, 104.723}, //56
+ {394.933, -514.64, 104.724}, //57
+ {388.917, -514.688, 104.734}, //58
+ {383.814, -515.834, 104.73}, //59
+ {377.887, -518.653, 104.777}, //60
+ {371.376, -518.289, 104.781}, //61
+ {365.669, -517.822, 104.758}, //62
+ {359.572, -517.314, 104.706}, //63
+ {353.632, -517.146, 104.647}, //64
+ {347.998, -517.038, 104.538}, //65
+ {341.803, -516.98, 104.584}, //66
+ {335.879, -516.674, 104.628}, //67
+ {329.871, -515.92, 104.711}, //68
+ // Breach Zone
+ {485.4577, -511.2515, 115.3011}, //69
+ {435.1892, -514.5232, 118.6719}, //70
+ {413.9327, -540.9407, 138.2614}, //71
+};
+
+enum eCombatPhase
+{
+ FLYING,
+ SKADI
+};
+
+enum eSpells
+{
+ //Skadi Spells
+ SPELL_CRUSH = 50234,
+ SPELL_POISONED_SPEAR = 50225, //isn't being casted =/
+ SPELL_WHIRLWIND = 50228, //random target, but not the tank approx. every 20s
+ SPELL_RAPID_FIRE = 56570,
+ SPELL_HARPOON_DAMAGE = 56578,
+ SPELL_FREEZING_CLOUD = 47579,
+};
+
+enum eCreature
+{
+ CREATURE_YMIRJAR_WARRIOR = 26690,
+ CREATURE_YMIRJAR_WITCH_DOCTOR = 26691,
+ CREATURE_YMIRJAR_HARPOONER = 26692,
+ CREATURE_GRAUF = 26893,
+ CREATURE_TRIGGER = 28351,
+ DATA_MOUNT = 27043,
+};
+
+enum eAchievments
+{
+ ACHIEV_TIMED_START_EVENT = 17726,
+};
+
+struct boss_skadiAI : public ScriptedAI
+{
+ boss_skadiAI(Creature *c) : ScriptedAI(c), Summons(me)
+ {
+ m_pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* m_pInstance;
+ SummonList Summons;
+ uint64 m_uiGraufGUID;
+ std::vector<uint64> triggersGUID;
+
+ uint32 m_uiCrushTimer;
+ uint32 m_uiPoisonedSpearTimer;
+ uint32 m_uiWhirlwindTimer;
+ uint32 m_uiWaypointId;
+ uint32 m_uiMovementTimer;
+ uint32 m_uiMountTimer;
+ uint32 m_uiSummonTimer;
+ uint8 m_uiSpellHitCount;
+ bool m_bSaidEmote;
+
+ eCombatPhase Phase;
+
+ void Reset()
+ {
+ triggersGUID.clear();
+
+ m_uiCrushTimer = 8000;
+ m_uiPoisonedSpearTimer = 10000;
+ m_uiWhirlwindTimer = 20000;
+ m_uiMountTimer = 3000;
+ m_uiWaypointId = 0;
+ m_bSaidEmote = false;
+ m_uiSpellHitCount = 0;
+
+ Phase = SKADI;
+
+ Summons.DespawnAll();
+ me->SetSpeed(MOVE_FLIGHT, 3.0f);
+ if ((Unit::GetCreature((*me), m_uiGraufGUID) == NULL) && !me->IsMounted())
+ me->SummonCreature(CREATURE_GRAUF,Location[0].GetPositionX(),Location[0].GetPositionY(),Location[0].GetPositionZ(),3.0f);
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(DATA_SKADI_THE_RUTHLESS_EVENT, NOT_STARTED);
+ m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ }
+ }
+
+ void JustReachedHome()
+ {
+ me->SetFlying(false);
+ me->Unmount();
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
+ if (Unit::GetCreature((*me), m_uiGraufGUID) == NULL)
+ me->SummonCreature(CREATURE_GRAUF,Location[0].GetPositionX(),Location[0].GetPositionY(),Location[0].GetPositionZ(),3.0f);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
+
+ Phase = FLYING;
+
+ m_uiMovementTimer = 1000;
+ m_uiSummonTimer = 10000;
+ me->SetInCombatWithZone();
+ if (m_pInstance)
+ {
+ m_pInstance->SetData(DATA_SKADI_THE_RUTHLESS_EVENT, IN_PROGRESS);
+ m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+ me->GetMotionMaster()->MoveJump(Location[0].GetPositionX(), Location[0].GetPositionY(), Location[0].GetPositionZ(), 5.0f, 10.0f);
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ m_uiMountTimer = 1000;
+ Summons.DespawnEntry(CREATURE_GRAUF);
+ }
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ switch (pSummoned->GetEntry())
+ {
+ case CREATURE_GRAUF:
+ m_uiGraufGUID = pSummoned->GetGUID();
+ break;
+ case CREATURE_YMIRJAR_WARRIOR:
+ case CREATURE_YMIRJAR_WITCH_DOCTOR:
+ case CREATURE_YMIRJAR_HARPOONER:
+ pSummoned->setActive(true);
+ pSummoned->SetInCombatWithZone();
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ pSummoned->AI()->AttackStart(pTarget);
+ break;
+ case CREATURE_TRIGGER:
+ pSummoned->CastSpell((Unit*)NULL, SPELL_FREEZING_CLOUD, true);
+ pSummoned->ForcedDespawn(10*IN_MILISECONDS);
+ break;
+ }
+ Summons.Summon(pSummoned);
+ }
+
+ void SummonedCreatureDespawn(Creature* pSummoned)
+ {
+ if (pSummoned->GetEntry() == CREATURE_GRAUF)
+ m_uiGraufGUID = 0;
+ Summons.Despawn(pSummoned);
+ }
+
+ void SpellHit(Unit *caster, const SpellEntry *spell)
+ {
+ if (spell->Id == SPELL_HARPOON_DAMAGE)
+ {
+ m_uiSpellHitCount++;
+ if (m_uiSpellHitCount >= 5)
+ {
+ Phase = SKADI;
+ me->SetFlying(false);
+ me->Unmount();
+ if(Creature* pGrauf = me->SummonCreature(CREATURE_GRAUF, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3*IN_MILISECONDS))
+ {
+ pGrauf->GetMotionMaster()->MoveFall(0);
+ pGrauf->HandleEmoteCommand(EMOTE_ONESHOT_FLYDEATH);
+ }
+ sLog.outBasic("[Skadi] Fly off");
+ me->GetMotionMaster()->MoveJump(Location[4].GetPositionX(), Location[4].GetPositionY(), Location[4].GetPositionZ(), 5.0f, 10.0f);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
+ DoScriptText(SAY_DRAKE_DEATH, me);
+ m_uiCrushTimer = 8000;
+ m_uiPoisonedSpearTimer = 10000;
+ m_uiWhirlwindTimer = 20000;
+ me->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM));
+ }
+ }
+ }
+
+
+ void UpdateAI(const uint32 diff)
+ {
+ switch(Phase)
+ {
+ case FLYING:
+ if (!UpdateVictim())
+ return;
+
+ if (me->GetPositionX() >= 519)
+ {
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
+ if (!m_bSaidEmote)
+ {
+ DoScriptText(EMOTE_RANGE, me);
+ m_bSaidEmote = true;
+ }
+ }
+ else
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
+ m_bSaidEmote = false;
+ }
+
+ if (m_uiMountTimer && m_uiMountTimer <= diff)
+ {
+ me->Mount(DATA_MOUNT);
+ me->SetFlying(true);
+ m_uiMountTimer = 0;
+ } else m_uiMountTimer -= diff;
+
+ if (m_uiSummonTimer <= diff)
+ {
+ SpawnMobs();
+ m_uiSummonTimer = 25000;
+ } else m_uiSummonTimer -= diff;
+
+ if (m_uiMovementTimer <= diff)
+ {
+ switch(m_uiWaypointId)
+ {
+ case 0:
+ me->GetMotionMaster()->MovePoint(0, Location[1].GetPositionX(), Location[1].GetPositionY(), Location[1].GetPositionZ());
+ m_uiMovementTimer = 5000;
+ break;
+ case 1:
+ me->GetMotionMaster()->MovePoint(0, Location[2].GetPositionX(), Location[2].GetPositionY(), Location[2].GetPositionZ());
+ m_uiMovementTimer = 2000;
+ break;
+ case 2:
+ me->GetMotionMaster()->MovePoint(0, Location[3].GetPositionX(), Location[3].GetPositionY(), Location[3].GetPositionZ());
+ m_uiMovementTimer = 15000;
+ break;
+ case 3:
+ me->GetMotionMaster()->MovePoint(0, Location[69].GetPositionX(), Location[69].GetPositionY(), Location[69].GetPositionZ());
+ DoScriptText(RAND(SAY_DRAKE_BREATH_1,SAY_DRAKE_BREATH_2), me);
+ DoScriptText(EMOTE_BREATH, me);
+ m_uiMovementTimer = 2500;
+ break;
+ case 4:
+ me->GetMotionMaster()->MovePoint(0, Location[70].GetPositionX(), Location[70].GetPositionY(), Location[70].GetPositionZ());
+ m_uiMovementTimer = 2000;
+ SpawnTrigger();
+ break;
+ case 5:
+ me->GetMotionMaster()->MovePoint(0, Location[71].GetPositionX(), Location[71].GetPositionY(), Location[71].GetPositionZ());
+ m_uiMovementTimer = 3000;
+ break;
+ case 6:
+ me->GetMotionMaster()->MovePoint(0, Location[3].GetPositionX(), Location[3].GetPositionY(), Location[3].GetPositionZ());
+ m_uiWaypointId = 2;
+ m_uiMovementTimer = 15000;
+ break;
+ }
+ m_uiWaypointId++;
+ } else m_uiMovementTimer -= diff;
+ break;
+ case SKADI:
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (m_uiCrushTimer <= diff)
+ {
+ DoCastVictim(SPELL_CRUSH);
+ m_uiCrushTimer = 8000;
+ } else m_uiCrushTimer -= diff;
+
+ if (m_uiPoisonedSpearTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_POISONED_SPEAR);
+ m_uiPoisonedSpearTimer = 10000;
+ } else m_uiPoisonedSpearTimer -= diff;
+
+ if (m_uiWhirlwindTimer <= diff)
+ {
+ DoCastAOE(SPELL_WHIRLWIND);
+ m_uiWhirlwindTimer = 20000;
+ } else m_uiWhirlwindTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ break;
+ }
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ Summons.DespawnAll();
+ if (m_pInstance)
+ m_pInstance->SetData(DATA_SKADI_THE_RUTHLESS_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(RAND(SAY_KILL_1,SAY_KILL_2), me);
+ }
+
+ void SpawnMobs()
+ {
+ for (uint8 i = 0; i < DUNGEON_MODE(5,6); ++i)
+ {
+ switch (urand(0,2))
+ {
+ case 0: me->SummonCreature(CREATURE_YMIRJAR_WARRIOR, SpawnLoc.GetPositionX()+rand()%5, SpawnLoc.GetPositionY()+rand()%5, SpawnLoc.GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); break;
+ case 1: me->SummonCreature(CREATURE_YMIRJAR_WITCH_DOCTOR, SpawnLoc.GetPositionX()+rand()%5, SpawnLoc.GetPositionY()+rand()%5, SpawnLoc.GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); break;
+ case 2: me->SummonCreature(CREATURE_YMIRJAR_HARPOONER, SpawnLoc.GetPositionX()+rand()%5, SpawnLoc.GetPositionY()+rand()%5, SpawnLoc.GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); break;
+ }
+ }
+ }
+
+ void SpawnTrigger()
+ {
+ uint8 iStart,iEnd;
+ switch (urand(0,1))
+ {
+ case 0:
+ iStart = 8;
+ iEnd = 37;
+ break;
+ case 1:
+ iStart = 38;
+ iEnd = 68;
+ break;
+ }
+ for(uint32 i = iStart; i < iEnd; ++i)
+ me->SummonCreature(CREATURE_TRIGGER,Location[i]);
+ }
+};
+
+bool GOHello_go_harpoon_launcher(Player *pPlayer, GameObject *pGO)
+{
+ ScriptedInstance* m_pInstance;
+ m_pInstance = (ScriptedInstance*)pGO->GetInstanceData();
+ if (!m_pInstance) return false;
+
+ if (Creature* pSkadi = Unit::GetCreature((*pGO),m_pInstance->GetData64(DATA_SKADI_THE_RUTHLESS)))
+ {
+ pPlayer->CastSpell(pSkadi,SPELL_RAPID_FIRE, true);
+ }
+ return false;
+}
+
+CreatureAI* GetAI_boss_skadi(Creature* pCreature)
+{
+ return new boss_skadiAI (pCreature);
+}
+
+void AddSC_boss_skadi()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_skadi";
+ newscript->GetAI = &GetAI_boss_skadi;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_harpoon_launcher";
+ newscript->pGOHello = &GOHello_go_harpoon_launcher;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp b/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp
new file mode 100644
index 00000000000..aae1015ddab
--- /dev/null
+++ b/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_svala.cpp
@@ -0,0 +1,408 @@
+/* Copyright (C) 2008 - 2010 TrinityCore <http://www.trinitycore.org>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "utgarde_pinnacle.h"
+
+enum Spells
+{
+ SPELL_CALL_FLAMES = 48258,
+ SPELL_RITUAL_OF_THE_SWORD = 48276, //Effect #1 Teleport, Effect #2 Dummy
+ SPELL_SINSTER_STRIKE = 15667,
+ H_SPELL_SINSTER_STRIKE = 59409,
+ SPELL_SVALA_TRANSFORMING1 = 54140,
+ SPELL_SVALA_TRANSFORMING2 = 54205
+};
+//not in db
+enum Yells
+{
+ SAY_DIALOG_WITH_ARTHAS_1 = -1575015,
+ SAY_DIALOG_WITH_ARTHAS_2 = -1575016,
+ SAY_DIALOG_WITH_ARTHAS_3 = -1575017,
+ SAY_AGGRO = -1575018,
+ SAY_SLAY_1 = -1575019,
+ SAY_SLAY_2 = -1575020,
+ SAY_SLAY_3 = -1575021,
+ SAY_DEATH = -1575022,
+ SAY_SACRIFICE_PLAYER_1 = -1575023,
+ SAY_SACRIFICE_PLAYER_2 = -1575024,
+ SAY_SACRIFICE_PLAYER_3 = -1575025,
+ SAY_SACRIFICE_PLAYER_4 = -1575026,
+ SAY_SACRIFICE_PLAYER_5 = -1575027,
+ SAY_DIALOG_OF_ARTHAS_1 = -1575028,
+ SAY_DIALOG_OF_ARTHAS_2 = -1575029
+};
+enum Creatures
+{
+ CREATURE_ARTHAS = 24266, // Image of Arthas
+ CREATURE_SVALA_SORROWGRAVE = 26668, // Svala after transformation
+ CREATURE_SVALA = 29281, // Svala before transformation
+ CREATURE_RITUAL_CHANNELER = 27281
+};
+enum ChannelerSpells
+{
+ //ritual channeler's spells
+ SPELL_PARALYZE = 48278,
+ SPELL_SHADOWS_IN_THE_DARK = 59407
+};
+enum Misc
+{
+ DATA_SVALA_DISPLAY_ID = 25944
+};
+enum IntroPhase
+{
+ IDLE,
+ INTRO,
+ FINISHED
+};
+enum CombatPhase
+{
+ NORMAL,
+ SACRIFICING
+};
+
+static Position RitualChannelerPos[]=
+{
+ {296.42, -355.01, 90.94},
+ {302.36, -352.01, 90.54},
+ {291.39, -350.89, 90.54}
+};
+static Position ArthasPos = { 295.81, -366.16, 92.57, 1.58 };
+static Position SvalaPos = { 296.632, -346.075, 90.6307, 1.58 };
+
+struct boss_svalaAI : public ScriptedAI
+{
+ boss_svalaAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiIntroTimer;
+
+ uint8 uiIntroPhase;
+
+ IntroPhase Phase;
+
+ TempSummon* pArthas;
+ uint64 uiArthasGUID;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ Phase = IDLE;
+ uiIntroTimer = 1*IN_MILISECONDS;
+ uiIntroPhase = 0;
+ uiArthasGUID = 0;
+
+ if (pInstance)
+ pInstance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, NOT_STARTED);
+ }
+
+ void MoveInLineOfSight(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ if (Phase == IDLE && pWho->isTargetableForAttack() && me->IsHostileTo(pWho) && me->IsWithinDistInMap(pWho, 40))
+ {
+ Phase = INTRO;
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ if (Creature *pArthas = me->SummonCreature(CREATURE_ARTHAS, ArthasPos, TEMPSUMMON_MANUAL_DESPAWN))
+ {
+ pArthas->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ pArthas->SetFloatValue(OBJECT_FIELD_SCALE_X, 5);
+ uiArthasGUID = pArthas->GetGUID();
+ }
+ }
+ }
+
+ void AttackStart(Unit* /*who*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (Phase != INTRO)
+ return;
+
+ if (uiIntroTimer <= diff)
+ {
+ Creature *pArthas = Unit::GetCreature(*me, uiArthasGUID);
+ if (!pArthas)
+ return;
+
+ switch (uiIntroPhase)
+ {
+ case 0:
+ DoScriptText(SAY_DIALOG_WITH_ARTHAS_1, me);
+ ++uiIntroPhase;
+ uiIntroTimer = 3.5*IN_MILISECONDS;
+ break;
+ case 1:
+ DoScriptText(SAY_DIALOG_OF_ARTHAS_1, pArthas);
+ ++uiIntroPhase;
+ uiIntroTimer = 3.5*IN_MILISECONDS;
+ break;
+ case 2:
+ DoScriptText(SAY_DIALOG_WITH_ARTHAS_2, me);
+ ++uiIntroPhase;
+ uiIntroTimer = 3.5*IN_MILISECONDS;
+ break;
+ case 3:
+ DoScriptText(SAY_DIALOG_OF_ARTHAS_2, pArthas);
+ ++uiIntroPhase;
+ uiIntroTimer = 3.5*IN_MILISECONDS;
+ break;
+ case 4:
+ DoScriptText(SAY_DIALOG_WITH_ARTHAS_3, me);
+ DoCast(me, SPELL_SVALA_TRANSFORMING1);
+ ++uiIntroPhase;
+ uiIntroTimer = 2.8*IN_MILISECONDS;
+ break;
+ case 5:
+ DoCast(me, SPELL_SVALA_TRANSFORMING2);
+ ++uiIntroPhase;
+ uiIntroTimer = 200;
+ break;
+ case 6:
+ if (Creature* pSvalaSorrowgrave = me->SummonCreature(CREATURE_SVALA_SORROWGRAVE, SvalaPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60*IN_MILISECONDS))
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ me->SetDisplayId(DATA_SVALA_DISPLAY_ID);
+ pArthas->ToTempSummon()->UnSummon();
+ uiArthasGUID = 0;
+ Phase = FINISHED;
+ }
+ else
+ Reset();
+ break;
+ }
+ } else uiIntroTimer -= diff;
+ }
+};
+
+struct mob_ritual_channelerAI : public Scripted_NoMovementAI
+{
+ mob_ritual_channelerAI(Creature *c) :Scripted_NoMovementAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ DoCast(me, SPELL_SHADOWS_IN_THE_DARK);
+ }
+
+ // called by svala sorrowgrave to set guid of victim
+ void DoAction(uint32 /*action*/)
+ {
+ if (pInstance)
+ if (Unit *pVictim = me->GetUnit(*me, pInstance->GetData64(DATA_SACRIFICED_PLAYER)))
+ DoCast(pVictim, SPELL_PARALYZE);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ }
+};
+
+struct boss_svala_sorrowgraveAI : public ScriptedAI
+{
+ boss_svala_sorrowgraveAI(Creature *c) : ScriptedAI(c), summons(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiSinsterStrikeTimer;
+ uint32 uiCallFlamesTimer;
+ uint32 uiRitualOfSwordTimer;
+ uint32 uiSacrificeTimer;
+
+ CombatPhase Phase;
+
+ SummonList summons;
+
+ bool bSacrificed;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiSinsterStrikeTimer = 7*IN_MILISECONDS;
+ uiCallFlamesTimer = 10*IN_MILISECONDS;
+ uiRitualOfSwordTimer = 20*IN_MILISECONDS;
+ uiSacrificeTimer = 8*IN_MILISECONDS;
+
+ bSacrificed = false;
+
+ Phase = NORMAL;
+
+ DoTeleportTo(296.632, -346.075, 90.6307);
+ me->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
+
+ summons.DespawnAll();
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, NOT_STARTED);
+ pInstance->SetData64(DATA_SACRIFICED_PLAYER,0);
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, IN_PROGRESS);
+ }
+
+ void JustSummoned(Creature *summon)
+ {
+ summons.Summon(summon);
+ }
+
+ void SummonedCreatureDespawn(Creature *summon)
+ {
+ summons.Despawn(summon);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (Phase == NORMAL)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiSinsterStrikeTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_SINSTER_STRIKE);
+ uiSinsterStrikeTimer = urand(5*IN_MILISECONDS,9*IN_MILISECONDS);
+ } else uiSinsterStrikeTimer -= diff;
+
+ if (uiCallFlamesTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ {
+ DoCast(pTarget, SPELL_CALL_FLAMES);
+ uiCallFlamesTimer = urand(8*IN_MILISECONDS,12*IN_MILISECONDS);
+ }
+ } else uiCallFlamesTimer -= diff;
+
+ if (!bSacrificed)
+ if (uiRitualOfSwordTimer <= diff)
+ {
+ if (Unit* pSacrificeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ {
+ DoScriptText(RAND(SAY_SACRIFICE_PLAYER_1,SAY_SACRIFICE_PLAYER_2,SAY_SACRIFICE_PLAYER_3,SAY_SACRIFICE_PLAYER_4,SAY_SACRIFICE_PLAYER_5),me);
+ DoCast(pSacrificeTarget, SPELL_RITUAL_OF_THE_SWORD);
+ //Spell doesn't teleport
+ DoTeleportPlayer(pSacrificeTarget, 296.632, -346.075, 90.63, 4.6);
+ me->SetUnitMovementFlags(MOVEMENTFLAG_FLY_MODE);
+ DoTeleportTo(296.632, -346.075, 120.85);
+ Phase = SACRIFICING;
+ if (pInstance)
+ {
+ pInstance->SetData64(DATA_SACRIFICED_PLAYER,pSacrificeTarget->GetGUID());
+
+ for (uint8 i = 0; i < 3; ++i)
+ if (Creature* pSummon = me->SummonCreature(CREATURE_RITUAL_CHANNELER, RitualChannelerPos[i], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000))
+ pSummon->AI()->DoAction(0);
+ }
+
+ bSacrificed = true;
+ }
+ } else uiRitualOfSwordTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+ else //SACRIFICING
+ {
+ if (uiSacrificeTimer <= diff)
+ {
+ Unit* pSacrificeTarget = pInstance ? Unit::GetUnit(*me, pInstance->GetData64(DATA_SACRIFICED_PLAYER)) : NULL;
+ if (pInstance && !summons.empty() && pSacrificeTarget && pSacrificeTarget->isAlive())
+ me->Kill(pSacrificeTarget, false); // durability damage?
+
+ //go down
+ Phase = NORMAL;
+ pSacrificeTarget = NULL;
+ me->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ me->GetMotionMaster()->MoveChase(pTarget);
+
+ uiSacrificeTimer = 8*IN_MILISECONDS;
+ }
+ else uiSacrificeTimer -= diff;
+ }
+ }
+
+ void KilledUnit(Unit* /*pVictim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (pInstance)
+ {
+ Creature* pSvala = Unit::GetCreature((*me), pInstance->GetData64(DATA_SVALA));
+ if (pSvala && pSvala->isAlive())
+ pKiller->Kill(pSvala);
+
+ pInstance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, DONE);
+ }
+ DoScriptText(SAY_DEATH, me);
+ }
+};
+
+CreatureAI* GetAI_boss_svala(Creature* pCreature)
+{
+ return new boss_svalaAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_ritual_channeler(Creature* pCreature)
+{
+ return new mob_ritual_channelerAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_svala_sorrowgrave(Creature* pCreature)
+{
+ return new boss_svala_sorrowgraveAI(pCreature);
+}
+
+void AddSC_boss_svala()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_svala";
+ newscript->GetAI = &GetAI_boss_svala;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_ritual_channeler";
+ newscript->GetAI = &GetAI_mob_ritual_channeler;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_svala_sorrowgrave";
+ newscript->GetAI = &GetAI_boss_svala_sorrowgrave;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp b/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp
new file mode 100644
index 00000000000..1a650f94101
--- /dev/null
+++ b/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/boss_ymiron.cpp
@@ -0,0 +1,367 @@
+/* Script Data Start
+SDName: Boss ymiron
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = 'boss_ymiron' where entry = '';
+*** SQL END ***/
+#include "ScriptedPch.h"
+#include "utgarde_pinnacle.h"
+
+enum Spells
+{
+ SPELL_BANE = 48294,
+ H_SPELL_BANE = 59301,
+ SPELL_DARK_SLASH = 48292,
+ SPELL_FETID_ROT = 48291,
+ H_SPELL_FETID_ROT = 59300,
+ SPELL_SCREAMS_OF_THE_DEAD = 51750,
+ SPELL_SPIRIT_BURST = 48529,
+ H_SPELL_SPIRIT_BURST = 59305,
+ SPELL_SPIRIT_STRIKE = 48423,
+ H_SPELL_SPIRIT_STRIKE = 59304,
+ SPELL_ANCESTORS_VENGEANCE = 16939,
+
+ SPELL_SUMMON_AVENGING_SPIRIT = 48592,
+ SPELL_SUMMON_SPIRIT_FOUNT = 48386,
+
+ SPELL_CHANNEL_SPIRIT_TO_YMIRON = 48316,
+ SPELL_CHANNEL_YMIRON_TO_SPIRIT = 48307,
+
+ SPELL_SPIRIT_FOUNT = 48380,
+ H_SPELL_SPIRIT_FOUNT = 59320
+};
+
+//not in db
+enum Yells
+{
+ SAY_AGGRO = -1575028,
+ SAY_SLAY_1 = -1575029,
+ SAY_SLAY_2 = -1575030,
+ SAY_SLAY_3 = -1575031,
+ SAY_SLAY_4 = -1575032,
+ SAY_DEATH = -1575033,
+ SAY_SUMMON_BJORN = -1575034,
+ SAY_SUMMON_HALDOR = -1575035,
+ SAY_SUMMON_RANULF = -1575036,
+ SAY_SUMMON_TORGYN = -1575037
+};
+
+enum Creatures
+{
+ CREATURE_BJORN = 27303,
+ CREATURE_BJORN_VISUAL = 27304,
+ CREATURE_HALDOR = 27307,
+ CREATURE_HALDOR_VISUAL = 27310,
+ CREATURE_RANULF = 27308,
+ CREATURE_RANULF_VISUAL = 27311,
+ CREATURE_TORGYN = 27309,
+ CREATURE_TORGYN_VISUAL = 27312,
+ CREATURE_SPIRIT_FOUNT = 27339,
+ CREATURE_AVENGING_SPIRIT = 27386
+};
+
+struct ActiveBoatStruct
+{
+ uint32 npc;
+ int32 say;
+ float MoveX,MoveY,MoveZ,SpawnX,SpawnY,SpawnZ,SpawnO;
+};
+
+static ActiveBoatStruct ActiveBot[4] =
+{
+ {CREATURE_BJORN_VISUAL, SAY_SUMMON_BJORN, 404.379, -335.335, 104.756, 413.594, -335.408, 107.995, 3.157},
+ {CREATURE_HALDOR_VISUAL, SAY_SUMMON_HALDOR, 380.813, -335.069, 104.756, 369.994, -334.771, 107.995, 6.232},
+ {CREATURE_RANULF_VISUAL, SAY_SUMMON_RANULF, 381.546, -314.362, 104.756, 370.841, -314.426, 107.995, 6.232},
+ {CREATURE_TORGYN_VISUAL, SAY_SUMMON_TORGYN, 404.310, -314.761, 104.756, 413.992, -314.703, 107.995, 3.157}
+};
+
+struct boss_ymironAI : public ScriptedAI
+{
+ boss_ymironAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ srand(time(NULL));
+ for (int i = 0; i < 4; ++i)
+ m_uiActiveOrder[i] = i;
+ for (int i = 0; i < 3; ++i)
+ {
+ int r = i + (rand()%(4-i));
+ int temp = m_uiActiveOrder[i];
+ m_uiActiveOrder[i] = m_uiActiveOrder[r];
+ m_uiActiveOrder[r] = temp;
+ }
+ }
+
+ bool m_bIsWalking;
+ bool m_bIsPause;
+ bool m_bIsActiveWithBJORN;
+ bool m_bIsActiveWithHALDOR;
+ bool m_bIsActiveWithRANULF;
+ bool m_bIsActiveWithTORGYN;
+
+ uint8 m_uiActiveOrder[4];
+ uint8 m_uiActivedNumber;
+
+ uint32 m_uiFetidRot_Timer;
+ uint32 m_uiBane_Timer;
+ uint32 m_uiDarkSlash_Timer;
+ uint32 m_uiAncestors_Vengeance_Timer;
+
+ uint32 m_uiAbility_BJORN_Timer;
+ uint32 m_uiAbility_HALDOR_Timer;
+ uint32 m_uiAbility_RANULF_Timer;
+ uint32 m_uiAbility_TORGYN_Timer;
+
+ uint32 m_uiPause_Timer;
+ uint32 m_uiHealthAmountModifier;
+ uint32 m_uiHealthAmountMultipler;
+
+ uint64 m_uiActivedCreatureGUID;
+ uint64 m_uiOrbGUID;
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ m_bIsPause = false;
+ m_bIsActiveWithBJORN = false;
+ m_bIsActiveWithHALDOR = false;
+ m_bIsActiveWithRANULF = false;
+ m_bIsActiveWithTORGYN = false;
+
+ m_uiFetidRot_Timer = urand(8000,13000);
+ m_uiBane_Timer = urand(18000,23000);
+ m_uiDarkSlash_Timer = urand(28000,33000);
+ m_uiAncestors_Vengeance_Timer = DUNGEON_MODE(60000,45000);
+ m_uiPause_Timer = 0;
+
+ m_uiAbility_BJORN_Timer = 0;
+ m_uiAbility_HALDOR_Timer = 0;
+ m_uiAbility_RANULF_Timer = 0;
+ m_uiAbility_TORGYN_Timer = 0;
+
+ m_uiActivedNumber = 0;
+ m_uiHealthAmountModifier = 1;
+ m_uiHealthAmountMultipler = DUNGEON_MODE(20,25);
+
+ DespawnBoatGhosts(m_uiActivedCreatureGUID);
+ DespawnBoatGhosts(m_uiOrbGUID);
+
+ if (pInstance)
+ pInstance->SetData(DATA_KING_YMIRON_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_KING_YMIRON_EVENT, IN_PROGRESS);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (m_bIsWalking)
+ {
+ if (m_uiPause_Timer <= diff)
+ {
+ DoScriptText(ActiveBot[m_uiActiveOrder[m_uiActivedNumber]].say, me);
+ DoCast(me, SPELL_CHANNEL_YMIRON_TO_SPIRIT); // should be on spirit
+ if (Creature* pTemp = me->SummonCreature(ActiveBot[m_uiActiveOrder[m_uiActivedNumber]].npc, ActiveBot[m_uiActiveOrder[m_uiActivedNumber]].SpawnX, ActiveBot[m_uiActiveOrder[m_uiActivedNumber]].SpawnY, ActiveBot[m_uiActiveOrder[m_uiActivedNumber]].SpawnZ, ActiveBot[m_uiActiveOrder[m_uiActivedNumber]].SpawnO, TEMPSUMMON_CORPSE_DESPAWN, 0))
+ {
+ m_uiActivedCreatureGUID = pTemp->GetGUID();
+ pTemp->CastSpell(me, SPELL_CHANNEL_SPIRIT_TO_YMIRON, true);
+ pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pTemp->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ switch(m_uiActiveOrder[m_uiActivedNumber])
+ {
+ case 0: m_bIsActiveWithBJORN = true; break;
+ case 1: m_bIsActiveWithHALDOR = true; break;
+ case 2: m_bIsActiveWithRANULF = true; break;
+ case 3: m_bIsActiveWithTORGYN = true; break;
+ }
+ }
+
+ m_bIsPause = true;
+ m_bIsWalking = false;
+ m_uiPause_Timer = 3000;
+ } else m_uiPause_Timer -= diff;
+ return;
+ }
+ else if (m_bIsPause)
+ {
+ if (m_uiPause_Timer <= diff)
+ {
+ m_uiAbility_BJORN_Timer = 5000;
+ m_uiAbility_HALDOR_Timer = 5000;
+ m_uiAbility_RANULF_Timer = 5000;
+ m_uiAbility_TORGYN_Timer = 5000;
+
+ m_bIsPause = false;
+ m_uiPause_Timer = 0;
+ } else m_uiPause_Timer -= diff;
+ return;
+ }
+
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (!m_bIsPause)
+ {
+ // Normal spells ------------------------------------------------------------------------
+ if (m_uiBane_Timer <= diff)
+ {
+ DoCast(me, SPELL_BANE);
+ m_uiBane_Timer = urand(20000,25000);
+ } else m_uiBane_Timer -= diff;
+
+ if (m_uiFetidRot_Timer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_FETID_ROT);
+ m_uiFetidRot_Timer = urand(10000,15000);
+ } else m_uiFetidRot_Timer -= diff;
+
+ if (m_uiDarkSlash_Timer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_DARK_SLASH);
+ m_uiDarkSlash_Timer = urand(30000,35000);
+ } else m_uiDarkSlash_Timer -= diff;
+
+ if (m_uiAncestors_Vengeance_Timer <= diff)
+ {
+ DoCast(me, SPELL_ANCESTORS_VENGEANCE);
+ m_uiAncestors_Vengeance_Timer = DUNGEON_MODE(urand(60000,65000),urand(45000,50000));
+ } else m_uiAncestors_Vengeance_Timer -= diff;
+
+ // Abilities ------------------------------------------------------------------------------
+ if (m_bIsActiveWithBJORN && m_uiAbility_BJORN_Timer <= diff)
+ {
+ //DoCast(me, SPELL_SUMMON_SPIRIT_FOUNT); // works fine, but using summon has better control
+ if (Creature* pTemp = me->SummonCreature(CREATURE_SPIRIT_FOUNT, 385+rand()%10, -330+rand()%10, 104.756, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 180000))
+ {
+ pTemp->SetSpeed(MOVE_RUN, 0.4f);
+ pTemp->CastSpell(pTemp, DUNGEON_MODE(SPELL_SPIRIT_FOUNT, H_SPELL_SPIRIT_FOUNT), true);
+ pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ pTemp->SetDisplayId(11686);
+ //pTemp->GetMotionMaster()->MoveChase(me->getVictim());
+ m_uiOrbGUID = pTemp->GetGUID();
+ }
+ m_bIsActiveWithBJORN = false; // only one orb
+ } else m_uiAbility_BJORN_Timer -= diff;
+
+ if (m_bIsActiveWithHALDOR && m_uiAbility_HALDOR_Timer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_SPIRIT_STRIKE);
+ m_uiAbility_HALDOR_Timer = 5000; // overtime
+ } else m_uiAbility_HALDOR_Timer -= diff;
+
+ if (m_bIsActiveWithRANULF && m_uiAbility_RANULF_Timer <= diff)
+ {
+ DoCast(me, SPELL_SPIRIT_BURST);
+ m_uiAbility_RANULF_Timer = 10000; // overtime
+ } else m_uiAbility_RANULF_Timer -= diff;
+
+ if (m_bIsActiveWithTORGYN && m_uiAbility_TORGYN_Timer <= diff)
+ {
+ float x,y,z;
+ x = me->GetPositionX()-5;
+ y = me->GetPositionY()-5;
+ z = me->GetPositionZ();
+ for (uint8 i = 0; i < 4; ++i)
+ {
+ //DoCast(me, SPELL_SUMMON_AVENGING_SPIRIT); // works fine, but using summon has better control
+ if (Creature* pTemp = me->SummonCreature(CREATURE_AVENGING_SPIRIT, x+rand()%10, y+rand()%10, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000))
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ pTemp->AddThreat(pTarget, 0.0f);
+ pTemp->AI()->AttackStart(pTarget);
+ }
+ }
+ }
+ m_uiAbility_TORGYN_Timer = 15000; // overtime
+ } else m_uiAbility_TORGYN_Timer -= diff;
+
+ // Health check -----------------------------------------------------------------------------
+ if ((me->GetHealth()*100 / me->GetMaxHealth()) < (100-(m_uiHealthAmountMultipler * m_uiHealthAmountModifier)))
+ {
+ uint8 m_uiOrder = m_uiHealthAmountModifier - 1;
+ ++m_uiHealthAmountModifier;
+
+ me->InterruptNonMeleeSpells(true);
+ DoCast(me, SPELL_SCREAMS_OF_THE_DEAD);
+ me->GetMotionMaster()->Clear();
+ me->StopMoving();
+ me->AttackStop();
+ me->GetMotionMaster()->MovePoint(0, ActiveBot[m_uiActiveOrder[m_uiOrder]].MoveX, ActiveBot[m_uiActiveOrder[m_uiOrder]].MoveY, ActiveBot[m_uiActiveOrder[m_uiOrder]].MoveZ);
+
+ DespawnBoatGhosts(m_uiActivedCreatureGUID);
+ DespawnBoatGhosts(m_uiOrbGUID);
+
+ m_bIsActiveWithBJORN = false;
+ m_bIsActiveWithHALDOR = false;
+ m_bIsActiveWithRANULF = false;
+ m_bIsActiveWithTORGYN = false;
+
+ m_uiBane_Timer += 8000;
+ m_uiFetidRot_Timer += 8000;
+ m_uiDarkSlash_Timer += 8000;
+ m_uiAncestors_Vengeance_Timer += 8000;
+
+ m_uiActivedNumber = m_uiOrder;
+ m_bIsWalking = true;
+ m_uiPause_Timer = 2000;
+ return;
+ }
+ DoMeleeAttackIfReady();
+ }
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ DespawnBoatGhosts(m_uiActivedCreatureGUID);
+ DespawnBoatGhosts(m_uiOrbGUID);
+
+ if (pInstance)
+ pInstance->SetData(DATA_KING_YMIRON_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit * /*victim*/)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3,SAY_SLAY_4), me);
+ }
+
+ void DespawnBoatGhosts(uint64& m_uiCreatureGUID)
+ {
+ if (m_uiCreatureGUID)
+ if (Creature* pTemp = Unit::GetCreature(*me, m_uiCreatureGUID))
+ pTemp->DisappearAndDie();
+
+ m_uiCreatureGUID = 0;
+ }
+};
+
+CreatureAI* GetAI_boss_ymiron(Creature* pCreature)
+{
+ return new boss_ymironAI(pCreature);
+}
+
+void AddSC_boss_ymiron()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_ymiron";
+ newscript->GetAI = &GetAI_boss_ymiron;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp b/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp
new file mode 100644
index 00000000000..cf042867707
--- /dev/null
+++ b/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/instance_pinnacle.cpp
@@ -0,0 +1,241 @@
+#include "ScriptedPch.h"
+#include "utgarde_pinnacle.h"
+
+#define MAX_ENCOUNTER 4
+
+/* Utgarde Pinnacle encounters:
+0 - Svala Sorrowgrave
+1 - Gortok Palehoof
+2 - Skadi the Ruthless
+3 - King Ymiron
+*/
+
+enum GameObjects
+{
+ ENTRY_SKADI_THE_RUTHLESS_DOOR = 192173,
+ ENTRY_KING_YMIRON_DOOR = 192174,
+ ENTRY_GORK_PALEHOOF_SPHERE = 188593
+};
+
+struct instance_pinnacle : public ScriptedInstance
+{
+ instance_pinnacle(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+
+ uint64 uiSvalaSorrowgrave;
+ uint64 uiGortokPalehoof;
+ uint64 uiSkadiTheRuthless;
+ uint64 uiKingYmiron;
+
+ uint64 uiSkadiTheRuthlessDoor;
+ uint64 uiKingYmironDoor;
+ uint64 uiGortokPalehoofSphere;
+
+ uint64 uiFrenziedWorgen;
+ uint64 uiRavenousFurbolg;
+ uint64 uiFerociousRhino;
+ uint64 uiMassiveJormungar;
+ uint64 uiPalehoofOrb;
+
+ uint64 uiSvala;
+ uint64 uiSacrificedPlayer;
+
+ uint32 m_auiEncounter[MAX_ENCOUNTER];
+
+ std::string str_data;
+
+ void Initialize()
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ m_auiEncounter[i] = NOT_STARTED;
+
+ uiSvalaSorrowgrave = 0;
+ uiGortokPalehoof = 0;
+ uiSkadiTheRuthless = 0;
+ uiKingYmiron = 0;
+
+ uiSkadiTheRuthlessDoor = 0;
+ uiKingYmironDoor = 0;
+ uiGortokPalehoofSphere = 0;
+
+ uiFrenziedWorgen = 0;
+ uiRavenousFurbolg = 0;
+ uiFerociousRhino = 0;
+ uiMassiveJormungar = 0;
+ uiPalehoofOrb = 0;
+
+ uiSvala = 0;
+ uiSacrificedPlayer = 0;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool /*add*/)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case BOSS_SVALA_SORROWGRAVE: uiSvalaSorrowgrave = pCreature->GetGUID(); break;
+ case BOSS_GORTOK_PALEHOOF: uiGortokPalehoof = pCreature->GetGUID(); break;
+ case BOSS_SKADI_RUTHLESS: uiSkadiTheRuthless = pCreature->GetGUID(); break;
+ case BOSS_KING_YMIRON: uiKingYmiron = pCreature->GetGUID(); break;
+ case MOB_FRENZIED_WORGEN: uiFrenziedWorgen = pCreature->GetGUID(); break;
+ case MOB_RAVENOUS_FURBOLG: uiRavenousFurbolg = pCreature->GetGUID(); break;
+ case MOB_MASSIVE_JORMUNGAR: uiMassiveJormungar = pCreature->GetGUID(); break;
+ case MOB_FEROCIOUS_RHINO: uiFerociousRhino = pCreature->GetGUID(); break;
+ case MOB_SVALA: uiSvala = pCreature->GetGUID(); break;
+ case MOB_PALEHOOF_ORB: uiPalehoofOrb = pCreature->GetGUID(); break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
+ {
+ switch(pGo->GetEntry())
+ {
+ case ENTRY_SKADI_THE_RUTHLESS_DOOR:
+ uiSkadiTheRuthlessDoor = pGo->GetGUID();
+ if (m_auiEncounter[2] == DONE) HandleGameObject(NULL,true,pGo);
+ break;
+ case ENTRY_KING_YMIRON_DOOR:
+ uiKingYmironDoor = pGo->GetGUID();
+ if (m_auiEncounter[3] == DONE) HandleGameObject(NULL,true,pGo);
+ break;
+ case ENTRY_GORK_PALEHOOF_SPHERE:
+ uiGortokPalehoofSphere = pGo->GetGUID();
+ if (m_auiEncounter[1] == DONE)
+ {
+ HandleGameObject(NULL,true,pGo);
+ pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1);
+ }
+ break;
+ }
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_SVALA_SORROWGRAVE_EVENT:
+ m_auiEncounter[0] = data;
+ break;
+ case DATA_GORTOK_PALEHOOF_EVENT:
+ m_auiEncounter[1] = data;
+ break;
+ case DATA_SKADI_THE_RUTHLESS_EVENT:
+ if (data == DONE)
+ HandleGameObject(uiSkadiTheRuthlessDoor,true);
+ m_auiEncounter[2] = data;
+ break;
+ case DATA_KING_YMIRON_EVENT:
+ if (data == DONE)
+ HandleGameObject(uiKingYmironDoor,true);
+ m_auiEncounter[3] = data;
+ break;
+ }
+
+ if (data == DONE)
+ SaveToDB();
+ }
+
+ void SetData64(uint32 type, uint64 data)
+ {
+ if (type == DATA_SACRIFICED_PLAYER)
+ uiSacrificedPlayer = data;
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_SVALA_SORROWGRAVE_EVENT: return m_auiEncounter[0];
+ case DATA_GORTOK_PALEHOOF_EVENT: return m_auiEncounter[1];
+ case DATA_SKADI_THE_RUTHLESS_EVENT: return m_auiEncounter[2];
+ case DATA_KING_YMIRON_EVENT: return m_auiEncounter[3];
+ }
+ return 0;
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_SVALA_SORROWGRAVE: return uiSvalaSorrowgrave;
+ case DATA_GORTOK_PALEHOOF: return uiGortokPalehoof;
+ case DATA_SKADI_THE_RUTHLESS: return uiSkadiTheRuthless;
+ case DATA_KING_YMIRON: return uiKingYmiron;
+ case DATA_MOB_FRENZIED_WORGEN: return uiFrenziedWorgen;
+ case DATA_MOB_RAVENOUS_FURBOLG: return uiRavenousFurbolg;
+ case DATA_MOB_MASSIVE_JORMUNGAR: return uiMassiveJormungar;
+ case DATA_MOB_FEROCIOUS_RHINO: return uiFerociousRhino;
+ case DATA_MOB_ORB: return uiPalehoofOrb;
+ case DATA_SVALA: return uiSvala;
+ case DATA_GORTOK_PALEHOOF_SPHERE: return uiGortokPalehoofSphere;
+ }
+
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "U P " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
+ << m_auiEncounter[2] << " " << m_auiEncounter[3];
+
+ str_data = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return str_data;
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0, data1, data2, data3;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;
+
+ if (dataHead1 == 'U' && dataHead2 == 'P')
+ {
+ m_auiEncounter[0] = data0;
+ m_auiEncounter[1] = data1;
+ m_auiEncounter[2] = data2;
+ m_auiEncounter[3] = data3;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_utgarde_pinnacle(Map* pMap)
+{
+ return new instance_pinnacle(pMap);
+}
+
+void AddSC_instance_utgarde_pinnacle()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_utgarde_pinnacle";
+ newscript->GetInstanceData = &GetInstanceData_instance_utgarde_pinnacle;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h b/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h
new file mode 100644
index 00000000000..a51d7aceda0
--- /dev/null
+++ b/src/server/scripts/northrend/utgarde_keep/utgarde_pinnacle/utgarde_pinnacle.h
@@ -0,0 +1,42 @@
+#ifndef DEF_PINNACLE_H
+#define DEF_PINNACLE_H
+
+enum Data
+{
+ DATA_SVALA_SORROWGRAVE_EVENT,
+ DATA_GORTOK_PALEHOOF_EVENT,
+ DATA_SKADI_THE_RUTHLESS_EVENT,
+ DATA_KING_YMIRON_EVENT
+};
+enum Data64
+{
+ DATA_SVALA,
+ DATA_SVALA_SORROWGRAVE,
+ DATA_GORTOK_PALEHOOF,
+ DATA_SKADI_THE_RUTHLESS,
+ DATA_MOB_GRAUF,
+ DATA_KING_YMIRON,
+ DATA_MOB_FRENZIED_WORGEN,
+ DATA_MOB_RAVENOUS_FURBOLG,
+ DATA_MOB_MASSIVE_JORMUNGAR,
+ DATA_MOB_FEROCIOUS_RHINO,
+ DATA_MOB_ORB,
+ DATA_GORTOK_PALEHOOF_SPHERE,
+ DATA_SACRIFICED_PLAYER
+};
+
+enum eCreatures
+{
+ BOSS_SVALA_SORROWGRAVE = 26668,
+ BOSS_GORTOK_PALEHOOF = 26687,
+ BOSS_SKADI_RUTHLESS = 26693,
+ BOSS_KING_YMIRON = 26861,
+ MOB_FRENZIED_WORGEN = 26683,
+ MOB_RAVENOUS_FURBOLG = 26684,
+ MOB_MASSIVE_JORMUNGAR = 26685,
+ MOB_FEROCIOUS_RHINO = 26686,
+ MOB_SVALA = 29281,
+ MOB_PALEHOOF_ORB = 26688,
+};
+
+#endif
diff --git a/src/server/scripts/northrend/vault_of_archavon/boss_archavon.cpp b/src/server/scripts/northrend/vault_of_archavon/boss_archavon.cpp
new file mode 100644
index 00000000000..11d432e94c6
--- /dev/null
+++ b/src/server/scripts/northrend/vault_of_archavon/boss_archavon.cpp
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2009-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*** SQL START ***
+UPDATE `creature_template` SET `ScriptName`='boss_archavon' WHERE `entry`='31125';
+UPDATE `creature_template` SET `ScriptName`='mob_archavon_warder' WHERE `entry`='32353';
+*** SQL END ***/
+
+#include "ScriptedPch.h"
+#include "vault_of_archavon.h"
+
+#define EMOTE_BERSERK -1590002
+
+//Spells Archavon
+#define SPELL_ROCK_SHARDS 58678
+#define SPELL_CRUSHING_LEAP RAID_MODE(58960,60894)//Instant (10-80yr range) -- Leaps at an enemy, inflicting 8000 Physical damage, knocking all nearby enemies away, and creating a cloud of choking debris.
+#define SPELL_STOMP RAID_MODE(58663,60880)
+#define SPELL_IMPALE RAID_MODE(58666,60882) //Lifts an enemy off the ground with a spiked fist, inflicting 47125 to 52875 Physical damage and 9425 to 10575 additional damage each second for 8 sec.
+#define SPELL_BERSERK 47008
+//Spells Archavon Warders
+#define SPELL_ROCK_SHOWER RAID_MODE(60919,60923)
+#define SPELL_SHIELD_CRUSH RAID_MODE(60897,60899)
+#define SPELL_WHIRL RAID_MODE(60902,60916)
+
+//4 Warders spawned
+#define ARCHAVON_WARDER 32353 //npc 32353
+
+//Yell
+#define SAY_LEAP "Archavon the Stone Watcher lunges for $N!" //$N should be the target
+
+#define EVENT_ROCK_SHARDS 1 //15s cd
+#define EVENT_CHOKING_CLOUD 2 //30s cd
+#define EVENT_STOMP 3 //45s cd
+#define EVENT_IMPALE 4
+#define EVENT_BERSERK 5 //300s cd
+
+//mob
+#define EVENT_ROCK_SHOWER 5 //set = 20s cd,unkown cd
+#define EVENT_SHIELD_CRUSH 6 //set = 30s cd
+#define EVENT_WHIRL 8 //set= 10s cd
+
+struct boss_archavonAI : public ScriptedAI
+{
+ boss_archavonAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+
+ if (pInstance)
+ pInstance->SetData(DATA_ARCHAVON_EVENT, NOT_STARTED);
+ }
+
+ void KilledUnit(Unit* /*Victim*/) {}
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_ARCHAVON_EVENT, DONE);
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ DoZoneInCombat();
+ events.ScheduleEvent(EVENT_ROCK_SHARDS, 15000);
+ events.ScheduleEvent(EVENT_CHOKING_CLOUD, 30000);
+ events.ScheduleEvent(EVENT_STOMP, 45000);
+ events.ScheduleEvent(EVENT_BERSERK, 300000);
+
+ if (pInstance)
+ pInstance->SetData(DATA_ARCHAVON_EVENT, IN_PROGRESS);
+ }
+
+ // Below UpdateAI may need review/debug.
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_ROCK_SHARDS:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_ROCK_SHARDS);
+ events.ScheduleEvent(EVENT_ROCK_SHARDS, 15000);
+ return;
+ case EVENT_CHOKING_CLOUD:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_CRUSHING_LEAP, true); //10y~80y, ignore range
+ events.ScheduleEvent(EVENT_CHOKING_CLOUD, 30000);
+ return;
+ case EVENT_STOMP:
+ DoCast(me->getVictim(), SPELL_STOMP);
+ events.ScheduleEvent(EVENT_IMPALE, 3000);
+ events.ScheduleEvent(EVENT_STOMP, 45000);
+ return;
+ case EVENT_IMPALE:
+ DoCast(me->getVictim(), SPELL_IMPALE);
+ return;
+ case EVENT_BERSERK:
+ DoCast(me, SPELL_BERSERK);
+ DoScriptText(EMOTE_BERSERK, me);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+/*######
+## Mob Archavon Warder
+######*/
+struct mob_archavon_warderAI : public ScriptedAI //npc 32353
+{
+ mob_archavon_warderAI(Creature *c) : ScriptedAI(c) {}
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ DoZoneInCombat();
+ events.ScheduleEvent(EVENT_ROCK_SHOWER, 2000);
+ events.ScheduleEvent(EVENT_SHIELD_CRUSH, 20000);
+ events.ScheduleEvent(EVENT_WHIRL, 7500);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_ROCK_SHOWER:
+ {
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_ROCK_SHOWER);
+ events.ScheduleEvent(EVENT_ROCK_SHARDS, 6000);
+ return;
+ }
+ case EVENT_SHIELD_CRUSH:
+ DoCast(me->getVictim(), SPELL_SHIELD_CRUSH);
+ events.ScheduleEvent(EVENT_SHIELD_CRUSH, 20000);
+ return;
+ case EVENT_WHIRL:
+ DoCast(me->getVictim(), SPELL_WHIRL);
+ events.ScheduleEvent(EVENT_WHIRL, 8000);
+ return;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_archavon_warder(Creature* pCreature)
+{
+ return new mob_archavon_warderAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_archavon(Creature* pCreature)
+{
+ return new boss_archavonAI (pCreature);
+}
+
+void AddSC_boss_archavon()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_archavon";
+ newscript->GetAI = &GetAI_boss_archavon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_archavon_warder";
+ newscript->GetAI = &GetAI_mob_archavon_warder;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/vault_of_archavon/boss_emalon.cpp b/src/server/scripts/northrend/vault_of_archavon/boss_emalon.cpp
new file mode 100644
index 00000000000..92a0331708e
--- /dev/null
+++ b/src/server/scripts/northrend/vault_of_archavon/boss_emalon.cpp
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2009-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "vault_of_archavon.h"
+
+//Emalon spells
+#define SPELL_CHAIN_LIGHTNING RAID_MODE(64213, 64215)
+#define SPELL_LIGHTNING_NOVA RAID_MODE(64216, 65279)
+#define SPELL_OVERCHARGE 64218 //Casted every 45 sec on a random Tempest Minion
+#define SPELL_BERSERK 26662
+
+//Tempest Minion spells
+#define SPELL_SHOCK 64363
+#define SPELL_OVERCHARGED 64217
+#define SPELL_OVERCHARGED_BLAST 64219 //Casted when Overcharged reaches 10 stacks. Mob dies after that
+
+//Emotes
+#define EMOTE_OVERCHARGE -1590000
+#define EMOTE_MINION_RESPAWN -1590001
+#define EMOTE_BERSERK -1590002
+
+//Events
+#define EVENT_CHAIN_LIGHTNING 1
+#define EVENT_LIGHTNING_NOVA 2
+#define EVENT_OVERCHARGE 3
+#define EVENT_BERSERK 4
+#define EVENT_SHOCK 5
+
+//Creatures
+#define MOB_TEMPEST_MINION 33998
+
+#define MAX_TEMPEST_MINIONS 4
+
+struct Position TempestMinions[MAX_TEMPEST_MINIONS] =
+{
+ {-203.980103, -281.287720, 91.650223, 1.598807},
+ {-233.489410, -281.139282, 91.652412, 1.598807},
+ {-233.267578, -297.104645, 91.681915, 1.598807},
+ {-203.842529, -297.097015, 91.745163, 1.598807}
+};
+
+/*######
+## Emalon the Storm Watcher
+######*/
+struct boss_emalonAI : public BossAI
+{
+ boss_emalonAI(Creature *c) : BossAI(c, DATA_EMALON_EVENT)
+ {
+ }
+
+ void Reset()
+ {
+ _Reset();
+
+ for (uint8 i = 0; i < MAX_TEMPEST_MINIONS; ++i)
+ me->SummonCreature(MOB_TEMPEST_MINION, TempestMinions[i], TEMPSUMMON_CORPSE_DESPAWN, 0);
+ }
+
+ void JustSummoned(Creature *summoned)
+ {
+ BossAI::JustSummoned(summoned);
+
+ if (me->getVictim() && summoned->AI())
+ summoned->AI()->AttackStart(me->getVictim());
+ }
+
+ void EnterCombat(Unit * who)
+ {
+ if (!summons.empty())
+ {
+ for (std::list<uint64>::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
+ {
+ Creature *minion = Unit::GetCreature(*me, *itr);
+ if (minion && minion->isAlive() && !minion->getVictim() && minion->AI())
+ minion->AI()->AttackStart(who);
+ }
+ }
+
+ events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 5000);
+ events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 40000);
+ events.ScheduleEvent(EVENT_BERSERK, 360000);
+ events.ScheduleEvent(EVENT_OVERCHARGE, 45000);
+
+ _EnterCombat();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_CHAIN_LIGHTNING:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_CHAIN_LIGHTNING);
+ events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 25000);
+ break;
+ case EVENT_LIGHTNING_NOVA:
+ DoCastAOE(SPELL_LIGHTNING_NOVA, false);
+ events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 40000);
+ break;
+ case EVENT_OVERCHARGE:
+ if (!summons.empty())
+ {
+ std::list<uint64>::const_iterator itr = summons.begin();
+ std::advance(itr, urand(0, summons.size()-1));
+ Creature *minion = Unit::GetCreature(*me, *itr);
+ if (minion && minion->isAlive())
+ {
+ minion->CastSpell(me, SPELL_OVERCHARGED, true);
+ minion->SetHealth(minion->GetMaxHealth());
+ DoScriptText(EMOTE_OVERCHARGE, me);
+ events.ScheduleEvent(EVENT_OVERCHARGE, 45000);
+ }
+ }
+ break;
+ case EVENT_BERSERK:
+ DoCast(me, SPELL_BERSERK);
+ DoScriptText(EMOTE_BERSERK, me);
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+/*######
+## Tempest Minion
+######*/
+struct mob_tempest_minionAI : public ScriptedAI
+{
+ mob_tempest_minionAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ EventMap events;
+
+ uint32 uiOverchargedTimer;
+
+ void Reset()
+ {
+ events.Reset();
+
+ uiOverchargedTimer = 0;
+ }
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ if (Creature *pEmalon = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_EMALON) : 0))
+ {
+ if (pEmalon->isAlive())
+ {
+ pEmalon->SummonCreature(MOB_TEMPEST_MINION, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+ DoScriptText(EMOTE_MINION_RESPAWN, me);
+ }
+ }
+ }
+
+ void EnterCombat(Unit * who)
+ {
+ DoZoneInCombat();
+ events.ScheduleEvent(EVENT_SHOCK, 20000);
+
+ if (Creature *pEmalon = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_EMALON) : 0))
+ {
+ if (!pEmalon->getVictim() && pEmalon->AI())
+ pEmalon->AI()->AttackStart(who);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ if (Aura *overchargedAura = me->GetAura(SPELL_OVERCHARGED))
+ {
+ if (overchargedAura->GetStackAmount() < 10)
+ {
+ if (uiOverchargedTimer <= diff)
+ {
+ DoCast(me, SPELL_OVERCHARGED);
+ uiOverchargedTimer = 2000;
+ } else uiOverchargedTimer -=diff;
+ }
+ else
+ {
+ if (overchargedAura->GetStackAmount() == 10)
+ {
+ DoCast(me, SPELL_OVERCHARGED_BLAST);
+ me->ForcedDespawn();
+ DoScriptText(EMOTE_MINION_RESPAWN, me);
+ }
+ }
+ }
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SHOCK:
+ DoCast(me->getVictim(), SPELL_SHOCK);
+ events.ScheduleEvent(EVENT_SHOCK, 20000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_tempest_minion(Creature *_Creature)
+{
+ return new mob_tempest_minionAI (_Creature);
+}
+
+CreatureAI* GetAI_boss_emalon(Creature *_Creature)
+{
+ return new boss_emalonAI (_Creature);
+}
+
+void AddSC_boss_emalon()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_emalon";
+ newscript->GetAI = &GetAI_boss_emalon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_tempest_minion";
+ newscript->GetAI = &GetAI_mob_tempest_minion;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/vault_of_archavon/boss_koralon.cpp b/src/server/scripts/northrend/vault_of_archavon/boss_koralon.cpp
new file mode 100644
index 00000000000..61843647136
--- /dev/null
+++ b/src/server/scripts/northrend/vault_of_archavon/boss_koralon.cpp
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2009-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*** SQL START ***
+UPDATE `creature_template` SET `ScriptName`='boss_koralon' WHERE `entry`='35013';
+UPDATE `creature_template` SET `ScriptName`='mob_flame_warder' WHERE `entry`='35143';
+*** SQL END ***/
+
+#include "ScriptedPch.h"
+#include "vault_of_archavon.h"
+
+enum Events
+{
+ EVENT_NONE,
+
+ // Koralon
+ EVENT_BURNING_BREATH,
+ EVENT_BURNING_FURY,
+ EVENT_FLAME_CINDER_A,
+ EVENT_METEOR_FISTS_A,
+ EVENT_METEOR_FISTS_B,
+
+ // Flame Warder
+ EVENT_FW_LAVA_BIRST,
+ EVENT_FW_METEOR_FISTS_A,
+ EVENT_FW_METEOR_FISTS_B,
+};
+
+enum Spells
+{
+ // Spells Koralon
+ SPELL_BURNING_BREATH = 66665,
+ SPELL_BURNING_BREATH_H = 67328,
+ SPELL_BURNING_FURY = 66721,
+ SPELL_FLAME_CINDER_A = 66684,
+ SPELL_FLAME_CINDER_A_H = 67332,
+ SPELL_FLAME_CINDER_B = 66681, // don't know the real relation to SPELL_FLAME_CINDER_A atm.
+ SPELL_METEOR_FISTS_A = 66725,
+ SPELL_METEOR_FISTS_A_H = 66765,
+ SPELL_METEOR_FISTS_B = 67333,
+ SPELL_METEOR_FISTS_B_H = 68161,
+
+ // Spells Flame Warder
+ SPELL_FW_LAVA_BIRST = 66813,
+ SPELL_FW_LAVA_BIRST_H = 67330,
+ SPELL_FW_METEOR_FISTS_A = 66808,
+ SPELL_FW_METEOR_FISTS_A_H = 66809,
+ SPELL_FW_METEOR_FISTS_B = 67331,
+ SPELL_FW_METEOR_FISTS_B_H = 68160,
+};
+
+struct boss_koralonAI : public ScriptedAI
+{
+ boss_koralonAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance *pInstance;
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+
+ if (pInstance)
+ pInstance->SetData(DATA_KORALON_EVENT, NOT_STARTED);
+ }
+
+ void KilledUnit(Unit* /*Victim*/) {}
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_KORALON_EVENT, DONE);
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ DoZoneInCombat();
+
+ DoCast(me, SPELL_BURNING_FURY);
+
+ events.ScheduleEvent(EVENT_BURNING_FURY, 20000); // TODO check timer
+ events.ScheduleEvent(EVENT_BURNING_BREATH, 15000); // 1st after 15sec, then every 45sec
+ events.ScheduleEvent(EVENT_METEOR_FISTS_A, 75000); // 1st after 75sec, then every 45sec
+ events.ScheduleEvent(EVENT_FLAME_CINDER_A, 30000); // TODO check timer
+
+ if (pInstance)
+ pInstance->SetData(DATA_KORALON_EVENT, IN_PROGRESS);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_BURNING_FURY:
+ DoCast(me, SPELL_BURNING_FURY);
+ events.ScheduleEvent(EVENT_BURNING_FURY, 20000);
+ return;
+ case EVENT_BURNING_BREATH:
+ DoCast(me, RAID_MODE(SPELL_BURNING_BREATH,SPELL_BURNING_BREATH_H));
+ events.ScheduleEvent(EVENT_BURNING_BREATH, 45000);
+ return;
+ case EVENT_METEOR_FISTS_A:
+ DoCast(me, RAID_MODE(SPELL_METEOR_FISTS_A,SPELL_METEOR_FISTS_A_H));
+ events.ScheduleEvent(EVENT_METEOR_FISTS_B, 1500);
+ return;
+ case EVENT_METEOR_FISTS_B:
+ DoCast(me, RAID_MODE(SPELL_METEOR_FISTS_B,SPELL_METEOR_FISTS_B_H));
+ events.ScheduleEvent(EVENT_METEOR_FISTS_A, 45000);
+ return;
+ case EVENT_FLAME_CINDER_A:
+ DoCast(me, RAID_MODE(SPELL_FLAME_CINDER_A,SPELL_FLAME_CINDER_A_H));
+ events.ScheduleEvent(EVENT_FLAME_CINDER_A, 30000);
+ return;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+};
+
+/*######
+## Mob Flame Warder
+######*/
+struct mob_flame_warderAI : public ScriptedAI
+{
+ mob_flame_warderAI(Creature *c) : ScriptedAI(c) {}
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ DoZoneInCombat();
+
+ events.ScheduleEvent(EVENT_FW_LAVA_BIRST, 5000);
+ events.ScheduleEvent(EVENT_FW_METEOR_FISTS_A, 10000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_FW_LAVA_BIRST:
+ DoCast(me->getVictim(), RAID_MODE(SPELL_FW_LAVA_BIRST,SPELL_FW_LAVA_BIRST_H));
+ events.ScheduleEvent(EVENT_FW_LAVA_BIRST, 15000);
+ return;
+ case EVENT_FW_METEOR_FISTS_A:
+ DoCast(me, RAID_MODE(SPELL_FW_METEOR_FISTS_A,SPELL_FW_METEOR_FISTS_A_H));
+ events.ScheduleEvent(EVENT_FW_METEOR_FISTS_B, 1500);
+ return;
+ case EVENT_FW_METEOR_FISTS_B:
+ DoCast(me, RAID_MODE(SPELL_FW_METEOR_FISTS_B,SPELL_FW_METEOR_FISTS_B_H));
+ events.ScheduleEvent(EVENT_FW_METEOR_FISTS_A, 20000);
+ return;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_koralon(Creature* pCreature)
+{
+ return new boss_koralonAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_flame_warder(Creature* pCreature)
+{
+ return new mob_flame_warderAI (pCreature);
+}
+
+void AddSC_boss_koralon()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_koralon";
+ newscript->GetAI = &GetAI_boss_koralon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_flame_warder";
+ newscript->GetAI = &GetAI_mob_flame_warder;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/vault_of_archavon/boss_toravon.cpp b/src/server/scripts/northrend/vault_of_archavon/boss_toravon.cpp
new file mode 100644
index 00000000000..2e16f9211d2
--- /dev/null
+++ b/src/server/scripts/northrend/vault_of_archavon/boss_toravon.cpp
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2009-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*** SQL START ***
+UPDATE `creature_template` SET `ScriptName`='boss_toravon' WHERE `entry`='38433';
+UPDATE `creature_template` SET `ScriptName`='mob_frost_warder' WHERE `entry`='38482';
+UPDATE `creature_template` SET `ScriptName`='mob_frozen_orb_stalker' WHERE `entry`='38461';
+UPDATE `creature_template` SET `ScriptName`='mob_frozen_orb' WHERE `entry`='38456';
+*** SQL END ***/
+
+#include "ScriptedPch.h"
+#include "vault_of_archavon.h"
+
+// Spells Toravon
+#define SPELL_FREEZING_GROUND RAID_MODE(72090,72104) // don't know cd... using 20 secs.
+#define SPELL_FROZEN_ORB RAID_MODE(72091,72095)
+#define SPELL_WHITEOUT RAID_MODE(72034,72096) // Every 38 sec. cast. (after SPELL_FROZEN_ORB)
+#define SPELL_FROZEN_MALLET 71993
+
+// Spells Frost Warder
+#define SPELL_FROST_BLAST RAID_MODE(72123,72124) // don't know cd... using 20 secs.
+#define SPELL_FROZEN_MALLET 72122
+
+// Spell Frozen Orb
+#define SPELL_FROZEN_ORB_DMG 72081 // priodic dmg aura
+#define SPELL_FROZEN_ORB_AURA 72067 // make visible
+
+// Spell Frozen Orb Stalker
+#define SPELL_FROZEN_ORB_SUMMON 72093 // summon orb
+
+// Events boss
+#define EVENT_FREEZING_GROUND 1
+#define EVENT_FROZEN_ORB 2
+#define EVENT_WHITEOUT 3
+
+// Events mob
+#define EVENT_FROST_BLAST 4
+
+// Mob Frozen Orb
+#define MOB_FROZEN_ORB 38456 // 1 in 10 mode and 3 in 25 mode
+
+struct boss_toravonAI : public ScriptedAI
+{
+ boss_toravonAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance *pInstance;
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+
+ if (pInstance)
+ pInstance->SetData(DATA_TORAVON_EVENT, NOT_STARTED);
+ }
+
+ void KilledUnit(Unit* /*Victim*/) {}
+
+ void JustDied(Unit* /*Killer*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_TORAVON_EVENT, DONE);
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ DoZoneInCombat();
+
+ DoCast(me, SPELL_FROZEN_MALLET);
+
+ events.ScheduleEvent(EVENT_FROZEN_ORB, 11000);
+ events.ScheduleEvent(EVENT_WHITEOUT, 13000);
+ events.ScheduleEvent(EVENT_FREEZING_GROUND, 15000);
+
+ if (pInstance)
+ pInstance->SetData(DATA_TORAVON_EVENT, IN_PROGRESS);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_FROZEN_ORB:
+ DoCast(me, SPELL_FROZEN_ORB);
+ events.ScheduleEvent(EVENT_FROZEN_ORB, 38000);
+ return;
+ case EVENT_WHITEOUT:
+ DoCast(me, SPELL_WHITEOUT);
+ events.ScheduleEvent(EVENT_WHITEOUT, 38000);
+ return;
+ case EVENT_FREEZING_GROUND:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_FREEZING_GROUND);
+ events.ScheduleEvent(EVENT_FREEZING_GROUND, 20000);
+ return;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+};
+
+/*######
+## Mob Frost Warder
+######*/
+struct mob_frost_warderAI : public ScriptedAI
+{
+ mob_frost_warderAI(Creature *c) : ScriptedAI(c) {}
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ DoZoneInCombat();
+
+ DoCast(me, SPELL_FROZEN_MALLET);
+
+ events.ScheduleEvent(EVENT_FROST_BLAST, 5000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_FROST_BLAST:
+ DoCast(me->getVictim(), SPELL_FROST_BLAST);
+ events.ScheduleEvent(EVENT_FROST_BLAST, 20000);
+ return;
+ }
+ }
+ DoMeleeAttackIfReady();
+ }
+};
+
+
+/*######
+## Mob Frozen Orb
+######*/
+struct mob_frozen_orbAI : public ScriptedAI
+{
+ mob_frozen_orbAI(Creature *c) : ScriptedAI(c) {}
+
+ bool done;
+ uint32 killtimer;
+
+ void Reset()
+ {
+ done = false;
+ killtimer = 60000; // if after this time there is no victim -> destroy!
+ }
+
+ void EnterCombat(Unit * /*who*/)
+ {
+ DoZoneInCombat();
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!done)
+ {
+ DoCast(me, SPELL_FROZEN_ORB_AURA, true);
+ DoCast(me, SPELL_FROZEN_ORB_DMG, true);
+ done = true;
+ }
+
+ if (killtimer <= diff)
+ {
+ if (!UpdateVictim())
+ me->ForcedDespawn();
+ killtimer = 10000;
+ }
+ else
+ killtimer -= diff;
+ }
+};
+
+/*######
+## Mob Frozen Orb Stalker
+######*/
+struct mob_frozen_orb_stalkerAI : public Scripted_NoMovementAI
+{
+ mob_frozen_orb_stalkerAI(Creature* c) : Scripted_NoMovementAI(c)
+ {
+ c->SetVisibility(VISIBILITY_OFF);
+ c->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_DISABLE_MOVE);
+ c->SetReactState(REACT_PASSIVE);
+
+ pInstance = c->GetInstanceData();
+ spawned = false;
+ }
+
+ ScriptedInstance *pInstance;
+ bool spawned;
+
+ void UpdateAI(const uint32 /*diff*/)
+ {
+ if (spawned)
+ return;
+
+ spawned = true;
+ if (!pInstance)
+ return;
+
+ Unit* pToravon = me->GetCreature(*me, pInstance->GetData64(DATA_TORAVON));
+ if (!pToravon)
+ return;
+
+ uint8 num_orbs = RAID_MODE(1, 3);
+ for (uint8 i=0; i<num_orbs; ++i)
+ {
+ Position pos;
+ me->GetNearPoint(pToravon, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, 10.0f, 0.0f);
+ me->SetPosition(pos, true);
+ DoCast(me, SPELL_FROZEN_ORB_SUMMON);
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_toravon(Creature* pCreature)
+{
+ return new boss_toravonAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_frost_warder(Creature* pCreature)
+{
+ return new mob_frost_warderAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_frozen_orb(Creature* pCreature)
+{
+ return new mob_frozen_orbAI (pCreature);
+}
+
+CreatureAI* GetAI_mob_frozen_orb_stalker(Creature* pCreature)
+{
+ return new mob_frozen_orb_stalkerAI (pCreature);
+}
+
+void AddSC_boss_toravon()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_toravon";
+ newscript->GetAI = &GetAI_boss_toravon;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_frost_warder";
+ newscript->GetAI = &GetAI_mob_frost_warder;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_frozen_orb";
+ newscript->GetAI = &GetAI_mob_frozen_orb;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_frozen_orb_stalker";
+ newscript->GetAI = &GetAI_mob_frozen_orb_stalker;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp b/src/server/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp
new file mode 100644
index 00000000000..a7183921cce
--- /dev/null
+++ b/src/server/scripts/northrend/vault_of_archavon/instance_vault_of_archavon.cpp
@@ -0,0 +1,143 @@
+#include "ScriptedPch.h"
+#include "vault_of_archavon.h"
+
+#define ENCOUNTERS 4
+
+/* Vault of Archavon encounters:
+1 - Archavon the Stone Watcher event
+2 - Emalon the Storm Watcher event
+3 - Koralon the Flame Watcher event
+4 - Toravon the Ice Watcher event
+*/
+
+struct instance_archavon : public ScriptedInstance
+{
+ instance_archavon(Map *Map) : ScriptedInstance(Map) {};
+
+ uint32 uiEncounters[ENCOUNTERS];
+
+ uint64 uiArchavon;
+ uint64 uiEmalon;
+ uint64 uiKoralon;
+ uint64 uiToravon;
+
+ void Initialize()
+ {
+ uiArchavon = 0;
+ uiEmalon = 0;
+ uiKoralon = 0;
+ uiToravon = 0;
+
+ for (uint8 i = 0; i < ENCOUNTERS; i++)
+ uiEncounters[i] = NOT_STARTED;
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for (uint8 i = 0; i < ENCOUNTERS; i++)
+ if (uiEncounters[i] == IN_PROGRESS)
+ return true;
+
+ return false;
+ }
+
+ void OnCreatureCreate(Creature *creature, bool /*add*/)
+ {
+ switch(creature->GetEntry())
+ {
+ case CREATURE_ARCHAVON: uiArchavon = creature->GetGUID(); break;
+ case CREATURE_EMALON: uiEmalon = creature->GetGUID(); break;
+ case CREATURE_KORALON: uiKoralon = creature->GetGUID(); break;
+ case CREATURE_TORAVON: uiToravon = creature->GetGUID(); break;
+ }
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_ARCHAVON_EVENT: return uiEncounters[0];
+ case DATA_EMALON_EVENT: return uiEncounters[1];
+ case DATA_KORALON_EVENT: return uiEncounters[2];
+ case DATA_TORAVON_EVENT: return uiEncounters[3];
+ }
+ return 0;
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_ARCHAVON: return uiArchavon;
+ case DATA_EMALON: return uiEmalon;
+ case DATA_KORALON: return uiKoralon;
+ case DATA_TORAVON: return uiToravon;
+ }
+ return 0;
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_ARCHAVON_EVENT: uiEncounters[0] = data; break;
+ case DATA_EMALON_EVENT: uiEncounters[1] = data; break;
+ case DATA_KORALON_EVENT: uiEncounters[2] = data; break;
+ case DATA_TORAVON_EVENT: uiEncounters[3] = data; break;
+ }
+
+ if (data == DONE)
+ SaveToDB();
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+ std::ostringstream stream;
+ stream << uiEncounters[0] << " " << uiEncounters[1] << " " << uiEncounters[2] << " " << uiEncounters[3];
+
+ char* out = new char[stream.str().length() + 1];
+ strcpy(out, stream.str().c_str());
+ if (out)
+ {
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return out;
+ }
+
+ return NULL;
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ std::istringstream stream(in);
+ stream >> uiEncounters[0] >> uiEncounters[1] >> uiEncounters[2] >> uiEncounters[3];
+
+ for (uint8 i = 0; i < ENCOUNTERS; ++i)
+ if (uiEncounters[i] == IN_PROGRESS)
+ uiEncounters[i] = NOT_STARTED;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+};
+
+InstanceData* GetInstanceData_instance_archavon(Map* map)
+{
+ return new instance_archavon(map);
+}
+
+void AddSC_instance_archavon()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_archavon";
+ newscript->GetInstanceData = &GetInstanceData_instance_archavon;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/vault_of_archavon/vault_of_archavon.h b/src/server/scripts/northrend/vault_of_archavon/vault_of_archavon.h
new file mode 100644
index 00000000000..6aa642ff701
--- /dev/null
+++ b/src/server/scripts/northrend/vault_of_archavon/vault_of_archavon.h
@@ -0,0 +1,28 @@
+#ifndef DEF_ARCHAVON_H
+#define DEF_ARCHAVON_H
+
+enum Creatures
+{
+ CREATURE_ARCHAVON = 31125,
+ CREATURE_EMALON = 33993,
+ CREATURE_KORALON = 35013,
+ CREATURE_TORAVON = 38433,
+};
+
+enum Data
+{
+ DATA_ARCHAVON_EVENT,
+ DATA_EMALON_EVENT,
+ DATA_KORALON_EVENT,
+ DATA_TORAVON_EVENT,
+};
+
+enum Data64
+{
+ DATA_ARCHAVON,
+ DATA_EMALON,
+ DATA_KORALON,
+ DATA_TORAVON,
+};
+
+#endif
diff --git a/src/server/scripts/northrend/violet_hold/boss_cyanigosa.cpp b/src/server/scripts/northrend/violet_hold/boss_cyanigosa.cpp
new file mode 100644
index 00000000000..589e69a6f18
--- /dev/null
+++ b/src/server/scripts/northrend/violet_hold/boss_cyanigosa.cpp
@@ -0,0 +1,156 @@
+/* Script Data Start
+SDName: Boss cyanigosa
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "ScriptedPch.h"
+#include "violet_hold.h"
+
+enum Spells
+{
+ SPELL_ARCANE_VACUUM = 58694,
+ SPELL_BLIZZARD = 58693,
+ H_SPELL_BLIZZARD = 59369,
+ SPELL_MANA_DESTRUCTION = 59374,
+ SPELL_TAIL_SWEEP = 58690,
+ H_SPELL_TAIL_SWEEP = 59283,
+ SPELL_UNCONTROLLABLE_ENERGY = 58688,
+ H_SPELL_UNCONTROLLABLE_ENERGY = 59281,
+ SPELL_TRANSFORM = 58668
+};
+
+enum Yells
+{
+ SAY_AGGRO = -1608000,
+ SAY_SLAY_1 = -1608001,
+ SAY_SLAY_2 = -1608002,
+ SAY_SLAY_3 = -1608003,
+ SAY_DEATH = -1608004,
+ SAY_SPAWN = -1608005,
+ SAY_DISRUPTION = -1608006,
+ SAY_BREATH_ATTACK = -1608007,
+ SAY_SPECIAL_ATTACK_1 = -1608008,
+ SAY_SPECIAL_ATTACK_2 = -1608009
+};
+
+struct boss_cyanigosaAI : public ScriptedAI
+{
+ boss_cyanigosaAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiArcaneVacuumTimer;
+ uint32 uiBlizzardTimer;
+ uint32 uiManaDestructionTimer;
+ uint32 uiTailSweepTimer;
+ uint32 uiUncontrollableEnergyTimer;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiArcaneVacuumTimer = 10000;
+ uiBlizzardTimer = 15000;
+ uiManaDestructionTimer = 30000;
+ uiTailSweepTimer = 20000;
+ uiUncontrollableEnergyTimer = 25000;
+ if (pInstance)
+ pInstance->SetData(DATA_CYANIGOSA_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ DoCast(me, SPELL_TRANSFORM);
+
+ if (pInstance)
+ pInstance->SetData(DATA_CYANIGOSA_EVENT, IN_PROGRESS);
+ }
+
+ void MoveInLineOfSight(Unit* /*who*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (pInstance && pInstance->GetData(DATA_REMOVE_NPC) == 1)
+ {
+ me->ForcedDespawn();
+ pInstance->SetData(DATA_REMOVE_NPC, 0);
+ }
+
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiArcaneVacuumTimer <= diff)
+ {
+ DoCast(SPELL_ARCANE_VACUUM);
+ uiArcaneVacuumTimer = 10000;
+ } else uiArcaneVacuumTimer -= diff;
+
+ if (uiBlizzardTimer <= diff)
+ {
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_BLIZZARD);
+ uiBlizzardTimer = 15000;
+ } else uiBlizzardTimer -= diff;
+
+ if (uiTailSweepTimer <= diff)
+ {
+ DoCast(SPELL_TAIL_SWEEP);
+ uiTailSweepTimer = 20000;
+ } else uiTailSweepTimer -= diff;
+
+ if (uiUncontrollableEnergyTimer <= diff)
+ {
+ DoCastVictim(SPELL_UNCONTROLLABLE_ENERGY);
+ uiUncontrollableEnergyTimer = 25000;
+ } else uiUncontrollableEnergyTimer -= diff;
+
+ if (IsHeroic())
+ if (uiManaDestructionTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_MANA_DESTRUCTION);
+ uiManaDestructionTimer = 30000;
+ } else uiManaDestructionTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_CYANIGOSA_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+};
+
+CreatureAI* GetAI_boss_cyanigosa(Creature* pCreature)
+{
+ return new boss_cyanigosaAI (pCreature);
+}
+
+void AddSC_boss_cyanigosa()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_cyanigosa";
+ newscript->GetAI = &GetAI_boss_cyanigosa;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/violet_hold/boss_erekem.cpp b/src/server/scripts/northrend/violet_hold/boss_erekem.cpp
new file mode 100644
index 00000000000..a9cc7393af4
--- /dev/null
+++ b/src/server/scripts/northrend/violet_hold/boss_erekem.cpp
@@ -0,0 +1,329 @@
+/* Script Data Start
+SDName: Boss erekem
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "ScriptedPch.h"
+#include "violet_hold.h"
+
+enum Spells
+{
+ SPELL_BLOODLUST = 54516,
+ SPELL_BREAK_BONDS = 59463,
+ SPELL_CHAIN_HEAL = 54481,
+ H_SPELL_CHAIN_HEAL = 59473,
+ SPELL_EARTH_SHIELD = 54479,
+ H_SPELL_EARTH_SHIELD = 59471,
+ SPELL_EARTH_SHOCK = 54511,
+ SPELL_LIGHTNING_BOLT = 53044,
+ SPELL_STORMSTRIKE = 51876
+};
+
+enum Yells
+{
+ SAY_AGGRO = -1608010,
+ SAY_SLAY_1 = -1608011,
+ SAY_SLAY_2 = -1608012,
+ SAY_SLAY_3 = -1608013,
+ SAY_DEATH = -1608014,
+ SAY_SPAWN = -1608015,
+ SAY_ADD_KILLED = -1608016,
+ SAY_BOTH_ADDS_KILLED = -1608017
+};
+
+struct boss_erekemAI : public ScriptedAI
+{
+ boss_erekemAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiBloodlustTimer;
+ uint32 uiChainHealTimer;
+ uint32 uiEarthShockTimer;
+ uint32 uiLightningBoltTimer;
+ uint32 uiEarthShieldTimer;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiBloodlustTimer = 15000;
+ uiChainHealTimer = 0;
+ uiEarthShockTimer = urand(2000,8000);
+ uiLightningBoltTimer = urand(5000,10000);
+ uiEarthShieldTimer = 20000;
+ if (pInstance)
+ {
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, NOT_STARTED);
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
+ }
+
+ if (Creature *pGuard1 = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_EREKEM_GUARD_1) : 0))
+ {
+ if (!pGuard1->isAlive())
+ pGuard1->Respawn();
+ }
+ if (Creature *pGuard2 = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_EREKEM_GUARD_2) : 0))
+ {
+ if (!pGuard2->isAlive())
+ pGuard2->Respawn();
+ }
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (me->Attack(pWho, true))
+ {
+ me->AddThreat(pWho, 0.0f);
+ me->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(me);
+ DoStartMovement(pWho);
+
+ if (Creature *pGuard1 = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_EREKEM_GUARD_1) : 0))
+ {
+ pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
+ if (!pGuard1->getVictim() && pGuard1->AI())
+ pGuard1->AI()->AttackStart(pWho);
+ }
+ if (Creature *pGuard2 = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_EREKEM_GUARD_2) : 0))
+ {
+ pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
+ if (!pGuard2->getVictim() && pGuard2->AI())
+ pGuard2->AI()->AttackStart(pWho);
+ }
+ }
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ DoCast(me, SPELL_EARTH_SHIELD);
+
+ if (pInstance)
+ {
+ if (GameObject *pDoor = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_EREKEM_CELL)))
+ if (pDoor->GetGoState() == GO_STATE_READY)
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
+ }
+ }
+
+ void MoveInLineOfSight(Unit* /*who*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ //spam stormstrike in hc mode if spawns are dead
+ if (IsHeroic())
+ {
+ if (Creature *pGuard1 = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_EREKEM_GUARD_1) : 0))
+ {
+ if (Creature *pGuard2 = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_EREKEM_GUARD_2) : 0))
+ {
+ if (!pGuard1->isAlive() && !pGuard2->isAlive())
+ DoCast(me->getVictim(), SPELL_STORMSTRIKE);
+ }
+ }
+ }
+
+ if (uiEarthShieldTimer <= diff)
+ {
+ DoCast(me, SPELL_EARTH_SHIELD);
+ uiEarthShieldTimer = 20000;
+ } else uiEarthShieldTimer -= diff;
+
+ if (uiChainHealTimer <= diff)
+ {
+ if (uint64 TargetGUID = GetChainHealTargetGUID())
+ {
+ if (Creature *pTarget = Unit::GetCreature(*me, TargetGUID))
+ DoCast(pTarget, SPELL_CHAIN_HEAL);
+
+ //If one of the adds is dead spawn heals faster
+ Creature *pGuard1 = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_EREKEM_GUARD_1) : 0);
+ Creature *pGuard2 = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_EREKEM_GUARD_2) : 0);
+ uiChainHealTimer = ((pGuard1 && !pGuard1->isAlive()) || (pGuard2 && !pGuard2->isAlive()) ? 3000 : 8000) + rand()%3000;
+ }
+ } else uiChainHealTimer -= diff;
+
+ if (uiBloodlustTimer <= diff)
+ {
+ DoCast(me, SPELL_BLOODLUST);
+ uiBloodlustTimer = urand(35000,45000);
+ } else uiBloodlustTimer -= diff;
+
+ if (uiEarthShockTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_EARTH_SHOCK);
+ uiEarthShockTimer = urand(8000,13000);
+ } else uiEarthShockTimer -= diff;
+
+ if (uiLightningBoltTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_LIGHTNING_BOLT);
+ uiLightningBoltTimer = urand(18000,24000);
+ } else uiLightningBoltTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ {
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ {
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, DONE);
+ pInstance->SetData(DATA_WAVE_COUNT, 7);
+ }
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ {
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, DONE);
+ pInstance->SetData(DATA_WAVE_COUNT, 13);
+ }
+ }
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+
+ uint64 GetChainHealTargetGUID()
+ {
+ if (HealthBelowPct(85))
+ return me->GetGUID();
+
+ Creature *pGuard1 = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_EREKEM_GUARD_1) : 0);
+ if (pGuard1 && pGuard1->isAlive() && (pGuard1->GetHealth()*100 <= pGuard1->GetMaxHealth() * 75))
+ return pGuard1->GetGUID();
+
+ Creature *pGuard2 = Unit::GetCreature(*me, pInstance ? pInstance->GetData64(DATA_EREKEM_GUARD_2) : 0);
+ if (pGuard2 && pGuard2->isAlive() && (pGuard2->GetHealth()*100 <= pGuard2->GetMaxHealth() * 75))
+ return pGuard2->GetGUID();
+
+ return 0;
+ }
+};
+
+CreatureAI* GetAI_boss_erekem(Creature* pCreature)
+{
+ return new boss_erekemAI (pCreature);
+}
+
+enum GuardSpells
+{
+ SPELL_GUSHING_WOUND = 39215,
+ SPELL_HOWLING_SCREECH = 54462,
+ SPELL_STRIKE = 14516
+};
+
+struct mob_erekem_guardAI : public ScriptedAI
+{
+ mob_erekem_guardAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiGushingWoundTimer;
+ uint32 uiHowlingScreechTimer;
+ uint32 uiStrikeTimer;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiStrikeTimer = urand(4000,8000);
+ uiHowlingScreechTimer = urand(8000,13000);
+ uiGushingWoundTimer = urand(1000,3000);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (me->Attack(pWho, true))
+ {
+ me->AddThreat(pWho, 0.0f);
+ me->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(me);
+ DoStartMovement(pWho);
+ }
+ }
+
+ void MoveInLineOfSight(Unit* /*who*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+
+ if (uiStrikeTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_STRIKE);
+ uiStrikeTimer = urand(4000,8000);
+ } else uiStrikeTimer -= diff;
+
+ if (uiHowlingScreechTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_HOWLING_SCREECH);
+ uiHowlingScreechTimer = urand(8000,13000);
+ } else uiHowlingScreechTimer -= diff;
+
+ if (uiGushingWoundTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_GUSHING_WOUND);
+ uiGushingWoundTimer = urand(7000,12000);
+ } else uiGushingWoundTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_erekem_guard(Creature* pCreature)
+{
+ return new mob_erekem_guardAI (pCreature);
+}
+
+void AddSC_boss_erekem()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_erekem";
+ newscript->GetAI = &GetAI_boss_erekem;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_erekem_guard";
+ newscript->GetAI = &GetAI_mob_erekem_guard;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/violet_hold/boss_ichoron.cpp b/src/server/scripts/northrend/violet_hold/boss_ichoron.cpp
new file mode 100644
index 00000000000..a28bfdffb7c
--- /dev/null
+++ b/src/server/scripts/northrend/violet_hold/boss_ichoron.cpp
@@ -0,0 +1,394 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Script Data Start
+SDName: Boss ichoron
+SDAuthor: ckegg
+SD%Complete: 80%
+SDComment: TODO: better spawn location for adds
+SDCategory:
+Script Data End */
+
+#include "ScriptedPch.h"
+#include "violet_hold.h"
+
+enum Spells
+{
+ SPELL_DRAINED = 59820,
+ SPELL_FRENZY = 54312,
+ SPELL_FRENZY_H = 59522,
+ SPELL_PROTECTIVE_BUBBLE = 54306,
+ SPELL_WATER_BLAST = 54237,
+ SPELL_WATER_BLAST_H = 59520,
+ SPELL_WATER_BOLT_VOLLEY = 54241,
+ SPELL_WATER_BOLT_VOLLEY_H = 59521,
+ SPELL_SPLASH = 59516,
+};
+
+enum IchoronCreatures
+{
+ NPC_ICHOR_GLOBULE = 29321,
+};
+
+enum Yells
+{
+ SAY_AGGRO = -1608018,
+ SAY_SLAY_1 = -1608019,
+ SAY_SLAY_2 = -1608020,
+ SAY_SLAY_3 = -1608021,
+ SAY_DEATH = -1608022,
+ SAY_SPAWN = -1608023,
+ SAY_ENRAGE = -1608024,
+ SAY_SHATTER = -1608025,
+ SAY_BUBBLE = -1608026
+};
+
+enum Achievements
+{
+ ACHIEVEMENT_DEHYDRATION = 2041,
+};
+
+enum Actions
+{
+ ACTION_WATER_ELEMENT_HIT = 1,
+ ACTION_WATER_ELEMENT_KILLED = 2,
+};
+
+// TODO get those positions from spawn of creature 29326
+#define MAX_SPAWN_LOC 5
+static Position SpawnLoc[MAX_SPAWN_LOC]=
+{
+ {1840.64, 795.407, 44.079, 1.676},
+ {1886.24, 757.733, 47.750, 5.201},
+ {1877.91, 845.915, 43.417, 3.560},
+ {1918.97, 850.645, 47.225, 4.136},
+ {1935.50, 796.224, 52.492, 4.224},
+};
+
+struct boss_ichoronAI : public ScriptedAI
+{
+ boss_ichoronAI(Creature* pCreature) : ScriptedAI(pCreature), m_waterElements(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ bool bIsExploded;
+ bool bIsFrenzy;
+ bool bAchievement;
+
+ uint32 uiBubbleCheckerTimer;
+ uint32 uiWaterBoltVolleyTimer;
+
+ ScriptedInstance* pInstance;
+
+ SummonList m_waterElements;
+
+ void Reset()
+ {
+ bIsExploded = false;
+ bIsFrenzy = false;
+ bAchievement = true;
+ uiBubbleCheckerTimer = 1000;
+ uiWaterBoltVolleyTimer = urand(10000, 15000);
+
+ me->SetVisibility(VISIBILITY_ON);
+ DespawnWaterElements();
+
+ if (pInstance)
+ {
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, NOT_STARTED);
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
+ }
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+
+ DoCast(me, SPELL_PROTECTIVE_BUBBLE);
+
+ if (pInstance)
+ {
+ if (GameObject *pDoor = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_ICHORON_CELL)))
+ if (pDoor->GetGoState() == GO_STATE_READY)
+ {
+ EnterEvadeMode();
+ return;
+ }
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
+ }
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (me->Attack(pWho, true))
+ {
+ me->AddThreat(pWho, 0.0f);
+ me->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(me);
+ DoStartMovement(pWho);
+ }
+ }
+
+ void DoAction(const int32 param)
+ {
+ if (!me->isAlive())
+ return;
+
+ switch(param)
+ {
+ case ACTION_WATER_ELEMENT_HIT:
+ me->SetHealth(me->GetHealth() + me->GetMaxHealth() * 0.01);
+
+ if (bIsExploded)
+ DoExplodeCompleted();
+
+ bAchievement = false;
+ break;
+ case ACTION_WATER_ELEMENT_KILLED:
+ uint32 damage = (me->GetMaxHealth()*3)/100;
+ me->SetHealth(me->GetHealth() - damage);
+ me->LowerPlayerDamageReq(damage);
+ break;
+ }
+ }
+
+ void DespawnWaterElements()
+ {
+ m_waterElements.DespawnAll();
+ }
+
+ // call when explode shall stop.
+ // either when "hit" by a bubble, or when there is no bubble left.
+ void DoExplodeCompleted()
+ {
+ bIsExploded = false;
+
+ if (!HealthBelowPct(25))
+ {
+ DoScriptText(SAY_BUBBLE, me);
+ DoCast(me, SPELL_PROTECTIVE_BUBBLE, true);
+ }
+
+ me->SetVisibility(VISIBILITY_ON);
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+ }
+
+ void MoveInLineOfSight(Unit* /*pWho*/) {}
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (!bIsFrenzy && HealthBelowPct(25) && !bIsExploded)
+ {
+ DoScriptText(SAY_ENRAGE, me);
+ DoCast(me, SPELL_FRENZY, true);
+ bIsFrenzy = true;
+ }
+
+ if (!bIsFrenzy)
+ {
+ if (uiBubbleCheckerTimer <= uiDiff)
+ {
+ if (!bIsExploded)
+ {
+ if (!me->HasAura(SPELL_PROTECTIVE_BUBBLE, 0))
+ {
+ DoScriptText(SAY_SHATTER, me);
+ DoCast(me, SPELL_WATER_BLAST);
+ DoCast(me, SPELL_DRAINED);
+ bIsExploded = true;
+ me->AttackStop();
+ me->SetVisibility(VISIBILITY_OFF);
+ for (uint8 i = 0; i < 10; i++)
+ {
+ int tmp = urand(0, MAX_SPAWN_LOC-1);
+ me->SummonCreature(NPC_ICHOR_GLOBULE, SpawnLoc[tmp], TEMPSUMMON_CORPSE_DESPAWN);
+ }
+ }
+ }
+ else
+ {
+ bool bIsWaterElementsAlive = false;
+ if (!m_waterElements.empty())
+ {
+ for (std::list<uint64>::const_iterator itr = m_waterElements.begin(); itr != m_waterElements.end(); ++itr)
+ if (Creature* pTemp = Unit::GetCreature(*me, *itr))
+ if (pTemp->isAlive())
+ {
+ bIsWaterElementsAlive = true;
+ break;
+ }
+ }
+
+ if (!bIsWaterElementsAlive)
+ DoExplodeCompleted();
+ }
+ uiBubbleCheckerTimer = 1000;
+ }
+ else uiBubbleCheckerTimer -= uiDiff;
+ }
+
+ if (!bIsExploded)
+ {
+ if (uiWaterBoltVolleyTimer <= uiDiff)
+ {
+ DoCast(me, SPELL_WATER_BOLT_VOLLEY);
+ uiWaterBoltVolleyTimer = urand(10000, 15000);
+ }
+ else uiWaterBoltVolleyTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (bIsExploded)
+ {
+ bIsExploded = false;
+ me->SetVisibility(VISIBILITY_ON);
+ }
+
+ DespawnWaterElements();
+
+ if (pInstance)
+ {
+ if (IsHeroic() && bAchievement)
+ pInstance->DoCompleteAchievement(ACHIEVEMENT_DEHYDRATION);
+
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ {
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, DONE);
+ pInstance->SetData(DATA_WAVE_COUNT, 7);
+ }
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ {
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, DONE);
+ pInstance->SetData(DATA_WAVE_COUNT, 13);
+ }
+ }
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ pSummoned->SetSpeed(MOVE_RUN, 0.3f);
+ pSummoned->GetMotionMaster()->MoveFollow(me, 0, 0);
+ m_waterElements.push_back(pSummoned->GetGUID());
+ }
+
+
+ void SummonedCreatureDespawn(Creature *pSummoned)
+ {
+ m_waterElements.remove(pSummoned->GetGUID());
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+};
+
+CreatureAI* GetAI_boss_ichoron(Creature* pCreature)
+{
+ return new boss_ichoronAI (pCreature);
+}
+
+struct mob_ichor_globuleAI : public ScriptedAI
+{
+ mob_ichor_globuleAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiRangeCheck_Timer;
+
+ void Reset()
+ {
+ uiRangeCheck_Timer = 1000;
+ }
+
+ void AttackStart(Unit* /*pWho*/)
+ {
+ return;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (uiRangeCheck_Timer < uiDiff)
+ {
+ if (pInstance)
+ {
+ if (Creature* pIchoron = Unit::GetCreature(*me, pInstance->GetData64(DATA_ICHORON)))
+ {
+ if (me->IsWithinDist(pIchoron, 2.0f , false))
+ {
+ if (pIchoron->AI())
+ pIchoron->AI()->DoAction(ACTION_WATER_ELEMENT_HIT);
+ me->ForcedDespawn();
+ }
+ }
+ }
+ uiRangeCheck_Timer = 1000;
+ }
+ else uiRangeCheck_Timer -= uiDiff;
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ DoCast(me, SPELL_SPLASH);
+ if (Creature* pIchoron = Unit::GetCreature(*me, pInstance->GetData64(DATA_ICHORON)))
+ if (pIchoron->AI())
+ pIchoron->AI()->DoAction(ACTION_WATER_ELEMENT_KILLED);
+ }
+};
+
+CreatureAI* GetAI_mob_ichor_globule(Creature* pCreature)
+{
+ return new mob_ichor_globuleAI (pCreature);
+}
+
+void AddSC_boss_ichoron()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_ichoron";
+ newscript->GetAI = &GetAI_boss_ichoron;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_ichor_globule";
+ newscript->GetAI = &GetAI_mob_ichor_globule;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/violet_hold/boss_lavanthor.cpp b/src/server/scripts/northrend/violet_hold/boss_lavanthor.cpp
new file mode 100644
index 00000000000..d8cd3a4962f
--- /dev/null
+++ b/src/server/scripts/northrend/violet_hold/boss_lavanthor.cpp
@@ -0,0 +1,155 @@
+/* Script Data Start
+SDName: Boss lavanthor
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "ScriptedPch.h"
+#include "violet_hold.h"
+
+enum Spells
+{
+ SPELL_CAUTERIZING_FLAMES = 59466, //Only in heroic
+ SPELL_FIREBOLT = 54235,
+ H_SPELL_FIREBOLT = 59468,
+ SPELL_FLAME_BREATH = 54282,
+ H_SPELL_FLAME_BREATH = 59469,
+ SPELL_LAVA_BURN = 54249,
+ H_SPELL_LAVA_BURN = 59594
+};
+
+struct boss_lavanthorAI : public ScriptedAI
+{
+ boss_lavanthorAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiFireboltTimer;
+ uint32 uiFlameBreathTimer;
+ uint32 uiLavaBurnTimer;
+ uint32 uiCauterizingFlamesTimer;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiFireboltTimer = 1000;
+ uiFlameBreathTimer = 5000;
+ uiLavaBurnTimer = 10000;
+ uiCauterizingFlamesTimer = 3000;
+ if (pInstance)
+ {
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, NOT_STARTED);
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ if (pInstance)
+ {
+ if (GameObject *pDoor = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_LAVANTHOR_CELL)))
+ if (pDoor->GetGoState() == GO_STATE_READY)
+ {
+ EnterEvadeMode();
+ return;
+ }
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
+ }
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (me->Attack(pWho, true))
+ {
+ me->AddThreat(pWho, 0.0f);
+ me->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(me);
+ DoStartMovement(pWho);
+ }
+ }
+
+ void MoveInLineOfSight(Unit* /*who*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiFireboltTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_FIREBOLT);
+ uiFireboltTimer = urand(5000,13000);
+ } else uiFireboltTimer -= diff;
+
+ if (uiFlameBreathTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_FLAME_BREATH);
+ uiFlameBreathTimer = urand(10000,15000);
+ } else uiFlameBreathTimer -= diff;
+
+ if (uiLavaBurnTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_LAVA_BURN);
+ uiLavaBurnTimer = urand(15000,23000);
+ }
+
+ if (IsHeroic())
+ {
+ if (uiCauterizingFlamesTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_CAUTERIZING_FLAMES);
+ uiCauterizingFlamesTimer = urand(10000,16000);
+ } else uiCauterizingFlamesTimer -= diff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ {
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ {
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, DONE);
+ pInstance->SetData(DATA_WAVE_COUNT, 7);
+ }
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ {
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, DONE);
+ pInstance->SetData(DATA_WAVE_COUNT, 13);
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_lavanthor(Creature* pCreature)
+{
+ return new boss_lavanthorAI (pCreature);
+}
+
+void AddSC_boss_lavanthor()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_lavanthor";
+ newscript->GetAI = &GetAI_boss_lavanthor;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/violet_hold/boss_moragg.cpp b/src/server/scripts/northrend/violet_hold/boss_moragg.cpp
new file mode 100644
index 00000000000..6d283c7bfb4
--- /dev/null
+++ b/src/server/scripts/northrend/violet_hold/boss_moragg.cpp
@@ -0,0 +1,133 @@
+/* Script Data Start
+SDName: Boss moragg
+SDAuthor: LordVanMartin
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+/*** SQL START ***
+update creature_template set scriptname = '' where entry = '';
+*** SQL END ***/
+#include "ScriptedPch.h"
+#include "violet_hold.h"
+
+//Spells
+enum Spells
+{
+ SPELL_CORROSIVE_SALIVA = 54527,
+ SPELL_OPTIC_LINK = 54396
+};
+
+struct boss_moraggAI : public ScriptedAI
+{
+ boss_moraggAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiOpticLinkTimer;
+ uint32 uiCorrosiveSalivaTimer;
+
+ ScriptedInstance* pInstance;
+
+ void Reset()
+ {
+ uiOpticLinkTimer = 10000;
+ uiCorrosiveSalivaTimer = 5000;
+
+ if (pInstance)
+ {
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, NOT_STARTED);
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ if (pInstance)
+ {
+ if (GameObject *pDoor = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_MORAGG_CELL)))
+ if (pDoor->GetGoState() == GO_STATE_READY)
+ {
+ EnterEvadeMode();
+ return;
+ }
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
+ }
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (me->Attack(pWho, true))
+ {
+ me->AddThreat(pWho, 0.0f);
+ me->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(me);
+ DoStartMovement(pWho);
+ }
+ }
+
+ void MoveInLineOfSight(Unit* /*who*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiOpticLinkTimer <= diff)
+ {
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ DoCast(pTarget, SPELL_OPTIC_LINK);
+ uiOpticLinkTimer = 15000;
+ } else uiOpticLinkTimer -= diff;
+
+ if (uiCorrosiveSalivaTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_CORROSIVE_SALIVA);
+ uiCorrosiveSalivaTimer = 10000;
+ } else uiCorrosiveSalivaTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ {
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ {
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, DONE);
+ pInstance->SetData(DATA_WAVE_COUNT, 7);
+ }
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ {
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, DONE);
+ pInstance->SetData(DATA_WAVE_COUNT,13);
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_moragg(Creature* pCreature)
+{
+ return new boss_moraggAI (pCreature);
+}
+
+void AddSC_boss_moragg()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_moragg";
+ newscript->GetAI = &GetAI_boss_moragg;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/violet_hold/boss_xevozz.cpp b/src/server/scripts/northrend/violet_hold/boss_xevozz.cpp
new file mode 100644
index 00000000000..2633705c1b7
--- /dev/null
+++ b/src/server/scripts/northrend/violet_hold/boss_xevozz.cpp
@@ -0,0 +1,307 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Script Data Start
+SDName: Boss xevozz
+SD%Complete:
+SDComment:
+SDCategory:
+Script Data End */
+
+#include "ScriptedPch.h"
+#include "violet_hold.h"
+
+enum Spells
+{
+ SPELL_ARCANE_BARRAGE_VOLLEY = 54202,
+ SPELL_ARCANE_BARRAGE_VOLLEY_H = 59483,
+ SPELL_ARCANE_BUFFET = 54226,
+ SPELL_ARCANE_BUFFET_H = 59485,
+ SPELL_SUMMON_ETHEREAL_SPHERE_1 = 54102,
+ SPELL_SUMMON_ETHEREAL_SPHERE_2 = 54137,
+ SPELL_SUMMON_ETHEREAL_SPHERE_3 = 54138,
+};
+
+enum NPCs
+{
+ NPC_ETHEREAL_SPHERE = 29271,
+ //NPC_ETHEREAL_SPHERE2 = 32582, // heroic only?
+};
+
+enum CreatureSpells
+{
+ SPELL_ARCANE_POWER = 54160,
+ H_SPELL_ARCANE_POWER = 59474,
+ SPELL_SUMMON_PLAYERS = 54164,
+ SPELL_POWER_BALL_VISUAL = 54141,
+};
+
+enum Yells
+{
+ SAY_AGGRO = -1608027,
+ SAY_SLAY_1 = -1608028,
+ SAY_SLAY_2 = -1608029,
+ SAY_SLAY_3 = -1608030,
+ SAY_DEATH = -1608031,
+ SAY_SPAWN = -1608032,
+ SAY_CHARGED = -1608033,
+ SAY_REPEAT_SUMMON_1 = -1608034,
+ SAY_REPEAT_SUMMON_2 = -1608035,
+ SAY_SUMMON_ENERGY = -1608036
+};
+
+struct boss_xevozzAI : public ScriptedAI
+{
+ boss_xevozzAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiSummonEtherealSphere_Timer;
+ uint32 uiArcaneBarrageVolley_Timer;
+ uint32 uiArcaneBuffet_Timer;
+
+ void Reset()
+ {
+ if (pInstance)
+ {
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, NOT_STARTED);
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
+ }
+
+ uiSummonEtherealSphere_Timer = urand(10000, 12000);
+ uiArcaneBarrageVolley_Timer = urand(20000, 22000);
+ uiArcaneBuffet_Timer = uiSummonEtherealSphere_Timer + urand(5000, 6000);
+ DespawnSphere();
+ }
+
+ void DespawnSphere()
+ {
+ std::list<Creature*> assistList;
+ GetCreatureListWithEntryInGrid(assistList,me, NPC_ETHEREAL_SPHERE ,150.0f);
+
+ if (assistList.empty())
+ return;
+
+ for (std::list<Creature*>::const_iterator iter = assistList.begin(); iter != assistList.end(); ++iter)
+ {
+ if (Creature* pSphere = *iter)
+ pSphere->Kill(pSphere, false);
+ }
+ }
+
+ void JustSummoned(Creature* pSummoned)
+ {
+ pSummoned->SetSpeed(MOVE_RUN, 0.5f);
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ pSummoned->AddThreat(pTarget, 0.00f);
+ pSummoned->AI()->AttackStart(pTarget);
+ }
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (me->Attack(pWho, true))
+ {
+ me->AddThreat(pWho, 0.0f);
+ me->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(me);
+ DoStartMovement(pWho);
+ }
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ if (pInstance)
+ {
+ if (GameObject *pDoor = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_XEVOZZ_CELL)))
+ if (pDoor->GetGoState() == GO_STATE_READY)
+ {
+ EnterEvadeMode();
+ return;
+ }
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
+ }
+ }
+
+ void MoveInLineOfSight(Unit* /*pWho*/) {}
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (uiArcaneBarrageVolley_Timer < uiDiff)
+ {
+ DoCast(me, SPELL_ARCANE_BARRAGE_VOLLEY);
+ uiArcaneBarrageVolley_Timer = urand(20000, 22000);
+ }
+ else uiArcaneBarrageVolley_Timer -= uiDiff;
+
+ if (uiArcaneBuffet_Timer)
+ if (uiArcaneBuffet_Timer < uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_ARCANE_BUFFET);
+ uiArcaneBuffet_Timer = 0;
+ }
+ else uiArcaneBuffet_Timer -= uiDiff;
+
+ if (uiSummonEtherealSphere_Timer < uiDiff)
+ {
+ DoScriptText(SAY_SPAWN, me);
+ DoCast(me, SPELL_SUMMON_ETHEREAL_SPHERE_1);
+ if (IsHeroic()) // extra one for heroic
+ me->SummonCreature(NPC_ETHEREAL_SPHERE, me->GetPositionX()-5+rand()%10, me->GetPositionY()-5+rand()%10, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 40000);
+
+ uiSummonEtherealSphere_Timer = urand(45000, 47000);
+ uiArcaneBuffet_Timer = urand(5000, 6000);
+ }
+ else uiSummonEtherealSphere_Timer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*pKiller*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ DespawnSphere();
+
+ if (pInstance)
+ {
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ {
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, DONE);
+ pInstance->SetData(DATA_WAVE_COUNT, 7);
+ }
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ {
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
+ pInstance->SetData(DATA_WAVE_COUNT, 13);
+ }
+ }
+ }
+ void KilledUnit(Unit* pVictim)
+ {
+ if (pVictim == me)
+ return;
+
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+};
+
+CreatureAI* GetAI_boss_xevozz(Creature* pCreature)
+{
+ return new boss_xevozzAI (pCreature);
+}
+
+struct mob_ethereal_sphereAI : public ScriptedAI
+{
+ mob_ethereal_sphereAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 uiSummonPlayers_Timer;
+ uint32 uiRangeCheck_Timer;
+
+ void Reset()
+ {
+ uiSummonPlayers_Timer = urand(33000, 35000);
+ uiRangeCheck_Timer = 1000;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (!me->HasAura(SPELL_POWER_BALL_VISUAL))
+ DoCast(me, SPELL_POWER_BALL_VISUAL);
+
+ if (uiRangeCheck_Timer < uiDiff)
+ {
+ if (pInstance)
+ {
+ if (Creature* pXevozz = Unit::GetCreature(*me, pInstance->GetData64(DATA_XEVOZZ)))
+ {
+ float fDistance = me->GetDistance2d(pXevozz);
+ if (fDistance <= 3)
+ DoCast(pXevozz, SPELL_ARCANE_POWER);
+ else
+ DoCast(me, 35845); //Is it blizzlike?
+ }
+ }
+ uiRangeCheck_Timer = 1000;
+ }
+ else uiRangeCheck_Timer -= uiDiff;
+
+ if (uiSummonPlayers_Timer < uiDiff)
+ {
+ DoCast(me, SPELL_SUMMON_PLAYERS); // not working right
+
+ Map* pMap = me->GetMap();
+ if (pMap && pMap->IsDungeon())
+ {
+ Map::PlayerList const &PlayerList = pMap->GetPlayers();
+
+ if (!PlayerList.isEmpty())
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ if (i->getSource()->isAlive())
+ DoTeleportPlayer(i->getSource(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), i->getSource()->GetOrientation());
+ }
+
+ uiSummonPlayers_Timer = urand(33000, 35000);
+ }
+ else uiSummonPlayers_Timer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_mob_ethereal_sphere(Creature* pCreature)
+{
+ return new mob_ethereal_sphereAI (pCreature);
+}
+
+void AddSC_boss_xevozz()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_xevozz";
+ newscript->GetAI = &GetAI_boss_xevozz;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "mob_ethereal_sphere";
+ newscript->GetAI = &GetAI_mob_ethereal_sphere;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/violet_hold/boss_zuramat.cpp b/src/server/scripts/northrend/violet_hold/boss_zuramat.cpp
new file mode 100644
index 00000000000..da75ed94fc2
--- /dev/null
+++ b/src/server/scripts/northrend/violet_hold/boss_zuramat.cpp
@@ -0,0 +1,178 @@
+/* Script Data Start
+SDName: Boss zuramat
+SD%Complete:
+SDComment: The phasemask for the voids dosen't work.
+SDCategory:
+Script Data End */
+
+#include "ScriptedPch.h"
+#include "violet_hold.h"
+
+enum Spells
+{
+ SPELL_SHROUD_OF_DARKNESS = 54524,
+ H_SPELL_SHROUD_OF_DARKNESS = 59745,
+ SPELL_SUMMON_VOID_SENTRY = 54369,
+ SPELL_VOID_SHIFT = 54361,
+ H_SPELL_VOID_SHIFT = 59743,
+
+ SPELL_ZURAMAT_ADD_2 = 54342,
+ H_SPELL_ZURAMAT_ADD_2 = 59747
+};
+
+enum ZuramatCreatures
+{
+ CREATURE_VOID_SENTRY = 29364
+};
+
+enum Yells
+{
+ SAY_AGGRO = -1608037,
+ SAY_SLAY_1 = -1608038,
+ SAY_SLAY_2 = -1608039,
+ SAY_SLAY_3 = -1608040,
+ SAY_DEATH = -1608041,
+ SAY_SPAWN = -1608042,
+ SAY_SHIELD = -1608043,
+ SAY_WHISPER = -1608044
+};
+
+struct boss_zuramatAI : public ScriptedAI
+{
+ boss_zuramatAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint32 SpellVoidShiftTimer;
+ uint32 SpellSummonVoidTimer;
+ uint32 SpellShroudOfDarknessTimer;
+
+ void Reset()
+ {
+ if (pInstance)
+ {
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, NOT_STARTED);
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
+ }
+
+ SpellShroudOfDarknessTimer = 22000;
+ SpellVoidShiftTimer = 15000;
+ SpellSummonVoidTimer = 12000;
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ return;
+
+ if (me->Attack(pWho, true))
+ {
+ me->AddThreat(pWho, 0.0f);
+ me->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(me);
+ DoStartMovement(pWho);
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ if (pInstance)
+ {
+ if (GameObject *pDoor = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_ZURAMAT_CELL)))
+ if (pDoor->GetGoState() == GO_STATE_READY)
+ {
+ EnterEvadeMode();
+ return;
+ }
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
+ }
+ }
+
+ void MoveInLineOfSight(Unit* /*who*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ if (SpellSummonVoidTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_SUMMON_VOID_SENTRY, false);
+ SpellSummonVoidTimer = 20000;
+ } else SpellSummonVoidTimer -=diff;
+
+ if (SpellVoidShiftTimer <= diff)
+ {
+ if (Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pUnit, SPELL_VOID_SHIFT);
+ SpellVoidShiftTimer = 20000;
+ } else SpellVoidShiftTimer -=diff;
+
+ if (SpellShroudOfDarknessTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_SHROUD_OF_DARKNESS);
+ SpellShroudOfDarknessTimer = 20000;
+ } else SpellShroudOfDarknessTimer -=diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ {
+ if (pInstance->GetData(DATA_WAVE_COUNT) == 6)
+ {
+ pInstance->SetData(DATA_1ST_BOSS_EVENT, DONE);
+ pInstance->SetData(DATA_WAVE_COUNT, 7);
+ }
+ else if (pInstance->GetData(DATA_WAVE_COUNT) == 12)
+ {
+ pInstance->SetData(DATA_2ND_BOSS_EVENT, DONE);
+ pInstance->SetData(DATA_WAVE_COUNT, 13);
+ }
+ }
+ }
+
+ void KilledUnit(Unit * victim)
+ {
+ if (victim == me)
+ return;
+
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ summon->AI()->AttackStart(me->getVictim());
+ summon->AI()->DoCastAOE(SPELL_ZURAMAT_ADD_2);
+ summon->SetPhaseMask(17,true);
+ }
+};
+
+CreatureAI* GetAI_boss_zuramat(Creature* pCreature)
+{
+ return new boss_zuramatAI (pCreature);
+}
+
+void AddSC_boss_zuramat()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "boss_zuramat";
+ newscript->GetAI = &GetAI_boss_zuramat;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/violet_hold/instance_violet_hold.cpp b/src/server/scripts/northrend/violet_hold/instance_violet_hold.cpp
new file mode 100644
index 00000000000..781511f940b
--- /dev/null
+++ b/src/server/scripts/northrend/violet_hold/instance_violet_hold.cpp
@@ -0,0 +1,528 @@
+#include "ScriptedPch.h"
+#include "violet_hold.h"
+
+#define MAX_ENCOUNTER 3
+
+/* Violet Hold encounters:
+0 - First boss
+1 - Second boss
+2 - Cyanigosa*/
+
+/* Violet hold bosses:
+1 - Moragg
+2 - Erekem
+3 - Ichoron
+4 - Lavanthor
+5 - Xevozz
+6 - Zuramat
+7 - Cyanigosa */
+
+enum GameObjects
+{
+ GO_MAIN_DOOR = 191723,
+ GO_XEVOZZ_DOOR = 191556,
+ GO_LAVANTHOR_DOOR = 191566,
+ GO_ICHORON_DOOR = 191722,
+ GO_ZURAMAT_DOOR = 191565,
+ GO_EREKEM_DOOR = 191564,
+ GO_EREKEM_GUARD_1_DOOR = 191563,
+ GO_EREKEM_GUARD_2_DOOR = 191562,
+ GO_MORAGG_DOOR = 191606,
+ GO_INTRO_ACTIVATION_CRYSTAL = 193615,
+ GO_ACTIVATION_CRYSTAL = 193611
+};
+
+const Position PortalLocation[] =
+{
+ {1936.07, 803.198, 53.3749, 3.12414},
+ {1877.51, 850.104, 44.6599, 4.7822 },
+ {1890.64, 753.471, 48.7224, 1.71042},
+ {1908.31, 809.657, 38.7037, 3.08701},
+ {1918.37, 853.437, 47.1624, 4.12294},
+ {1927.61, 758.436, 51.4533, 2.20891}
+};
+
+struct instance_violet_hold : public ScriptedInstance
+{
+ instance_violet_hold(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+
+ uint64 uiMoragg;
+ uint64 uiErekem;
+ uint64 uiErekemGuard[2];
+ uint64 uiIchoron;
+ uint64 uiLavanthor;
+ uint64 uiXevozz;
+ uint64 uiZuramat;
+ uint64 uiCyanigosa;
+ uint64 uiSinclari;
+
+ uint64 uiMoraggCell;
+ uint64 uiErekemCell;
+ uint64 uiErekemLeftGuardCell;
+ uint64 uiErekemRightGuardCell;
+ uint64 uiIchoronCell;
+ uint64 uiLavanthorCell;
+ uint64 uiXevozzCell;
+ uint64 uiZuramatCell;
+ uint64 uiMainDoor;
+
+ uint64 uiActivationCrystal[3];
+
+ uint32 uiActivationTimer;
+
+ uint8 uiWaveCount;
+ uint8 uiLocation;
+ uint8 uiFirstBoss;
+ uint8 uiSecondBoss;
+ uint8 uiRemoveNpc;
+
+ uint8 m_auiEncounter[MAX_ENCOUNTER];
+ uint8 uiCountErekemGuards;
+ uint8 uiCountActivationCrystals;
+
+ bool bActive;
+ bool bWiped;
+
+ std::string str_data;
+
+ void Initialize()
+ {
+ uiMoragg = 0;
+ uiErekem = 0;
+ uiIchoron = 0;
+ uiLavanthor = 0;
+ uiXevozz = 0;
+ uiZuramat = 0;
+ uiCyanigosa = 0;
+ uiSinclari = 0;
+
+ uiMoraggCell = 0;
+ uiErekemCell = 0;
+ uiErekemGuard[0] = 0;
+ uiErekemGuard[1] = 0;
+ uiIchoronCell = 0;
+ uiLavanthorCell = 0;
+ uiXevozzCell = 0;
+ uiZuramatCell = 0;
+ uiMainDoor = 0;
+ uiRemoveNpc = 0;
+
+ uiWaveCount = 0;
+ uiLocation = urand(0,5);
+ uiFirstBoss = 0;
+ uiSecondBoss = 0;
+ uiCountErekemGuards = 0;
+ uiCountActivationCrystals = 0;
+
+ uiActivationTimer = 5000;
+
+ bActive = false;
+ bWiped = false;
+
+ memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+ }
+
+ bool IsEncounterInProgress() const
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS) return true;
+
+ return false;
+ }
+
+ void OnCreatureCreate(Creature* pCreature, bool add)
+ {
+ switch(pCreature->GetEntry())
+ {
+ case CREATURE_XEVOZZ:
+ uiXevozz = pCreature->GetGUID();
+ break;
+ case CREATURE_LAVANTHOR:
+ uiLavanthor = pCreature->GetGUID();
+ break;
+ case CREATURE_ICHORON:
+ uiIchoron = pCreature->GetGUID();
+ break;
+ case CREATURE_ZURAMAT:
+ uiZuramat = pCreature->GetGUID();
+ break;
+ case CREATURE_EREKEM:
+ uiErekem = pCreature->GetGUID();
+ break;
+ case CREATURE_EREKEM_GUARD:
+ if (uiCountErekemGuards < 2)
+ {
+ uiErekemGuard[uiCountErekemGuards++] = pCreature->GetGUID();
+ pCreature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
+ }
+ break;
+ case CREATURE_MORAGG:
+ uiMoragg = pCreature->GetGUID();
+ break;
+ case CREATURE_CYANIGOSA:
+ uiCyanigosa = pCreature->GetGUID();
+ break;
+ case CREATURE_SINCLARI:
+ uiSinclari = pCreature->GetGUID();
+ break;
+ }
+
+ if (add && (pCreature->GetGUID() == uiFirstBoss || pCreature->GetGUID() == uiSecondBoss))
+ {
+ pCreature->AllLootRemovedFromCorpse();
+ pCreature->RemoveLootMode(1);
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
+ {
+ switch(pGo->GetEntry())
+ {
+ case GO_EREKEM_GUARD_1_DOOR:
+ uiErekemLeftGuardCell = pGo->GetGUID();
+ break;
+ case GO_EREKEM_GUARD_2_DOOR:
+ uiErekemRightGuardCell = pGo->GetGUID();
+ break;
+ case GO_EREKEM_DOOR:
+ uiErekemCell = pGo->GetGUID();
+ break;
+ case GO_ZURAMAT_DOOR:
+ uiZuramatCell = pGo->GetGUID();
+ break;
+ case GO_LAVANTHOR_DOOR:
+ uiLavanthorCell = pGo->GetGUID();
+ break;
+ case GO_MORAGG_DOOR:
+ uiMoraggCell = pGo->GetGUID();
+ break;
+ case GO_ICHORON_DOOR:
+ uiIchoronCell = pGo->GetGUID();
+ break;
+ case GO_XEVOZZ_DOOR:
+ uiXevozzCell = pGo->GetGUID();
+ break;
+ case GO_MAIN_DOOR:
+ uiMainDoor = pGo->GetGUID();
+ break;
+ case GO_ACTIVATION_CRYSTAL:
+ if (uiCountActivationCrystals < 3)
+ uiActivationCrystal[uiCountActivationCrystals++] = pGo->GetGUID();
+ break;
+ }
+ }
+
+ void SetData(uint32 type, uint32 data)
+ {
+ switch(type)
+ {
+ case DATA_1ST_BOSS_EVENT:
+ m_auiEncounter[0] = data;
+ if (data == DONE)
+ SaveToDB();
+ break;
+ case DATA_2ND_BOSS_EVENT:
+ m_auiEncounter[1] = data;
+ if (data == DONE)
+ SaveToDB();
+ break;
+ case DATA_CYANIGOSA_EVENT:
+ m_auiEncounter[2] = data;
+ if (data == DONE)
+ {
+ SaveToDB();
+ if (GameObject* pMainDoor = instance->GetGameObject(uiMainDoor))
+ pMainDoor->SetGoState(GO_STATE_ACTIVE);
+ }
+ break;
+ case DATA_WAVE_COUNT:
+ uiWaveCount = data;
+ bActive = true;
+ break;
+ case DATA_REMOVE_NPC:
+ uiRemoveNpc = data;
+ break;
+ }
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ switch(type)
+ {
+ case DATA_1ST_BOSS_EVENT: return m_auiEncounter[0];
+ case DATA_2ND_BOSS_EVENT: return m_auiEncounter[1];
+ case DATA_CYANIGOSA_EVENT: return m_auiEncounter[2];
+ case DATA_WAVE_COUNT: return uiWaveCount;
+ case DATA_REMOVE_NPC: return uiRemoveNpc;
+ }
+
+ return 0;
+ }
+
+ void SpawnPortal()
+ {
+ if (Creature *pSinclari = instance->GetCreature(uiSinclari))
+ if (Creature *pPortal = pSinclari->SummonCreature(CREATURE_TELEPORTATION_PORTAL,PortalLocation[uiLocation],TEMPSUMMON_CORPSE_DESPAWN))
+ uiLocation = (uiLocation+urand(1,5))%6;
+ }
+
+ void StartBossEncounter(uint8 uiBoss, bool bForceRespawn = true)
+ {
+ Creature* pBoss = NULL;
+
+ switch(uiBoss)
+ {
+ case BOSS_MORAGG:
+ HandleGameObject(uiMoraggCell,bForceRespawn);
+ pBoss = instance->GetCreature(uiMoragg);
+ if (pBoss)
+ pBoss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
+ break;
+ case BOSS_EREKEM:
+ HandleGameObject(uiErekemCell, bForceRespawn);
+ HandleGameObject(uiErekemRightGuardCell, bForceRespawn);
+ HandleGameObject(uiErekemLeftGuardCell, bForceRespawn);
+
+ pBoss = instance->GetCreature(uiErekem);
+ if (pBoss)
+ pBoss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
+
+ if (Creature* pGuard1 = instance->GetCreature(uiErekemGuard[0]))
+ {
+ if (bForceRespawn)
+ pGuard1->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
+ else
+ pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ if (Creature* pGuard2 = instance->GetCreature(uiErekemGuard[1]))
+ {
+ if (bForceRespawn)
+ pGuard2->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
+ else
+ pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
+ }
+ break;
+ case BOSS_ICHORON:
+ HandleGameObject(uiIchoronCell,bForceRespawn);
+ pBoss = instance->GetCreature(uiIchoron);
+ if (pBoss)
+ pBoss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
+ break;
+ case BOSS_LAVANTHOR:
+ HandleGameObject(uiLavanthorCell,bForceRespawn);
+ pBoss = instance->GetCreature(uiLavanthor);
+ if (pBoss)
+ pBoss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
+ break;
+ case BOSS_XEVOZZ:
+ HandleGameObject(uiXevozzCell,bForceRespawn);
+ pBoss = instance->GetCreature(uiXevozz);
+ if (pBoss)
+ pBoss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
+ break;
+ case BOSS_ZURAMAT:
+ HandleGameObject(uiZuramatCell,bForceRespawn);
+ pBoss = instance->GetCreature(uiZuramat);
+ if (pBoss)
+ pBoss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
+ break;
+ }
+
+ if (!bForceRespawn && pBoss)
+ {
+ if (pBoss->isDead())
+ {
+ // respawn but avoid to be looted again
+ pBoss->Respawn();
+ pBoss->RemoveLootMode(1);
+ }
+ pBoss->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
+ SetData(DATA_WAVE_COUNT,0);
+ uiWaveCount = 0;
+ }
+ }
+
+ void AddWave()
+ {
+ DoUpdateWorldState(WORLD_STATE_VH, 1);
+ DoUpdateWorldState(WORLD_STATE_VH_WAVE_COUNT, uiWaveCount);
+ DoUpdateWorldState(WORLD_STATE_VH_PRISON_STATE, 100); // TODO
+
+ switch(uiWaveCount)
+ {
+ case 6:
+ if (uiFirstBoss == 0)
+ uiFirstBoss = urand(1,6);
+ StartBossEncounter(uiFirstBoss);
+ break;
+ case 12:
+ if (uiSecondBoss == 0)
+ do
+ {
+ uiSecondBoss = urand(1,6);
+ } while (uiSecondBoss == uiFirstBoss);
+ StartBossEncounter(uiSecondBoss);
+ break;
+ case 18:
+ {
+ Creature *pSinclari = instance->GetCreature(uiSinclari);
+ if (pSinclari)
+ pSinclari->SummonCreature(CREATURE_CYANIGOSA,PortalLocation[0],TEMPSUMMON_DEAD_DESPAWN);
+ break;
+ }
+ case 1:
+ {
+ if (GameObject* pMainDoor = instance->GetGameObject(uiMainDoor))
+ pMainDoor->SetGoState(GO_STATE_READY);
+ }
+ default:
+ if (!bWiped)
+ SpawnPortal();
+ bWiped = false;
+ break;
+ }
+ }
+
+ uint64 GetData64(uint32 identifier)
+ {
+ switch(identifier)
+ {
+ case DATA_MORAGG: return uiMoragg;
+ case DATA_EREKEM: return uiErekem;
+ case DATA_EREKEM_GUARD_1: return uiErekemGuard[0];
+ case DATA_EREKEM_GUARD_2: return uiErekemGuard[1];
+ case DATA_ICHORON: return uiIchoron;
+ case DATA_LAVANTHOR: return uiLavanthor;
+ case DATA_XEVOZZ: return uiXevozz;
+ case DATA_ZURAMAT: return uiZuramat;
+ case DATA_CYANIGOSA: return uiCyanigosa;
+ case DATA_MORAGG_CELL: return uiMoraggCell;
+ case DATA_EREKEM_CELL: return uiErekemCell;
+ case DATA_EREKEM_RIGHT_GUARD_CELL: return uiErekemRightGuardCell;
+ case DATA_EREKEM_LEFT_GUARD_CELL: return uiErekemLeftGuardCell;
+ case DATA_ICHORON_CELL: return uiIchoronCell;
+ case DATA_LAVANTHOR_CELL: return uiLavanthorCell;
+ case DATA_XEVOZZ_CELL: return uiXevozzCell;
+ case DATA_ZURAMAT_CELL: return uiZuramatCell;
+ case DATA_MAIN_DOOR: return uiMainDoor;
+ case DATA_SINCLARI: return uiSinclari;
+ }
+
+ return 0;
+ }
+
+ std::string GetSaveData()
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "V H " << (uint16)m_auiEncounter[0]
+ << " " << (uint16)m_auiEncounter[1]
+ << " " << (uint16)m_auiEncounter[2]
+ << " " << (uint16)uiFirstBoss
+ << " " << (uint16)uiSecondBoss;
+
+ str_data = saveStream.str();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return str_data;
+ }
+
+ void Load(const char* in)
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+ uint16 data0, data1, data2, data3, data4;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4;
+
+ if (dataHead1 == 'V' && dataHead2 == 'H')
+ {
+ m_auiEncounter[0] = data0;
+ m_auiEncounter[1] = data1;
+ m_auiEncounter[2] = data2;
+
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ if (m_auiEncounter[i] == IN_PROGRESS)
+ m_auiEncounter[i] = NOT_STARTED;
+
+ uiFirstBoss = data3;
+ uiSecondBoss = data4;
+ } else OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+
+ bool CheckWipe()
+ {
+ Map::PlayerList const &players = instance->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ {
+ Player* pPlayer = itr->getSource();
+ if (pPlayer->isGameMaster())
+ continue;
+
+ if (pPlayer->isAlive())
+ return false;
+ }
+
+ return true;
+ }
+
+ void Update(uint32 diff)
+ {
+ if (!instance->HavePlayers())
+ return;
+
+ if (bActive)
+ {
+ if (uiActivationTimer < diff)
+ {
+ AddWave();
+ bActive = false;
+ uiActivationTimer = 5000;
+ } else uiActivationTimer -= diff;
+ }
+
+ if (GameObject* pMainDoor = instance->GetGameObject(uiMainDoor))
+ if (pMainDoor->GetGoState() != GO_STATE_ACTIVE && CheckWipe())
+ {
+ SetData(DATA_REMOVE_NPC, 1);
+ StartBossEncounter(uiFirstBoss, false);
+ StartBossEncounter(uiSecondBoss, false);
+ bWiped = true;
+ if (Creature* pSinclari = instance->GetCreature(uiSinclari))
+ {
+ pSinclari->DisappearAndDie();
+ pSinclari->Respawn(true);
+ }
+
+ if (GameObject* pMainDoor = instance->GetGameObject(uiMainDoor))
+ pMainDoor->SetGoState(GO_STATE_ACTIVE);
+ SetData(DATA_WAVE_COUNT, 0);
+ }
+ }
+};
+
+InstanceData* GetInstanceData_instance_violet_hold(Map* pMap)
+{
+ return new instance_violet_hold(pMap);
+}
+
+void AddSC_instance_violet_hold()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "instance_violet_hold";
+ newscript->GetInstanceData = &GetInstanceData_instance_violet_hold;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/violet_hold/violet_hold.cpp b/src/server/scripts/northrend/violet_hold/violet_hold.cpp
new file mode 100644
index 00000000000..49883b5dbf3
--- /dev/null
+++ b/src/server/scripts/northrend/violet_hold/violet_hold.cpp
@@ -0,0 +1,274 @@
+#include "ScriptedPch.h"
+#include "violet_hold.h"
+
+#define GOSSIP_START_EVENT "Get your people to safety, we'll keep the Blue Dragonflight's forces at bay."
+#define GOSSIP_ITEM_1 "Activate the crystals when we get in trouble, right"
+#define SPAWN_TIME 20000
+
+enum PortalCreatures
+{
+ CREATURE_AZURE_INVADER = 30661,
+ CREATURE_AZURE_SPELLBREAKER = 30662,
+ CREATURE_AZURE_BINDER = 30663,
+ CREATURE_AZURE_MAGE_SLAYER = 30664,
+ CREATURE_AZURE_CAPTAIN = 30666,
+ CREATURE_AZURE_SORCEROR = 30667,
+ CREATURE_AZURE_RAIDER = 30668,
+ CREATURE_AZURE_STALKER = 32191
+};
+
+enum Spells
+{
+ SPELL_PORTAL_CHANNEL = 58012
+};
+
+enum eSinclari
+{
+ NPC_VIOLET_HOLD_GUARD = 30659,
+
+ SAY_SINCLARI_1 = -1608045,
+};
+
+const Position DoorPosition = { 1828.300049, 797.309021, 46.135502, 1.48353};
+const Position MovePosition = { 1806.955566, 803.851807, 44.363323};
+
+struct npc_sinclariAI : public ScriptedAI
+{
+ npc_sinclariAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = pCreature->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ uint8 uiPhase;
+ uint32 uiTimer;
+
+ void Reset()
+ {
+ uiPhase = 0;
+ uiTimer = 0;
+
+ me->SetVisibility(VISIBILITY_ON);
+ me->SetReactState(REACT_AGGRESSIVE);
+
+ std::list<Creature*> GuardList;
+ me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
+ if (!GuardList.empty())
+ {
+ for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
+ {
+ if (Creature* pGuard = *itr)
+ {
+ pGuard->DisappearAndDie();
+ pGuard->Respawn();
+ pGuard->SetVisibility(VISIBILITY_ON);
+ pGuard->SetReactState(REACT_AGGRESSIVE);
+ }
+ }
+ }
+ }
+
+ void MovementInform(uint32 uiType, uint32 /*uiId*/)
+ {
+ if (uiType != POINT_MOTION_TYPE)
+ return;
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_WAVE_COUNT,1);
+ pInstance->SetData(DATA_REMOVE_NPC,0); // might not have been reset after a wipe on a boss.
+ }
+
+ //She should not be despawned, she will be used by the instance to summon some npcs
+ me->SetVisibility(VISIBILITY_OFF);
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ ScriptedAI::UpdateAI(uiDiff);
+
+ if (uiPhase)
+ {
+ if (uiTimer <= uiDiff)
+ {
+ switch(uiPhase)
+ {
+ case 1:
+ DoScriptText(SAY_SINCLARI_1, me);
+ uiTimer = 4000;
+ uiPhase = 2;
+ break;
+ case 2:
+ {
+ std::list<Creature*> GuardList;
+ me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
+ if (!GuardList.empty())
+ for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
+ {
+ if (Creature* pGuard = *itr)
+ {
+ pGuard->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ pGuard->GetMotionMaster()->MovePoint(0, MovePosition);
+ }
+ }
+ uiTimer = 6000;
+ uiPhase = 3;
+ break;
+ }
+ case 3:
+ {
+ std::list<Creature*> GuardList;
+ me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
+ if (!GuardList.empty())
+ for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
+ {
+ if (Creature* pGuard = *itr)
+ {
+ pGuard->SetVisibility(VISIBILITY_OFF);
+ pGuard->SetReactState(REACT_PASSIVE);
+ }
+ }
+ uiTimer = 2000;
+ uiPhase = 4;
+ break;
+ }
+ case 4:
+ me->GetMotionMaster()->MovePoint(0, MovePosition);
+ uiTimer = 0;
+ uiPhase = 0;
+ break;
+ }
+ }
+ else uiTimer -= uiDiff;
+ }
+
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_sinclari(Creature* pCreature)
+{
+ return new npc_sinclariAI(pCreature);
+}
+
+bool GossipHello_npc_sinclari(Player* pPlayer, Creature* pCreature)
+{
+ ScriptedInstance* pInstance = pCreature->GetInstanceData();
+ if (pInstance && pInstance->GetData(DATA_CYANIGOSA_EVENT) != DONE && pInstance->GetData(DATA_WAVE_COUNT) == 0 && pPlayer)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT,GOSSIP_ITEM_1,GOSSIP_SENDER_MAIN,GOSSIP_ACTION_INFO_DEF+2);
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT,GOSSIP_START_EVENT,GOSSIP_SENDER_MAIN,GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(13853, pCreature->GetGUID());
+ }else
+ pPlayer->SEND_GOSSIP_MENU(13910, pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_sinclari(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ switch(uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ if (pPlayer)
+ pPlayer->CLOSE_GOSSIP_MENU();
+ CAST_AI(npc_sinclariAI, (pCreature->AI()))->uiPhase = 1;
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->SEND_GOSSIP_MENU(13854, pCreature->GetGUID());
+ break;
+ }
+ return true;
+}
+
+struct npc_teleportation_portalAI : public ScriptedAI
+{
+ npc_teleportation_portalAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ uint32 uiSpawnTimer;
+ bool bPortalGuardianOrKeeperSpawn;
+
+ ScriptedInstance *pInstance;
+
+ void Reset()
+ {
+ uiSpawnTimer = 10000;
+ bPortalGuardianOrKeeperSpawn = false;
+ }
+
+ void EnterCombat(Unit * /*who*/) {}
+ void MoveInLineOfSight(Unit * /*who*/) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (pInstance && pInstance->GetData(DATA_REMOVE_NPC) == 1)
+ {
+ me->ForcedDespawn();
+ pInstance->SetData(DATA_REMOVE_NPC, 0);
+ }
+
+ if (uiSpawnTimer <= diff)
+ {
+ if (bPortalGuardianOrKeeperSpawn)
+ {
+ uint8 k = pInstance->GetData(DATA_WAVE_COUNT) < 12 ? 2 : 3;
+ for (uint8 i = 0; i < k; ++i)
+ {
+ uint32 entry = RAND(CREATURE_AZURE_CAPTAIN,CREATURE_AZURE_RAIDER,CREATURE_AZURE_STALKER,CREATURE_AZURE_SORCEROR);
+ if (Creature* pSummon = DoSummon(entry, me, 2.0f, 30000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT))
+ pSummon->GetMotionMaster()->MovePoint(0, DoorPosition);
+ }
+ }
+ else
+ {
+ bPortalGuardianOrKeeperSpawn = true;
+ uint32 entry = RAND(CREATURE_PORTAL_GUARDIAN, CREATURE_PORTAL_KEEPER);
+ if (Creature *pPortalKeeper = DoSummon(entry, me, 2.0f, 0, TEMPSUMMON_DEAD_DESPAWN))
+ me->CastSpell(pPortalKeeper, SPELL_PORTAL_CHANNEL, false);
+ }
+ uiSpawnTimer = SPAWN_TIME;
+ } else uiSpawnTimer -= diff;
+
+ if (bPortalGuardianOrKeeperSpawn && !me->IsNonMeleeSpellCasted(false))
+ {
+ me->Kill(me, false);
+ me->RemoveCorpse();
+ return;
+ }
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_WAVE_COUNT,pInstance->GetData(DATA_WAVE_COUNT)+1);
+ }
+};
+
+CreatureAI* GetAI_npc_teleportation_portal(Creature *pCreature)
+{
+ return new npc_teleportation_portalAI(pCreature);
+}
+
+void AddSC_violet_hold()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_sinclari_vh";
+ newscript->GetAI = &GetAI_npc_sinclari;
+ newscript->pGossipHello = &GossipHello_npc_sinclari;
+ newscript->pGossipSelect = &GossipSelect_npc_sinclari;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_teleportation_portal_vh";
+ newscript->GetAI = &GetAI_npc_teleportation_portal;
+ newscript->RegisterSelf();
+}
diff --git a/src/server/scripts/northrend/violet_hold/violet_hold.h b/src/server/scripts/northrend/violet_hold/violet_hold.h
new file mode 100644
index 00000000000..4476d5e823a
--- /dev/null
+++ b/src/server/scripts/northrend/violet_hold/violet_hold.h
@@ -0,0 +1,71 @@
+#ifndef DEF_VIOLET_HOLD_H
+#define DEF_VIOLET_HOLD_H
+
+enum Creatures
+{
+ CREATURE_TELEPORTATION_PORTAL = 31011,
+ CREATURE_PORTAL_GUARDIAN = 30660,
+ CREATURE_PORTAL_KEEPER = 30695,
+ CREATURE_XEVOZZ = 29266,
+ CREATURE_LAVANTHOR = 29312,
+ CREATURE_ICHORON = 29313,
+ CREATURE_ZURAMAT = 29314,
+ CREATURE_EREKEM = 29315,
+ CREATURE_EREKEM_GUARD = 29395,
+ CREATURE_MORAGG = 29316,
+ CREATURE_CYANIGOSA = 31134,
+ CREATURE_SINCLARI = 30658
+};
+
+enum Data
+{
+ DATA_1ST_BOSS_EVENT,
+ DATA_2ND_BOSS_EVENT,
+ DATA_CYANIGOSA_EVENT,
+ DATA_WAVE_COUNT,
+ DATA_REMOVE_NPC
+};
+
+enum Data64
+{
+ DATA_MORAGG,
+ DATA_EREKEM,
+ DATA_EREKEM_GUARD_1,
+ DATA_EREKEM_GUARD_2,
+ DATA_ICHORON,
+ DATA_LAVANTHOR,
+ DATA_XEVOZZ,
+ DATA_ZURAMAT,
+ DATA_CYANIGOSA,
+ DATA_MORAGG_CELL,
+ DATA_EREKEM_CELL,
+ DATA_EREKEM_LEFT_GUARD_CELL,
+ DATA_EREKEM_RIGHT_GUARD_CELL,
+ DATA_ICHORON_CELL,
+ DATA_LAVANTHOR_CELL,
+ DATA_XEVOZZ_CELL,
+ DATA_ZURAMAT_CELL,
+ DATA_MAIN_DOOR,
+ DATA_SINCLARI
+};
+
+enum Bosses
+{
+ BOSS_NONE, // 0 used as marker for not yet randomized
+ BOSS_MORAGG,
+ BOSS_EREKEM,
+ BOSS_ICHORON,
+ BOSS_LAVANTHOR,
+ BOSS_XEVOZZ,
+ BOSS_ZURAMAT,
+ BOSS_CYANIGOSA
+};
+
+enum VHWorldStates
+{
+ WORLD_STATE_VH = 3816,
+ WORLD_STATE_VH_PRISON_STATE = 3815,
+ WORLD_STATE_VH_WAVE_COUNT = 3810,
+};
+
+#endif
diff --git a/src/server/scripts/northrend/zuldrak.cpp b/src/server/scripts/northrend/zuldrak.cpp
new file mode 100644
index 00000000000..a821ea4ffae
--- /dev/null
+++ b/src/server/scripts/northrend/zuldrak.cpp
@@ -0,0 +1,1403 @@
+/*
+ * Copyright (C) 2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "ScriptedEscortAI.h"
+
+/*####
+## npc_drakuru_shackles
+####*/
+
+enum eDrakuruShackles
+{
+ SPELL_LEFT_CHAIN = 59951,
+ SPELL_RIGHT_CHAIN = 59952,
+ SPELL_UNLOCK_SHACKLE = 55083,
+ SPELL_FREE_RAGECLAW = 55223,
+
+ NPC_RAGECLAW = 29686
+};
+
+struct npc_drakuru_shacklesAI : public ScriptedAI
+{
+ npc_drakuru_shacklesAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint64 RageclawGUID;
+
+ void Reset()
+ {
+ RageclawGUID = 0;
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+ float x, y, z;
+ me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, 0.1f);
+
+ if (Unit* summon = me->SummonCreature(NPC_RAGECLAW, x, y, z,
+ 0, TEMPSUMMON_DEAD_DESPAWN, 1000))
+ {
+ RageclawGUID = summon->GetGUID();
+ LockRageclaw();
+ }
+ }
+
+ void LockRageclaw()
+ {
+ Unit *Rageclaw = Unit::GetCreature(*me, RageclawGUID);
+ // pointer check not needed
+ me->SetInFront(Rageclaw);
+ Rageclaw->SetInFront(me);
+
+ DoCast(Rageclaw, SPELL_LEFT_CHAIN, true);
+ DoCast(Rageclaw, SPELL_RIGHT_CHAIN, true);
+ }
+
+ void UnlockRageclaw(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ Creature *Rageclaw = Unit::GetCreature(*me, RageclawGUID);
+ // pointer check not needed
+ DoCast(Rageclaw, SPELL_FREE_RAGECLAW, true);
+
+ me->setDeathState(DEAD);
+ }
+
+ void SpellHit(Unit* pCaster, const SpellEntry* pSpell)
+ {
+ if (pSpell->Id == SPELL_UNLOCK_SHACKLE)
+ {
+ if (Creature *Rageclaw = Unit::GetCreature(*me, RageclawGUID))
+ UnlockRageclaw(pCaster);
+ else
+ me->setDeathState(JUST_DIED);
+ }
+ }
+};
+
+
+CreatureAI* GetAI_npc_drakuru_shackles(Creature* pCreature)
+{
+ return new npc_drakuru_shacklesAI (pCreature);
+}
+
+/*####
+## npc_captured_rageclaw
+####*/
+
+enum eRageclaw
+{
+ SPELL_UNSHACKLED = 55085,
+ SPELL_KNEEL = 39656
+};
+
+const char * SAY_RAGECLAW_1 = "I poop on you, trollses!";
+const char * SAY_RAGECLAW_2 = "ARRRROOOOGGGGAAAA!";
+const char * SAY_RAGECLAW_3 = "No more mister nice wolvar!";
+
+#define SAY_RAGECLAW RAND(SAY_RAGECLAW_1,SAY_RAGECLAW_2,SAY_RAGECLAW_3)
+
+struct npc_captured_rageclawAI : public ScriptedAI
+{
+ npc_captured_rageclawAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint32 DespawnTimer;
+ bool Despawn;
+
+ void Reset()
+ {
+ Despawn = false;
+ DespawnTimer = 0;
+ me->setFaction(35);
+ DoCast(me, SPELL_KNEEL, true); // Little Hack for kneel - Thanks Illy :P
+ }
+
+ void MoveInLineOfSight(Unit * /*who*/){}
+
+ void SpellHit(Unit* /*pCaster*/, const SpellEntry* pSpell)
+ {
+ if (pSpell->Id == SPELL_FREE_RAGECLAW)
+ {
+ me->RemoveAurasDueToSpell(SPELL_LEFT_CHAIN);
+
+ me->RemoveAurasDueToSpell(SPELL_RIGHT_CHAIN);
+
+ me->RemoveAurasDueToSpell(SPELL_KNEEL);
+
+ me->setFaction(me->GetCreatureInfo()->faction_H);
+
+ DoCast(me, SPELL_UNSHACKLED, true);
+ me->MonsterSay(SAY_RAGECLAW, LANG_UNIVERSAL, NULL);
+ me->GetMotionMaster()->MoveRandom(10);
+
+ DespawnTimer = 10000;
+ Despawn = true;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (UpdateVictim())
+ {
+ DoMeleeAttackIfReady();
+ return;
+ }
+
+ if (!Despawn)
+ return;
+
+ if (DespawnTimer <= uiDiff)
+ me->DisappearAndDie();
+ else DespawnTimer -= uiDiff;
+ }
+};
+
+CreatureAI* GetAI_npc_captured_rageclaw(Creature* pCreature)
+{
+ return new npc_captured_rageclawAI (pCreature);
+}
+
+/*####
+## npc_gymer
+####*/
+
+#define GOSSIP_ITEM_G "I'm ready, Gymer. Let's go!"
+
+enum eGymer
+{
+ QUEST_STORM_KING_VENGEANCE = 12919,
+ SPELL_GYMER = 55568
+};
+
+bool GossipHello_npc_gymer(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_STORM_KING_VENGEANCE) == QUEST_STATUS_INCOMPLETE)
+ {
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_G, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ pPlayer->SEND_GOSSIP_MENU(13640, pCreature->GetGUID());
+ }
+
+ return true;
+}
+
+bool GossipSelect_npc_gymer(Player* pPlayer, Creature* /*pCreature*/, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
+ {
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pPlayer->CastSpell(pPlayer, SPELL_GYMER, true);
+ }
+
+ return true;
+}
+
+/*####
+## npc_gurgthock
+####*/
+
+enum eGurgthock
+{
+ QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON = 12935,
+ QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER = 12936,
+ QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2 = 12954,
+ QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1 = 12932,
+ QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR = 12933,
+ QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND = 12934,
+
+ NPC_ORINOKO_TUSKBREAKER = 30020,
+ NPC_KORRAK_BLOODRAGER = 30023,
+ NPC_YGGDRAS = 30014,
+ NPC_STINKBEARD = 30017,
+ NPC_AZ_BARIN = 30026, // air
+ NPC_DUKE_SINGEN = 30019, // fire
+ NPC_ERATHIUS = 30025, // earth
+ NPC_GARGORAL = 30024, // water
+ NPC_FIEND_WATER = 30044,
+ NPC_FIEND_AIR = 30045,
+ NPC_FIEND_FIRE = 30042,
+ NPC_FIEND_EARTH = 30043,
+
+ SAY_QUEST_ACCEPT_TUSKARRMAGEDON = -1571031,
+ SAY_QUEST_ACCEPT_KORRAK_1 = -1571033,
+ SAY_QUEST_ACCEPT_KORRAK_2 = -1571034,
+ SAY_QUEST_ACCEPT_MAGNATAUR = -1571035,
+
+ EMOTE_YGGDRAS_SPAWN = -1571039,
+ SAY_STINKBEARD_SPAWN = -1571040,
+ SAY_GURGTHOCK_ELEMENTAL_SPAWN = -1571041,
+
+ SPELL_CRASHING_WAVE = 55909, // water
+ SPELL_SHOCKWAVE = 55918, // earth
+ SPELL_BLAST_OF_AIR = 55912, // air
+ SPELL_MAGMA_WAVE = 55916, // fire
+
+ SPELL_ORB_OF_WATER = 55888, // fiend of water spell
+ SPELL_ORB_OF_STORMS = 55882, // fiend of air spell
+ SPELL_BOULDER = 55886, // fiend of earth spell
+ SPELL_ORB_OF_FLAME = 55872, // fiend of fire spell
+};
+
+struct BossAndAdd
+{
+ uint32 uiBoss;
+ uint32 uiAdd;
+ uint32 uiSpell;
+ uint32 uiAddSpell;
+};
+
+static BossAndAdd Boss[]=
+{
+ {NPC_GARGORAL,NPC_FIEND_WATER,SPELL_CRASHING_WAVE,SPELL_ORB_OF_WATER},
+ {NPC_AZ_BARIN,NPC_FIEND_AIR,SPELL_BLAST_OF_AIR,SPELL_ORB_OF_STORMS},
+ {NPC_DUKE_SINGEN,NPC_FIEND_FIRE,SPELL_MAGMA_WAVE,SPELL_ORB_OF_FLAME},
+ {NPC_ERATHIUS,NPC_FIEND_EARTH,SPELL_SHOCKWAVE,SPELL_BOULDER},
+};
+
+const Position SpawnPosition[] =
+{
+ {5754.692, -2939.46, 286.276123, 5.156380}, // stinkbeard || orinoko || korrak
+ {5762.054199, -2954.385010, 273.826955, 5.108289}, //yggdras
+ {5776.855, -2989.77979, 272.96814, 5.194} // elementals
+};
+
+const Position AddSpawnPosition[] =
+{
+ {5722.487, -3010.75, 312.751648, 0.478}, // caster location
+ {5724.983, -2969.89551, 286.359619, 0.478},
+ {5733.76025, -3000.34644, 286.359619, 0.478},
+ {5739.8125, -2981.524, 290.7671, 0.478}, // caster location
+ {5742.101, -2950.75586, 286.2643, 5.21},
+ {5743.305, -3011.29736, 290.7671, 0.478}, // caster location
+ {5744.417, -3025.528, 286.35965, 0.478},
+ {5763.189, -3029.67529, 290.7671, 0.478},
+ {5769.401, -2935.121, 286.335754, 5.21},
+ {5793.061, -2934.593, 286.359619, 3.53},
+ {5797.32129, -2955.26855, 290.7671, 3.53}, // caster location
+ {5813.94531, -2956.74683, 286.359619, 3.53},
+ {5816.85547, -2974.476, 290.7671, 3.53}, // caster location
+ {5820.30859, -3002.83716, 290.7671, 3.53}, // caster location
+ {5828.50244, -2981.737, 286.359619, 3.53},
+ {5828.899, -2960.15479, 312.751648, 3.53}, // caster location
+};
+
+
+struct npc_gurgthockAI : public ScriptedAI
+{
+ npc_gurgthockAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint64 SummonGUID;
+ uint64 uiPlayerGUID;
+
+ uint32 uiTimer;
+ uint32 uiPhase;
+ uint32 uiRemoveFlagTimer;
+ uint32 uiQuest;
+ uint8 uiBossRandom;
+
+ bool bRemoveFlag;
+
+ void Reset()
+ {
+ SummonGUID = 0;
+ uiPlayerGUID = 0;
+
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ uiTimer = 0;
+ uiPhase = 0;
+ uiQuest = 0;
+ uiRemoveFlagTimer = 5000;
+
+ uiBossRandom = 0;
+
+ bRemoveFlag = false;
+ }
+
+ void SetGUID(const uint64 &guid, int32 id)
+ {
+ uiPlayerGUID = guid;
+ }
+
+ void SetData(uint32 uiId, uint32 uiValue)
+ {
+ bRemoveFlag = true;
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+
+ switch(uiId)
+ {
+ case 1:
+ switch(uiValue)
+ {
+ case QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON:
+ DoScriptText(SAY_QUEST_ACCEPT_TUSKARRMAGEDON, me);
+ uiPhase = 1;
+ uiTimer = 4000;
+ break;
+ case QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER:
+ DoScriptText(SAY_QUEST_ACCEPT_KORRAK_1, me);
+ uiPhase = 3;
+ uiTimer = 3000;
+ break;
+ case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2:
+ case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1:
+ uiPhase = 6;
+ uiTimer = 3000;
+ break;
+ case QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR:
+ uiTimer = 5000;
+ uiPhase = 7;
+ break;
+ case QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND:
+ uiTimer = 2000;
+ uiPhase = 12;
+ break;
+ }
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ ScriptedAI::UpdateAI(uiDiff);
+
+ if (bRemoveFlag)
+ if (uiRemoveFlagTimer <= uiDiff)
+ {
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
+ bRemoveFlag = false;
+
+ uiRemoveFlagTimer = 10000;
+ } else uiRemoveFlagTimer -= uiDiff;
+
+ if (uiPhase)
+ {
+ Player* pPlayer = me->GetPlayer(uiPlayerGUID);
+
+ if (uiTimer <= uiDiff)
+ {
+ switch(uiPhase)
+ {
+ case 1:
+ if (Creature* pSummon = me->SummonCreature(NPC_ORINOKO_TUSKBREAKER, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000))
+ SummonGUID = pSummon->GetGUID();
+ uiPhase = 2;
+ uiTimer = 4000;
+ break;
+ case 2:
+ if (Creature* pSummon = Unit::GetCreature(*me, SummonGUID))
+ pSummon->GetMotionMaster()->MoveJump(5776.319824, -2981.005371, 273.100037, 10.0f, 20.0f);
+ uiPhase = 0;
+ SummonGUID = 0;
+ break;
+ case 3:
+ DoScriptText(SAY_QUEST_ACCEPT_KORRAK_2, me);
+ uiTimer = 3000;
+ uiPhase = 4;
+ break;
+ case 4:
+ if (Creature* pSummon = me->SummonCreature(NPC_KORRAK_BLOODRAGER, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000))
+ SummonGUID = pSummon->GetGUID();
+ uiTimer = 3000;
+ uiPhase = 0;
+ break;
+ case 6:
+ {
+ if (!pPlayer)
+ return;
+
+ std::string sText = ("The grand Amphitheater of Anguish awaits, " + std::string(pPlayer->GetName()) + ". Remember, once a battle starts you have to stay in the area. WIN OR DIE!");
+
+ me->MonsterSay(sText.c_str(),LANG_UNIVERSAL,0);
+ uiTimer = 5000;
+ uiPhase = 9;
+ }
+ break;
+ case 7:
+ {
+ if (!pPlayer)
+ return;
+
+ std::string sText = ("Prepare to make you stand, " + std::string(pPlayer->GetName()) + "! Get in the Amphitheater and stand ready! Remember, you and your opponent must stay in the arena at all times or you will be disqualified!");
+ me->MonsterSay(sText.c_str(),LANG_UNIVERSAL,0);
+ uiTimer = 3000;
+ uiPhase = 8;
+ }
+ break;
+ case 8:
+ DoScriptText(SAY_QUEST_ACCEPT_MAGNATAUR, me);
+ uiTimer = 5000;
+ uiPhase = 11;
+ break;
+ case 9:
+ {
+ if (!pPlayer)
+ return;
+
+ std::string sText = ("Here we are once again, ladies and gentlemen. The epic struggle between life and death in the Amphitheater of Anguish! For this round we have " + std::string(pPlayer->GetName()) + " versus the hulking jormungar, Yg... Yggd? Yggdoze? Who comes up with these names?! " + std::string(pPlayer->GetName()) + " versus big worm!");
+ me->MonsterYell(sText.c_str(),LANG_UNIVERSAL,0);
+ uiTimer = 10000;
+ uiPhase = 10;
+ }
+ break;
+ case 10:
+ me->SummonCreature(NPC_YGGDRAS, SpawnPosition[1], TEMPSUMMON_CORPSE_DESPAWN, 1000);
+ DoScriptText(EMOTE_YGGDRAS_SPAWN,me);
+ uiPhase = 0;
+ break;
+ case 11:
+ if (Creature* pCreature = me->SummonCreature(NPC_STINKBEARD, SpawnPosition[0], TEMPSUMMON_CORPSE_DESPAWN, 1000))
+ DoScriptText(SAY_STINKBEARD_SPAWN,pCreature);
+ uiPhase = 0;
+ break;
+ case 12:
+ {
+ if (!pPlayer)
+ return;
+
+ std::string sText = ("Prepare to make you stand, " + std::string(pPlayer->GetName()) + "! Get in the Amphitheater and stand ready! Remember, you and your opponent must stay in the arena at all times or you will be disqualified!");
+ me->MonsterSay(sText.c_str(),LANG_UNIVERSAL,0);
+ uiTimer = 5000;
+ uiPhase = 13;
+ }
+ break;
+ case 13:
+ DoScriptText(SAY_GURGTHOCK_ELEMENTAL_SPAWN,me);
+ uiTimer = 3000;
+ uiPhase = 14;
+ break;
+ case 14:
+ uiBossRandom = urand(0,3);
+ if (Creature* pCreature = me->SummonCreature(Boss[uiBossRandom].uiBoss,SpawnPosition[2],TEMPSUMMON_CORPSE_DESPAWN, 1000))
+ pCreature->AI()->SetData(1,uiBossRandom);
+ uiPhase = 0;
+ break;
+ }
+ }else uiTimer -= uiDiff;
+ }
+ }
+};
+
+bool QuestAccept_npc_gurgthock(Player* pPlayer, Creature* pCreature, Quest const* pQuest)
+{
+ switch (pQuest->GetQuestId())
+ {
+ case QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON:
+ pCreature->AI()->SetData(1, pQuest->GetQuestId());
+ break;
+ case QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER:
+ pCreature->AI()->SetData(1, pQuest->GetQuestId());
+ break;
+ case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2:
+ case QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1:
+ pCreature->AI()->SetData(1, pQuest->GetQuestId());
+ break;
+ case QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR:
+ pCreature->AI()->SetData(1, pQuest->GetQuestId());
+ break;
+ case QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND:
+ pCreature->AI()->SetData(1, pQuest->GetQuestId());
+ break;
+ }
+
+ pCreature->AI()->SetGUID(pPlayer->GetGUID());
+
+ return false;
+}
+
+CreatureAI* GetAI_npc_gurgthock(Creature* pCreature)
+{
+ return new npc_gurgthockAI(pCreature);
+}
+
+/*####
+## npc_orinoko_tuskbreaker
+####*/
+
+enum eOrinokoTuskbreaker
+{
+ SPELL_BATTLE_SHOUT = 32064,
+ SPELL_FISHY_SCENT = 55937,
+ SPELL_IMPALE = 55929,
+ SPELL_SUMMON_WHISKER = 55946,
+
+ NPC_WHISKER = 30113,
+ NPC_HUNGRY_PENGUIN = 30110,
+
+ SAY_CALL_FOR_HELP = -1571032
+};
+
+struct npc_orinoko_tuskbreakerAI : public ScriptedAI
+{
+ npc_orinoko_tuskbreakerAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ bool bSummoned;
+ bool bBattleShout;
+ bool bFishyScent;
+
+ uint32 uiBattleShoutTimer;
+ uint32 uiFishyScentTimer;
+
+ uint64 AffectedGUID;
+ uint64 uiWhisker;
+
+ void Reset()
+ {
+ bSummoned = false;
+ bBattleShout = false;
+ bFishyScent = false;
+ uiBattleShoutTimer = 0;
+ uiFishyScentTimer = 20000;
+ uiWhisker = 0;
+ AffectedGUID = 0;
+ }
+
+ void EnterEvadeMode()
+ {
+ if (Creature *pWhisker = me->GetCreature(*me, uiWhisker))
+ pWhisker->RemoveFromWorld();
+ }
+
+ void MovementInform(uint32 uiType, uint32 uiId)
+ {
+ if (uiType != POINT_MOTION_TYPE)
+ return;
+
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->SetHomePosition(me->GetPositionX(),me->GetPositionY(),me->GetPositionZ(),me->GetOrientation());
+ uiBattleShoutTimer = 7000;
+ }
+
+ void EnterCombat(Unit* pWho)
+ {
+ DoCast(pWho, SPELL_IMPALE);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (!bBattleShout && uiBattleShoutTimer <= uiDiff)
+ {
+ DoCast(me, SPELL_BATTLE_SHOUT);
+ bBattleShout = true;
+ } else uiBattleShoutTimer -= uiDiff;
+
+ if (uiFishyScentTimer <= uiDiff)
+ {
+ if (Unit *pAffected = SelectUnit(SELECT_TARGET_RANDOM,0))
+ {
+ DoCast(pAffected, SPELL_FISHY_SCENT);
+ AffectedGUID = pAffected->GetGUID();
+ }
+ uiFishyScentTimer = 20000;
+ } else uiFishyScentTimer -= uiDiff;
+
+ if (!bSummoned && me->GetHealth()*100 / me->GetMaxHealth() <= 50)
+ {
+ DoScriptText(SAY_CALL_FOR_HELP ,me);
+ //DoCast(me->getVictim(), SPELL_SUMMON_WHISKER); petai is not working correctly???
+
+ if (Creature *pWhisker = me->SummonCreature(NPC_WHISKER, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0))
+ uiWhisker = pWhisker->GetGUID();
+ bSummoned = true;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustSummoned(Creature* pSummon)
+ {
+ switch(pSummon->GetEntry())
+ {
+ case NPC_WHISKER:
+ pSummon->AI()->AttackStart(me->getVictim());
+ break;
+ case NPC_HUNGRY_PENGUIN:
+ if (Unit *pAffected = Unit::GetUnit(*me, AffectedGUID))
+ {
+ if (pAffected->isAlive())
+ pSummon->AI()->AttackStart(pAffected);
+ }
+ break;
+ }
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (uiWhisker)
+ if (Creature *pWhisker = me->GetCreature(*me, uiWhisker))
+ pWhisker->RemoveFromWorld();
+
+ if (pKiller->GetTypeId() == TYPEID_PLAYER)
+ pKiller->GetCharmerOrOwnerPlayerOrPlayerItself()->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_TUSKARRMAGEDDON, pKiller);
+
+ }
+};
+
+CreatureAI* GetAI_npc_orinoko_tuskbreaker(Creature* pCreature)
+{
+ return new npc_orinoko_tuskbreakerAI(pCreature);
+}
+
+/*####
+## npc_korrak_bloodrager
+####*/
+
+enum eKorrakBloodrager
+{
+ SPELL_GROW = 55948,
+ SPELL_CHARGE = 24193,
+ SPELL_UPPERCUT = 30471,
+ SPELL_ENRAGE = 42745
+};
+
+struct npc_korrak_bloodragerAI : public npc_escortAI
+{
+ npc_korrak_bloodragerAI(Creature* pCreature) : npc_escortAI(pCreature)
+ {
+ Start(true,true, 0, NULL);
+ SetDespawnAtEnd(false);
+ }
+
+ uint32 uiChargeTimer;
+ uint32 uiUppercutTimer;
+
+ bool bEnrage;
+
+ void Reset()
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetReactState(REACT_PASSIVE);
+ uiChargeTimer = 15000;
+ uiUppercutTimer = 12000;
+ bEnrage = false;
+ }
+
+ void WaypointReached(uint32 uiI)
+ {
+ switch(uiI)
+ {
+ case 6:
+ me->SetHomePosition(me->GetPositionX(),me->GetPositionY(),me->GetPositionZ(), 0);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ break;
+ }
+ }
+
+ void EnterCombat(Unit* /*pWho*/)
+ {
+ DoCast(me, SPELL_GROW);
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ npc_escortAI::UpdateAI(uiDiff);
+
+ if (!UpdateVictim())
+ return;
+
+ if (uiUppercutTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_NEAREST, 0))
+ DoCast(pTarget, SPELL_UPPERCUT);
+ uiUppercutTimer = 12000;
+ } else uiUppercutTimer -= uiDiff;
+
+ if (uiChargeTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_FARTHEST, 0))
+ DoCast(pTarget, SPELL_CHARGE);
+ uiChargeTimer = 15000;
+ } else uiChargeTimer -= uiDiff;
+
+ if (!bEnrage && me->GetHealth()*100 / me->GetMaxHealth() <= 20)
+ {
+ DoCast(me, SPELL_ENRAGE);
+ bEnrage = true;
+ }
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (Player* pPlayer = pKiller->GetCharmerOrOwnerPlayerOrPlayerItself())
+ pPlayer->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_KORRAK_BLOODRAGER, pKiller);
+ }
+};
+
+CreatureAI* GetAI_npc_korrak_bloodrager(Creature* pCreature)
+{
+ return new npc_korrak_bloodragerAI(pCreature);
+}
+
+/*####
+## npc_yggdras
+####*/
+
+enum eYggdras
+{
+ SPELL_CLEAVE = 40504,
+ SPELL_CORRODE_FLESH = 57076,
+ SPELL_JORMUNGAR_SPAWN = 55859
+};
+
+struct npc_yggdrasAI : public ScriptedAI
+{
+ npc_yggdrasAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint32 uiCleaveTimer;
+ uint32 uiCorrodeFleshTimer;
+
+ void Reset()
+ {
+ uiCleaveTimer = 9000;
+ uiCorrodeFleshTimer = 6000;
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (me->getVictim()->GetPositionZ() >= 286.276)
+ {
+ std::list<HostileReference *> t_list = me->getThreatManager().getThreatList();
+ for (std::list<HostileReference *>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
+ {
+ if (Unit* pUnit = Unit::GetUnit(*me, (*itr)->getUnitGuid()))
+ {
+ if (pUnit->GetPositionZ() <= 286.276)
+ {
+ me->getThreatManager().resetAllAggro();
+ me->AddThreat(pUnit,5.0f);
+ break;
+ }
+ EnterEvadeMode();
+ }
+ }
+ }
+
+ if (uiCleaveTimer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_CLEAVE);
+ uiCleaveTimer = 9000;
+ } else uiCleaveTimer -= uiDiff;
+
+ if (uiCorrodeFleshTimer <= uiDiff)
+ {
+ DoCast(me->getVictim(), SPELL_CORRODE_FLESH);
+ uiCorrodeFleshTimer = 6000;
+ } else uiCorrodeFleshTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (Unit* pSummoner = me->ToTempSummon()->GetSummoner())
+ {
+ std::string sText = (std::string(pKiller->GetName()) + " has defeated Yg.. Yggg-really big worm!");
+ pSummoner->MonsterYell(sText.c_str(),LANG_UNIVERSAL,0);
+ }
+
+
+ if (Player* pPlayer = pKiller->GetCharmerOrOwnerPlayerOrPlayerItself())
+ {
+ pPlayer->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_1, pKiller);
+ pPlayer->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_YGGDRAS_2, pKiller);
+ }
+
+ for (uint8 i = 0; i < 3; ++i)
+ DoCast(pKiller, SPELL_JORMUNGAR_SPAWN, true);
+ }
+};
+
+CreatureAI* GetAI_npc_yggdras(Creature* pCreature)
+{
+ return new npc_yggdrasAI(pCreature);
+}
+
+enum eStinkbeard
+{
+ SPELL_ENRAGE_STINKBEARD = 50420,
+ SPELL_KNOCK_AWAY = 31389,
+ SPELL_STINKY_BEARD = 55867,
+ SPELL_THUNDERBLADE = 55866,
+ SPELL_THUNDERCLAP = 15588
+};
+
+/*####
+## npc_stinkbeard
+####*/
+
+struct npc_stinkbeardAI : public npc_escortAI
+{
+ npc_stinkbeardAI(Creature* pCreature) : npc_escortAI(pCreature)
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetReactState(REACT_PASSIVE);
+ Start(true,true, 0, NULL);
+ SetDespawnAtEnd(false);
+ }
+
+ uint32 uiKnockAwayTimer;
+ uint32 uiStinkyBeardTimer;
+
+ bool bEnrage;
+ bool bThunderClap;
+
+ void Reset()
+ {
+ me->AddAura(SPELL_THUNDERBLADE,me);
+ uiKnockAwayTimer = 10000;
+ uiStinkyBeardTimer = 15000;
+ bEnrage = false;
+ bThunderClap = false;
+ }
+
+ void WaypointReached(uint32 uiI)
+ {
+ switch(uiI)
+ {
+ case 7:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ npc_escortAI::UpdateAI(uiDiff);
+
+ if (!UpdateVictim())
+ return;
+
+ if (Unit* victim = me->getVictim())
+ {
+ if (victim->GetPositionZ() >= 286.276)
+ {
+ std::list<HostileReference *> t_list = me->getThreatManager().getThreatList();
+ for (std::list<HostileReference *>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
+ {
+ if (Unit* pUnit = Unit::GetUnit(*me, (*itr)->getUnitGuid()))
+ {
+ if (pUnit->GetPositionZ() <= 286.276)
+ {
+ me->getThreatManager().resetAllAggro();
+ me->AddThreat(pUnit,5.0f);
+ break;
+ }
+ EnterEvadeMode();
+ }
+ }
+ }
+ }
+
+ if (bThunderClap && me->GetHealth()*100 / me->GetMaxHealth() <= 10)
+ {
+ DoCastAOE(SPELL_THUNDERCLAP);
+ bThunderClap = true;
+ }
+
+ if (uiKnockAwayTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ if (pTarget && pTarget->isAlive())
+ DoCast(pTarget, SPELL_KNOCK_AWAY);
+ }
+ uiKnockAwayTimer = 10000;
+ } else uiKnockAwayTimer -= uiDiff;
+
+ if (uiStinkyBeardTimer <= uiDiff)
+ {
+ if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ if (pTarget && pTarget->isAlive())
+ DoCast(pTarget, SPELL_STINKY_BEARD);
+ }
+ uiStinkyBeardTimer = 15000;
+ } else uiStinkyBeardTimer -= uiDiff;
+
+ if (!bEnrage && me->GetHealth()*100 / me->GetMaxHealth() <= 20)
+ {
+ DoCast(me, SPELL_ENRAGE_STINKBEARD);
+ bEnrage = true;
+ }
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (Player* pPlayer = pKiller->GetCharmerOrOwnerPlayerOrPlayerItself())
+ pPlayer->GetCharmerOrOwnerPlayerOrPlayerItself()->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_MAGNATAUR, pKiller);
+
+ std::string sText = ("And with AUTHORITY, " + std::string(pKiller->GetName()) + " dominates the magnataur lord! Stinkbeard's clan is gonna miss him back home in the Dragonblight!");
+ me->MonsterYell(sText.c_str(),LANG_UNIVERSAL,0);
+ }
+};
+
+CreatureAI* GetAI_npc_stinkbeard(Creature* pCreature)
+{
+ return new npc_stinkbeardAI(pCreature);
+}
+
+/*####
+## npc_elemental_lord
+####*/
+
+struct npc_elemental_lordAI : public ScriptedAI
+{
+ npc_elemental_lordAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ std::list<uint64> SummonList;
+
+ uint32 uiElementalSpellTimer;
+
+ uint8 uiBossRandom;
+ uint32 uiSpellEntry;
+
+ bool bAddAttack;
+
+ void Reset()
+ {
+ uiBossRandom = 0;
+ uiSpellEntry = 0;
+ uiElementalSpellTimer = urand(5000,8000);
+
+ bAddAttack = false;
+ }
+
+ void SetData(uint32 uiData, uint32 uiValue)
+ {
+ if (uiData == 1)
+ {
+ uiBossRandom = uiValue;
+ SummonAdds();
+ }
+ }
+
+ void SummonAdds()
+ {
+ if (!Boss[uiBossRandom].uiAdd)
+ return;
+
+ SummonList.clear();
+
+ for (uint8 uiI = 0; uiI < 16 ; uiI++)
+ {
+ if (Creature* pSummon = me->SummonCreature(Boss[uiBossRandom].uiAdd,AddSpawnPosition[uiI]))
+ {
+ pSummon->AI()->SetData(1,uiBossRandom);
+ SummonList.push_back(pSummon->GetGUID());
+ }
+ }
+
+ }
+
+ void EnterCombat(Unit* pUnit)
+ {
+ if (!SummonList.empty())
+ for (std::list<uint64>::const_iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr)
+ {
+ if (Creature* pTemp = Unit::GetCreature(*me, *itr))
+ {
+ pTemp->m_CombatDistance = 100.0f; // ugly hack? we are not in a instance sorry. :(
+ pTemp->AI()->AttackStart(pUnit);
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (me->getVictim()->GetPositionZ() >= 286.276)
+ {
+ std::list<HostileReference *> t_list = me->getThreatManager().getThreatList();
+ for (std::list<HostileReference *>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
+ {
+ if (Unit* pUnit = Unit::GetUnit(*me, (*itr)->getUnitGuid()))
+ {
+ if (pUnit->GetPositionZ() <= 286.276)
+ {
+ me->getThreatManager().resetAllAggro();
+ me->AddThreat(pUnit,5.0f);
+ break;
+ }
+ EnterEvadeMode();
+ }
+ }
+ }
+
+ if (uiElementalSpellTimer <= uiDiff)
+ {
+ DoCastVictim(Boss[uiBossRandom].uiSpell);
+
+ uiElementalSpellTimer = urand(5000,8000);
+ } else uiElementalSpellTimer -= uiDiff;
+
+ if (!bAddAttack && me->GetHealth()*100 / me->GetMaxHealth() <= 20)
+ {
+ if (!SummonList.empty())
+ for (std::list<uint64>::const_iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr)
+ {
+ if (Creature* pTemp = Unit::GetCreature(*me, *itr))
+ {
+ if (pTemp->GetPositionZ() >= 287.00f)
+ continue;
+
+ if (pTemp->getVictim())
+ pTemp->GetMotionMaster()->MoveChase(pTemp->getVictim());
+ }
+ }
+
+ bAddAttack = true;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (!SummonList.empty())
+ for (std::list<uint64>::const_iterator itr = SummonList.begin(); itr != SummonList.end(); ++itr)
+ {
+ if (Creature* pTemp = Unit::GetCreature(*me, *itr))
+ pTemp->ForcedDespawn();
+ }
+
+ if (Player* pPlayer = pKiller->GetCharmerOrOwnerPlayerOrPlayerItself())
+ pPlayer->GetCharmerOrOwnerPlayerOrPlayerItself()->GroupEventHappens(QUEST_AMPHITHEATER_ANGUISH_FROM_BEYOND, pKiller);
+
+ std::string sText = (std::string(pKiller->GetName()) + " is victorious once more!");
+
+ if (Unit* pSummoner = me->ToTempSummon()->GetSummoner())
+ pSummoner->MonsterYell(sText.c_str(),LANG_UNIVERSAL,0);
+ }
+};
+
+CreatureAI* GetAI_npc_elemental_lord(Creature* pCreature)
+{
+ return new npc_elemental_lordAI(pCreature);
+}
+
+/*####
+## npc_fiend_elemental
+####*/
+
+struct npc_fiend_elementalAI : public ScriptedAI
+{
+ npc_fiend_elementalAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint32 uiMissleTimer;
+ uint32 uiSpell;
+
+ void Reset()
+ {
+ if (me->GetPositionZ() >= 287.0f)
+ me->GetMotionMaster()->MoveIdle();
+
+ uiSpell = 0;
+ uiMissleTimer = urand(2000,7000);
+ }
+
+ void AttackStart(Unit* pWho)
+ {
+ if (!pWho)
+ return;
+
+ AttackStartNoMove(pWho);
+ }
+
+ void SetData(uint32 uiData, uint32 uiValue)
+ {
+ if (uiData == 1)
+ uiSpell = Boss[uiValue].uiAddSpell;
+
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (me->GetPositionZ() >= 287.0f)
+ if (uiMissleTimer <= uiDiff)
+ {
+ DoCast(me,uiSpell); // this spell is not supported ... YET!
+ uiMissleTimer = urand(2000,7000);
+
+ } else uiMissleTimer -= uiDiff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_fiend_elemental(Creature* pCreature)
+{
+ return new npc_fiend_elementalAI(pCreature);
+}
+
+/*####
+## npc_released_offspring_harkoa
+####*/
+
+struct npc_released_offspring_harkoaAI : public ScriptedAI
+{
+ npc_released_offspring_harkoaAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ void Reset()
+ {
+ float x, y, z;
+ me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, 25.0f);
+ me->GetMotionMaster()->MovePoint(0, x, y, z);
+ }
+
+ void MovementInform(uint32 uiType, uint32 /*uiId*/)
+ {
+ if (uiType != POINT_MOTION_TYPE)
+ return;
+ me->DisappearAndDie();
+ }
+};
+
+CreatureAI* GetAI_npc_released_offspring_harkoa(Creature* pCreature)
+{
+ return new npc_released_offspring_harkoaAI(pCreature);
+}
+
+/*######
+## npc_crusade_recruit
+######*/
+
+enum eCrusade_recruit
+{
+ SPELL_QUEST_CREDIT = 50633,
+
+ QUEST_TROLL_PATROL_INTESTINAL_FORTITUDE = 12509,
+
+ GOSSIP_CRUSADE_TEXT = 13069,
+
+ SAY_RECRUIT_1 = -1571036,
+ SAY_RECRUIT_2 = -1571037,
+ SAY_RECRUIT_3 = -1571038
+};
+
+#define GOSSIP_ITEM_1 "Get out there and make those Scourge wish they were never reborn!"
+
+struct npc_crusade_recruitAI : public ScriptedAI
+{
+ npc_crusade_recruitAI(Creature* pCreature) : ScriptedAI(pCreature) {}
+
+ uint8 m_uiPhase; //The current phase we are in
+ uint32 m_uiTimer; //Timer until phase transition
+ float m_heading; //Store creature heading
+
+ void Reset()
+ {
+ m_uiTimer = 0;
+ m_uiPhase = 0;
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_COWER);
+ m_heading = me->GetOrientation();
+ }
+
+ void UpdateAI(const uint32 uiDiff)
+ {
+ if (m_uiPhase)
+ {
+ if (m_uiTimer <= uiDiff)
+ {
+ switch(m_uiPhase)
+ {
+ case 1:
+ // say random text
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
+ DoScriptText(RAND(SAY_RECRUIT_1,SAY_RECRUIT_2,SAY_RECRUIT_3), me);
+ m_uiTimer = 3000;
+ m_uiPhase = 2;
+ break;
+ case 2:
+ // walk forward
+ me->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
+ me->GetMotionMaster()->MovePoint(0,me->GetPositionX() + (cos(m_heading) * 10), me->GetPositionY() + (sin(m_heading) * 10), me->GetPositionZ());
+ m_uiTimer = 5000;
+ m_uiPhase = 3;
+ break;
+ case 3:
+ // despawn
+ me->DisappearAndDie();
+ m_uiTimer = 0;
+ m_uiPhase = 0;
+ break;
+ }
+ }
+ else
+ m_uiTimer -= uiDiff;
+ }
+ ScriptedAI::UpdateAI(uiDiff);
+
+ if (!UpdateVictim())
+ return;
+ }
+};
+
+CreatureAI* GetAI_npc_crusade_recruit(Creature* pCreature)
+{
+ return new npc_crusade_recruitAI (pCreature);
+}
+
+bool GossipHello_npc_crusade_recruit(Player* pPlayer, Creature* pCreature)
+{
+ if (pPlayer->GetQuestStatus(QUEST_TROLL_PATROL_INTESTINAL_FORTITUDE) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
+
+ pPlayer->SEND_GOSSIP_MENU(GOSSIP_CRUSADE_TEXT, pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_crusade_recruit(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 uiAction)
+{
+ if (uiAction == GOSSIP_ACTION_INFO_DEF +1)
+ {
+ pPlayer->CLOSE_GOSSIP_MENU();
+ pCreature->CastSpell(pPlayer, SPELL_QUEST_CREDIT, true);
+ CAST_AI(npc_crusade_recruitAI, (pCreature->AI()))->m_uiPhase = 1;
+ pCreature->SetInFront(pPlayer);
+ pCreature->SendMovementFlagUpdate();
+ }
+
+ return true;
+}
+
+/*######
+## Quest 12916: Our Only Hope!
+## go_scourge_enclosure
+######*/
+
+enum eScourgeEnclosure
+{
+ QUEST_OUR_ONLY_HOPE = 12916,
+ NPC_GYMER_DUMMY = 29928 //from quest template
+};
+
+bool GOHello_go_scourge_enclosure(Player* pPlayer, GameObject* pGO)
+{
+ if (pPlayer->GetQuestStatus(QUEST_OUR_ONLY_HOPE) == QUEST_STATUS_INCOMPLETE)
+ {
+ Creature* pGymerDummy = pGO->FindNearestCreature(NPC_GYMER_DUMMY,20.0f);
+ if (pGymerDummy)
+ {
+ pGO->UseDoorOrButton();
+ pPlayer->KilledMonsterCredit(pGymerDummy->GetEntry(),pGymerDummy->GetGUID());
+ pGymerDummy->CastSpell(pGymerDummy, 55529, true);
+ pGymerDummy->DisappearAndDie();
+ }
+ }
+ return true;
+}
+
+void AddSC_zuldrak()
+{
+ Script* newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_drakuru_shackles";
+ newscript->GetAI = &GetAI_npc_drakuru_shackles;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_captured_rageclaw";
+ newscript->GetAI = &GetAI_npc_captured_rageclaw;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_gymer";
+ newscript->pGossipHello = &GossipHello_npc_gymer;
+ newscript->pGossipSelect = &GossipSelect_npc_gymer;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_gurgthock";
+ newscript->GetAI = &GetAI_npc_gurgthock;
+ newscript->pQuestAccept = &QuestAccept_npc_gurgthock;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_orinoko_tuskbreaker";
+ newscript->GetAI = &GetAI_npc_orinoko_tuskbreaker;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_korrak_bloodrager";
+ newscript->GetAI = &GetAI_npc_korrak_bloodrager;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_yggdras";
+ newscript->GetAI = &GetAI_npc_yggdras;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_stinkbeard";
+ newscript->GetAI = &GetAI_npc_stinkbeard;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_released_offspring_harkoa";
+ newscript->GetAI = &GetAI_npc_released_offspring_harkoa;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_crusade_recruit";
+ newscript->GetAI = &GetAI_npc_crusade_recruit;
+ newscript->pGossipHello = &GossipHello_npc_crusade_recruit;
+ newscript->pGossipSelect = &GossipSelect_npc_crusade_recruit;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_elemental_lord";
+ newscript->GetAI = &GetAI_npc_elemental_lord;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_fiend_elemental";
+ newscript->GetAI = &GetAI_npc_fiend_elemental;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "go_scourge_enclosure";
+ newscript->pGOHello = &GOHello_go_scourge_enclosure;
+ newscript->RegisterSelf();
+}