From 5caf6aad98eba766017b6a3acc04dd0e30086142 Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Wed, 30 Apr 2014 22:15:28 +0200 Subject: Core/Texts: * Fix creautre text with gender female * Small cleanUp * ObjectMgr.cpp/ObjectMgr.h part from joschi --- src/server/game/Entities/Creature/GossipDef.cpp | 4 ++-- src/server/game/Entities/Player/Player.cpp | 8 ++----- src/server/game/Entities/Unit/Unit.cpp | 2 -- src/server/game/Globals/ObjectMgr.cpp | 4 ++-- src/server/game/Globals/ObjectMgr.h | 6 +++++ src/server/game/Handlers/QueryHandler.cpp | 4 ++-- src/server/game/Texts/CreatureTextMgr.cpp | 29 ++++++++++++++----------- src/server/game/Texts/CreatureTextMgr.h | 2 +- 8 files changed, 31 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 078b6758860..d335a9a5926 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -97,13 +97,13 @@ void GossipMenu::AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, ui /// OptionText if (optionBroadcastText) - ObjectMgr::GetLocaleString(optionBroadcastText->MaleText, GetLocale(), strOptionText); + strOptionText = optionBroadcastText->GetText(GetLocale()); else strOptionText = itr->second.OptionText; /// BoxText if (boxBroadcastText) - ObjectMgr::GetLocaleString(boxBroadcastText->MaleText, GetLocale(), strBoxText); + strBoxText = optionBroadcastText->GetText(GetLocale()); else strBoxText = itr->second.BoxText; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 2da94d34a62..13aae30153b 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -640,10 +640,6 @@ void KillRewarder::Reward() instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, _victim->GetEntry(), _victim); } -// == Player ==================================================== - -// we can disable this warning for this since it only -// causes undefined behavior when passed to the base class constructor Player::Player(WorldSession* session): Unit(true) { m_speakTime = 0; @@ -14437,12 +14433,12 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool LocaleConstant locale = GetSession()->GetSessionDbLocaleIndex(); if (optionBroadcastText) - ObjectMgr::GetLocaleString(getGender() == GENDER_MALE ? optionBroadcastText->MaleText : optionBroadcastText->FemaleText, locale, strOptionText); + strOptionText = optionBroadcastText->GetText(locale, getGender()); else strOptionText = itr->second.OptionText; if (boxBroadcastText) - ObjectMgr::GetLocaleString(getGender() == GENDER_MALE ? boxBroadcastText->MaleText : boxBroadcastText->FemaleText, locale, strBoxText); + strBoxText = optionBroadcastText->GetText(locale, getGender()); else strBoxText = itr->second.BoxText; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 69c47ad99c1..b01c17e91d4 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -155,8 +155,6 @@ ProcEventInfo::ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, _damageInfo(damageInfo), _healInfo(healInfo) { } -// we can disable this warning for this since it only -// causes undefined behavior when passed to the base class constructor Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject), m_movedPlayer(NULL), m_lastSanctuaryTime(0), IsAIEnabled(false), NeedChangeAI(false), LastCharmerGUID(0), diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index afe42261e6d..2905b0454c4 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -8619,8 +8619,8 @@ void ObjectMgr::LoadBroadcastTexts() bct.Id = fields[0].GetUInt32(); bct.Language = fields[1].GetUInt32(); - AddLocaleString(fields[2].GetString(), DEFAULT_LOCALE, bct.MaleText); - AddLocaleString(fields[3].GetString(), DEFAULT_LOCALE, bct.FemaleText); + bct.MaleText[DEFAULT_LOCALE] = fields[2].GetString(); + bct.FemaleText[DEFAULT_LOCALE] = fields[3].GetString(); bct.EmoteId0 = fields[4].GetUInt32(); bct.EmoteId1 = fields[5].GetUInt32(); bct.EmoteId2 = fields[6].GetUInt32(); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 797d870aa62..42fdfbf9bfe 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -412,6 +412,12 @@ struct AreaTrigger struct BroadcastText { + BroadcastText() + { + MaleText.resize(DEFAULT_LOCALE + 1); + FemaleText.resize(DEFAULT_LOCALE + 1); + } + uint32 Id; uint32 Language; StringVector MaleText; diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 3d083b3aa05..de08392b86a 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -299,8 +299,8 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket& recvData) BroadcastText const* bct = sObjectMgr->GetBroadcastText(gossip->Options[i].BroadcastTextID); if (bct) { - ObjectMgr::GetLocaleString(bct->MaleText, locale, text0[i]); - ObjectMgr::GetLocaleString(bct->FemaleText, locale, text1[i]); + text0[i] = bct->GetText(locale, GENDER_MALE, true); + text1[i] = bct->GetText(locale, GENDER_FEMALE, true); } else { diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp index 72aaa17394f..57690d7e5c1 100644 --- a/src/server/game/Texts/CreatureTextMgr.cpp +++ b/src/server/game/Texts/CreatureTextMgr.cpp @@ -28,18 +28,19 @@ class CreatureTextBuilder { public: - CreatureTextBuilder(WorldObject const* obj, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, WorldObject const* target) - : _source(obj), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target) { } + CreatureTextBuilder(WorldObject const* obj, uint8 gender, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, WorldObject const* target) + : _source(obj), _gender(gender), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target) { } size_t operator()(WorldPacket* data, LocaleConstant locale) const { - std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _textGroup, _textId, locale); + std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, locale); return ChatHandler::BuildChatPacket(*data, _msgType, Language(_language), _source, _target, text, 0, "", locale); } private: WorldObject const* _source; + uint8 _gender; ChatMsg _msgType; uint8 _textGroup; uint32 _textId; @@ -50,12 +51,12 @@ class CreatureTextBuilder class PlayerTextBuilder { public: - PlayerTextBuilder(WorldObject const* obj, WorldObject const* speaker, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, WorldObject const* target) - : _source(obj), _talker(speaker), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target) { } + PlayerTextBuilder(WorldObject const* obj, WorldObject const* speaker, uint8 gender, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, WorldObject const* target) + : _source(obj), _talker(speaker), _gender(gender), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target) { } size_t operator()(WorldPacket* data, LocaleConstant locale) const { - std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _textGroup, _textId, locale); + std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, locale); return ChatHandler::BuildChatPacket(*data, _msgType, Language(_language), _talker, _target, text, 0, "", locale); } @@ -63,6 +64,7 @@ class PlayerTextBuilder private: WorldObject const* _source; WorldObject const* _talker; + uint8 _gender; ChatMsg _msgType; uint8 _textGroup; uint32 _textId; @@ -283,14 +285,15 @@ uint32 CreatureTextMgr::SendChat(Creature* source, uint8 textGroup, WorldObject if (srcPlr) { - PlayerTextBuilder builder(source, finalSource, finalType, iter->group, iter->id, finalLang, whisperTarget); + PlayerTextBuilder builder(source, finalSource, finalSource->getGender(), finalType, iter->group, iter->id, finalLang, whisperTarget); SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly); } else { - CreatureTextBuilder builder(finalSource, finalType, iter->group, iter->id, finalLang, whisperTarget); + CreatureTextBuilder builder(finalSource, finalSource->getGender(), finalType, iter->group, iter->id, finalLang, whisperTarget); SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly); } + if (isEqualChanced || (!isEqualChanced && totalChance == 100.0f)) SetRepeatId(source, textGroup, iter->id); @@ -451,7 +454,7 @@ bool CreatureTextMgr::TextExist(uint32 sourceEntry, uint8 textGroup) return true; } -std::string CreatureTextMgr::GetLocalizedChatString(uint32 entry, uint8 textGroup, uint32 id, LocaleConstant locale) const +std::string CreatureTextMgr::GetLocalizedChatString(uint32 entry, uint8 gender, uint8 textGroup, uint32 id, LocaleConstant locale) const { CreatureTextMap::const_iterator mapitr = mTextMap.find(entry); if (mapitr == mTextMap.end()) @@ -476,15 +479,15 @@ std::string CreatureTextMgr::GetLocalizedChatString(uint32 entry, uint8 textGrou BroadcastText const* bct = sObjectMgr->GetBroadcastText(groupItr->BroadcastTextId); if (bct) - ObjectMgr::GetLocaleString(bct->MaleText, locale, baseText); + baseText = bct->GetText(locale, gender); else baseText = groupItr->text; if (locale != DEFAULT_LOCALE && !bct) { - LocaleCreatureTextMap::const_iterator locItr = mLocaleTextMap.find(CreatureTextId(entry, uint32(textGroup), id)); - if (locItr != mLocaleTextMap.end()) - ObjectMgr::GetLocaleString(locItr->second.Text, locale, baseText); + LocaleCreatureTextMap::const_iterator locItr = mLocaleTextMap.find(CreatureTextId(entry, uint32(textGroup), id)); + if (locItr != mLocaleTextMap.end()) + ObjectMgr::GetLocaleString(locItr->second.Text, locale, baseText); } return baseText; diff --git a/src/server/game/Texts/CreatureTextMgr.h b/src/server/game/Texts/CreatureTextMgr.h index c3bc8966563..2e4eec3f225 100644 --- a/src/server/game/Texts/CreatureTextMgr.h +++ b/src/server/game/Texts/CreatureTextMgr.h @@ -97,7 +97,7 @@ class CreatureTextMgr //if sent, returns the 'duration' of the text else 0 if error uint32 SendChat(Creature* source, uint8 textGroup, WorldObject const* whisperTarget = NULL, ChatMsg msgType = CHAT_MSG_ADDON, Language language = LANG_ADDON, CreatureTextRange range = TEXT_RANGE_NORMAL, uint32 sound = 0, Team team = TEAM_OTHER, bool gmOnly = false, Player* srcPlr = NULL); bool TextExist(uint32 sourceEntry, uint8 textGroup); - std::string GetLocalizedChatString(uint32 entry, uint8 textGroup, uint32 id, LocaleConstant locale) const; + std::string GetLocalizedChatString(uint32 entry, uint8 gender, uint8 textGroup, uint32 id, LocaleConstant locale) const; template void SendChatPacket(WorldObject* source, Builder const& builder, ChatMsg msgType, WorldObject const* whisperTarget = NULL, CreatureTextRange range = TEXT_RANGE_NORMAL, Team team = TEAM_OTHER, bool gmOnly = false) const; -- cgit v1.2.3 From cbd36d5a4e97d41e56b7339a619ee1072fc9cc17 Mon Sep 17 00:00:00 2001 From: Dehravor Date: Thu, 1 May 2014 10:10:13 +0200 Subject: Core/Misc: Remove remaining COMPILER_HAS_CPP11_SUPPORT related macros --- src/server/collision/Management/MMapFactory.h | 3 +- src/server/collision/Management/MMapManager.h | 9 +- src/server/collision/Management/VMapManager2.h | 8 +- src/server/collision/Maps/MapTree.h | 6 +- src/server/collision/Models/GameObjectModel.cpp | 2 +- src/server/game/AI/SmartScripts/SmartScript.h | 2 +- src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 4 +- src/server/game/AI/SmartScripts/SmartScriptMgr.h | 8 +- src/server/game/Achievements/AchievementMgr.h | 12 +-- src/server/game/AuctionHouse/AuctionHouseMgr.h | 2 +- src/server/game/Battlegrounds/ArenaTeamMgr.h | 2 +- src/server/game/Battlegrounds/BattlegroundMgr.h | 2 +- src/server/game/DungeonFinding/LFGMgr.h | 2 +- src/server/game/Entities/Creature/Creature.h | 14 +-- src/server/game/Entities/Creature/CreatureGroups.h | 4 +- src/server/game/Entities/GameObject/GameObject.h | 2 +- .../game/Entities/Item/ItemEnchantmentMgr.cpp | 2 +- src/server/game/Entities/Item/ItemPrototype.h | 2 +- src/server/game/Entities/Object/Object.h | 2 +- src/server/game/Entities/Pet/Pet.h | 2 +- src/server/game/Entities/Player/Player.h | 14 +-- src/server/game/Entities/Unit/Unit.cpp | 2 +- src/server/game/Entities/Unit/Unit.h | 4 +- src/server/game/Events/GameEventMgr.cpp | 2 +- src/server/game/Events/GameEventMgr.h | 2 +- src/server/game/Globals/ObjectAccessor.cpp | 2 +- src/server/game/Globals/ObjectAccessor.h | 8 +- src/server/game/Globals/ObjectMgr.h | 72 ++++++------- src/server/game/Groups/Group.h | 2 +- src/server/game/Guilds/Guild.h | 2 +- src/server/game/Guilds/GuildMgr.h | 2 +- src/server/game/Instances/InstanceSaveMgr.h | 6 +- src/server/game/Loot/LootMgr.h | 2 +- src/server/game/Maps/Map.h | 10 +- src/server/game/Maps/MapInstanced.h | 2 +- src/server/game/Maps/MapManager.h | 2 +- src/server/game/Maps/TransportMgr.h | 6 +- .../game/Movement/Waypoints/WaypointManager.h | 2 +- src/server/game/Scripting/ScriptSystem.h | 2 +- src/server/game/Server/WorldSession.h | 2 +- src/server/game/Skills/SkillDiscovery.cpp | 2 +- src/server/game/Spells/SpellMgr.h | 15 +-- src/server/game/Texts/CreatureTextMgr.h | 8 +- src/server/game/Weather/WeatherMgr.cpp | 4 +- src/server/game/World/World.h | 4 +- .../Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp | 8 +- src/server/shared/Common.h | 2 +- src/server/shared/CompilerDefs.h | 8 -- src/server/shared/Dynamic/HashNamespace.h | 119 --------------------- src/server/shared/Dynamic/ObjectRegistry.h | 2 +- src/server/shared/Dynamic/UnorderedMap.h | 72 ------------- src/server/shared/Dynamic/UnorderedSet.h | 66 ------------ src/server/shared/Logging/Appender.h | 5 +- src/server/shared/Logging/Log.h | 6 +- 54 files changed, 147 insertions(+), 410 deletions(-) delete mode 100644 src/server/shared/Dynamic/HashNamespace.h delete mode 100644 src/server/shared/Dynamic/UnorderedMap.h delete mode 100644 src/server/shared/Dynamic/UnorderedSet.h (limited to 'src') diff --git a/src/server/collision/Management/MMapFactory.h b/src/server/collision/Management/MMapFactory.h index 837c893f038..4b883d43613 100644 --- a/src/server/collision/Management/MMapFactory.h +++ b/src/server/collision/Management/MMapFactory.h @@ -19,11 +19,12 @@ #ifndef _MMAP_FACTORY_H #define _MMAP_FACTORY_H +#include "Define.h" #include "MMapManager.h" -#include "UnorderedMap.h" #include "DetourAlloc.h" #include "DetourNavMesh.h" #include "DetourNavMeshQuery.h" +#include namespace MMAP { diff --git a/src/server/collision/Management/MMapManager.h b/src/server/collision/Management/MMapManager.h index 7840921e4e6..798d0206538 100644 --- a/src/server/collision/Management/MMapManager.h +++ b/src/server/collision/Management/MMapManager.h @@ -19,17 +19,18 @@ #ifndef _MMAP_MANAGER_H #define _MMAP_MANAGER_H -#include "UnorderedMap.h" +#include "Define.h" #include "DetourAlloc.h" #include "DetourNavMesh.h" #include "DetourNavMeshQuery.h" #include +#include // move map related classes namespace MMAP { - typedef UNORDERED_MAP MMapTileSet; - typedef UNORDERED_MAP NavMeshQuerySet; + typedef std::unordered_map MMapTileSet; + typedef std::unordered_map NavMeshQuerySet; // dummy struct to hold map's mmap data struct MMapData @@ -52,7 +53,7 @@ namespace MMAP }; - typedef UNORDERED_MAP MMapDataSet; + typedef std::unordered_map MMapDataSet; // singleton class // holds all all access to mmap loading unloading and meshes diff --git a/src/server/collision/Management/VMapManager2.h b/src/server/collision/Management/VMapManager2.h index abddd5d7cc3..711025e67c0 100644 --- a/src/server/collision/Management/VMapManager2.h +++ b/src/server/collision/Management/VMapManager2.h @@ -19,9 +19,9 @@ #ifndef _VMAPMANAGER2_H #define _VMAPMANAGER2_H -#include "IVMapManager.h" -#include "Dynamic/UnorderedMap.h" #include "Define.h" +#include "IVMapManager.h" +#include #include //=========================================================== @@ -63,8 +63,8 @@ namespace VMAP int iRefCount; }; - typedef UNORDERED_MAP InstanceTreeMap; - typedef UNORDERED_MAP ModelFileMap; + typedef std::unordered_map InstanceTreeMap; + typedef std::unordered_map ModelFileMap; class VMapManager2 : public IVMapManager { diff --git a/src/server/collision/Maps/MapTree.h b/src/server/collision/Maps/MapTree.h index 696935e4198..05351b74019 100644 --- a/src/server/collision/Maps/MapTree.h +++ b/src/server/collision/Maps/MapTree.h @@ -20,8 +20,8 @@ #define _MAPTREE_H #include "Define.h" -#include "Dynamic/UnorderedMap.h" #include "BoundingIntervalHierarchy.h" +#include namespace VMAP { @@ -39,8 +39,8 @@ namespace VMAP class StaticMapTree { - typedef UNORDERED_MAP loadedTileMap; - typedef UNORDERED_MAP loadedSpawnMap; + typedef std::unordered_map loadedTileMap; + typedef std::unordered_map loadedSpawnMap; private: uint32 iMapID; bool iIsTiled; diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp index 42584693a13..1b99e282132 100644 --- a/src/server/collision/Models/GameObjectModel.cpp +++ b/src/server/collision/Models/GameObjectModel.cpp @@ -43,7 +43,7 @@ struct GameobjectModelData std::string name; }; -typedef UNORDERED_MAP ModelList; +typedef std::unordered_map ModelList; ModelList model_list; void LoadGameObjectModelList() diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 244728a3037..b83222dc263 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -231,7 +231,7 @@ class SmartScript SmartScriptType mScriptType; uint32 mEventPhase; - UNORDERED_MAP mStoredDecimals; + std::unordered_map mStoredDecimals; uint32 mPathId; SmartAIEventList mStoredEvents; std::listmRemIDs; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 993e6967ba5..2e8453904a1 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -37,7 +37,7 @@ void SmartWaypointMgr::LoadFromDB() { uint32 oldMSTime = getMSTime(); - for (UNORDERED_MAP::iterator itr = waypoint_map.begin(); itr != waypoint_map.end(); ++itr) + for (std::unordered_map::iterator itr = waypoint_map.begin(); itr != waypoint_map.end(); ++itr) { for (WPPath::iterator pathItr = itr->second->begin(); pathItr != itr->second->end(); ++pathItr) delete pathItr->second; @@ -96,7 +96,7 @@ void SmartWaypointMgr::LoadFromDB() SmartWaypointMgr::~SmartWaypointMgr() { - for (UNORDERED_MAP::iterator itr = waypoint_map.begin(); itr != waypoint_map.end(); ++itr) + for (std::unordered_map::iterator itr = waypoint_map.begin(); itr != waypoint_map.end(); ++itr) { for (WPPath::iterator pathItr = itr->second->begin(); pathItr != itr->second->end(); ++pathItr) delete pathItr->second; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 7ed9bbde2de..3d14b8f69e9 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1338,7 +1338,7 @@ struct SmartScriptHolder bool enableTimed; }; -typedef UNORDERED_MAP WPPath; +typedef std::unordered_map WPPath; typedef std::list ObjectList; typedef std::list GuidList; @@ -1392,7 +1392,7 @@ public: delete m_guidList; } }; -typedef UNORDERED_MAP ObjectListMap; +typedef std::unordered_map ObjectListMap; class SmartWaypointMgr { @@ -1411,14 +1411,14 @@ class SmartWaypointMgr } private: - UNORDERED_MAP waypoint_map; + std::unordered_map waypoint_map; }; // all events for a single entry typedef std::vector SmartAIEventList; // all events for all entries / guids -typedef UNORDERED_MAP SmartAIEventMap; +typedef std::unordered_map SmartAIEventMap; // Helper Stores typedef std::map > CacheSpellContainer; diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index 0a3e711e2ef..c3a1481bb2e 100644 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -35,8 +35,8 @@ class WorldPacket; typedef std::vector AchievementCriteriaEntryList; typedef std::vector AchievementEntryList; -typedef UNORDERED_MAP AchievementCriteriaListByAchievement; -typedef UNORDERED_MAP AchievementListByReferencedId; +typedef std::unordered_map AchievementCriteriaListByAchievement; +typedef std::unordered_map AchievementListByReferencedId; struct CriteriaProgress { @@ -236,7 +236,7 @@ struct AchievementReward uint32 mailTemplate; }; -typedef UNORDERED_MAP AchievementRewards; +typedef std::unordered_map AchievementRewards; struct AchievementRewardLocale { @@ -244,7 +244,7 @@ struct AchievementRewardLocale std::vector text; }; -typedef UNORDERED_MAP AchievementRewardLocales; +typedef std::unordered_map AchievementRewardLocales; struct CompletedAchievementData { @@ -252,8 +252,8 @@ struct CompletedAchievementData bool changed; }; -typedef UNORDERED_MAP CriteriaProgressMap; -typedef UNORDERED_MAP CompletedAchievementMap; +typedef std::unordered_map CriteriaProgressMap; +typedef std::unordered_map CompletedAchievementMap; enum ProgressType { diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h index 506c4bea0c5..f45fc4100de 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.h +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h @@ -145,7 +145,7 @@ class AuctionHouseMgr public: - typedef UNORDERED_MAP ItemMap; + typedef std::unordered_map ItemMap; AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId); AuctionHouseObject* GetBidsMap(uint32 factionTemplateId); diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.h b/src/server/game/Battlegrounds/ArenaTeamMgr.h index 123cbe2d41b..946824fb656 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.h +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.h @@ -27,7 +27,7 @@ class ArenaTeamMgr ~ArenaTeamMgr(); public: - typedef UNORDERED_MAP ArenaTeamContainer; + typedef std::unordered_map ArenaTeamContainer; ArenaTeam* GetArenaTeamById(uint32 arenaTeamId) const; ArenaTeam* GetArenaTeamByName(std::string const& arenaTeamName) const; diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index 42803620e27..786e664c3f3 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -28,7 +28,7 @@ typedef std::map BattlegroundContainer; typedef std::set BattlegroundClientIdsContainer; -typedef UNORDERED_MAP BattleMastersMap; +typedef std::unordered_map BattleMastersMap; #define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day #define WS_ARENA_DISTRIBUTION_TIME 20001 // Custom worldstate diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 7d998997401..2c31fe37d4d 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -145,7 +145,7 @@ typedef std::map LfgProposalPlayerContainer; typedef std::map LfgPlayerBootContainer; typedef std::map LfgGroupDataContainer; typedef std::map LfgPlayerDataContainer; -typedef UNORDERED_MAP LFGDungeonContainer; +typedef std::unordered_map LFGDungeonContainer; // Data needed by SMSG_LFG_JOIN_RESULT struct LfgJoinResultData diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 920c2623254..9cc08e3b71d 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -170,7 +170,7 @@ struct CreatureTemplate }; // Benchmarked: Faster than std::map (insert/find) -typedef UNORDERED_MAP CreatureTemplateContainer; +typedef std::unordered_map CreatureTemplateContainer; // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push, N), also any gcc version not support it at some platform #if defined(__GNUC__) @@ -218,7 +218,7 @@ struct CreatureBaseStats static CreatureBaseStats const* GetBaseStats(uint8 level, uint8 unitClass); }; -typedef UNORDERED_MAP CreatureBaseStatsContainer; +typedef std::unordered_map CreatureBaseStatsContainer; struct CreatureLocale { @@ -243,8 +243,8 @@ struct EquipmentInfo }; // Benchmarked: Faster than std::map (insert/find) -typedef UNORDERED_MAP EquipmentInfoContainerInternal; -typedef UNORDERED_MAP EquipmentInfoContainer; +typedef std::unordered_map EquipmentInfoContainerInternal; +typedef std::unordered_map EquipmentInfoContainer; // from `creature` table struct CreatureData @@ -284,7 +284,7 @@ struct CreatureModelInfo }; // Benchmarked: Faster than std::map (insert/find) -typedef UNORDERED_MAP CreatureModelContainer; +typedef std::unordered_map CreatureModelContainer; enum InhabitTypeValues { @@ -325,7 +325,7 @@ struct CreatureAddon std::vector auras; }; -typedef UNORDERED_MAP CreatureAddonContainer; +typedef std::unordered_map CreatureAddonContainer; // Vendors struct VendorItem @@ -401,7 +401,7 @@ struct TrainerSpell bool IsCastable() const { return learnedSpell[0] != spell; } }; -typedef UNORDERED_MAP TrainerSpellMap; +typedef std::unordered_map TrainerSpellMap; struct TrainerSpellData { diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h index 846b05abc17..b790853f5e1 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.h +++ b/src/server/game/Entities/Creature/CreatureGroups.h @@ -20,7 +20,7 @@ #define _FORMATIONS_H #include "Define.h" -#include "UnorderedMap.h" +#include #include class Creature; @@ -36,7 +36,7 @@ struct FormationInfo uint16 point_2; }; -typedef UNORDERED_MAP CreatureGroupInfoType; +typedef std::unordered_map CreatureGroupInfoType; class FormationMgr { diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 979abebb2ea..e94bccc4835 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -538,7 +538,7 @@ struct GameObjectTemplate }; // Benchmarked: Faster than std::map (insert/find) -typedef UNORDERED_MAP GameObjectTemplateContainer; +typedef std::unordered_map GameObjectTemplateContainer; class OPvPCapturePoint; struct TransportAnimation; diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp index 3e31347a496..f5813ae0781 100644 --- a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp +++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp @@ -40,7 +40,7 @@ struct EnchStoreItem }; typedef std::vector EnchStoreList; -typedef UNORDERED_MAP EnchantmentStore; +typedef std::unordered_map EnchantmentStore; static EnchantmentStore RandomItemEnch; diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h index d411af218b1..cc477c5bd37 100644 --- a/src/server/game/Entities/Item/ItemPrototype.h +++ b/src/server/game/Entities/Item/ItemPrototype.h @@ -744,7 +744,7 @@ struct ItemTemplate }; // Benchmarked: Faster than std::map (insert/find) -typedef UNORDERED_MAP ItemTemplateContainer; +typedef std::unordered_map ItemTemplateContainer; struct ItemLocale { diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 4dac0c7e87e..be35c91fbf4 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -116,7 +116,7 @@ class WorldObject; class WorldPacket; class ZoneScript; -typedef UNORDERED_MAP UpdateDataMapType; +typedef std::unordered_map UpdateDataMapType; class Object { diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 71f79c4935a..68465f6b8e7 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -32,7 +32,7 @@ struct PetSpell PetSpellType type; }; -typedef UNORDERED_MAP PetSpellMap; +typedef std::unordered_map PetSpellMap; typedef std::vector AutoSpellList; class Player; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index a3d8d0955ff..92691c3fd45 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -121,8 +121,8 @@ struct SpellModifier Aura* const ownerAura; }; -typedef UNORDERED_MAP PlayerTalentMap; -typedef UNORDERED_MAP PlayerSpellMap; +typedef std::unordered_map PlayerTalentMap; +typedef std::unordered_map PlayerSpellMap; typedef std::list SpellModList; typedef std::list WhisperListContainer; @@ -134,7 +134,7 @@ struct SpellCooldown }; typedef std::map SpellCooldowns; -typedef UNORDERED_MAP InstanceTimeMap; +typedef std::unordered_map InstanceTimeMap; enum TrainerSpellState { @@ -551,7 +551,7 @@ struct SkillStatusData SkillUpdateState uState; }; -typedef UNORDERED_MAP SkillStatusMap; +typedef std::unordered_map SkillStatusMap; class Quest; class Spell; @@ -1544,7 +1544,7 @@ class Player : public Unit, public GridObject uint8 unReadMails; time_t m_nextMailDelivereTime; - typedef UNORDERED_MAP ItemMap; + typedef std::unordered_map ItemMap; ItemMap mMitems; //template defined in objectmgr.cpp @@ -2169,7 +2169,7 @@ class Player : public Unit, public GridObject /*** INSTANCE SYSTEM ***/ /*********************************************************/ - typedef UNORDERED_MAP< uint32 /*mapId*/, InstancePlayerBind > BoundInstancesMap; + typedef std::unordered_map< uint32 /*mapId*/, InstancePlayerBind > BoundInstancesMap; void UpdateHomebindTime(uint32 time); @@ -2331,7 +2331,7 @@ class Player : public Unit, public GridObject //We allow only one timed quest active at the same time. Below can then be simple value instead of set. typedef std::set QuestSet; typedef std::set SeasonalQuestSet; - typedef UNORDERED_MAP SeasonalEventQuestMap; + typedef std::unordered_map SeasonalEventQuestMap; QuestSet m_timedquests; QuestSet m_weeklyquests; QuestSet m_monthlyquests; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 69c47ad99c1..70b35696205 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -17699,7 +17699,7 @@ void Unit::BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCooldowns c data.Initialize(SMSG_SPELL_COOLDOWN, 8 + 1 + (4 + 4) * cooldowns.size()); data << uint64(GetGUID()); data << uint8(flags); - for (UNORDERED_MAP::const_iterator itr = cooldowns.begin(); itr != cooldowns.end(); ++itr) + for (std::unordered_map::const_iterator itr = cooldowns.begin(); itr != cooldowns.end(); ++itr) { data << uint32(itr->first); data << uint32(itr->second); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 22c6d6b272e..9926403f7af 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1040,7 +1040,7 @@ struct GlobalCooldown uint32 cast_time; }; -typedef UNORDERED_MAP GlobalCooldownList; +typedef std::unordered_map GlobalCooldownList; class GlobalCooldownMgr // Shared by Player and CharmInfo { @@ -1247,7 +1247,7 @@ enum SpellCooldownFlags SPELL_COOLDOWN_FLAG_INCLUDE_EVENT_COOLDOWNS = 0x2 ///< Starts GCD for spells that should start their cooldown on events, requires SPELL_COOLDOWN_FLAG_INCLUDE_GCD set }; -typedef UNORDERED_MAP PacketCooldowns; +typedef std::unordered_map PacketCooldowns; // delay time next attack to prevent client attack animation problems #define ATTACK_DISPLAY_DELAY 200 diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index 95d4c7e2503..e4522536a81 100644 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -1620,7 +1620,7 @@ uint16 GameEventMgr::GetEventIdForQuest(Quest const* quest) const if (!quest) return 0; - UNORDERED_MAP::const_iterator itr = _questToEventLinks.find(quest->GetQuestId()); + std::unordered_map::const_iterator itr = _questToEventLinks.find(quest->GetQuestId()); if (itr == _questToEventLinks.end()) return 0; diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h index ea6f9359ea3..df062c6f660 100644 --- a/src/server/game/Events/GameEventMgr.h +++ b/src/server/game/Events/GameEventMgr.h @@ -173,7 +173,7 @@ class GameEventMgr QuestIdToEventConditionMap mQuestToEventConditions; GameEventNPCFlagMap mGameEventNPCFlags; ActiveEvents m_ActiveEvents; - UNORDERED_MAP _questToEventLinks; + std::unordered_map _questToEventLinks; bool isSystemInit; public: GameEventGuidMap mGameEventCreatureGuids; diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index ca173865570..8bf353d3eaa 100644 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -431,7 +431,7 @@ void ObjectAccessor::UnloadAll() /// Define the static members of HashMapHolder -template UNORDERED_MAP< uint64, T* > HashMapHolder::m_objectMap; +template std::unordered_map< uint64, T* > HashMapHolder::m_objectMap; template typename HashMapHolder::LockType HashMapHolder::i_lock; /// Global definitions for the hashmap storage diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h index 4943c648b93..b52699c85ac 100644 --- a/src/server/game/Globals/ObjectAccessor.h +++ b/src/server/game/Globals/ObjectAccessor.h @@ -22,7 +22,7 @@ #include "Define.h" #include #include -#include "UnorderedMap.h" +#include #include "UpdateData.h" @@ -47,7 +47,7 @@ class HashMapHolder { public: - typedef UNORDERED_MAP MapType; + typedef std::unordered_map MapType; typedef ACE_RW_Thread_Mutex LockType; static void Insert(T* o) @@ -222,8 +222,8 @@ class ObjectAccessor static void _buildPacket(Player*, Object*, UpdateDataMapType&); void _update(); - typedef UNORDERED_MAP Player2CorpsesMapType; - typedef UNORDERED_MAP::value_type UpdateDataValueType; + typedef std::unordered_map Player2CorpsesMapType; + typedef std::unordered_map::value_type UpdateDataValueType; std::set i_objects; Player2CorpsesMapType i_player2corpse; diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 797d870aa62..7736d96ff4c 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -125,11 +125,11 @@ enum ScriptCommands SCRIPT_COMMAND_PLAYMOVIE = 34 // source = Player, datalong = movie id }; -// Benchmarked: Faster than UNORDERED_MAP (insert/find) +// Benchmarked: Faster than std::unordered_map (insert/find) typedef std::map PageTextContainer; // Benchmarked: Faster than std::map (insert/find) -typedef UNORDERED_MAP InstanceTemplateContainer; +typedef std::unordered_map InstanceTemplateContainer; struct GameTele { @@ -142,7 +142,7 @@ struct GameTele std::wstring wnameLow; }; -typedef UNORDERED_MAP GameTeleContainer; +typedef std::unordered_map GameTeleContainer; enum ScriptsType { @@ -444,7 +444,7 @@ struct BroadcastText } }; -typedef UNORDERED_MAP BroadcastTextContainer; +typedef std::unordered_map BroadcastTextContainer; typedef std::set CellGuidSet; typedef std::map CellCorpseSet; @@ -454,8 +454,8 @@ struct CellObjectGuids CellGuidSet gameobjects; CellCorpseSet corpses; }; -typedef UNORDERED_MAP CellObjectGuidsMap; -typedef UNORDERED_MAP MapObjectGuids; +typedef std::unordered_map CellObjectGuidsMap; +typedef std::unordered_map MapObjectGuids; // Trinity string ranges #define MIN_TRINITY_STRING_ID 1 // 'trinity_string' @@ -472,19 +472,19 @@ struct TrinityStringLocale }; typedef std::map LinkedRespawnContainer; -typedef UNORDERED_MAP CreatureDataContainer; -typedef UNORDERED_MAP GameObjectDataContainer; +typedef std::unordered_map CreatureDataContainer; +typedef std::unordered_map GameObjectDataContainer; typedef std::map > TempSummonDataContainer; -typedef UNORDERED_MAP CreatureLocaleContainer; -typedef UNORDERED_MAP GameObjectLocaleContainer; -typedef UNORDERED_MAP ItemLocaleContainer; -typedef UNORDERED_MAP ItemSetNameLocaleContainer; -typedef UNORDERED_MAP QuestLocaleContainer; -typedef UNORDERED_MAP NpcTextLocaleContainer; -typedef UNORDERED_MAP PageTextLocaleContainer; -typedef UNORDERED_MAP TrinityStringLocaleContainer; -typedef UNORDERED_MAP GossipMenuItemsLocaleContainer; -typedef UNORDERED_MAP PointOfInterestLocaleContainer; +typedef std::unordered_map CreatureLocaleContainer; +typedef std::unordered_map GameObjectLocaleContainer; +typedef std::unordered_map ItemLocaleContainer; +typedef std::unordered_map ItemSetNameLocaleContainer; +typedef std::unordered_map QuestLocaleContainer; +typedef std::unordered_map NpcTextLocaleContainer; +typedef std::unordered_map PageTextLocaleContainer; +typedef std::unordered_map TrinityStringLocaleContainer; +typedef std::unordered_map GossipMenuItemsLocaleContainer; +typedef std::unordered_map PointOfInterestLocaleContainer; typedef std::multimap QuestRelations; typedef std::pair QuestRelationBounds; @@ -510,7 +510,7 @@ struct MailLevelReward }; typedef std::list MailLevelRewardList; -typedef UNORDERED_MAP MailLevelRewardContainer; +typedef std::unordered_map MailLevelRewardContainer; // We assume the rate is in general the same for all three types below, but chose to keep three for scalability and customization struct RepRewardRate @@ -612,7 +612,7 @@ struct QuestPOI }; typedef std::vector QuestPOIVector; -typedef UNORDERED_MAP QuestPOIContainer; +typedef std::unordered_map QuestPOIContainer; struct GraveYardData { @@ -624,8 +624,8 @@ typedef std::multimap GraveYardContainer; typedef std::pair GraveYardMapBounds; typedef std::pair GraveYardMapBoundsNonConst; -typedef UNORDERED_MAP CacheVendorItemContainer; -typedef UNORDERED_MAP CacheTrainerSpellContainer; +typedef std::unordered_map CacheVendorItemContainer; +typedef std::unordered_map CacheTrainerSpellContainer; enum SkillRangeType { @@ -673,7 +673,7 @@ struct DungeonEncounter }; typedef std::list DungeonEncounterList; -typedef UNORDERED_MAP DungeonEncounterContainer; +typedef std::unordered_map DungeonEncounterContainer; class PlayerDumpReader; @@ -687,21 +687,21 @@ class ObjectMgr ~ObjectMgr(); public: - typedef UNORDERED_MAP ItemMap; + typedef std::unordered_map ItemMap; - typedef UNORDERED_MAP QuestMap; + typedef std::unordered_map QuestMap; - typedef UNORDERED_MAP AreaTriggerContainer; + typedef std::unordered_map AreaTriggerContainer; - typedef UNORDERED_MAP AreaTriggerScriptContainer; + typedef std::unordered_map AreaTriggerScriptContainer; - typedef UNORDERED_MAP AccessRequirementContainer; + typedef std::unordered_map AccessRequirementContainer; - typedef UNORDERED_MAP RepRewardRateContainer; - typedef UNORDERED_MAP RepOnKillContainer; - typedef UNORDERED_MAP RepSpilloverTemplateContainer; + typedef std::unordered_map RepRewardRateContainer; + typedef std::unordered_map RepOnKillContainer; + typedef std::unordered_map RepSpilloverTemplateContainer; - typedef UNORDERED_MAP PointOfInterestContainer; + typedef std::unordered_map PointOfInterestContainer; typedef std::vector ScriptNameContainer; @@ -881,7 +881,7 @@ class ObjectMgr DungeonEncounterList const* GetDungeonEncounterList(uint32 mapId, Difficulty difficulty) { - UNORDERED_MAP::const_iterator itr = _dungeonEncounterStore.find(MAKE_PAIR32(mapId, difficulty)); + std::unordered_map::const_iterator itr = _dungeonEncounterStore.find(MAKE_PAIR32(mapId, difficulty)); if (itr != _dungeonEncounterStore.end()) return &itr->second; return NULL; @@ -1307,8 +1307,8 @@ class ObjectMgr QuestMap _questTemplates; - typedef UNORDERED_MAP GossipTextContainer; - typedef UNORDERED_MAP QuestAreaTriggerContainer; + typedef std::unordered_map GossipTextContainer; + typedef std::unordered_map QuestAreaTriggerContainer; typedef std::set TavernAreaTriggerContainer; typedef std::set GameObjectForQuestContainer; @@ -1389,7 +1389,7 @@ class ObjectMgr HalfNameContainer _petHalfName0; HalfNameContainer _petHalfName1; - typedef UNORDERED_MAP ItemSetNameContainer; + typedef std::unordered_map ItemSetNameContainer; ItemSetNameContainer _itemSetNameStore; MapObjectGuids _mapObjectGuidsStore; diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 64122b0cb4d..f0061a70621 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -171,7 +171,7 @@ class Group typedef std::list MemberSlotList; typedef MemberSlotList::const_iterator member_citerator; - typedef UNORDERED_MAP< uint32 /*mapId*/, InstanceGroupBind> BoundInstancesMap; + typedef std::unordered_map< uint32 /*mapId*/, InstanceGroupBind> BoundInstancesMap; protected: typedef MemberSlotList::iterator member_witerator; typedef std::set InvitesList; diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index fca483e92c3..ea0b2e44c53 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -637,7 +637,7 @@ private: void CanStoreItemInTab(Item* pItem, uint8 skipSlotId, bool merge, uint32& count); }; - typedef UNORDERED_MAP Members; + typedef std::unordered_map Members; typedef std::vector Ranks; typedef std::vector BankTabs; diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h index 3d07059000b..e8e6acb1bf0 100644 --- a/src/server/game/Guilds/GuildMgr.h +++ b/src/server/game/Guilds/GuildMgr.h @@ -43,7 +43,7 @@ public: void ResetTimes(); protected: - typedef UNORDERED_MAP GuildContainer; + typedef std::unordered_map GuildContainer; uint32 NextGuildId; GuildContainer GuildStore; }; diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h index 1d753ebaa48..4f1b576cae6 100644 --- a/src/server/game/Instances/InstanceSaveMgr.h +++ b/src/server/game/Instances/InstanceSaveMgr.h @@ -24,7 +24,7 @@ #include #include #include -#include "UnorderedMap.h" +#include #include "DatabaseEnv.h" #include "DBCEnums.h" #include "ObjectDefines.h" @@ -140,7 +140,7 @@ class InstanceSave ACE_Thread_Mutex _lock; }; -typedef UNORDERED_MAP ResetTimeByMapDifficultyMap; +typedef std::unordered_map ResetTimeByMapDifficultyMap; class InstanceSaveManager { @@ -152,7 +152,7 @@ class InstanceSaveManager ~InstanceSaveManager(); public: - typedef UNORDERED_MAP InstanceSaveHashMap; + typedef std::unordered_map InstanceSaveHashMap; /* resetTime is a global propery of each (raid/heroic) map all instances of that map reset at the same time */ diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index fe21e4726ef..ed0f3b9717b 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -178,7 +178,7 @@ typedef std::vector QuestItemList; typedef std::vector LootItemList; typedef std::map QuestItemMap; typedef std::list LootStoreItemList; -typedef UNORDERED_MAP LootTemplateMap; +typedef std::unordered_map LootTemplateMap; typedef std::set LootIdSet; diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index d965351fc79..a2d88905f50 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -256,7 +256,7 @@ struct ZoneDynamicInfo typedef std::map CreatureGroupHolderType; -typedef UNORDERED_MAP ZoneDynamicInfoMap; +typedef std::unordered_map ZoneDynamicInfoMap; class Map : public GridRefManager { @@ -482,7 +482,7 @@ class Map : public GridRefManager time_t GetLinkedRespawnTime(uint64 guid) const; time_t GetCreatureRespawnTime(uint32 dbGuid) const { - UNORDERED_MAP::const_iterator itr = _creatureRespawnTimes.find(dbGuid); + std::unordered_map::const_iterator itr = _creatureRespawnTimes.find(dbGuid); if (itr != _creatureRespawnTimes.end()) return itr->second; @@ -491,7 +491,7 @@ class Map : public GridRefManager time_t GetGORespawnTime(uint32 dbGuid) const { - UNORDERED_MAP::const_iterator itr = _goRespawnTimes.find(dbGuid); + std::unordered_map::const_iterator itr = _goRespawnTimes.find(dbGuid); if (itr != _goRespawnTimes.end()) return itr->second; @@ -658,8 +658,8 @@ class Map : public GridRefManager m_activeNonPlayers.erase(obj); } - UNORDERED_MAP _creatureRespawnTimes; - UNORDERED_MAP _goRespawnTimes; + std::unordered_map _creatureRespawnTimes; + std::unordered_map _goRespawnTimes; ZoneDynamicInfoMap _zoneDynamicInfo; uint32 _defaultLight; diff --git a/src/server/game/Maps/MapInstanced.h b/src/server/game/Maps/MapInstanced.h index aa2b5f95d3f..30aec43cc21 100644 --- a/src/server/game/Maps/MapInstanced.h +++ b/src/server/game/Maps/MapInstanced.h @@ -27,7 +27,7 @@ class MapInstanced : public Map { friend class MapManager; public: - typedef UNORDERED_MAP< uint32, Map*> InstancedMaps; + typedef std::unordered_map< uint32, Map*> InstancedMaps; MapInstanced(uint32 id, time_t expiry); ~MapInstanced() { } diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h index 98a5f8c7180..b7fb0617a46 100644 --- a/src/server/game/Maps/MapManager.h +++ b/src/server/game/Maps/MapManager.h @@ -126,7 +126,7 @@ class MapManager MapUpdater * GetMapUpdater() { return &m_updater; } private: - typedef UNORDERED_MAP MapMapType; + typedef std::unordered_map MapMapType; typedef std::vector InstanceIds; MapManager(); diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h index a207522c4df..5da856b185c 100644 --- a/src/server/game/Maps/TransportMgr.h +++ b/src/server/game/Maps/TransportMgr.h @@ -31,10 +31,10 @@ class Map; typedef Movement::Spline TransportSpline; typedef std::vector KeyFrameVec; -typedef UNORDERED_MAP TransportTemplates; +typedef std::unordered_map TransportTemplates; typedef std::set TransportSet; -typedef UNORDERED_MAP TransportMap; -typedef UNORDERED_MAP > TransportInstanceMap; +typedef std::unordered_map TransportMap; +typedef std::unordered_map > TransportInstanceMap; struct KeyFrame { diff --git a/src/server/game/Movement/Waypoints/WaypointManager.h b/src/server/game/Movement/Waypoints/WaypointManager.h index fe7ca5ec931..bafc6322e71 100644 --- a/src/server/game/Movement/Waypoints/WaypointManager.h +++ b/src/server/game/Movement/Waypoints/WaypointManager.h @@ -34,7 +34,7 @@ struct WaypointData }; typedef std::vector WaypointPath; -typedef UNORDERED_MAP WaypointPathContainer; +typedef std::unordered_map WaypointPathContainer; class WaypointMgr { diff --git a/src/server/game/Scripting/ScriptSystem.h b/src/server/game/Scripting/ScriptSystem.h index af2e50bae36..11120f3031b 100644 --- a/src/server/game/Scripting/ScriptSystem.h +++ b/src/server/game/Scripting/ScriptSystem.h @@ -53,7 +53,7 @@ class SystemMgr ~SystemMgr() { } public: - typedef UNORDERED_MAP PointMoveMap; + typedef std::unordered_map PointMoveMap; //Database void LoadScriptWaypoints(); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 94c6f831ef6..9d1a05ae753 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -951,7 +951,7 @@ class WorldSession WorldSession* Session; private: - typedef UNORDERED_MAP OpcodeStatusMap; + typedef std::unordered_map OpcodeStatusMap; OpcodeStatusMap _isOpcodeAllowed; // could be bool array, but wouldn't be practical for game versions with non-linear opcodes Policy _policy; diff --git a/src/server/game/Skills/SkillDiscovery.cpp b/src/server/game/Skills/SkillDiscovery.cpp index 5e272edb531..e8a89039031 100644 --- a/src/server/game/Skills/SkillDiscovery.cpp +++ b/src/server/game/Skills/SkillDiscovery.cpp @@ -40,7 +40,7 @@ struct SkillDiscoveryEntry }; typedef std::list SkillDiscoveryList; -typedef UNORDERED_MAP SkillDiscoveryMap; +typedef std::unordered_map SkillDiscoveryMap; static SkillDiscoveryMap SkillDiscoveryStore; diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 5f11870b3e9..acab7058c85 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -23,14 +23,15 @@ #include +#include "Define.h" #include "DBCStructure.h" #include "SharedDefines.h" -#include "UnorderedMap.h" #include "Util.h" #include #include #include +#include class SpellInfo; class Player; @@ -287,7 +288,7 @@ struct SpellProcEventEntry uint32 cooldown; // hidden cooldown used for some spell proc events, applied to _triggered_spell_ }; -typedef UNORDERED_MAP SpellProcEventMap; +typedef std::unordered_map SpellProcEventMap; struct SpellProcEntry { @@ -305,7 +306,7 @@ struct SpellProcEntry uint32 charges; // if nonzero - owerwrite procCharges field for given Spell.dbc entry, defines how many times proc can occur before aura remove, 0 - infinite }; -typedef UNORDERED_MAP SpellProcMap; +typedef std::unordered_map SpellProcMap; struct SpellEnchantProcEntry { @@ -314,7 +315,7 @@ struct SpellEnchantProcEntry uint32 procEx; }; -typedef UNORDERED_MAP SpellEnchantProcEventMap; +typedef std::unordered_map SpellEnchantProcEventMap; struct SpellBonusEntry { @@ -324,7 +325,7 @@ struct SpellBonusEntry float ap_dot_bonus; }; -typedef UNORDERED_MAP SpellBonusMap; +typedef std::unordered_map SpellBonusMap; enum SpellGroup { @@ -445,7 +446,7 @@ enum EffectRadiusIndex class PetAura { private: - typedef UNORDERED_MAP PetAuraMap; + typedef std::unordered_map PetAuraMap; public: PetAura() : removeOnChangePet(false), damage(0) { } @@ -525,7 +526,7 @@ struct SpellChainNode uint8 rank; }; -typedef UNORDERED_MAP SpellChainMap; +typedef std::unordered_map SpellChainMap; // spell_id req_spell typedef std::multimap SpellRequiredMap; diff --git a/src/server/game/Texts/CreatureTextMgr.h b/src/server/game/Texts/CreatureTextMgr.h index c3bc8966563..70b3f28d3d2 100644 --- a/src/server/game/Texts/CreatureTextMgr.h +++ b/src/server/game/Texts/CreatureTextMgr.h @@ -70,15 +70,15 @@ struct CreatureTextId }; typedef std::vector CreatureTextGroup; //texts in a group -typedef UNORDERED_MAP CreatureTextHolder; //groups for a creature by groupid -typedef UNORDERED_MAP CreatureTextMap; //all creatures by entry +typedef std::unordered_map CreatureTextHolder; //groups for a creature by groupid +typedef std::unordered_map CreatureTextMap; //all creatures by entry typedef std::map LocaleCreatureTextMap; //used for handling non-repeatable random texts typedef std::vector CreatureTextRepeatIds; -typedef UNORDERED_MAP CreatureTextRepeatGroup; -typedef UNORDERED_MAP CreatureTextRepeatMap;//guid based +typedef std::unordered_map CreatureTextRepeatGroup; +typedef std::unordered_map CreatureTextRepeatMap;//guid based class CreatureTextMgr { diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp index 886a910becc..59dc591ccd0 100644 --- a/src/server/game/Weather/WeatherMgr.cpp +++ b/src/server/game/Weather/WeatherMgr.cpp @@ -34,8 +34,8 @@ namespace WeatherMgr namespace { - typedef UNORDERED_MAP > WeatherMap; - typedef UNORDERED_MAP WeatherZoneMap; + typedef std::unordered_map > WeatherMap; + typedef std::unordered_map WeatherZoneMap; WeatherMap m_weathers; WeatherZoneMap mWeatherZoneMap; diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 1557baf3bfa..9bac3032161 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -502,7 +502,7 @@ private: CliCommandHolder& operator=(CliCommandHolder const& right) = delete; }; -typedef UNORDERED_MAP SessionMap; +typedef std::unordered_map SessionMap; struct CharacterNameData { @@ -774,7 +774,7 @@ class World uint32 m_currentTime; SessionMap m_sessions; - typedef UNORDERED_MAP DisconnectMap; + typedef std::unordered_map DisconnectMap; DisconnectMap m_disconnects; uint32 m_maxActiveSessionCount; uint32 m_maxQueuedSessionCount; diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp index ceedf0024ad..35086afa42e 100644 --- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp +++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_cthun.cpp @@ -483,7 +483,7 @@ public: uint64 StomachEnterTarget; //Stomach map, bool = true then in stomach - UNORDERED_MAP Stomach_Map; + std::unordered_map Stomach_Map; void Reset() override { @@ -536,7 +536,7 @@ public: if (Stomach_Map.empty()) return NULL; - UNORDERED_MAP::const_iterator i = Stomach_Map.begin(); + std::unordered_map::const_iterator i = Stomach_Map.begin(); std::list temp; std::list::const_iterator j; @@ -680,7 +680,7 @@ public: DoCast(me, SPELL_PURPLE_COLORATION, true); - UNORDERED_MAP::iterator i = Stomach_Map.begin(); + std::unordered_map::iterator i = Stomach_Map.begin(); //Kick all players out of stomach while (i != Stomach_Map.end()) @@ -712,7 +712,7 @@ public: if (StomachAcidTimer <= diff) { //Apply aura to all players in stomach - UNORDERED_MAP::iterator i = Stomach_Map.begin(); + std::unordered_map::iterator i = Stomach_Map.begin(); while (i != Stomach_Map.end()) { diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h index fb153f2ba3e..f49bbf0bada 100644 --- a/src/server/shared/Common.h +++ b/src/server/shared/Common.h @@ -61,7 +61,7 @@ #include "Define.h" -#include "Dynamic/UnorderedMap.h" +#include #include #include #include diff --git a/src/server/shared/CompilerDefs.h b/src/server/shared/CompilerDefs.h index 8a557328af4..2c2d7ea861d 100644 --- a/src/server/shared/CompilerDefs.h +++ b/src/server/shared/CompilerDefs.h @@ -55,12 +55,4 @@ # error "FATAL ERROR: Unknown compiler." #endif -#if defined(__cplusplus) && __cplusplus == 201103L -# define COMPILER_HAS_CPP11_SUPPORT 1 -#elif _MSC_VER >= 1700 -# define COMPILER_HAS_CPP11_SUPPORT 1 -#else -# define COMPILER_HAS_CPP11_SUPPORT 0 -#endif - #endif diff --git a/src/server/shared/Dynamic/HashNamespace.h b/src/server/shared/Dynamic/HashNamespace.h deleted file mode 100644 index 0e95332c05f..00000000000 --- a/src/server/shared/Dynamic/HashNamespace.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * This program is free software; you can 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, see . - */ - -#ifndef TRINITY_HASH_NAMESPACE_H -#define TRINITY_HASH_NAMESPACE_H - -#include "Define.h" - -#if COMPILER_HAS_CPP11_SUPPORT -# define HASH_NAMESPACE_START namespace std { -# define HASH_NAMESPACE_END } -#elif defined(_STLPORT_VERSION) -# define HASH_NAMESPACE_START namespace std { -# define HASH_NAMESPACE_END } -#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1600 // VS100 -# define HASH_NAMESPACE_START namespace std { -# define HASH_NAMESPACE_END } -#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1500 && _HAS_TR1 -# define HASH_NAMESPACE_START namespace std { namespace tr1 { -# define HASH_NAMESPACE_END } } -#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1300 -# define HASH_NAMESPACE_START namespace stdext { -# define HASH_NAMESPACE_END } - -#if !_HAS_TRADITIONAL_STL -#ifndef HASH_NAMESPACE -#define HASH_NAMESPACE -#else - -// can be not used by some platforms, so provide fake forward -HASH_NAMESPACE_START - -template -class hash -{ -public: - size_t operator() (K const&); -}; - -HASH_NAMESPACE_END - -#endif -#endif - -#elif COMPILER == COMPILER_INTEL -# define HASH_NAMESPACE_START namespace std { -# define HASH_NAMESPACE_END } -#elif COMPILER == COMPILER_GNU && defined(__clang__) && defined(_LIBCPP_VERSION) -# define HASH_NAMESPACE_START namespace std { -# define HASH_NAMESPACE_END } -#elif COMPILER == COMPILER_GNU && GCC_VERSION > 40200 -# define HASH_NAMESPACE_START namespace std { namespace tr1 { -# define HASH_NAMESPACE_END } } -#elif COMPILER == COMPILER_GNU && GCC_VERSION >= 30000 -# define HASH_NAMESPACE_START namespace __gnu_cxx { -# define HASH_NAMESPACE_END } - -#include -#include - -HASH_NAMESPACE_START - -template<> -class hash -{ -public: - size_t operator()(const unsigned long long &__x) const { return (size_t)__x; } -}; - -template -class hash -{ -public: - size_t operator()(T * const &__x) const { return (size_t)__x; } -}; - -template<> struct hash -{ - size_t operator()(const std::string &__x) const - { - return hash()(__x.c_str()); - } -}; - -HASH_NAMESPACE_END - -#else -# define HASH_NAMESPACE_START namespace std { -# define HASH_NAMESPACE_END } -#endif - -#if COMPILER != COMPILER_MICROSOFT - -// Visual Studio use non standard hash calculation function, so provide fake forward for other -HASH_NAMESPACE_START - -template -size_t hash_value(K const&); - -HASH_NAMESPACE_END - -#endif - -#endif diff --git a/src/server/shared/Dynamic/ObjectRegistry.h b/src/server/shared/Dynamic/ObjectRegistry.h index 4b17b2fc558..be7ce00ac05 100644 --- a/src/server/shared/Dynamic/ObjectRegistry.h +++ b/src/server/shared/Dynamic/ObjectRegistry.h @@ -20,12 +20,12 @@ #define TRINITY_OBJECTREGISTRY_H #include "Define.h" -#include "Dynamic/UnorderedMap.h" #include #include #include #include +#include /** ObjectRegistry holds all registry item of the same type */ diff --git a/src/server/shared/Dynamic/UnorderedMap.h b/src/server/shared/Dynamic/UnorderedMap.h deleted file mode 100644 index f97c4830c75..00000000000 --- a/src/server/shared/Dynamic/UnorderedMap.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * This program is free software; you can 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, see . - */ - -#ifndef TRINITY_UNORDERED_MAP_H -#define TRINITY_UNORDERED_MAP_H - -#include "HashNamespace.h" - -#if COMPILER_HAS_CPP11_SUPPORT -# include -#elif COMPILER == COMPILER_INTEL -# include -#elif COMPILER == COMPILER_GNU && defined(__clang__) && defined(_LIBCPP_VERSION) -# include -#elif COMPILER == COMPILER_GNU && GCC_VERSION > 40200 -# include -#elif COMPILER == COMPILER_GNU && GCC_VERSION >= 30000 -# include -#elif COMPILER == COMPILER_MICROSOFT && ((_MSC_VER >= 1500 && _HAS_TR1) || _MSC_VER >= 1700) // VC9.0 SP1 and later -# include -#else -# include -#endif - -#ifdef _STLPORT_VERSION -# define UNORDERED_MAP std::hash_map -# define UNORDERED_MULTIMAP std::hash_multimap -#elif COMPILER_HAS_CPP11_SUPPORT -# define UNORDERED_MAP std::unordered_map -# define UNORDERED_MULTIMAP std::unordered_multimap -#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1600 // VS100 -# define UNORDERED_MAP std::tr1::unordered_map -# define UNORDERED_MULTIMAP std::tr1::unordered_multimap -#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1500 && _HAS_TR1 -# define UNORDERED_MAP std::tr1::unordered_map -# define UNORDERED_MULTIMAP std::tr1::unordered_multimap -#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1300 -# define UNORDERED_MAP stdext::hash_map -# define UNORDERED_MULTIMAP stdext::hash_multimap -#elif COMPILER == COMPILER_INTEL -# define UNORDERED_MAP std::hash_map -# define UNORDERED_MULTIMAP std::hash_multimap -#elif COMPILER == COMPILER_GNU && defined(__clang__) && defined(_LIBCPP_VERSION) -# define UNORDERED_MAP std::unordered_map -# define UNORDERED_MULTIMAP std::unordered_multimap -#elif COMPILER == COMPILER_GNU && GCC_VERSION > 40200 -# define UNORDERED_MAP std::tr1::unordered_map -# define UNORDERED_MULTIMAP std::tr1::unordered_multimap -#elif COMPILER == COMPILER_GNU && GCC_VERSION >= 30000 -# define UNORDERED_MAP __gnu_cxx::hash_map -# define UNORDERED_MULTIMAP __gnu_cxx::hash_multimap -#else -# define UNORDERED_MAP std::hash_map -# define UNORDERED_MULTIMAP std::hash_multimap -#endif - -#endif diff --git a/src/server/shared/Dynamic/UnorderedSet.h b/src/server/shared/Dynamic/UnorderedSet.h deleted file mode 100644 index 0e084698c47..00000000000 --- a/src/server/shared/Dynamic/UnorderedSet.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * This program is free software; you can 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, see . - */ - -#ifndef TRINITY_UNORDERED_SET_H -#define TRINITY_UNORDERED_SET_H - -#include "HashNamespace.h" - -#if COMPILER_HAS_CPP11_SUPPORT -# include -#elif COMPILER == COMPILER_INTEL -# include -#elif COMPILER == COMPILER_GNU && defined(__clang__) && defined(_LIBCPP_VERSION) -# include -#elif COMPILER == COMPILER_GNU && GCC_VERSION > 40200 -# include -#elif COMPILER == COMPILER_GNU && GCC_VERSION >= 30000 -# include -#elif COMPILER == COMPILER_MICROSOFT && ((_MSC_VER >= 1500 && _HAS_TR1) || _MSC_VER >= 1700) // VC9.0 SP1 and later -# include -#else -# include -#endif - -#ifdef _STLPORT_VERSION -# define UNORDERED_SET std::hash_set -using std::hash_set; -#elif COMPILER_HAS_CPP11_SUPPORT -# define UNORDERED_SET std::unordered_set -#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1600 // VS100 -# define UNORDERED_SET std::tr1::unordered_set -#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1500 && _HAS_TR1 -# define UNORDERED_SET std::tr1::unordered_set -#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1300 -# define UNORDERED_SET stdext::hash_set -using stdext::hash_set; -#elif COMPILER == COMPILER_INTEL -# define UNORDERED_SET std::hash_set -using std::hash_set; -#elif COMPILER == COMPILER_GNU && defined(__clang__) && defined(_LIBCPP_VERSION) -# define UNORDERED_SET std::unordered_set -#elif COMPILER == COMPILER_GNU && GCC_VERSION > 40200 -# define UNORDERED_SET std::tr1::unordered_set -#elif COMPILER == COMPILER_GNU && GCC_VERSION >= 30000 -# define UNORDERED_SET __gnu_cxx::hash_set -#else -# define UNORDERED_SET std::hash_set -using std::hash_set; -#endif - -#endif diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h index b373f0459c9..84d0dc14eca 100644 --- a/src/server/shared/Logging/Appender.h +++ b/src/server/shared/Logging/Appender.h @@ -20,8 +20,7 @@ #include "Define.h" #include -#include "Dynamic/UnorderedMap.h" - +#include #include // Values assigned have their equivalent in enum ACE_Log_Priority @@ -105,6 +104,6 @@ class Appender AppenderFlags flags; }; -typedef UNORDERED_MAP AppenderMap; +typedef std::unordered_map AppenderMap; #endif diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h index 73c5601b95b..5fa638e2f40 100644 --- a/src/server/shared/Logging/Log.h +++ b/src/server/shared/Logging/Log.h @@ -23,8 +23,8 @@ #include "Appender.h" #include "Logger.h" #include "LogWorker.h" -#include "Dynamic/UnorderedMap.h" +#include #include #include @@ -34,8 +34,8 @@ class Log { friend class ACE_Singleton; - typedef UNORDERED_MAP LoggerMap; - typedef UNORDERED_MAP CachedLoggerContainer; + typedef std::unordered_map LoggerMap; + typedef std::unordered_map CachedLoggerContainer; private: Log(); -- cgit v1.2.3 From 3ff9589c9afe72c270db28f58a0476a23f766351 Mon Sep 17 00:00:00 2001 From: joschiwald Date: Thu, 1 May 2014 15:14:42 +0200 Subject: Core/Battleground: fixed possible crash in BattlegroundSA Closes #11969 --- .../game/Battlegrounds/Zones/BattlegroundSA.cpp | 35 ++++++++++++---------- src/server/game/Entities/GameObject/GameObject.cpp | 1 + 2 files changed, 20 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp index 7af9c0a3fa5..0966ddd19bd 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp @@ -552,8 +552,9 @@ void BattlegroundSA::ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* switch (go->GetGoType()) { case GAMEOBJECT_TYPE_GOOBER: - if (eventId == BG_SA_EVENT_TITAN_RELIC_ACTIVATED) - TitanRelicActivated(invoker->ToPlayer()); + if (invoker) + if (eventId == BG_SA_EVENT_TITAN_RELIC_ACTIVATED) + TitanRelicActivated(invoker->ToPlayer()); break; case GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING: { @@ -577,8 +578,15 @@ void BattlegroundSA::ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* GateStatus[gate->GateId] = BG_SA_GATE_DESTROYED; _gateDestroyed = true; - bool rewardHonor = true; + if (gateId < 5) + DelObject(gateId + 14); + if (Creature* c = obj->FindNearestCreature(NPC_WORLD_TRIGGER, 500.0f)) + SendChatMessage(c, gate->DestroyedText, invoker); + + PlaySoundToAll(Attackers == TEAM_ALLIANCE ? SOUND_WALL_DESTROYED_ALLIANCE : SOUND_WALL_DESTROYED_HORDE); + + bool rewardHonor = true; switch (gateId) { case BG_SA_GREEN_GATE: @@ -601,23 +609,18 @@ void BattlegroundSA::ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* break; } - if (gateId < 5) - DelObject(gateId + 14); - - if (Unit* unit = invoker->ToUnit()) + if (invoker) { - if (Player* player = unit->GetCharmerOrOwnerPlayerOrPlayerItself()) + if (Unit* unit = invoker->ToUnit()) { - UpdatePlayerScore(player, SCORE_DESTROYED_WALL, 1); - if (rewardHonor) - UpdatePlayerScore(player, SCORE_BONUS_HONOR, GetBonusHonorFromKill(1)); + if (Player* player = unit->GetCharmerOrOwnerPlayerOrPlayerItself()) + { + UpdatePlayerScore(player, SCORE_DESTROYED_WALL, 1); + if (rewardHonor) + UpdatePlayerScore(player, SCORE_BONUS_HONOR, GetBonusHonorFromKill(1)); + } } } - - if (Creature* c = obj->FindNearestCreature(NPC_WORLD_TRIGGER, 500.0f)) - SendChatMessage(c, gate->DestroyedText, invoker); - - PlaySoundToAll(Attackers == TEAM_ALLIANCE ? SOUND_WALL_DESTROYED_ALLIANCE : SOUND_WALL_DESTROYED_HORDE); } else break; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index de53385af9e..77f9ca59db4 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -1904,6 +1904,7 @@ void GameObject::ModifyHealth(int32 change, Unit* attackerOrHealer /*= NULL*/, u if (newState == GetDestructibleState()) return; + /// @todo: pass attackerOrHealer instead of player SetDestructibleState(newState, player, false); } -- cgit v1.2.3 From 0faf4b1b24cefaf83a6bcc6156e1ea35a034e0ee Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Thu, 1 May 2014 21:59:00 +0200 Subject: Core/Text: Fix typo in 5caf6aad98eba766017b6a3acc04dd0e30086142 --- src/server/game/Entities/Creature/GossipDef.cpp | 2 +- src/server/game/Entities/Player/Player.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index d335a9a5926..492d82c5a03 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -103,7 +103,7 @@ void GossipMenu::AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, ui /// BoxText if (boxBroadcastText) - strBoxText = optionBroadcastText->GetText(GetLocale()); + strBoxText = boxBroadcastText->GetText(GetLocale()); else strBoxText = itr->second.BoxText; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 13aae30153b..a701e6fc38f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -14438,7 +14438,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool strOptionText = itr->second.OptionText; if (boxBroadcastText) - strBoxText = optionBroadcastText->GetText(locale, getGender()); + strBoxText = boxBroadcastText->GetText(locale, getGender()); else strBoxText = itr->second.BoxText; -- cgit v1.2.3 From 3e78578f27c28441b1baf4e66be9e4606146c699 Mon Sep 17 00:00:00 2001 From: Lucas Date: Fri, 2 May 2014 16:07:48 +0200 Subject: Core/Spells: Fix hots proccing wrong auras & Partly revert unnecessary changes in 1719e19572bc22463edbcbe4089e68a97019e787 --- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 2 +- src/server/game/Spells/SpellMgr.cpp | 47 ++++++++++++++--------- 2 files changed, 29 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 0175c685076..b87524357d2 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -6099,7 +6099,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC; uint32 procEx = (crit ? PROC_EX_CRITICAL_HIT : PROC_EX_NORMAL_HIT) | PROC_EX_INTERNAL_HOT; // ignore item heals - if (!haveCastItem && GetAuraType() != SPELL_AURA_OBS_MOD_HEALTH) + if (!haveCastItem) caster->ProcDamageAndSpell(target, procAttacker, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo()); } diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 548685b9bb6..e40ee32c46f 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -784,13 +784,15 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr bool hasFamilyMask = false; - /** - + /** + * @brief Check auras procced by periodics *Only damaging Dots can proc auras with PROC_FLAG_TAKEN_DAMAGE - *Both Dots and hots can proc if ONLY has PROC_FLAG_DONE_PERIODIC or PROC_FLAG_TAKEN_PERIODIC. Such auras need support in Unit::HandleAuraProc. + *Only Dots can proc if ONLY has PROC_FLAG_DONE_PERIODIC and spellfamily == 0 or PROC_FLAG_TAKEN_PERIODIC. + + *Hots can proc if ONLY has PROC_FLAG_DONE_PERIODIC and spellfamily != 0 *Only Dots can proc auras with PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG or PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG @@ -804,7 +806,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr * @param procFlags proc_flags of spellProc * @param procExtra proc_EX of procSpell * @param EventProcFlag proc_flags of aura to be procced - + * @param spellProcEvent SpellProcEventEntry of aura to be procced */ @@ -812,34 +814,41 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr if (procFlags & PROC_FLAG_TAKEN_DAMAGE && EventProcFlag & PROC_FLAG_TAKEN_DAMAGE) return true; - /// Any aura that has only PROC_FLAG_DONE_PERIODIC or PROC_FLAG_TAKEN_PERIODIC should always proc, if procSpell is correct or not is checked in Unit::HandleAuraProc - if ((EventProcFlag == PROC_FLAG_DONE_PERIODIC && procFlags == PROC_FLAG_DONE_PERIODIC) || (EventProcFlag == PROC_FLAG_TAKEN_PERIODIC && procFlags == PROC_FLAG_TAKEN_PERIODIC)) - return true; - if (procFlags & PROC_FLAG_DONE_PERIODIC && EventProcFlag & PROC_FLAG_DONE_PERIODIC) - { - /// Aura must have positive procflags for a HOT to proc + { if (procExtra & PROC_EX_INTERNAL_HOT) { - if (!(EventProcFlag & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS))) + if (EventProcFlag == PROC_FLAG_DONE_PERIODIC) + { + /// no aura with only PROC_FLAG_DONE_PERIODIC and spellFamilyName == 0 can proc from a HOT. + if (!spellProcEvent->spellFamilyName) + return false; + } + /// Aura must have positive procflags for a HOT to proc + else if (!(EventProcFlag & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS))) return false; } - /// Aura must have negative procflags for a DOT to proc - else if (!(EventProcFlag & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG))) - return false; + /// Aura must have negative or neutral(PROC_FLAG_DONE_PERIODIC only) procflags for a DOT to proc + else if (EventProcFlag != PROC_FLAG_DONE_PERIODIC) + if (!(EventProcFlag & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG))) + return false; } if (procFlags & PROC_FLAG_TAKEN_PERIODIC && EventProcFlag & PROC_FLAG_TAKEN_PERIODIC) - { - /// Aura must have positive procflags for a HOT to proc + { if (procExtra & PROC_EX_INTERNAL_HOT) { + /// No aura that only has PROC_FLAG_TAKEN_PERIODIC can proc from a HOT. + if (EventProcFlag == PROC_FLAG_TAKEN_PERIODIC) + return false; + /// Aura must have positive procflags for a HOT to proc if (!(EventProcFlag & (PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS))) return false; } - /// Aura must have negative procflags for a DOT to proc - else if (!(EventProcFlag & (PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG))) - return false; + /// Aura must have negative or neutral(PROC_FLAG_TAKEN_PERIODIC only) procflags for a DOT to proc + else if (EventProcFlag != PROC_FLAG_TAKEN_PERIODIC) + if (!(EventProcFlag & (PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG))) + return false; } // Trap casts are active by default if (procFlags & PROC_FLAG_DONE_TRAP_ACTIVATION) -- cgit v1.2.3 From 3e0d2e49448ae5d53baefa0ef3b2df4542aae1dd Mon Sep 17 00:00:00 2001 From: jackpoz Date: Fri, 2 May 2014 23:21:37 +0200 Subject: Core/Misc: Fix static analysis issues --- src/server/game/Globals/ObjectMgr.h | 3 ++- src/server/game/Spells/SpellMgr.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 42fdfbf9bfe..8cf8f221dd2 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -412,7 +412,8 @@ struct AreaTrigger struct BroadcastText { - BroadcastText() + BroadcastText() : Id(0), Language(0), EmoteId0(0), EmoteId1(0), EmoteId2(0), + EmoteDelay0(0), EmoteDelay1(0), EmoteDelay2(0), SoundId(0), Unk1(0), Unk2(0) { MaleText.resize(DEFAULT_LOCALE + 1); FemaleText.resize(DEFAULT_LOCALE + 1); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index e40ee32c46f..e0a20346242 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -821,7 +821,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr if (EventProcFlag == PROC_FLAG_DONE_PERIODIC) { /// no aura with only PROC_FLAG_DONE_PERIODIC and spellFamilyName == 0 can proc from a HOT. - if (!spellProcEvent->spellFamilyName) + if (!spellProcEvent || !spellProcEvent->spellFamilyName) return false; } /// Aura must have positive procflags for a HOT to proc -- cgit v1.2.3 From 0c8df80415b17f1689d9b94ba4ee41351f75b682 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Sat, 3 May 2014 02:11:37 +0200 Subject: Core/Auth: Add support for build 13930 of china By phoenixfight closes #11978 --- src/server/authserver/Authentication/AuthCodes.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/server/authserver/Authentication/AuthCodes.cpp b/src/server/authserver/Authentication/AuthCodes.cpp index 1bf5dcad51f..bb278dd6653 100644 --- a/src/server/authserver/Authentication/AuthCodes.cpp +++ b/src/server/authserver/Authentication/AuthCodes.cpp @@ -25,6 +25,7 @@ namespace AuthHelper {15595, 4, 3, 4, ' '}, {14545, 4, 2, 2, ' '}, {13623, 4, 0, 6, 'a'}, + {13930, 3, 3, 5, 'a'}, // 3.3.5a China Mainland build {12340, 3, 3, 5, 'a'}, {11723, 3, 3, 3, 'a'}, {11403, 3, 3, 2, ' '}, -- cgit v1.2.3 From 065207b1b8fe04265bd0cc7f386021be0d7e2201 Mon Sep 17 00:00:00 2001 From: Lucas Date: Sat, 3 May 2014 02:25:33 +0200 Subject: Core/Spells: Correct a mistake in HOT aura procs A crash fix was added in 3e0d2e49448ae5d53baefa0ef3b2df4542aae1dd but the usage of spellProcEvent itself was incorrect, we should instead use spellProto of aura to be procced --- src/server/game/Entities/Unit/Unit.cpp | 2 +- src/server/game/Spells/SpellMgr.cpp | 8 ++++---- src/server/game/Spells/SpellMgr.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index b01c17e91d4..6e6072aa5b4 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -14972,7 +14972,7 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, SpellInfo const } // Check spellProcEvent data requirements - if (!sSpellMgr->IsSpellProcEventCanTriggeredBy(spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra, active)) + if (!sSpellMgr->IsSpellProcEventCanTriggeredBy(spellProto, spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra, active)) return false; // In most cases req get honor or XP from kill if (EventProcFlag & PROC_FLAG_KILL && GetTypeId() == TYPEID_PLAYER) diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index e0a20346242..ba5b8856323 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -773,7 +773,7 @@ SpellProcEventEntry const* SpellMgr::GetSpellProcEvent(uint32 spellId) const return NULL; } -bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellInfo const* procSpell, uint32 procFlags, uint32 procExtra, bool active) const +bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellInfo const* procSpell, uint32 procFlags, uint32 procExtra, bool active) const { // No extra req need uint32 procEvent_procEx = PROC_EX_NONE; @@ -790,7 +790,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr *Only damaging Dots can proc auras with PROC_FLAG_TAKEN_DAMAGE - *Only Dots can proc if ONLY has PROC_FLAG_DONE_PERIODIC and spellfamily == 0 or PROC_FLAG_TAKEN_PERIODIC. + *Only Dots can proc if ONLY has PROC_FLAG_DONE_PERIODIC or PROC_FLAG_TAKEN_PERIODIC. *Hots can proc if ONLY has PROC_FLAG_DONE_PERIODIC and spellfamily != 0 @@ -806,7 +806,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr * @param procFlags proc_flags of spellProc * @param procExtra proc_EX of procSpell * @param EventProcFlag proc_flags of aura to be procced - * @param spellProcEvent SpellProcEventEntry of aura to be procced + * @param spellProto SpellInfo of aura to be procced */ @@ -821,7 +821,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr if (EventProcFlag == PROC_FLAG_DONE_PERIODIC) { /// no aura with only PROC_FLAG_DONE_PERIODIC and spellFamilyName == 0 can proc from a HOT. - if (!spellProcEvent || !spellProcEvent->spellFamilyName) + if (!spellProto->SpellFamilyName) return false; } /// Aura must have positive procflags for a HOT to proc diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 5f11870b3e9..bea740732c3 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -657,7 +657,7 @@ class SpellMgr // Spell proc event table SpellProcEventEntry const* GetSpellProcEvent(uint32 spellId) const; - bool IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellInfo const* procSpell, uint32 procFlags, uint32 procExtra, bool active) const; + bool IsSpellProcEventCanTriggeredBy(SpellInfo const* spellProto, SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellInfo const* procSpell, uint32 procFlags, uint32 procExtra, bool active) const; // Spell proc table SpellProcEntry const* GetSpellProcEntry(uint32 spellId) const; -- cgit v1.2.3 From 720c3cbbd0f0b34284484d743801afe281e7272d Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sat, 3 May 2014 21:22:12 +0200 Subject: Core/Misc: Fix exploit Fix exploit that allowed to duplicate stackable splitable items. If the item that cast the spell can't be found anymore, the spell is cancelled. Fixes https://github.com/TrinityCore/TrinityCore/issues/11977 --- src/server/game/Spells/Spell.cpp | 34 ++++++++++++++++++++++++++++----- src/server/game/Spells/Spell.h | 2 +- src/server/game/Spells/SpellEffects.cpp | 3 +++ 3 files changed, 33 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index d9ad62ebf71..3a947b1b07f 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -3016,7 +3016,12 @@ void Spell::cancel() void Spell::cast(bool skipCheck) { // update pointers base at GUIDs to prevent access to non-existed already object - UpdatePointers(); + if (!UpdatePointers()) + { + // cancel the spell if UpdatePointers() returned false, something wrong happened there + cancel(); + return; + } // cancel at lost explicit target during cast if (m_targets.GetObjectTargetGUID() && !m_targets.GetObjectTarget()) @@ -3266,7 +3271,12 @@ void Spell::handle_immediate() uint64 Spell::handle_delayed(uint64 t_offset) { - UpdatePointers(); + if (!UpdatePointers()) + { + // finish the spell if UpdatePointers() returned false, something wrong happened there + finish(false); + return 0; + } if (m_caster->GetTypeId() == TYPEID_PLAYER) m_caster->ToPlayer()->SetSpellModTakingSpell(this, true); @@ -3418,7 +3428,12 @@ void Spell::SendSpellCooldown() void Spell::update(uint32 difftime) { // update pointers based at it's GUIDs - UpdatePointers(); + if (!UpdatePointers()) + { + // cancel the spell if UpdatePointers() returned false, something wrong happened there + cancel(); + return; + } if (m_targets.GetUnitTargetGUID() && !m_targets.GetUnitTarget()) { @@ -4248,6 +4263,7 @@ void Spell::TakeCastItem() m_targets.SetItemTarget(NULL); m_CastItem = NULL; + m_castItemGUID = 0; } } @@ -4492,6 +4508,7 @@ void Spell::TakeReagents() } m_CastItem = NULL; + m_castItemGUID = 0; } // if GetItemTarget is also spell reagent @@ -6301,7 +6318,7 @@ void Spell::DelayedChannel() SendChannelUpdate(m_timer); } -void Spell::UpdatePointers() +bool Spell::UpdatePointers() { if (m_originalCasterGUID == m_caster->GetGUID()) m_originalCaster = m_caster; @@ -6313,13 +6330,18 @@ void Spell::UpdatePointers() } if (m_castItemGUID && m_caster->GetTypeId() == TYPEID_PLAYER) + { m_CastItem = m_caster->ToPlayer()->GetItemByGuid(m_castItemGUID); + // cast item not found, somehow the item is no longer where we expected + if (!m_CastItem) + return false; + } m_targets.Update(m_caster); // further actions done only for dest targets if (!m_targets.HasDst()) - return; + return true; // cache last transport WorldObject* transport = NULL; @@ -6340,6 +6362,8 @@ void Spell::UpdatePointers() dest._position.RelocateOffset(dest._transportOffset); } } + + return true; } CurrentSpellTypes Spell::GetCurrentContainer() const diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index db781e7c5a4..9c6353da486 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -486,7 +486,7 @@ class Spell SpellInfo const* GetSpellInfo() const { return m_spellInfo; } int32 GetPowerCost() const { return m_powerCost; } - void UpdatePointers(); // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc) + bool UpdatePointers(); // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc) void CleanupTargetList(); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 775f6540944..31e0006d9f3 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2096,6 +2096,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex) m_targets.SetItemTarget(NULL); m_CastItem = NULL; + m_castItemGUID = 0; player->StoreItem(dest, pNewItem, true); return; @@ -2114,6 +2115,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex) m_targets.SetItemTarget(NULL); m_CastItem = NULL; + m_castItemGUID = 0; player->BankItem(dest, pNewItem, true); return; @@ -2136,6 +2138,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex) m_targets.SetItemTarget(NULL); m_CastItem = NULL; + m_castItemGUID = 0; player->EquipItem(dest, pNewItem, true); player->AutoUnequipOffhandIfNeed(); -- cgit v1.2.3 From 3aca9e64b34baee781f402c3f33ad7ee7991c232 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sun, 4 May 2014 13:41:07 +0200 Subject: Core/Misc: Fix exploit Fix exploit that allowed to learn spells from recipes without consuming them. --- src/server/game/Spells/Spell.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src') diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 3a947b1b07f..3282ce880f9 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -6335,6 +6335,45 @@ bool Spell::UpdatePointers() // cast item not found, somehow the item is no longer where we expected if (!m_CastItem) return false; + + // check if the retrieved item can even cast the spell + ItemTemplate const* proto = m_CastItem->GetTemplate(); + bool spellFound = false; + for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) + { + if (proto->Spells[i].SpellId == GetSpellInfo()->Id) + { + spellFound = true; + break; + } + } + + // check enchantment if the spell wasn't found in item proto + if (!spellFound) + { + for (uint8 e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot) + { + uint32 enchant_id = m_CastItem->GetEnchantmentId(EnchantmentSlot(e_slot)); + SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if (!pEnchant) + continue; + + for (uint8 s = 0; s < MAX_ITEM_ENCHANTMENT_EFFECTS; ++s) + { + if (pEnchant->spellid[s] == GetSpellInfo()->Id) + { + spellFound = true; + break; + } + } + + if (spellFound) + break; + } + } + + if (!spellFound) + return false; } m_targets.Update(m_caster); -- cgit v1.2.3 From 1c0c163485a2ba1781abf5a1f72b168375199d40 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Sun, 4 May 2014 14:03:42 +0200 Subject: Core/Misc: Fix warning --- src/server/game/Spells/Spell.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 3282ce880f9..2dc501d896f 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -6341,7 +6341,7 @@ bool Spell::UpdatePointers() bool spellFound = false; for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) { - if (proto->Spells[i].SpellId == GetSpellInfo()->Id) + if (uint32(proto->Spells[i].SpellId) == GetSpellInfo()->Id) { spellFound = true; break; -- cgit v1.2.3 From 109495ac9b5120f302728887dcca9a4de0f921d9 Mon Sep 17 00:00:00 2001 From: Dehravor Date: Sun, 4 May 2014 20:30:19 +0200 Subject: Scripts/Ulduar: Fix crash when Algalon's Big Bang is casted by player --- .../scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp index bd446c60c90..67500382758 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp @@ -1196,7 +1196,7 @@ class spell_algalon_big_bang : public SpellScriptLoader bool Load() override { _targetCount = 0; - return true; + return GetCaster()->GetTypeId() == TYPEID_UNIT && GetCaster()->IsAIEnabled; } void CountTargets(std::list& targets) -- cgit v1.2.3 From 24ef7dbdf4b76d312cb1df44958c6ccc79bf75f4 Mon Sep 17 00:00:00 2001 From: Gacko Date: Sun, 4 May 2014 22:15:11 +0200 Subject: Core/GameObject: Solve some TODOs related to traps in GameObject::Update and improve logic. Some more changes, TODO solutions and a fix for traps like those in #1359 or #6388 will follow. --- src/server/game/Entities/GameObject/GameObject.cpp | 99 ++++++++++++---------- src/server/game/Entities/GameObject/GameObject.h | 2 +- 2 files changed, 55 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 77f9ca59db4..a8b63eddb85 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -451,84 +451,83 @@ void GameObject::Update(uint32 diff) if (isSpawned()) { - // traps can have time and can not have GameObjectTemplate const* goInfo = GetGOInfo(); if (goInfo->type == GAMEOBJECT_TYPE_TRAP) { if (m_cooldownTime >= time(NULL)) - return; + break; - // Type 2 - Bomb (will go away after casting it's spell) + // Type 2 (bomb) does not need to be triggered by a unit and despawns after casting its spell. if (goInfo->trap.type == 2) { - if (goInfo->trap.spellId) - CastSpell(NULL, goInfo->trap.spellId); // FIXME: null target won't work for target type 1 - SetLootState(GO_JUST_DEACTIVATED); + SetLootState(GO_ACTIVATED); break; } - // Type 0 and 1 - trap (type 0 will not get removed after casting a spell) - Unit* owner = GetOwner(); - Unit* ok = NULL; // pointer to appropriate target if found any - bool IsBattlegroundTrap = false; - //FIXME: this is activation radius (in different casting radius that must be selected from spell data) - /// @todo move activated state code (cast itself) to GO_ACTIVATED, in this place only check activating and set state - float radius = (float)(goInfo->trap.radius)/3*2; /// @todo rename radius to diameter (goInfo->trap.radius) should be (goInfo->trap.diameter) - if (!radius) - { - if (goInfo->trap.cooldown != 3) // cast in other case (at some triggering/linked go/etc explicit call) - return; - else - { - if (m_respawnTime > 0) - break; + // Type 0 despawns after being triggered, type 1 does not. - radius = (float)goInfo->trap.cooldown; // battlegrounds gameobjects has data2 == 0 && data5 == 3 - IsBattlegroundTrap = true; + bool isBattlegroundTrap; - if (!radius) - return; - } + /// @todo This is activation radius. Casting radius must be selected from spell data. + /// @todo Move activated state code to GO_ACTIVATED, in this place just check for activation and set state. + float radius; + if (!goInfo->trap.diameter) + { + // Cast in other case (at some triggering/linked go/etc explicit call) + if (goInfo->trap.cooldown != 3 || m_respawnTime > 0) + break; + + // Battleground gameobjects have data2 == 0 && data5 == 3 + isBattlegroundTrap = true; + radius = 3.f; + } else { + isBattlegroundTrap = false; + radius = goInfo->trap.diameter / 2.f; } - // Note: this hack with search required until GO casting not implemented - // search unfriendly creature - if (owner) // hunter trap + Unit* owner = GetOwner(); + // Pointer to appropriate target if found any + Unit* target = NULL; + + /// @todo this hack with search required until GO casting not implemented + // Hunter trap: Search units which are unfriendly to the trap's owner + if (owner) { Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck checker(this, owner, radius); - Trinity::UnitSearcher searcher(this, ok, checker); + Trinity::UnitSearcher searcher(this, target, checker); VisitNearbyGridObject(radius, searcher); - if (!ok) VisitNearbyWorldObject(radius, searcher); + if (!target) + VisitNearbyWorldObject(radius, searcher); } - else // environmental trap + // Environmental trap: Any target + else { - // environmental damage spells already have around enemies targeting but this not help in case not existed GO casting support - // affect only players + // Environmental damage spells already have around enemies targeting but this does not help in case of not existing GO casting support + // Affect only players Player* player = NULL; Trinity::AnyPlayerInObjectRangeCheck checker(this, radius); Trinity::PlayerSearcher searcher(this, player, checker); VisitNearbyWorldObject(radius, searcher); - ok = player; + target = player; } - if (ok) + if (target) { - // some traps do not have spell but should be triggered + // Some traps do not have a spell but should be triggered if (goInfo->trap.spellId) - CastSpell(ok, goInfo->trap.spellId); + CastSpell(target, goInfo->trap.spellId); - m_cooldownTime = time(NULL) + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)); // template or 4 seconds + // Template value or 4 seconds + m_cooldownTime = time(NULL) + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)); if (goInfo->trap.type == 1) SetLootState(GO_JUST_DEACTIVATED); - if (IsBattlegroundTrap && ok->GetTypeId() == TYPEID_PLAYER) - { - //Battleground gameobjects case - if (ok->ToPlayer()->InBattleground()) - if (Battleground* bg = ok->ToPlayer()->GetBattleground()) + // Battleground gameobjects case + if (isBattlegroundTrap) + if (Player* player = target->ToPlayer()) + if (Battleground* bg = player->GetBattleground()) bg->HandleTriggerBuff(GetGUID()); - } } } else if (uint32 max_charges = goInfo->GetCharges()) @@ -574,6 +573,16 @@ void GameObject::Update(uint32 diff) } else m_groupLootTimer -= diff; } + case GAMEOBJECT_TYPE_TRAP: + { + GameObjectTemplate const* goInfo = GetGOInfo(); + if (goInfo->trap.spellId) + /// @todo NULL target won't work for target type 1 + CastSpell(NULL, goInfo->trap.spellId); + + SetLootState(GO_JUST_DEACTIVATED); + break; + } default: break; } diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index e94bccc4835..511a04bb9af 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -123,7 +123,7 @@ struct GameObjectTemplate { uint32 lockId; //0 -> Lock.dbc uint32 level; //1 - uint32 radius; //2 radius for trap activation + uint32 diameter; //2 radius for trap activation uint32 spellId; //3 uint32 type; //4 0 trap with no despawn after cast. 1 trap despawns after cast. 2 bomb casts on spawn. uint32 cooldown; //5 time in secs -- cgit v1.2.3 From 99e04ddaf6b5c7a6634dcef21417ecf369bac081 Mon Sep 17 00:00:00 2001 From: Gacko Date: Sun, 4 May 2014 22:32:24 +0200 Subject: Fix indention from changes in previous commit. --- src/server/game/Entities/GameObject/GameObject.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 511a04bb9af..95d8933a1fa 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -123,7 +123,7 @@ struct GameObjectTemplate { uint32 lockId; //0 -> Lock.dbc uint32 level; //1 - uint32 diameter; //2 radius for trap activation + uint32 diameter; //2 radius for trap activation uint32 spellId; //3 uint32 type; //4 0 trap with no despawn after cast. 1 trap despawns after cast. 2 bomb casts on spawn. uint32 cooldown; //5 time in secs -- cgit v1.2.3 From b6bf83589c7000a9d327009a01d9a22ba4bc6df8 Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Mon, 5 May 2014 10:06:44 +0200 Subject: Core/Gameobject: Added missing break in 24ef7dbdf4b76d312cb1df44958c6ccc79bf75f4 --- src/server/game/Entities/GameObject/GameObject.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index a8b63eddb85..98cfb722e50 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -480,7 +480,9 @@ void GameObject::Update(uint32 diff) // Battleground gameobjects have data2 == 0 && data5 == 3 isBattlegroundTrap = true; radius = 3.f; - } else { + } + else + { isBattlegroundTrap = false; radius = goInfo->trap.diameter / 2.f; } @@ -573,6 +575,7 @@ void GameObject::Update(uint32 diff) } else m_groupLootTimer -= diff; } + break; case GAMEOBJECT_TYPE_TRAP: { GameObjectTemplate const* goInfo = GetGOInfo(); -- cgit v1.2.3 From d0e66932668bcae08e8d5f960a0175b4d16c7371 Mon Sep 17 00:00:00 2001 From: Gacko Date: Mon, 5 May 2014 12:35:41 +0200 Subject: Core/GameObject: Format comments and apply rename of previous commit. --- src/server/game/Entities/GameObject/GameObject.cpp | 10 ++++++---- src/server/game/Entities/GameObject/GameObject.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 98cfb722e50..1c86db771a5 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -422,7 +422,7 @@ void GameObject::Update(uint32 diff) } case GAMEOBJECT_TYPE_DOOR: case GAMEOBJECT_TYPE_BUTTON: - //we need to open doors if they are closed (add there another condition if this code breaks some usage, but it need to be here for battlegrounds) + // We need to open doors if they are closed (add there another condition if this code breaks some usage, but it need to be here for battlegrounds) if (GetGoState() != GO_STATE_READY) ResetDoorOrButton(); break; @@ -434,13 +434,15 @@ void GameObject::Update(uint32 diff) break; } - if (!m_spawnedByDefault) // despawn timer + // Despawn timer + if (!m_spawnedByDefault) { - // can be despawned or destroyed + // Can be despawned or destroyed SetLootState(GO_JUST_DEACTIVATED); return; } - // respawn timer + + // Respawn timer uint32 poolid = GetDBTableGUIDLow() ? sPoolMgr->IsPartOfAPool(GetDBTableGUIDLow()) : 0; if (poolid) sPoolMgr->UpdatePool(poolid, GetDBTableGUIDLow()); diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 95d8933a1fa..6e36639b84f 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -123,7 +123,7 @@ struct GameObjectTemplate { uint32 lockId; //0 -> Lock.dbc uint32 level; //1 - uint32 diameter; //2 radius for trap activation + uint32 diameter; //2 diameter for trap activation uint32 spellId; //3 uint32 type; //4 0 trap with no despawn after cast. 1 trap despawns after cast. 2 bomb casts on spawn. uint32 cooldown; //5 time in secs -- cgit v1.2.3 From c6bf7e0b1d615a22c2145c6f4a757a10a9eca92c Mon Sep 17 00:00:00 2001 From: Gacko Date: Mon, 5 May 2014 18:39:53 +0200 Subject: Core/GameObject: Store unit in GameObject::SetLootState - required for trap activation. --- src/server/game/Entities/GameObject/GameObject.cpp | 1 + src/server/game/Entities/GameObject/GameObject.h | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 1c86db771a5..f4f2a26240c 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -2015,6 +2015,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* void GameObject::SetLootState(LootState state, Unit* unit) { m_lootState = state; + m_lootStateUnit = unit; AI()->OnStateChanged(state, unit); sScriptMgr->OnGameObjectLootStateChanged(this, state, unit); if (m_model) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 6e36639b84f..7b73f9a2318 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -841,6 +841,7 @@ class GameObject : public WorldObject, public GridObject, public Map time_t m_respawnTime; // (secs) time of next respawn (or despawn if GO have owner()), uint32 m_respawnDelayTime; // (secs) if 0 then current GO state no dependent from timer LootState m_lootState; + Unit* m_lootStateUnit; bool m_spawnedByDefault; time_t m_cooldownTime; // used as internal reaction delay time store (not state change reaction). // For traps this: spell casting cooldown, for doors/buttons: reset time. -- cgit v1.2.3 From 3ac4e3033cb0f8b33554dcfbd29a2cf5d94a19bf Mon Sep 17 00:00:00 2001 From: Gacko Date: Mon, 5 May 2014 18:59:56 +0200 Subject: Core/GameObject: Add missing initialization of m_lootStateUnit --- src/server/game/Entities/GameObject/GameObject.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index f4f2a26240c..f9ff0d09b9f 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -47,6 +47,7 @@ GameObject::GameObject() : WorldObject(false), MapObject(), m_respawnTime = 0; m_respawnDelayTime = 300; m_lootState = GO_NOT_READY; + m_lootStateUnit = NULL; m_spawnedByDefault = true; m_usetimes = 0; m_spellId = 0; -- cgit v1.2.3 From 2878b0d1051ed01f9ff024828ed409f0db25cdc7 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Mon, 5 May 2014 20:05:33 +0200 Subject: Core/Misc: Fix enchants broken in 3aca9e64b34baee781f402c3f33ad7ee7991c232 Compare cast item entry instead of checking cast item spells to fix the exploit mentioned in 3aca9e64b34baee781f402c3f33ad7ee7991c232 without breaking any functionality. --- src/server/game/Spells/Spell.cpp | 48 ++++++++------------------------- src/server/game/Spells/Spell.h | 1 + src/server/game/Spells/SpellEffects.cpp | 3 +++ 3 files changed, 15 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 2dc501d896f..7c6f2552b44 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -571,6 +571,7 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme m_CastItem = NULL; m_castItemGUID = 0; + m_castItemEntry = 0; unitTarget = NULL; itemTarget = NULL; @@ -2806,9 +2807,15 @@ bool Spell::UpdateChanneledTargetList() void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggeredByAura) { if (m_CastItem) + { m_castItemGUID = m_CastItem->GetGUID(); + m_castItemEntry = m_CastItem->GetEntry(); + } else + { m_castItemGUID = 0; + m_castItemEntry = 0; + } InitExplicitTargets(*targets); @@ -4264,6 +4271,7 @@ void Spell::TakeCastItem() m_CastItem = NULL; m_castItemGUID = 0; + m_castItemEntry = 0; } } @@ -4509,6 +4517,7 @@ void Spell::TakeReagents() m_CastItem = NULL; m_castItemGUID = 0; + m_castItemEntry = 0; } // if GetItemTarget is also spell reagent @@ -6336,43 +6345,8 @@ bool Spell::UpdatePointers() if (!m_CastItem) return false; - // check if the retrieved item can even cast the spell - ItemTemplate const* proto = m_CastItem->GetTemplate(); - bool spellFound = false; - for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) - { - if (uint32(proto->Spells[i].SpellId) == GetSpellInfo()->Id) - { - spellFound = true; - break; - } - } - - // check enchantment if the spell wasn't found in item proto - if (!spellFound) - { - for (uint8 e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot) - { - uint32 enchant_id = m_CastItem->GetEnchantmentId(EnchantmentSlot(e_slot)); - SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); - if (!pEnchant) - continue; - - for (uint8 s = 0; s < MAX_ITEM_ENCHANTMENT_EFFECTS; ++s) - { - if (pEnchant->spellid[s] == GetSpellInfo()->Id) - { - spellFound = true; - break; - } - } - - if (spellFound) - break; - } - } - - if (!spellFound) + // check if the item is really the same, in case it has been wrapped for example + if (m_castItemEntry != m_CastItem->GetEntry()) return false; } diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 9c6353da486..341867ff787 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -451,6 +451,7 @@ class Spell SpellInfo const* const m_spellInfo; Item* m_CastItem; uint64 m_castItemGUID; + uint32 m_castItemEntry; uint8 m_cast_count; uint32 m_glyphIndex; uint32 m_preCastSpell; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 31e0006d9f3..65530b4b282 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2097,6 +2097,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex) m_CastItem = NULL; m_castItemGUID = 0; + m_castItemEntry = 0; player->StoreItem(dest, pNewItem, true); return; @@ -2116,6 +2117,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex) m_CastItem = NULL; m_castItemGUID = 0; + m_castItemEntry = 0; player->BankItem(dest, pNewItem, true); return; @@ -2139,6 +2141,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex) m_CastItem = NULL; m_castItemGUID = 0; + m_castItemEntry = 0; player->EquipItem(dest, pNewItem, true); player->AutoUnequipOffhandIfNeed(); -- cgit v1.2.3 From b48879ab7947b3910fb18d842cf05fcba8b5a5a2 Mon Sep 17 00:00:00 2001 From: Gacko Date: Mon, 5 May 2014 22:28:45 +0200 Subject: Core/GameObject: Finish moving activation code of traps to GO_ACTIVATED Fixing #6388 should be easier now... --- src/server/game/Entities/GameObject/GameObject.cpp | 72 ++++++++++------------ 1 file changed, 32 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index f9ff0d09b9f..4f3f4c73f3b 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -309,13 +309,13 @@ void GameObject::Update(uint32 diff) GameObjectTemplate const* goInfo = GetGOInfo(); // Bombs if (goInfo->trap.type == 2) - m_cooldownTime = time(NULL) + 10; // Hardcoded tooltip value + // Hardcoded tooltip value + m_cooldownTime = time(NULL) + 10; else if (Unit* owner = GetOwner()) - { if (owner->IsInCombat()) m_cooldownTime = time(NULL) + goInfo->trap.startDelay; - } - m_lootState = GO_READY; + + SetLootState(GO_READY); break; } case GAMEOBJECT_TYPE_TRANSPORT: @@ -396,7 +396,7 @@ void GameObject::Update(uint32 diff) if (targetGuid == dbtableHighGuid) // if linking self, never respawn (check delayed to next day) SetRespawnTime(DAY); else - m_respawnTime = (now > linkedRespawntime ? now : linkedRespawntime)+urand(5, MINUTE); // else copy time from master and add a little + m_respawnTime = (now > linkedRespawntime ? now : linkedRespawntime) + urand(5, MINUTE); // else copy time from master and add a little SaveRespawnTime(); // also save to DB immediately return; } @@ -468,47 +468,35 @@ void GameObject::Update(uint32 diff) } // Type 0 despawns after being triggered, type 1 does not. - - bool isBattlegroundTrap; - /// @todo This is activation radius. Casting radius must be selected from spell data. - /// @todo Move activated state code to GO_ACTIVATED, in this place just check for activation and set state. float radius; if (!goInfo->trap.diameter) { - // Cast in other case (at some triggering/linked go/etc explicit call) - if (goInfo->trap.cooldown != 3 || m_respawnTime > 0) + // Battleground traps: data2 == 0 && data5 == 3 + if (goInfo->trap.cooldown != 3) break; - // Battleground gameobjects have data2 == 0 && data5 == 3 - isBattlegroundTrap = true; radius = 3.f; } else - { - isBattlegroundTrap = false; radius = goInfo->trap.diameter / 2.f; - } - Unit* owner = GetOwner(); // Pointer to appropriate target if found any Unit* target = NULL; /// @todo this hack with search required until GO casting not implemented - // Hunter trap: Search units which are unfriendly to the trap's owner - if (owner) + if (Unit* owner = GetOwner()) { + // Hunter trap: Search units which are unfriendly to the trap's owner Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck checker(this, owner, radius); Trinity::UnitSearcher searcher(this, target, checker); VisitNearbyGridObject(radius, searcher); if (!target) VisitNearbyWorldObject(radius, searcher); } - // Environmental trap: Any target else { - // Environmental damage spells already have around enemies targeting but this does not help in case of not existing GO casting support - // Affect only players + // Environmental trap: Any player Player* player = NULL; Trinity::AnyPlayerInObjectRangeCheck checker(this, radius); Trinity::PlayerSearcher searcher(this, player, checker); @@ -517,23 +505,8 @@ void GameObject::Update(uint32 diff) } if (target) - { - // Some traps do not have a spell but should be triggered - if (goInfo->trap.spellId) - CastSpell(target, goInfo->trap.spellId); + SetLootState(GO_ACTIVATED, target); - // Template value or 4 seconds - m_cooldownTime = time(NULL) + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)); - - if (goInfo->trap.type == 1) - SetLootState(GO_JUST_DEACTIVATED); - - // Battleground gameobjects case - if (isBattlegroundTrap) - if (Player* player = target->ToPlayer()) - if (Battleground* bg = player->GetBattleground()) - bg->HandleTriggerBuff(GetGUID()); - } } else if (uint32 max_charges = goInfo->GetCharges()) { @@ -582,11 +555,30 @@ void GameObject::Update(uint32 diff) case GAMEOBJECT_TYPE_TRAP: { GameObjectTemplate const* goInfo = GetGOInfo(); - if (goInfo->trap.spellId) + if (goInfo->trap.type == 2 && goInfo->trap.spellId) + { /// @todo NULL target won't work for target type 1 CastSpell(NULL, goInfo->trap.spellId); + SetLootState(GO_JUST_DEACTIVATED); + } + else if (m_lootStateUnit) + { + // Some traps do not have a spell but should be triggered + if (goInfo->trap.spellId) + CastSpell(m_lootStateUnit, goInfo->trap.spellId); - SetLootState(GO_JUST_DEACTIVATED); + // Template value or 4 seconds + m_cooldownTime = time(NULL) + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)); + + if (goInfo->trap.type == 1) + SetLootState(GO_JUST_DEACTIVATED); + + // Battleground gameobjects have data2 == 0 && data5 == 3 + if (!goInfo->trap.diameter && goInfo->trap.cooldown == 3) + if (Player* player = m_lootStateUnit->ToPlayer()) + if (Battleground* bg = player->GetBattleground()) + bg->HandleTriggerBuff(GetGUID()); + } break; } default: -- cgit v1.2.3 From 41d9364b164aca67d66134a565890d2f8d49fbd0 Mon Sep 17 00:00:00 2001 From: Gacko Date: Tue, 6 May 2014 18:46:08 +0200 Subject: Core/GameObject: Fix crash added in c6bf7e0b1d615a22c2145c6f4a757a10a9eca92c Thanks @jackpoz --- src/server/game/Entities/GameObject/GameObject.cpp | 11 ++++++----- src/server/game/Entities/GameObject/GameObject.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 4f3f4c73f3b..ea27d7add1f 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -47,7 +47,7 @@ GameObject::GameObject() : WorldObject(false), MapObject(), m_respawnTime = 0; m_respawnDelayTime = 300; m_lootState = GO_NOT_READY; - m_lootStateUnit = NULL; + m_lootStateUnitGUID = 0; m_spawnedByDefault = true; m_usetimes = 0; m_spellId = 0; @@ -561,11 +561,12 @@ void GameObject::Update(uint32 diff) CastSpell(NULL, goInfo->trap.spellId); SetLootState(GO_JUST_DEACTIVATED); } - else if (m_lootStateUnit) + else if (m_lootStateUnitGUID) + if (Unit* target = Unit::GetUnit(*this, m_lootStateUnitGUID)) { // Some traps do not have a spell but should be triggered if (goInfo->trap.spellId) - CastSpell(m_lootStateUnit, goInfo->trap.spellId); + CastSpell(target, goInfo->trap.spellId); // Template value or 4 seconds m_cooldownTime = time(NULL) + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)); @@ -575,7 +576,7 @@ void GameObject::Update(uint32 diff) // Battleground gameobjects have data2 == 0 && data5 == 3 if (!goInfo->trap.diameter && goInfo->trap.cooldown == 3) - if (Player* player = m_lootStateUnit->ToPlayer()) + if (Player* player = target->ToPlayer()) if (Battleground* bg = player->GetBattleground()) bg->HandleTriggerBuff(GetGUID()); } @@ -2008,7 +2009,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* void GameObject::SetLootState(LootState state, Unit* unit) { m_lootState = state; - m_lootStateUnit = unit; + m_lootStateUnitGUID = unit ? unit->GetGUID() : 0; AI()->OnStateChanged(state, unit); sScriptMgr->OnGameObjectLootStateChanged(this, state, unit); if (m_model) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 7b73f9a2318..a99c5db93aa 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -841,7 +841,7 @@ class GameObject : public WorldObject, public GridObject, public Map time_t m_respawnTime; // (secs) time of next respawn (or despawn if GO have owner()), uint32 m_respawnDelayTime; // (secs) if 0 then current GO state no dependent from timer LootState m_lootState; - Unit* m_lootStateUnit; + uint64 m_lootStateUnitGUID; // GUID of the unit passed with SetLootState(LootState, Unit*) bool m_spawnedByDefault; time_t m_cooldownTime; // used as internal reaction delay time store (not state change reaction). // For traps this: spell casting cooldown, for doors/buttons: reset time. -- cgit v1.2.3 From 111bbb3620093f7db9bb94c37fcbc97c0a45c4c3 Mon Sep 17 00:00:00 2001 From: Gacko Date: Tue, 6 May 2014 19:06:59 +0200 Subject: Remove unnecessary check in previous fix --- src/server/game/Entities/GameObject/GameObject.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index ea27d7add1f..8051c757bf2 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -561,8 +561,7 @@ void GameObject::Update(uint32 diff) CastSpell(NULL, goInfo->trap.spellId); SetLootState(GO_JUST_DEACTIVATED); } - else if (m_lootStateUnitGUID) - if (Unit* target = Unit::GetUnit(*this, m_lootStateUnitGUID)) + else if (Unit* target = Unit::GetUnit(*this, m_lootStateUnitGUID)) { // Some traps do not have a spell but should be triggered if (goInfo->trap.spellId) -- cgit v1.2.3 From eabec73d98d6885c24dbabc9fe10f64fdd290adc Mon Sep 17 00:00:00 2001 From: MitchesD Date: Thu, 8 May 2014 17:45:11 +0200 Subject: Scripts/Duskwood: prevention to spawn multiple Twilight Corrupter and fixed some issues there --- .../2014_05_09_02_world_creature_template.sql | 1 + .../scripts/EasternKingdoms/zone_duskwood.cpp | 56 +++++++++++----------- 2 files changed, 30 insertions(+), 27 deletions(-) create mode 100644 sql/updates/world/2014_05_09_02_world_creature_template.sql (limited to 'src') diff --git a/sql/updates/world/2014_05_09_02_world_creature_template.sql b/sql/updates/world/2014_05_09_02_world_creature_template.sql new file mode 100644 index 00000000000..5520ca5d6f8 --- /dev/null +++ b/sql/updates/world/2014_05_09_02_world_creature_template.sql @@ -0,0 +1 @@ +UPDATE `creature_template` SET `faction`=14 WHERE `entry`=15625; diff --git a/src/server/scripts/EasternKingdoms/zone_duskwood.cpp b/src/server/scripts/EasternKingdoms/zone_duskwood.cpp index 236455137dc..4eaf98d0a0e 100644 --- a/src/server/scripts/EasternKingdoms/zone_duskwood.cpp +++ b/src/server/scripts/EasternKingdoms/zone_duskwood.cpp @@ -29,18 +29,19 @@ EndScriptData */ enum TwilightCorrupter { - ITEM_FRAGMENT = 21149, NPC_TWILIGHT_CORRUPTER = 15625, - YELL_TWILIGHTCORRUPTOR_RESPAWN = 0, - YELL_TWILIGHTCORRUPTOR_AGGRO = 1, - YELL_TWILIGHTCORRUPTOR_KILL = 2, + YELL_TWILIGHT_CORRUPTOR_RESPAWN = 0, + YELL_TWILIGHT_CORRUPTOR_AGGRO = 1, + YELL_TWILIGHT_CORRUPTOR_KILL = 2, + SPELL_SOUL_CORRUPTION = 25805, SPELL_CREATURE_OF_NIGHTMARE = 25806, SPELL_LEVEL_UP = 24312, EVENT_SOUL_CORRUPTION = 1, EVENT_CREATURE_OF_NIGHTMARE = 2, - FACTION_HOSTILE = 14 + + QUEST_NIGHTMARES_CORRUPTION = 8735 }; /*###### @@ -58,12 +59,13 @@ public: void Reset() override { - KillCount = 0; + _events.Reset(); + KillCount = 0; } void EnterCombat(Unit* /*who*/) override { - Talk(YELL_TWILIGHTCORRUPTOR_AGGRO); + Talk(YELL_TWILIGHT_CORRUPTOR_AGGRO); _events.ScheduleEvent(EVENT_SOUL_CORRUPTION, 15000); _events.ScheduleEvent(EVENT_CREATURE_OF_NIGHTMARE, 30000); } @@ -73,7 +75,7 @@ public: if (victim->GetTypeId() == TYPEID_PLAYER) { ++KillCount; - Talk(YELL_TWILIGHTCORRUPTOR_KILL, victim); + Talk(YELL_TWILIGHT_CORRUPTOR_KILL, victim); if (KillCount == 3) { @@ -90,22 +92,27 @@ public: _events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_SOUL_CORRUPTION: - DoCastVictim(SPELL_SOUL_CORRUPTION); - _events.ScheduleEvent(EVENT_SOUL_CORRUPTION, rand()%4000+15000); + DoCastAOE(SPELL_SOUL_CORRUPTION); + _events.ScheduleEvent(EVENT_SOUL_CORRUPTION, urand(15000, 19000)); break; case EVENT_CREATURE_OF_NIGHTMARE: - DoCastVictim(SPELL_CREATURE_OF_NIGHTMARE); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + DoCast(target, SPELL_CREATURE_OF_NIGHTMARE); _events.ScheduleEvent(EVENT_CREATURE_OF_NIGHTMARE, 45000); break; default: break; } } + DoMeleeAttackIfReady(); } @@ -124,27 +131,22 @@ public: # at_twilight_grove ######*/ +Position const TwillightCorrupter = { -10328.16f, -489.57f, 49.95f, 0.0f }; + class at_twilight_grove : public AreaTriggerScript { -public: - at_twilight_grove() : AreaTriggerScript("at_twilight_grove") { } + public: + at_twilight_grove() : AreaTriggerScript("at_twilight_grove") { } - bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) override - { - if (player->HasQuestForItem(ITEM_FRAGMENT)) + bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) override { - if (Unit* corrupter = player->SummonCreature(NPC_TWILIGHT_CORRUPTER, -10328.16f, -489.57f, 49.95f, 0, TEMPSUMMON_MANUAL_DESPAWN, 60000)) - corrupter->setFaction(FACTION_HOSTILE); + if (player->GetQuestStatus(QUEST_NIGHTMARES_CORRUPTION) == QUEST_STATUS_INCOMPLETE) + if (!player->FindNearestCreature(NPC_TWILIGHT_CORRUPTER, 500.0f, true)) + if (Creature* corrupter = player->SummonCreature(NPC_TWILIGHT_CORRUPTER, TwillightCorrupter, TEMPSUMMON_MANUAL_DESPAWN, 60000)) + corrupter->AI()->Talk(YELL_TWILIGHT_CORRUPTOR_RESPAWN, player); - if (Creature* CorrupterSpeaker = player->SummonCreature(1, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()-1, 0, TEMPSUMMON_TIMED_DESPAWN, 15000)) - { - CorrupterSpeaker->SetName("Twilight Corrupter"); - CorrupterSpeaker->SetVisible(true); - CorrupterSpeaker->AI()->Talk(YELL_TWILIGHTCORRUPTOR_RESPAWN, player); - } - } - return false; - }; + return false; + }; }; void AddSC_duskwood() -- cgit v1.2.3 From 71795bf9776183429455d5742125b069836810e4 Mon Sep 17 00:00:00 2001 From: Discover- Date: Fri, 9 May 2014 17:58:04 +0200 Subject: Core/Trade: It's no longer possible to fake the amount of gold put into the trade window. It's only visual but still an exploit, allowing scamming. --- src/server/game/Entities/Player/Player.cpp | 6 ++++++ src/server/game/Handlers/TradeHandler.cpp | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a701e6fc38f..e7d14d68377 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -364,6 +364,12 @@ void TradeData::SetMoney(uint32 money) if (m_money == money) return; + if (!m_player->HasEnoughMoney(money)) + { + m_player->GetSession()->SendTradeStatus(TRADE_STATUS_BUSY); + return; + } + m_money = money; SetAccepted(false); diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index 4372de9eafe..1fe4718d7ae 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -686,7 +686,6 @@ void WorldSession::HandleSetTradeGoldOpcode(WorldPacket& recvPacket) if (!my_trade) return; - // gold can be incorrect, but this is checked at trade finished. my_trade->SetMoney(gold); } -- cgit v1.2.3 From 8e7cf15dd1a5aea0b4b77fc7853f0fdc21f7a8d9 Mon Sep 17 00:00:00 2001 From: MitchesD Date: Mon, 28 Apr 2014 22:26:43 +0200 Subject: Scripts/HallsOfReflection: Major changes * corrections to Intro Event (Falric, Marwyn etc.) * fixed issues with Frostsworn General * improved the whole Wrath of the Lich King event * implemented outro gunship * optimalization code and cleanup and fixed some typos * Big thanks to @joschiwald, he is author too ;-) --- .../2014_05_10_01_world_halls_of_reflection.sql | 218 ++ src/server/game/AI/CoreAI/UnitAI.cpp | 1 - src/server/game/AI/ScriptedAI/ScriptedCreature.cpp | 3 - src/server/game/Entities/GameObject/GameObject.cpp | 2 +- src/server/game/Entities/Transport/Transport.cpp | 15 +- src/server/game/Maps/Map.cpp | 44 +- src/server/game/Spells/Auras/SpellAuras.cpp | 12 +- src/server/game/Spells/SpellMgr.cpp | 12 + .../FrozenHalls/HallsOfReflection/boss_falric.cpp | 162 +- .../FrozenHalls/HallsOfReflection/boss_marwyn.cpp | 164 +- .../HallsOfReflection/halls_of_reflection.cpp | 3362 +++++++++++--------- .../HallsOfReflection/halls_of_reflection.h | 275 +- .../instance_halls_of_reflection.cpp | 1168 ++++--- 13 files changed, 3152 insertions(+), 2286 deletions(-) create mode 100644 sql/updates/world/2014_05_10_01_world_halls_of_reflection.sql (limited to 'src') diff --git a/sql/updates/world/2014_05_10_01_world_halls_of_reflection.sql b/sql/updates/world/2014_05_10_01_world_halls_of_reflection.sql new file mode 100644 index 00000000000..6d6c8feb956 --- /dev/null +++ b/sql/updates/world/2014_05_10_01_world_halls_of_reflection.sql @@ -0,0 +1,218 @@ +SET @CGUID := 142975; -- need 93 +DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+92; +INSERT INTO `creature` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `MovementType`) VALUES +-- The Skybreaker +(@CGUID+0, 30351, 712, 3, 1, 40.85356, 44.65979, 25.11708, 2.617994, 7200, 0, 0), +(@CGUID+1, 30867, 712, 3, 1, -32.58828, 22.11204, 21.78542, 1.762783, 7200, 0, 0), +(@CGUID+2, 30867, 712, 3, 1, -11.11922, 23.02313, 21.71026, 1.727876, 7200, 0, 0), +(@CGUID+3, 30867, 712, 3, 1, 36.80393, 45.60984, 25.11626, 1.43117, 7200, 0, 0), +(@CGUID+4, 30351, 712, 3, 1, 1.432831, 22.45517, 21.75367, 3.193953, 7200, 0, 0), +(@CGUID+5, 30394, 712, 3, 1, -57.66117, -6.004808, 23.56313, 4.956735, 7200, 0, 0), +(@CGUID+6, 30351, 712, 3, 1, 1.032896, 9.635975, 20.53982, 3.211406, 7200, 0, 0), +(@CGUID+7, 30351, 712, 3, 1, -36.27486, -6.711545, 20.53283, 1.53589, 7200, 0, 0), +(@CGUID+8, 30351, 712, 3, 1, -36.26366, 6.612509, 20.5329, 4.642576, 7200, 0, 0), +(@CGUID+9, 30352, 712, 3, 1, -16.93313, 2.497342, 20.87589, 3.106686, 7200, 0, 0), +(@CGUID+10, 30352, 712, 3, 1, -49.00542, 0.003014, 20.75066, 0.01745329, 7200, 0, 0), +(@CGUID+11, 30352, 712, 3, 1, 16.73826, 2.378118, 20.50117, 3.159046, 7200, 0, 0), +(@CGUID+12, 30352, 712, 3, 1, 48.81408, 8.76864, 40.16452, 1.675516, 7200, 0, 0), +(@CGUID+13, 30352, 712, 3, 1, -16.85414, -2.518523, 20.87587, 3.263766, 7200, 0, 0), +(@CGUID+14, 30351, 712, 3, 1, 4.010166, -22.42914, 21.77942, 0.2617994, 7200, 0, 0), +(@CGUID+15, 30351, 712, 3, 1, 0.778628, -9.484917, 20.5411, 3.036873, 7200, 0, 0), +(@CGUID+16, 30867, 712, 3, 1, -9.599308, -23.15501, 21.71576, 4.782202, 7200, 0, 0), +(@CGUID+17, 30352, 712, 3, 1, 48.82674, -8.803922, 40.16443, 4.712389, 7200, 0, 0), +(@CGUID+18, 30867, 712, 3, 1, -32.99351, -22.17393, 21.7879, 4.502949, 7200, 0, 0), +(@CGUID+19, 30867, 712, 3, 1, 37.14339, -45.94594, 25.11639, 4.014257, 7200, 0, 0), +(@CGUID+20, 30344, 712, 3, 1, -2.700737, 12.2316, 20.52945, 1.727876, 7200, 0, 0), +(@CGUID+21, 22515, 712, 3, 1, -27.09398, 38.85326, 1.366914, 1.256637, 7200, 0, 0), +(@CGUID+22, 22515, 712, 3, 1, -6.396934, 39.80114, 1.470398, 1.256637, 7200, 0, 0), +(@CGUID+23, 22515, 712, 3, 1, 4.017809, 38.32001, 1.533938, 1.256637, 7200, 0, 0), +(@CGUID+24, 30392, 712, 3, 1, 28.1948, 7.542603, 23.37183, 5.8294, 7200, 0, 0), +(@CGUID+25, 30833, 712, 3, 1, 6.518055, 0.003965, 20.66434, 0, 7200, 0, 0), +(@CGUID+26, 30350, 712, 3, 1, 16.36582, -2.323581, 20.49201, 3.141593, 7200, 0, 0), +(@CGUID+27, 30347, 712, 3, 1, 28.24817, -7.667989, 23.37183, 0.4363323, 7200, 0, 0), +-- Orgrim Hammer +(@CGUID+28, 30755, 713, 3, 1, -18.96152, 27.52218, 90.04992, 6.213372, 7200, 0, 0), +(@CGUID+29, 30754, 713, 3, 1, -54.68485, 15.01545, 34.49284, 2.338741, 7200, 0, 0), +(@CGUID+30, 30752, 713, 3, 1, -10.94232, 32.12282, 10.65215, 1.518436, 7200, 0, 0), +(@CGUID+31, 30754, 713, 3, 1, -8.504885, -0.019059, 86.17371, 3.159046, 7200, 0, 0), +(@CGUID+32, 30866, 713, 3, 1, -36.03656, 23.91632, 34.00398, 1.937315, 7200, 0, 0), +(@CGUID+33, 30754, 713, 3, 1, 29.97084, 29.32993, 89.84912, 0.122173, 7200, 0, 0), +(@CGUID+34, 30753, 713, 3, 1, 15.19238, -0.108369, 86.17371, 3.071779, 7200, 0, 0), +(@CGUID+35, 30752, 713, 3, 1, 7.702429, 25.23042, 35.08076, 4.764749, 7200, 0, 0), +(@CGUID+36, 30755, 713, 3, 1, 8.555423, 5.155768, 84.79706, 3.560472, 7200, 0, 0), +(@CGUID+37, 30755, 713, 3, 1, -4.588624, 27.91955, 34.27925, 4.729842, 7200, 0, 0), +(@CGUID+38, 30754, 713, 3, 1, -19.19535, -27.024, 90.05069, 3.124139, 7200, 0, 0), +(@CGUID+39, 30754, 713, 3, 1, -54.63672, -15.29832, 34.48149, 3.717551, 7200, 0, 0), +(@CGUID+40, 30753, 713, 3, 1, -26.19901, -10.37834, 35.63048, 1.64061, 7200, 0, 0), +(@CGUID+41, 30755, 713, 3, 1, -56.79522, -3.870484, 13.31639, 0.1047198, 7200, 0, 0), +(@CGUID+42, 30755, 713, 3, 1, -56.8364, 3.557915, 13.3138, 6.178465, 7200, 0, 0), +(@CGUID+43, 30753, 713, 3, 1, -34.95441, 11.84717, 11.5961, 1.082104, 7200, 0, 0), +(@CGUID+44, 30752, 713, 3, 1, 1.994709, 31.96335, 10.09305, 1.448623, 7200, 0, 0), +(@CGUID+45, 30753, 713, 3, 1, -26.06219, 10.57757, 35.58858, 4.712389, 7200, 0, 0), +(@CGUID+46, 30752, 713, 3, 1, 15.2307, 31.76827, 10.66515, 1.466077, 7200, 0, 0), +(@CGUID+47, 30753, 713, 3, 1, 1.994774, 17.06817, 9.246212, 1.500983, 7200, 0, 0), +(@CGUID+48, 30755, 713, 3, 1, -4.484874, 18.00111, 8.70937, 4.729842, 7200, 0, 0), +(@CGUID+49, 30755, 713, 3, 1, 8.521951, 17.92888, 8.777781, 4.625123, 7200, 0, 0), +(@CGUID+50, 30755, 713, 3, 1, -26.0374, 6.533113, 9.42994, 3.124139, 7200, 0, 0), +(@CGUID+51, 30755, 713, 3, 1, -19.30323, 6.17474, 6.879124, 0, 7200, 0, 0), +(@CGUID+52, 30755, 713, 3, 1, 8.786416, -5.037911, 84.79706, 2.740167, 7200, 0, 0), +(@CGUID+53, 30755, 713, 3, 1, 8.557505, 5.72448, 34.52152, 3.106686, 7200, 0, 0), +(@CGUID+54, 30755, 713, 3, 1, 8.450569, -5.609207, 34.52058, 2.792527, 7200, 0, 0), +(@CGUID+55, 30866, 713, 3, 1, -36.32559, -23.21568, 34.04234, 4.39823, 7200, 0, 0), +(@CGUID+56, 30753, 713, 3, 1, -35.48437, -11.9256, 11.71411, 5.986479, 7200, 0, 0), +(@CGUID+57, 30752, 713, 3, 1, 8.472344, -22.36673, 34.99833, 1.780236, 7200, 0, 0), +(@CGUID+58, 30755, 713, 3, 1, -4.738312, -28.17381, 34.26831, 1.466077, 7200, 0, 0), +(@CGUID+59, 30755, 713, 3, 1, 31.3718, -29.84369, 89.84172, 2.96706, 7200, 0, 0), +(@CGUID+60, 30755, 713, 3, 1, 37.59615, -9.010085, 30.1788, 0.05235988, 7200, 0, 0), +(@CGUID+61, 30755, 713, 3, 1, 37.52684, 8.718971, 30.17881, 5.969026, 7200, 0, 0), +(@CGUID+62, 30755, 713, 3, 1, -25.42656, -6.577197, 9.33257, 2.932153, 7200, 0, 0), +(@CGUID+63, 30755, 713, 3, 1, 23.24178, 6.302864, 7.032903, 3.176499, 7200, 0, 0), +(@CGUID+64, 30755, 713, 3, 1, -19.45751, -6.235432, 6.89157, 6.265732, 7200, 0, 0), +(@CGUID+65, 30752, 713, 3, 1, -11.36508, -29.14235, 10.01249, 4.642576, 7200, 0, 0), +(@CGUID+66, 30753, 713, 3, 1, 46.41658, 7.696208, 10.48851, 4.101524, 7200, 0, 0), +(@CGUID+67, 30752, 713, 3, 1, 15.44485, -29.7788, 9.977043, 4.694936, 7200, 0, 0), +(@CGUID+68, 30754, 713, 3, 1, 38.01897, -12.83605, 30.17452, 0.6108652, 7200, 0, 0), +(@CGUID+69, 30866, 713, 3, 1, 17.22244, -26.63993, 35.64188, 4.817109, 7200, 0, 0), +(@CGUID+70, 30752, 713, 3, 1, 2.069969, -29.66959, 9.395721, 4.677482, 7200, 0, 0), +(@CGUID+71, 30753, 713, 3, 1, 2.036507, -17.18819, 9.245911, 4.764749, 7200, 0, 0), +(@CGUID+72, 30753, 713, 3, 1, 46.33955, -7.35728, 10.47599, 2.391101, 7200, 0, 0), +(@CGUID+73, 30755, 713, 3, 1, 8.592517, -17.94128, 8.77952, 1.553343, 7200, 0, 0), +(@CGUID+74, 30755, 713, 3, 1, -4.406364, -17.97099, 8.709299, 1.48353, 7200, 0, 0), +(@CGUID+75, 30755, 713, 3, 1, 22.90693, -6.745431, 7.115322, 3.124139, 7200, 0, 0), +(@CGUID+76, 30824, 713, 3, 1, 17.28272, 21.73325, 35.37741, 1.623156, 7200, 0, 0), +(@CGUID+77, 30827, 713, 3, 1, 45.76886, -8.964413, 30.17881, 1.396263, 7200, 0, 0), +(@CGUID+78, 30825, 713, 3, 1, 38.55754, -0.025193, 10.27214, 3.106686, 7200, 0, 0), +(@CGUID+79, 30826, 713, 3, 1, 55.08521, -3.344726, 30.1788, 2.687807, 7200, 0, 0), +(@CGUID+80, 37593, 713, 3, 1, 2.015905, 34.44526, 10.09305, 1.64061, 7200, 0, 0), +(@CGUID+81, 37593, 713, 3, 1, 14.85607, 33.80163, 9.849781, 1.64061, 7200, 0, 0), +(@CGUID+82, 37593, 713, 3, 1, -10.84229, 34.34502, 10.6434, 1.64061, 7200, 0, 0), +-- Others +(@CGUID+83, 22515, 668, 3, 1, 5274.933, 1693.941, 797.2499, 0, 7200, 0, 0), +(@CGUID+84, 36736, 668, 3, 1, 5415.332, 2080.358, 720.5068, 1.64061, 7200, 0, 0), +(@CGUID+85, 36736, 668, 3, 1, 5376.905, 2115.425, 720.3566, 6.126106, 7200, 0, 0), +(@CGUID+86, 36736, 668, 3, 1, 5445.525, 2099.37, 720.3999, 2.600541, 7200, 0, 0), +(@CGUID+87, 36736, 668, 3, 1, 5431.74, 2087.503, 720.3914, 2.076942, 7200, 0, 0), +(@CGUID+88, 36736, 668, 3, 1, 5395.38, 2146.632, 720.2123, 5.305801, 7200, 0, 0), +(@CGUID+89, 36736, 668, 3, 1, 5380.971, 2134.462, 720.6889, 5.637414, 7200, 0, 0), +(@CGUID+90, 36736, 668, 3, 1, 5449.623, 2117.587, 720.4929, 3.176499, 7200, 0, 0), +(@CGUID+91, 36736, 668, 3, 1, 5412.493, 2150.627, 720.3359, 4.502949, 7200, 0, 0), +(@CGUID+92, 37071, 668, 3, 1, 5408.362, 2110.33, 726.9917, 3.630285, 7200, 0, 0); + +DELETE FROM `creature_template_addon` WHERE `entry`=36736; +INSERT INTO `creature_template_addon` (`entry`, `mount`, `bytes1`, `bytes2`, `auras`) VALUES +(36736, 0, 0x0, 0x1, '69174'); -- Invisible Stalker (Icecrown Dungeon Trap) - Reflection Window Beam Visual + +DELETE FROM `creature_text` WHERE `entry` IN (30344, 30824, 36954); +INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `comment`, `BroadcastTextID`) VALUES +-- High Captain Justin Bartlett +(30344, 0, 0, 'FIRE! FIRE!', 14, 0, 100, 0, 0, 16721, 'High Captain Justin Bartlett - Fire', 36993), +(30344, 1, 0, 'Quickly, climb aboard! We mustn''t tarry here! There''s no telling when this whole mountainside will collapse.', 14, 0, 100, 0, 0, 16722, 'High Captain Justin Bartlett - Final', 37213), +-- Sky-Reaver Korm Blackscar +(30824, 0, 0, 'FIRE! FIRE!', 14, 0, 100, 0, 0, 16732, 'Sky-Reaver Korm Blackscar - Fire', 38681), +(30824, 1, 0, 'Get on board, now! This whole mountainside could collapse at any moment.', 14, 0, 100, 0, 0, 16733, 'Sky-Reaver Korm Blackscar - Final', 37212), +-- Lich King +(36954, 0, 0, 'Your allies have arrived, Jaina, just as you promised. You will all become powerful agents of the Scourge..', 14, 0, 100, 0, 0, 17212, 'Lich King SAY_LICH_KING_AGGRO_A', 37172), +(36954, 1, 0, 'I will not make the same mistake again, Sylvanas. This time there will be no escape. You will all serve me in death!', 14, 0, 100, 0, 0, 17213, 'Lich King SAY_LICH_KING_AGGRO_H', 37173), +(36954, 2, 0, 'There is no escape!', 14, 0, 100, 0, 0, 17217, 'Lich King SAY_LICH_KING_WALL_01', 37177), +(36954, 3, 0, 'Succumb to the chill of the grave.', 14, 0, 100, 0, 0, 17218, 'Lich King SAY_LICH_KING_WALL_02', 37175), +(36954, 4, 0, 'Another dead end.', 14, 0, 100, 0, 0, 17219, 'Lich King SAY_LICH_KING_WALL_03', 37176), +(36954, 5, 0, 'How long can you fight it?', 14, 0, 100, 0, 0, 17220, 'Lich King SAY_LICH_KING_WALL_04', 38668), +(36954, 6, 0, 'Arise minions. Do not let them pass.', 14, 0, 100, 0, 0, 17216, 'Lich King SAY_LICH_KING_GHOUL', 38669), +(36954, 7, 0, 'Minions, sieze them. Bring their corpses back to me.', 14, 0, 100, 0, 0, 17222, 'Lich King SAY_LICH_KING_ABON', 38670), +(36954, 8, 0, 'Death''s cold embrace awaits.', 14, 0, 100, 0, 0, 17221, 'Lich King SAY_LICH_KING_WINTER', 37174), +(36954, 9, 0, 'Nowhere to run! You''re mine now...', 14, 0, 100, 0, 0, 17223, 'Lich King SAY_LICH_KING_END_DUN', 36994); + +DELETE FROM `areatrigger_scripts` WHERE `entry` IN (5605,5740); +INSERT INTO `areatrigger_scripts` (`entry`,`scriptname`) VALUES +(5605, 'at_hor_shadow_throne'), +(5740, 'at_hor_impenetrable_door'); + +DELETE FROM `areatrigger_teleport` WHERE `id`=5740; +INSERT INTO `areatrigger_teleport` (`id`, `name`, `target_map`, `target_position_x`, `target_position_y`, `target_position_z`, `target_orientation`) VALUES +(5740, 'Halls of Reflection (The Impenetrable Door)', 668, 5354.01, 2053.53, 707.695, 0.7853982); + +DELETE FROM `lfg_entrances` WHERE `dungeonId` IN(255,256); +INSERT INTO `lfg_entrances` (`dungeonId`, `name`, `position_x`, `position_y`, `position_z`, `orientation`) VALUES +(255, 'Halls of Reflection (Normal)', 5239.01, 1932.64, 707.695, 0.800565), +(256, 'Halls of Reflection (Heroic)', 5239.01, 1932.64, 707.695, 0.800565); + +-- Lady Jaina Proudmoore +UPDATE `creature_template` SET `ScriptName`='npc_jaina_or_sylvanas_intro_hor' WHERE `entry`=37221; +-- Lady Sylvanas Windrunner +UPDATE `creature_template` SET `ScriptName`='npc_jaina_or_sylvanas_intro_hor' WHERE `entry`=37223; +-- Frostsworn General +UPDATE `creature_template` SET `ScriptName`='npc_frostsworn_general' WHERE `entry`=36723; +-- The Lich King +UPDATE `creature_template` SET `ScriptName`='npc_the_lich_king_escape_hor', `mechanic_immune_mask`=617299839 WHERE `entry` = 36954; +-- Icecrown Dungeon Horde Gunship Cannon +UPDATE `creature_template` SET `InhabitType`=4 WHERE `entry`=37593; + +UPDATE `gameobject_template` SET `faction`=2102,`flags`=32 WHERE `entry`=201385; +UPDATE `gameobject_template` SET `faction`=1375,`flags`=32 WHERE `entry` IN (201596,201709,202211); +UPDATE `gameobject_template` SET `flags`=40 WHERE `entry` IN (201598,201599); +UPDATE `gameobject_template` SET `faction`=35,`flags`=16 WHERE `entry` IN (201710,202212,202336,202337); + + -- Lady Jaina Proudmoore +UPDATE `creature_template` SET `spell1`=0, `gossip_menu_id`=10860 WHERE `entry`=36955; + -- Lady Sylvanas Windrunner +UPDATE `creature_template` SET `gossip_menu_id`=10909 WHERE `entry`=37554; + +DELETE FROM `gossip_menu` WHERE `entry`=10931; +INSERT INTO `gossip_menu` (`entry`, `text_id`) VALUES +(10931, 15190); -- 37554 -- outro gossip + +UPDATE `gossip_menu_option` SET `option_id`=1, `npc_option_npcflag`=1 WHERE `menu_id`=10860 AND `id`=0; + +-- skip intro +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup` IN (11031,10950); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(15,11031,1,0,0,14,0,24500,0,0,1,0,0,'','Show options only if quest 24500 taken/complete/rewarded'), +(15,10950,1,0,0,14,0,24802,0,0,1,0,0,'','Show options only if quest 24802 taken/complete/rewarded'); + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (72900,70190,70017,72368,72369); +INSERT INTO `spell_script_names` (`spell_id` ,`ScriptName`) VALUES +(72900, 'spell_hor_start_halls_of_reflection_quest_ae'), +(70190, 'spell_hor_evasion'), +(70017, 'spell_hor_gunship_cannon_fire'), +(72368, 'spell_marwyn_shared_suffering'), +(72369, 'spell_marwyn_shared_suffering'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (69857,70199,70021,70246); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13,1,69857,0,0,31,0,3,36954,0,0,0,0,'','Taunt Arthas targets The Lich King'), +(13,2,70199,0,0,31,0,3,36954,0,0,0,0,'','Blinding Retreat targets The Lich King'), +(13,1,70021,0,0,31,0,3,22515,0,0,0,0,'','Gunship Cannon Fire targets World Trigger'), +(13,1,70021,0,0,1,0,70017,0,0,1,0,0,'','Gunship Cannon Fire target not has aura Gunship Cannon Fire'), +(13,1,70246,0,0,31,0,3,22515,0,0,0,0,'','Gunship Cannon Fire targets World Trigger'), +(13,1,70246,0,0,1,0,70017,0,0,1,0,0,'','Gunship Cannon Fire target not has aura Gunship Cannon Fire'); + +-- Cloak of Darkness proc on dodge +DELETE FROM `spell_proc_event` WHERE `entry`=70188; +INSERT INTO `spell_proc_event` (`entry`,`procEx`) VALUES +(70188,0x10); + +SET @OGUID := 21620; -- need 12 +DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+11; +INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES +(@OGUID+0, 201709, 668, 3, 1, 5228.354, 1640.958, 783.7306, 5.585054, 0, 0, 0, 1, -7200, 255, 1), +(@OGUID+1, 201709, 668, 3, 1, 5215.889, 1626.078, 796.4562, 5.585054, 0, 0, 0, 1, -7200, 255, 1), +(@OGUID+2, 202211, 668, 3, 1, 5242.835, 1623.45, 784.1498, 5.811947, 0, 0, 0, 1, -7200, 255, 1), +(@OGUID+3, 202211, 668, 3, 1, 5225.201, 1589.099, 808.5507, 5.811947, 0, 0, 0, 1, -7200, 255, 1), +(@OGUID+4, 202211, 668, 3, 1, 5233.985, 1606.311, 796.2543, 5.811947, 0, 0, 0, 1, -7200, 255, 1), +(@OGUID+5, 195682, 712, 3, 1, 4.395291, 13.68329, 20.80389, 4.19445, 0, 0, 0, 1, 7200, 255, 1), +(@OGUID+6, 201710, 712, 1, 1, -11.7548, 12.02463, 20.40827, 3.217069, 0, 0, 0, 1, 7200, 255, 1), +(@OGUID+7, 202336, 712, 2, 1, -11.7548, 12.02463, 20.40827, 3.217069, 0, 0, 0, 1, 7200, 255, 1), +(@OGUID+8, 202212, 713, 1, 1, 12.23327, 22.47315, 35.07432, 1.239183, 0, 0, 0, 1, 7200, 255, 1), +(@OGUID+9, 202337, 713, 2, 1, 12.23327, 22.47315, 35.07432, 1.239183, 0, 0, 0, 1, 7200, 255, 1), +(@OGUID+10, 195682, 713, 3, 1, 22.17697, 22.95274, 35.65761, 1.919862, 0, 0, 0, 1, 7200, 255, 1), +(@OGUID+11, 191640, 713, 3, 1, 42.08455, 14.60723, 10.65548, 4.244588, 0, 0, 0, 1, 7200, 255, 1); + +DELETE FROM `spelldifficulty_dbc` WHERE `id` IN(72395,72396,72397); +INSERT INTO `spelldifficulty_dbc` (`id`,`spellid0`,`spellid1`) VALUES +(72395,72395,72390), -- Hopelessness +(72396,72396,72391), -- Hopelessness +(72397,72397,72393); -- Hopelessness + +DELETE FROM `spell_custom_attr` WHERE `entry` = 74117; +INSERT INTO `spell_custom_attr` (`entry`,`attributes`) VALUES +(74117, 2); diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index 8bf34527769..9631b75fe06 100644 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -28,7 +28,6 @@ void UnitAI::AttackStart(Unit* victim) { - if (victim && me->Attack(victim, true)) me->GetMotionMaster()->MoveChase(victim); } diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index 36c1d384693..c205dd908c7 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -478,10 +478,7 @@ void BossAI::_JustDied() events.Reset(); summons.DespawnAll(); if (instance) - { instance->SetBossState(_bossId, DONE); - instance->SaveToDB(); - } } void BossAI::_EnterCombat() diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 8051c757bf2..49fe0a35b98 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -526,7 +526,7 @@ void GameObject::Update(uint32 diff) { case GAMEOBJECT_TYPE_DOOR: case GAMEOBJECT_TYPE_BUTTON: - if (GetGOInfo()->GetAutoCloseTime() && (m_cooldownTime < time(NULL))) + if (m_cooldownTime && (m_cooldownTime < time(NULL))) ResetDoorOrButton(); break; case GAMEOBJECT_TYPE_GOOBER: diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index fd45c3fc596..8bc07732bb6 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -85,8 +85,8 @@ bool Transport::Create(uint32 guidlow, uint32 entry, uint32 mapid, float x, floa _triggeredDepartureEvent = false; m_goValue.Transport.PathProgress = 0; - SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size); - SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction); + SetObjectScale(goinfo->size); + SetFaction(goinfo->faction); SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); SetPeriod(tInfo->pathTime); SetEntry(goinfo->entry); @@ -210,8 +210,14 @@ void Transport::Update(uint32 diff) 3. transport moves from active to inactive grid 4. the grid that transport is currently in unloads */ - if (_staticPassengers.empty() && GetMap()->IsGridLoaded(GetPositionX(), GetPositionY())) // 2. + bool gridActive = GetMap()->IsGridLoaded(GetPositionX(), GetPositionY()); + + if (_staticPassengers.empty() && gridActive) // 2. LoadStaticPassengers(); + else if (!_staticPassengers.empty() && !gridActive) + // 4. - if transports stopped on grid edge, some passengers can remain in active grids + // unload all static passengers otherwise passengers won't load correctly when the grid that transport is currently in becomes active + UnloadStaticPassengers(); } } @@ -450,6 +456,7 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu void Transport::UpdatePosition(float x, float y, float z, float o) { bool newActive = GetMap()->IsGridLoaded(x, y); + Cell oldCell(GetPositionX(), GetPositionY()); Relocate(x, y, z, o); UpdateModelPosition(); @@ -464,7 +471,7 @@ void Transport::UpdatePosition(float x, float y, float z, float o) */ if (_staticPassengers.empty() && newActive) // 1. LoadStaticPassengers(); - else if (!_staticPassengers.empty() && !newActive && Cell(x, y).DiffGrid(Cell(GetPositionX(), GetPositionY()))) // 3. + else if (!_staticPassengers.empty() && !newActive && oldCell.DiffGrid(Cell(GetPositionX(), GetPositionY()))) // 3. UnloadStaticPassengers(); else UpdatePassengerPositions(_staticPassengers); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index cd391299785..ba271235330 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -1544,11 +1544,8 @@ void Map::UnloadAll() Transport* transport = *itr; ++itr; - transport->RemoveFromWorld(); - delete transport; + RemoveFromMap(transport, true); } - - _transports.clear(); } // ***************************** @@ -2648,24 +2645,27 @@ void Map::RemoveAllObjectsInRemoveList() RemoveFromMap(corpse, true); break; } - case TYPEID_DYNAMICOBJECT: - RemoveFromMap((DynamicObject*)obj, true); - break; - case TYPEID_GAMEOBJECT: - if (Transport* transport = obj->ToGameObject()->ToTransport()) - RemoveFromMap(transport, true); - else - RemoveFromMap(obj->ToGameObject(), true); - break; - case TYPEID_UNIT: - // in case triggered sequence some spell can continue casting after prev CleanupsBeforeDelete call - // make sure that like sources auras/etc removed before destructor start - obj->ToCreature()->CleanupsBeforeDelete(); - RemoveFromMap(obj->ToCreature(), true); - break; - default: - TC_LOG_ERROR("maps", "Non-grid object (TypeId: %u) is in grid object remove list, ignored.", obj->GetTypeId()); - break; + case TYPEID_DYNAMICOBJECT: + RemoveFromMap(obj->ToDynObject(), true); + break; + case TYPEID_GAMEOBJECT: + { + GameObject* go = obj->ToGameObject(); + if (Transport* transport = go->ToTransport()) + RemoveFromMap(transport, true); + else + RemoveFromMap(go, true); + break; + } + case TYPEID_UNIT: + // in case triggered sequence some spell can continue casting after prev CleanupsBeforeDelete call + // make sure that like sources auras/etc removed before destructor start + obj->ToCreature()->CleanupsBeforeDelete(); + RemoveFromMap(obj->ToCreature(), true); + break; + default: + TC_LOG_ERROR("maps", "Non-grid object (TypeId: %u) is in grid object remove list, ignored.", obj->GetTypeId()); + break; } i_objectsToRemove.erase(itr); diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 8e7edfc5355..3e1763e6c5b 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1343,17 +1343,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b if (target->HasAura(61988) && !target->HasAura(25771)) target->RemoveAura(61988); break; - case 72368: // Shared Suffering - case 72369: - if (caster) - { - if (AuraEffect* aurEff = GetEffect(0)) - { - int32 remainingDamage = aurEff->GetAmount() * (aurEff->GetTotalTicks() - aurEff->GetTickNumber()); - if (remainingDamage > 0) - caster->CastCustomSpell(caster, 72373, NULL, &remainingDamage, NULL, true); - } - } + default: break; } break; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index ba5b8856323..501cb1e77f2 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3375,6 +3375,18 @@ void SpellMgr::LoadSpellInfoCorrections() break; // ENDOF TRIAL OF THE CRUSADER SPELLS // + // HALLS OF REFLECTION SPELLS + // + case 72435: // Defiling Horror + case 72452: // Defiling Horror + spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_60_YARDS); // 60yd + spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_60_YARDS); // 60yd + break; + case 72900: // Start Halls of Reflection Quest AE + spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd + break; + // ENDOF HALLS OF REFLECTION SPELLS + // // ICECROWN CITADEL SPELLS // // THESE SPELLS ARE WORKING CORRECTLY EVEN WITHOUT THIS HACK diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp index 9cf61058bd9..a5577b6a0ea 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp @@ -25,7 +25,7 @@ enum Texts SAY_SLAY = 1, SAY_DEATH = 2, SAY_IMPENDING_DESPAIR = 3, - SAY_DEFILING_HORROR = 4, + SAY_DEFILING_HORROR = 4 }; enum Spells @@ -33,8 +33,9 @@ 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. + SPELL_HOPELESSNESS_1 = 72395, + SPELL_HOPELESSNESS_2 = 72396, + SPELL_HOPELESSNESS_3 = 72397 }; enum Events @@ -42,99 +43,106 @@ enum Events EVENT_NONE, EVENT_QUIVERING_STRIKE, EVENT_IMPENDING_DESPAIR, - EVENT_DEFILING_HORROR, + EVENT_DEFILING_HORROR }; +uint32 const HopelessnessHelper[3] = { SPELL_HOPELESSNESS_1, SPELL_HOPELESSNESS_2, SPELL_HOPELESSNESS_3 }; + class boss_falric : public CreatureScript { -public: - boss_falric() : CreatureScript("boss_falric") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI(creature); - } - - struct boss_falricAI : public boss_horAI - { - boss_falricAI(Creature* creature) : boss_horAI(creature) { } - - uint8 uiHopelessnessCount; - - void Reset() override - { - boss_horAI::Reset(); - - uiHopelessnessCount = 0; + public: + boss_falric() : CreatureScript("boss_falric") { } - instance->SetBossState(DATA_FALRIC_EVENT, NOT_STARTED); - } - - void EnterCombat(Unit* /*who*/) override + struct boss_falricAI : public boss_horAI { - Talk(SAY_AGGRO); - instance->SetBossState(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. - } + boss_falricAI(Creature* creature) : boss_horAI(creature, DATA_FALRIC) { } - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEATH); - - instance->SetBossState(DATA_FALRIC_EVENT, DONE); - } + void Reset() override + { + boss_horAI::Reset(); + _hopelessnessCount = 0; + } - void KilledUnit(Unit* /*victim*/) override - { - Talk(SAY_SLAY); - } + void EnterCombat(Unit* /*who*/) override + { + Talk(SAY_AGGRO); + DoZoneInCombat(); + instance->SetBossState(DATA_FALRIC, IN_PROGRESS); - void UpdateAI(uint32 diff) override - { - // Return since we have no target - if (!UpdateVictim()) - return; + events.ScheduleEvent(EVENT_QUIVERING_STRIKE, 23000); + events.ScheduleEvent(EVENT_IMPENDING_DESPAIR, 9000); + events.ScheduleEvent(EVENT_DEFILING_HORROR, urand(21000, 39000)); + } - events.Update(diff); + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if ((_hopelessnessCount < 1 && me->HealthBelowPctDamaged(66, damage)) + || (_hopelessnessCount < 2 && me->HealthBelowPctDamaged(33, damage)) + || (_hopelessnessCount < 3 && me->HealthBelowPctDamaged(10, damage))) + { + if (_hopelessnessCount) + me->RemoveOwnedAura(sSpellMgr->GetSpellIdForDifficulty(HopelessnessHelper[_hopelessnessCount - 1], me)); + DoCast(me, HopelessnessHelper[_hopelessnessCount]); + ++_hopelessnessCount; + } + } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_DEATH); + events.Reset(); + instance->SetBossState(DATA_FALRIC, DONE); + } - switch (events.ExecuteEvent()) + void KilledUnit(Unit* who) override { - case EVENT_QUIVERING_STRIKE: - DoCast(SPELL_QUIVERING_STRIKE); - events.ScheduleEvent(EVENT_QUIVERING_STRIKE, 10000); - break; - case EVENT_IMPENDING_DESPAIR: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - { - Talk(SAY_IMPENDING_DESPAIR); - DoCast(target, 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 (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); } - if ((uiHopelessnessCount < 1 && HealthBelowPct(66)) - || (uiHopelessnessCount < 2 && HealthBelowPct(33)) - || (uiHopelessnessCount < 3 && HealthBelowPct(10))) + void UpdateAI(uint32 diff) override { - uiHopelessnessCount++; - DoCast(DUNGEON_MODE(SPELL_HOPELESSNESS, H_SPELL_HOPELESSNESS)); + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_QUIVERING_STRIKE: + DoCastVictim(SPELL_QUIVERING_STRIKE); + events.ScheduleEvent(EVENT_QUIVERING_STRIKE, 10000); + break; + case EVENT_IMPENDING_DESPAIR: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f, true)) + { + Talk(SAY_IMPENDING_DESPAIR); + DoCast(target, SPELL_IMPENDING_DESPAIR); + } + events.ScheduleEvent(EVENT_IMPENDING_DESPAIR, 13000); + break; + case EVENT_DEFILING_HORROR: + DoCastAOE(SPELL_DEFILING_HORROR); + events.ScheduleEvent(EVENT_DEFILING_HORROR, urand(21000, 39000)); + break; + default: + break; + } + + DoMeleeAttackIfReady(); } - DoMeleeAttackIfReady(); - } - }; + private: + uint8 _hopelessnessCount; + }; + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfReflectionAI(creature); + } }; void AddSC_boss_falric() diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp index cf267ff1079..902a917c594 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_marwyn.cpp @@ -17,6 +17,8 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" #include "halls_of_reflection.h" enum Texts @@ -33,6 +35,7 @@ enum Spells SPELL_WELL_OF_CORRUPTION = 72362, SPELL_CORRUPTED_FLESH = 72363, SPELL_SHARED_SUFFERING = 72368, + SPELL_SHARED_SUFFERING_DISPEL = 72373 }; enum Events @@ -41,93 +44,130 @@ enum Events EVENT_OBLITERATE, EVENT_WELL_OF_CORRUPTION, EVENT_CORRUPTED_FLESH, - EVENT_SHARED_SUFFERING, + EVENT_SHARED_SUFFERING }; class boss_marwyn : public CreatureScript { -public: - boss_marwyn() : CreatureScript("boss_marwyn") { } + public: + boss_marwyn() : CreatureScript("boss_marwyn") { } - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI(creature); - } - - struct boss_marwynAI : public boss_horAI - { - boss_marwynAI(Creature* creature) : boss_horAI(creature) { } - - void Reset() override + struct boss_marwynAI : public boss_horAI { - boss_horAI::Reset(); + boss_marwynAI(Creature* creature) : boss_horAI(creature, DATA_MARWYN) { } - instance->SetBossState(DATA_MARWYN_EVENT, NOT_STARTED); - } + void Reset() override + { + boss_horAI::Reset(); + } - void EnterCombat(Unit* /*who*/) override - { - Talk(SAY_AGGRO); - instance->SetBossState(DATA_MARWYN_EVENT, IN_PROGRESS); + void EnterCombat(Unit* /*who*/) override + { + Talk(SAY_AGGRO); + DoZoneInCombat(); + instance->SetBossState(DATA_MARWYN, IN_PROGRESS); + + events.ScheduleEvent(EVENT_OBLITERATE, urand(8000, 13000)); + events.ScheduleEvent(EVENT_WELL_OF_CORRUPTION, 13000); + events.ScheduleEvent(EVENT_CORRUPTED_FLESH, 20000); + events.ScheduleEvent(EVENT_SHARED_SUFFERING, urand(14000, 15000)); + } - 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*/) override + { + Talk(SAY_DEATH); + events.Reset(); + instance->SetBossState(DATA_MARWYN, DONE); + } - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEATH); + void KilledUnit(Unit* who) override + { + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - instance->SetBossState(DATA_MARWYN_EVENT, DONE); - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (events.ExecuteEvent()) + { + case EVENT_OBLITERATE: + DoCastVictim(SPELL_OBLITERATE); + events.ScheduleEvent(EVENT_OBLITERATE, urand(8000, 13000)); + break; + case EVENT_WELL_OF_CORRUPTION: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_WELL_OF_CORRUPTION); + events.ScheduleEvent(EVENT_WELL_OF_CORRUPTION, 13000); + break; + case EVENT_CORRUPTED_FLESH: + Talk(SAY_CORRUPTED_FLESH); + DoCastAOE(SPELL_CORRUPTED_FLESH); + events.ScheduleEvent(EVENT_CORRUPTED_FLESH, 20000); + break; + case EVENT_SHARED_SUFFERING: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + DoCast(target, SPELL_SHARED_SUFFERING); + events.ScheduleEvent(EVENT_SHARED_SUFFERING, urand(14000, 15000)); + break; + default: + break; + } + + DoMeleeAttackIfReady(); + } + }; - void KilledUnit(Unit* /*victim*/) override + CreatureAI* GetAI(Creature* creature) const override { - Talk(SAY_SLAY); + return GetHallsOfReflectionAI(creature); } +}; - void UpdateAI(uint32 diff) override - { - // Return since we have no target - if (!UpdateVictim()) - return; +// 72368, 72369 - Shared Suffering +class spell_marwyn_shared_suffering : public SpellScriptLoader +{ + public: + spell_marwyn_shared_suffering() : SpellScriptLoader("spell_marwyn_shared_suffering") { } - events.Update(diff); + class spell_marwyn_shared_suffering_AuraScript : public AuraScript + { + PrepareAuraScript(spell_marwyn_shared_suffering_AuraScript); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + void HandleEffectRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL) + return; + + if (Unit* caster = GetCaster()) + { + int32 remainingDamage = aurEff->GetAmount() * (aurEff->GetTotalTicks() - aurEff->GetTickNumber()); + if (remainingDamage > 0) + caster->CastCustomSpell(SPELL_SHARED_SUFFERING_DISPEL, SPELLVALUE_BASE_POINT1, remainingDamage, GetTarget(), TRIGGERED_FULL_MASK); + } + } - switch (events.ExecuteEvent()) + void Register() override { - 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: - Talk(SAY_CORRUPTED_FLESH); - DoCast(SPELL_CORRUPTED_FLESH); - events.ScheduleEvent(EVENT_CORRUPTED_FLESH, 20000); - break; - case EVENT_SHARED_SUFFERING: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_SHARED_SUFFERING); - events.ScheduleEvent(EVENT_SHARED_SUFFERING, 20000); - break; + AfterEffectRemove += AuraEffectRemoveFn(spell_marwyn_shared_suffering_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); } + }; - DoMeleeAttackIfReady(); + AuraScript* GetAuraScript() const override + { + return new spell_marwyn_shared_suffering_AuraScript(); } - }; - }; void AddSC_boss_marwyn() { new boss_marwyn(); + new spell_marwyn_shared_suffering(); } diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index ca2a181a48a..a86dcc26907 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -18,6 +18,8 @@ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" +#include "SpellScript.h" +#include "Transport.h" #include "Player.h" #include "halls_of_reflection.h" @@ -36,17 +38,6 @@ enum Text SAY_JAINA_INTRO_11 = 10, SAY_JAINA_INTRO_END = 11, - SAY_JAINA_ESCAPE_1 = 0, - SAY_JAINA_ESCAPE_2 = 1, - SAY_JAINA_ESCAPE_3 = 2, - SAY_JAINA_ESCAPE_4 = 3, - SAY_JAINA_ESCAPE_5 = 4, - SAY_JAINA_ESCAPE_6 = 5, - SAY_JAINA_ESCAPE_7 = 6, - SAY_JAINA_ESCAPE_8 = 7, - SAY_JAINA_ESCAPE_9 = 8, - SAY_JAINA_ESCAPE_10 = 9, - SAY_SYLVANAS_INTRO_1 = 0, SAY_SYLVANAS_INTRO_2 = 1, SAY_SYLVANAS_INTRO_3 = 2, @@ -57,16 +48,6 @@ enum Text SAY_SYLVANAS_INTRO_8 = 7, SAY_SYLVANAS_INTRO_END = 8, - SAY_SYLVANAS_ESCAPE_1 = 0, - SAY_SYLVANAS_ESCAPE_2 = 1, - SAY_SYLVANAS_ESCAPE_3 = 2, - SAY_SYLVANAS_ESCAPE_4 = 3, - SAY_SYLVANAS_ESCAPE_5 = 4, - SAY_SYLVANAS_ESCAPE_6 = 5, - SAY_SYLVANAS_ESCAPE_7 = 6, - SAY_SYLVANAS_ESCAPE_8 = 7, - SAY_SYLVANAS_ESCAPE_9 = 8, - SAY_UTHER_INTRO_A2_1 = 0, SAY_UTHER_INTRO_A2_2 = 1, SAY_UTHER_INTRO_A2_3 = 2, @@ -90,27 +71,40 @@ enum Text SAY_LK_JAINA_INTRO_END = 3, SAY_LK_SYLVANAS_INTRO_END = 4, + SAY_JAINA_SYLVANAS_ESCAPE_1 = 0, + SAY_JAINA_SYLVANAS_ESCAPE_2 = 1, + SAY_JAINA_SYLVANAS_ESCAPE_3 = 2, + SAY_JAINA_SYLVANAS_ESCAPE_4 = 3, + SAY_JAINA_SYLVANAS_ESCAPE_5 = 4, + SAY_JAINA_SYLVANAS_ESCAPE_6 = 5, + SAY_JAINA_SYLVANAS_ESCAPE_7 = 6, // unused + SAY_JAINA_SYLVANAS_ESCAPE_8 = 7, + + SAY_JAINA_ESCAPE_9 = 8, + SAY_JAINA_ESCAPE_10 = 9, + + SAY_SYLVANAS_ESCAPE_9 = 8, + SAY_LK_ESCAPE_1 = 0, SAY_LK_ESCAPE_2 = 1, - SAY_LK_ESCAPE_3 = 2, - SAY_LK_ESCAPE_4 = 3, - SAY_LK_ESCAPE_5 = 4, - SAY_LK_ESCAPE_6 = 5, - SAY_LK_ESCAPE_7 = 6, - SAY_LK_ESCAPE_8 = 7, - SAY_LK_ESCAPE_9 = 8, - SAY_LK_ESCAPE_10 = 9, - SAY_LK_ESCAPE_11 = 10, + SAY_LK_ESCAPE_ICEWALL_SUMMONED_1 = 2, + SAY_LK_ESCAPE_ICEWALL_SUMMONED_2 = 3, + SAY_LK_ESCAPE_ICEWALL_SUMMONED_3 = 4, + SAY_LK_ESCAPE_ICEWALL_SUMMONED_4 = 5, + SAY_LK_ESCAPE_GHOULS = 6, + SAY_LK_ESCAPE_ABOMINATION = 7, + SAY_LK_ESCAPE_WINTER = 8, + SAY_LK_ESCAPE_HARVEST_SOUL = 9, SAY_FALRIC_INTRO_1 = 5, SAY_FALRIC_INTRO_2 = 6, - SAY_MARWYN_INTRO_1 = 4, + SAY_MARWYN_INTRO_1 = 4 }; enum Events { - EVENT_WALK_INTRO1 = 1, + EVENT_WALK_INTRO1 = 1, EVENT_WALK_INTRO2, EVENT_START_INTRO, EVENT_SKIP_INTRO, @@ -181,21 +175,17 @@ enum Events EVENT_ESCAPE_13, EVENT_ESCAPE_14, EVENT_ESCAPE_15, - //EVENT_ESCAPE_16, + EVENT_ESCAPE_16, EVENT_ESCAPE_17, - EVENT_ESCAPE_18, - EVENT_ESCAPE_19, - EVENT_ESCAPE_20, - EVENT_ESCAPE_21, - EVENT_ESCAPE_22, - EVENT_ESCAPE_23, - EVENT_ESCAPE_24, - EVENT_ESCAPE_25, - EVENT_ESCAPE_26, - EVENT_ESCAPE_27, - - EVENT_OPEN_FROSTWORN_DOOR, - EVENT_CLOSE_FROSTWORN_DOOR, + + EVENT_REMORSELESS_WINTER, + EVENT_ESCAPE_SUMMON_GHOULS, + EVENT_ESCAPE_SUMMON_WITCH_DOCTOR, + EVENT_ESCAPE_SUMMON_LUMBERING_ABOMINATION, + + EVENT_OPEN_IMPENETRABLE_DOOR, + EVENT_CLOSE_IMPENETRABLE_DOOR, + EVENT_KORELN_LORALEN_DEATH }; enum Misc @@ -203,915 +193,1157 @@ enum Misc 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, + JAINA_SYLVANAS_MAX_HEALTH = 252000, + + POINT_SHADOW_THRONE_DOOR = 1, + POINT_ATTACK_ICEWALL = 2, + POINT_TRAP = 3, + + SOUND_LK_SLAY_1 = 17214, + SOUND_LK_SLAY_2 = 17215, + SOUND_LK_FURY_OF_FROSTMOURNE = 17224 }; enum Spells { - SPELL_CAST_VISUAL = 65633, // Jaina/Sylavana - SPELL_BOSS_SPAWN_AURA = 72712, // Falric and Marwyn - SPELL_UTHER_DESPAWN = 70693, + // Misc SPELL_TAKE_FROSTMOURNE = 72729, SPELL_FROSTMOURNE_DESPAWN = 72726, SPELL_FROSTMOURNE_VISUAL = 73220, SPELL_FROSTMOURNE_SOUNDS = 70667, - SPELL_JAINA_ICEBARRIER = 69787, // Jaina Ice Barrier - SPELL_JAINA_ICEPRISON = 69708, // Jaina Ice Prison - SPELL_SYLVANAS_CLOAKOFDARKNESS = 70188, // Sylvanas Cloak of Darkness - SPELL_SYLVANAS_DARKBINDING = 70194, // Sylvanas Dark Binding - SPELL_REMORSELESS_WINTER = 69780, // Lich King Remorseless Winter - SPELL_SOUL_REAPER = 69409, // Lich King Soul Reaper - SPELL_FURY_OF_FROSTMOURNE = 70063, // Lich King Fury of FrostMourne + SPELL_BOSS_SPAWN_AURA = 72712, // Falric and Marwyn + SPELL_UTHER_DESPAWN = 70693, + + // Jaina, Sylvanas + SPELL_CAST_VISUAL = 65633, // wrong + SPELL_SUMMON_SOULS = 72711, + SPELL_TAUNT_ARTHAS = 69857, + SPELL_JAINA_ICE_BARRIER = 69787, // Jaina Ice Barrier + SPELL_JAINA_ICE_PRISON = 69708, // Jaina Ice Prison SPELL_JAINA_DESTROY_ICE_WALL = 69784, // Jaina + SPELL_SYLVANAS_CLOAK_OF_DARKNESS = 70188, // Sylvanas Cloak of Darkness + SPELL_SYLVANAS_DARK_BINDING = 70194, // Sylvanas Dark Binding SPELL_SYLVANAS_DESTROY_ICE_WALL = 70224, // Sylvanas - SPELL_SYLVANAS_JUMP = 68339, // Sylvanas Jump + SPELL_SYLVANAS_BLINDING_RETREAT = 70199, // Sylvanas Blinding Retreat + + // Lich King + SPELL_REMORSELESS_WINTER = 69780, // Lich King Remorseless Winter + SPELL_SOUL_REAPER = 69409, // Lich King Soul Reaper + SPELL_FURY_OF_FROSTMOURNE = 70063, // Lich King Fury of Frostmourne SPELL_RAISE_DEAD = 69818, - SPELL_HARVEST_SOUL = 70070, - SPELL_SUMMON_RISE_WITCH_DOCTOR = 69836, + SPELL_SUMMON_RISEN_WITCH_DOCTOR = 69836, SPELL_SUMMON_LUMBERING_ABOMINATION = 69835, SPELL_SUMMON_ICE_WALL = 69768, // Visual effect and icewall summoning + SPELL_PAIN_AND_SUFFERING = 74115, // Lich King Pain and Suffering + SPELL_STUN_BREAK_JAINA = 69764, // Lich King visual spell, another Stun Break is 69763, should remove the stun effect + SPELL_STUN_BREAK_SYLVANAS = 70200, + SPELL_HARVEST_SOUL = 69866, // Lich King Harvest Soul + + // Koreln, Loralen + SPELL_FEIGN_DEATH = 29266, // Raging Ghoul - SPELL_EMERGE_VISUAL = 50142, SPELL_GHOUL_JUMP = 70150, + SPELL_RAGING_GHOUL_SPAWN = 69636, - // Witch Doctor - SPELL_COURSE_OF_DOOM = 70144, + // Risen Witch Doctor + SPELL_CURSE_OF_DOOM = 70144, SPELL_SHADOW_BOLT_VOLLEY = 70145, SPELL_SHADOW_BOLT = 70080, + SPELL_RISEN_WITCH_DOCTOR_SPAWN = 69639, // Lumbering Abomination - SPELL_ABON_STRIKE = 40505, - SPELL_VOMIT_SPRAY = 70176, + SPELL_CLEAVE = 40505, + SPELL_VOMIT_SPRAY = 70176 }; -const Position HallsofReflectionLocs[] = +enum HorGossipMenu { - {5283.234863f, 1990.946777f, 707.695679f, 0.929097f}, // 2 Loralen Follows - {5408.031250f, 2102.918213f, 707.695251f, 0.792756f}, // 9 Sylvanas Follows - {5401.866699f, 2110.837402f, 707.695251f, 0.800610f}, // 10 Loralen follows + GOSSIP_MENU_JAINA_FINAL = 10930, + GOSSIP_MENU_SYLVANAS_FINAL = 10931 }; -const Position NpcJainaOrSylvanasEscapeRoute[] = +Position const NpcJainaOrSylvanasEscapeRoute[] = { - {5601.217285f, 2207.652832f, 731.541931f, 5.223304f}, // leave the throne room - {5607.224375f, 2173.913330f, 731.126038f, 2.608723f}, // adjust route - {5583.427246f, 2138.784180f, 731.150391f, 4.260901f}, // stop for talking - {5560.281738f, 2104.025635f, 731.410889f, 4.058383f}, // attack the first icewall - {5510.990723f, 2000.772217f, 734.716064f, 3.973213f}, // attack the second icewall - {5452.641113f, 1905.762329f, 746.530579f, 4.118834f}, // attack the third icewall - {5338.126953f, 1768.429810f, 767.237244f, 3.855189f}, // attack the fourth icewall - {5257.712402f, 1669.379395f, 784.300110f, 0.908373f}, // face the Lich king - {5261.191895f, 1681.901611f, 784.285278f, 4.410465f}, // final position + { 5601.217285f, 2207.652832f, 731.541931f, 5.223304f }, // leave the throne room + { 5607.224375f, 2173.913330f, 731.126038f, 2.608723f }, // adjust route + { 5583.427246f, 2138.784180f, 731.150391f, 4.260901f }, // stop for talking + { 5560.281738f, 2104.025635f, 731.410889f, 4.058383f }, // attack the first icewall + { 5510.990723f, 2000.772217f, 734.716064f, 3.973213f }, // attack the second icewall + { 5452.641113f, 1905.762329f, 746.530579f, 4.118834f }, // attack the third icewall + { 5338.126953f, 1768.429810f, 767.237244f, 3.855189f }, // attack the fourth icewall + { 5259.06f, 1669.27f, 784.3008f, 0.0f }, // trap (sniffed) + { 5265.53f, 1681.6f, 784.2947f, 4.13643f } // final position (sniffed) }; -const Position IceWalls[] = +Position const LichKingMoveAwayPos = { 5400.069824f, 2102.7131689f, 707.69525f, 0.843803f }; // Lich King walks away +Position const LichKingFirstSummon = { 5600.076172f, 2192.270996f, 731.750488f, 4.330935f }; // Lich King First summons +Position const JainaSylvanasShadowThroneDoor = { 5577.243f, 2235.852f, 733.0128f, 2.209562f }; // Jaina/Sylvanas move to door +Position const LichKingFinalPos = { 5283.742188f, 1706.335693f, 783.293518f, 4.138510f }; // Lich King Final Pos + +// sniffed +Position const KorelnOrLoralenPos[] = { - {5547.833f, 2083.701f,731.4332f,4.24115f}, // first icewall - {5503.213f, 1969.547f,737.0245f,4.293779f},// second icewall - {5439.976f, 1879.005f,752.7048f,4.207591f},// third icewall - {5318.289f, 1749.184f,771.9423f,4.054276f},// fourth icewall + { 5253.061f, 1953.616f, 707.6948f, 0.8377581f }, + { 5283.226f, 1992.300f, 707.7445f, 0.8377581f }, + { 5360.711f, 2064.797f, 707.6948f, 0.0f } }; -const Position IntroPos = {5265.89f, 1952.98f, 707.6978f, 0.0f}; // Jaina/Sylvanas Intro Start Position -const Position MoveThronePos = {5306.952148f, 1998.499023f, 709.341431f, 1.277278f}; // Jaina/Sylvanas walks to throne -const Position UtherSpawnPos = {5308.310059f, 2003.857178f, 709.341431f, 4.650315f}; -const Position LichKingSpawnPos = {5362.917480f, 2062.307129f, 707.695374f, 3.945812f}; -const Position LichKingMoveThronePos = {5312.080566f, 2009.172119f, 709.341431f, 3.973301f}; // Lich King walks to throne -const Position LichKingMoveAwayPos = {5400.069824f, 2102.7131689f, 707.69525f, 0.843803f}; // Lich King walks away -const Position LichKingSpawnPos2 = {5552.733398f, 2262.718506f, 733.011047f, 4.009696f}; // Lich King Spawn Position 2 -const Position LichKingFirstSummon = {5600.076172f, 2192.270996f, 731.750488f, 4.330935f}; // Lich King First summons -const Position JainaShadowThroneDoor = {5577.243f, 2235.852f, 733.0128f, 2.209562f}; // Jaina Spawn Position 2 -const Position SylvanasShadowThroneDoor = {5577.243f, 2235.852f, 733.0128f, 2.209562f}; // Sylvanas Spawn Position 2 -const Position FalricStartPos = {5283.878906f, 2030.459595f, 709.319641f, 5.506670f}; // Falric start position -const Position MarwynStartPos = {5334.979980f, 1982.399536f, 709.320129f, 2.347014f}; // Marwyn start position -const Position LichKingFinalPos = {5283.742188f, 1706.335693f, 783.293518f, 4.138510f}; // Lich King Final Pos -const Position ChestPos = {5246.187500f, 1649.079468f, 784.301758f, 0.901268f}; // Chest position -const Position FinalPortalPos = {5270.634277f ,1639.101196f, 784.303040f, 1.682743f}; // Final portal position - -class npc_jaina_or_sylvanas_hor : public CreatureScript +Position const SylvanasIntroPosition[] = { - public: - npc_jaina_or_sylvanas_hor() : CreatureScript("npc_jaina_or_sylvanas_hor") { } - - // AI of Part1 - struct npc_jaina_or_sylvanas_horAI : public ScriptedAI - { - npc_jaina_or_sylvanas_horAI(Creature* creature) : ScriptedAI(creature) - { - _instance = me->GetInstanceScript(); - } - - InstanceScript* _instance; - uint64 _utherGUID; - uint64 _lichkingGUID; - - EventMap _events; + { 0.0f, 0.0f, 0.0f, 0.0f }, // 0 - Spawn + { 5263.2f, 1950.96f, 707.6948f, 0.8028514f }, // 1 - Move to Door + { 5306.82f, 1998.17f, 709.341f, 1.239184f }, // 2 - Move to Frostmourne +}; - void sGossipSelect(Player* player, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) - { - case 0: - player->CLOSE_GOSSIP_MENU(); - _events.ScheduleEvent(EVENT_START_INTRO, 1000); - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); - break; - case 1: - player->CLOSE_GOSSIP_MENU(); - _events.ScheduleEvent(EVENT_SKIP_INTRO, 1000); - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); - break; - } - } +Position const JainaIntroPosition[] = +{ + { 0.0f, 0.0f, 0.0f, 0.0f }, // 0 - Spawn + { 5265.89f, 1952.98f, 707.6978f, 0.0f }, // 1 - Move to Door + { 5306.95f, 1998.49f, 709.3414f, 1.277278f } // 2 - Move to Frostmourne +}; - void Reset() override - { - _events.Reset(); +Position const UtherSpawnPos = { 5307.814f, 2003.168f, 709.4244f, 4.537856f }; - _utherGUID = 0; - _lichkingGUID = 0; +Position const LichKingIntroPosition[] = +{ + { 5362.463f, 2062.693f, 707.7781f, 3.944444f }, // 0 - Spawn + { 5332.83f, 2031.24f, 707.6948f, 0.0f }, // 1 - Door + { 5312.93f, 2010.24f, 709.34f, 0.0f }, // 2 - Move to Frostmourne + { 5319.028f, 2016.662f, 707.6948f, 0.0f }, // 3 - Move back + { 5332.285f, 2030.832f, 707.6948f, 0.0f }, // 4 - Move back 2 + { 5355.488f, 2055.149f, 707.6907f, 0.0f } // 5 - Move back 3 +}; - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); - me->SetStandState(UNIT_STAND_STATE_STAND); - _events.ScheduleEvent(EVENT_WALK_INTRO1, 3000); - } +Position const FalricPosition[] = +{ + { 5276.583f, 2037.45f, 709.4025f, 5.532694f }, // 0 - Spawn + { 5283.95f, 2030.53f, 709.3191f, 0.0f } // 1 - Intro +}; - void UpdateAI(uint32 diff) override - { - _events.Update(diff); +Position const MarwynPosition[] = +{ + { 5342.232f, 1975.696f, 709.4025f, 2.391101f }, // 0 - Spawn + { 5335.01f, 1982.37f, 709.3191f, 0.0f } // 1 - Intro +}; - switch (_events.ExecuteEvent()) - { - case EVENT_WALK_INTRO1: - me->GetMotionMaster()->MovePoint(0, IntroPos); - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - { - Talk(SAY_JAINA_INTRO_1); - _events.ScheduleEvent(EVENT_WALK_INTRO2, 7000); - } - else - { - Talk(SAY_SYLVANAS_INTRO_1); - _events.ScheduleEvent(EVENT_WALK_INTRO2, 9000); - } - break; - case EVENT_WALK_INTRO2: - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - Talk(SAY_JAINA_INTRO_2); - else - Talk(SAY_SYLVANAS_INTRO_2); - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); - break; - 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 (_instance->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: - Talk(SAY_JAINA_INTRO_3); - _events.ScheduleEvent(EVENT_INTRO_A2_2, 7000); - break; - case EVENT_INTRO_A2_2: - Talk(SAY_JAINA_INTRO_4); - _events.ScheduleEvent(EVENT_INTRO_A2_3, 10000); - break; - case EVENT_INTRO_A2_3: - me->CastSpell(me, SPELL_CAST_VISUAL, false); - me->CastSpell(me, SPELL_FROSTMOURNE_SOUNDS, true); - _instance->HandleGameObject(_instance->GetData64(DATA_FROSTMOURNE), true); - _events.ScheduleEvent(EVENT_INTRO_A2_4, 10000); - break; - case EVENT_INTRO_A2_4: - if (Creature* uther = me->SummonCreature(NPC_UTHER, UtherSpawnPos, TEMPSUMMON_MANUAL_DESPAWN)) - { - uther->GetMotionMaster()->MoveIdle(); - _utherGUID = uther->GetGUID(); - } - _events.ScheduleEvent(EVENT_INTRO_A2_5, 2000); - break; - case EVENT_INTRO_A2_5: - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - uther->AI()->Talk(SAY_UTHER_INTRO_A2_1); - _events.ScheduleEvent(EVENT_INTRO_A2_6, 3000); - break; - case EVENT_INTRO_A2_6: - Talk(SAY_JAINA_INTRO_5); - _events.ScheduleEvent(EVENT_INTRO_A2_7, 7000); - break; - case EVENT_INTRO_A2_7: - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - uther->AI()->Talk(SAY_UTHER_INTRO_A2_2); - _events.ScheduleEvent(EVENT_INTRO_A2_8, 7000); - break; - case EVENT_INTRO_A2_8: - Talk(SAY_JAINA_INTRO_6); - _events.ScheduleEvent(EVENT_INTRO_A2_9, 1200); - break; - case EVENT_INTRO_A2_9: - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - uther->AI()->Talk(SAY_UTHER_INTRO_A2_3); - _events.ScheduleEvent(EVENT_INTRO_A2_10, 11000); - break; - case EVENT_INTRO_A2_10: - Talk(SAY_JAINA_INTRO_7); - _events.ScheduleEvent(EVENT_INTRO_A2_11, 6000); - break; - case EVENT_INTRO_A2_11: - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - uther->AI()->Talk(SAY_UTHER_INTRO_A2_4); - _events.ScheduleEvent(EVENT_INTRO_A2_12, 12000); - break; - case EVENT_INTRO_A2_12: - Talk(SAY_JAINA_INTRO_8); - _events.ScheduleEvent(EVENT_INTRO_A2_13, 6000); - break; - case EVENT_INTRO_A2_13: - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - uther->AI()->Talk(SAY_UTHER_INTRO_A2_5); - _events.ScheduleEvent(EVENT_INTRO_A2_14, 13000); - break; - case EVENT_INTRO_A2_14: - Talk(SAY_JAINA_INTRO_9); - _events.ScheduleEvent(EVENT_INTRO_A2_15, 12000); - break; - case EVENT_INTRO_A2_15: - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - uther->AI()->Talk(SAY_UTHER_INTRO_A2_6); - _events.ScheduleEvent(EVENT_INTRO_A2_16, 25000); - break; - case EVENT_INTRO_A2_16: - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - uther->AI()->Talk(SAY_UTHER_INTRO_A2_7); - _events.ScheduleEvent(EVENT_INTRO_A2_17, 6000); - break; - case EVENT_INTRO_A2_17: - Talk(SAY_JAINA_INTRO_10); - _events.ScheduleEvent(EVENT_INTRO_A2_18, 5000); - break; - case EVENT_INTRO_A2_18: - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - { - uther->HandleEmoteCommand(EMOTE_ONESHOT_NO); - uther->AI()->Talk(SAY_UTHER_INTRO_A2_8); - } - _events.ScheduleEvent(EVENT_INTRO_A2_19, 12000); - break; - case EVENT_INTRO_A2_19: - Talk(SAY_JAINA_INTRO_11); - _events.ScheduleEvent(EVENT_INTRO_LK_1, 3000); - break; - // H2 Intro Events - case EVENT_INTRO_H2_1: - Talk(SAY_SYLVANAS_INTRO_1); - _events.ScheduleEvent(EVENT_INTRO_H2_2, 8000); - break; - case EVENT_INTRO_H2_2: - Talk(SAY_SYLVANAS_INTRO_2); - _events.ScheduleEvent(EVENT_INTRO_H2_3, 6000); - break; - case EVENT_INTRO_H2_3: - Talk(SAY_SYLVANAS_INTRO_3); - me->CastSpell(me, SPELL_CAST_VISUAL, false); - me->CastSpell(me, SPELL_FROSTMOURNE_SOUNDS, true); - _instance->HandleGameObject(_instance->GetData64(DATA_FROSTMOURNE), true); - _events.ScheduleEvent(EVENT_INTRO_H2_4, 6000); - break; - case EVENT_INTRO_H2_4: - // spawn UTHER during speach 2 - if (Creature* uther = me->SummonCreature(NPC_UTHER, UtherSpawnPos, TEMPSUMMON_MANUAL_DESPAWN)) - { - uther->GetMotionMaster()->MoveIdle(); - _utherGUID = uther->GetGUID(); - } - _events.ScheduleEvent(EVENT_INTRO_H2_5, 2000); - break; - case EVENT_INTRO_H2_5: - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - uther->AI()->Talk(SAY_UTHER_INTRO_H2_1); - _events.ScheduleEvent(EVENT_INTRO_H2_6, 11000); - break; - case EVENT_INTRO_H2_6: - Talk(SAY_SYLVANAS_INTRO_4); - _events.ScheduleEvent(EVENT_INTRO_H2_7, 3000); - break; - case EVENT_INTRO_H2_7: - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - uther->AI()->Talk(SAY_UTHER_INTRO_H2_2); - _events.ScheduleEvent(EVENT_INTRO_H2_8, 6000); - break; - case EVENT_INTRO_H2_8: - Talk(SAY_SYLVANAS_INTRO_5); - _events.ScheduleEvent(EVENT_INTRO_H2_9, 5000); - break; - case EVENT_INTRO_H2_9: - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - uther->AI()->Talk(SAY_UTHER_INTRO_H2_3); - _events.ScheduleEvent(EVENT_INTRO_H2_10, 19000); - break; - case EVENT_INTRO_H2_10: - Talk(SAY_SYLVANAS_INTRO_6); - _events.ScheduleEvent(EVENT_INTRO_H2_11, 1500); - break; - case EVENT_INTRO_H2_11: - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - uther->AI()->Talk(SAY_UTHER_INTRO_H2_4); - _events.ScheduleEvent(EVENT_INTRO_H2_12, 19500); - break; - case EVENT_INTRO_H2_12: - Talk(SAY_SYLVANAS_INTRO_7); - _events.ScheduleEvent(EVENT_INTRO_H2_13, 2000); - break; - case EVENT_INTRO_H2_13: - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - { - uther->HandleEmoteCommand(EMOTE_ONESHOT_NO); - uther->AI()->Talk(SAY_UTHER_INTRO_H2_5); - } - _events.ScheduleEvent(EVENT_INTRO_H2_14, 12000); - break; - case EVENT_INTRO_H2_14: - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - uther->AI()->Talk(SAY_UTHER_INTRO_H2_6); - _events.ScheduleEvent(EVENT_INTRO_H2_15, 8000); - break; - case EVENT_INTRO_H2_15: - Talk(SAY_SYLVANAS_INTRO_8); - _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* lichking = me->SummonCreature(NPC_LICH_KING_PART1, LichKingSpawnPos, TEMPSUMMON_MANUAL_DESPAWN)) - { - lichking->SetWalk(true); - lichking->GetMotionMaster()->MovePoint(0, LichKingMoveThronePos); - _lichkingGUID = lichking->GetGUID(); - _events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 0); - _events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 4000); - } - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - { - uther->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_COWER); - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - uther->AI()->Talk(SAY_UTHER_INTRO_A2_9); - else - uther->AI()->Talk(SAY_UTHER_INTRO_H2_7); - } - _events.ScheduleEvent(EVENT_INTRO_LK_2, 10000); - break; - case EVENT_INTRO_LK_2: - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) - lichking->AI()->Talk(SAY_LK_INTRO_1); - _events.ScheduleEvent(EVENT_INTRO_LK_3, 1000); - break; - case EVENT_INTRO_LK_3: - // The Lich King banishes Uther to the abyss. - if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) - { - uther->CastSpell(uther, SPELL_UTHER_DESPAWN, true); - uther->DespawnOrUnsummon(5000); - _utherGUID = 0; - } - _events.ScheduleEvent(EVENT_INTRO_LK_4, 9000); - break; - case EVENT_INTRO_LK_4: - // He steps forward and removes the runeblade from the heap of skulls. - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) - { - if (GameObject* frostmourne = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_FROSTMOURNE))) - frostmourne->SetPhaseMask(2, true); - lichking->CastSpell(lichking, SPELL_TAKE_FROSTMOURNE, true); - lichking->CastSpell(lichking, SPELL_FROSTMOURNE_VISUAL, true); - } - _events.ScheduleEvent(EVENT_INTRO_LK_5, 8000); - break; - case EVENT_INTRO_LK_5: - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) - lichking->AI()->Talk(SAY_LK_INTRO_2); - _events.ScheduleEvent(EVENT_INTRO_LK_6, 10000); - break; - case EVENT_INTRO_LK_6: - // summon Falric and Marwyn. then go back to the door - if (Creature* falric = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_FALRIC_EVENT))) - { - falric->CastSpell(falric, SPELL_BOSS_SPAWN_AURA, true); - falric->SetVisible(true); - } - if (Creature* marwyn = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MARWYN_EVENT))) - { - marwyn->CastSpell(marwyn, SPELL_BOSS_SPAWN_AURA, true); - marwyn->SetVisible(true); - } - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) - { - lichking->AI()->Talk(SAY_LK_INTRO_3); - lichking->SetWalk(true); - lichking->GetMotionMaster()->MovePoint(0, LichKingMoveAwayPos); - } - _events.ScheduleEvent(EVENT_INTRO_LK_7, 10000); - _events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 5000); - break; - case EVENT_INTRO_LK_7: - if (Creature* marwyn = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MARWYN_EVENT))) - { - marwyn->AI()->Talk(SAY_MARWYN_INTRO_1); - marwyn->SetWalk(true); - marwyn->GetMotionMaster()->MovePoint(0, MarwynStartPos); - } - _events.ScheduleEvent(EVENT_INTRO_LK_8, 1000); - break; - case EVENT_INTRO_LK_8: - if (Creature* falric = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_FALRIC_EVENT))) - { - falric->AI()->Talk(SAY_FALRIC_INTRO_1); - falric->SetWalk(true); - falric->GetMotionMaster()->MovePoint(0, FalricStartPos); - } - _events.ScheduleEvent(EVENT_INTRO_LK_9, 5000); - break; - case EVENT_INTRO_LK_9: - if (Creature* falric = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_FALRIC_EVENT))) - falric->AI()->Talk(SAY_FALRIC_INTRO_2); - _instance->ProcessEvent(0, EVENT_SPAWN_WAVES); - _events.ScheduleEvent(EVENT_INTRO_LK_10, 4000); - break; - case EVENT_INTRO_LK_10: - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - Talk(SAY_JAINA_INTRO_END); - else - Talk(SAY_SYLVANAS_INTRO_END); - me->GetMotionMaster()->MovePoint(0, LichKingMoveAwayPos); - /// @todo Loralen/Koreln shall run also - _events.ScheduleEvent(EVENT_INTRO_LK_11, 5000); - break; - case EVENT_INTRO_LK_11: - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) - { - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - lichking->AI()->Talk(SAY_LK_JAINA_INTRO_END); - else - lichking->AI()->Talk(SAY_LK_SYLVANAS_INTRO_END); - } - _events.ScheduleEvent(EVENT_INTRO_END, 5000); - break; - case EVENT_INTRO_END: - _instance->SetData(DATA_INTRO_EVENT, DONE); - // Loralen or Koreln disappearAndDie() - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) - { - lichking->DespawnOrUnsummon(5000); - _lichkingGUID = 0; - } - me->DespawnOrUnsummon(10000); - _events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 7000); - break; - case EVENT_SKIP_INTRO: - me->GetMotionMaster()->MovePoint(0, MoveThronePos); - /// @todo Loralen/Koreln shall run also - if (Creature* lichking = me->SummonCreature(NPC_LICH_KING_PART1, LichKingSpawnPos, TEMPSUMMON_MANUAL_DESPAWN)) - { - lichking->SetWalk(true); - lichking->GetMotionMaster()->MovePoint(0, LichKingMoveThronePos); - lichking->SetReactState(REACT_PASSIVE); - _lichkingGUID = lichking->GetGUID(); - _events.ScheduleEvent(EVENT_OPEN_FROSTWORN_DOOR, 0); - _events.ScheduleEvent(EVENT_CLOSE_FROSTWORN_DOOR, 4000); - } - _events.ScheduleEvent(EVENT_INTRO_LK_4, 15000); - break; - case EVENT_OPEN_FROSTWORN_DOOR: - if (GameObject* gate = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_FROSTWORN_DOOR))) - _instance->HandleGameObject(0, true, gate); - break; - case EVENT_CLOSE_FROSTWORN_DOOR: - if (GameObject* gate = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_FROSTWORN_DOOR))) - _instance->HandleGameObject(0, false, gate); - break; - } - } - }; +Position const SylvanasShadowThroneDoorPosition = { 5576.79f, 2235.73f, 733.0029f, 2.687807f }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetHallsOfReflectionAI(creature); - } +Position const IceWallTargetPosition[] = +{ + { 5547.833f, 2083.701f, 731.4332f, 1.029744f }, // 1st Icewall + { 5503.213f, 1969.547f, 737.0245f, 1.27409f }, // 2nd Icewall + { 5439.976f, 1879.005f, 752.7048f, 1.064651f }, // 3rd Icewall + { 5318.289f, 1749.184f, 771.9423f, 0.8726646f } // 4th Icewall }; -class npc_jaina_or_sylvanas_escape_hor : public CreatureScript +class npc_jaina_or_sylvanas_intro_hor : public CreatureScript { public: - npc_jaina_or_sylvanas_escape_hor() : CreatureScript("npc_jaina_or_sylvanas_escape_hor") { } - - // AI of Part2 - struct npc_jaina_or_sylvanas_escape_horAI : public ScriptedAI - { - npc_jaina_or_sylvanas_escape_horAI(Creature* creature) : ScriptedAI(creature), - _instance(creature->GetInstanceScript()), _lichkingGUID(0), _walltargetGUID(0), - _icewallGUID(0), _icewall(0) - { - } - - InstanceScript* _instance; - uint64 _lichkingGUID; - uint64 _walltargetGUID; // dummy - uint64 _icewallGUID; // object - uint32 _icewall; // icewall number - - EventMap _events; - - void Reset() override - { - _events.Reset(); - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) - lichking->DespawnOrUnsummon(1); - _lichkingGUID = 0; - _walltargetGUID = 0; - _icewallGUID = 0; - _icewall = 0; - _events.ScheduleEvent(EVENT_ESCAPE, 0); - } + npc_jaina_or_sylvanas_intro_hor() : CreatureScript("npc_jaina_or_sylvanas_intro_hor") { } - void JustDied(Unit* /*Killer*/) override + struct npc_jaina_or_sylvanas_intro_horAI : public ScriptedAI { - _instance->SetData(DATA_ESCAPE_EVENT, FAIL); - } - - void DoAction(int32 actionId) override - { - switch (actionId) - { - case ACTION_START_ESCAPING: // called by InstanceScript when we need to start the escaping event - _events.ScheduleEvent(EVENT_ESCAPE_1, 1000); - break; - case ACTION_WALL_BROKEN: - _icewall++; - if (_icewall != 4) - _events.ScheduleEvent(EVENT_ESCAPE_17, 3000); - else - _events.ScheduleEvent(EVENT_ESCAPE_23, 3000); - break; + npc_jaina_or_sylvanas_intro_horAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); } - } - void sGossipSelect(Player* player, uint32 /*sender*/, uint32 action) override - { - player->PlayerTalkClass->ClearMenus(); - switch (action) + void sGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override { - case 0: - player->CLOSE_GOSSIP_MENU(); - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); - _events.ScheduleEvent(EVENT_ESCAPE_7, 0); - break; - } - } + player->PlayerTalkClass->ClearMenus(); - void DestroyIceWall() - { - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - me->RemoveAurasDueToSpell(SPELL_JAINA_DESTROY_ICE_WALL); - else - me->RemoveAurasDueToSpell(SPELL_SYLVANAS_DESTROY_ICE_WALL); + switch (gossipListId) + { + case 0: + player->PlayerTalkClass->SendCloseGossip(); + _events.ScheduleEvent(EVENT_START_INTRO, 1000); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); + break; + case 1: + player->PlayerTalkClass->SendCloseGossip(); + _events.ScheduleEvent(EVENT_SKIP_INTRO, 1000); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); + break; + default: + break; + } + } - _instance->HandleGameObject(_icewallGUID, true); + void Reset() override + { + _events.Reset(); - if (Creature* wallTarget = ObjectAccessor::GetCreature(*me, _walltargetGUID)) - wallTarget->DespawnOrUnsummon(); - } + _utherGUID = 0; + _lichkingGUID = 0; - void UpdateAI(uint32 diff) override - { - _events.Update(diff); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); + me->SetStandState(UNIT_STAND_STATE_STAND); + _events.ScheduleEvent(EVENT_WALK_INTRO1, 3000); + } - while (uint32 event = _events.ExecuteEvent()) + void UpdateAI(uint32 diff) override { - switch (event) + _events.Update(diff); + + switch (_events.ExecuteEvent()) { - case EVENT_ESCAPE: - if (Creature* lichking = me->SummonCreature(NPC_LICH_KING_PART2, LichKingSpawnPos2, TEMPSUMMON_MANUAL_DESPAWN)) + case EVENT_WALK_INTRO1: + if (Creature* korelnOrLoralen = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_KORELN_LORALEN))) + korelnOrLoralen->GetMotionMaster()->MovePoint(0, KorelnOrLoralenPos[0]); + + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) { - me->Attack(lichking, true); - lichking->Attack(me, true); - me->SetReactState(REACT_PASSIVE); - lichking->SetReactState(REACT_PASSIVE); - _lichkingGUID = lichking->GetGUID(); - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - DoCast(me, SPELL_JAINA_ICEBARRIER); - else - DoCast(me, SPELL_SYLVANAS_CLOAKOFDARKNESS); + me->GetMotionMaster()->MovePoint(0, JainaIntroPosition[1]); + Talk(SAY_JAINA_INTRO_1); + _events.ScheduleEvent(EVENT_WALK_INTRO2, 7000); } - me->SetHealth(252000); - break; - case EVENT_ESCAPE_1: - _instance->SetData(DATA_ESCAPE_EVENT, IN_PROGRESS); - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) + else { - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - lichking->AI()->Talk(SAY_LK_ESCAPE_1); - else - lichking->AI()->Talk(SAY_LK_ESCAPE_2); - _events.ScheduleEvent(EVENT_ESCAPE_2, 8000); + me->GetMotionMaster()->MovePoint(0, SylvanasIntroPosition[1]); + Talk(SAY_SYLVANAS_INTRO_1); + _events.ScheduleEvent(EVENT_WALK_INTRO2, 9000); } break; - case EVENT_ESCAPE_2: + case EVENT_WALK_INTRO2: if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - DoCast(me, SPELL_CAST_VISUAL, true); + Talk(SAY_JAINA_INTRO_2); else - DoCast(me, SPELL_SYLVANAS_JUMP, true); - _events.ScheduleEvent(EVENT_ESCAPE_3, 1000); + Talk(SAY_SYLVANAS_INTRO_2); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); break; - case EVENT_ESCAPE_3: + case EVENT_START_INTRO: + if (Creature* korelnOrLoralen = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_KORELN_LORALEN))) + korelnOrLoralen->GetMotionMaster()->MovePoint(0, KorelnOrLoralenPos[1]); + // Begining of intro is differents between factions as the speech sequence and timers are differents. if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - DoCastAOE(SPELL_JAINA_ICEPRISON, true); + { + me->GetMotionMaster()->MovePoint(0, JainaIntroPosition[2]); + _events.ScheduleEvent(EVENT_INTRO_A2_1, 0); + } else - DoCastAOE(SPELL_SYLVANAS_DARKBINDING, true); - _events.ScheduleEvent(EVENT_ESCAPE_4, 2000); + { + me->GetMotionMaster()->MovePoint(0, SylvanasIntroPosition[2]); + _events.ScheduleEvent(EVENT_INTRO_H2_1, 0); + } break; - case EVENT_ESCAPE_4: - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - Talk(SAY_JAINA_ESCAPE_1); - else - Talk(SAY_SYLVANAS_ESCAPE_1); - _events.ScheduleEvent(EVENT_ESCAPE_5, 2000); + // A2 Intro Events + case EVENT_INTRO_A2_1: + Talk(SAY_JAINA_INTRO_3); + _events.ScheduleEvent(EVENT_INTRO_A2_2, 7000); break; - case EVENT_ESCAPE_5: - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) - lichking->CombatStop(); - me->GetMotionMaster()->MovePoint(0, JainaShadowThroneDoor); - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - me->RemoveAurasDueToSpell(SPELL_JAINA_ICEBARRIER); - else - me->RemoveAurasDueToSpell(SPELL_SYLVANAS_CLOAKOFDARKNESS); - _events.ScheduleEvent(EVENT_ESCAPE_6, 5000); + case EVENT_INTRO_A2_2: + Talk(SAY_JAINA_INTRO_4); + _events.ScheduleEvent(EVENT_INTRO_A2_3, 10000); break; - case EVENT_ESCAPE_6: - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER); + case EVENT_INTRO_A2_3: + me->CastSpell(me, SPELL_CAST_VISUAL, false); + me->CastSpell(me, SPELL_FROSTMOURNE_SOUNDS, true); + _instance->HandleGameObject(_instance->GetData64(DATA_FROSTMOURNE), true); + _events.ScheduleEvent(EVENT_INTRO_A2_4, 10000); break; - case EVENT_ESCAPE_7: - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) - { - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - lichking->RemoveAurasDueToSpell(SPELL_JAINA_ICEPRISON); - else - lichking->RemoveAurasDueToSpell(SPELL_SYLVANAS_DARKBINDING); - } - _events.ScheduleEvent(EVENT_ESCAPE_8, 1000); + case EVENT_INTRO_A2_4: + if (Creature* uther = me->SummonCreature(NPC_UTHER, UtherSpawnPos, TEMPSUMMON_MANUAL_DESPAWN)) + _utherGUID = uther->GetGUID(); + _events.ScheduleEvent(EVENT_INTRO_A2_5, 2000); break; - case EVENT_ESCAPE_8: - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) - lichking->HandleEmoteCommand(TEXT_EMOTE_ROAR); - me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[0]); - _events.ScheduleEvent(EVENT_ESCAPE_9, 3000); + case EVENT_INTRO_A2_5: + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) + uther->AI()->Talk(SAY_UTHER_INTRO_A2_1); + _events.ScheduleEvent(EVENT_INTRO_A2_6, 3000); break; - case EVENT_ESCAPE_9: - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) - lichking->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[0]); - _events.ScheduleEvent(EVENT_ESCAPE_10, 1000); + case EVENT_INTRO_A2_6: + Talk(SAY_JAINA_INTRO_5); + _events.ScheduleEvent(EVENT_INTRO_A2_7, 7000); break; - case EVENT_ESCAPE_10: - me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[1]); - _events.ScheduleEvent(EVENT_ESCAPE_11, 5000); + case EVENT_INTRO_A2_7: + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) + uther->AI()->Talk(SAY_UTHER_INTRO_A2_2); + _events.ScheduleEvent(EVENT_INTRO_A2_8, 7000); break; - case EVENT_ESCAPE_11: - me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[2]); - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) - lichking->GetMotionMaster()->MovePoint(0, LichKingFirstSummon); - _events.ScheduleEvent(EVENT_ESCAPE_12, 6000); + case EVENT_INTRO_A2_8: + Talk(SAY_JAINA_INTRO_6); + _events.ScheduleEvent(EVENT_INTRO_A2_9, 1200); break; - case EVENT_ESCAPE_12: - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) + case EVENT_INTRO_A2_9: + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) + uther->AI()->Talk(SAY_UTHER_INTRO_A2_3); + _events.ScheduleEvent(EVENT_INTRO_A2_10, 11000); + break; + case EVENT_INTRO_A2_10: + Talk(SAY_JAINA_INTRO_7); + _events.ScheduleEvent(EVENT_INTRO_A2_11, 6000); + break; + case EVENT_INTRO_A2_11: + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) + uther->AI()->Talk(SAY_UTHER_INTRO_A2_4); + _events.ScheduleEvent(EVENT_INTRO_A2_12, 12000); + break; + case EVENT_INTRO_A2_12: + Talk(SAY_JAINA_INTRO_8); + _events.ScheduleEvent(EVENT_INTRO_A2_13, 6000); + break; + case EVENT_INTRO_A2_13: + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) + uther->AI()->Talk(SAY_UTHER_INTRO_A2_5); + _events.ScheduleEvent(EVENT_INTRO_A2_14, 13000); + break; + case EVENT_INTRO_A2_14: + Talk(SAY_JAINA_INTRO_9); + _events.ScheduleEvent(EVENT_INTRO_A2_15, 12000); + break; + case EVENT_INTRO_A2_15: + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) + uther->AI()->Talk(SAY_UTHER_INTRO_A2_6); + _events.ScheduleEvent(EVENT_INTRO_A2_16, 25000); + break; + case EVENT_INTRO_A2_16: + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) + uther->AI()->Talk(SAY_UTHER_INTRO_A2_7); + _events.ScheduleEvent(EVENT_INTRO_A2_17, 6000); + break; + case EVENT_INTRO_A2_17: + Talk(SAY_JAINA_INTRO_10); + _events.ScheduleEvent(EVENT_INTRO_A2_18, 5000); + break; + case EVENT_INTRO_A2_18: + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) { - lichking->AI()->Talk(SAY_LK_ESCAPE_3); - lichking->CastSpell(me, SPELL_RAISE_DEAD); - lichking->Attack(me, true); + uther->HandleEmoteCommand(EMOTE_ONESHOT_NO); + uther->AI()->Talk(SAY_UTHER_INTRO_A2_8); } - _events.ScheduleEvent(EVENT_ESCAPE_13, 4000); + _events.ScheduleEvent(EVENT_INTRO_A2_19, 12000); break; - case EVENT_ESCAPE_13: - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) + case EVENT_INTRO_A2_19: + Talk(SAY_JAINA_INTRO_11); + _events.ScheduleEvent(EVENT_INTRO_LK_1, 3000); + break; + // H2 Intro Events + case EVENT_INTRO_H2_1: + Talk(SAY_SYLVANAS_INTRO_1); + _events.ScheduleEvent(EVENT_INTRO_H2_2, 8000); + break; + case EVENT_INTRO_H2_2: + Talk(SAY_SYLVANAS_INTRO_2); + _events.ScheduleEvent(EVENT_INTRO_H2_3, 6000); + break; + case EVENT_INTRO_H2_3: + Talk(SAY_SYLVANAS_INTRO_3); + me->CastSpell(me, SPELL_CAST_VISUAL, false); + me->CastSpell(me, SPELL_FROSTMOURNE_SOUNDS, true); + _instance->HandleGameObject(_instance->GetData64(DATA_FROSTMOURNE), true); + _events.ScheduleEvent(EVENT_INTRO_H2_4, 6000); + break; + case EVENT_INTRO_H2_4: + // spawn UTHER during speach 2 + if (Creature* uther = me->SummonCreature(NPC_UTHER, UtherSpawnPos, TEMPSUMMON_MANUAL_DESPAWN)) + _utherGUID = uther->GetGUID(); + _events.ScheduleEvent(EVENT_INTRO_H2_5, 2000); + break; + case EVENT_INTRO_H2_5: + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) + uther->AI()->Talk(SAY_UTHER_INTRO_H2_1); + _events.ScheduleEvent(EVENT_INTRO_H2_6, 11000); + break; + case EVENT_INTRO_H2_6: + Talk(SAY_SYLVANAS_INTRO_4); + _events.ScheduleEvent(EVENT_INTRO_H2_7, 3000); + break; + case EVENT_INTRO_H2_7: + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) + uther->AI()->Talk(SAY_UTHER_INTRO_H2_2); + _events.ScheduleEvent(EVENT_INTRO_H2_8, 6000); + break; + case EVENT_INTRO_H2_8: + Talk(SAY_SYLVANAS_INTRO_5); + _events.ScheduleEvent(EVENT_INTRO_H2_9, 5000); + break; + case EVENT_INTRO_H2_9: + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) + uther->AI()->Talk(SAY_UTHER_INTRO_H2_3); + _events.ScheduleEvent(EVENT_INTRO_H2_10, 19000); + break; + case EVENT_INTRO_H2_10: + Talk(SAY_SYLVANAS_INTRO_6); + _events.ScheduleEvent(EVENT_INTRO_H2_11, 1500); + break; + case EVENT_INTRO_H2_11: + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) + uther->AI()->Talk(SAY_UTHER_INTRO_H2_4); + _events.ScheduleEvent(EVENT_INTRO_H2_12, 19500); + break; + case EVENT_INTRO_H2_12: + Talk(SAY_SYLVANAS_INTRO_7); + _events.ScheduleEvent(EVENT_INTRO_H2_13, 2000); + break; + case EVENT_INTRO_H2_13: + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) { - lichking->CastSpell(lichking, SPELL_REMORSELESS_WINTER, true); - lichking->CastSpell(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); - lichking->GetMotionMaster()->MoveIdle(); - lichking->GetMotionMaster()->MoveChase(me); + uther->HandleEmoteCommand(EMOTE_ONESHOT_NO); + uther->AI()->Talk(SAY_UTHER_INTRO_H2_5); } - if (Creature* walltarget = me->SummonCreature(NPC_ICE_WALL, IceWalls[0], TEMPSUMMON_MANUAL_DESPAWN, 720000)) + _events.ScheduleEvent(EVENT_INTRO_H2_14, 12000); + break; + case EVENT_INTRO_H2_14: + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) + uther->AI()->Talk(SAY_UTHER_INTRO_H2_6); + _events.ScheduleEvent(EVENT_INTRO_H2_15, 8000); + break; + case EVENT_INTRO_H2_15: + Talk(SAY_SYLVANAS_INTRO_8); + _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* lichking = me->SummonCreature(NPC_THE_LICH_KING_INTRO, LichKingIntroPosition[0], TEMPSUMMON_MANUAL_DESPAWN)) { - _walltargetGUID = walltarget->GetGUID(); - walltarget->CastSpell(walltarget, SPELL_SUMMON_ICE_WALL); - walltarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - me->Attack(walltarget, false); + lichking->SetWalk(true); + lichking->GetMotionMaster()->MovePoint(0, LichKingIntroPosition[2]); + _lichkingGUID = lichking->GetGUID(); + _events.ScheduleEvent(EVENT_OPEN_IMPENETRABLE_DOOR, 0); + _events.ScheduleEvent(EVENT_CLOSE_IMPENETRABLE_DOOR, 4000); } - me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[3]); - _events.ScheduleEvent(EVENT_ESCAPE_14, 8000); - break; - case EVENT_ESCAPE_14: - if (Creature* walltarget = ObjectAccessor::GetCreature(*me, _walltargetGUID)) + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) { - if (GameObject* icewall = walltarget->FindNearestGameObject(GO_ICE_WALL, 50.00f)) - { - _icewallGUID = icewall->GetGUID(); - icewall->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); - _instance->HandleGameObject(0, false, icewall); - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - Talk(SAY_JAINA_ESCAPE_2); - else - Talk(SAY_SYLVANAS_ESCAPE_2); - } + uther->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_COWER); + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + uther->AI()->Talk(SAY_UTHER_INTRO_A2_9); + else + uther->AI()->Talk(SAY_UTHER_INTRO_H2_7); } - _events.ScheduleEvent(EVENT_ESCAPE_15, 1000); + _events.ScheduleEvent(EVENT_INTRO_LK_2, 10000); break; - case EVENT_ESCAPE_15: + case EVENT_INTRO_LK_2: if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) + lichking->AI()->Talk(SAY_LK_INTRO_1); + _events.ScheduleEvent(EVENT_INTRO_LK_3, 1000); + break; + case EVENT_INTRO_LK_3: + // The Lich King banishes Uther to the abyss. + if (Creature* uther = ObjectAccessor::GetCreature(*me, _utherGUID)) { - lichking->GetMotionMaster()->MoveIdle(); - lichking->GetMotionMaster()->MoveChase(me); - lichking->SetReactState(REACT_PASSIVE); + uther->CastSpell(uther, SPELL_UTHER_DESPAWN, true); + uther->DespawnOrUnsummon(5000); + _utherGUID = 0; } - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - DoCast(me, SPELL_JAINA_DESTROY_ICE_WALL, true); - else - DoCast(me, SPELL_SYLVANAS_DESTROY_ICE_WALL, true); + _events.ScheduleEvent(EVENT_INTRO_LK_4, 9000); break; - case EVENT_ESCAPE_17:// ICEWALL BROKEN - me->GetMotionMaster()->MoveIdle(); + case EVENT_INTRO_LK_4: + // He steps forward and removes the runeblade from the heap of skulls. if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) { - lichking->StopMoving(); - lichking->AI()->Talk(SAY_LK_ESCAPE_3); - lichking->CastSpell(me, SPELL_RAISE_DEAD); + if (GameObject* frostmourne = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_FROSTMOURNE))) + frostmourne->SetPhaseMask(2, true); + lichking->CastSpell(lichking, SPELL_TAKE_FROSTMOURNE, true); + lichking->CastSpell(lichking, SPELL_FROSTMOURNE_VISUAL, true); } - - DestroyIceWall(); - - if (_icewall && _icewall < 4) - me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[_icewall + 3]); - _events.ScheduleEvent(EVENT_ESCAPE_18, 2000); + _events.ScheduleEvent(EVENT_INTRO_LK_5, 8000); break; - case EVENT_ESCAPE_18: + case EVENT_INTRO_LK_5: if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) + lichking->AI()->Talk(SAY_LK_INTRO_2); + _events.ScheduleEvent(EVENT_INTRO_LK_6, 10000); + break; + case EVENT_INTRO_LK_6: + // summon Falric and Marwyn. then go back to the door + if (Creature* falric = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_FALRIC))) { - lichking->GetMotionMaster()->MoveIdle(); - lichking->GetMotionMaster()->MoveChase(me); + falric->CastSpell(falric, SPELL_BOSS_SPAWN_AURA, true); + falric->SetVisible(true); } - _events.ScheduleEvent(EVENT_ESCAPE_19, 6000); - break; - case EVENT_ESCAPE_19: - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) + if (Creature* marwyn = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MARWYN))) { - if (_icewall && _icewall < 4) - lichking->CastSpell(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); - lichking->GetMotionMaster()->MoveIdle(); - lichking->GetMotionMaster()->MoveChase(me); - lichking->SetReactState(REACT_PASSIVE); - lichking->Attack(me, true); + marwyn->CastSpell(marwyn, SPELL_BOSS_SPAWN_AURA, true); + marwyn->SetVisible(true); } - if (_icewall < 4) + if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) { - if (Creature* walltarget = me->SummonCreature(NPC_ICE_WALL, IceWalls[_icewall], TEMPSUMMON_MANUAL_DESPAWN, 720000)) - { - _walltargetGUID = walltarget->GetGUID(); - walltarget->CastSpell(walltarget, SPELL_SUMMON_ICE_WALL); - walltarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - me->Attack(walltarget, false); - } + lichking->AI()->Talk(SAY_LK_INTRO_3); + lichking->SetWalk(true); + lichking->GetMotionMaster()->MovePoint(0, LichKingMoveAwayPos); } - _events.ScheduleEvent(EVENT_ESCAPE_20, 3000); + _events.ScheduleEvent(EVENT_INTRO_LK_7, 10000); + _events.ScheduleEvent(EVENT_OPEN_IMPENETRABLE_DOOR, 5000); break; - case EVENT_ESCAPE_20: - if (Creature* walltarget = ObjectAccessor::GetCreature(*me, _walltargetGUID)) + case EVENT_INTRO_LK_7: + if (Creature* marwyn = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MARWYN))) { - if (GameObject* icewall = walltarget->FindNearestGameObject(GO_ICE_WALL, 50.00f)) - { - _icewallGUID = icewall->GetGUID(); - _instance->HandleGameObject(0, false, icewall); - icewall->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - { - if (_icewall == 1) - Talk(SAY_JAINA_ESCAPE_3); - else if (_icewall == 2) - Talk(SAY_JAINA_ESCAPE_4); - else if (_icewall == 3) - Talk(SAY_JAINA_ESCAPE_5); - } - else if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE) - { - if (_icewall == 1) - Talk(SAY_SYLVANAS_ESCAPE_3); - else if (_icewall == 2) - Talk(SAY_SYLVANAS_ESCAPE_4); - else if (_icewall == 3) - Talk(SAY_SYLVANAS_ESCAPE_5); - } - } + marwyn->AI()->Talk(SAY_MARWYN_INTRO_1); + marwyn->SetWalk(true); + marwyn->GetMotionMaster()->MovePoint(0, MarwynPosition[1]); } - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) + _events.ScheduleEvent(EVENT_INTRO_LK_8, 1000); + break; + case EVENT_INTRO_LK_8: + if (Creature* falric = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_FALRIC))) { - if (_icewall && _icewall < 3) - lichking->CastSpell(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); - else - lichking->CastSpell(lichking, SPELL_SUMMON_LUMBERING_ABOMINATION); + falric->AI()->Talk(SAY_FALRIC_INTRO_1); + falric->SetWalk(true); + falric->GetMotionMaster()->MovePoint(0, FalricPosition[1]); } - if (_icewall == 3) - _events.ScheduleEvent(EVENT_ESCAPE_21, 16000); // last wall, really far - else - _events.ScheduleEvent(EVENT_ESCAPE_21, 9000); + _events.ScheduleEvent(EVENT_INTRO_LK_9, 5000); + break; + case EVENT_INTRO_LK_9: + if (Creature* falric = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_FALRIC))) + falric->AI()->Talk(SAY_FALRIC_INTRO_2); + _instance->ProcessEvent(0, EVENT_SPAWN_WAVES); + _events.ScheduleEvent(EVENT_INTRO_LK_10, 4000); break; - case EVENT_ESCAPE_21: + case EVENT_INTRO_LK_10: if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - DoCast(me, SPELL_JAINA_DESTROY_ICE_WALL, true); + Talk(SAY_JAINA_INTRO_END); else - DoCast(me, SPELL_SYLVANAS_DESTROY_ICE_WALL, true); - + Talk(SAY_SYLVANAS_INTRO_END); + me->GetMotionMaster()->MovePoint(0, LichKingMoveAwayPos); + /// @todo: needs some improvements + if (Creature* korelnOrLoralen = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_KORELN_LORALEN))) + korelnOrLoralen->GetMotionMaster()->MovePoint(1, KorelnOrLoralenPos[2]); + _events.ScheduleEvent(EVENT_INTRO_LK_11, 5000); + break; + case EVENT_INTRO_LK_11: if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) { - if (_icewall == 1) - lichking->CastSpell(lichking, SPELL_SUMMON_LUMBERING_ABOMINATION); - else if (_icewall > 1 && _icewall < 4) - { - lichking->CastSpell(lichking, SPELL_SUMMON_RISE_WITCH_DOCTOR); - _events.ScheduleEvent(EVENT_ESCAPE_22, 1000); - } + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + lichking->AI()->Talk(SAY_LK_JAINA_INTRO_END); + else + lichking->AI()->Talk(SAY_LK_SYLVANAS_INTRO_END); } + _events.ScheduleEvent(EVENT_INTRO_END, 5000); break; - case EVENT_ESCAPE_22: + case EVENT_INTRO_END: + _instance->SetData(DATA_INTRO_EVENT, DONE); + _events.ScheduleEvent(EVENT_KORELN_LORALEN_DEATH, 8000); if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) { - if (_icewall >= 2 && _icewall < 4) - lichking->CastSpell(lichking, SPELL_SUMMON_LUMBERING_ABOMINATION); + lichking->DespawnOrUnsummon(5000); + _lichkingGUID = 0; } + me->DespawnOrUnsummon(10000); + _events.ScheduleEvent(EVENT_CLOSE_IMPENETRABLE_DOOR, 7000); break; - case EVENT_ESCAPE_23: // FINAL PART - DestroyIceWall(); - + case EVENT_SKIP_INTRO: if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - Talk(SAY_JAINA_ESCAPE_6); + me->GetMotionMaster()->MovePoint(0, JainaIntroPosition[2]); else - Talk(SAY_SYLVANAS_ESCAPE_6); + me->GetMotionMaster()->MovePoint(0, SylvanasIntroPosition[2]); - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) + if (Creature* korelnOrLoralen = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_KORELN_LORALEN))) + korelnOrLoralen->GetMotionMaster()->MovePoint(0, KorelnOrLoralenPos[1]); + + if (Creature* lichking = me->SummonCreature(NPC_THE_LICH_KING_INTRO, LichKingIntroPosition[0], TEMPSUMMON_MANUAL_DESPAWN)) { - lichking->GetMotionMaster()->MovePoint(0, LichKingFinalPos); - lichking->AI()->Talk(SAY_LK_ESCAPE_11); + lichking->SetWalk(true); + lichking->GetMotionMaster()->MovePoint(0, LichKingIntroPosition[2]); + lichking->SetReactState(REACT_PASSIVE); + _lichkingGUID = lichking->GetGUID(); + _events.ScheduleEvent(EVENT_OPEN_IMPENETRABLE_DOOR, 0); + _events.ScheduleEvent(EVENT_CLOSE_IMPENETRABLE_DOOR, 4000); } - me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[8]); - _events.ScheduleEvent(EVENT_ESCAPE_24, 10000); + _events.ScheduleEvent(EVENT_INTRO_LK_4, 15000); break; - case EVENT_ESCAPE_24: - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - Talk(SAY_JAINA_ESCAPE_8); - else - Talk(SAY_SYLVANAS_ESCAPE_8); - _events.ScheduleEvent(EVENT_ESCAPE_25, 5000); + case EVENT_OPEN_IMPENETRABLE_DOOR: + _instance->HandleGameObject(_instance->GetData64(DATA_IMPENETRABLE_DOOR), true); break; - case EVENT_ESCAPE_25: - if (GameObject* cave = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_CAVE_IN))) - cave->SetGoState(GO_STATE_READY); - _events.ScheduleEvent(EVENT_ESCAPE_26, 4000); + case EVENT_CLOSE_IMPENETRABLE_DOOR: + _instance->HandleGameObject(_instance->GetData64(DATA_IMPENETRABLE_DOOR), false); break; - case EVENT_ESCAPE_26: - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - Talk(SAY_JAINA_ESCAPE_10); - else - Talk(SAY_SYLVANAS_ESCAPE_9); - _events.ScheduleEvent(EVENT_ESCAPE_27, 4000); + case EVENT_KORELN_LORALEN_DEATH: + if (Creature* korelnOrLoralen = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_KORELN_LORALEN))) + korelnOrLoralen->CastSpell(korelnOrLoralen, SPELL_FEIGN_DEATH); break; - case EVENT_ESCAPE_27: - if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) - me->SummonGameObject(IsHeroic() ? GO_CAPTAIN_CHEST_ALLIANCE_HEROIC : GO_CAPTAIN_CHEST_ALLIANCE_NORMAL, ChestPos.GetPositionX(), ChestPos.GetPositionY(), ChestPos.GetPositionZ(), ChestPos.GetOrientation(), 0, 0, 0, 0, 720000); - else - me->SummonGameObject(IsHeroic() ? GO_CAPTAIN_CHEST_HORDE_HEROIC : GO_CAPTAIN_CHEST_HORDE_NORMAL, ChestPos.GetPositionX(), ChestPos.GetPositionY(), ChestPos.GetPositionZ(), ChestPos.GetOrientation(), 0, 0, 0, 0, 720000); - me->SummonGameObject(GO_PORTAL, FinalPortalPos.GetPositionX(), FinalPortalPos.GetPositionY(), FinalPortalPos.GetPositionZ(), FinalPortalPos.GetOrientation(), 0, 0, 0, 0, 720000); - if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) - lichking->DespawnOrUnsummon(1); + default: break; - } } } - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetHallsOfReflectionAI(creature); - } + private: + InstanceScript* _instance; + EventMap _events; + uint64 _utherGUID; + uint64 _lichkingGUID; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfReflectionAI(creature); + } }; -enum TrashSpells +class npc_jaina_or_sylvanas_escape_hor : public CreatureScript { - // Ghostly Priest - SPELL_SHADOW_WORD_PAIN = 72318, - SPELL_CIRCLE_OF_DESTRUCTION = 72320, - SPELL_COWER_IN_FEAR = 72321, + public: + npc_jaina_or_sylvanas_escape_hor() : CreatureScript("npc_jaina_or_sylvanas_escape_hor") { } + + bool OnGossipHello(Player* player, Creature* creature) override + { + // override default gossip + if (InstanceScript* instance = creature->GetInstanceScript()) + if (instance->GetBossState(DATA_THE_LICH_KING_ESCAPE) == DONE) + { + player->PrepareGossipMenu(creature, creature->GetEntry() == NPC_JAINA_ESCAPE ? GOSSIP_MENU_JAINA_FINAL : GOSSIP_MENU_SYLVANAS_FINAL, true); + player->SendPreparedGossip(creature); + return true; + } + + // load default gossip + return false; + } + + struct npc_jaina_or_sylvanas_escape_horAI : public ScriptedAI + { + npc_jaina_or_sylvanas_escape_horAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()), _icewall(0), _prefight(false), _invincibility(true) { } + + void Reset() override + { + _events.Reset(); + _icewall = 0; + _events.ScheduleEvent(EVENT_ESCAPE, 1000); + _instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_NOT_RETREATING_EVENT); + } + + void JustDied(Unit* /*killer*/) override + { + if (Creature* lichking = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING_ESCAPE))) + lichking->AI()->EnterEvadeMode(); // event failed + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (damage >= me->GetHealth() && _invincibility) + damage = me->GetHealth() - 1; + } + + void DoAction(int32 actionId) override + { + switch (actionId) + { + case ACTION_START_PREFIGHT: + if (_prefight) + return; + _prefight = true; + _events.ScheduleEvent(EVENT_ESCAPE_1, 1000); + break; + case ACTION_WALL_BROKEN: + ++_icewall; + if (_icewall < 4) + _events.ScheduleEvent(EVENT_ESCAPE_13, 3000); + else + _events.ScheduleEvent(EVENT_ESCAPE_15, 3000); + break; + case ACTION_GUNSHIP_ARRIVAL: + _events.ScheduleEvent(EVENT_ESCAPE_16, 5000); + break; + case ACTION_GUNSHIP_ARRIVAL_2: + _events.ScheduleEvent(EVENT_ESCAPE_17, 5000); + break; + default: + break; + } + } + + void sGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + { + player->PlayerTalkClass->ClearMenus(); + + switch (gossipListId) + { + case 0: + player->PlayerTalkClass->SendCloseGossip(); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + _events.ScheduleEvent(EVENT_ESCAPE_6, 0); + break; + default: + break; + } + } + + void DestroyIceWall() + { + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + me->RemoveAurasDueToSpell(SPELL_JAINA_DESTROY_ICE_WALL); + else + me->RemoveAurasDueToSpell(SPELL_SYLVANAS_DESTROY_ICE_WALL); + + _instance->HandleGameObject(_instance->GetData64(DATA_ICEWALL), true); + me->m_Events.AddEvent(new GameObjectDeleteDelayEvent(me, _instance->GetData64(DATA_ICEWALL)), me->m_Events.CalculateTime(5000)); + + if (Creature* wallTarget = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ICEWALL_TARGET))) + wallTarget->DespawnOrUnsummon(); + } + + void SummonIceWall() + { + if (_icewall < 4) + { + if (Creature* lichking = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING_ESCAPE))) + { + lichking->StopMoving(); + if (Creature* wallTarget = me->SummonCreature(NPC_ICE_WALL_TARGET, IceWallTargetPosition[_icewall], TEMPSUMMON_MANUAL_DESPAWN, 720000)) + lichking->CastSpell(wallTarget, SPELL_SUMMON_ICE_WALL); + + lichking->AI()->SetData(DATA_ICEWALL, _icewall); + } + } + } + + void AttackIceWall() + { + if (_icewall < 4) + Talk(SAY_JAINA_SYLVANAS_ESCAPE_2 + _icewall); + + if (Creature* wallTarget = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ICEWALL_TARGET))) + me->SetFacingToObject(wallTarget); + + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + DoCast(me, SPELL_JAINA_DESTROY_ICE_WALL, true); + else + DoCast(me, SPELL_SYLVANAS_DESTROY_ICE_WALL, true); + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != POINT_MOTION_TYPE) + return; + + switch (pointId) + { + case POINT_SHADOW_THRONE_DOOR: + if (me->GetEntry() == NPC_JAINA_ESCAPE) + me->RemoveAurasDueToSpell(SPELL_JAINA_ICE_BARRIER); + else + me->RemoveAurasDueToSpell(SPELL_SYLVANAS_CLOAK_OF_DARKNESS); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + me->SetHealth(JAINA_SYLVANAS_MAX_HEALTH); + me->SetFacingTo(SylvanasShadowThroneDoorPosition.GetOrientation()); + break; + case POINT_ATTACK_ICEWALL: + AttackIceWall(); + break; + case POINT_TRAP: + Talk(SAY_JAINA_SYLVANAS_ESCAPE_8); + if (Creature* lichking = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING_ESCAPE))) + me->SetFacingToObject(lichking); + break; + default: + break; + } + } + + void DeleteAllFromThreatList(Unit* target, uint64 except) + { + ThreatContainer::StorageType threatlist = target->getThreatManager().getThreatList(); + for (auto i : threatlist) + { + if (i->getUnitGuid() == except) + continue; + + i->removeReference(); + } + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + while (uint32 event = _events.ExecuteEvent()) + { + switch (event) + { + case EVENT_ESCAPE: + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + DoCast(me, SPELL_JAINA_ICE_BARRIER); + else + DoCast(me, SPELL_SYLVANAS_CLOAK_OF_DARKNESS); + + if (Creature* lichking = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING_ESCAPE))) + { + AttackStart(lichking); + lichking->AI()->AttackStart(me); + me->CastSpell(lichking, SPELL_TAUNT_ARTHAS, true); + } + me->SetHealth(JAINA_SYLVANAS_MAX_HEALTH); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); + break; + case EVENT_ESCAPE_1: + if (Creature* lichking = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING_ESCAPE))) + { + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + lichking->AI()->Talk(SAY_LK_ESCAPE_1); + else + lichking->AI()->Talk(SAY_LK_ESCAPE_2); + _events.ScheduleEvent(EVENT_ESCAPE_2, 8000); + } + break; + case EVENT_ESCAPE_2: + me->AttackStop(); + me->StopMoving(); + me->SetReactState(REACT_PASSIVE); + + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + DoCast(me, SPELL_JAINA_ICE_PRISON, false); + else + DoCast(me, SPELL_SYLVANAS_BLINDING_RETREAT, true); + + if (Creature* lichking = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING_ESCAPE))) + { + lichking->SetReactState(REACT_PASSIVE); + lichking->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED); + } + + _events.ScheduleEvent(EVENT_ESCAPE_3, 1500); + break; + case EVENT_ESCAPE_3: + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE) + DoCastAOE(SPELL_SYLVANAS_DARK_BINDING, true); + _events.ScheduleEvent(EVENT_ESCAPE_4, 1000); + break; + case EVENT_ESCAPE_4: + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + DoCast(me, SPELL_CREDIT_FINDING_JAINA); + else + DoCast(me, SPELL_CREDIT_FINDING_SYLVANAS); + Talk(SAY_JAINA_SYLVANAS_ESCAPE_1); + + if (Creature* lichking = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING_ESCAPE))) + { + lichking->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + lichking->RemoveAllAttackers(); + + DeleteAllFromThreatList(lichking, me->GetGUID()); + } + + _events.ScheduleEvent(EVENT_ESCAPE_5, 2000); + break; + case EVENT_ESCAPE_5: + me->GetMotionMaster()->MovePoint(POINT_SHADOW_THRONE_DOOR, SylvanasShadowThroneDoorPosition); + break; + case EVENT_ESCAPE_6: + if (Creature* lichking = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING_ESCAPE))) + { + lichking->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_PACIFIED); + + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + { + lichking->CastSpell(lichking, SPELL_STUN_BREAK_JAINA); + lichking->RemoveAurasDueToSpell(SPELL_JAINA_ICE_PRISON); + } + else + { + lichking->CastSpell(lichking, SPELL_STUN_BREAK_SYLVANAS); + lichking->RemoveAurasDueToSpell(SPELL_SYLVANAS_DARK_BINDING); + } + } + _invincibility = false; + _instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_NOT_RETREATING_EVENT); + _events.ScheduleEvent(EVENT_ESCAPE_7, 1000); + break; + case EVENT_ESCAPE_7: + if (Creature* lichking = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING_ESCAPE))) + lichking->HandleEmoteCommand(TEXT_EMOTE_ROAR); + me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[0]); + _events.ScheduleEvent(EVENT_ESCAPE_8, 3000); + break; + case EVENT_ESCAPE_8: + if (Creature* lichking = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING_ESCAPE))) + lichking->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[0]); + _events.ScheduleEvent(EVENT_ESCAPE_9, 1000); + break; + case EVENT_ESCAPE_9: + me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[1]); + _events.ScheduleEvent(EVENT_ESCAPE_10, 5000); + break; + case EVENT_ESCAPE_10: + me->GetMotionMaster()->MovePoint(0, NpcJainaOrSylvanasEscapeRoute[2]); + if (Creature* lichking = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING_ESCAPE))) + lichking->GetMotionMaster()->MovePoint(1, LichKingFirstSummon); + _events.ScheduleEvent(EVENT_ESCAPE_11, 6000); + break; + case EVENT_ESCAPE_11: + SummonIceWall(); + _events.ScheduleEvent(EVENT_ESCAPE_12, 4000); + break; + case EVENT_ESCAPE_12: + if (Creature* lichking = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING_ESCAPE))) + lichking->CastSpell(lichking, SPELL_PAIN_AND_SUFFERING, true); + + me->GetMotionMaster()->MovePoint(POINT_ATTACK_ICEWALL, NpcJainaOrSylvanasEscapeRoute[3]); + break; + case EVENT_ESCAPE_13: // ICEWALL BROKEN + DestroyIceWall(); + + if (_icewall && _icewall < 4) + me->GetMotionMaster()->MovePoint(POINT_ATTACK_ICEWALL, NpcJainaOrSylvanasEscapeRoute[_icewall + 3]); + _events.ScheduleEvent(EVENT_ESCAPE_14, 8000); + break; + case EVENT_ESCAPE_14: + SummonIceWall(); + break; + case EVENT_ESCAPE_15: // FINAL PART + DestroyIceWall(); + + Talk(SAY_JAINA_SYLVANAS_ESCAPE_6); + + if (Creature* lichking = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING_ESCAPE))) + { + lichking->GetMotionMaster()->MovePoint(2, LichKingFinalPos); + lichking->RemoveAurasDueToSpell(SPELL_REMORSELESS_WINTER); + } + me->GetMotionMaster()->MovePoint(POINT_TRAP, NpcJainaOrSylvanasEscapeRoute[7]); + break; + case EVENT_ESCAPE_16: + me->RemoveAurasDueToSpell(SPELL_HARVEST_SOUL); + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + Talk(SAY_JAINA_ESCAPE_9); + if (Transport* gunship = ObjectAccessor::GetTransport(*me, _instance->GetData64(DATA_GUNSHIP))) + gunship->EnableMovement(true); + _instance->SetBossState(DATA_THE_LICH_KING_ESCAPE, DONE); + break; + case EVENT_ESCAPE_17: + if (_instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) + Talk(SAY_JAINA_ESCAPE_10); + else + Talk(SAY_SYLVANAS_ESCAPE_9); + DoCast(me, SPELL_CREDIT_ESCAPING_ARTHAS); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + InstanceScript* _instance; + EventMap _events; + uint32 _icewall; // icewall number + bool _prefight; + bool _invincibility; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfReflectionAI(creature); + } +}; + +class npc_the_lich_king_escape_hor : public CreatureScript +{ + public: + npc_the_lich_king_escape_hor() : CreatureScript("npc_the_lich_king_escape_hor") { } + + struct npc_the_lich_king_escape_horAI : public ScriptedAI + { + npc_the_lich_king_escape_horAI(Creature* creature) : ScriptedAI(creature) + { + _instance = me->GetInstanceScript(); + _instance->SetBossState(DATA_THE_LICH_KING_ESCAPE, NOT_STARTED); + _summonsCount = 0; + _icewall = 0; + _despawn = false; + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (damage >= me->GetHealth()) + damage = me->GetHealth() - 1; + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type == POINT_MOTION_TYPE) + { + switch (pointId) + { + case 1: + if (Creature* target = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ESCAPE_LEADER))) + me->GetMotionMaster()->MoveChase(target); + break; + case 2: + Talk(SAY_LK_ESCAPE_HARVEST_SOUL); + + if (Creature* target = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ESCAPE_LEADER))) + DoCast(target, SPELL_HARVEST_SOUL); + + if (Transport* gunship = ObjectAccessor::GetTransport(*me, _instance->GetData64(DATA_GUNSHIP))) + gunship->EnableMovement(true); + break; + default: + break; + } + } + } + + void JustSummoned(Creature* /*summon*/) override + { + ++_summonsCount; + } + + void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) override + { + // should never happen + if (!_summonsCount) + return; + + --_summonsCount; + + // All summons dead and no summon events scheduled + if (!_summonsCount && _events.Empty()) + { + if (Creature* jainaOrSylvanas = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ESCAPE_LEADER))) + jainaOrSylvanas->AI()->DoAction(ACTION_WALL_BROKEN); + } + } + + void KilledUnit(Unit* who) override + { + if (who->GetTypeId() == TYPEID_PLAYER) + DoPlaySoundToSet(me, RAND(SOUND_LK_SLAY_1, SOUND_LK_SLAY_2)); + } + + void SetData(uint32 type, uint32 data) override + { + if (type != DATA_ICEWALL) + return; + + _icewall = data; + + switch (_icewall) + { + case 0: // 6 Ghouls, 1 Witch Doctor + DoZoneInCombat(); + _events.ScheduleEvent(EVENT_REMORSELESS_WINTER, 0); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_GHOULS, 8000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_WITCH_DOCTOR, 14000); + Talk(SAY_LK_ESCAPE_ICEWALL_SUMMONED_1); + break; + case 1: // 6 Ghouls, 2 Witch Doctor, 1 Lumbering Abomination + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_GHOULS, 8000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_LUMBERING_ABOMINATION, 13000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_WITCH_DOCTOR, 16000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_WITCH_DOCTOR, 18000); + Talk(SAY_LK_ESCAPE_ICEWALL_SUMMONED_2); + break; + case 2: // 6 Ghouls, 2 Witch Doctor, 2 Lumbering Abomination + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_GHOULS, 9000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_LUMBERING_ABOMINATION, 14000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_WITCH_DOCTOR, 17000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_LUMBERING_ABOMINATION, 19000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_WITCH_DOCTOR, 39000); + Talk(SAY_LK_ESCAPE_ICEWALL_SUMMONED_3); + break; + case 3: // 12 Ghouls, 4 Witch Doctor, 3 Lumbering Abomination + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_GHOULS, 9000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_WITCH_DOCTOR, 17000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_WITCH_DOCTOR, 19000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_LUMBERING_ABOMINATION, 40000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_LUMBERING_ABOMINATION, 46000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_GHOULS, 55000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_WITCH_DOCTOR, 62000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_WITCH_DOCTOR, 66000); + _events.ScheduleEvent(EVENT_ESCAPE_SUMMON_LUMBERING_ABOMINATION, 14000); + Talk(SAY_LK_ESCAPE_ICEWALL_SUMMONED_4); + break; + default: + break; + } + } + + void EnterEvadeMode() override + { + if (_despawn) + return; + + _instance->SetBossState(DATA_THE_LICH_KING_ESCAPE, FAIL); + me->StopMoving(); + DoPlaySoundToSet(me, SOUND_LK_FURY_OF_FROSTMOURNE); + DoCastAOE(SPELL_FURY_OF_FROSTMOURNE); + me->DespawnOrUnsummon(12000); + _despawn = true; + } + + void UpdateAI(uint32 diff) override + { + if (!SelectVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 event = _events.ExecuteEvent()) + { + switch (event) + { + case EVENT_REMORSELESS_WINTER: + me->StopMoving(); + Talk(SAY_LK_ESCAPE_WINTER); + DoCast(me, SPELL_REMORSELESS_WINTER); + break; + case EVENT_ESCAPE_SUMMON_GHOULS: + me->StopMoving(); + Talk(SAY_LK_ESCAPE_GHOULS); + DoCast(me, SPELL_RAISE_DEAD); + break; + case EVENT_ESCAPE_SUMMON_WITCH_DOCTOR: + DoCast(me, SPELL_SUMMON_RISEN_WITCH_DOCTOR); + break; + case EVENT_ESCAPE_SUMMON_LUMBERING_ABOMINATION: + Talk(SAY_LK_ESCAPE_ABOMINATION); + DoCast(me, SPELL_SUMMON_LUMBERING_ABOMINATION); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + bool SelectVictim() + { + if (!me->IsInCombat()) + return false; + + if (!me->HasReactState(REACT_PASSIVE)) + { + if (Unit* victim = me->SelectVictim()) + AttackStart(victim); + return me->GetVictim(); + } + else if (me->getThreatManager().getThreatList().size() < 2 && me->HasAura(SPELL_REMORSELESS_WINTER)) + { + EnterEvadeMode(); + return false; + } + + return true; + } + + InstanceScript* _instance; + EventMap _events; + uint8 _icewall; + uint32 _summonsCount; + bool _despawn; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfReflectionAI(creature); + } +}; + +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 @@ -1140,7 +1372,7 @@ enum TrashSpells SPELL_SHOOT = 72208, SPELL_CURSED_ARROW = 72222, SPELL_FROST_TRAP = 72215, - SPELL_ICE_SHOT = 72268, + SPELL_ICE_SHOT = 72268 }; enum TrashEvents @@ -1175,19 +1407,16 @@ enum TrashEvents EVENT_SHOOT, EVENT_CURSED_ARROW, EVENT_FROST_TRAP, - EVENT_ICE_SHOT, + EVENT_ICE_SHOT }; struct npc_gauntlet_trash : public ScriptedAI { - npc_gauntlet_trash(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) - { - InternalWaveId = 0; - } + npc_gauntlet_trash(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()), InternalWaveId(0) { } void Reset() override { - InternalWaveId = 0; me->CastSpell(me, SPELL_WELL_OF_SOULS, true); _events.Reset(); } @@ -1222,352 +1451,362 @@ protected: class npc_ghostly_priest : public CreatureScript { -public: - npc_ghostly_priest() : CreatureScript("npc_ghostly_priest") { } - - struct npc_ghostly_priestAI : public npc_gauntlet_trash - { - npc_ghostly_priestAI(Creature* creature) : npc_gauntlet_trash(creature) { } + public: + npc_ghostly_priest() : CreatureScript("npc_ghostly_priest") { } - void EnterCombat(Unit* /*who*/) override + struct npc_ghostly_priestAI : public npc_gauntlet_trash { - _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); - } + npc_ghostly_priestAI(Creature* creature) : npc_gauntlet_trash(creature) { } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (_events.ExecuteEvent()) - { - case EVENT_SHADOW_WORD_PAIN: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_SHADOW_WORD_PAIN); - _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000); - break; - case EVENT_CIRCLE_OF_DESTRUCTION: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_CIRCLE_OF_DESTRUCTION); - _events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000); - break; - case EVENT_COWER_IN_FEAR: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_COWER_IN_FEAR); - _events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000); - break; - case EVENT_DARK_MENDING: - // find an ally with missing HP - if (Unit* target = DoSelectLowestHpFriendly(40, DUNGEON_MODE(30000, 50000))) - { - DoCast(target, 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); - } - break; + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(6000, 15000)); + _events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000); + _events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000); + _events.ScheduleEvent(EVENT_DARK_MENDING, 20000); } - DoMeleeAttackIfReady(); - } - }; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI(creature); - } -}; + _events.Update(diff); -class npc_phantom_mage : public CreatureScript -{ -public: - npc_phantom_mage() : CreatureScript("npc_phantom_mage") { } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - struct npc_phantom_mageAI : public npc_gauntlet_trash - { - npc_phantom_mageAI(Creature* creature) : npc_gauntlet_trash(creature) { } + switch (_events.ExecuteEvent()) + { + case EVENT_SHADOW_WORD_PAIN: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true)) + DoCast(target, SPELL_SHADOW_WORD_PAIN); + _events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(6000, 15000)); + break; + case EVENT_CIRCLE_OF_DESTRUCTION: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 10.0f, true)) + DoCast(target, SPELL_CIRCLE_OF_DESTRUCTION); + _events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000); + break; + case EVENT_COWER_IN_FEAR: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 20.0f, true)) + DoCast(target, SPELL_COWER_IN_FEAR); + _events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000); + break; + case EVENT_DARK_MENDING: + // find an ally with missing HP + if (Unit* target = DoSelectLowestHpFriendly(40, DUNGEON_MODE(30000, 50000))) + { + DoCast(target, 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); + } + break; + default: + break; + } + + DoMeleeAttackIfReady(); + } + }; - void EnterEvadeMode() override + CreatureAI* GetAI(Creature* creature) const override { - if (!me->HasAura(AURA_HALLUCINATION)) - npc_gauntlet_trash::EnterEvadeMode(); + return GetHallsOfReflectionAI(creature); } +}; - void EnterCombat(Unit* /*who*/) override +class npc_phantom_mage : public CreatureScript +{ + public: + npc_phantom_mage() : CreatureScript("npc_phantom_mage") { } + + struct npc_phantom_mageAI : public npc_gauntlet_trash { - _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); - } + npc_phantom_mageAI(Creature* creature) : npc_gauntlet_trash(creature) { } + + void EnterEvadeMode() override + { + if (!me->HasAura(AURA_HALLUCINATION)) + npc_gauntlet_trash::EnterEvadeMode(); + } + + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_FIREBALL, 3000); + _events.ScheduleEvent(EVENT_FLAMESTRIKE, 6000); + _events.ScheduleEvent(EVENT_FROSTBOLT, 9000); + _events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 12000); + _events.ScheduleEvent(EVENT_HALLUCINATION, 40000); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (_events.ExecuteEvent()) + { + case EVENT_FIREBALL: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true)) + DoCast(target, SPELL_FIREBALL); + _events.ScheduleEvent(EVENT_FIREBALL, 15000); + break; + case EVENT_FLAMESTRIKE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true)) + DoCast(target, SPELL_FLAMESTRIKE); + _events.ScheduleEvent(EVENT_FLAMESTRIKE, 15000); + break; + case EVENT_FROSTBOLT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true)) + DoCast(target, SPELL_FROSTBOLT); + _events.ScheduleEvent(EVENT_FROSTBOLT, 15000); + break; + case EVENT_CHAINS_OF_ICE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) + DoCast(target, SPELL_CHAINS_OF_ICE); + _events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 15000); + break; + case EVENT_HALLUCINATION: + // removing any dots on mage or else the invisibility spell will break duration + me->RemoveAllAuras(); + DoCast(me, SPELL_HALLUCINATION); + break; + default: + break; + } + + DoMeleeAttackIfReady(); + } + }; - void UpdateAI(uint32 diff) override + CreatureAI* GetAI(Creature* creature) const override { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (_events.ExecuteEvent()) - { - case EVENT_FIREBALL: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_FIREBALL); - _events.ScheduleEvent(EVENT_FIREBALL, 15000); - break; - case EVENT_FLAMESTRIKE: - DoCast(SPELL_FLAMESTRIKE); - _events.ScheduleEvent(EVENT_FLAMESTRIKE, 15000); - break; - case EVENT_FROSTBOLT: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_FROSTBOLT); - _events.ScheduleEvent(EVENT_FROSTBOLT, 15000); - break; - case EVENT_CHAINS_OF_ICE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_CHAINS_OF_ICE); - _events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 15000); - break; - case EVENT_HALLUCINATION: - // removing any dots on mage or else the invisibility spell will break duration - me->RemoveAllAuras(); - DoCast(SPELL_HALLUCINATION); - break; - } - - DoMeleeAttackIfReady(); + return GetHallsOfReflectionAI(creature); } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI(creature); - } }; class npc_phantom_hallucination : public CreatureScript { -public: - npc_phantom_hallucination() : CreatureScript("npc_phantom_hallucination") { } - - struct npc_phantom_hallucinationAI : public npc_phantom_mage::npc_phantom_mageAI - { - npc_phantom_hallucinationAI(Creature* creature) : npc_phantom_mage::npc_phantom_mageAI(creature) { } + public: + npc_phantom_hallucination() : CreatureScript("npc_phantom_hallucination") { } - void Reset() override + struct npc_phantom_hallucinationAI : public npc_phantom_mage::npc_phantom_mageAI { - if (Unit* unit = me->SelectNearestTarget()) - AttackStart(unit); - DoZoneInCombat(); - } + npc_phantom_hallucinationAI(Creature* creature) : npc_phantom_mage::npc_phantom_mageAI(creature) { } - void EnterEvadeMode() override - { - if (me->GetOwner() && !me->GetOwner()->HasAura(AURA_HALLUCINATION)) - npc_phantom_mage::npc_phantom_mageAI::EnterEvadeMode(); - } + void Reset() override + { + DoZoneInCombat(me, MAX_VISIBILITY_DISTANCE); + } + + void EnterEvadeMode() override + { + if (me->GetOwner() && !me->GetOwner()->HasAura(AURA_HALLUCINATION)) + npc_phantom_mage::npc_phantom_mageAI::EnterEvadeMode(); + } + + void JustDied(Unit* /*killer*/) override + { + DoCastAOE(SPELL_HALLUCINATION_2); + } + }; - void JustDied(Unit* /*killer*/) override + CreatureAI* GetAI(Creature* creature) const override { - DoCast(SPELL_HALLUCINATION_2); + return new npc_phantom_hallucinationAI(creature); } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_phantom_hallucinationAI(creature); - } }; class npc_shadowy_mercenary : public CreatureScript { -public: - npc_shadowy_mercenary() : CreatureScript("npc_shadowy_mercenary") { } - - struct npc_shadowy_mercenaryAI : public npc_gauntlet_trash - { - npc_shadowy_mercenaryAI(Creature* creature) : npc_gauntlet_trash(creature) { } + public: + npc_shadowy_mercenary() : CreatureScript("npc_shadowy_mercenary") { } - void EnterCombat(Unit* /*who*/) override + struct npc_shadowy_mercenaryAI : public npc_gauntlet_trash { - _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); - } + npc_shadowy_mercenaryAI(Creature* creature) : npc_gauntlet_trash(creature) { } - void UpdateAI(uint32 diff) override + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_SHADOW_STEP, 23000); + _events.ScheduleEvent(EVENT_DEADLY_POISON, 5000); + _events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000); + _events.ScheduleEvent(EVENT_KIDNEY_SHOT, 12000); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (_events.ExecuteEvent()) + { + case EVENT_SHADOW_STEP: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_SHADOW_STEP); + _events.ScheduleEvent(EVENT_SHADOW_STEP, 8000); + break; + case EVENT_DEADLY_POISON: + DoCastVictim(SPELL_DEADLY_POISON); + _events.ScheduleEvent(EVENT_DEADLY_POISON, 10000); + break; + case EVENT_ENVENOMED_DAGGER_THROW: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true)) + DoCast(target, SPELL_ENVENOMED_DAGGER_THROW); + _events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000); + break; + case EVENT_KIDNEY_SHOT: + DoCastVictim(SPELL_KIDNEY_SHOT); + _events.ScheduleEvent(EVENT_KIDNEY_SHOT, 10000); + break; + default: + break; + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (_events.ExecuteEvent()) - { - case EVENT_SHADOW_STEP: - DoCast(SPELL_SHADOW_STEP); - _events.ScheduleEvent(EVENT_SHADOW_STEP, 8000); - break; - case EVENT_DEADLY_POISON: - DoCastVictim(SPELL_DEADLY_POISON); - _events.ScheduleEvent(EVENT_DEADLY_POISON, 10000); - break; - case EVENT_ENVENOMED_DAGGER_THROW: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_ENVENOMED_DAGGER_THROW); - _events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000); - break; - case EVENT_KIDNEY_SHOT: - DoCastVictim(SPELL_KIDNEY_SHOT); - _events.ScheduleEvent(EVENT_KIDNEY_SHOT, 10000); - break; - } - - DoMeleeAttackIfReady(); + return GetHallsOfReflectionAI(creature); } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI(creature); - } }; class npc_spectral_footman : public CreatureScript { -public: - npc_spectral_footman() : CreatureScript("npc_spectral_footman") { } - - struct npc_spectral_footmanAI : public npc_gauntlet_trash - { - npc_spectral_footmanAI(Creature* creature) : npc_gauntlet_trash(creature) { } + public: + npc_spectral_footman() : CreatureScript("npc_spectral_footman") { } - void EnterCombat(Unit* /*who*/) override + struct npc_spectral_footmanAI : public npc_gauntlet_trash { - _events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); /// @todo adjust timers - _events.ScheduleEvent(EVENT_SHIELD_BASH, 10000); - _events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000); - } + npc_spectral_footmanAI(Creature* creature) : npc_gauntlet_trash(creature) { } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 14000); + _events.ScheduleEvent(EVENT_SHIELD_BASH, 10000); + _events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - _events.Update(diff); + _events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - switch (_events.ExecuteEvent()) - { - case EVENT_SPECTRAL_STRIKE: - DoCastVictim(SPELL_SPECTRAL_STRIKE); - _events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); - break; - case EVENT_SHIELD_BASH: - DoCastVictim(SPELL_SHIELD_BASH); - _events.ScheduleEvent(EVENT_SHIELD_BASH, 5000); - break; - case EVENT_TORTURED_ENRAGE: - DoCast(SPELL_TORTURED_ENRAGE); - _events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000); - break; + switch (_events.ExecuteEvent()) + { + case EVENT_SPECTRAL_STRIKE: + DoCastVictim(SPELL_SPECTRAL_STRIKE); + _events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); + break; + case EVENT_SHIELD_BASH: + DoCastVictim(SPELL_SHIELD_BASH); + _events.ScheduleEvent(EVENT_SHIELD_BASH, 5000); + break; + case EVENT_TORTURED_ENRAGE: + DoCast(me, SPELL_TORTURED_ENRAGE); + _events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000); + break; + default: + break; + } + + DoMeleeAttackIfReady(); } + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfReflectionAI(creature); } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI(creature); - } }; class npc_tortured_rifleman : public CreatureScript { -public: - npc_tortured_rifleman() : CreatureScript("npc_tortured_rifleman") { } - - struct npc_tortured_riflemanAI : public npc_gauntlet_trash - { - npc_tortured_riflemanAI(Creature* creature) : npc_gauntlet_trash(creature) { } + public: + npc_tortured_rifleman() : CreatureScript("npc_tortured_rifleman") { } - void EnterCombat(Unit* /*who*/) override + struct npc_tortured_riflemanAI : public npc_gauntlet_trash { - _events.ScheduleEvent(EVENT_SHOOT, 1); /// @todo adjust timers - _events.ScheduleEvent(EVENT_CURSED_ARROW, 7000); - _events.ScheduleEvent(EVENT_FROST_TRAP, 10000); - _events.ScheduleEvent(EVENT_ICE_SHOT, 15000); - } + npc_tortured_riflemanAI(Creature* creature) : npc_gauntlet_trash(creature) { } + + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_SHOOT, 1); + _events.ScheduleEvent(EVENT_CURSED_ARROW, 7000); + _events.ScheduleEvent(EVENT_FROST_TRAP, 10000); + _events.ScheduleEvent(EVENT_ICE_SHOT, 15000); + } - void UpdateAI(uint32 diff) override + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (_events.ExecuteEvent()) + { + case EVENT_SHOOT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true)) + DoCast(target, SPELL_SHOOT); + _events.ScheduleEvent(EVENT_SHOOT, 2000); + break; + case EVENT_CURSED_ARROW: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true)) + DoCast(target, SPELL_CURSED_ARROW); + _events.ScheduleEvent(EVENT_CURSED_ARROW, 10000); + break; + case EVENT_FROST_TRAP: + DoCast(me, SPELL_FROST_TRAP); + _events.ScheduleEvent(EVENT_FROST_TRAP, 30000); + break; + case EVENT_ICE_SHOT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true)) + DoCast(target, SPELL_ICE_SHOT); + _events.ScheduleEvent(EVENT_ICE_SHOT, 15000); + break; + default: + break; + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override { - if (!UpdateVictim()) - return; - - _events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (_events.ExecuteEvent()) - { - case EVENT_SHOOT: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_SHOOT); - _events.ScheduleEvent(EVENT_SHOOT, 2000); - break; - case EVENT_CURSED_ARROW: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_CURSED_ARROW); - _events.ScheduleEvent(EVENT_CURSED_ARROW, 10000); - break; - case EVENT_FROST_TRAP: - DoCast(SPELL_FROST_TRAP); - _events.ScheduleEvent(EVENT_FROST_TRAP, 30000); - break; - case EVENT_ICE_SHOT: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_ICE_SHOT); - _events.ScheduleEvent(EVENT_ICE_SHOT, 15000); - break; - } - DoMeleeAttackIfReady(); + return GetHallsOfReflectionAI(creature); } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI(creature); - } }; - -enum GeneralEvents +enum FrostswornGeneral { - //General + // General EVENT_SHIELD = 1, EVENT_SPIKE = 2, EVENT_CLONE = 3, @@ -1575,554 +1814,647 @@ enum GeneralEvents SAY_AGGRO = 0, SAY_DEATH = 1, - SPELL_SHIELD_THROWN = 69222, // 73076 on hc - SPELL_SPIKE = 69184, // 70399 on hc - SPELL_CLONE_NAME = 57507, - SPELL_CLONE_MODEL = 45204, + SPELL_SHIELD_THROWN = 69222, + SPELL_SPIKE = 69184, + SPELL_CLONE = 69828, + SPELL_GHOST_VISUAL = 69861, + + // Reflection + EVENT_BALEFUL_STRIKE = 1, + + SPELL_BALEFUL_STRIKE = 69933, + SPELL_SPIRIT_BURST = 69900 +}; + +class npc_frostsworn_general : public CreatureScript +{ + public: + npc_frostsworn_general() : CreatureScript("npc_frostsworn_general") { } + + struct npc_frostsworn_generalAI : public ScriptedAI + { + npc_frostsworn_generalAI(Creature* creature) : ScriptedAI(creature) + { + _instance = creature->GetInstanceScript(); + } + + void Reset() override + { + _events.Reset(); + _instance->SetData(DATA_FROSTSWORN_GENERAL, NOT_STARTED); + } + + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_DEATH); + _events.Reset(); + _instance->SetData(DATA_FROSTSWORN_GENERAL, DONE); + } + + void EnterCombat(Unit* /*victim*/) override + { + Talk(SAY_AGGRO); + DoZoneInCombat(); + _events.ScheduleEvent(EVENT_SHIELD, 5000); + _events.ScheduleEvent(EVENT_SPIKE, 14000); + _events.ScheduleEvent(EVENT_CLONE, 22000); + _instance->SetData(DATA_FROSTSWORN_GENERAL, IN_PROGRESS); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 event = _events.ExecuteEvent()) + { + switch (event) + { + case EVENT_SHIELD: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f, true)) + DoCast(target, SPELL_SHIELD_THROWN); + _events.ScheduleEvent(EVENT_SHIELD, urand(8000, 12000)); + break; + case EVENT_SPIKE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f, true)) + DoCast(target, SPELL_SPIKE); + _events.ScheduleEvent(EVENT_SPIKE, urand(15000, 20000)); + break; + case EVENT_CLONE: + SummonClones(); + _events.ScheduleEvent(EVENT_CLONE, 60000); + break; + default: + break; + } + } + DoMeleeAttackIfReady(); + } + + void SummonClones() + { + std::list playerList; + SelectTargetList(playerList, 5, SELECT_TARGET_TOPAGGRO, 0.0f, true); + for (Unit* target : playerList) + { + if (Creature* reflection = me->SummonCreature(NPC_REFLECTION, *target, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000)) + { + target->CastSpell(reflection, SPELL_CLONE, true); + target->CastSpell(reflection, SPELL_GHOST_VISUAL, true); + reflection->AI()->AttackStart(target); + } + } + } - // Reflection - EVENT_BALEFUL_STRIKE = 1, + private: + InstanceScript* _instance; + EventMap _events; + }; - SPELL_BALEFUL_STRIKE = 69933, // 70400 on hc - SPELL_SPIRIT_BURST = 69900, // 73046 on hc + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfReflectionAI(creature); + } }; -class npc_frostworn_general : public CreatureScript +class npc_spiritual_reflection : public CreatureScript { -public: - npc_frostworn_general() : CreatureScript("npc_frostworn_general") { } + public: + npc_spiritual_reflection() : CreatureScript("npc_spiritual_reflection") { } - struct npc_frostworn_generalAI : public ScriptedAI - { - npc_frostworn_generalAI(Creature* creature) : ScriptedAI(creature) + struct npc_spiritual_reflectionAI : public ScriptedAI { - _instance = me->GetInstanceScript(); - Reset(); - } - - InstanceScript* _instance; - EventMap _events; + npc_spiritual_reflectionAI(Creature *creature) : ScriptedAI(creature) { } - void Reset() override - { - _events.Reset(); - _instance->SetData(DATA_FROSWORN_EVENT, NOT_STARTED); - } + void Reset() override + { + _events.Reset(); + } - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEATH); - _instance->SetData(DATA_FROSWORN_EVENT, DONE); - } + void EnterCombat(Unit* /*victim*/) override + { + _events.ScheduleEvent(EVENT_BALEFUL_STRIKE, 3000); + } - void EnterCombat(Unit* /*victim*/) override - { - Talk(SAY_AGGRO); - _events.ScheduleEvent(EVENT_SHIELD, 5000); - _events.ScheduleEvent(EVENT_SPIKE, 14000); - _events.ScheduleEvent(EVENT_CLONE, 22000); - _instance->SetData(DATA_FROSWORN_EVENT, IN_PROGRESS); - } + void JustDied(Unit* /*killer*/) override + { + DoCastAOE(SPELL_SPIRIT_BURST); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - _events.Update(diff); + _events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - while (uint32 event = _events.ExecuteEvent()) - { - switch (event) + switch (_events.ExecuteEvent()) { - case EVENT_SHIELD: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SHIELD_THROWN); - _events.ScheduleEvent(EVENT_SHIELD, urand(8000, 12000)); - break; - case EVENT_SPIKE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SPIKE); - _events.ScheduleEvent(EVENT_SPIKE, urand(15000, 20000)); + case EVENT_BALEFUL_STRIKE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 8.0f, true)) + DoCast(target, SPELL_BALEFUL_STRIKE); + _events.ScheduleEvent(EVENT_BALEFUL_STRIKE, urand(3000, 8000)); break; - case EVENT_CLONE: - SummonClones(); - _events.ScheduleEvent(EVENT_CLONE, 60000); + default: break; } + + DoMeleeAttackIfReady(); } - DoMeleeAttackIfReady(); - } - void SummonClones() + private: + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const override { - std::list playerList; - SelectTargetList(playerList, 5, SELECT_TARGET_TOPAGGRO, 0, true); - for (std::list::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr) - { - Unit* temp = (*itr); - Creature* reflection = me->SummonCreature(NPC_REFLECTION, temp->GetPositionX(), temp->GetPositionY(), temp->GetPositionZ(), temp->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 3000); - reflection->SetName(temp->GetName()); - temp->CastSpell(reflection, SPELL_CLONE_NAME, true); - temp->CastSpell(reflection, SPELL_CLONE_MODEL, true); - reflection->setFaction(me->getFaction()); - reflection->AI()->AttackStart(temp); - } + return new npc_spiritual_reflectionAI(creature); } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI(creature); - } }; -class npc_spiritual_reflection : public CreatureScript +// 5689 +class at_hor_intro_start : public AreaTriggerScript { -public: - npc_spiritual_reflection() : CreatureScript("npc_spiritual_reflection") { } + public: + at_hor_intro_start() : AreaTriggerScript("at_hor_intro_start") { } - struct npc_spiritual_reflectionAI : public ScriptedAI - { - npc_spiritual_reflectionAI(Creature *creature) : ScriptedAI(creature) + bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) override { - Reset(); - } + if (player->IsGameMaster()) + return true; - EventMap _events; + InstanceScript* _instance = player->GetInstanceScript(); - void Reset() override - { - _events.Reset(); - } + if (_instance->GetData(DATA_INTRO_EVENT) == NOT_STARTED) + _instance->SetData(DATA_INTRO_EVENT, IN_PROGRESS); - void EnterCombat(Unit* /*victim*/) override - { - _events.ScheduleEvent(EVENT_BALEFUL_STRIKE, 3000); + return true; } +}; - void JustDied(Unit* killer) override - { - DoCast(killer, SPELL_SPIRIT_BURST); - } +class at_hor_waves_restarter : public AreaTriggerScript +{ + public: + at_hor_waves_restarter() : AreaTriggerScript("at_hor_waves_restarter") { } - void UpdateAI(uint32 diff) override + bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) override { - if (!UpdateVictim()) - return; + if (player->IsGameMaster()) + return true; - _events.Update(diff); + InstanceScript* _instance = player->GetInstanceScript(); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (_instance->GetData(DATA_WAVE_COUNT)) + return true; - switch (_events.ExecuteEvent()) + if (_instance->GetData(DATA_INTRO_EVENT) == DONE && _instance->GetBossState(DATA_MARWYN) != DONE) { - case EVENT_BALEFUL_STRIKE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_BALEFUL_STRIKE); - _events.ScheduleEvent(EVENT_BALEFUL_STRIKE, urand(3000, 8000)); - } + _instance->ProcessEvent(0, EVENT_SPAWN_WAVES); - DoMeleeAttackIfReady(); + if (Creature* falric = player->GetCreature(*player, _instance->GetData64(DATA_FALRIC))) + { + falric->CastSpell(falric, SPELL_BOSS_SPAWN_AURA, true); + falric->SetVisible(true); + } + if (Creature* marwyn = player->GetCreature(*player, _instance->GetData64(DATA_MARWYN))) + { + marwyn->CastSpell(marwyn, SPELL_BOSS_SPAWN_AURA, true); + marwyn->SetVisible(true); + } + } + return true; } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_spiritual_reflectionAI(creature); - } }; -class at_hor_intro_start : public AreaTriggerScript +// 5740 +class at_hor_impenetrable_door : public AreaTriggerScript { -public: - at_hor_intro_start() : AreaTriggerScript("at_hor_intro_start") { } - - bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) override - { - InstanceScript* _instance = player->GetInstanceScript(); + public: + at_hor_impenetrable_door() : AreaTriggerScript("at_hor_impenetrable_door") { } - if (player->IsGameMaster()) - return true; + bool OnTrigger(Player* player, AreaTriggerEntry const* /*at*/) override + { + if (player->IsGameMaster()) + return true; - if (_instance->GetData(DATA_INTRO_EVENT) == NOT_STARTED) - _instance->SetData(DATA_INTRO_EVENT, IN_PROGRESS); + InstanceScript* _instance = player->GetInstanceScript(); + if (_instance->GetBossState(DATA_MARWYN) == DONE) + return true; - return true; - } + /// return false to handle teleport by db + return false; + } }; -class at_hor_waves_restarter : public AreaTriggerScript +// 5605 +class at_hor_shadow_throne : public AreaTriggerScript { -public: - at_hor_waves_restarter() : AreaTriggerScript("at_hor_waves_restarter") { } - - bool OnTrigger(Player* player, AreaTriggerEntry const* /*trigger*/) override - { - InstanceScript* _instance = player->GetInstanceScript(); + public: + at_hor_shadow_throne() : AreaTriggerScript("at_hor_shadow_throne") { } - if (player->IsGameMaster()) - return true; + bool OnTrigger(Player* player, AreaTriggerEntry const* /*at*/) override + { + if (player->IsGameMaster()) + return true; - if (_instance->GetData(DATA_WAVE_COUNT)) - return true; + InstanceScript* _instance = player->GetInstanceScript(); - if (_instance->GetData(DATA_INTRO_EVENT) == DONE && _instance->GetBossState(DATA_MARWYN_EVENT) != DONE) - { - _instance->ProcessEvent(0, EVENT_SPAWN_WAVES); + if (_instance->GetBossState(DATA_THE_LICH_KING_ESCAPE) == NOT_STARTED) + _instance->SetBossState(DATA_THE_LICH_KING_ESCAPE, IN_PROGRESS); - if (Creature* falric = player->GetCreature(*player, _instance->GetData64(DATA_FALRIC_EVENT))) - { - falric->CastSpell(falric, SPELL_BOSS_SPAWN_AURA, true); - falric->SetVisible(true); - } - if (Creature* marwyn = player->GetCreature(*player, _instance->GetData64(DATA_MARWYN_EVENT))) - { - marwyn->CastSpell(marwyn, SPELL_BOSS_SPAWN_AURA, true); - marwyn->SetVisible(true); - } + return true; } - return true; - } }; -class at_shadow_throne : public AreaTriggerScript +enum EscapeEvents { -public: - at_shadow_throne() : AreaTriggerScript("at_shadow_throne") { } - - bool OnTrigger(Player* player, const AreaTriggerEntry* /*at*/) override - { - InstanceScript* _instance = player->GetInstanceScript(); - - if (player->IsGameMaster()) - return true; + // Raging Ghoul + EVENT_RAGING_GHOUL_JUMP = 1, - if (_instance->GetData(DATA_ESCAPE_EVENT) == NOT_STARTED) - _instance->SetData(DATA_ESCAPE_EVENT, IN_PROGRESS); + // Risen Witch Doctor + EVENT_RISEN_WITCH_DOCTOR_CURSE, + EVENT_RISEN_WITCH_DOCTOR_SHADOW_BOLT, + EVENT_RISEN_WITCH_DOCTOR_SHADOW_BOLT_VOLLEY, - return true; - } + // Lumbering Abomination + EVENT_LUMBERING_ABOMINATION_VOMIT_SPRAY, + EVENT_LUMBERING_ABOMINATION_CLEAVE }; -class npc_raging_ghoul : public CreatureScript +class StartMovementEvent : public BasicEvent { -public: - npc_raging_ghoul() : CreatureScript("npc_raging_ghoul") { } + public: + StartMovementEvent(Creature* owner) : _owner(owner) { } - struct npc_raging_ghoulAI : public ScriptedAI - { - npc_raging_ghoulAI(Creature* creature) : ScriptedAI(creature) + bool Execute(uint64 /*execTime*/, uint32 /*diff*/) override { - _instance = me->GetInstanceScript(); + _owner->SetReactState(REACT_AGGRESSIVE); + if (Unit* target = _owner->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + _owner->AI()->AttackStart(target); + return true; } - InstanceScript* _instance; - uint32 _emergeTimer; - bool _doEmerge; - bool _doJump; - uint64 _leaderGUID; + private: + Creature* _owner; +}; - void Reset() override - { - _emergeTimer = 4000; - _doEmerge = false; - _doJump = false; - if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) - _instance->SetData(DATA_SUMMONS, 1); +struct npc_escape_event_trash : public ScriptedAI +{ + npc_escape_event_trash(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - } + void Reset() override + { + _events.Reset(); + } - void IsSummonedBy(Unit*) override - { - DoCast(me, SPELL_EMERGE_VISUAL); - } + void UpdateAI(uint32 /*diff*/) override + { + if (_instance->GetBossState(DATA_THE_LICH_KING_ESCAPE) == FAIL || _instance->GetBossState(DATA_THE_LICH_KING_ESCAPE) == NOT_STARTED) + me->DespawnOrUnsummon(); + } - void JustDied(Unit* /*killer*/) override + void IsSummonedBy(Unit* /*summoner*/) override + { + DoZoneInCombat(me, MAX_VISIBILITY_DISTANCE); + if (Creature* leader = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ESCAPE_LEADER))) { - _instance->SetData(DATA_SUMMONS, 0); + me->SetInCombatWith(leader); + leader->SetInCombatWith(me); + me->AddThreat(leader, 0.0f); } + } + +protected: + EventMap _events; + InstanceScript* _instance; +}; + +class npc_raging_ghoul : public CreatureScript +{ + public: + npc_raging_ghoul() : CreatureScript("npc_raging_ghoul") { } - void AttackStart(Unit* who) override + struct npc_raging_ghoulAI : public npc_escape_event_trash { - if (!who) - return; + npc_raging_ghoulAI(Creature* creature) : npc_escape_event_trash(creature) { } - if (!_doEmerge) - return; + void Reset() override + { + npc_escape_event_trash::Reset(); + _events.ScheduleEvent(EVENT_RAGING_GHOUL_JUMP, 5000); + } - ScriptedAI::AttackStart(who); - } + void IsSummonedBy(Unit* summoner) override + { + me->CastSpell(me, SPELL_RAGING_GHOUL_SPAWN, true); + me->SetReactState(REACT_PASSIVE); + me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); + me->m_Events.AddEvent(new StartMovementEvent(me), me->m_Events.CalculateTime(5000)); - void UpdateAI(uint32 diff) override - { - if (!_instance) - return; + npc_escape_event_trash::IsSummonedBy(summoner); + } - if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) + void UpdateAI(uint32 diff) override { - _leaderGUID = _instance->GetData64(DATA_ESCAPE_LEADER); - Creature* leader = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ESCAPE_LEADER)); + npc_escape_event_trash::UpdateAI(diff); + + if (!UpdateVictim()) + return; + + _events.Update(diff); - if (_doEmerge != true) + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (_events.ExecuteEvent()) { - if (_emergeTimer < diff) - { - _doEmerge = true; - if (leader) + case EVENT_RAGING_GHOUL_JUMP: + if (Unit* victim = me->GetVictim()) { - DoResetThreat(); - me->GetMotionMaster()->MoveIdle(); - me->GetMotionMaster()->MoveChase(leader); + if (me->IsInRange(victim, 5.0f, 30.0f)) + { + DoCast(victim, SPELL_GHOUL_JUMP); + return; + } } - } - else - _emergeTimer -= diff; + _events.ScheduleEvent(EVENT_RAGING_GHOUL_JUMP, 500); + break; + default: + break; } - if (me->Attack(leader,true))/*(Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150.0f))*/ - { - if (!_doJump && me->IsWithinDistInMap(leader, 30.0f) && !me->IsWithinDistInMap(leader, 5.0f)) - { - _doJump = true; - DoCast(leader, SPELL_GHOUL_JUMP); - } - } + DoMeleeAttackIfReady(); } - else if (_instance->GetData(DATA_ESCAPE_EVENT) == FAIL || _instance->GetData(DATA_ESCAPE_EVENT) == NOT_STARTED) - me->DespawnOrUnsummon(); - DoMeleeAttackIfReady(); - } - }; + }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI(creature); - } + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfReflectionAI(creature); + } }; class npc_risen_witch_doctor : public CreatureScript { -public: - npc_risen_witch_doctor() : CreatureScript("npc_risen_witch_doctor") { } + public: + npc_risen_witch_doctor() : CreatureScript("npc_risen_witch_doctor") { } - struct npc_risen_witch_doctorAI : public ScriptedAI - { - npc_risen_witch_doctorAI(Creature* creature) : ScriptedAI(creature) + struct npc_risen_witch_doctorAI : public npc_escape_event_trash { - _instance = me->GetInstanceScript(); - } + npc_risen_witch_doctorAI(Creature* creature) : npc_escape_event_trash(creature) { } - InstanceScript* _instance; - uint32 _emergeTimer; - bool _doEmerge; - uint64 _leaderGUID; - uint32 _boltTimer; - uint32 _boltVolleyTimer; - uint32 _curseTimer; + void Reset() override + { + npc_escape_event_trash::Reset(); + _events.ScheduleEvent(EVENT_RISEN_WITCH_DOCTOR_SHADOW_BOLT, 6000); + _events.ScheduleEvent(EVENT_RISEN_WITCH_DOCTOR_SHADOW_BOLT_VOLLEY, 15000); + _events.ScheduleEvent(EVENT_RISEN_WITCH_DOCTOR_CURSE, 7000); + } - void Reset() override - { - _emergeTimer = 5000; - _boltTimer = 6000; - _boltVolleyTimer = 15000; - _curseTimer = 7000; - _doEmerge = false; - if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) - _instance->SetData(DATA_SUMMONS, 1); - } + void IsSummonedBy(Unit* summoner) override + { + me->CastSpell(me, SPELL_RISEN_WITCH_DOCTOR_SPAWN, true); + me->SetReactState(REACT_PASSIVE); + me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); + me->m_Events.AddEvent(new StartMovementEvent(me), me->m_Events.CalculateTime(5000)); - void IsSummonedBy(Unit*) override - { - DoCast(me, SPELL_EMERGE_VISUAL); - DoZoneInCombat(me, 100.00f); - } + npc_escape_event_trash::IsSummonedBy(summoner); + } - void JustDied(Unit* /*killer*/) override - { - _instance->SetData(DATA_SUMMONS, 0); - } + void UpdateAI(uint32 diff) override + { + npc_escape_event_trash::UpdateAI(diff); - void AttackStart(Unit* who) override - { - if (!who) - return; + if (!UpdateVictim()) + return; - if (_doEmerge == false) - return; + _events.Update(diff); - ScriptedAI::AttackStart(who); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (_events.ExecuteEvent()) + { + case EVENT_RISEN_WITCH_DOCTOR_CURSE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true)) + DoCast(target, SPELL_CURSE_OF_DOOM); + _events.ScheduleEvent(EVENT_RISEN_WITCH_DOCTOR_CURSE, urand(10000, 15000)); + break; + case EVENT_RISEN_WITCH_DOCTOR_SHADOW_BOLT: + if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0, 20.0f, true)) + DoCast(target, SPELL_SHADOW_BOLT); + _events.ScheduleEvent(EVENT_RISEN_WITCH_DOCTOR_SHADOW_BOLT, urand(2000, 3000)); + break; + case EVENT_RISEN_WITCH_DOCTOR_SHADOW_BOLT_VOLLEY: + if (SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, true)) + DoCastAOE(SPELL_SHADOW_BOLT_VOLLEY); + _events.ScheduleEvent(EVENT_RISEN_WITCH_DOCTOR_SHADOW_BOLT_VOLLEY, urand(15000, 22000)); + break; + default: + break; + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfReflectionAI(creature); } +}; + +class npc_lumbering_abomination : public CreatureScript +{ + public: + npc_lumbering_abomination() : CreatureScript("npc_lumbering_abomination") { } - void UpdateAI(uint32 diff) override + struct npc_lumbering_abominationAI : public npc_escape_event_trash { - if (!_instance) - return; + npc_lumbering_abominationAI(Creature* creature) : npc_escape_event_trash(creature) { } - if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) + void Reset() override { - if (_doEmerge != true) - { - if (_emergeTimer < diff) - { - _doEmerge = true; - _leaderGUID = _instance->GetData64(DATA_ESCAPE_LEADER); + npc_escape_event_trash::Reset(); + _events.ScheduleEvent(EVENT_LUMBERING_ABOMINATION_VOMIT_SPRAY, 15000); + _events.ScheduleEvent(EVENT_LUMBERING_ABOMINATION_CLEAVE, 6000); + } - if (Creature* leader = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ESCAPE_LEADER))) - { - DoResetThreat(); - me->GetMotionMaster()->MoveIdle(); - me->GetMotionMaster()->MoveChase(leader); - } - } - else - _emergeTimer -= diff; - } + void UpdateAI(uint32 diff) override + { + npc_escape_event_trash::UpdateAI(diff); - if (_curseTimer < diff) - { - if (Unit *target = SelectTarget(SELECT_TARGET_RANDOM)) - DoCast(target, SPELL_COURSE_OF_DOOM); - _curseTimer = urand(10000, 15000); - } - else - _curseTimer -= diff; + if (!UpdateVictim()) + return; - if (_boltTimer < diff) - { - if (Unit *target = SelectTarget(SELECT_TARGET_TOPAGGRO)) - DoCast(target, SPELL_SHADOW_BOLT); - _boltTimer = urand(2000, 3000); - } - else - _boltTimer -= diff; + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - if (_boltVolleyTimer < diff) + switch (_events.ExecuteEvent()) { - if (Unit *target = SelectTarget(SELECT_TARGET_TOPAGGRO)) - DoCast(target, SPELL_SHADOW_BOLT_VOLLEY); - _boltVolleyTimer = urand(15000, 22000); + case EVENT_LUMBERING_ABOMINATION_VOMIT_SPRAY: + DoCastVictim(SPELL_VOMIT_SPRAY); + _events.ScheduleEvent(EVENT_LUMBERING_ABOMINATION_VOMIT_SPRAY, urand(15000, 20000)); + break; + case EVENT_LUMBERING_ABOMINATION_CLEAVE: + DoCastVictim(SPELL_CLEAVE); + _events.ScheduleEvent(EVENT_LUMBERING_ABOMINATION_CLEAVE, urand(7000, 9000)); + break; + default: + break; } - else - _boltVolleyTimer -= diff; + + DoMeleeAttackIfReady(); } - else if (_instance->GetData(DATA_ESCAPE_EVENT) == FAIL || _instance->GetData(DATA_ESCAPE_EVENT) == NOT_STARTED) - me->DespawnOrUnsummon(); - DoMeleeAttackIfReady(); - } - }; + }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI(creature); - } + CreatureAI* GetAI(Creature* creature) const override + { + return GetHallsOfReflectionAI(creature); + } }; - -class npc_lumbering_abomination : public CreatureScript +// 72900 - Start Halls of Reflection Quest AE +class spell_hor_start_halls_of_reflection_quest_ae : public SpellScriptLoader { -public: - npc_lumbering_abomination() : CreatureScript("npc_lumbering_abomination") { } + public: + spell_hor_start_halls_of_reflection_quest_ae() : SpellScriptLoader("spell_hor_start_halls_of_reflection_quest_ae") { } - struct npc_lumbering_abominationAI : public ScriptedAI - { - npc_lumbering_abominationAI(Creature* creature) : ScriptedAI(creature) + class spell_hor_start_halls_of_reflection_quest_ae_SpellScript : public SpellScript { - _instance = me->GetInstanceScript(); - } + PrepareSpellScript(spell_hor_start_halls_of_reflection_quest_ae_SpellScript); + + void StartQuests(SpellEffIndex /*effIndex*/) + { + if (Player* target = GetHitPlayer()) + { + // CanTakeQuest and CanAddQuest checks done in spell effect execution + if (target->GetTeam() == ALLIANCE) + target->CastSpell(target, SPELL_START_HALLS_OF_REFLECTION_QUEST_A, true); + else + target->CastSpell(target, SPELL_START_HALLS_OF_REFLECTION_QUEST_H, true); + } + } - InstanceScript* _instance; - uint64 _leaderGUID; - bool _doWalk; - uint32 _strikeTimer; - uint32 _vomitTimer; + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_hor_start_halls_of_reflection_quest_ae_SpellScript::StartQuests, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; - void Reset() override + SpellScript* GetSpellScript() const override { - _doWalk = false; - _vomitTimer = 15000; - _strikeTimer = 6000; - if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) - _instance->SetData(DATA_SUMMONS, 1); + return new spell_hor_start_halls_of_reflection_quest_ae_SpellScript(); } +}; + +// 70190 - Evasion +class spell_hor_evasion : public SpellScriptLoader +{ + public: + spell_hor_evasion() : SpellScriptLoader("spell_hor_evasion") { } + + class spell_hor_evasion_SpellScript : public SpellScript + { + PrepareSpellScript(spell_hor_evasion_SpellScript); + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } - void IsSummonedBy(Unit*) override + void SetDest(SpellDestination& dest) + { + WorldObject* target = GetExplTargetWorldObject(); + Position pos(*target); + Position home = GetCaster()->ToCreature()->GetHomePosition(); + + // prevent evasion outside the room + if (pos.IsInDist2d(&home, 15.0f)) + return; + + float angle = pos.GetAngle(&home); + float dist = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster()); + target->MovePosition(pos, dist, angle); + + dest.Relocate(pos); + } + + void Register() override + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_hor_evasion_SpellScript::SetDest, EFFECT_0, TARGET_DEST_TARGET_RADIUS); + } + }; + + SpellScript* GetSpellScript() const override { - DoCast(me, SPELL_EMERGE_VISUAL); - DoZoneInCombat(me, 100.00f); + return new spell_hor_evasion_SpellScript(); } +}; + +// 70017 - Gunship Cannon Fire +class spell_hor_gunship_cannon_fire : public SpellScriptLoader +{ + public: + spell_hor_gunship_cannon_fire() : SpellScriptLoader("spell_hor_gunship_cannon_fire") { } - void UpdateAI(uint32 diff) override + class spell_hor_gunship_cannon_fire_AuraScript : public AuraScript { - if (_instance->GetData(DATA_ESCAPE_EVENT) == IN_PROGRESS) + PrepareAuraScript(spell_hor_gunship_cannon_fire_AuraScript); + + void HandlePeriodic(AuraEffect const* /*aurEff*/) { - if (_doWalk != true) - { - _doWalk = true; - _leaderGUID = _instance->GetData64(DATA_ESCAPE_LEADER); - if (Creature* leader = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ESCAPE_LEADER))) - { - DoResetThreat(); - me->GetMotionMaster()->MoveIdle(); - me->GetMotionMaster()->MoveChase(leader); - } - } - if (_strikeTimer < diff) + if (!urand(0, 2)) { - if (Unit *target = SelectTarget(SELECT_TARGET_TOPAGGRO)) - DoCast(target, SPELL_ABON_STRIKE); - _strikeTimer = urand(7000, 9000); + if (GetTarget()->GetEntry() == NPC_GUNSHIP_CANNON_HORDE) + GetTarget()->CastSpell((Unit*)NULL, SPELL_GUNSHIP_CANNON_FIRE_MISSILE_HORDE, true); + else + GetTarget()->CastSpell((Unit*)NULL, SPELL_GUNSHIP_CANNON_FIRE_MISSILE_ALLIANCE, true); } - else - _strikeTimer -= diff; + } - if (_vomitTimer < diff) - { - if (Unit *target = SelectTarget(SELECT_TARGET_TOPAGGRO)) - DoCast(target, SPELL_VOMIT_SPRAY); - _vomitTimer = urand(15000, 20000); - } - else - _vomitTimer -= diff; + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_hor_gunship_cannon_fire_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); } - else if (_instance->GetData(DATA_ESCAPE_EVENT) == FAIL || _instance->GetData(DATA_ESCAPE_EVENT) == NOT_STARTED) - me->DespawnOrUnsummon(); - DoMeleeAttackIfReady(); - } + }; - void JustDied(Unit* /*killer*/) override + AuraScript* GetAuraScript() const override { - _instance->SetData(DATA_SUMMONS, 0); + return new spell_hor_gunship_cannon_fire_AuraScript(); } - - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI(creature); - } }; void AddSC_halls_of_reflection() { new at_hor_intro_start(); new at_hor_waves_restarter(); - new at_shadow_throne(); - new npc_jaina_or_sylvanas_hor(); + new at_hor_impenetrable_door(); + new at_hor_shadow_throne(); + new npc_jaina_or_sylvanas_intro_hor(); new npc_jaina_or_sylvanas_escape_hor(); + new npc_the_lich_king_escape_hor(); new npc_ghostly_priest(); new npc_phantom_mage(); new npc_phantom_hallucination(); new npc_shadowy_mercenary(); new npc_spectral_footman(); new npc_tortured_rifleman(); + new npc_frostsworn_general(); + new npc_spiritual_reflection(); new npc_raging_ghoul(); new npc_risen_witch_doctor(); new npc_lumbering_abomination(); - new npc_frostworn_general(); - new npc_spiritual_reflection(); + new spell_hor_start_halls_of_reflection_quest_ae(); + new spell_hor_evasion(); + new spell_hor_gunship_cannon_fire(); } diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h index c4776c3cfcd..e07751da337 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h @@ -15,170 +15,231 @@ * with this program. If not, see . */ -#ifndef DEF_HALLS_OF_REFLECTION_H -#define DEF_HALLS_OF_REFLECTION_H +#ifndef HALLS_OF_REFLECTION_H_ +#define HALLS_OF_REFLECTION_H_ #define HoRScriptName "instance_halls_of_reflection" -#define MAX_ENCOUNTER 3 + +uint32 const EncounterCount = 3; /* Halls of Reflection encounters: -0- Falric -1- Marwyn -2- The Lich King + 0 - Falric + 1 - Marwyn + 2 - The Lich King */ -enum Data +enum DataTypes { - DATA_FALRIC_EVENT = 0, - DATA_MARWYN_EVENT = 1, - DATA_LICHKING_EVENT = 2, + DATA_FALRIC = 0, + DATA_MARWYN = 1, + DATA_THE_LICH_KING_ESCAPE = 2, + DATA_INTRO_EVENT = 3, - DATA_FROSWORN_EVENT = 4, + DATA_FROSTSWORN_GENERAL = 4, - DATA_WAVE_COUNT = 5, - DATA_TEAM_IN_INSTANCE = 6, - DATA_FROSTMOURNE = 7, - DATA_FROSTWORN_DOOR = 8, - DATA_ESCAPE_EVENT = 9, + DATA_KORELN_LORALEN = 5, + DATA_WAVE_COUNT = 6, + DATA_TEAM_IN_INSTANCE = 7, + DATA_FROSTMOURNE = 8, + DATA_IMPENETRABLE_DOOR = 9, DATA_ESCAPE_LEADER = 10, - DATA_SUMMONS = 11, - DATA_ICEWALL = 12, - DATA_CAVE_IN = 13 + DATA_ICEWALL = 11, + DATA_ICEWALL_TARGET = 12, + DATA_GUNSHIP = 13 }; -enum Creatures +enum CreatureIds { - NPC_JAINA_PART1 = 37221, - NPC_SYLVANAS_PART1 = 37223, - NPC_UTHER = 37225, - NPC_LICH_KING_PART1 = 37226, - NPC_LORALEN = 37779, - NPC_KORELN = 37582, - - NPC_FALRIC = 38112, - NPC_MARWYN = 38113, - NPC_WAVE_MERCENARY = 38177, - NPC_WAVE_FOOTMAN = 38173, - NPC_WAVE_RIFLEMAN = 38176, - NPC_WAVE_PRIEST = 38175, - NPC_WAVE_MAGE = 38172, - - NPC_FROSTWORN_GENERAL = 36723, - NPC_REFLECTION = 37068, // 37107 for tank only? - - NPC_JAINA_PART2 = 36955, - NPC_SYLVANAS_PART2 = 37554, - NPC_LICH_KING_PART2 = 36954, - NPC_BARTLETT = 37182, // High Captain Justin Bartlett - NPC_KORM = 37833, // Sky-Reaver Korm Blackscar - NPC_ICE_WALL = 37014, // Ice Wall Target - - NPC_RAGING_GNOUL = 36940, - NPC_RISEN_WITCH_DOCTOR = 36941, - NPC_ABON = 37069 + NPC_JAINA_INTRO = 37221, + NPC_SYLVANAS_INTRO = 37223, + NPC_UTHER = 37225, + NPC_THE_LICH_KING_INTRO = 37226, + NPC_KORELN = 37582, + NPC_LORALEN = 37779, + NPC_FROSTMOUNRE_ALTAR_BUNNY = 37704, + + NPC_FALRIC = 38112, + NPC_MARWYN = 38113, + NPC_WAVE_MERCENARY = 38177, + NPC_WAVE_FOOTMAN = 38173, + NPC_WAVE_RIFLEMAN = 38176, + NPC_WAVE_PRIEST = 38175, + NPC_WAVE_MAGE = 38172, + + NPC_FROSTSWORN_GENERAL = 36723, + NPC_REFLECTION = 37068, // 37107 for tank only? + + NPC_JAINA_ESCAPE = 36955, + NPC_SYLVANAS_ESCAPE = 37554, + NPC_THE_LICH_KING_ESCAPE = 36954, + NPC_ICE_WALL_TARGET = 37014, + + NPC_RAGING_GHOUL = 36940, + NPC_RISEN_WITCH_DOCTOR = 36941, + NPC_LUMBERING_ABOMINATION = 37069, + + NPC_GUNSHIP_CANNON_HORDE = 37593, + NPC_JUSTIN_BARTLETT = 30344, + NPC_KORM_BLACKSCAR = 30824, + + NPC_WORLD_TRIGGER = 22515 }; -enum GameObjects +enum GameObjectIds { - GO_FROSTMOURNE = 202302, - GO_ENTRANCE_DOOR = 201976, - GO_FROSTWORN_DOOR = 197341, - GO_ARTHAS_DOOR = 197342, - //GO_ESCAPE_DOOR = 197343, // always open ? - - GO_ICE_WALL = 201385, - GO_CAVE = 201596, - - GO_STAIRS_SKYBREAKER = 201709, - GO_SKYBREAKER = 201598, - GO_STAIRS_ORGRIM_HAMMER = 202211, - GO_ORGRIM_HAMMER = 201599, - GO_PORTAL = 202079, - - GO_CAPTAIN_CHEST_HORDE_NORMAL = 202212, //3145 - GO_CAPTAIN_CHEST_ALLIANCE_NORMAL = 201710, //30357 - GO_CAPTAIN_CHEST_HORDE_HEROIC = 202337, //3246 - GO_CAPTAIN_CHEST_ALLIANCE_HEROIC = 202336, //3333 + GO_FROSTMOURNE = 202302, + GO_ENTRANCE_DOOR = 201976, + GO_IMPENETRABLE_DOOR = 197341, + GO_SHADOW_THRONE_DOOR = 197342, + GO_ESCAPE_DOOR = 197343, // always open ? + + GO_ICE_WALL = 201385, + GO_CAVE_IN = 201596, + + GO_THE_SKYBREAKER = 201598, + GO_ORGRIMS_HAMMER = 201599, + GO_THE_SKYBREAKER_STAIRS = 201709, + GO_ORGRIMS_HAMMER_STAIRS = 202211, + GO_PORTAL_TO_DALARAN = 195682, + + GO_THE_CAPTAIN_CHEST_ALLIANCE_NORMAL = 201710, + GO_THE_CAPTAIN_CHEST_HORDE_NORMAL = 202212, + GO_THE_CAPTAIN_CHEST_ALLIANCE_HEROIC = 202336, + GO_THE_CAPTAIN_CHEST_HORDE_HEROIC = 202337 }; -enum HorWorldStates +enum Achievements { - WORLD_STATE_HOR_WAVES_ENABLED = 4884, - WORLD_STATE_HOR_WAVE_COUNT = 4882, + ACHIEV_NOT_RETREATING_EVENT = 22615, + SPELL_ACHIEV_CHECK = 72830 }; // Common actions from Instance Script to Boss Script enum Actions { - ACTION_ENTER_COMBAT, - ACTION_START_ESCAPING, - ACTION_WALL_BROKEN + ACTION_ENTER_COMBAT = -668001, + ACTION_START_PREFIGHT = -668002, + ACTION_WALL_BROKEN = -668003, + ACTION_GUNSHIP_ARRIVAL = -668004, + ACTION_GUNSHIP_ARRIVAL_2 = -668005 }; -enum TrashGeneralSpells +enum InstanceEvents { - // General spells - SPELL_WELL_OF_SOULS = 72630, // cast when spawn(become visible) - SPELL_SPIRIT_ACTIVATE = 72130, // cast when unit activates + EVENT_SPAWN_WAVES = 1, + EVENT_NEXT_WAVE = 2, + EVENT_DO_WIPE = 3, + EVENT_ADD_WAVE = 4, + EVENT_SPAWN_ESCAPE_EVENT = 5 }; -enum InstanceEvents +enum InstanceEventIds { - EVENT_SPAWN_WAVES = 1, - EVENT_NEXT_WAVE = 2, - EVENT_DO_WIPE = 3, - EVENT_ADD_WAVE = 4, + EVENT_GUNSHIP_ARRIVAL = 22709, + EVENT_GUNSHIP_ARRIVAL_2 = 22714, + EVENT_ICE_WALL_SUMMONED = 22795 }; -// Base class for FALRIC and MARWYN -// handled the summonList and the notification events to/from the InstanceScript -struct boss_horAI : ScriptedAI +enum InstanceSpells { - boss_horAI(Creature* creature) : ScriptedAI(creature), summons(creature) - { - instance = me->GetInstanceScript(); - } + // Trash + SPELL_WELL_OF_SOULS = 72630, // cast when spawn (become visible) + SPELL_SPIRIT_ACTIVATE = 72130, // cast when unit activates + + // Start Quests + SPELL_START_HALLS_OF_REFLECTION_QUEST_A = 71351, + SPELL_START_HALLS_OF_REFLECTION_QUEST_H = 71542, + SPELL_START_HALLS_OF_REFLECTION_QUEST_AE = 72900, + + // Quest Credits + SPELL_CREDIT_FINDING_SYLVANAS = 71536, + SPELL_CREDIT_FINDING_JAINA = 71538, + SPELL_CREDIT_ESCAPING_ARTHAS = 71352, + + // Gunship + SPELL_GUNSHIP_CANNON_FIRE = 70017, + SPELL_GUNSHIP_CANNON_FIRE_MISSILE_ALLIANCE = 70021, + SPELL_GUNSHIP_CANNON_FIRE_MISSILE_HORDE = 70246 +}; - InstanceScript* instance; - EventMap events; - SummonList summons; +enum InstanceWorldStates +{ + WORLD_STATE_HOR_WAVES_ENABLED = 4884, + WORLD_STATE_HOR_WAVE_COUNT = 4882 +}; + +enum InstanceYells +{ + SAY_CAPTAIN_FIRE = 0, + SAY_CAPTAIN_FINAL = 1 +}; + +// Base class for FALRIC and MARWYN +struct boss_horAI : BossAI +{ + boss_horAI(Creature* creature, uint32 bossId) : BossAI(creature, bossId) { } - void Reset() + void Reset() override { - events.Reset(); + _Reset(); me->SetVisible(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); me->SetReactState(REACT_PASSIVE); if (instance->GetData(DATA_WAVE_COUNT) != NOT_STARTED) - instance->ProcessEvent(0, EVENT_DO_WIPE); + instance->ProcessEvent(NULL, EVENT_DO_WIPE); } - void DoAction(int32 actionID) + void DoAction(int32 actionId) override { - switch (actionID) + switch (actionId) { - case ACTION_ENTER_COMBAT: // called by InstanceScript when boss shall enter in combat. + case ACTION_ENTER_COMBAT: // called by InstanceScript when boss shall enter in combat. me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); me->SetReactState(REACT_AGGRESSIVE); - - if (Unit* unit = me->SelectNearestTarget()) - AttackStart(unit); - - DoZoneInCombat(); + DoZoneInCombat(me, MAX_VISIBILITY_DISTANCE); + break; + default: break; } } - void JustSummoned(Creature* summoned) + void JustSummoned(Creature* summon) override { - summons.Summon(summoned); + summons.Summon(summon); } }; +class GameObjectDeleteDelayEvent : public BasicEvent +{ + public: + GameObjectDeleteDelayEvent(Unit* owner, uint64 gameObjectGUID) : _owner(owner), _gameObjectGUID(gameObjectGUID) { } + + void DeleteGameObject() + { + if (GameObject* go = ObjectAccessor::GetGameObject(*_owner, _gameObjectGUID)) + go->Delete(); + } + + bool Execute(uint64 /*execTime*/, uint32 /*diff*/) override + { + DeleteGameObject(); + return true; + } + + void Abort(uint64 /*execTime*/) override + { + DeleteGameObject(); + } + + private: + Unit* _owner; + uint64 _gameObjectGUID; +}; + template AI* GetHallsOfReflectionAI(Creature* creature) { return GetInstanceAI(creature, HoRScriptName); } -#endif +#endif // HALLS_OF_REFLECTION_H_ diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp index ab5168dd34a..6f33e80b92b 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp @@ -19,590 +19,792 @@ #include "ScriptedCreature.h" #include "InstanceScript.h" #include "Player.h" +#include "Transport.h" #include "WorldPacket.h" #include "halls_of_reflection.h" -Position const JainaSpawnPos = {5236.659f, 1929.894f, 707.7781f, 0.8726646f}; // Jaina Spawn Position -Position const SylvanasSpawnPos = {5236.667f, 1929.906f, 707.7781f, 0.8377581f}; // Sylvanas Spawn Position -Position const GeneralSpawnPos = {5415.538f, 2117.842f, 707.7781f, 3.944444f}; // Frostsworn General -Position const JainaSpawnPos2 = {5549.011f, 2257.041f, 733.0120f, 1.153993f}; // Jaina Spawn Position 2 -Position const SylvanasSpawnPos2 = {5549.011f, 2257.041f, 733.0120f, 1.153993f}; // Sylvanas Spawn Position 2 +Position const JainaSpawnPos = { 5236.659f, 1929.894f, 707.7781f, 0.8726646f }; // Jaina Spawn Position +Position const SylvanasSpawnPos = { 5236.667f, 1929.906f, 707.7781f, 0.8377581f }; // Sylvanas Spawn Position (sniffed) +Position const JainaSpawnPos2 = { 5549.011f, 2257.041f, 733.0120f, 1.153993f }; // Jaina Spawn Position 2 +Position const SylvanasSpawnPos2 = { 5549.29f, 2257.353f, 733.0943f, 0.8901179f }; // Sylvanas Spawn Position 2 (sniffed) +Position const KorelnOrLoralenSpawnPos = { 5232.68f, 1931.46f, 707.7781f, 0.8377581f }; + +Position const TheLichKingEscapePosition[] = +{ + { 5557.017f, 2266.103f, 733.0943f, 3.892084f }, // 0 - Spawn (Horde) + { 5552.733f, 2262.718f, 733.0110f, 4.009696f } // 1 - Spawn (Alliance) +}; Position const SpawnPos[] = { - {5309.577f, 2042.668f, 707.7781f, 4.694936f}, - {5295.885f, 2040.342f, 707.7781f, 5.078908f}, - {5340.836f, 1992.458f, 707.7781f, 2.757620f}, - {5325.072f, 1977.597f, 707.7781f, 2.076942f}, - {5277.365f, 1993.229f, 707.7781f, 0.401426f}, - {5275.479f, 2001.135f, 707.7781f, 0.174533f}, - {5302.448f, 2042.222f, 707.7781f, 4.904375f}, - {5343.293f, 1999.384f, 707.7781f, 2.914700f}, - {5295.635f, 1973.757f, 707.7781f, 1.186824f}, - {5311.031f, 1972.229f, 707.7781f, 1.640610f}, - {5275.076f, 2008.724f, 707.7781f, 6.213372f}, - {5316.701f, 2041.550f, 707.7781f, 4.502949f}, - {5344.150f, 2007.168f, 707.7781f, 3.159046f}, - {5319.158f, 1973.998f, 707.7781f, 1.919862f}, - {5302.247f, 1972.415f, 707.7781f, 1.378810f}, - {5277.739f, 2016.882f, 707.7781f, 5.969026f}, - {5322.964f, 2040.288f, 707.7781f, 4.345870f}, - {5343.467f, 2015.951f, 707.7781f, 3.490659f}, - {5313.820f, 1978.146f, 707.7781f, 1.745329f}, - {5279.649f, 2004.656f, 707.7781f, 0.069814f}, - {5306.057f, 2037.002f, 707.7781f, 4.817109f}, - {5337.865f, 2003.403f, 707.7781f, 2.984513f}, - {5299.434f, 1979.009f, 707.7781f, 1.239184f}, - {5312.752f, 2037.122f, 707.7781f, 4.590216f}, - {5335.724f, 1996.859f, 707.7781f, 2.740167f}, - {5280.632f, 2012.156f, 707.7781f, 6.056293f}, - {5320.369f, 1980.125f, 707.7781f, 2.007129f}, - {5306.572f, 1977.474f, 707.7781f, 1.500983f}, - {5336.599f, 2017.278f, 707.7781f, 3.473205f}, - {5282.897f, 2019.597f, 707.7781f, 5.881760f}, - {5318.704f, 2036.108f, 707.7781f, 4.223697f}, - {5280.513f, 1997.842f, 707.7781f, 0.296706f}, - {5337.833f, 2010.057f, 707.7781f, 3.228859f}, - {5299.250f, 2035.998f, 707.7781f, 5.026548f}, + { 5309.577f, 2042.668f, 707.7781f, 4.694936f }, + { 5295.885f, 2040.342f, 707.7781f, 5.078908f }, + { 5340.836f, 1992.458f, 707.7781f, 2.757620f }, + { 5325.072f, 1977.597f, 707.7781f, 2.076942f }, + { 5277.365f, 1993.229f, 707.7781f, 0.401426f }, + { 5275.479f, 2001.135f, 707.7781f, 0.174533f }, + { 5302.448f, 2042.222f, 707.7781f, 4.904375f }, + { 5343.293f, 1999.384f, 707.7781f, 2.914700f }, + { 5295.635f, 1973.757f, 707.7781f, 1.186824f }, + { 5311.031f, 1972.229f, 707.7781f, 1.640610f }, + { 5275.076f, 2008.724f, 707.7781f, 6.213372f }, + { 5316.701f, 2041.550f, 707.7781f, 4.502949f }, + { 5344.150f, 2007.168f, 707.7781f, 3.159046f }, + { 5319.158f, 1973.998f, 707.7781f, 1.919862f }, + { 5302.247f, 1972.415f, 707.7781f, 1.378810f }, + { 5277.739f, 2016.882f, 707.7781f, 5.969026f }, + { 5322.964f, 2040.288f, 707.7781f, 4.345870f }, + { 5343.467f, 2015.951f, 707.7781f, 3.490659f }, + { 5313.820f, 1978.146f, 707.7781f, 1.745329f }, + { 5279.649f, 2004.656f, 707.7781f, 0.069814f }, + { 5306.057f, 2037.002f, 707.7781f, 4.817109f }, + { 5337.865f, 2003.403f, 707.7781f, 2.984513f }, + { 5299.434f, 1979.009f, 707.7781f, 1.239184f }, + { 5312.752f, 2037.122f, 707.7781f, 4.590216f }, + { 5335.724f, 1996.859f, 707.7781f, 2.740167f }, + { 5280.632f, 2012.156f, 707.7781f, 6.056293f }, + { 5320.369f, 1980.125f, 707.7781f, 2.007129f }, + { 5306.572f, 1977.474f, 707.7781f, 1.500983f }, + { 5336.599f, 2017.278f, 707.7781f, 3.473205f }, + { 5282.897f, 2019.597f, 707.7781f, 5.881760f }, + { 5318.704f, 2036.108f, 707.7781f, 4.223697f }, + { 5280.513f, 1997.842f, 707.7781f, 0.296706f }, + { 5337.833f, 2010.057f, 707.7781f, 3.228859f }, + { 5299.250f, 2035.998f, 707.7781f, 5.026548f } }; class instance_halls_of_reflection : public InstanceMapScript { -public: - instance_halls_of_reflection() : InstanceMapScript("instance_halls_of_reflection", 668) { } - - struct instance_halls_of_reflection_InstanceMapScript : public InstanceScript - { - instance_halls_of_reflection_InstanceMapScript(Map* map) : InstanceScript(map) { } + public: + instance_halls_of_reflection() : InstanceMapScript(HoRScriptName, 668) { } - void Initialize() override + struct instance_halls_of_reflection_InstanceMapScript : public InstanceScript { - SetBossNumber(MAX_ENCOUNTER); - events.Reset(); - - _falricGUID = 0; - _marwynGUID = 0; - _jainaOrSylvanasPart1GUID = 0; - _jainaOrSylvanasPart2GUID = 0; - _lichkingPart1GUID = 0; - _frostwornGeneralGUID = 0; - - _frostmourneGUID = 0; - _entranceDoorGUID = 0; - _frostwornDoorGUID = 0; - _arthasDoorGUID = 0; - _escapeDoorGUID = 0; - _caveGUID = 0; - - _teamInInstance = 0; - _waveCount = 0; - _introEvent = NOT_STARTED; - _frostwornGeneral = NOT_STARTED; - _escapeevent = NOT_STARTED; - _mobsaticewall = 0; - } + instance_halls_of_reflection_InstanceMapScript(Map* map) : InstanceScript(map) + { + SetBossNumber(EncounterCount); + + JainaOrSylvanasIntroGUID = 0; + KorelnOrLoralenGUID = 0; + TheLichkingIntroGUID = 0; + FalricGUID = 0; + MarwynGUID = 0; + FrostmourneAltarBunnyGUID = 0; + FrostswornGeneralGUID = 0; + JainaOrSylvanasEscapeGUID = 0; + TheLichKingEscapeGUID = 0; + + FrostmourneGUID = 0; + EntranceDoorGUID = 0; + ImpenetrableDoorGUID = 0; + ShadowThroneDoorGUID = 0; + CaveInGUID = 0; + GunshipGUID = 0; + CaptainsChestGUID = 0; + CaptainGUID = 0; + IcewallGUID = 0; + IcewallTargetGUID = 0; + + _teamInInstance = 0; + _waveCount = 0; + _introState = NOT_STARTED; + _frostswornGeneralState = NOT_STARTED; + + events.Reset(); + } - void OnPlayerEnter(Player* player) override - { - if (!_teamInInstance) - _teamInInstance = player->GetTeam(); - } + void OnPlayerEnter(Player* player) override + { + if (!_teamInInstance) + _teamInInstance = player->GetTeam(); - void OnCreatureCreate(Creature* creature) override - { - if (!_teamInInstance) + if (GetBossState(DATA_MARWYN) == DONE) + { + SpawnGunship(); + + if (!JainaOrSylvanasEscapeGUID && GetBossState(DATA_THE_LICH_KING_ESCAPE) != DONE) + SpawnEscapeEvent(); + } + } + + void OnCreatureCreate(Creature* creature) override { - Map::PlayerList const& players = instance->GetPlayers(); - if (!players.isEmpty()) - if (Player* player = players.begin()->GetSource()) - _teamInInstance = player->GetTeam(); + switch (creature->GetEntry()) + { + case NPC_JAINA_INTRO: + case NPC_SYLVANAS_INTRO: + JainaOrSylvanasIntroGUID = creature->GetGUID(); + break; + case NPC_KORELN: + case NPC_LORALEN: + if (GetBossState(DATA_MARWYN) != DONE) + creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + KorelnOrLoralenGUID = creature->GetGUID(); + break; + case NPC_THE_LICH_KING_INTRO: + TheLichkingIntroGUID = creature->GetGUID(); + break; + case NPC_FALRIC: + FalricGUID = creature->GetGUID(); + break; + case NPC_MARWYN: + MarwynGUID = creature->GetGUID(); + break; + case NPC_FROSTMOUNRE_ALTAR_BUNNY: + FrostmourneAltarBunnyGUID = creature->GetGUID(); + break; + case NPC_FROSTSWORN_GENERAL: + FrostswornGeneralGUID = creature->GetGUID(); + if (GetBossState(DATA_MARWYN) == DONE) + creature->SetPhaseMask(1, true); + break; + case NPC_JAINA_ESCAPE: + case NPC_SYLVANAS_ESCAPE: + JainaOrSylvanasEscapeGUID = creature->GetGUID(); + break; + case NPC_THE_LICH_KING_ESCAPE: + TheLichKingEscapeGUID = creature->GetGUID(); + break; + case NPC_JUSTIN_BARTLETT: + case NPC_KORM_BLACKSCAR: + CaptainGUID = creature->GetGUID(); + break; + case NPC_WORLD_TRIGGER: + if (!creature->GetTransport()) + break; + // no break + case NPC_GUNSHIP_CANNON_HORDE: + GunshipCannonGUIDs.insert(creature->GetGUID()); + break; + case NPC_ICE_WALL_TARGET: + IcewallTargetGUID = creature->GetGUID(); + break; + default: + break; + } } - switch (creature->GetEntry()) + void OnCreatureRemove(Creature* creature) override { - case NPC_JAINA_PART1: - case NPC_SYLVANAS_PART1: - _jainaOrSylvanasPart1GUID = creature->GetGUID(); - break; - case NPC_FALRIC: - _falricGUID = creature->GetGUID(); - break; - case NPC_MARWYN: - _marwynGUID = creature->GetGUID(); - break; - case NPC_FROSTWORN_GENERAL: - _frostwornGeneralGUID = creature->GetGUID(); - if (GetBossState(DATA_MARWYN_EVENT) == DONE) - if (Creature* general = instance->GetCreature(_frostwornGeneralGUID)) - general->SetPhaseMask(1, true); - break; - case NPC_JAINA_PART2: - case NPC_SYLVANAS_PART2: - _jainaOrSylvanasPart2GUID = creature->GetGUID(); - break; + switch (creature->GetEntry()) + { + case NPC_WAVE_MERCENARY: + case NPC_WAVE_FOOTMAN: + case NPC_WAVE_RIFLEMAN: + case NPC_WAVE_PRIEST: + case NPC_WAVE_MAGE: + { + uint32 internalWaveId = creature->AI()->GetData(0); + waveGuidList[internalWaveId].erase(creature->GetGUID()); + break; + } + case NPC_ICE_WALL_TARGET: + IcewallTargetGUID = 0; + break; + case NPC_WORLD_TRIGGER: + case NPC_GUNSHIP_CANNON_HORDE: + GunshipCannonGUIDs.erase(creature->GetGUID()); + break; + default: + break; + } } - } - void OnCreatureRemove(Creature* creature) override - { - switch (creature->GetEntry()) + uint32 GetGameObjectEntry(uint32 /*guidLow*/, uint32 entry) override { - case NPC_WAVE_MERCENARY: - case NPC_WAVE_FOOTMAN: - case NPC_WAVE_RIFLEMAN: - case NPC_WAVE_PRIEST: - case NPC_WAVE_MAGE: + if (!_teamInInstance) + { + Map::PlayerList const& players = instance->GetPlayers(); + if (!players.isEmpty()) + if (Player* player = players.begin()->GetSource()) + _teamInInstance = player->GetTeam(); + } + + switch (entry) { - uint32 internalWaveId = creature->AI()->GetData(0); - waveGuidList[internalWaveId].erase(creature->GetGUID()); - break; + case GO_THE_CAPTAIN_CHEST_ALLIANCE_NORMAL: + case GO_THE_CAPTAIN_CHEST_ALLIANCE_HEROIC: + case GO_THE_SKYBREAKER_STAIRS: + if (_teamInInstance == HORDE) + return 0; + break; + case GO_THE_CAPTAIN_CHEST_HORDE_NORMAL: + case GO_THE_CAPTAIN_CHEST_HORDE_HEROIC: + case GO_ORGRIMS_HAMMER_STAIRS: + if (_teamInInstance == ALLIANCE) + return 0; + break; + default: + break; } + + return entry; } - } - void OnGameObjectCreate(GameObject* go) override - { - switch (go->GetEntry()) + void OnGameObjectCreate(GameObject* go) override { - case GO_FROSTMOURNE: - _frostmourneGUID = go->GetGUID(); - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); - HandleGameObject(0, false, go); - if (GetData(DATA_INTRO_EVENT) == DONE) - go->SetPhaseMask(2, true); - break; - case GO_ENTRANCE_DOOR: - _entranceDoorGUID = go->GetGUID(); - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); - HandleGameObject(0, true, go); - break; - case GO_FROSTWORN_DOOR: - _frostwornDoorGUID = go->GetGUID(); - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); - if (GetBossState(DATA_MARWYN_EVENT) == DONE) - HandleGameObject(0, true, go); - else - HandleGameObject(0, false, go); - break; - case GO_ARTHAS_DOOR: - _arthasDoorGUID = go->GetGUID(); - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); - if (GetData(DATA_FROSWORN_EVENT) == DONE) - HandleGameObject(0, true, go); - else + switch (go->GetEntry()) + { + case GO_FROSTMOURNE: + FrostmourneGUID = go->GetGUID(); + if (GetData(DATA_INTRO_EVENT) == DONE) + go->SetPhaseMask(2, true); + break; + case GO_ENTRANCE_DOOR: + EntranceDoorGUID = go->GetGUID(); + break; + case GO_IMPENETRABLE_DOOR: + ImpenetrableDoorGUID = go->GetGUID(); + HandleGameObject(0, GetBossState(DATA_MARWYN) == DONE, go); + break; + case GO_SHADOW_THRONE_DOOR: + ShadowThroneDoorGUID = go->GetGUID(); + HandleGameObject(0, GetData(DATA_FROSTSWORN_GENERAL) == DONE, go); + break; + case GO_CAVE_IN: + CaveInGUID = go->GetGUID(); + break; + case GO_THE_SKYBREAKER: + case GO_ORGRIMS_HAMMER: + GunshipGUID = go->GetGUID(); + break; + case GO_THE_SKYBREAKER_STAIRS: + case GO_ORGRIMS_HAMMER_STAIRS: + if (GetBossState(DATA_THE_LICH_KING_ESCAPE) == DONE) + go->SetRespawnTime(DAY); + GunshipStairGUIDs.insert(go->GetGUID()); + break; + case GO_THE_CAPTAIN_CHEST_ALLIANCE_NORMAL: + case GO_THE_CAPTAIN_CHEST_HORDE_NORMAL: + case GO_THE_CAPTAIN_CHEST_ALLIANCE_HEROIC: + case GO_THE_CAPTAIN_CHEST_HORDE_HEROIC: + CaptainsChestGUID = go->GetGUID(); + break; + case GO_ICE_WALL: HandleGameObject(0, false, go); - break; - case GO_CAVE: - _caveGUID = go->GetGUID(); - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); - break; + IcewallGUID = go->GetGUID(); + break; + default: + break; + } } - } - void FillInitialWorldStates(WorldPacket& data) override - { - data << uint32(WORLD_STATE_HOR_WAVES_ENABLED) << uint32(0); - data << uint32(WORLD_STATE_HOR_WAVE_COUNT) << uint32(0); - } - - bool SetBossState(uint32 type, EncounterState state) override - { - if (!InstanceScript::SetBossState(type, state)) - return false; - - switch (type) + void OnGameObjectRemove(GameObject* go) override { - case DATA_FALRIC_EVENT: - if (state == DONE) - { - ++_waveCount; - events.ScheduleEvent(EVENT_NEXT_WAVE, 60000); - } - break; - case DATA_MARWYN_EVENT: - if (state == DONE) - { - HandleGameObject(_entranceDoorGUID, true); - HandleGameObject(_frostwornDoorGUID, true); - DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 0); - if (Creature* general = instance->GetCreature(_frostwornGeneralGUID)) - general->SetPhaseMask(1, true); - } - break; - case DATA_LICHKING_EVENT: - default: - break; + switch (go->GetEntry()) + { + case GO_THE_SKYBREAKER_STAIRS: + case GO_ORGRIMS_HAMMER_STAIRS: + GunshipStairGUIDs.erase(go->GetGUID()); + break; + default: + break; + } } - return true; - } + void FillInitialWorldStates(WorldPacket& data) override + { + data << uint32(WORLD_STATE_HOR_WAVES_ENABLED) << uint32(_introState == DONE && GetBossState(DATA_MARWYN) != DONE); + data << uint32(WORLD_STATE_HOR_WAVE_COUNT) << uint32(_waveCount); + } - void SetData(uint32 type, uint32 data) override - { - switch (type) + bool SetBossState(uint32 type, EncounterState state) override { - case DATA_INTRO_EVENT: - if (data == IN_PROGRESS) - { - if (!_introEvent) + if (!InstanceScript::SetBossState(type, state)) + return false; + + switch (type) + { + case DATA_FALRIC: + if (state == DONE) { - if (_teamInInstance == ALLIANCE) - instance->SummonCreature(NPC_JAINA_PART1, JainaSpawnPos); - else - instance->SummonCreature(NPC_SYLVANAS_PART1, SylvanasSpawnPos); + ++_waveCount; + events.ScheduleEvent(EVENT_NEXT_WAVE, 60000); } - } - _introEvent = data; - break; - case DATA_WAVE_COUNT: - if (_waveCount && data == NOT_STARTED) - ProcessEvent(NULL, EVENT_DO_WIPE); - break; - case DATA_FROSWORN_EVENT: - if (data == DONE) - { - HandleGameObject(_arthasDoorGUID, true); - if (_teamInInstance == ALLIANCE) - instance->SummonCreature(NPC_JAINA_PART2, JainaSpawnPos2); - else - instance->SummonCreature(NPC_SYLVANAS_PART2, SylvanasSpawnPos2); - } - _frostwornGeneral = data; - break; - case DATA_ESCAPE_EVENT: - if (data == IN_PROGRESS) - { - if (!_escapeevent) - if (Creature* jaina_or_sylvanas = instance->GetCreature(_jainaOrSylvanasPart2GUID)) - jaina_or_sylvanas->AI()->DoAction(ACTION_START_ESCAPING); - } - else if (data == NOT_STARTED) - { - if (Creature* jaina_or_sylvanas = instance->GetCreature(_jainaOrSylvanasPart2GUID)) - jaina_or_sylvanas->DespawnOrUnsummon(1); - if (_teamInInstance == ALLIANCE) - instance->SummonCreature(NPC_JAINA_PART2, JainaSpawnPos2); - else - instance->SummonCreature(NPC_SYLVANAS_PART2, SylvanasSpawnPos2); - SetData(DATA_ESCAPE_EVENT,IN_PROGRESS); - } - _escapeevent = data; - break; - case DATA_SUMMONS: - if (data == 0) - { - _mobsaticewall--; - if (_mobsaticewall == 0) + break; + case DATA_MARWYN: + if (state == DONE) { - if (Creature* jaina_or_sylvanas = instance->GetCreature(_jainaOrSylvanasPart2GUID)) - jaina_or_sylvanas->AI()->DoAction(ACTION_WALL_BROKEN); + if (Creature* bunny = instance->GetCreature(FrostmourneAltarBunnyGUID)) + bunny->CastSpell(bunny, SPELL_START_HALLS_OF_REFLECTION_QUEST_AE, true); + + if (Creature* korelnOrLoralen = instance->GetCreature(KorelnOrLoralenGUID)) + korelnOrLoralen->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER); + + HandleGameObject(EntranceDoorGUID, true); + HandleGameObject(ImpenetrableDoorGUID, true); + DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 0); + if (Creature* general = instance->GetCreature(FrostswornGeneralGUID)) + general->SetPhaseMask(1, true); + + SpawnGunship(); + SpawnEscapeEvent(); } - } - else if (data == 1) - _mobsaticewall++; - break; + break; + case DATA_THE_LICH_KING_ESCAPE: + switch (state) + { + case NOT_STARTED: + break; + case IN_PROGRESS: + if (Creature* jainaOrSylvanas = instance->GetCreature(JainaOrSylvanasEscapeGUID)) + jainaOrSylvanas->AI()->DoAction(ACTION_START_PREFIGHT); + break; + case DONE: + if (GameObject* chest = instance->GetGameObject(CaptainsChestGUID)) + chest->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN); + + DoUseDoorOrButton(CaveInGUID, 15); + + if (Creature* lichking = instance->GetCreature(TheLichKingEscapeGUID)) + { + lichking->CastSpell((Unit*)NULL, SPELL_ACHIEV_CHECK, true); + lichking->DespawnOrUnsummon(1); + } + break; + case FAIL: + DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_NOT_RETREATING_EVENT); + + if (Creature* jainaOrSylvanas = instance->GetCreature(JainaOrSylvanasEscapeGUID)) + jainaOrSylvanas->DespawnOrUnsummon(10000); + + if (Creature* icewallTarget = instance->GetCreature(IcewallTargetGUID)) + icewallTarget->DespawnOrUnsummon(); + + if (GameObject* icewall = instance->GetGameObject(IcewallGUID)) + icewall->Delete(); + + events.ScheduleEvent(EVENT_SPAWN_ESCAPE_EVENT, 30000); + break; + default: + break; + } + break; + default: + break; + } + + return true; } - SaveToDB(); - } + void SpawnGunship() + { + // don't spawn gunship twice + if (GunshipGUID) + return; + if (!_teamInInstance) + { + Map::PlayerList const& players = instance->GetPlayers(); + if (!players.isEmpty()) + if (Player* player = players.begin()->GetSource()) + _teamInInstance = player->GetTeam(); + } - // wave scheduling,checked when wave npcs die - void OnUnitDeath(Unit* unit) override - { - Creature* creature = unit->ToCreature(); - if (!creature) - return; + if (Transport* gunship = sTransportMgr->CreateTransport(_teamInInstance == HORDE ? GO_ORGRIMS_HAMMER : GO_THE_SKYBREAKER, 0, instance)) + gunship->EnableMovement(GetBossState(DATA_THE_LICH_KING_ESCAPE) == DONE); + } - switch (creature->GetEntry()) + void SpawnEscapeEvent() { - case NPC_WAVE_MERCENARY: - case NPC_WAVE_FOOTMAN: - case NPC_WAVE_RIFLEMAN: - case NPC_WAVE_PRIEST: - case NPC_WAVE_MAGE: + if (!_teamInInstance) { - uint32 deadNpcs = 0; - uint32 waveId = creature->AI()->GetData(0); - for (std::set::const_iterator itr = waveGuidList[waveId].begin(); itr != waveGuidList[waveId].end(); ++itr) - { - Creature* npc = instance->GetCreature(*itr); - if (!npc || !npc->IsAlive()) - ++deadNpcs; - } - // because the current npc returns IsAlive when OnUnitDeath happens - // we check if the number of dead npcs is equal to the list-1 - if (deadNpcs == waveGuidList[waveId].size() - 1) + Map::PlayerList const& players = instance->GetPlayers(); + if (!players.isEmpty()) + if (Player* player = players.begin()->GetSource()) + _teamInInstance = player->GetTeam(); + } + + if (_teamInInstance == ALLIANCE) + { + instance->SummonCreature(NPC_JAINA_ESCAPE, JainaSpawnPos2); + instance->SummonCreature(NPC_THE_LICH_KING_ESCAPE, TheLichKingEscapePosition[1]); + } + else + { + instance->SummonCreature(NPC_SYLVANAS_ESCAPE, SylvanasSpawnPos2); + instance->SummonCreature(NPC_THE_LICH_KING_ESCAPE, TheLichKingEscapePosition[0]); + } + } + + void SetData(uint32 type, uint32 data) override + { + switch (type) + { + case DATA_INTRO_EVENT: + if (data == IN_PROGRESS) + { + if (_introState == NOT_STARTED) + { + if (_teamInInstance == ALLIANCE) + { + instance->SummonCreature(NPC_JAINA_INTRO, JainaSpawnPos); + instance->SummonCreature(NPC_KORELN, KorelnOrLoralenSpawnPos); + } + else + { + instance->SummonCreature(NPC_SYLVANAS_INTRO, SylvanasSpawnPos); + instance->SummonCreature(NPC_LORALEN, KorelnOrLoralenSpawnPos); + } + } + } + _introState = data; + break; + case DATA_WAVE_COUNT: + if (_waveCount && data == NOT_STARTED) + ProcessEvent(NULL, EVENT_DO_WIPE); + break; + case DATA_FROSTSWORN_GENERAL: + if (data == DONE) + HandleGameObject(ShadowThroneDoorGUID, true); + _frostswornGeneralState = data; + break; + default: + break; + } + + SaveToDB(); + } + + // wave scheduling, checked when wave npcs die + void OnUnitDeath(Unit* unit) override + { + Creature* creature = unit->ToCreature(); + if (!creature) + return; + + switch (creature->GetEntry()) + { + case NPC_WAVE_MERCENARY: + case NPC_WAVE_FOOTMAN: + case NPC_WAVE_RIFLEMAN: + case NPC_WAVE_PRIEST: + case NPC_WAVE_MAGE: { + uint32 waveId = creature->AI()->GetData(0); + for (uint64 guid : waveGuidList[waveId]) + { + if (Creature* npc = instance->GetCreature(guid)) + if (npc->IsAlive()) + return; + } + ++_waveCount; events.ScheduleEvent(EVENT_NEXT_WAVE, 3000); + break; } - break; } } - } - void Update(uint32 diff) override - { - if (!instance->HavePlayers()) - return; + void Update(uint32 diff) override + { + if (!instance->HavePlayers()) + return; - events.Update(diff); + events.Update(diff); - switch (events.ExecuteEvent()) - { - case EVENT_NEXT_WAVE: - ProcessEvent(NULL, EVENT_ADD_WAVE); - break; + switch (events.ExecuteEvent()) + { + case EVENT_NEXT_WAVE: + ProcessEvent(NULL, EVENT_ADD_WAVE); + break; + case EVENT_SPAWN_ESCAPE_EVENT: + SpawnEscapeEvent(); + break; + } } - } - void ProcessEvent(WorldObject* /*go*/, uint32 eventId) override - { - switch (eventId) + void ProcessEvent(WorldObject* /*obj*/, uint32 eventId) override { - // spawning all wave npcs at once - case EVENT_SPAWN_WAVES: - _waveCount = 1; - DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 1); - DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, _waveCount); - { - std::list possibilityList, tempList; - uint32 posIndex = 0; + switch (eventId) + { + // spawning all wave npcs at once + case EVENT_SPAWN_WAVES: + _waveCount = 1; + DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 1); + DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, _waveCount); + { + std::list possibilityList, tempList; + uint32 posIndex = 0; - possibilityList.push_back(NPC_WAVE_MERCENARY); - possibilityList.push_back(NPC_WAVE_FOOTMAN); - possibilityList.push_back(NPC_WAVE_RIFLEMAN); - possibilityList.push_back(NPC_WAVE_PRIEST); - possibilityList.push_back(NPC_WAVE_MAGE); + possibilityList.push_back(NPC_WAVE_MERCENARY); + possibilityList.push_back(NPC_WAVE_FOOTMAN); + possibilityList.push_back(NPC_WAVE_RIFLEMAN); + possibilityList.push_back(NPC_WAVE_PRIEST); + possibilityList.push_back(NPC_WAVE_MAGE); - // iterate each wave - for (uint8 i = 0; i < 8; ++i) - { - tempList = possibilityList; + // iterate each wave + for (uint8 i = 0; i < 8; ++i) + { + tempList = possibilityList; - uint64 bossGuid = i <= 3 ? _falricGUID : _marwynGUID; + uint64 bossGuid = i <= 3 ? FalricGUID : MarwynGUID; - if (!i) - Trinity::Containers::RandomResizeList(tempList, 3); - else if (i < 6 && i != 3) - Trinity::Containers::RandomResizeList(tempList, 4); + if (!i) + Trinity::Containers::RandomResizeList(tempList, 3); + else if (i < 6 && i != 3) + Trinity::Containers::RandomResizeList(tempList, 4); - for (std::list::const_iterator itr = tempList.begin(); itr != tempList.end(); ++itr) - { - if (Creature* boss = instance->GetCreature(bossGuid)) + for (uint32 entry : tempList) { - if (Creature* temp = boss->SummonCreature(*itr, SpawnPos[posIndex], TEMPSUMMON_DEAD_DESPAWN)) + if (Creature* boss = instance->GetCreature(bossGuid)) { - temp->AI()->SetData(0, i); - waveGuidList[i].insert(temp->GetGUID()); + if (Creature* temp = boss->SummonCreature(entry, SpawnPos[posIndex], TEMPSUMMON_DEAD_DESPAWN)) + { + temp->AI()->SetData(0, i); + waveGuidList[i].insert(temp->GetGUID()); + } } - } - ++posIndex; + ++posIndex; + } } } - } - events.ScheduleEvent(EVENT_NEXT_WAVE, 5000); - break; - case EVENT_ADD_WAVE: - DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 1); - DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, _waveCount); - HandleGameObject(_entranceDoorGUID, false); - - if (_waveCount % 5) - { - uint32 internalWaveId = _waveCount - ((_waveCount < 5) ? 1 : 2); - for (std::set::const_iterator itr = waveGuidList[internalWaveId].begin(); itr != waveGuidList[internalWaveId].end(); ++itr) + events.ScheduleEvent(EVENT_NEXT_WAVE, 5000); + break; + case EVENT_ADD_WAVE: + DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 1); + DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, _waveCount); + HandleGameObject(EntranceDoorGUID, false); + + if (_waveCount % 5) { - if (Creature* temp = instance->GetCreature(*itr)) + uint32 internalWaveId = _waveCount - ((_waveCount < 5) ? 1 : 2); + for (uint64 guid : waveGuidList[internalWaveId]) { - temp->CastSpell(temp, SPELL_SPIRIT_ACTIVATE, true); - temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC|UNIT_FLAG_NOT_SELECTABLE); - temp->AI()->DoZoneInCombat(temp, 100.00f); + if (Creature* temp = instance->GetCreature(guid)) + { + temp->CastSpell(temp, SPELL_SPIRIT_ACTIVATE, false); + temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NOT_SELECTABLE); + temp->AI()->DoZoneInCombat(temp, 100.00f); + } } } - } - else - { - uint32 bossIndex = (_waveCount / 5) - 1; - if (GetBossState(DATA_FALRIC_EVENT + bossIndex) != DONE) + else + { + uint32 bossIndex = (_waveCount / 5) - 1; + if (GetBossState(DATA_FALRIC + bossIndex) != DONE) + { + if (Creature* boss = instance->GetCreature(bossIndex ? MarwynGUID : FalricGUID)) + boss->AI()->DoAction(ACTION_ENTER_COMBAT); + } + else if (_waveCount != 10) + { + ++_waveCount; + events.ScheduleEvent(EVENT_NEXT_WAVE, 5000); + } + } + break; + case EVENT_DO_WIPE: + _waveCount = 0; + events.Reset(); + DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 1); + DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, _waveCount); + HandleGameObject(EntranceDoorGUID, true); + + if (Creature* falric = instance->GetCreature(FalricGUID)) + falric->SetVisible(false); + if (Creature* marwyn = instance->GetCreature(MarwynGUID)) + marwyn->SetVisible(false); + // despawn wave npcs + for (uint8 i = 0; i < 8; ++i) { - if (Creature* boss = instance->GetCreature(bossIndex ? _marwynGUID : _falricGUID)) - boss->AI()->DoAction(ACTION_ENTER_COMBAT); + for (uint64 guid : waveGuidList[i]) + if (Creature* creature = instance->GetCreature(guid)) + creature->DespawnOrUnsummon(1); + waveGuidList[i].clear(); } - else if (_waveCount != 10) + break; + // Gunship Outro + case EVENT_GUNSHIP_ARRIVAL: + if (GetBossState(DATA_THE_LICH_KING_ESCAPE) == DONE) + break; + + if (Transport* gunship = instance->GetTransport(GunshipGUID)) + gunship->EnableMovement(false); + + if (Creature* jainaOrSylvanas = instance->GetCreature(JainaOrSylvanasEscapeGUID)) + jainaOrSylvanas->AI()->DoAction(ACTION_GUNSHIP_ARRIVAL); + + if (Creature* captain = instance->GetCreature(CaptainGUID)) + captain->AI()->Talk(SAY_CAPTAIN_FIRE); + + for (uint64 guid : GunshipCannonGUIDs) { - ++_waveCount; - events.ScheduleEvent(EVENT_NEXT_WAVE, 5000); + uint32 entry = GUID_ENPART(guid); + if ((entry == NPC_WORLD_TRIGGER && _teamInInstance == ALLIANCE) || (entry == NPC_GUNSHIP_CANNON_HORDE && _teamInInstance == HORDE)) + if (Creature* cannon = instance->GetCreature(guid)) + cannon->CastSpell(cannon, SPELL_GUNSHIP_CANNON_FIRE, true); } - } - break; - case EVENT_DO_WIPE: - _waveCount = 0; - events.Reset(); - DoUpdateWorldState(WORLD_STATE_HOR_WAVES_ENABLED, 1); - DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, _waveCount); - HandleGameObject(_entranceDoorGUID, true); - - if (Creature* falric = instance->GetCreature(_falricGUID)) - falric->SetVisible(false); - if (Creature* marwyn = instance->GetCreature(_marwynGUID)) - marwyn->SetVisible(false); - //despawn wave npcs - for (uint8 i = 0; i < 8; ++i) - { - for (std::set::const_iterator itr = waveGuidList[i].begin(); itr != waveGuidList[i].end(); ++itr) - if (Creature* creature = instance->GetCreature(*itr)) - creature->DespawnOrUnsummon(1); - waveGuidList[i].clear(); - } - break; + break; + case EVENT_GUNSHIP_ARRIVAL_2: + if (Transport* gunship = instance->GetTransport(GunshipGUID)) + gunship->EnableMovement(false); + + for (uint64 guid : GunshipStairGUIDs) + if (GameObject* stairs = instance->GetGameObject(guid)) + stairs->SetRespawnTime(DAY); + + if (Creature* jainaOrSylvanas = instance->GetCreature(JainaOrSylvanasEscapeGUID)) + jainaOrSylvanas->AI()->DoAction(ACTION_GUNSHIP_ARRIVAL_2); + + if (Creature* captain = instance->GetCreature(CaptainGUID)) + captain->AI()->Talk(SAY_CAPTAIN_FINAL); + + break; + default: + break; + } } - } - uint32 GetData(uint32 type) const override - { - switch (type) + uint32 GetData(uint32 type) const override { - case DATA_WAVE_COUNT: - return _waveCount; - case DATA_TEAM_IN_INSTANCE: - return _teamInInstance; - case DATA_INTRO_EVENT: - return _introEvent; - case DATA_FROSWORN_EVENT: - return _frostwornGeneral; - case DATA_ESCAPE_EVENT: - return _escapeevent; - case DATA_SUMMONS: - return _mobsaticewall; - default: - break; - } + switch (type) + { + case DATA_WAVE_COUNT: + return _waveCount; + case DATA_TEAM_IN_INSTANCE: + return _teamInInstance; + case DATA_INTRO_EVENT: + return _introState; + case DATA_FROSTSWORN_GENERAL: + return _frostswornGeneralState; + default: + break; + } - return 0; - } + return 0; + } - uint64 GetData64(uint32 type) const override - { - switch (type) + uint64 GetData64(uint32 type) const override { - case DATA_FALRIC_EVENT: - return _falricGUID; - case DATA_MARWYN_EVENT: - return _marwynGUID; - case DATA_FROSWORN_EVENT: - return _frostwornGeneralGUID; - case DATA_FROSTWORN_DOOR: - return _frostwornDoorGUID; - case DATA_FROSTMOURNE: - return _frostmourneGUID; - case DATA_ESCAPE_LEADER: - return _jainaOrSylvanasPart2GUID; - case DATA_CAVE_IN: - return _caveGUID; - default: - break; - } + switch (type) + { + case DATA_FALRIC: + return FalricGUID; + case DATA_MARWYN: + return MarwynGUID; + case DATA_FROSTSWORN_GENERAL: + return FrostswornGeneralGUID; + case DATA_IMPENETRABLE_DOOR: + return ImpenetrableDoorGUID; + case DATA_FROSTMOURNE: + return FrostmourneGUID; + case DATA_ESCAPE_LEADER: + return JainaOrSylvanasEscapeGUID; + case DATA_KORELN_LORALEN: + return KorelnOrLoralenGUID; + case DATA_THE_LICH_KING_ESCAPE: + return TheLichKingEscapeGUID; + case DATA_GUNSHIP: + return GunshipGUID; + case DATA_ICEWALL: + return IcewallGUID; + case DATA_ICEWALL_TARGET: + return IcewallTargetGUID; + default: + break; + } - return 0; - } + return 0; + } - std::string GetSaveData() override - { - OUT_SAVE_INST_DATA; + std::string GetSaveData() override + { + OUT_SAVE_INST_DATA; - std::ostringstream saveStream; - saveStream << "H R " << GetBossSaveData() << _introEvent << ' ' << _frostwornGeneral << ' ' << _escapeevent; + std::ostringstream saveStream; + saveStream << "H R " << GetBossSaveData() << _introState << ' ' << _frostswornGeneralState; - OUT_SAVE_INST_DATA_COMPLETE; - return saveStream.str(); - } + OUT_SAVE_INST_DATA_COMPLETE; + return saveStream.str(); + } - void Load(char const* in) override - { - if (!in) + void Load(char const* in) override { - OUT_LOAD_INST_DATA_FAIL; - return; - } + if (!in) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } - OUT_LOAD_INST_DATA(in); + OUT_LOAD_INST_DATA(in); - char dataHead1, dataHead2; + char dataHead1, dataHead2; - std::istringstream loadStream(in); - loadStream >> dataHead1 >> dataHead2; + std::istringstream loadStream(in); + loadStream >> dataHead1 >> dataHead2; - if (dataHead1 == 'H' && dataHead2 == 'R') - { - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + if (dataHead1 == 'H' && dataHead2 == 'R') { - uint32 tmpState; - loadStream >> tmpState; - if (tmpState == IN_PROGRESS || tmpState > SPECIAL) - tmpState = NOT_STARTED; + for (uint8 i = 0; i < EncounterCount; ++i) + { + uint32 tmpState; + loadStream >> tmpState; + if (tmpState == IN_PROGRESS || tmpState > SPECIAL) + tmpState = NOT_STARTED; - SetBossState(i, EncounterState(tmpState)); - } + SetBossState(i, EncounterState(tmpState)); + } - uint32 temp = 0; - loadStream >> temp; - if (temp == DONE) - SetData(DATA_INTRO_EVENT, DONE); - else - SetData(DATA_INTRO_EVENT, NOT_STARTED); + uint32 temp = 0; + loadStream >> temp; + if (temp == DONE) + SetData(DATA_INTRO_EVENT, DONE); + else + SetData(DATA_INTRO_EVENT, NOT_STARTED); - loadStream >> temp; - if (temp == DONE) - SetData(DATA_FROSWORN_EVENT, DONE); + loadStream >> temp; + if (temp == DONE) + SetData(DATA_FROSTSWORN_GENERAL, DONE); + else + SetData(DATA_FROSTSWORN_GENERAL, NOT_STARTED); + } else - SetData(DATA_FROSWORN_EVENT, NOT_STARTED); + OUT_LOAD_INST_DATA_FAIL; - loadStream >> temp; - if (temp == DONE) - SetData(DATA_ESCAPE_EVENT, DONE); - else - SetData(DATA_ESCAPE_EVENT, NOT_STARTED); + OUT_LOAD_INST_DATA_COMPLETE; } - else - OUT_LOAD_INST_DATA_FAIL; - OUT_LOAD_INST_DATA_COMPLETE; + private: + uint64 JainaOrSylvanasIntroGUID; // unused + uint64 KorelnOrLoralenGUID; + uint64 TheLichkingIntroGUID; // unused + uint64 FalricGUID; + uint64 MarwynGUID; + uint64 FrostmourneAltarBunnyGUID; + uint64 FrostswornGeneralGUID; + uint64 JainaOrSylvanasEscapeGUID; + uint64 TheLichKingEscapeGUID; + + uint64 FrostmourneGUID; + uint64 EntranceDoorGUID; + uint64 ImpenetrableDoorGUID; + uint64 ShadowThroneDoorGUID; + uint64 CaveInGUID; + + uint32 _teamInInstance; + uint32 _waveCount; + uint32 _introState; + uint32 _frostswornGeneralState; + + EventMap events; + std::set waveGuidList[8]; + + uint64 GunshipGUID; + uint64 CaptainsChestGUID; + uint64 CaptainGUID; + uint64 IcewallGUID; + uint64 IcewallTargetGUID; + + std::set GunshipCannonGUIDs; + std::set GunshipStairGUIDs; + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const override + { + return new instance_halls_of_reflection_InstanceMapScript(map); } - - private: - uint64 _falricGUID; - uint64 _marwynGUID; - uint64 _jainaOrSylvanasPart1GUID; - uint64 _jainaOrSylvanasPart2GUID; - uint64 _lichkingPart1GUID; - uint64 _frostwornGeneralGUID; - - uint64 _frostmourneGUID; - uint64 _entranceDoorGUID; - uint64 _frostwornDoorGUID; - uint64 _arthasDoorGUID; - uint64 _escapeDoorGUID; - uint64 _caveGUID; - - uint32 _teamInInstance; - uint32 _waveCount; - uint32 _introEvent; - uint32 _frostwornGeneral; - uint32 _escapeevent; - uint32 _mobsaticewall; - - EventMap events; - - std::set waveGuidList[8]; - }; - - InstanceScript* GetInstanceScript(InstanceMap* map) const override - { - return new instance_halls_of_reflection_InstanceMapScript(map); - } }; void AddSC_instance_halls_of_reflection() -- cgit v1.2.3 From 392e045bda32a8901526b05ab216ba15920e8aec Mon Sep 17 00:00:00 2001 From: Kinzcool Date: Sun, 11 May 2014 03:15:31 -0400 Subject: DB: Changed WDBVerified startdard to VerifiedBuild --- sql/updates/world/2014_05_11_01_world_misc.sql | 39 ++++++++++++++++++++++++++ src/server/game/Globals/ObjectMgr.cpp | 4 +-- src/server/game/Globals/ObjectMgr.h | 2 +- src/server/game/Quests/QuestDef.cpp | 2 +- 4 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 sql/updates/world/2014_05_11_01_world_misc.sql (limited to 'src') diff --git a/sql/updates/world/2014_05_11_01_world_misc.sql b/sql/updates/world/2014_05_11_01_world_misc.sql new file mode 100644 index 00000000000..8f8dfc4567b --- /dev/null +++ b/sql/updates/world/2014_05_11_01_world_misc.sql @@ -0,0 +1,39 @@ +ALTER TABLE `broadcast_text` CHANGE COLUMN `WDBVerified` `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `creature_equip_template` CHANGE COLUMN `WDBVerified` `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `creature_template` CHANGE COLUMN `WDBVerified` `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `gameobject_template` CHANGE COLUMN `WDBVerified` `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `item_set_names` CHANGE COLUMN `WDBVerified` `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `item_template` CHANGE COLUMN `WDBVerified` `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `npc_text` CHANGE COLUMN `WDBVerified` `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `page_text` CHANGE COLUMN `WDBVerified` `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `quest_template` CHANGE COLUMN `WDBVerified` `VerifiedBuild` SMALLINT(5) DEFAULT '0'; + +ALTER TABLE `areatrigger_teleport` ADD `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `creature` ADD `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `lfg_entrances` ADD `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `locales_broadcast_text` ADD `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `locales_creature` ADD `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `locales_gameobject` ADD `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `locales_item` ADD `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `locales_item_set_names` ADD `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `locales_quest` ADD `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `npc_vendor` ADD `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `quest_poi_points` ADD `VerifiedBuild` SMALLINT(5) DEFAULT '0'; +ALTER TABLE `quest_poi` ADD `VerifiedBuild` SMALLINT(5) DEFAULT '0'; + +UPDATE `locales_broadcast_text` SET `VerifiedBuild`=18019; +UPDATE `locales_creature` SET `VerifiedBuild`=18019; +UPDATE `locales_gameobject` SET `VerifiedBuild`=18019; +UPDATE `locales_item` SET `VerifiedBuild`=15050; +UPDATE `locales_item_set_names` SET `VerifiedBuild`=15050; +UPDATE `locales_quest` SET `VerifiedBuild`=18019; + +UPDATE `creature_template` SET `VerifiedBuild`=0 WHERE `VerifiedBuild`=1; +UPDATE `gameobject_template` SET `VerifiedBuild`=0 WHERE `VerifiedBuild`=1; +UPDATE `item_set_names` SET `VerifiedBuild`=0 WHERE `VerifiedBuild`=1; +UPDATE `item_template` SET `VerifiedBuild`=0 WHERE `VerifiedBuild`=1; +UPDATE `npc_text` SET `VerifiedBuild`=0 WHERE `VerifiedBuild`=1; +UPDATE `page_text` SET `VerifiedBuild`=0 WHERE `VerifiedBuild`=1; +UPDATE `item_template` SET `VerifiedBuild`=0 WHERE `VerifiedBuild`=1; + +UPDATE `locales_item` SET `VerifiedBuild`=-12340 WHERE `entry` IN (1019, 5022, 5084, 5085, 5096, 5512, 5530, 5544, 5798, 6712, 6949, 6950, 6951, 7675, 8925, 8926, 8927, 8928, 8984, 8985, 9250, 9315, 9577, 10920, 10921, 10922, 10958, 11163, 11168, 11223, 11367, 11368, 12368, 12708, 13466, 16051, 16209, 16262, 16263, 16306, 16310, 16972, 17414, 17683, 17771, 18224, 18256, 18562, 18947, 19004, 19005, 20310, 20844, 21214, 21279, 21280, 21281, 21282, 21283, 21284, 21285, 21287, 21288, 21289, 21290, 21291, 21292, 21293, 21294, 21295, 21296, 21297, 21298, 21299, 21300, 21302, 21303, 21304, 21306, 21307, 21927, 22053, 22054, 22055, 22146, 22153, 22530, 22540, 22549, 22550, 22890, 22891, 22897, 23094, 23096, 23099, 23100, 23105, 23106, 23108, 23109, 23113, 23114, 23115, 23116, 23121, 23130, 23133, 23136, 23137, 23142, 23143, 23144, 23145, 23148, 23149, 23150, 23151, 23155, 23320, 23778, 23815, 23902, 24029, 24030, 24031, 24032, 24037, 24047, 24050, 24051, 24052, 24056, 24057, 24060, 24061, 24062, 24065, 24162, 24192, 24195, 24196, 24197, 24201, 24203, 24205, 24206, 24207, 24211, 24212, 24215, 24216, 24217, 24219, 27679, 27689, 27774, 27777, 27785, 27786, 27809, 27811, 27812, 27820, 28048, 28117, 28118, 28120, 28122, 28274, 28360, 28361, 28362, 28363, 28460, 28461, 28462, 28465, 28466, 28468, 28469, 28470, 28557, 28595, 28596, 2874, 2893, 2939, 29468, 29549, 29550, 29553, 30467, 30547, 30548, 30550, 30551, 30552, 30553, 30555, 30556, 30558, 30559, 30560, 30563, 30564, 30565, 30572, 30573, 30574, 30575, 30581, 30583, 30585, 30586, 30589, 30590, 30591, 30593, 30594, 30600, 30601, 30603, 30605, 30606, 31116, 31117, 31118, 31359, 31501, 31837, 31860, 31861, 31862, 31863, 31864, 31865, 31866, 31867, 31868, 31869, 31870, 31871, 31872, 31873, 31874, 31875, 31876, 31877, 31878, 31879, 32195, 32196, 32197, 32198, 32202, 32204, 32206, 32207, 32208, 32210, 32213, 32214, 32215, 32216, 32219, 32220, 32221, 32222, 32223, 32225, 32281, 32282, 32283, 32284, 32288, 32290, 32292, 32293, 32294, 32296, 32299, 32300, 32301, 32302, 32305, 32306, 32307, 32308, 32309, 32311, 3238, 32634, 32635, 32636, 32637, 32638, 32639, 32640, 32735, 33139, 33141, 3371, 3372, 33804, 34060, 34061, 34200, 34201, 34218, 3460, 35238, 35239, 35240, 35241, 35245, 35248, 35249, 35250, 35251, 35252, 35255, 35256, 35257, 35259, 35261, 35262, 35266, 35268, 35270, 35271, 35304, 35305, 35306, 35307, 35396, 35397, 35398, 35399, 35400, 35417, 35418, 35419, 35420, 35421, 35422, 35423, 35424, 35425, 35426, 35427, 35428, 35429, 35430, 35431, 35432, 35433, 35434, 35435, 35436, 35437, 35438, 35439, 35440, 35441, 35442, 35443, 35444, 35445, 35446, 35447, 35448, 35449, 35450, 35451, 35452, 35453, 35454, 35455, 35456, 35457, 35458, 35459, 35460, 35461, 35462, 35487, 35488, 35489, 35500, 35707, 35708, 35756, 36766, 37347, 37602, 37603, 3776, 3819, 38545, 38546, 38547, 38549, 38679, 38682, 38766, 38767, 38768, 38769, 38770, 38771, 38772, 38773, 38774, 38775, 38776, 38777, 38778, 38779, 38780, 38781, 38782, 38783, 38784, 38785, 38786, 38787, 38788, 38789, 38790, 38791, 38792, 38793, 38794, 38795, 38796, 38797, 38798, 38799, 38800, 38801, 38802, 38803, 38804, 38805, 38806, 38807, 38808, 38809, 38810, 38811, 38812, 38813, 38814, 38815, 38816, 38817, 38818, 38819, 38820, 38821, 38822, 38823, 38824, 38825, 38826, 38827, 38828, 38829, 38830, 38831, 38832, 38833, 38834, 38835, 38836, 38837, 38838, 38839, 38840, 38841, 38842, 38843, 38844, 38845, 38846, 38847, 38848, 38849, 38850, 38851, 38852, 38853, 38854, 38855, 38856, 38857, 38858, 38859, 38860, 38861, 38862, 38863, 38864, 38865, 38866, 38867, 38868, 38869, 38870, 38871, 38872, 38873, 38874, 38875, 38876, 38877, 38878, 38879, 38880, 38881, 38882, 38883, 38884, 38885, 38886, 38887, 38888, 38889, 38890, 38891, 38892, 38893, 38894, 38895, 38896, 38897, 38898, 38899, 38900, 38901, 38902, 38903, 38904, 38905, 38906, 38907, 38908, 38909, 38910, 38911, 38912, 38913, 38914, 38915, 38917, 38918, 38919, 38920, 38921, 38922, 38923, 38924, 38925, 38926, 38927, 38928, 38929, 38930, 38931, 38932, 38933, 38934, 38935, 38936, 38937, 38938, 38939, 38940, 38941, 38942, 38943, 38944, 38945, 38946, 38947, 38948, 38949, 38950, 38951, 38953, 38954, 38955, 38956, 38958, 38959, 38960, 38961, 38962, 38963, 38964, 38965, 38966, 38967, 38968, 38969, 38971, 38972, 38973, 38974, 38975, 38976, 38977, 38978, 38979, 38980, 38981, 38982, 38983, 38984, 38985, 38986, 38987, 38988, 38989, 38990, 38991, 38992, 38993, 38994, 38995, 38997, 38998, 38999, 39000, 39001, 39002, 39003, 39004, 39005, 39006, 39349, 39350, 39906, 39907, 39909, 39911, 39912, 39915, 39916, 39927, 39933, 39936, 39937, 39938, 39942, 39943, 39944, 39946, 39948, 39953, 39957, 39958, 39960, 39961, 39962, 39963, 39965, 39966, 39968, 39975, 39976, 39979, 39981, 39983, 39984, 39985, 39986, 39988, 39991, 39998, 39999, 40000, 40002, 40010, 40012, 40014, 40015, 40023, 40024, 40025, 40027, 40029, 40030, 40031, 40032, 40033, 40038, 40044, 40047, 40049, 40050, 40052, 40053, 40054, 40055, 40057, 40058, 40085, 40088, 40089, 40092, 40094, 40096, 40099, 40100, 40101, 40103, 40104, 40113, 40114, 40115, 40117, 40121, 40123, 40125, 40126, 40131, 40132, 40134, 40136, 40137, 40138, 40140, 40143, 40148, 40151, 40153, 40154, 40156, 40157, 40158, 40159, 40161, 40162, 40164, 40166, 40167, 40170, 40172, 40174, 40175, 40176, 40177, 40178, 40181, 40411, 40899, 40901, 40903, 40920, 41094, 41096, 41098, 41100, 41101, 41104, 41105, 41106, 41107, 41109, 41110, 41170, 41377, 41429, 41433, 41436, 41438, 41439, 41440, 41444, 41447, 41449, 41450, 41452, 41454, 41456, 41458, 41459, 41462, 41463, 41464, 41467, 41469, 41471, 41473, 41475, 41477, 41478, 41479, 41481, 41482, 41486, 41487, 41488, 41490, 41491, 41494, 41496, 41501, 41502, 41524, 41535, 41538, 41541, 41563, 41564, 41567, 41568, 41570, 41573, 41580, 41581, 41582, 41687, 41688, 41689, 41694, 41696, 41697, 41698, 41699, 41701, 41702, 41703, 41705, 41718, 41719, 41721, 41722, 41724, 41725, 41730, 41732, 41736, 41739, 41747, 41777, 41782, 41785, 41791, 41795, 41796, 41817, 41818, 41820, 42144, 42146, 42153, 42157, 42299, 42303, 42304, 42309, 42315, 42397, 42403, 42405, 42407, 42416, 42417, 42456, 42465, 42466, 42469, 42471, 42734, 42740, 42743, 42747, 42750, 42753, 42754, 42899, 42901, 42906, 42907, 42909, 42910, 42912, 42915, 42916, 42917, 42965, 42971, 43145, 43146, 43230, 43231, 43232, 43233, 43234, 43235, 43237, 43335, 43339, 43350, 43354, 43355, 43357, 43359, 43360, 43366, 43368, 43369, 43380, 43386, 43391, 43394, 43396, 43397, 43398, 43412, 43414, 43416, 43417, 43418, 43420, 43423, 43424, 43425, 43426, 43428, 43429, 43432, 43441, 43534, 43538, 43545, 43548, 43549, 43553, 4361, 4363, 43671, 43672, 43673, 43826, 43867, 43868, 43869, 43952, 43987, 44449, 44453, 44455, 44456, 44457, 44458, 44463, 44465, 44466, 44467, 44469, 44470, 44493, 44497, 44511, 44512, 44815, 44842, 44843, 44944, 44946, 44947, 45056, 45060, 45603, 45628, 45733, 45737, 45743, 45744, 45757, 45758, 45760, 45761, 45776, 45789, 45793, 45794, 45803, 45804, 45805, 45883, 46026, 46098, 46372, 46767, 46897, 46899, 46900, 46902, 46903, 46906, 46907, 46908, 46909, 46910, 46914, 46916, 46919, 46921, 46922, 46927, 46928, 46930, 46931, 46934, 46936, 46939, 46940, 46944, 46945, 46946, 46947, 46951, 46952, 46953, 46956, 47008, 47010, 47011, 47012, 47016, 47023, 47179, 48720, 49084, 50045, 50077, 50125, 50166, 50167, 50168, 50816, 52022, 52023); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 2905b0454c4..207f80eabe7 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -3822,8 +3822,8 @@ void ObjectMgr::LoadQuests() "RequiredItemId1, RequiredItemId2, RequiredItemId3, RequiredItemId4, RequiredItemId5, RequiredItemId6, RequiredItemCount1, RequiredItemCount2, RequiredItemCount3, RequiredItemCount4, RequiredItemCount5, RequiredItemCount6, " // 117 118 119 120 121 122 123 124 125 126 127 128 129 "Unknown0, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4, DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4, DetailsEmoteDelay1, DetailsEmoteDelay2, DetailsEmoteDelay3, DetailsEmoteDelay4, " - // 130 131 132 133 134 135 136 137 138 139 140 - "EmoteOnIncomplete, EmoteOnComplete, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4, OfferRewardEmoteDelay1, OfferRewardEmoteDelay2, OfferRewardEmoteDelay3, OfferRewardEmoteDelay4, WDBVerified" + // 130 131 132 133 134 135 136 137 138 139 + "EmoteOnIncomplete, EmoteOnComplete, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4, OfferRewardEmoteDelay1, OfferRewardEmoteDelay2, OfferRewardEmoteDelay3, OfferRewardEmoteDelay4" " FROM quest_template"); if (!result) { diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 48c9e618a1d..ba5940d7e12 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -432,7 +432,7 @@ struct BroadcastText uint32 SoundId; uint32 Unk1; uint32 Unk2; - // uint32 WDBVerified; + // uint32 VerifiedBuild; std::string const& GetText(LocaleConstant locale = DEFAULT_LOCALE, uint8 gender = GENDER_MALE, bool forceGender = false) const { diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index 9b3732d232b..099275ba8dc 100644 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -137,7 +137,7 @@ Quest::Quest(Field* questRecord) for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) OfferRewardEmoteDelay[i] = questRecord[136+i].GetInt32(); - //int32 WDBVerified = questRecord[140].GetInt32(); + //int32 VerifiedBuild = questRecord[140].GetInt32(); if (SpecialFlags & QUEST_SPECIAL_FLAGS_AUTO_ACCEPT) Flags |= QUEST_FLAGS_AUTO_ACCEPT; -- cgit v1.2.3 From dabbe38022fddce5778ea7d71915a65dbe9d4b8c Mon Sep 17 00:00:00 2001 From: Gacko Date: Sun, 11 May 2014 12:35:40 +0200 Subject: Core/GameObject: Set trap type 0 back to GO_READY after activation. Otherwise it would be activated again on every update. My fault, moving the activation code to GO_ACTIVATED skips the cooldown check. Closes #12047 --- src/server/game/Entities/GameObject/GameObject.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 8051c757bf2..5efe5a75335 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -568,10 +568,12 @@ void GameObject::Update(uint32 diff) CastSpell(target, goInfo->trap.spellId); // Template value or 4 seconds - m_cooldownTime = time(NULL) + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)); + m_cooldownTime = time(NULL) + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)); if (goInfo->trap.type == 1) SetLootState(GO_JUST_DEACTIVATED); + else if (!goInfo->trap.type) + SetLootState(GO_READY); // Battleground gameobjects have data2 == 0 && data5 == 3 if (!goInfo->trap.diameter && goInfo->trap.cooldown == 3) -- cgit v1.2.3 From b76bcad46e6086719bb1b8d09eddca76766a0860 Mon Sep 17 00:00:00 2001 From: Gacko Date: Sun, 11 May 2014 15:15:43 +0200 Subject: Script/ICC: Use existing method for getting GO auto-close-time --- src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index 25cc47b358c..592c44940a4 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -1800,7 +1800,7 @@ class spell_icc_sprit_alarm : public SpellScriptLoader } if (GameObject* trap = GetCaster()->FindNearestGameObject(trapId, 5.0f)) - trap->SetRespawnTime(trap->GetGOInfo()->trap.autoCloseTime); + trap->SetRespawnTime(trap->GetGOInfo()->GetAutoCloseTime()); std::list wards; GetCaster()->GetCreatureListWithEntryInGrid(wards, NPC_DEATHBOUND_WARD, 150.0f); -- cgit v1.2.3 From 11f6eb91c0f1343ccfea11c6dc7e8d346bb04ce1 Mon Sep 17 00:00:00 2001 From: Trisjdc Date: Sun, 11 May 2014 14:43:12 +0100 Subject: Core/Spells: Fix fishing on areas with liquid data but no valid height --- src/server/game/Spells/Spell.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 7c6f2552b44..b36d857881d 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1251,8 +1251,12 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici float angle = float(rand_norm()) * static_cast(M_PI * 35.0f / 180.0f) - static_cast(M_PI * 17.5f / 180.0f); m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dist, angle); - float ground = z; - float liquidLevel = m_caster->GetMap()->GetWaterOrGroundLevel(x, y, z, &ground); + float ground = m_caster->GetMap()->GetHeight(m_caster->GetPhaseMask(), x, y, z, true, 50.0f); + float liquidLevel = VMAP_INVALID_HEIGHT_VALUE; + LiquidData liquidData; + if (m_caster->GetMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquidData)) + liquidLevel = liquidData.level; + if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level { SendCastResult(SPELL_FAILED_NOT_HERE); -- cgit v1.2.3 From de6eddaa353b26d84e3164abd47f789944b7bce2 Mon Sep 17 00:00:00 2001 From: joschiwald Date: Sun, 11 May 2014 18:13:02 +0200 Subject: Scripts/HoR: fixed conflict between multiple classes with same name Closes #12051 --- .../FrozenHalls/HallsOfReflection/halls_of_reflection.cpp | 13 +++++++++---- .../FrozenHalls/HallsOfReflection/halls_of_reflection.h | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index a86dcc26907..7366ba32bdf 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -1606,7 +1606,7 @@ class npc_phantom_hallucination : public CreatureScript void Reset() override { - DoZoneInCombat(me, MAX_VISIBILITY_DISTANCE); + DoZoneInCombat(me, 150.0f); } void EnterEvadeMode() override @@ -2089,6 +2089,9 @@ enum EscapeEvents EVENT_LUMBERING_ABOMINATION_CLEAVE }; +namespace hor +{ + class StartMovementEvent : public BasicEvent { public: @@ -2106,6 +2109,8 @@ class StartMovementEvent : public BasicEvent Creature* _owner; }; +} // namespace hor + struct npc_escape_event_trash : public ScriptedAI { npc_escape_event_trash(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } @@ -2123,7 +2128,7 @@ struct npc_escape_event_trash : public ScriptedAI void IsSummonedBy(Unit* /*summoner*/) override { - DoZoneInCombat(me, MAX_VISIBILITY_DISTANCE); + DoZoneInCombat(me, 0.0f); if (Creature* leader = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ESCAPE_LEADER))) { me->SetInCombatWith(leader); @@ -2157,7 +2162,7 @@ class npc_raging_ghoul : public CreatureScript me->CastSpell(me, SPELL_RAGING_GHOUL_SPAWN, true); me->SetReactState(REACT_PASSIVE); me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); - me->m_Events.AddEvent(new StartMovementEvent(me), me->m_Events.CalculateTime(5000)); + me->m_Events.AddEvent(new hor::StartMovementEvent(me), me->m_Events.CalculateTime(5000)); npc_escape_event_trash::IsSummonedBy(summoner); } @@ -2223,7 +2228,7 @@ class npc_risen_witch_doctor : public CreatureScript me->CastSpell(me, SPELL_RISEN_WITCH_DOCTOR_SPAWN, true); me->SetReactState(REACT_PASSIVE); me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); - me->m_Events.AddEvent(new StartMovementEvent(me), me->m_Events.CalculateTime(5000)); + me->m_Events.AddEvent(new hor::StartMovementEvent(me), me->m_Events.CalculateTime(5000)); npc_escape_event_trash::IsSummonedBy(summoner); } diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h index e07751da337..a05035f7b44 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.h @@ -196,7 +196,7 @@ struct boss_horAI : BossAI case ACTION_ENTER_COMBAT: // called by InstanceScript when boss shall enter in combat. me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC); me->SetReactState(REACT_AGGRESSIVE); - DoZoneInCombat(me, MAX_VISIBILITY_DISTANCE); + DoZoneInCombat(me, 150.0f); break; default: break; -- cgit v1.2.3 From b17e3246fe769e6dc388612d5764150a184aef07 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Mon, 12 May 2014 21:18:59 +0200 Subject: Core/Misc: Fix static analysis issues Fix uninitialized values spotted by coverity. Remove unused "dynamic analysis" code, use Valgrind or another dynamic analysis tool instead if needed. --- src/server/game/Grids/GridStates.cpp | 12 ------------ src/server/game/Grids/GridStates.h | 7 ------- .../FrozenHalls/HallsOfReflection/halls_of_reflection.cpp | 2 ++ 3 files changed, 2 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/server/game/Grids/GridStates.cpp b/src/server/game/Grids/GridStates.cpp index 8b57c382cd7..3e085f1f381 100644 --- a/src/server/game/Grids/GridStates.cpp +++ b/src/server/game/Grids/GridStates.cpp @@ -20,18 +20,6 @@ #include "GridNotifiers.h" #include "Log.h" -#ifdef TRINITY_DEBUG -bool GridState::checkMagic() -{ - if (i_Magic != MAGIC_TESTVAL) - { - TC_LOG_ERROR("misc", "!!! GridState: Magic value gone !!!"); - return false; - } - return true; -} -#endif - void InvalidState::Update(Map&, NGridType&, GridInfo&, uint32) const { } diff --git a/src/server/game/Grids/GridStates.h b/src/server/game/Grids/GridStates.h index 016df4dc3d4..af11ab08d5e 100644 --- a/src/server/game/Grids/GridStates.h +++ b/src/server/game/Grids/GridStates.h @@ -27,13 +27,6 @@ class Map; class GridState { public: -#ifdef TRINITY_DEBUG -#define MAGIC_TESTVAL 0xFBE823BA - GridState() { i_Magic = MAGIC_TESTVAL; } - bool checkMagic(); - void setMagic() { i_Magic = MAGIC_TESTVAL; } - unsigned int i_Magic; -#endif virtual ~GridState() { }; virtual void Update(Map &, NGridType&, GridInfo &, uint32 t_diff) const = 0; }; diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index 7366ba32bdf..0c5514a1c0a 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -347,6 +347,8 @@ class npc_jaina_or_sylvanas_intro_hor : public CreatureScript npc_jaina_or_sylvanas_intro_horAI(Creature* creature) : ScriptedAI(creature) { _instance = me->GetInstanceScript(); + _utherGUID = 0; + _lichkingGUID = 0; } void sGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override -- cgit v1.2.3 From db2593f41d75fb9b832f240313522d50d95f4618 Mon Sep 17 00:00:00 2001 From: jackpoz Date: Mon, 12 May 2014 22:40:55 +0200 Subject: Core/Arena: Fix exploit in arena team Fix exploit that allowed anyone to add a target Player to any arena team. --- src/server/game/Handlers/ArenaTeamHandler.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/server/game/Handlers/ArenaTeamHandler.cpp b/src/server/game/Handlers/ArenaTeamHandler.cpp index 632bd02def0..3bb3edac500 100644 --- a/src/server/game/Handlers/ArenaTeamHandler.cpp +++ b/src/server/game/Handlers/ArenaTeamHandler.cpp @@ -121,6 +121,12 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket& recvData) return; } + if (GetPlayer()->GetArenaTeamId(arenaTeam->GetSlot()) != arenaTeamId) + { + SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS); + return; + } + // OK result but don't send invite if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) return; -- cgit v1.2.3