aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/authserver/CMakeLists.txt2
-rw-r--r--src/server/collision/BoundingIntervalHierarchy.cpp2
-rw-r--r--src/server/collision/Management/MMapFactory.cpp2
-rw-r--r--src/server/collision/Management/MMapManager.cpp10
-rw-r--r--src/server/collision/Maps/TileAssembler.cpp3
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp3
-rw-r--r--src/server/game/Battlegrounds/ArenaTeam.cpp38
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.cpp3
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAV.h2
-rw-r--r--src/server/game/Calendar/CalendarMgr.cpp14
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp12
-rw-r--r--src/server/game/DataStores/DBCStores.cpp14
-rw-r--r--src/server/game/DataStores/DBCStores.h3
-rw-r--r--src/server/game/Entities/Player/Player.cpp10
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp7
-rw-r--r--src/server/game/Entities/Vehicle/Vehicle.cpp11
-rw-r--r--src/server/game/Groups/Group.cpp144
-rw-r--r--src/server/game/Guilds/Guild.cpp4
-rw-r--r--src/server/game/Handlers/AuctionHouseHandler.cpp237
-rw-r--r--src/server/game/Handlers/CalendarHandler.cpp4
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp2
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp2
-rw-r--r--src/server/game/Handlers/TicketHandler.cpp1
-rw-r--r--src/server/game/Loot/LootMgr.cpp12
-rw-r--r--src/server/game/Maps/Map.cpp6
-rw-r--r--src/server/game/Maps/PhaseMgr.h5
-rw-r--r--src/server/game/Miscellaneous/Language.h8
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp22
-rw-r--r--src/server/game/Movement/PathGenerator.cpp2
-rw-r--r--src/server/game/Movement/Waypoints/Path.h4
-rw-r--r--src/server/game/Scripting/ScriptLoader.cpp2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp8
-rw-r--r--src/server/game/Spells/Spell.cpp5
-rw-r--r--src/server/game/Spells/SpellEffects.cpp2
-rw-r--r--src/server/game/Spells/SpellInfo.cpp2
-rw-r--r--src/server/game/Spells/SpellMgr.cpp11
-rw-r--r--src/server/game/World/World.cpp2
-rw-r--r--src/server/scripts/Commands/cs_account.cpp2
-rw-r--r--src/server/scripts/Commands/cs_character.cpp4
-rw-r--r--src/server/scripts/Commands/cs_deserter.cpp6
-rw-r--r--src/server/scripts/Commands/cs_list.cpp4
-rw-r--r--src/server/scripts/Commands/cs_lookup.cpp22
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp76
-rw-r--r--src/server/scripts/Commands/cs_mmaps.cpp12
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp24
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp2
-rw-r--r--src/server/scripts/Commands/cs_rbac.cpp42
-rw-r--r--src/server/scripts/Commands/cs_wp.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp78
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp2
-rw-r--r--src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp14
-rw-r--r--src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp10
-rw-r--r--src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp8
-rw-r--r--src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp4
-rw-r--r--src/server/scripts/Kalimdor/zone_winterspring.cpp12
-rw-r--r--src/server/scripts/Northrend/CMakeLists.txt2
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp3
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp11
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp4
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp170
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp3221
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp55
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp389
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h96
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp33
-rw-r--r--src/server/scripts/Northrend/zone_icecrown.cpp2
-rw-r--r--src/server/scripts/OutdoorPvP/OutdoorPvPHP.cpp2
-rw-r--r--src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp3
-rw-r--r--src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp11
-rw-r--r--src/server/scripts/Outland/TempestKeep/Mechanar/boss_gatewatcher_gyrokill.cpp6
-rw-r--r--src/server/scripts/Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp10
-rw-r--r--src/server/scripts/Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp10
-rw-r--r--src/server/scripts/Spells/spell_mage.cpp4
-rw-r--r--src/server/scripts/World/npcs_special.cpp2
-rw-r--r--src/server/shared/Cryptography/SHA1.cpp1
-rw-r--r--src/server/shared/Database/Field.cpp1
-rw-r--r--src/server/shared/Database/MySQLConnection.cpp2
-rw-r--r--src/server/shared/Database/PreparedStatement.cpp1
-rw-r--r--src/server/shared/Debugging/Errors.cpp12
-rw-r--r--src/server/shared/Debugging/Errors.h21
-rw-r--r--src/server/shared/Logging/Log.h6
-rw-r--r--src/server/shared/Packets/ByteBuffer.h2
-rw-r--r--src/server/shared/Threading/Callback.h2
-rw-r--r--src/server/worldserver/CMakeLists.txt1
-rw-r--r--src/server/worldserver/Main.cpp19
-rw-r--r--src/server/worldserver/TCSoap/TCSoap.h2
-rw-r--r--src/tools/mmaps_generator/Info/readme.txt5
87 files changed, 4305 insertions, 749 deletions
diff --git a/src/server/authserver/CMakeLists.txt b/src/server/authserver/CMakeLists.txt
index 57ab1ffa4ed..6d756434a20 100644
--- a/src/server/authserver/CMakeLists.txt
+++ b/src/server/authserver/CMakeLists.txt
@@ -80,6 +80,8 @@ target_link_libraries(authserver
shared
${MYSQL_LIBRARY}
${OPENSSL_LIBRARIES}
+ ${CMAKE_THREAD_LIBS_INIT}
+ ${ACE_LIBRARY}
)
if( WIN32 )
diff --git a/src/server/collision/BoundingIntervalHierarchy.cpp b/src/server/collision/BoundingIntervalHierarchy.cpp
index 340d66ddaf0..c5ae1f2a265 100644
--- a/src/server/collision/BoundingIntervalHierarchy.cpp
+++ b/src/server/collision/BoundingIntervalHierarchy.cpp
@@ -272,7 +272,7 @@ bool BIH::readFromFile(FILE* rf)
check += fread(&count, sizeof(uint32), 1, rf);
objects.resize(count); // = new uint32[nObjects];
check += fread(&objects[0], sizeof(uint32), count, rf);
- return check == (3 + 3 + 2 + treeSize + count);
+ return uint64(check) == uint64(3 + 3 + 1 + 1 + uint64(treeSize) + uint64(count));
}
void BIH::BuildStats::updateLeaf(int depth, int n)
diff --git a/src/server/collision/Management/MMapFactory.cpp b/src/server/collision/Management/MMapFactory.cpp
index 7adf7fbfa66..6aa71d77ed8 100644
--- a/src/server/collision/Management/MMapFactory.cpp
+++ b/src/server/collision/Management/MMapFactory.cpp
@@ -25,7 +25,7 @@ namespace MMAP
{
// ######################## MMapFactory ########################
// our global singleton copy
- MMapManager *g_MMapManager = NULL;
+ MMapManager* g_MMapManager = NULL;
MMapManager* MMapFactory::createOrGetMMapManager()
{
diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp
index 70ae878aa6b..a3f89f42443 100644
--- a/src/server/collision/Management/MMapManager.cpp
+++ b/src/server/collision/Management/MMapManager.cpp
@@ -109,7 +109,7 @@ namespace MMAP
snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i%02i%02i.mmtile").c_str(), mapId, x, y);
- FILE *file = fopen(fileName, "rb");
+ FILE* file = fopen(fileName, "rb");
if (!file)
{
TC_LOG_DEBUG(LOG_FILTER_MAPS, "MMAP:loadMap: Could not open mmtile file '%s'", fileName);
@@ -123,6 +123,7 @@ namespace MMAP
if (fread(&fileHeader, sizeof(MmapTileHeader), 1, file) != 1 || fileHeader.mmapMagic != MMAP_MAGIC)
{
TC_LOG_ERROR(LOG_FILTER_MAPS, "MMAP:loadMap: Bad header in mmap %03u%02i%02i.mmtile", mapId, x, y);
+ fclose(file);
return false;
}
@@ -130,6 +131,7 @@ namespace MMAP
{
TC_LOG_ERROR(LOG_FILTER_MAPS, "MMAP:loadMap: %03u%02i%02i.mmtile was built with generator v%i, expected v%i",
mapId, x, y, fileHeader.mmapVersion, MMAP_VERSION);
+ fclose(file);
return false;
}
@@ -154,7 +156,7 @@ namespace MMAP
{
mmap->mmapLoadedTiles.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef));
++loadedTiles;
- TC_LOG_INFO(LOG_FILTER_MAPS, "MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, x, y, mapId, header->x, header->y);
+ TC_LOG_INFO(LOG_FILTER_MAPS, "MMAP:loadMap: Loaded mmtile %03i[%02i, %02i] into %03i[%02i, %02i]", mapId, x, y, mapId, header->x, header->y);
return true;
}
else
@@ -203,7 +205,7 @@ namespace MMAP
{
mmap->mmapLoadedTiles.erase(packedGridPos);
--loadedTiles;
- TC_LOG_INFO(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId);
+ TC_LOG_INFO(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %03i", mapId, x, y, mapId);
return true;
}
@@ -230,7 +232,7 @@ namespace MMAP
else
{
--loadedTiles;
- TC_LOG_INFO(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId);
+ TC_LOG_INFO(LOG_FILTER_MAPS, "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %03i", mapId, x, y, mapId);
}
}
diff --git a/src/server/collision/Maps/TileAssembler.cpp b/src/server/collision/Maps/TileAssembler.cpp
index ba1ae275c9a..aca7c02e79f 100644
--- a/src/server/collision/Maps/TileAssembler.cpp
+++ b/src/server/collision/Maps/TileAssembler.cpp
@@ -516,7 +516,8 @@ namespace VMAP
for (uint32 g = 0; g < groups && succeed; ++g)
succeed = groupsArray[g].Read(rf);
- fclose(rf);
+ if (succeed) /// rf will be freed inside Read if the function had any errors.
+ fclose(rf);
return succeed;
}
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index b4053da2932..576d77a2e24 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -1470,8 +1470,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!einfo)
{
TC_LOG_ERROR(LOG_FILTER_SQL, "SmartScript: SMART_ACTION_EQUIP uses non-existent equipment info id %u for creature %u", equipId, npc->GetEntry());
+ delete targets;
return;
}
+
npc->SetCurrentEquipmentId(equipId);
slot[0] = einfo->ItemEntry[0];
slot[1] = einfo->ItemEntry[1];
@@ -2576,6 +2578,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
return;
ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->getVictim());
+ break;
}
case SMART_EVENT_FRIENDLY_HEALTH:
{
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp
index 6d58e41e2ab..668858618cb 100644
--- a/src/server/game/Battlegrounds/ArenaTeam.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeam.cpp
@@ -367,31 +367,31 @@ void ArenaTeam::Roster(WorldSession* session)
uint8 unk308 = 0;
WorldPacket data(SMSG_ARENA_TEAM_ROSTER, 100);
- data << uint32(GetId()); // team id
- data << uint8(unk308); // 308 unknown value but affect packet structure
- data << uint32(GetMembersSize()); // members count
- data << uint32(GetType()); // arena team type?
+ data << uint32(GetId()); // team id
+ data << uint8(unk308); // 3.0.8 unknown value but affect packet structure
+ data << uint32(GetMembersSize()); // members count
+ data << uint32(GetType()); // arena team type?
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
{
player = ObjectAccessor::FindPlayer(itr->Guid);
- data << uint64(itr->Guid); // guid
+ data << uint64(itr->Guid); // guid
data << uint8((player ? 1 : 0)); // online flag
- data << itr->Name; // member name
- data << uint32((itr->Guid == GetCaptain() ? 0 : 1));// captain flag 0 captain 1 member
- data << uint8((player ? player->getLevel() : 0)); // unknown, level?
- data << uint8(itr->Class); // class
- data << uint32(itr->WeekGames); // played this week
- data << uint32(itr->WeekWins); // wins this week
- data << uint32(itr->SeasonGames); // played this season
- data << uint32(itr->SeasonWins); // wins this season
- data << uint32(itr->PersonalRating); // personal rating
- if (unk308)
- {
- data << float(0.0f); // 308 unk
- data << float(0.0f); // 308 unk
- }
+ data << itr->Name; // member name
+ data << uint32((itr->Guid == GetCaptain() ? 0 : 1)); // captain flag 0 captain 1 member
+ data << uint8((player ? player->getLevel() : 0)); // unknown, level?
+ data << uint8(itr->Class); // class
+ data << uint32(itr->WeekGames); // played this week
+ data << uint32(itr->WeekWins); // wins this week
+ data << uint32(itr->SeasonGames); // played this season
+ data << uint32(itr->SeasonWins); // wins this season
+ data << uint32(itr->PersonalRating); // personal rating
+ //if (unk308)
+ //{
+ // data << float(0.0f); // 308 unk
+ // data << float(0.0f); // 308 unk
+ //}
}
session->SendPacket(&data);
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index 18afd190739..0ad4afc9028 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -812,6 +812,7 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original
{
case BATTLEGROUND_RB:
isRandom = true;
+ /// Intentional fallback, "All Arenas" is random too
case BATTLEGROUND_AA:
bgTypeId = GetRandomBG(originalBgTypeId);
break;
@@ -1335,7 +1336,7 @@ void BattlegroundMgr::ScheduleQueueUpdate(uint32 arenaMatchmakerRating, uint8 ar
{
//This method must be atomic, @todo add mutex
//we will use only 1 number created of bgTypeId and bracket_id
- uint64 const scheduleId = ((uint64)arenaMatchmakerRating << 32) | (arenaType << 24) | (bgQueueTypeId << 16) | (bgTypeId << 8) | bracket_id;
+ uint64 const scheduleId = ((uint64)arenaMatchmakerRating << 32) | (uint32(arenaType) << 24) | (bgQueueTypeId << 16) | (bgTypeId << 8) | bracket_id;
if (std::find(m_QueueUpdateScheduler.begin(), m_QueueUpdateScheduler.end(), scheduleId) == m_QueueUpdateScheduler.end())
m_QueueUpdateScheduler.push_back(scheduleId);
}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h
index 7a0af0b06d7..bbe3b064c35 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h
@@ -1046,7 +1046,7 @@ const uint32 BG_AV_CreatureInfo[AV_NPC_INFO_MAX][4] =
{ 13326, 1216, 59, 59 }, //Seasoned Defender
{ 13331, 1216, 60, 60 }, //Veteran Defender
{ 13422, 1216, 61, 61 }, //Champion Defender
- { 13358, 1216, 59, 60 }, //Stormpike Bowman /// @todo: Confirm if this is correct. Author assumpted 60,61 & 69,70, but wouldn't work here
+ { 13358, 1216, 59, 60 }, //Stormpike Bowman /// @todo: Confirm if this is correct. Author assumpted 60, 61 & 69, 70, but wouldn't work here
{ 11949, 469, 0, 0}, //not spawned with this data, but used for handlekillunit
{ 11948, 469, 0, 0}, //not spawned with this data, but used for handlekillunit
{ 12053, 1214, 58, 58 }, //Frostwolf Guardian
diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp
index 5dd332a0ae1..0aa46d0d10b 100644
--- a/src/server/game/Calendar/CalendarMgr.cpp
+++ b/src/server/game/Calendar/CalendarMgr.cpp
@@ -159,20 +159,20 @@ void CalendarMgr::RemoveEvent(uint64 eventId, uint64 remover)
PreparedStatement* stmt;
MailDraft mail(calendarEvent->BuildCalendarMailSubject(remover), calendarEvent->BuildCalendarMailBody());
- CalendarInviteStore::iterator itr = _invites[eventId].begin();
- while (itr != _invites[eventId].end())
+ CalendarInviteStore& eventInvites = _invites[eventId];
+ for (size_t i = 0; i < eventInvites.size(); ++i)
{
+ CalendarInvite* invite = eventInvites[i];
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CALENDAR_INVITE);
- stmt->setUInt64(0, (*itr)->GetInviteId());
+ stmt->setUInt64(0, invite->GetInviteId());
trans->Append(stmt);
// guild events only? check invite status here?
// When an event is deleted, all invited (accepted/declined? - verify) guildies are notified via in-game mail. (wowwiki)
- if (remover && (*itr)->GetInviteeGUID() != remover)
- mail.SendMailTo(trans, MailReceiver((*itr)->GetInviteeGUID()), calendarEvent, MAIL_CHECK_MASK_COPIED);
+ if (remover && invite->GetInviteeGUID() != remover)
+ mail.SendMailTo(trans, MailReceiver(invite->GetInviteeGUID()), calendarEvent, MAIL_CHECK_MASK_COPIED);
- delete *itr;
- _invites[eventId].erase(itr);
+ delete invite;
}
_invites.erase(eventId);
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 43ac9d1c30a..507f8e066e3 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -1134,6 +1134,9 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
if ((1<<firstEffIndex) & *itr)
break;
+ if (firstEffIndex >= MAX_SPELL_EFFECTS)
+ return false;
+
// get shared data
ConditionList* sharedList = spellInfo->Effects[firstEffIndex].ImplicitTargetConditions;
@@ -1153,9 +1156,18 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
{
// add new list, create new shared mask
sharedList = new ConditionList();
+ bool assigned = false;
for (uint8 i = firstEffIndex; i < MAX_SPELL_EFFECTS; ++i)
+ {
if ((1<<i) & commonMask)
+ {
spellInfo->Effects[i].ImplicitTargetConditions = sharedList;
+ assigned = true;
+ }
+ }
+
+ if (!assigned)
+ delete sharedList;
}
sharedList->push_back(cond);
break;
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index eb7d93723f2..5ee2721e610 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -853,6 +853,18 @@ AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag, uint32 map_
return NULL;
}
+char const* GetRaceName(uint8 race, uint8 /*locale*/)
+{
+ ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race);
+ return raceEntry ? raceEntry->name : NULL;
+}
+
+char const* GetClassName(uint8 class_, uint8 /*locale*/)
+{
+ ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_);
+ return classEntry ? classEntry->name : NULL;
+}
+
uint32 GetAreaFlagByMapId(uint32 mapid)
{
AreaFlagByMapID::iterator i = sAreaFlagByMapID.find(mapid);
@@ -1226,7 +1238,7 @@ LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty)
if (!dungeon)
continue;
- if (dungeon->map == mapId && Difficulty(dungeon->difficulty) == difficulty)
+ if (dungeon->map == int32(mapId) && Difficulty(dungeon->difficulty) == difficulty)
return dungeon;
}
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index b49a1a96bd2..0a8ebad7bc8 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -37,6 +37,9 @@ AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id);
AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag, uint32 map_id);
uint32 GetAreaFlagByMapId(uint32 mapid);
+char const* GetRaceName(uint8 race, uint8 locale);
+char const* GetClassName(uint8 class_, uint8 locale);
+
WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid);
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index bbb27a8f354..b39942929ce 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -2624,8 +2624,9 @@ void Player::Regenerate(Powers power)
}
break;
case POWER_RUNES:
- case POWER_HEALTH:
break;
+ case POWER_HEALTH:
+ return;
default:
break;
}
@@ -4223,6 +4224,7 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank)
// learnSpell(prev_id, false);
}
// if ranked non-stackable spell: need activate lesser rank and update dendence state
+ /// No need to check for spellInfo != NULL here because if cur_active is true, then that means that the spell was already in m_spells, and only valid spells can be pushed there.
else if (cur_active && !spellInfo->IsStackableWithRanks() && spellInfo->IsRanked())
{
// need manually update dependence state (learn spell ignore like attempts)
@@ -4746,12 +4748,6 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
charDelete_method = CHAR_DELETE_REMOVE;
else if (CharacterNameData const* nameData = sWorld->GetCharacterNameData(guid)) // To avoid a query, we select loaded data. If it doesn't exist, return.
{
- if (!nameData)
- {
- TC_LOG_ERROR(LOG_FILTER_PLAYER, "Cannot find CharacterNameData entry for player %u from account %u. Could not delete character.", guid, accountId);
- return;
- }
-
// Define the required variables
uint32 charDelete_minLvl = sWorld->getIntConfig(nameData->m_class != CLASS_DEATH_KNIGHT ? CONFIG_CHARDELETE_MIN_LEVEL : CONFIG_CHARDELETE_HEROIC_MIN_LEVEL);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index e0f4a771396..a0aea414cef 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -6895,6 +6895,8 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 /*damage*/, Aura* triggeredByAura
// Glyph of Divinity
else if (dummySpell->Id == 54939)
{
+ if (!procSpell)
+ return false;
*handled = true;
// Check if we are the target and prevent mana gain
if (victim && triggeredByAura->GetCasterGUID() == victim->GetGUID())
@@ -7143,6 +7145,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
Aura* charge = GetAura(50241);
if (charge && charge->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL))
RemoveAurasDueToSpell(50240);
+ break;
}
// Warrior - Vigilance, SPELLFAMILY_GENERIC
if (auraSpellInfo->Id == 50720)
@@ -9382,6 +9385,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
default:
return false;
}
+ break;
case SPELL_DAMAGE_CLASS_MAGIC:
{
if (schoolMask & SPELL_SCHOOL_MASK_NORMAL)
@@ -9525,6 +9529,7 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
break;
}
}
+ /// Intentional fallback. Calculate critical strike chance for both Ranged and Melee spells
case SPELL_DAMAGE_CLASS_RANGED:
{
if (victim)
@@ -15893,7 +15898,7 @@ void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* a
}
}
- if (aurApp && aurApp->GetRemoveMode())
+ if (!aurApp || aurApp->GetRemoveMode())
return;
if (Player* player = ToPlayer())
diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp
index 8e39b39be0c..214a47a6611 100644
--- a/src/server/game/Entities/Vehicle/Vehicle.cpp
+++ b/src/server/game/Entities/Vehicle/Vehicle.cpp
@@ -353,8 +353,9 @@ SeatMap::const_iterator Vehicle::GetNextEmptySeat(int8 seatId, bool next) const
}
else
{
- if (seat-- == Seats.begin())
+ if (seat == Seats.begin())
seat = Seats.end();
+ --seat;
}
// Make sure we don't loop indefinetly
@@ -417,7 +418,7 @@ void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 typ
* @author Machiavelli
* @date 17-2-2013
*
- * @param [in,out] The prospective passenger.
+ * @param [in, out] The prospective passenger.
* @param seatId Identifier for the seat. Value of -1 indicates the next available seat.
*
* @return true if it succeeds, false if it fails.
@@ -492,7 +493,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
* @author Machiavelli
* @date 17-2-2013
*
- * @param [in,out] unit The passenger to remove.
+ * @param [in, out] unit The passenger to remove.
*/
void Vehicle::RemovePassenger(Unit* unit)
@@ -615,7 +616,7 @@ void Vehicle::InitMovementInfoForBase()
* @author Machiavelli
* @date 17-2-2013
*
- * @param [in,out] The passenger for which we check the seat info.
+ * @param [in, out] The passenger for which we check the seat info.
*
* @return null if passenger not found on vehicle, else the DBC record for the seat.
*/
@@ -637,7 +638,7 @@ VehicleSeatEntry const* Vehicle::GetSeatForPassenger(Unit const* passenger) cons
* @author Machiavelli
* @date 17-2-2013
*
- * @param [in,out] passenger Passenger to look up.
+ * @param [in, out] passenger Passenger to look up.
*
* @return The seat iterator for specified passenger if it's found on the vehicle. Otherwise Seats.end() (invalid iterator).
*/
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index a150c7a016d..bfb0e005eda 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -396,24 +396,21 @@ bool Group::AddMember(Player* player)
SubGroupCounterIncrease(subGroup);
- if (player)
+ player->SetGroupInvite(NULL);
+ if (player->GetGroup())
{
- player->SetGroupInvite(NULL);
- if (player->GetGroup())
- {
- if (isBGGroup() || isBFGroup()) // if player is in group and he is being added to BG raid group, then call SetBattlegroundRaid()
- player->SetBattlegroundOrBattlefieldRaid(this, subGroup);
- else //if player is in bg raid and we are adding him to normal group, then call SetOriginalGroup()
- player->SetOriginalGroup(this, subGroup);
- }
- else //if player is not in group, then call set group
- player->SetGroup(this, subGroup);
-
- // if the same group invites the player back, cancel the homebind timer
- InstanceGroupBind* bind = GetBoundInstance(player);
- if (bind && bind->save->GetInstanceId() == player->GetInstanceId())
- player->m_InstanceValid = true;
+ if (isBGGroup() || isBFGroup()) // if player is in group and he is being added to BG raid group, then call SetBattlegroundRaid()
+ player->SetBattlegroundOrBattlefieldRaid(this, subGroup);
+ else //if player is in bg raid and we are adding him to normal group, then call SetOriginalGroup()
+ player->SetOriginalGroup(this, subGroup);
}
+ else //if player is not in group, then call set group
+ player->SetGroup(this, subGroup);
+
+ // if the same group invites the player back, cancel the homebind timer
+ InstanceGroupBind* bind = GetBoundInstance(player);
+ if (bind && bind->save->GetInstanceId() == player->GetInstanceId())
+ player->m_InstanceValid = true;
if (!isRaidGroup()) // reset targetIcons for non-raid-groups
{
@@ -439,89 +436,86 @@ bool Group::AddMember(Player* player)
SendUpdate();
sScriptMgr->OnGroupAddMember(this, player->GetGUID());
- if (player)
+ if (!IsLeader(player->GetGUID()) && !isBGGroup() && !isBFGroup())
{
- if (!IsLeader(player->GetGUID()) && !isBGGroup() && !isBFGroup())
- {
- // reset the new member's instances, unless he is currently in one of them
- // including raid/heroic instances that they are not permanently bound to!
- player->ResetInstances(INSTANCE_RESET_GROUP_JOIN, false);
- player->ResetInstances(INSTANCE_RESET_GROUP_JOIN, true);
+ // reset the new member's instances, unless he is currently in one of them
+ // including raid/heroic instances that they are not permanently bound to!
+ player->ResetInstances(INSTANCE_RESET_GROUP_JOIN, false);
+ player->ResetInstances(INSTANCE_RESET_GROUP_JOIN, true);
- if (player->getLevel() >= LEVELREQUIREMENT_HEROIC)
+ if (player->getLevel() >= LEVELREQUIREMENT_HEROIC)
+ {
+ if (player->GetDungeonDifficulty() != GetDungeonDifficulty())
{
- if (player->GetDungeonDifficulty() != GetDungeonDifficulty())
- {
- player->SetDungeonDifficulty(GetDungeonDifficulty());
- player->SendDungeonDifficulty(true);
- }
- if (player->GetRaidDifficulty() != GetRaidDifficulty())
- {
- player->SetRaidDifficulty(GetRaidDifficulty());
- player->SendRaidDifficulty(true);
- }
+ player->SetDungeonDifficulty(GetDungeonDifficulty());
+ player->SendDungeonDifficulty(true);
+ }
+ if (player->GetRaidDifficulty() != GetRaidDifficulty())
+ {
+ player->SetRaidDifficulty(GetRaidDifficulty());
+ player->SendRaidDifficulty(true);
}
}
- player->SetGroupUpdateFlag(GROUP_UPDATE_FULL);
- UpdatePlayerOutOfRange(player);
+ }
+ player->SetGroupUpdateFlag(GROUP_UPDATE_FULL);
+ UpdatePlayerOutOfRange(player);
- // quest related GO state dependent from raid membership
- if (isRaidGroup())
- player->UpdateForQuestWorldObjects();
+ // quest related GO state dependent from raid membership
+ if (isRaidGroup())
+ player->UpdateForQuestWorldObjects();
- {
- // Broadcast new player group member fields to rest of the group
- player->SetFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
+ {
+ // Broadcast new player group member fields to rest of the group
+ player->SetFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
- UpdateData groupData(player->GetMapId());
- WorldPacket groupDataPacket;
+ UpdateData groupData(player->GetMapId());
+ WorldPacket groupDataPacket;
- // Broadcast group members' fields to player
- for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
- {
- if (itr->getSource() == player)
- continue;
+ // Broadcast group members' fields to player
+ for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ if (itr->getSource() == player)
+ continue;
- if (Player* member = itr->getSource())
+ if (Player* member = itr->getSource())
+ {
+ if (player->HaveAtClient(member))
{
- if (player->HaveAtClient(member)) // must be on the same map, or shit will break
- {
- member->SetFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
- member->BuildValuesUpdateBlockForPlayer(&groupData, player);
- member->RemoveFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
- }
+ member->SetFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
+ member->BuildValuesUpdateBlockForPlayer(&groupData, player);
+ member->RemoveFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
+ }
- if (member->HaveAtClient(player))
+ if (member->HaveAtClient(player))
+ {
+ UpdateData newData(player->GetMapId());
+ WorldPacket newDataPacket;
+ player->BuildValuesUpdateBlockForPlayer(&newData, member);
+ if (newData.HasData())
{
- UpdateData newData(player->GetMapId());
- WorldPacket newDataPacket;
- player->BuildValuesUpdateBlockForPlayer(&newData, member);
- if (newData.HasData())
- {
- newData.BuildPacket(&newDataPacket);
- member->SendDirectMessage(&newDataPacket);
- }
+ newData.BuildPacket(&newDataPacket);
+ member->SendDirectMessage(&newDataPacket);
}
}
}
+ }
- if (groupData.HasData())
- {
- groupData.BuildPacket(&groupDataPacket);
- player->SendDirectMessage(&groupDataPacket);
- }
-
- player->RemoveFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
+ if (groupData.HasData())
+ {
+ groupData.BuildPacket(&groupDataPacket);
+ player->SendDirectMessage(&groupDataPacket);
}
- if (m_maxEnchantingLevel < player->GetSkillValue(SKILL_ENCHANTING))
- m_maxEnchantingLevel = player->GetSkillValue(SKILL_ENCHANTING);
+ player->RemoveFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
}
+ if (m_maxEnchantingLevel < player->GetSkillValue(SKILL_ENCHANTING))
+ m_maxEnchantingLevel = player->GetSkillValue(SKILL_ENCHANTING);
+
return true;
}
-bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOVEMETHOD_DEFAULT*/, uint64 kicker /*= 0*/, const char* reason /*= NULL*/)
+bool Group::RemoveMember(uint64 guid, const RemoveMethod& method /*= GROUP_REMOVEMETHOD_DEFAULT*/, uint64 kicker /*= 0*/, const char* reason /*= NULL*/)
{
BroadcastGroupUpdate();
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index 10163294f1b..89a3da610a9 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -2989,7 +2989,7 @@ inline int32 Guild::_GetMemberRemainingSlots(Member const* member, uint8 tabId)
uint8 rankId = member->GetRankId();
if (rankId == GR_GUILDMASTER)
return GUILD_WITHDRAW_SLOT_UNLIMITED;
- if ((_GetRankBankTabRights(rankId, tabId) & GUILD_BANK_RIGHT_VIEW_TAB) != GR_RIGHT_EMPTY)
+ if ((_GetRankBankTabRights(rankId, tabId) & GUILD_BANK_RIGHT_VIEW_TAB) != 0)
{
int32 remaining = _GetRankBankTabSlotsPerDay(rankId, tabId) - member->GetBankWithdrawValue(tabId);
if (remaining > 0)
@@ -3007,7 +3007,7 @@ inline int32 Guild::_GetMemberRemainingMoney(Member const* member) const
if (rankId == GR_GUILDMASTER)
return GUILD_WITHDRAW_MONEY_UNLIMITED;
- if ((_GetRankRights(rankId) & (GR_RIGHT_WITHDRAW_REPAIR | GR_RIGHT_WITHDRAW_GOLD)) != GR_RIGHT_EMPTY)
+ if ((_GetRankRights(rankId) & (GR_RIGHT_WITHDRAW_REPAIR | GR_RIGHT_WITHDRAW_GOLD)) != 0)
{
int32 remaining = _GetRankBankMoneyPerDay(rankId) - member->GetBankWithdrawValue(GUILD_BANK_MAX_TABS);
if (remaining > 0)
diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index 906a5ff5b88..cc3b065dbe4 100644
--- a/src/server/game/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
@@ -254,146 +254,143 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
}
}
- for (uint32 i = 0; i < itemsCount; ++i)
+ Item* item = items[0];
+
+ uint32 auctionTime = uint32(etime * sWorld->getRate(RATE_AUCTION_TIME));
+ AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction());
+
+ uint32 deposit = sAuctionMgr->GetAuctionDeposit(auctionHouseEntry, etime, item, finalCount);
+ if (!_player->HasEnoughMoney((uint64)deposit))
{
- Item* item = items[i];
+ SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_NOT_ENOUGHT_MONEY);
+ return;
+ }
- uint32 auctionTime = uint32(etime * sWorld->getRate(RATE_AUCTION_TIME));
- AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction());
+ AuctionEntry* AH = new AuctionEntry();
+
+ if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
+ AH->auctioneer = 23442; ///@TODO - HARDCODED DB GUID, BAD BAD BAD
+ else
+ AH->auctioneer = GUID_LOPART(auctioneer);
- uint32 deposit = sAuctionMgr->GetAuctionDeposit(auctionHouseEntry, etime, item, finalCount);
- if (!_player->HasEnoughMoney((uint64)deposit))
+ // Required stack size of auction matches to current item stack size, just move item to auctionhouse
+ if (itemsCount == 1 && item->GetCount() == count[0])
+ {
+ if (HasPermission(RBAC_PERM_LOG_GM_TRADE))
{
- SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_NOT_ENOUGHT_MONEY);
- return;
+ sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)",
+ GetPlayerName().c_str(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount());
}
- _player->ModifyMoney(-int32(deposit));
-
- AuctionEntry* AH = new AuctionEntry;
AH->Id = sObjectMgr->GenerateAuctionID();
-
- if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
- AH->auctioneer = 23442;
- else
- AH->auctioneer = GUID_LOPART(auctioneer);
-
- // Required stack size of auction matches to current item stack size, just move item to auctionhouse
- if (itemsCount == 1 && item->GetCount() == count[i])
+ AH->itemGUIDLow = item->GetGUIDLow();
+ AH->itemEntry = item->GetEntry();
+ AH->itemCount = item->GetCount();
+ AH->owner = _player->GetGUIDLow();
+ AH->startbid = bid;
+ AH->bidder = 0;
+ AH->bid = 0;
+ AH->buyout = buyout;
+ AH->expire_time = time(NULL) + auctionTime;
+ AH->deposit = deposit;
+ AH->auctionHouseEntry = auctionHouseEntry;
+
+ TC_LOG_INFO(LOG_FILTER_NETWORKIO, "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) "
+ "to auctioneer %u with count %u with initial bid " UI64FMTD " with buyout " UI64FMTD " and with time %u (in sec) in auctionhouse %u",
+ _player->GetName().c_str(), _player->GetGUIDLow(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetGUIDLow(),
+ AH->auctioneer, item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
+ sAuctionMgr->AddAItem(item);
+ auctionHouse->AddAuction(AH);
+
+ _player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true);
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ item->DeleteFromInventoryDB(trans);
+ item->SaveToDB(trans);
+ AH->SaveToDB(trans);
+ _player->SaveInventoryAndGoldToDB(trans);
+ CharacterDatabase.CommitTransaction(trans);
+
+ SendAuctionCommandResult(AH, AUCTION_SELL_ITEM, ERR_AUCTION_OK);
+
+ GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
+ }
+ else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size
+ {
+ Item* newItem = item->CloneItem(finalCount, _player);
+ if (!newItem)
{
- if (HasPermission(RBAC_PERM_LOG_GM_TRADE))
- {
- sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)",
- GetPlayerName().c_str(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount());
- }
-
- AH->itemGUIDLow = item->GetGUIDLow();
- AH->itemEntry = item->GetEntry();
- AH->itemCount = item->GetCount();
- AH->owner = _player->GetGUIDLow();
- AH->startbid = bid;
- AH->bidder = 0;
- AH->bid = 0;
- AH->buyout = buyout;
- AH->expire_time = time(NULL) + auctionTime;
- AH->deposit = deposit;
- AH->auctionHouseEntry = auctionHouseEntry;
-
- TC_LOG_INFO(LOG_FILTER_NETWORKIO, "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) "
- "to auctioneer %u with count %u with initial bid " UI64FMTD " with buyout " UI64FMTD " and with time %u (in sec) in auctionhouse %u",
- _player->GetName().c_str(), _player->GetGUIDLow(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetGUIDLow(),
- AH->auctioneer, item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
- sAuctionMgr->AddAItem(item);
- auctionHouse->AddAuction(AH);
-
- _player->MoveItemFromInventory(item->GetBagSlot(), item->GetSlot(), true);
-
- SQLTransaction trans = CharacterDatabase.BeginTransaction();
- item->DeleteFromInventoryDB(trans);
- item->SaveToDB(trans);
- AH->SaveToDB(trans);
- _player->SaveInventoryAndGoldToDB(trans);
- CharacterDatabase.CommitTransaction(trans);
-
- SendAuctionCommandResult(AH, AUCTION_SELL_ITEM, ERR_AUCTION_OK);
-
- GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
+ TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "CMSG_AUCTION_SELL_ITEM: Could not create clone of item %u", item->GetEntry());
+ SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
+ delete AH;
return;
}
- else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size
+
+ if (HasPermission(RBAC_PERM_LOG_GM_TRADE))
{
- Item* newItem = item->CloneItem(finalCount, _player);
- if (!newItem)
- {
- TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "CMSG_AUCTION_SELL_ITEM: Could not create clone of item %u", item->GetEntry());
- SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
- return;
- }
+ sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)",
+ GetPlayerName().c_str(), GetAccountId(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetCount());
+ }
- if (HasPermission(RBAC_PERM_LOG_GM_TRADE))
+ AH->Id = sObjectMgr->GenerateAuctionID();
+ AH->itemGUIDLow = newItem->GetGUIDLow();
+ AH->itemEntry = newItem->GetEntry();
+ AH->itemCount = newItem->GetCount();
+ AH->owner = _player->GetGUIDLow();
+ AH->startbid = bid;
+ AH->bidder = 0;
+ AH->bid = 0;
+ AH->buyout = buyout;
+ AH->expire_time = time(NULL) + auctionTime;
+ AH->deposit = deposit;
+ AH->auctionHouseEntry = auctionHouseEntry;
+
+ TC_LOG_INFO(LOG_FILTER_NETWORKIO, "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) to "
+ "auctioneer %u with count %u with initial bid " UI64FMTD " with buyout " UI64FMTD " and with time %u (in sec) in auctionhouse %u",
+ _player->GetName().c_str(), _player->GetGUIDLow(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(),
+ newItem->GetGUIDLow(), AH->auctioneer, newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
+ sAuctionMgr->AddAItem(newItem);
+ auctionHouse->AddAuction(AH);
+
+ for (uint32 j = 0; j < itemsCount; ++j)
+ {
+ Item* item2 = items[j];
+
+ // Item stack count equals required count, ready to delete item - cloned item will be used for auction
+ if (item2->GetCount() == count[j])
{
- sLog->outCommand(GetAccountId(), "GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)",
- GetPlayerName().c_str(), GetAccountId(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetCount());
- }
+ _player->MoveItemFromInventory(item2->GetBagSlot(), item2->GetSlot(), true);
- AH->itemGUIDLow = newItem->GetGUIDLow();
- AH->itemEntry = newItem->GetEntry();
- AH->itemCount = newItem->GetCount();
- AH->owner = _player->GetGUIDLow();
- AH->startbid = bid;
- AH->bidder = 0;
- AH->bid = 0;
- AH->buyout = buyout;
- AH->expire_time = time(NULL) + auctionTime;
- AH->deposit = deposit;
- AH->auctionHouseEntry = auctionHouseEntry;
-
- TC_LOG_INFO(LOG_FILTER_NETWORKIO, "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) to "
- "auctioneer %u with count %u with initial bid " UI64FMTD " with buyout " UI64FMTD " and with time %u (in sec) in auctionhouse %u",
- _player->GetName().c_str(), _player->GetGUIDLow(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(),
- newItem->GetGUIDLow(), AH->auctioneer, newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
- sAuctionMgr->AddAItem(newItem);
- auctionHouse->AddAuction(AH);
-
- for (uint32 j = 0; j < itemsCount; ++j)
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ item2->DeleteFromInventoryDB(trans);
+ item2->DeleteFromDB(trans);
+ CharacterDatabase.CommitTransaction(trans);
+ }
+ else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction
{
- Item* item2 = items[j];
-
- // Item stack count equals required count, ready to delete item - cloned item will be used for auction
- if (item2->GetCount() == count[j])
- {
- _player->MoveItemFromInventory(item2->GetBagSlot(), item2->GetSlot(), true);
-
- SQLTransaction trans = CharacterDatabase.BeginTransaction();
- item2->DeleteFromInventoryDB(trans);
- item2->DeleteFromDB(trans);
- CharacterDatabase.CommitTransaction(trans);
- }
- else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction
- {
- item2->SetCount(item2->GetCount() - count[j]);
- item2->SetState(ITEM_CHANGED, _player);
- _player->ItemRemovedQuestCheck(item2->GetEntry(), count[j]);
- item2->SendUpdateToPlayer(_player);
-
- SQLTransaction trans = CharacterDatabase.BeginTransaction();
- item2->SaveToDB(trans);
- CharacterDatabase.CommitTransaction(trans);
- }
+ item2->SetCount(item2->GetCount() - count[j]);
+ item2->SetState(ITEM_CHANGED, _player);
+ _player->ItemRemovedQuestCheck(item2->GetEntry(), count[j]);
+ item2->SendUpdateToPlayer(_player);
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ item2->SaveToDB(trans);
+ CharacterDatabase.CommitTransaction(trans);
}
+ }
- SQLTransaction trans = CharacterDatabase.BeginTransaction();
- newItem->SaveToDB(trans);
- AH->SaveToDB(trans);
- _player->SaveInventoryAndGoldToDB(trans);
- CharacterDatabase.CommitTransaction(trans);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ newItem->SaveToDB(trans);
+ AH->SaveToDB(trans);
+ _player->SaveInventoryAndGoldToDB(trans);
+ CharacterDatabase.CommitTransaction(trans);
- SendAuctionCommandResult(AH, AUCTION_SELL_ITEM, ERR_AUCTION_OK);
+ SendAuctionCommandResult(AH, AUCTION_SELL_ITEM, ERR_AUCTION_OK);
- GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
- return;
- }
+ GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
}
+
+ _player->ModifyMoney(-int32(deposit));
}
// this function is called when client bids or buys out auction
diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index 5832cf6e095..3c28a32af93 100644
--- a/src/server/game/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
@@ -450,8 +450,8 @@ void WorldSession::HandleCalendarEventInvite(WorldPacket& recvData)
}
// 946684800 is 01/01/2000 00:00:00 - default response time
- CalendarInvite* invite = new CalendarInvite(inviteId, 0, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
- sCalendarMgr->SendCalendarEventInvite(*invite);
+ CalendarInvite invite(inviteId, 0, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, "");
+ sCalendarMgr->SendCalendarEventInvite(invite);
}
}
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index 3d62fbcc740..9ec018aaf78 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -346,7 +346,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
// If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to
// We also do that if a player is under the required level for whispers.
- if (receiver->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) ||
+ if (receiver->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) ||
(HasPermission(RBAC_PERM_CAN_FILTER_WHISPERS) && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID())))
sender->AddWhisperWhiteList(receiver->GetGUID());
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 0905e33097f..2a21eedf354 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -1001,7 +1001,7 @@ void WorldSession::HandleRequestAccountData(WorldPacket& recvData)
TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "RAD: type %u", type);
- if (type > NUM_ACCOUNT_DATA_TYPES)
+ if (type >= NUM_ACCOUNT_DATA_TYPES)
return;
AccountData* adata = GetAccountData(AccountDataType(type));
diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp
index d39099485a5..57d41be9e23 100644
--- a/src/server/game/Handlers/TicketHandler.cpp
+++ b/src/server/game/Handlers/TicketHandler.cpp
@@ -83,6 +83,7 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recvData)
{
TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "CMSG_GMTICKET_CREATE possibly corrupt. Uncompression failed.");
recvData.rfinish();
+ delete ticket;
return;
}
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index 6d5170e0f49..7da7cd975ee 100644
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -158,6 +158,12 @@ uint32 LootStore::LoadLootTable()
continue; // error already printed to log/console.
}
+ if (group >= 1 << 7) // it stored in 7 bit field
+ {
+ TC_LOG_ERROR(LOG_FILTER_SQL, "Table '%s' entry %d item %d: group (%u) must be less %u - skipped", GetName(), entry, item, group, 1 << 7);
+ return false;
+ }
+
LootStoreItem* storeitem = new LootStoreItem(item, chanceOrQuestChance, lootmode, group, mincountOrRef, maxcount);
if (!storeitem->IsValid(*this, entry)) // Validity checks
@@ -293,12 +299,6 @@ bool LootStoreItem::Roll(bool rate) const
// Checks correctness of values
bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const
{
- if (group >= 1 << 7) // it stored in 7 bit field
- {
- TC_LOG_ERROR(LOG_FILTER_SQL, "Table '%s' entry %d item %d: group (%u) must be less %u - skipped", store.GetName(), entry, itemid, group, 1 << 7);
- return false;
- }
-
if (mincountOrRef == 0)
{
TC_LOG_ERROR(LOG_FILTER_SQL, "Table '%s' entry %d item %d: wrong mincountOrRef (%d) - skipped", store.GetName(), entry, itemid, mincountOrRef);
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index c9bf5df4cf8..45ce43bc3fc 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -672,6 +672,8 @@ void Map::ProcessRelocationNotifies(const uint32 diff)
void Map::RemovePlayerFromMap(Player* player, bool remove)
{
+ sScriptMgr->OnPlayerLeaveMap(this, player);
+
player->RemoveFromWorld();
SendRemoveTransports(player);
@@ -682,11 +684,7 @@ void Map::RemovePlayerFromMap(Player* player, bool remove)
ASSERT(remove); //maybe deleted in logoutplayer when player is not in a map
if (remove)
- {
DeleteFromWorld(player);
-
- sScriptMgr->OnPlayerLeaveMap(this, player);
- }
}
template<class T>
diff --git a/src/server/game/Maps/PhaseMgr.h b/src/server/game/Maps/PhaseMgr.h
index ec41146ded7..21f67038c3f 100644
--- a/src/server/game/Maps/PhaseMgr.h
+++ b/src/server/game/Maps/PhaseMgr.h
@@ -113,8 +113,9 @@ private:
struct PhaseUpdateData
{
- void AddConditionType(ConditionTypes conditionType) { _conditionTypeFlags |= (1 << conditionType); }
- void AddQuestUpdate(uint32 questId);
+ PhaseUpdateData(): _conditionTypeFlags(0), _questId(0) { }
+ void AddConditionType(ConditionTypes const conditionType) { _conditionTypeFlags |= (1 << conditionType); }
+ void AddQuestUpdate(uint32 const questId);
bool IsConditionRelated(Condition const* condition) const;
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index 62a0841405c..c26bbc1dfc9 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -209,15 +209,17 @@ enum TrinityStrings
LANG_YOU_CHANGE_RUNIC_POWER = 173,
LANG_YOURS_RUNIC_POWER_CHANGED = 174,
LANG_LIQUID_STATUS = 175,
+ LANG_INVALID_GAMEOBJECT_TYPE = 176,
+ LANG_GAMEOBJECT_DAMAGED = 177,
- LANG_PHASING_REPORT_STATUS = 176,
- LANG_PHASING_NO_DEFINITIONS = 177, // Phasing
LANG_PHASING_SUCCESS = 178,
LANG_PHASING_FAILED = 179,
LANG_PHASING_LAST_PHASE = 180,
LANG_PHASING_LIST = 181,
LANG_PHASING_PHASEMASK = 182,
- // Room for more level 1 183-199 not used
+ LANG_PHASING_REPORT_STATUS = 183,
+ LANG_PHASING_NO_DEFINITIONS = 184, // Phasing
+ // Room for more level 1 185-199 not used
// level 2 chat
LANG_NO_SELECTION = 200,
diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
index abb4ac9964b..8086e60c912 100755
--- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
@@ -27,7 +27,7 @@
#include "Player.h"
template<class T, typename D>
-void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T* owner, bool updateDestination)
+void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool updateDestination)
{
if (!i_target.isValid() || !i_target->IsInWorld())
return;
@@ -117,7 +117,7 @@ void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T* owner, bool upd
}
template<class T, typename D>
-bool TargetedMovementGeneratorMedium<T,D>::DoUpdate(T* owner, uint32 time_diff)
+bool TargetedMovementGeneratorMedium<T, D>::DoUpdate(T* owner, uint32 time_diff)
{
if (!i_target.isValid() || !i_target->IsInWorld())
return false;
@@ -185,7 +185,7 @@ template<class T>
void ChaseMovementGenerator<T>::_reachTarget(T* owner)
{
if (owner->IsWithinMeleeRange(this->i_target.getTarget()))
- owner->Attack(this->i_target.getTarget(),true);
+ owner->Attack(this->i_target.getTarget(), true);
}
template<>
@@ -303,14 +303,14 @@ void FollowMovementGenerator<Creature>::MovementInform(Creature* unit)
}
//-----------------------------------------------//
-template void TargetedMovementGeneratorMedium<Player,ChaseMovementGenerator<Player> >::_setTargetLocation(Player*, bool);
-template void TargetedMovementGeneratorMedium<Player,FollowMovementGenerator<Player> >::_setTargetLocation(Player*, bool);
-template void TargetedMovementGeneratorMedium<Creature,ChaseMovementGenerator<Creature> >::_setTargetLocation(Creature*, bool);
-template void TargetedMovementGeneratorMedium<Creature,FollowMovementGenerator<Creature> >::_setTargetLocation(Creature*, bool);
-template bool TargetedMovementGeneratorMedium<Player,ChaseMovementGenerator<Player> >::DoUpdate(Player*, uint32);
-template bool TargetedMovementGeneratorMedium<Player,FollowMovementGenerator<Player> >::DoUpdate(Player*, uint32);
-template bool TargetedMovementGeneratorMedium<Creature,ChaseMovementGenerator<Creature> >::DoUpdate(Creature*, uint32);
-template bool TargetedMovementGeneratorMedium<Creature,FollowMovementGenerator<Creature> >::DoUpdate(Creature*, uint32);
+template void TargetedMovementGeneratorMedium<Player, ChaseMovementGenerator<Player> >::_setTargetLocation(Player*, bool);
+template void TargetedMovementGeneratorMedium<Player, FollowMovementGenerator<Player> >::_setTargetLocation(Player*, bool);
+template void TargetedMovementGeneratorMedium<Creature, ChaseMovementGenerator<Creature> >::_setTargetLocation(Creature*, bool);
+template void TargetedMovementGeneratorMedium<Creature, FollowMovementGenerator<Creature> >::_setTargetLocation(Creature*, bool);
+template bool TargetedMovementGeneratorMedium<Player, ChaseMovementGenerator<Player> >::DoUpdate(Player*, uint32);
+template bool TargetedMovementGeneratorMedium<Player, FollowMovementGenerator<Player> >::DoUpdate(Player*, uint32);
+template bool TargetedMovementGeneratorMedium<Creature, ChaseMovementGenerator<Creature> >::DoUpdate(Creature*, uint32);
+template bool TargetedMovementGeneratorMedium<Creature, FollowMovementGenerator<Creature> >::DoUpdate(Creature*, uint32);
template void ChaseMovementGenerator<Player>::_reachTarget(Player*);
template void ChaseMovementGenerator<Creature>::_reachTarget(Creature*);
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 80e8f1e1f44..3fd7e7ee393 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -701,7 +701,7 @@ dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPo
// Find movement delta.
float delta[VERTEX_SIZE];
dtVsub(delta, steerPos, iterPos);
- float len = dtSqrt(dtVdot(delta,delta));
+ float len = dtSqrt(dtVdot(delta, delta));
// If the steer target is end of path or off-mesh link, do not move past the location.
if ((endOfPath || offMeshConnection) && len < SMOOTH_PATH_STEP_SIZE)
len = 1.0f;
diff --git a/src/server/game/Movement/Waypoints/Path.h b/src/server/game/Movement/Waypoints/Path.h
index 39f05184cf6..9814d1c65e1 100644
--- a/src/server/game/Movement/Waypoints/Path.h
+++ b/src/server/game/Movement/Waypoints/Path.h
@@ -40,13 +40,13 @@ class Path
void erase(uint32 idx) { i_nodes.erase(i_nodes.begin()+idx); }
void crop(unsigned int start, unsigned int end)
{
- while(start && !i_nodes.empty())
+ while (start && !i_nodes.empty())
{
i_nodes.pop_front();
--start;
}
- while(end && !i_nodes.empty())
+ while (end && !i_nodes.empty())
{
i_nodes.pop_back();
--end;
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index fbfd467e7eb..ec1b7ac609e 100644
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -446,6 +446,7 @@ void AddSC_ulduar_teleporter();
void AddSC_boss_mimiron();
void AddSC_boss_hodir();
void AddSC_boss_freya();
+void AddSC_boss_yogg_saron();
void AddSC_boss_algalon_the_observer();
void AddSC_instance_ulduar();
void AddSC_boss_keleseth(); //Utgarde Keep
@@ -1188,6 +1189,7 @@ void AddNorthrendScripts()
AddSC_boss_mimiron();
AddSC_boss_hodir();
AddSC_boss_freya();
+ AddSC_boss_yogg_saron();
AddSC_boss_algalon_the_observer();
AddSC_instance_ulduar();
AddSC_boss_keleseth(); //Utgarde Keep
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 92e72627668..cdfb706d173 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -683,7 +683,7 @@ void AuraEffect::CalculateSpellMod()
m_spellmod->op = SpellModOp(GetMiscValue());
ASSERT(m_spellmod->op < MAX_SPELLMOD);
- m_spellmod->type = SpellModType(GetAuraType()); // SpellModType value == spell aura types
+ m_spellmod->type = SpellModType(uint32(GetAuraType())); // SpellModType value == spell aura types
m_spellmod->spellId = GetId();
m_spellmod->mask = GetSpellInfo()->Effects[GetEffIndex()].SpellClassMask;
m_spellmod->charges = GetBase()->GetCharges();
@@ -1788,17 +1788,17 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
int32 basePoints = std::min<int32>(oldPower, FurorChance);
target->SetPower(POWER_ENERGY, 0);
target->CastCustomSpell(target, 17099, &basePoints, NULL, NULL, true, NULL, this);
+ break;
}
- break;
case FORM_BEAR:
- if (irand(0, 99) < FurorChance)
+ if (urand(0, 99) < FurorChance)
target->CastSpell(target, 17057, true);
default:
{
int32 newEnergy = std::min(target->GetPower(POWER_ENERGY), FurorChance);
target->SetPower(POWER_ENERGY, newEnergy);
+ break;
}
- break;
}
break;
}
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index c4a6b6e6d1c..4cbb9a28603 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -2613,7 +2613,8 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
{
// for delayed spells ignore negative spells (after duel end) for friendly targets
/// @todo this cause soul transfer bugged
- if (m_spellInfo->Speed > 0.0f && unit->GetTypeId() == TYPEID_PLAYER && !m_spellInfo->IsPositive())
+ // 63881 - Malady of the Mind jump spell (Yogg-Saron)
+ if (m_spellInfo->Speed > 0.0f && unit->GetTypeId() == TYPEID_PLAYER && !m_spellInfo->IsPositive() && m_spellInfo->Id != 63881)
return SPELL_MISS_EVADE;
// assisting case, healing and resurrection
@@ -3344,7 +3345,7 @@ void Spell::handle_immediate()
if (m_spellInfo->IsChanneled())
{
int32 duration = m_spellInfo->GetDuration();
- if (duration)
+ if (duration > 0)
{
// First mod_duration then haste - see Missile Barrage
// Apply duration mod
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index e74fac2ed7c..ca176e0e202 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -5417,7 +5417,7 @@ void Spell::EffectActivateRune(SpellEffIndex effIndex)
if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l+1) && player->GetCurrentRune(l+1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)))
{
// Should always update the rune with the lowest cd
- if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l+1))
+ if (l + 1 < MAX_RUNES && player->GetRuneCooldown(l) >= player->GetRuneCooldown(l+1))
l++;
player->SetRuneCooldown(l, 0);
--count;
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index aa6dac2d79a..88cda9d5db9 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -2690,7 +2690,7 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
continue;
// if non-positive trigger cast targeted to positive target this main cast is non-positive
// this will place this spell auras as debuffs
- if (!_IsPositiveTarget(spellTriggeredProto->Effects[i].TargetA.GetTarget(), spellTriggeredProto->Effects[i].TargetB.GetTarget()) && !spellTriggeredProto->_IsPositiveEffect(i, true))
+ if (_IsPositiveTarget(spellTriggeredProto->Effects[i].TargetA.GetTarget(), spellTriggeredProto->Effects[i].TargetB.GetTarget()) && !spellTriggeredProto->_IsPositiveEffect(i, true))
return false;
}
}
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 8c497ce6fdb..a2a4a85808a 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -84,6 +84,9 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto,
// ToC Icehowl Arctic Breath
else if (spellproto->SpellVisual[0] == 14153)
return DIMINISHING_NONE;
+ // Black Plague
+ else if (spellproto->Id == 64155)
+ return DIMINISHING_NONE;
break;
}
// Event spells
@@ -3374,6 +3377,14 @@ void SpellMgr::LoadSpellInfoCorrections()
// that will be clear if we get more spells with problem like this
spellInfo->AttributesEx |= SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY;
break;
+ case 61791: // Ride Vehicle (Yogg-Saron)
+ // TODO: remove this when basepoints of all Ride Vehicle auras are calculated correctly
+ spellInfo->Effects[EFFECT_0].BasePoints = 1;
+ break;
+ case 64468: // Empowering Shadows (Yogg-Saron)
+ case 64486: // Empowering Shadows (Yogg-Saron)
+ spellInfo->MaxAffectedTargets = 3; // same for both modes?
+ break;
case 62301: // Cosmic Smash (Algalon the Observer)
spellInfo->MaxAffectedTargets = 1;
break;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 66dc5225a35..b61c5ac5de3 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -2203,7 +2203,7 @@ namespace Trinity
{
WorldPacket* data = new WorldPacket();
- uint32 lineLength = (line ? strlen(line) : 0) + 1;
+ uint32 lineLength = strlen(line) + 1;
data->Initialize(SMSG_MESSAGECHAT, 100); // guess size
*data << uint8(CHAT_MSG_SYSTEM);
diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp
index 9aa68e0892c..c347648abab 100644
--- a/src/server/scripts/Commands/cs_account.cpp
+++ b/src/server/scripts/Commands/cs_account.cpp
@@ -482,7 +482,7 @@ public:
char* arg3 = strtok(NULL, " ");
bool isAccountNameGiven = true;
- if (arg1 && !arg3)
+ if (!arg3)
{
if (!handler->getSelectedPlayer())
return false;
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp
index 727aa55597f..2b316803029 100644
--- a/src/server/scripts/Commands/cs_character.cpp
+++ b/src/server/scripts/Commands/cs_character.cpp
@@ -320,7 +320,7 @@ public:
// check online security
if (handler->HasLowerSecurity(target, 0))
return false;
-
+
playerOldName = target->GetName();
}
else
@@ -345,7 +345,7 @@ public:
handler->SetSentErrorMessage(true);
return false;
}
-
+
if (WorldSession* session = handler->GetSession())
{
if (!session->HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName))
diff --git a/src/server/scripts/Commands/cs_deserter.cpp b/src/server/scripts/Commands/cs_deserter.cpp
index 3850456fcb3..ef2cd7b45b9 100644
--- a/src/server/scripts/Commands/cs_deserter.cpp
+++ b/src/server/scripts/Commands/cs_deserter.cpp
@@ -45,20 +45,20 @@ public:
ChatCommand* GetCommands() const
{
- static ChatCommand deserterInstanceCommandTable[] =
+ static ChatCommand deserterInstanceCommandTable[] =
{
{ "add", SEC_ADMINISTRATOR, false, &HandleDeserterInstanceAdd, "", NULL },
{ "remove", SEC_ADMINISTRATOR, false, &HandleDeserterInstanceRemove, "", NULL },
{ NULL, SEC_PLAYER, false, NULL, "", NULL }
};
- static ChatCommand deserterBGCommandTable[] =
+ static ChatCommand deserterBGCommandTable[] =
{
{ "add", SEC_ADMINISTRATOR, false, &HandleDeserterBGAdd, "", NULL },
{ "remove", SEC_ADMINISTRATOR, false, &HandleDeserterBGRemove, "", NULL },
{ NULL, SEC_PLAYER, false, NULL, "", NULL }
};
- static ChatCommand deserterCommandTable[] =
+ static ChatCommand deserterCommandTable[] =
{
{ "instance", SEC_ADMINISTRATOR, false, NULL, "", deserterInstanceCommandTable },
{ "bg", SEC_ADMINISTRATOR, false, NULL, "", deserterBGCommandTable },
diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp
index bbff716253e..364746adae9 100644
--- a/src/server/scripts/Commands/cs_list.cpp
+++ b/src/server/scripts/Commands/cs_list.cpp
@@ -518,7 +518,7 @@ public:
uint32 copp = (money % GOLD) % SILVER;
std::string receiverStr = handler->playerLink(receiver);
std::string senderStr = handler->playerLink(sender);
- handler->PSendSysMessage(LANG_LIST_MAIL_INFO_1 , messageId, subject.c_str(),gold, silv, copp);
+ handler->PSendSysMessage(LANG_LIST_MAIL_INFO_1, messageId, subject.c_str(), gold, silv, copp);
handler->PSendSysMessage(LANG_LIST_MAIL_INFO_2, senderStr.c_str(), senderId, receiverStr.c_str(), receiverId);
handler->PSendSysMessage(LANG_LIST_MAIL_INFO_3, TimeToTimestampStr(deliverTime).c_str(), TimeToTimestampStr(expireTime).c_str());
if (hasItem == 1)
@@ -541,7 +541,7 @@ public:
uint32 item_entry = fields[0].GetUInt32();
uint32 item_count = fields[1].GetUInt32();
QueryResult result4;
- result4 = WorldDatabase.PQuery("SELECT name,quality FROM item_template WHERE entry = '%u'", item_entry);
+ result4 = WorldDatabase.PQuery("SELECT name, quality FROM item_template WHERE entry = '%u'", item_entry);
Field* fields1 = result4->Fetch();
std::string item_name = fields1[0].GetString();
int item_quality = fields1[1].GetUInt8();
diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp
index e28251bebb4..ff5ece84272 100644
--- a/src/server/scripts/Commands/cs_lookup.cpp
+++ b/src/server/scripts/Commands/cs_lookup.cpp
@@ -869,12 +869,7 @@ public:
uint32 id = atoi((char*)args);
- bool found = false;
- uint32 count = 0;
- uint32 maxResults = 1;
-
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(id);
- if (spellInfo)
+ if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(id))
{
int locale = handler->GetSessionDbcLocale();
std::string name = spellInfo->SpellName;
@@ -884,14 +879,6 @@ public:
return true;
}
- if (locale < TOTAL_LOCALES)
- {
- if (maxResults && count++ == maxResults)
- {
- handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
- return true;
- }
-
bool known = target && target->HasSpell(id);
bool learn = (spellInfo->Effects[0].Effect == SPELL_EFFECT_LEARN_SPELL);
@@ -935,13 +922,8 @@ public:
ss << handler->GetTrinityString(LANG_ACTIVE);
handler->SendSysMessage(ss.str().c_str());
-
- if (!found)
- found = true;
- }
}
-
- if (!found)
+ else
handler->SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
return true;
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index c5182f7cf4c..489c11e0f94 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -1070,9 +1070,7 @@ public:
Player* player = handler->GetSession()->GetPlayer();
uint32 zone_id = player->GetZoneId();
- WorldSafeLocsEntry const* graveyard = sObjectMgr->GetClosestGraveYard(
- player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), team);
-
+ WorldSafeLocsEntry const* graveyard = sObjectMgr->GetClosestGraveYard(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), team);
if (graveyard)
{
uint32 graveyardId = graveyard->ID;
@@ -1102,14 +1100,12 @@ public:
{
std::string team_name;
- if (team == 0)
- team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY);
- else if (team == HORDE)
+ if (team == HORDE)
team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE);
else if (team == ALLIANCE)
team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE);
- if (team == ~uint32(0))
+ if (!team)
handler->PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id);
else
handler->PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id, team_name.c_str());
@@ -2046,6 +2042,70 @@ public:
if (!*args)
return false;
+ char* str = strtok((char*)args, " ");
+
+ if (strcmp(str, "go") == 0)
+ {
+ char* guidStr = strtok(NULL, " ");
+ if (!guidStr)
+ {
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ int32 guid = atoi(guidStr);
+ if (!guid)
+ {
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* damageStr = strtok(NULL, " ");
+ if (!damageStr)
+ {
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ int32 damage = atoi(damageStr);
+ if (!damage)
+ {
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (Player* player = handler->GetSession()->GetPlayer())
+ {
+ GameObject* go = NULL;
+
+ if (GameObjectData const* goData = sObjectMgr->GetGOData(guid))
+ go = handler->GetObjectGlobalyWithGuidOrNearWithDbGuid(guid, goData->id);
+
+ if (!go)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_OBJNOTFOUND, guid);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!go->IsDestructibleBuilding())
+ {
+ handler->SendSysMessage(LANG_INVALID_GAMEOBJECT_TYPE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ go->ModifyHealth(-damage, player);
+ handler->PSendSysMessage(LANG_GAMEOBJECT_DAMAGED, go->GetName().c_str(), guid, -damage, go->GetGOValue()->Building.Health);
+ }
+
+ return true;
+ }
+
Unit* target = handler->getSelectedUnit();
if (!target || !handler->GetSession()->GetPlayer()->GetSelection())
{
@@ -2084,7 +2144,7 @@ public:
return true;
}
- uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL;
+ uint32 school = atoi((char*)schoolStr);
if (school >= MAX_SPELL_SCHOOL)
return false;
diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp
index 55b6edbadbe..300b39fc389 100644
--- a/src/server/scripts/Commands/cs_mmaps.cpp
+++ b/src/server/scripts/Commands/cs_mmaps.cpp
@@ -128,7 +128,7 @@ public:
int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS;
handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gy, gx);
- handler->PSendSysMessage("gridloc [%i,%i]", gx, gy);
+ handler->PSendSysMessage("gridloc [%i, %i]", gx, gy);
// calculate navmesh tile location
dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId());
@@ -148,7 +148,7 @@ public:
int32 tilex = int32((y - min[0]) / SIZE_OF_GRIDS);
int32 tiley = int32((x - min[2]) / SIZE_OF_GRIDS);
- handler->PSendSysMessage("Calc [%02i,%02i]", tilex, tiley);
+ handler->PSendSysMessage("Calc [%02i, %02i]", tilex, tiley);
// navmesh poly -> navmesh tile location
dtQueryFilter filter = dtQueryFilter();
@@ -156,16 +156,16 @@ public:
navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL);
if (polyRef == INVALID_POLYREF)
- handler->PSendSysMessage("Dt [??,??] (invalid poly, probably no tile loaded)");
+ handler->PSendSysMessage("Dt [??, ??] (invalid poly, probably no tile loaded)");
else
{
dtMeshTile const* tile;
dtPoly const* poly;
navmesh->getTileAndPolyByRef(polyRef, &tile, &poly);
if (tile)
- handler->PSendSysMessage("Dt [%02i,%02i]", tile->header->x, tile->header->y);
+ handler->PSendSysMessage("Dt [%02i, %02i]", tile->header->x, tile->header->y);
else
- handler->PSendSysMessage("Dt [??,??] (no tile loaded)");
+ handler->PSendSysMessage("Dt [??, ??] (no tile loaded)");
}
return true;
@@ -190,7 +190,7 @@ public:
if (!tile || !tile->header)
continue;
- handler->PSendSysMessage("[%02i,%02i]", tile->header->x, tile->header->y);
+ handler->PSendSysMessage("[%02i, %02i]", tile->header->x, tile->header->y);
}
return true;
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index be111c9356b..ed933ffd5bc 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -310,24 +310,14 @@ public:
if (!pfactionid)
{
- if (target)
- {
- uint32 factionid = target->getFaction();
- uint32 flag = target->GetUInt32Value(UNIT_FIELD_FLAGS);
- uint32 npcflag = target->GetUInt32Value(UNIT_NPC_FLAGS);
- uint32 dyflag = target->GetUInt32Value(UNIT_DYNAMIC_FLAGS);
- handler->PSendSysMessage(LANG_CURRENT_FACTION, target->GetGUIDLow(), factionid, flag, npcflag, dyflag);
- }
+ uint32 factionid = target->getFaction();
+ uint32 flag = target->GetUInt32Value(UNIT_FIELD_FLAGS);
+ uint32 npcflag = target->GetUInt32Value(UNIT_NPC_FLAGS);
+ uint32 dyflag = target->GetUInt32Value(UNIT_DYNAMIC_FLAGS);
+ handler->PSendSysMessage(LANG_CURRENT_FACTION, target->GetGUIDLow(), factionid, flag, npcflag, dyflag);
return true;
}
- if (!target)
- {
- handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
uint32 factionid = atoi(pfactionid);
uint32 flag;
@@ -341,7 +331,7 @@ public:
uint32 npcflag;
if (!pnpcflag)
- npcflag = target->GetUInt32Value(UNIT_NPC_FLAGS);
+ npcflag = target->GetUInt32Value(UNIT_NPC_FLAGS);
else
npcflag = atoi(pnpcflag);
@@ -349,7 +339,7 @@ public:
uint32 dyflag;
if (!pdyflag)
- dyflag = target->GetUInt32Value(UNIT_DYNAMIC_FLAGS);
+ dyflag = target->GetUInt32Value(UNIT_DYNAMIC_FLAGS);
else
dyflag = atoi(pdyflag);
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index a398ac9004b..eadfd3b8da0 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -254,7 +254,7 @@ public:
return false;
}
- uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
+ uint32 vendor_entry = vendor->GetEntry();
if (!sObjectMgr->IsVendorItemValid(vendor_entry, itemId, maxcount, incrtime, extendedcost, type, handler->GetSession()->GetPlayer()))
{
diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp
index 604218c2e68..667815ce16c 100644
--- a/src/server/scripts/Commands/cs_rbac.cpp
+++ b/src/server/scripts/Commands/cs_rbac.cpp
@@ -32,6 +32,12 @@ EndScriptData */
struct RBACCommandData
{
RBACCommandData(): id(0), realmId(0), rbac(NULL), needDelete(false) { }
+ ~RBACCommandData()
+ {
+ if (needDelete)
+ delete rbac;
+ }
+
uint32 id;
int32 realmId;
RBACData* rbac;
@@ -230,8 +236,7 @@ public:
break;
}
- if (command->needDelete)
- delete command;
+ delete command;
return true;
}
@@ -266,8 +271,7 @@ public:
break;
}
- if (command->needDelete)
- delete command;
+ delete command;
return true;
}
@@ -295,8 +299,7 @@ public:
}
}
- if (command->needDelete)
- delete command;
+ delete command;
return true;
}
@@ -335,8 +338,7 @@ public:
break;
}
- if (command->needDelete)
- delete command;
+ delete command;
return true;
}
@@ -375,8 +377,7 @@ public:
break;
}
- if (command->needDelete)
- delete command;
+ delete command;
return true;
}
@@ -411,8 +412,7 @@ public:
break;
}
- if (command->needDelete)
- delete command;
+ delete command;
return true;
}
@@ -453,8 +453,7 @@ public:
}
}
- if (command->needDelete)
- delete command;
+ delete command;
return true;
}
@@ -493,8 +492,7 @@ public:
break;
}
- if (command->needDelete)
- delete command;
+ delete command;
return true;
}
@@ -533,8 +531,7 @@ public:
break;
}
- if (command->needDelete)
- delete command;
+ delete command;
return true;
}
@@ -569,8 +566,7 @@ public:
break;
}
- if (command->needDelete)
- delete command;
+ delete command;
return true;
}
@@ -613,8 +609,7 @@ public:
}
}
- if (command->needDelete)
- delete command;
+ delete command;
return true;
}
@@ -643,8 +638,7 @@ public:
}
}
- if (command->needDelete)
- delete command;
+ delete command;
return true;
}
diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp
index b162e0c51a4..745cc80ab41 100644
--- a/src/server/scripts/Commands/cs_wp.cpp
+++ b/src/server/scripts/Commands/cs_wp.cpp
@@ -800,7 +800,7 @@ public:
if (show == "info")
{
// Check if the user did specify a visual waypoint
- if (target->GetEntry() != VISUAL_WAYPOINT)
+ if (target && target->GetEntry() != VISUAL_WAYPOINT)
{
handler->PSendSysMessage(LANG_WAYPOINT_VP_SELECT);
handler->SetSentErrorMessage(true);
diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp
index 97b8e0334ee..3585debb1c2 100644
--- a/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp
+++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp
@@ -146,49 +146,51 @@ class boss_kirtonos_the_herald : public CreatureScript
{
events.Update(diff);
- while (uint32 eventId = events.ExecuteEvent() && !UpdateVictim())
+ if (!UpdateVictim())
{
- switch (eventId)
+ while (uint32 eventId = events.ExecuteEvent())
{
- case INTRO_1:
- me->GetMotionMaster()->MovePath(KIRTONOS_PATH, false);
- break;
- case INTRO_2:
- me->GetMotionMaster()->MovePoint(0, PosMove[0]);
- events.ScheduleEvent(INTRO_3, 1000);
- break;
- case INTRO_3:
- if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_GATE_KIRTONOS)))
- gate->SetGoState(GO_STATE_READY);
- me->SetFacingTo(0.01745329f);
- events.ScheduleEvent(INTRO_4, 3000);
- break;
- case INTRO_4:
- if (GameObject* brazier = me->GetMap()->GetGameObject(instance->GetData64(GO_BRAZIER_OF_THE_HERALD)))
- brazier->SetGoState(GO_STATE_READY);
- me->SetWalk(true);
- me->SetDisableGravity(false);
- DoCast(me, SPELL_KIRTONOS_TRANSFORM);
- me->SetCanFly(false);
- events.ScheduleEvent(INTRO_5, 1000);
- break;
- case INTRO_5:
- me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_KIRTONOS_STAFF));
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
- me->SetReactState(REACT_AGGRESSIVE);
- events.ScheduleEvent(INTRO_6, 5000);
- break;
- case INTRO_6:
- me->GetMotionMaster()->MovePoint(0, PosMove[1]);
- break;
- default:
- break;
+ switch (eventId)
+ {
+ case INTRO_1:
+ me->GetMotionMaster()->MovePath(KIRTONOS_PATH, false);
+ break;
+ case INTRO_2:
+ me->GetMotionMaster()->MovePoint(0, PosMove[0]);
+ events.ScheduleEvent(INTRO_3, 1000);
+ break;
+ case INTRO_3:
+ if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_GATE_KIRTONOS)))
+ gate->SetGoState(GO_STATE_READY);
+ me->SetFacingTo(0.01745329f);
+ events.ScheduleEvent(INTRO_4, 3000);
+ break;
+ case INTRO_4:
+ if (GameObject* brazier = me->GetMap()->GetGameObject(instance->GetData64(GO_BRAZIER_OF_THE_HERALD)))
+ brazier->SetGoState(GO_STATE_READY);
+ me->SetWalk(true);
+ me->SetDisableGravity(false);
+ DoCast(me, SPELL_KIRTONOS_TRANSFORM);
+ me->SetCanFly(false);
+ events.ScheduleEvent(INTRO_5, 1000);
+ break;
+ case INTRO_5:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
+ me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_KIRTONOS_STAFF));
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ events.ScheduleEvent(INTRO_6, 5000);
+ break;
+ case INTRO_6:
+ me->GetMotionMaster()->MovePoint(0, PosMove[1]);
+ break;
+ default:
+ break;
+ }
}
- }
- if (!UpdateVictim())
return;
+ }
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
index 630c379e71e..87a09749724 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
@@ -773,7 +773,7 @@ public:
void JustSummoned(Creature* summon)
{
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30, true);
- if (target && summon)
+ if (target)
summon->Attack(target, false);
summons.Summon(summon);
}
diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp
index aec78581514..397d20e92f9 100644
--- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp
+++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_ayamiss.cpp
@@ -34,13 +34,13 @@ enum Spells
enum Events
{
- EVENT_STINGER_SPRAY = 0,
- EVENT_POISON_STINGER = 1,
- EVENT_SUMMON_SWARMER = 2,
- EVENT_SWARMER_ATTACK = 3,
- EVENT_PARALYZE = 4,
- EVENT_LASH = 5,
- EVENT_TRASH = 6
+ EVENT_STINGER_SPRAY = 1,
+ EVENT_POISON_STINGER = 2,
+ EVENT_SUMMON_SWARMER = 3,
+ EVENT_SWARMER_ATTACK = 4,
+ EVENT_PARALYZE = 5,
+ EVENT_LASH = 6,
+ EVENT_TRASH = 7
};
enum Emotes
diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp
index 0ad077aaa4e..5da6606f05f 100644
--- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp
+++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_buru.cpp
@@ -42,11 +42,11 @@ enum Spells
enum Events
{
- EVENT_DISMEMBER = 0,
- EVENT_GATHERING_SPEED = 1,
- EVENT_FULL_SPEED = 2,
- EVENT_CREEPING_PLAGUE = 3,
- EVENT_RESPAWN_EGG = 4
+ EVENT_DISMEMBER = 1,
+ EVENT_GATHERING_SPEED = 2,
+ EVENT_FULL_SPEED = 3,
+ EVENT_CREEPING_PLAGUE = 4,
+ EVENT_RESPAWN_EGG = 5
};
enum Phases
diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp
index 79bc0c5accf..901438409a4 100644
--- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp
+++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp
@@ -40,10 +40,10 @@ enum Spells
enum Events
{
- EVENT_ARCANE_EXPLOSION = 0,
- EVENT_FULLFILMENT = 1,
- EVENT_BLINK = 2,
- EVENT_EARTH_SHOCK = 3
+ EVENT_ARCANE_EXPLOSION = 1,
+ EVENT_FULLFILMENT = 2,
+ EVENT_BLINK = 3,
+ EVENT_EARTH_SHOCK = 4
};
uint32 const BlinkSpells[3] = { 4801, 8195, 20449 };
diff --git a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
index 318fccfb5b6..ed50f1a79f1 100644
--- a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
+++ b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
@@ -58,8 +58,8 @@ enum HauntingWitchHill
NPC_RISEN_SPIRIT = 23554,
// Events
- EVENT_CONSUME_FLESH = 0,
- EVENT_INTANGIBLE_PRESENCE = 1,
+ EVENT_CONSUME_FLESH = 1,
+ EVENT_INTANGIBLE_PRESENCE = 2,
};
class mobs_risen_husk_spirit : public CreatureScript
diff --git a/src/server/scripts/Kalimdor/zone_winterspring.cpp b/src/server/scripts/Kalimdor/zone_winterspring.cpp
index 2b68c0a2cb6..6458047bb60 100644
--- a/src/server/scripts/Kalimdor/zone_winterspring.cpp
+++ b/src/server/scripts/Kalimdor/zone_winterspring.cpp
@@ -154,14 +154,14 @@ struct DialogueEntry
class DialogueHelper
{
public:
- // The array MUST be terminated by {0,0,0}
+ // The array MUST be terminated by {0, 0, 0}
DialogueHelper(DialogueEntry const* dialogueArray) :
_dialogueArray(dialogueArray),
_currentEntry(NULL),
_actionTimer(0),
_isFirstSide(true)
{}
- // The array MUST be terminated by {0,0,0,0,0}
+ // The array MUST be terminated by {0, 0, 0, 0, 0}
/// Function to initialize the dialogue helper for instances. If not used with instances, GetSpeakerByEntry MUST be overwritten to obtain the speakers
/// Set if take first entries or second entries
@@ -182,9 +182,7 @@ public:
}
if (!found)
- {
return;
- }
DoNextDialogueStep();
}
@@ -210,7 +208,7 @@ private:
void DoNextDialogueStep()
{
// Last Dialogue Entry done?
- if (_currentEntry && !_currentEntry->TextEntry)
+ if (!_currentEntry || !_currentEntry->TextEntry)
{
_actionTimer = 0;
return;
@@ -400,7 +398,7 @@ public:
void WaypointReached(uint32 pointId)
{
- switch(pointId)
+ switch (pointId)
{
case 3:
Talk(SAY_ENTER_OWL_THICKET);
@@ -439,7 +437,7 @@ public:
SetEscortPaused(true);
DoSummonPriestess();
Talk(SAY_RANSHALLA_ALTAR_2);
- events.ScheduleEvent(EVENT_RESUME,2000);
+ events.ScheduleEvent(EVENT_RESUME, 2000);
break;
case 44:
// Stop the escort and turn towards the altar
diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt
index 1da1e4ab178..674c35836a2 100644
--- a/src/server/scripts/Northrend/CMakeLists.txt
+++ b/src/server/scripts/Northrend/CMakeLists.txt
@@ -26,7 +26,7 @@ set(scripts_STAT_SRCS
Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
Northrend/Ulduar/Ulduar/instance_ulduar.cpp
Northrend/Ulduar/Ulduar/boss_auriaya.cpp
- Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp
+ Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
Northrend/Ulduar/Ulduar/boss_hodir.cpp
Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp
Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
index a68ea1025d5..090ebbca69d 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp
@@ -149,6 +149,9 @@ class npc_announcer_toc10 : public CreatureScript
}
}
+ if (i >= NUM_MESSAGES)
+ return false;
+
player->SEND_GOSSIP_MENU(_GossipMessage[i].msgnum, creature->GetGUID());
return true;
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp
index 3e44fe9eba4..9e369fa83bb 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp
@@ -33,10 +33,10 @@ enum Spells
enum Events
{
- EVENT_BERSERK = 0,
- EVENT_CLOUD = 1,
- EVENT_INJECT = 2,
- EVENT_SPRAY = 3
+ EVENT_BERSERK = 1,
+ EVENT_CLOUD = 2,
+ EVENT_INJECT = 3,
+ EVENT_SPRAY = 4
};
enum CreatureId
@@ -46,7 +46,8 @@ enum CreatureId
class boss_grobbulus : public CreatureScript
{
-public: boss_grobbulus() : CreatureScript("boss_grobbulus") { }
+public:
+ boss_grobbulus() : CreatureScript("boss_grobbulus") { }
CreatureAI* GetAI(Creature* creature) const
{
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
index d861343116f..b85c24a22eb 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
@@ -754,7 +754,7 @@ public:
void UpdateAI(uint32 diff)
{
- if (!UpdateVictim() && _phase != PHASE_NOT_STARTED && _phase != PHASE_TWO)
+ if (!instance || (!UpdateVictim() && _phase != PHASE_NOT_STARTED && _phase != PHASE_TWO))
return;
events.Update(diff);
@@ -854,7 +854,7 @@ public:
}
}
- if (_arcaneReinforcements && instance)
+ if (_arcaneReinforcements)
{
for (uint8 rangeDisks = 0; rangeDisks < (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL ? 4 : 5); rangeDisks++)
{
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
index 1f8ba3edade..71ef0cbe3ce 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
@@ -110,103 +110,107 @@ class npc_verdisa_beglaristrasz_eternos : public CreatureScript
public:
npc_verdisa_beglaristrasz_eternos() : CreatureScript("npc_verdisa_beglaristrasz_eternos") { }
- InstanceScript* instance;
-
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
{
player->PlayerTalkClass->ClearMenus();
switch (creature->GetEntry())
{
- case NPC_VERDISA: //Verdisa
- switch (action)
+ case NPC_VERDISA: //Verdisa
{
- case GOSSIP_ACTION_INFO_DEF + 1:
- if (!HAS_ESSENCE(player))
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA1, creature->GetGUID());
- }
- else
+ switch (action)
{
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA2, creature->GetGUID());
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ if (!HAS_ESSENCE(player))
+ {
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA1, creature->GetGUID());
+ }
+ else
+ {
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_VERDISA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA2, creature->GetGUID());
+ }
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ {
+ ItemPosCountVec dest;
+ uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_EMERALD_ESSENCE, 1);
+ if (msg == EQUIP_ERR_OK)
+ player->StoreNewItem(dest, ITEM_EMERALD_ESSENCE, true);
+ player->CLOSE_GOSSIP_MENU();
+ break;
+ }
+ case GOSSIP_ACTION_INFO_DEF + 3:
+ player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA3, creature->GetGUID());
+ break;
}
break;
- case GOSSIP_ACTION_INFO_DEF + 2:
- {
- ItemPosCountVec dest;
- uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_EMERALD_ESSENCE, 1);
- if (msg == EQUIP_ERR_OK)
- player->StoreNewItem(dest, ITEM_EMERALD_ESSENCE, true);
- player->CLOSE_GOSSIP_MENU();
- break;
}
- case GOSSIP_ACTION_INFO_DEF + 3:
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_VERDISA3, creature->GetGUID());
- break;
- }
- break;
- case NPC_BELGARISTRASZ: //Belgaristrasz
- switch (action)
+ case NPC_BELGARISTRASZ: //Belgaristrasz
{
- case GOSSIP_ACTION_INFO_DEF + 1:
- if (!HAS_ESSENCE(player))
+ switch (action)
{
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ1, creature->GetGUID());
- }
- else
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ2, creature->GetGUID());
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ if (!HAS_ESSENCE(player))
+ {
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ1, creature->GetGUID());
+ }
+ else
+ {
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BELGARISTRASZ2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ2, creature->GetGUID());
+ }
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ {
+ ItemPosCountVec dest;
+ uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_RUBY_ESSENCE, 1);
+ if (msg == EQUIP_ERR_OK)
+ player->StoreNewItem(dest, ITEM_RUBY_ESSENCE, true);
+ player->CLOSE_GOSSIP_MENU();
+ break;
+ }
+ case GOSSIP_ACTION_INFO_DEF + 3:
+ player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ3, creature->GetGUID());
+ break;
}
break;
- case GOSSIP_ACTION_INFO_DEF + 2:
- {
- ItemPosCountVec dest;
- uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_RUBY_ESSENCE, 1);
- if (msg == EQUIP_ERR_OK)
- player->StoreNewItem(dest, ITEM_RUBY_ESSENCE, true);
- player->CLOSE_GOSSIP_MENU();
- break;
- }
- case GOSSIP_ACTION_INFO_DEF + 3:
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_BELGARISTRASZ3, creature->GetGUID());
- break;
}
- break;
- case NPC_ETERNOS: //Eternos
- switch (action)
+ case NPC_ETERNOS: //Eternos
{
- case GOSSIP_ACTION_INFO_DEF + 1:
- if (!HAS_ESSENCE(player))
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS1, creature->GetGUID());
- }
- else
+ switch (action)
{
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS2, creature->GetGUID());
+ case GOSSIP_ACTION_INFO_DEF + 1:
+ if (!HAS_ESSENCE(player))
+ {
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS1, creature->GetGUID());
+ }
+ else
+ {
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ETERNOS2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
+ player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS2, creature->GetGUID());
+ }
+ break;
+ case GOSSIP_ACTION_INFO_DEF + 2:
+ {
+ ItemPosCountVec dest;
+ uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_AMBER_ESSENCE, 1);
+ if (msg == EQUIP_ERR_OK)
+ player->StoreNewItem(dest, ITEM_AMBER_ESSENCE, true);
+ player->CLOSE_GOSSIP_MENU();
+ break;
+ }
+ case GOSSIP_ACTION_INFO_DEF + 3:
+ player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS3, creature->GetGUID());
+ break;
}
break;
- case GOSSIP_ACTION_INFO_DEF + 2:
- {
- ItemPosCountVec dest;
- uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_AMBER_ESSENCE, 1);
- if (msg == EQUIP_ERR_OK)
- player->StoreNewItem(dest, ITEM_AMBER_ESSENCE, true);
- player->CLOSE_GOSSIP_MENU();
- break;
- }
- case GOSSIP_ACTION_INFO_DEF + 3:
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ETERNOS3, creature->GetGUID());
- break;
}
- break;
}
return true;
@@ -235,15 +239,15 @@ public:
void MovementInform(uint32 /*type*/, uint32 id)
{
+ if (id)
+ return;
+
// When Belgaristraz finish his moving say grateful text
if (me->GetEntry() == NPC_BELGARISTRASZ)
- if (id == 0)
- {
- Talk(SAY_BELGARISTRASZ);
- }
+ Talk(SAY_BELGARISTRASZ);
+
// The gossip flag should activate when Drakos die and not from DB
- if (id == 0)
- me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
};
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
new file mode 100644
index 00000000000..105b4757066
--- /dev/null
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yogg_saron.cpp
@@ -0,0 +1,3221 @@
+/*
+ * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "PassiveAI.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
+#include "MoveSplineInit.h"
+#include "CreatureTextMgr.h"
+#include "ulduar.h"
+
+enum Yells
+{
+ // Sara
+ SAY_SARA_ULDUAR_SCREAM_1 = 0, // screams randomly in a whole instance, unused on retail
+ SAY_SARA_ULDUAR_SCREAM_2 = 1, // screams randomly in a whole instance, unused on retail
+ SAY_SARA_AGGRO = 2,
+ SAY_SARA_FERVOR_HIT = 3,
+ SAY_SARA_BLESSING_HIT = 4,
+ SAY_SARA_KILL = 5,
+ SAY_SARA_TRANSFORM_1 = 6,
+ SAY_SARA_TRANSFORM_2 = 7,
+ SAY_SARA_TRANSFORM_3 = 8,
+ SAY_SARA_TRANSFORM_4 = 9,
+ SAY_SARA_DEATH_RAY = 10,
+ SAY_SARA_PSYCHOSIS_HIT = 11,
+
+ // Yogg-Saron
+ SAY_YOGG_SARON_SPAWN = 0,
+ SAY_YOGG_SARON_MADNESS = 1,
+ EMOTE_YOGG_SARON_MADNESS = 2,
+ SAY_YOGG_SARON_PHASE_3 = 3,
+ SAY_YOGG_SARON_DEAFENING_ROAR = 4,
+ EMOTE_YOGG_SARON_DEAFENING_ROAR = 5,
+ SAY_YOGG_SARON_DEATH = 6,
+ EMOTE_YOGG_SARON_EMPOWERING_SHADOWS = 7,
+ EMOTE_YOGG_SARON_EXTINGUISH_ALL_LIFE = 8,
+
+ // Voice of Yogg-Saron
+ WHISPER_VOICE_PHASE_1_WIPE = 0,
+ WHISPER_VOICE_INSANE = 1,
+
+ // Brain of Yogg-Saron
+ EMOTE_BRAIN_ILLUSION_SHATTERED = 0,
+
+ // Ominous Cloud
+ EMOTE_OMINOUS_CLOUD_PLAYER_TOUCH = 0,
+
+ // Keepers
+ SAY_KEEPER_CHOSEN_1 = 0,
+ SAY_KEEPER_CHOSEN_2 = 1,
+
+ // Yogg-Saron illusions
+ SAY_STORMWIND_ROLEPLAY_4 = 0,
+ SAY_STORMWIND_ROLEPLAY_7 = 1,
+ SAY_ICECROWN_ROLEPLAY_5 = 2,
+ SAY_ICECROWN_ROLEPLAY_6 = 3,
+ SAY_CHAMBER_ROLEPLAY_5 = 4,
+
+ // Neltharion
+ SAY_CHAMBER_ROLEPLAY_1 = 0,
+ SAY_CHAMBER_ROLEPLAY_3 = 1,
+
+ // Ysera
+ SAY_CHAMBER_ROLEPLAY_2 = 0,
+
+ // Malygos
+ SAY_CHAMBER_ROLEPLAY_4 = 0,
+
+ // Immolated Champion
+ SAY_ICECROWN_ROLEPLAY_1 = 0,
+ SAY_ICECROWN_ROLEPLAY_3 = 1,
+
+ // The Lich King
+ SAY_ICECROWN_ROLEPLAY_2 = 0,
+ SAY_ICECROWN_ROLEPLAY_4 = 1,
+
+ // Garona
+ SAY_STORMWIND_ROLEPLAY_1 = 0,
+ SAY_STORMWIND_ROLEPLAY_2 = 1,
+ SAY_STORMWIND_ROLEPLAY_3 = 2,
+ SAY_STORMWIND_ROLEPLAY_6 = 3,
+
+ // King Llane
+ SAY_STORMWIND_ROLEPLAY_5 = 0,
+};
+
+enum Spells
+{
+ // Voice of Yogg-Saron
+ SPELL_SUMMON_GUARDIAN_2 = 62978,
+ SPELL_SANITY_PERIODIC = 63786,
+ SPELL_SANITY = 63050,
+ SPELL_INSANE_PERIODIC = 64554,
+ SPELL_INSANE = 63120,
+ //SPELL_CLEAR_INSANE = 63122, // when it should be casted?
+ SPELL_CONSTRICTOR_TENTACLE = 64132,
+ SPELL_CRUSHER_TENTACLE_SUMMON = 64139,
+ SPELL_CORRUPTOR_TENTACLE_SUMMON = 64143,
+ SPELL_IMMORTAL_GUARDIAN = 64158,
+
+ // Sara
+ SPELL_SARAS_FERVOR = 63138,
+ SPELL_SARAS_FERVOR_TARGET_SELECTOR = 63747,
+ SPELL_SARAS_BLESSING = 63134,
+ SPELL_SARAS_BLESSING_TARGET_SELECTOR = 63745,
+ SPELL_SARAS_ANGER = 63147,
+ SPELL_SARAS_ANGER_TARGET_SELECTOR = 63744,
+ SPELL_FULL_HEAL = 43978,
+ SPELL_PHASE_2_TRANSFORM = 65157,
+ SPELL_SHADOWY_BARRIER_SARA = 64775,
+ SPELL_RIDE_YOGG_SARON_VEHICLE = 61791,
+ SPELL_PSYCHOSIS = 63795,
+ SPELL_MALADY_OF_THE_MIND = 63830,
+ SPELL_BRAIN_LINK = 63802,
+ SPELL_BRAIN_LINK_DAMAGE = 63803, // red beam
+ SPELL_BRAIN_LINK_NO_DAMAGE = 63804, // yellow beam
+ SPELL_DEATH_RAY = 63891,
+
+ // Ominous Cloud
+ SPELL_OMINOUS_CLOUD_VISUAL = 63084,
+ SPELL_SUMMON_GUARDIAN_1 = 63031,
+
+ // Guardian of Yogg-Saron
+ SPELL_DARK_VOLLEY = 63038,
+ SPELL_SHADOW_NOVA = 62714,
+ SPELL_SHADOW_NOVA_2 = 65719,
+
+ // Yogg-Saron
+ SPELL_EXTINGUISH_ALL_LIFE = 64166,
+ SPELL_SHADOWY_BARRIER_YOGG = 63894,
+ SPELL_KNOCK_AWAY = 64022,
+ SPELL_PHASE_3_TRANSFORM = 63895,
+ SPELL_DEAFENING_ROAR = 64189,
+ SPELL_LUNATIC_GAZE = 64163,
+ SPELL_LUNATIC_GAZE_DAMAGE = 64164,
+ SPELL_SHADOW_BEACON = 64465,
+
+ // Brain of Yogg-Saron
+ SPELL_MATCH_HEALTH = 64066,
+ SPELL_MATCH_HEALTH_2 = 64069,
+ SPELL_INDUCE_MADNESS = 64059,
+ SPELL_BRAIN_HURT_VISUAL = 64361,
+ SPELL_SHATTERED_ILLUSION = 64173,
+ SPELL_SHATTERED_ILLUSION_REMOVE = 65238,
+
+ // Tentacles
+ SPELL_ERUPT = 64144,
+ SPELL_TENTACLE_VOID_ZONE = 64017, // used by Corruptor Tentacle and Crusher Tentacle only
+
+ // Crusher Tentacle
+ SPELL_DIMINISH_POWER = 64145,
+ SPELL_DIMINSH_POWER = 64148,
+ SPELL_FOCUSED_ANGER = 57688,
+ SPELL_CRUSH = 64146,
+ //SPELL_CRUSH_2 = 65201, // triggered by SPELL_CRUSH, basepoints of SPELL_MALADY_OF_THE_MIND
+
+ // Constrictor Tentacle
+ SPELL_TENTACLE_VOID_ZONE_2 = 64384,
+ SPELL_LUNGE = 64131,
+
+ // Corruptor Tentacle
+ SPELL_APATHY = 64156,
+ SPELL_BLACK_PLAGUE = 64153,
+ SPELL_CURSE_OF_DOOM = 64157,
+ SPELL_DRAINING_POISON = 64152,
+
+ // Immortal Guardian
+ SPELL_EMPOWERING_SHADOWS = 64468,
+ SPELL_EMPOWERED = 64161,
+ SPELL_EMPOWERED_BUFF = 65294,
+ SPELL_WEAKENED = 64162,
+ SPELL_DRAIN_LIFE = 64159,
+ SPELL_RECENTLY_SPAWNED = 64497,
+ SPELL_SIMPLE_TELEPORT = 64195,
+
+ // Keepers at Observation Ring
+ SPELL_TELEPORT = 62940,
+
+ // Keepers
+ SPELL_SIMPLE_TELEPORT_KEEPERS = 12980,
+ SPELL_KEEPER_ACTIVE = 62647,
+
+ // Mimiron
+ SPELL_SPEED_OF_INVENTION = 62671,
+ SPELL_DESTABILIZATION_MATRIX = 65206,
+
+ // Freya
+ SPELL_RESILIENCE_OF_NATURE = 62670,
+ SPELL_SANITY_WELL_SUMMON = 64170,
+
+ // Sanity Well
+ SPELL_SANITY_WELL_VISUAL = 63288,
+ SPELL_SANITY_WELL = 64169,
+
+ // Thorim
+ SPELL_FURY_OF_THE_STORM = 62702,
+ SPELL_TITANIC_STORM = 64171,
+
+ // Hodir
+ SPELL_FORTITUDE_OF_FROST = 62650,
+ SPELL_HODIRS_PROTECTIVE_GAZE = 64174,
+ SPELL_FLASH_FREEZE_VISUAL = 64176,
+
+ // Death Orb
+ SPELL_DEATH_RAY_ORIGIN_VISUAL = 63893,
+
+ // Death Ray
+ SPELL_DEATH_RAY_WARNING_VISUAL = 63882,
+ SPELL_DEATH_RAY_PERIODIC = 63883,
+ SPELL_DEATH_RAY_DAMAGE_VISUAL = 63886,
+
+ // Laughing Skull
+ SPELL_LUNATIC_GAZE_SKULL = 64167,
+
+ // Descend Into Madness
+ SPELL_TELEPORT_PORTAL_VISUAL = 64416,
+
+ // Illusions
+ SPELL_GRIM_REPRISAL = 63305,
+ SPELL_GRIM_REPRISAL_DAMAGE = 64039,
+
+ // Suit of Armor
+ SPELL_NONDESCRIPT_1 = 64013,
+
+ // Dragon Consorts & Deathsworn Zealot
+ SPELL_NONDESCRIPT_2 = 64010,
+
+ // Garona
+ SPELL_ASSASSINATE = 64063,
+
+ // King Llane
+ SPELL_PERMANENT_FEIGN_DEATH = 29266,
+
+ // The Lich King
+ SPELL_DEATHGRASP = 63037,
+
+ // Turned Champion
+ SPELL_VERTEX_COLOR_BLACK = 39662,
+
+ // Player self cast spells
+ SPELL_MALADY_OF_THE_MIND_JUMP = 63881,
+ SPELL_ILLUSION_ROOM = 63988,
+ SPELL_HATE_TO_ZERO = 63984,
+ SPELL_TELEPORT_BACK_TO_MAIN_ROOM = 63992,
+ SPELL_INSANE_VISUAL = 64464,
+ SPELL_CONSTRICTOR_TENTACLE_SUMMON = 64133,
+ SPELL_SQUEEZE = 64125,
+ SPELL_FLASH_FREEZE = 64175,
+ SPELL_LOW_SANITY_SCREEN_EFFECT = 63752,
+
+ SPELL_IN_THE_MAWS_OF_THE_OLD_GOD = 64184,
+};
+
+enum Phases
+{
+ PHASE_ONE = 1,
+ PHASE_TRANSFORM = 2,
+ PHASE_TWO = 3,
+ PHASE_THREE = 4,
+};
+
+enum Events
+{
+ // Voice of Yogg-Saron
+ EVENT_LOCK_DOOR = 1,
+ EVENT_SUMMON_GUARDIAN_OF_YOGG_SARON = 2,
+ EVENT_SUMMON_CORRUPTOR_TENTACLE = 3,
+ EVENT_SUMMON_CONSTRICTOR_TENTACLE = 4,
+ EVENT_SUMMON_CRUSHER_TENTACLE = 5,
+ EVENT_ILLUSION = 6,
+ EVENT_SUMMON_IMMORTAL_GUARDIAN = 7,
+ EVENT_EXTINGUISH_ALL_LIFE = 8, // handled by Voice, timer starts at the beginning of the fight (Yogg-Saron is not spawned at this moment)
+
+ // Sara
+ EVENT_SARAS_FERVOR = 9,
+ EVENT_SARAS_BLESSING = 10,
+ EVENT_SARAS_ANGER = 11,
+ EVENT_TRANSFORM_1 = 12,
+ EVENT_TRANSFORM_2 = 13,
+ EVENT_TRANSFORM_3 = 14,
+ EVENT_TRANSFORM_4 = 15,
+ EVENT_PSYCHOSIS = 16,
+ EVENT_MALADY_OF_THE_MIND = 17,
+ EVENT_BRAIN_LINK = 18,
+ EVENT_DEATH_RAY = 19,
+
+ // Tentacles
+ EVENT_DIMINISH_POWER = 20,
+ EVENT_CAST_RANDOM_SPELL = 21,
+
+ // Yogg-Saron
+ EVENT_YELL_BOW_DOWN = 22,
+ EVENT_SHADOW_BEACON = 23,
+ EVENT_LUNATIC_GAZE = 24,
+ EVENT_DEAFENING_ROAR = 25, // only on 25-man with 0-3 keepers active (Hard Mode)
+
+ // Guardian of Yogg-Saron
+ EVENT_DARK_VOLLEY = 26,
+
+ // Immortal Guardian
+ EVENT_DRAIN_LIFE = 27,
+
+ // Keepers
+ EVENT_DESTABILIZATION_MATRIX = 28,
+ EVENT_HODIRS_PROTECTIVE_GAZE = 29,
+
+ // Chamber Illusion
+ EVENT_CHAMBER_ROLEPLAY_1 = 30,
+ EVENT_CHAMBER_ROLEPLAY_2 = 31,
+ EVENT_CHAMBER_ROLEPLAY_3 = 32,
+ EVENT_CHAMBER_ROLEPLAY_4 = 33,
+ EVENT_CHAMBER_ROLEPLAY_5 = 34,
+
+ // Icecrown Illusion
+ EVENT_ICECROWN_ROLEPLAY_1 = 35,
+ EVENT_ICECROWN_ROLEPLAY_2 = 36,
+ EVENT_ICECROWN_ROLEPLAY_3 = 37,
+ EVENT_ICECROWN_ROLEPLAY_4 = 38,
+ EVENT_ICECROWN_ROLEPLAY_5 = 39,
+ EVENT_ICECROWN_ROLEPLAY_6 = 40,
+
+ // Stormwind Illusion
+ EVENT_STORMWIND_ROLEPLAY_1 = 41,
+ EVENT_STORMWIND_ROLEPLAY_2 = 42,
+ EVENT_STORMWIND_ROLEPLAY_3 = 43,
+ EVENT_STORMWIND_ROLEPLAY_4 = 44,
+ EVENT_STORMWIND_ROLEPLAY_5 = 45,
+ EVENT_STORMWIND_ROLEPLAY_6 = 46,
+ EVENT_STORMWIND_ROLEPLAY_7 = 47,
+};
+
+enum EventGroups
+{
+ EVENT_GROUP_SUMMON_TENTACLES = 1,
+};
+
+enum Actions
+{
+ ACTION_PHASE_TRANSFORM = 0,
+ ACTION_PHASE_TWO = 1,
+ ACTION_PHASE_THREE = 2,
+ ACTION_INDUCE_MADNESS = 3,
+ ACTION_SANITY_WELLS = 4,
+ ACTION_FLASH_FREEZE = 5,
+ ACTION_TENTACLE_KILLED = 6,
+ ACTION_START_ROLEPLAY = 8,
+ ACTION_TOGGLE_SHATTERED_ILLUSION = 9,
+};
+
+enum CreatureGroups
+{
+ CREATURE_GROUP_CLOUDS = 0,
+ CREATURE_GROUP_PORTALS_10 = 1,
+ CREATURE_GROUP_PORTALS_25 = 2,
+};
+
+Position const YoggSaronSpawnPos = {1980.43f, -25.7708f, 324.9724f, 3.141593f};
+Position const ObservationRingKeepersPos[4] =
+{
+ {1945.682f, 33.34201f, 411.4408f, 5.270895f}, // Freya
+ {1945.761f, -81.52171f, 411.4407f, 1.029744f}, // Hodir
+ {2028.822f, -65.73573f, 411.4426f, 2.460914f}, // Thorim
+ {2028.766f, 17.42014f, 411.4446f, 3.857178f}, // Mimiron
+};
+Position const YSKeepersPos[4] =
+{
+ {2036.873f, 25.42513f, 338.4984f, 3.909538f}, // Freya
+ {1939.045f, -90.87457f, 338.5426f, 0.994837f}, // Hodir
+ {1939.148f, 42.49035f, 338.5427f, 5.235988f}, // Thorim
+ {2036.658f, -73.58822f, 338.4985f, 2.460914f}, // Mimiron
+};
+Position const IllusionsMiscPos[2] =
+{
+ {1928.793f, 65.03109f, 242.3763f, 0.0f}, // Garona end position
+ {1912.324f, -155.7967f, 239.9896f, 0.0f}, // Saurfang end position
+};
+
+enum MiscData
+{
+ ACHIEV_TIMED_START_EVENT = 21001,
+ SOUND_LUNATIC_GAZE = 15757,
+};
+
+class StartAttackEvent : public BasicEvent
+{
+ public:
+ StartAttackEvent(Creature* summoner, Creature* owner)
+ : _summoner(summoner), _owner(owner)
+ {
+ }
+
+ bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ {
+ _owner->SetReactState(REACT_AGGRESSIVE);
+ if (Unit* target = _summoner->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 300.0f))
+ _owner->AI()->AttackStart(target);
+ return true;
+ }
+
+ private:
+ Creature* _summoner;
+ Creature* _owner;
+};
+
+class boss_voice_of_yogg_saron : public CreatureScript
+{
+ public:
+ boss_voice_of_yogg_saron() : CreatureScript("boss_voice_of_yogg_saron") { }
+
+ struct boss_voice_of_yogg_saronAI : public BossAI
+ {
+ boss_voice_of_yogg_saronAI(Creature* creature) : BossAI(creature, BOSS_YOGG_SARON)
+ {
+ SetCombatMovement(false);
+ }
+
+ void MoveInLineOfSight(Unit* who)
+ {
+ // TODO: MoveInLineOfSight doesn't work for such a big distance
+ if (who->GetTypeId() == TYPEID_PLAYER && me->GetDistance2d(who) < 99.0f && !me->isInCombat())
+ me->SetInCombatWithZone();
+ }
+
+ void EnterEvadeMode()
+ {
+ BossAI::EnterEvadeMode();
+
+ for (uint8 i = DATA_SARA; i <= DATA_MIMIRON_YS; ++i)
+ if (Creature* creature = ObjectAccessor::GetCreature(*me, instance->GetData64(i)))
+ creature->AI()->EnterEvadeMode();
+
+ // not sure, spoken by Sara (sound), regarding to wowwiki Voice whispers it
+ Map::PlayerList const& players = me->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ if (Player* player = itr->getSource())
+ {
+ if (events.IsInPhase(PHASE_ONE))
+ Talk(WHISPER_VOICE_PHASE_1_WIPE, player->GetGUID());
+
+ player->RemoveAurasDueToSpell(SPELL_SANITY);
+ player->RemoveAurasDueToSpell(SPELL_INSANE);
+ }
+ }
+
+ void Reset()
+ {
+ _Reset();
+ events.SetPhase(PHASE_ONE);
+
+ instance->SetData(DATA_DRIVE_ME_CRAZY, uint32(true));
+ instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+
+ _guardiansCount = 0;
+ _guardianTimer = 20000;
+ _illusionShattered = false;
+
+ bool clockwise = false;
+ std::list<TempSummon*> clouds;
+ me->SummonCreatureGroup(CREATURE_GROUP_CLOUDS, &clouds);
+ clouds.sort(Trinity::ObjectDistanceOrderPred(me, true));
+ for (std::list<TempSummon*>::const_iterator itr = clouds.begin(); itr != clouds.end(); ++itr)
+ {
+ (*itr)->AI()->DoAction(int32(clockwise));
+ clockwise = !clockwise;
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ if (Creature* sara = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_SARA)))
+ sara->SetInCombatWith(me);
+
+ for (uint8 i = DATA_FREYA_YS; i <= DATA_MIMIRON_YS; ++i)
+ if (Creature* keeper = ObjectAccessor::GetCreature(*me, instance->GetData64(i)))
+ keeper->SetInCombatWith(me);
+
+ instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
+
+ me->CastCustomSpell(SPELL_SUMMON_GUARDIAN_2, SPELLVALUE_MAX_TARGETS, 1);
+ DoCast(me, SPELL_SANITY_PERIODIC);
+
+ events.ScheduleEvent(EVENT_LOCK_DOOR, 15000);
+ events.ScheduleEvent(EVENT_SUMMON_GUARDIAN_OF_YOGG_SARON, _guardianTimer, 0, PHASE_ONE);
+ events.ScheduleEvent(EVENT_EXTINGUISH_ALL_LIFE, 900000); // 15 minutes
+ }
+
+ void JustDied(Unit* killer)
+ {
+ // don't despawn Yogg-Saron's corpse, remove him from SummonList!
+ if (Creature* yogg = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_YOGG_SARON)))
+ summons.Despawn(yogg);
+
+ BossAI::JustDied(killer);
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+ // don't summon tentacles when illusion is shattered, delay them
+ if (_illusionShattered)
+ events.DelayEvents(diff, EVENT_GROUP_SUMMON_TENTACLES);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_LOCK_DOOR:
+ DoCast(me, SPELL_INSANE_PERIODIC);
+ instance->SetBossState(BOSS_YOGG_SARON, IN_PROGRESS);
+ break;
+ case EVENT_EXTINGUISH_ALL_LIFE:
+ if (Creature* yogg = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_YOGG_SARON)))
+ {
+ yogg->AI()->Talk(EMOTE_YOGG_SARON_EXTINGUISH_ALL_LIFE, me->GetGUID());
+ yogg->CastSpell((Unit*)NULL, SPELL_EXTINGUISH_ALL_LIFE, true);
+ }
+ events.ScheduleEvent(EVENT_EXTINGUISH_ALL_LIFE, 10000); // cast it again after a short while, players can survive
+ break;
+ case EVENT_SUMMON_GUARDIAN_OF_YOGG_SARON:
+ me->CastCustomSpell(SPELL_SUMMON_GUARDIAN_2, SPELLVALUE_MAX_TARGETS, 1);
+ ++_guardiansCount;
+ if (_guardiansCount <= 6 && _guardiansCount % 3 == 0)
+ _guardianTimer -= 5000;
+ events.ScheduleEvent(EVENT_SUMMON_GUARDIAN_OF_YOGG_SARON, _guardianTimer, 0, PHASE_ONE);
+ break;
+ case EVENT_SUMMON_CORRUPTOR_TENTACLE:
+ DoCastAOE(SPELL_CORRUPTOR_TENTACLE_SUMMON);
+ events.ScheduleEvent(EVENT_SUMMON_CORRUPTOR_TENTACLE, 30000, EVENT_GROUP_SUMMON_TENTACLES, PHASE_TWO);
+ break;
+ case EVENT_SUMMON_CONSTRICTOR_TENTACLE:
+ me->CastCustomSpell(SPELL_CONSTRICTOR_TENTACLE, SPELLVALUE_MAX_TARGETS, 1);
+ events.ScheduleEvent(EVENT_SUMMON_CONSTRICTOR_TENTACLE, 25000, EVENT_GROUP_SUMMON_TENTACLES, PHASE_TWO);
+ break;
+ case EVENT_SUMMON_CRUSHER_TENTACLE:
+ DoCastAOE(SPELL_CRUSHER_TENTACLE_SUMMON);
+ events.ScheduleEvent(EVENT_SUMMON_CRUSHER_TENTACLE, 60000, EVENT_GROUP_SUMMON_TENTACLES, PHASE_TWO);
+ break;
+ case EVENT_ILLUSION:
+ {
+ if (Creature* yogg = ObjectAccessor::GetCreature(*me, instance->GetData64(BOSS_YOGG_SARON)))
+ {
+ yogg->AI()->Talk(EMOTE_YOGG_SARON_MADNESS);
+ yogg->AI()->Talk(SAY_YOGG_SARON_MADNESS);
+ }
+
+ me->SummonCreatureGroup(CREATURE_GROUP_PORTALS_10);
+ if (me->GetMap()->Is25ManRaid())
+ me->SummonCreatureGroup(CREATURE_GROUP_PORTALS_25);
+
+ uint8 illusion = urand(CHAMBER_ILLUSION, STORMWIND_ILLUSION);
+ instance->SetData(DATA_ILLUSION, illusion);
+
+ if (Creature* brain = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_BRAIN_OF_YOGG_SARON)))
+ brain->AI()->DoAction(ACTION_INDUCE_MADNESS);
+ events.ScheduleEvent(EVENT_ILLUSION, 80000, 0, PHASE_TWO); // wowwiki says 80 secs, wowhead says something about 90 secs
+ break;
+ }
+ case EVENT_SUMMON_IMMORTAL_GUARDIAN:
+ DoCastAOE(SPELL_IMMORTAL_GUARDIAN);
+ events.ScheduleEvent(EVENT_SUMMON_IMMORTAL_GUARDIAN, 15000, 0, PHASE_THREE);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ void DoAction(int32 action)
+ {
+ switch (action)
+ {
+ case ACTION_PHASE_TRANSFORM:
+ events.SetPhase(PHASE_TRANSFORM);
+ summons.DespawnEntry(NPC_OMINOUS_CLOUD);
+ break;
+ case ACTION_PHASE_TWO:
+ events.SetPhase(PHASE_TWO);
+ me->SummonCreature(NPC_YOGG_SARON, YoggSaronSpawnPos);
+ if (Creature* brain = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_BRAIN_OF_YOGG_SARON)))
+ brain->SetInCombatWithZone();
+ events.ScheduleEvent(EVENT_SUMMON_CORRUPTOR_TENTACLE, 1, EVENT_GROUP_SUMMON_TENTACLES, PHASE_TWO);
+ events.ScheduleEvent(EVENT_SUMMON_CONSTRICTOR_TENTACLE, 1, EVENT_GROUP_SUMMON_TENTACLES, PHASE_TWO);
+ events.ScheduleEvent(EVENT_SUMMON_CRUSHER_TENTACLE, 1, EVENT_GROUP_SUMMON_TENTACLES, PHASE_TWO);
+ events.ScheduleEvent(EVENT_ILLUSION, 60000, 0, PHASE_TWO);
+ break;
+ case ACTION_TOGGLE_SHATTERED_ILLUSION:
+ _illusionShattered = !_illusionShattered;
+ break;
+ case ACTION_PHASE_THREE:
+ events.SetPhase(PHASE_THREE);
+ events.ScheduleEvent(EVENT_SUMMON_IMMORTAL_GUARDIAN, 1000, 0, PHASE_THREE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ switch (summon->GetEntry())
+ {
+ case NPC_GUARDIAN_OF_YOGG_SARON:
+ summon->m_Events.AddEvent(new StartAttackEvent(me, summon), summon->m_Events.CalculateTime(1000));
+ break;
+ case NPC_YOGG_SARON:
+ summon->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
+ break;
+ case NPC_CONSTRICTOR_TENTACLE:
+ summon->CastSpell(summon, SPELL_LUNGE, true);
+ break;
+ case NPC_CRUSHER_TENTACLE:
+ case NPC_CORRUPTOR_TENTACLE:
+ summon->SetReactState(REACT_PASSIVE);
+ summon->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
+ summon->m_Events.AddEvent(new StartAttackEvent(me, summon), summon->m_Events.CalculateTime(5000));
+ break;
+ case NPC_DESCEND_INTO_MADNESS:
+ summon->CastSpell(summon, SPELL_TELEPORT_PORTAL_VISUAL, true);
+ break;
+ case NPC_IMMORTAL_GUARDIAN:
+ summon->CastSpell(summon, SPELL_SIMPLE_TELEPORT, true);
+ break;
+ }
+
+ BossAI::JustSummoned(summon);
+ }
+
+ private:
+ uint8 _guardiansCount;
+ uint32 _guardianTimer;
+ bool _illusionShattered;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<boss_voice_of_yogg_saronAI>(creature);
+ }
+};
+
+class boss_sara : public CreatureScript
+{
+ public:
+ boss_sara() : CreatureScript("boss_sara") { }
+
+ struct boss_saraAI : public ScriptedAI
+ {
+ boss_saraAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
+
+ uint64 GetLinkedPlayerGUID(uint64 guid) const
+ {
+ std::map<uint64, uint64>::const_iterator itr = _linkData.find(guid);
+ if (itr != _linkData.end())
+ return itr->second;
+
+ return 0;
+ }
+
+ void SetLinkBetween(uint64 player1, uint64 player2)
+ {
+ _linkData[player1] = player2;
+ _linkData[player2] = player1;
+ }
+
+ // called once for each target on aura remove
+ void RemoveLinkFrom(uint64 player1)
+ {
+ _linkData.erase(player1);
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage)
+ {
+ if (_events.IsInPhase(PHASE_ONE) && damage >= me->GetHealth())
+ {
+ damage = 0;
+
+ if (Creature* voice = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VOICE_OF_YOGG_SARON)))
+ voice->AI()->DoAction(ACTION_PHASE_TRANSFORM);
+
+ Talk(SAY_SARA_TRANSFORM_1);
+ _events.SetPhase(PHASE_TRANSFORM);
+ _events.ScheduleEvent(EVENT_TRANSFORM_1, 4700, 0, PHASE_TRANSFORM);
+ _events.ScheduleEvent(EVENT_TRANSFORM_2, 9500, 0, PHASE_TRANSFORM);
+ _events.ScheduleEvent(EVENT_TRANSFORM_3, 14300, 0, PHASE_TRANSFORM);
+ _events.ScheduleEvent(EVENT_TRANSFORM_4, 14500, 0, PHASE_TRANSFORM);
+ }
+ }
+
+ void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell)
+ {
+ if (!roll_chance_i(30) || _events.IsInPhase(PHASE_TRANSFORM))
+ return;
+
+ switch (spell->Id)
+ {
+ case SPELL_SARAS_FERVOR:
+ Talk(SAY_SARA_FERVOR_HIT);
+ break;
+ case SPELL_SARAS_BLESSING:
+ Talk(SAY_SARA_BLESSING_HIT);
+ break;
+ case SPELL_PSYCHOSIS:
+ Talk(SAY_SARA_PSYCHOSIS_HIT);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void KilledUnit(Unit* victim)
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER && !me->IsInEvadeMode())
+ Talk(SAY_SARA_KILL);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ Talk(SAY_SARA_AGGRO);
+ _events.ScheduleEvent(EVENT_SARAS_FERVOR, 5000, 0, PHASE_ONE);
+ _events.ScheduleEvent(EVENT_SARAS_BLESSING, urand(10000, 30000), 0, PHASE_ONE);
+ _events.ScheduleEvent(EVENT_SARAS_ANGER, urand(15000, 25000), 0, PHASE_ONE);
+ }
+
+ void Reset()
+ {
+ me->RemoveAllAuras();
+ me->SetReactState(REACT_PASSIVE);
+ me->setFaction(35);
+ _events.Reset();
+ _events.SetPhase(PHASE_ONE);
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ if (!me->isInCombat())
+ return;
+
+ if (me->HasAura(SPELL_SHATTERED_ILLUSION))
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SARAS_FERVOR:
+ me->CastCustomSpell(SPELL_SARAS_FERVOR_TARGET_SELECTOR, SPELLVALUE_MAX_TARGETS, 1);
+ _events.ScheduleEvent(EVENT_SARAS_FERVOR, 6000, 0, PHASE_ONE);
+ break;
+ case EVENT_SARAS_ANGER:
+ me->CastCustomSpell(SPELL_SARAS_ANGER_TARGET_SELECTOR, SPELLVALUE_MAX_TARGETS, 1);
+ _events.ScheduleEvent(EVENT_SARAS_ANGER, urand(6000, 8000), 0, PHASE_ONE);
+ break;
+ case EVENT_SARAS_BLESSING:
+ me->CastCustomSpell(SPELL_SARAS_BLESSING_TARGET_SELECTOR, SPELLVALUE_MAX_TARGETS, 1);
+ _events.ScheduleEvent(EVENT_SARAS_BLESSING, urand(6000, 30000), 0, PHASE_ONE);
+ break;
+ case EVENT_TRANSFORM_1:
+ Talk(SAY_SARA_TRANSFORM_2);
+ break;
+ case EVENT_TRANSFORM_2:
+ Talk(SAY_SARA_TRANSFORM_3);
+ break;
+ case EVENT_TRANSFORM_3:
+ Talk(SAY_SARA_TRANSFORM_4);
+ DoCast(me, SPELL_FULL_HEAL);
+ me->setFaction(16);
+ if (Creature* voice = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VOICE_OF_YOGG_SARON)))
+ voice->AI()->DoAction(ACTION_PHASE_TWO);
+ if (Creature* mimiron = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MIMIRON_YS)))
+ mimiron->AI()->DoAction(ACTION_PHASE_TWO);
+ break;
+ case EVENT_TRANSFORM_4:
+ DoCast(me, SPELL_PHASE_2_TRANSFORM);
+ if (Creature* yogg = ObjectAccessor::GetCreature(*me, _instance->GetData64(BOSS_YOGG_SARON)))
+ DoCast(yogg, SPELL_RIDE_YOGG_SARON_VEHICLE);
+ DoCast(me, SPELL_SHADOWY_BARRIER_SARA);
+ _events.SetPhase(PHASE_TWO);
+ _events.ScheduleEvent(EVENT_DEATH_RAY, 20000, 0, PHASE_TWO); // almost never casted at scheduled time, why?
+ _events.ScheduleEvent(EVENT_MALADY_OF_THE_MIND, 18000, 0, PHASE_TWO);
+ _events.ScheduleEvent(EVENT_PSYCHOSIS, 1, 0, PHASE_TWO);
+ _events.ScheduleEvent(EVENT_BRAIN_LINK, 23000, 0, PHASE_TWO);
+ break;
+ case EVENT_DEATH_RAY:
+ DoCast(me, SPELL_DEATH_RAY);
+ _events.ScheduleEvent(EVENT_DEATH_RAY, 21000, 0, PHASE_TWO);
+ break;
+ case EVENT_MALADY_OF_THE_MIND:
+ me->CastCustomSpell(SPELL_MALADY_OF_THE_MIND, SPELLVALUE_MAX_TARGETS, 1);
+ _events.ScheduleEvent(EVENT_MALADY_OF_THE_MIND, urand(18000, 25000), 0, PHASE_TWO);
+ break;
+ case EVENT_PSYCHOSIS:
+ me->CastCustomSpell(SPELL_PSYCHOSIS, SPELLVALUE_MAX_TARGETS, 1);
+ _events.ScheduleEvent(EVENT_PSYCHOSIS, 4000, 0, PHASE_TWO);
+ break;
+ case EVENT_BRAIN_LINK:
+ me->CastCustomSpell(SPELL_BRAIN_LINK, SPELLVALUE_MAX_TARGETS, 2);
+ _events.ScheduleEvent(EVENT_BRAIN_LINK, urand(23000, 26000), 0, PHASE_TWO);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ summon->SetReactState(REACT_PASSIVE);
+
+ switch (summon->GetEntry())
+ {
+ case NPC_DEATH_ORB:
+ Talk(SAY_SARA_DEATH_RAY);
+ summon->CastSpell(summon, SPELL_DEATH_RAY_ORIGIN_VISUAL);
+ for (uint8 i = 0; i < 4; ++i)
+ {
+ Position pos;
+ float radius = frand(25.0f, 50.0f);
+ float angle = frand(0.0f, 2.0f * M_PI);
+ pos.m_positionX = YoggSaronSpawnPos.GetPositionX() + radius * cosf(angle);
+ pos.m_positionY = YoggSaronSpawnPos.GetPositionY() + radius * sinf(angle);
+ pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhaseMask(), pos.GetPositionX(), pos.GetPositionY(), YoggSaronSpawnPos.GetPositionZ() + 5.0f);
+ me->SummonCreature(NPC_DEATH_RAY, pos, TEMPSUMMON_TIMED_DESPAWN, 20000);
+ }
+ break;
+ case NPC_DEATH_RAY:
+ summon->CastSpell(summon, SPELL_DEATH_RAY_WARNING_VISUAL);
+ break;
+ }
+
+ if (Creature* voice = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VOICE_OF_YOGG_SARON)))
+ voice->AI()->JustSummoned(summon);
+ }
+
+ void DoAction(int32 action)
+ {
+ switch (action)
+ {
+ case ACTION_PHASE_THREE: // Sara does nothing in phase 3
+ _events.SetPhase(PHASE_THREE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private:
+ EventMap _events;
+ InstanceScript* _instance;
+ std::map<uint64, uint64> _linkData;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<boss_saraAI>(creature);
+ }
+};
+
+class boss_yogg_saron : public CreatureScript
+{
+ public:
+ boss_yogg_saron() : CreatureScript("boss_yogg_saron") { }
+
+ struct boss_yogg_saronAI : public PassiveAI
+ {
+ boss_yogg_saronAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { }
+
+ void Reset()
+ {
+ _events.Reset();
+ _events.SetPhase(PHASE_TWO);
+ _events.ScheduleEvent(EVENT_YELL_BOW_DOWN, 3000, 0, PHASE_TWO);
+ DoCast(me, SPELL_SHADOWY_BARRIER_YOGG);
+ DoCast(me, SPELL_KNOCK_AWAY);
+
+ me->ResetLootMode();
+ switch (_instance->GetData(DATA_KEEPERS_COUNT))
+ {
+ case 0:
+ me->AddLootMode(LOOT_MODE_HARD_MODE_4);
+ case 1:
+ me->AddLootMode(LOOT_MODE_HARD_MODE_3);
+ case 2:
+ me->AddLootMode(LOOT_MODE_HARD_MODE_2);
+ case 3:
+ me->AddLootMode(LOOT_MODE_HARD_MODE_1);
+ }
+ }
+
+ void SpellHit(Unit* /*caster*/, SpellInfo const* spell)
+ {
+ if (spell->Id == SPELL_IN_THE_MAWS_OF_THE_OLD_GOD)
+ me->AddLootMode(32);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ Talk(SAY_YOGG_SARON_DEATH);
+
+ if (Creature* creature = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VOICE_OF_YOGG_SARON)))
+ me->Kill(creature);
+
+ for (uint8 i = DATA_SARA; i <= DATA_BRAIN_OF_YOGG_SARON; ++i)
+ if (Creature* creature = ObjectAccessor::GetCreature(*me, _instance->GetData64(i)))
+ creature->DisappearAndDie();
+
+ for (uint8 i = DATA_FREYA_YS; i <= DATA_MIMIRON_YS; ++i)
+ if (Creature* creature = ObjectAccessor::GetCreature(*me, _instance->GetData64(i)))
+ creature->AI()->EnterEvadeMode();
+
+ Map::PlayerList const& players = me->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ if (Player* player = itr->getSource())
+ {
+ player->RemoveAurasDueToSpell(SPELL_SANITY);
+ player->RemoveAurasDueToSpell(SPELL_INSANE);
+ }
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_YELL_BOW_DOWN:
+ Talk(SAY_YOGG_SARON_SPAWN);
+ break;
+ case EVENT_SHADOW_BEACON:
+ DoCastAOE(SPELL_SHADOW_BEACON);
+ Talk(EMOTE_YOGG_SARON_EMPOWERING_SHADOWS);
+ _events.ScheduleEvent(EVENT_SHADOW_BEACON, 45000, 0, PHASE_THREE);
+ break;
+ case EVENT_LUNATIC_GAZE:
+ DoCast(me, SPELL_LUNATIC_GAZE);
+ sCreatureTextMgr->SendSound(me, SOUND_LUNATIC_GAZE, CHAT_MSG_MONSTER_YELL, 0, TEXT_RANGE_NORMAL, TEAM_OTHER, false);
+ _events.ScheduleEvent(EVENT_LUNATIC_GAZE, 12000, 0, PHASE_THREE);
+ break;
+ case EVENT_DEAFENING_ROAR:
+ DoCastAOE(SPELL_DEAFENING_ROAR);
+ Talk(SAY_YOGG_SARON_DEAFENING_ROAR);
+ Talk(EMOTE_YOGG_SARON_DEAFENING_ROAR);
+ _events.ScheduleEvent(EVENT_DEAFENING_ROAR, urand(20000, 25000), 0, PHASE_THREE); // timer guessed
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ void DoAction(int32 action)
+ {
+ switch (action)
+ {
+ case ACTION_PHASE_THREE:
+ _events.SetPhase(PHASE_THREE);
+ _events.ScheduleEvent(EVENT_SHADOW_BEACON, 45000, 0, PHASE_THREE);
+ _events.ScheduleEvent(EVENT_LUNATIC_GAZE, 12000, 0, PHASE_THREE);
+ if (me->GetMap()->Is25ManRaid() && _instance->GetData(DATA_KEEPERS_COUNT) < 4)
+ _events.ScheduleEvent(EVENT_DEAFENING_ROAR, urand(20000, 25000), 0, PHASE_THREE); // timer guessed
+ Talk(SAY_YOGG_SARON_PHASE_3);
+ DoCast(me, SPELL_PHASE_3_TRANSFORM);
+ me->RemoveAurasDueToSpell(SPELL_SHADOWY_BARRIER_YOGG);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private:
+ EventMap _events;
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<boss_yogg_saronAI>(creature);
+ }
+};
+
+class boss_brain_of_yogg_saron : public CreatureScript
+{
+ public:
+ boss_brain_of_yogg_saron() : CreatureScript("boss_brain_of_yogg_saron") { }
+
+ struct boss_brain_of_yogg_saronAI : public PassiveAI
+ {
+ boss_brain_of_yogg_saronAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()), _summons(creature) { }
+
+ void Reset()
+ {
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(me, SPELL_MATCH_HEALTH);
+ _summons.DespawnAll();
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage)
+ {
+ if (me->HealthBelowPctDamaged(30, damage) && !me->HasAura(SPELL_BRAIN_HURT_VISUAL))
+ {
+ me->RemoveAllAuras();
+ me->InterruptNonMeleeSpells(true);
+ DoCastAOE(SPELL_SHATTERED_ILLUSION_REMOVE, true);
+ DoCast(me, SPELL_MATCH_HEALTH_2, true); // it doesn't seem to hit Yogg-Saron here
+ DoCast(me, SPELL_BRAIN_HURT_VISUAL, true);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
+
+ if (Creature* voice = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VOICE_OF_YOGG_SARON)))
+ voice->AI()->DoAction(ACTION_PHASE_THREE);
+ if (Creature* sara = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_SARA)))
+ sara->AI()->DoAction(ACTION_PHASE_THREE);
+ if (Creature* yogg = ObjectAccessor::GetCreature(*me, _instance->GetData64(BOSS_YOGG_SARON)))
+ yogg->AI()->DoAction(ACTION_PHASE_THREE);
+
+ for (uint8 i = DATA_THORIM_YS; i <= DATA_MIMIRON_YS; ++i)
+ if (Creature* keeper = ObjectAccessor::GetCreature(*me, _instance->GetData64(i)))
+ keeper->AI()->DoAction(ACTION_PHASE_THREE);
+ }
+ }
+
+ void UpdateAI(uint32 /*diff*/) { }
+
+ void DoAction(int32 action)
+ {
+ switch (action)
+ {
+ case ACTION_INDUCE_MADNESS:
+ {
+ _tentaclesKilled = 0;
+
+ me->SummonCreatureGroup(_instance->GetData(DATA_ILLUSION));
+
+ // make sure doors won't be opened
+ for (uint32 i = GO_BRAIN_ROOM_DOOR_1; i <= GO_BRAIN_ROOM_DOOR_3; ++i)
+ _instance->HandleGameObject(_instance->GetData64(i), false);
+
+ DoCastAOE(SPELL_INDUCE_MADNESS);
+ break;
+ }
+ case ACTION_TENTACLE_KILLED:
+ {
+ uint8 illusion = _instance->GetData(DATA_ILLUSION);
+ if (++_tentaclesKilled >= (illusion == ICECROWN_ILLUSION ? 9 : 8))
+ {
+ sCreatureTextMgr->SendChat(me, EMOTE_BRAIN_ILLUSION_SHATTERED, 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_AREA);
+ _summons.DespawnAll();
+ DoCastAOE(SPELL_SHATTERED_ILLUSION, true);
+ _instance->HandleGameObject(_instance->GetData64(GO_BRAIN_ROOM_DOOR_1 + illusion), true);
+
+ if (Creature* voice = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VOICE_OF_YOGG_SARON)))
+ voice->AI()->DoAction(ACTION_TOGGLE_SHATTERED_ILLUSION);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ _summons.Summon(summon);
+ }
+
+ private:
+ InstanceScript* _instance;
+ SummonList _summons;
+ uint8 _tentaclesKilled;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<boss_brain_of_yogg_saronAI>(creature);
+ }
+};
+
+class npc_ominous_cloud : public CreatureScript
+{
+ public:
+ npc_ominous_cloud() : CreatureScript("npc_ominous_cloud") { }
+
+ struct npc_ominous_cloudAI : public PassiveAI
+ {
+ npc_ominous_cloudAI(Creature* creature) : PassiveAI(creature) { }
+
+ void Reset()
+ {
+ DoCast(me, SPELL_OMINOUS_CLOUD_VISUAL);
+ }
+
+ void FillCirclePath(Position const& centerPos, float radius, float z, Movement::PointsArray& path, bool clockwise)
+ {
+ float step = clockwise ? -M_PI / 8.0f : M_PI / 8.0f;
+ float angle = centerPos.GetAngle(me->GetPositionX(), me->GetPositionY());
+
+ for (uint8 i = 0; i < 16; angle += step, ++i)
+ {
+ G3D::Vector3 point;
+ point.x = centerPos.GetPositionX() + radius * cosf(angle);
+ point.y = centerPos.GetPositionY() + radius * sinf(angle);
+ point.z = me->GetMap()->GetHeight(me->GetPhaseMask(), point.x, point.y, z + 5.0f);
+ path.push_back(point);
+ }
+ }
+
+ void UpdateAI(uint32 /*diff*/) { }
+
+ void DoAction(int32 action)
+ {
+ Movement::MoveSplineInit init(me);
+ FillCirclePath(YoggSaronSpawnPos, me->GetDistance2d(YoggSaronSpawnPos.GetPositionX(), YoggSaronSpawnPos.GetPositionY()), me->GetPositionZ(), init.Path(), action);
+ init.SetWalk(true);
+ init.SetCyclic();
+ init.Launch();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<npc_ominous_cloudAI>(creature);
+ }
+};
+
+class npc_guardian_of_yogg_saron : public CreatureScript
+{
+ public:
+ npc_guardian_of_yogg_saron() : CreatureScript("npc_guardian_of_yogg_saron") { }
+
+ struct npc_guardian_of_yogg_saronAI : public ScriptedAI
+ {
+ npc_guardian_of_yogg_saronAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoCastAOE(SPELL_SHADOW_NOVA);
+ DoCastAOE(SPELL_SHADOW_NOVA_2);
+ }
+
+ void Reset()
+ {
+ _events.ScheduleEvent(EVENT_DARK_VOLLEY, urand(10000, 15000));
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_DARK_VOLLEY:
+ DoCastAOE(SPELL_DARK_VOLLEY);
+ _events.ScheduleEvent(EVENT_DARK_VOLLEY, urand(10000, 15000));
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void IsSummonedBy(Unit* summoner)
+ {
+ if (summoner->GetEntry() != NPC_OMINOUS_CLOUD)
+ return;
+
+ // Guardian can be summoned both by Voice of Yogg-Saron and by Ominous Cloud
+ if (Creature* voice = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VOICE_OF_YOGG_SARON)))
+ voice->AI()->JustSummoned(me);
+ }
+
+ private:
+ EventMap _events;
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<npc_guardian_of_yogg_saronAI>(creature);
+ }
+};
+
+class npc_corruptor_tentacle : public CreatureScript
+{
+ public:
+ npc_corruptor_tentacle() : CreatureScript("npc_corruptor_tentacle") { }
+
+ struct npc_corruptor_tentacleAI : public ScriptedAI
+ {
+ npc_corruptor_tentacleAI(Creature* creature) : ScriptedAI(creature)
+ {
+ SetCombatMovement(false);
+ }
+
+ void Reset()
+ {
+ DoCast(me, SPELL_TENTACLE_VOID_ZONE);
+ DoCastAOE(SPELL_ERUPT);
+ _events.ScheduleEvent(EVENT_CAST_RANDOM_SPELL, 1);
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (me->HasAura(SPELL_SHATTERED_ILLUSION))
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_CAST_RANDOM_SPELL:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(target, RAND(SPELL_BLACK_PLAGUE, SPELL_CURSE_OF_DOOM, SPELL_APATHY, SPELL_DRAINING_POISON));
+ _events.ScheduleEvent(EVENT_CAST_RANDOM_SPELL, 3000);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<npc_corruptor_tentacleAI>(creature);
+ }
+};
+
+class npc_constrictor_tentacle : public CreatureScript
+{
+ public:
+ npc_constrictor_tentacle() : CreatureScript("npc_constrictor_tentacle") { }
+
+ struct npc_constrictor_tentacleAI : public ScriptedAI
+ {
+ npc_constrictor_tentacleAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
+ {
+ SetCombatMovement(false);
+ }
+
+ void Reset()
+ {
+ DoCast(me, SPELL_TENTACLE_VOID_ZONE_2);
+ DoCastAOE(SPELL_ERUPT);
+ }
+
+ void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply)
+ {
+ if (!apply)
+ passenger->RemoveAurasDueToSpell(SPELL_SQUEEZE);
+ }
+
+ void UpdateAI(uint32 /*diff*/)
+ {
+ UpdateVictim();
+ }
+
+ void IsSummonedBy(Unit* /*summoner*/)
+ {
+ if (Creature* voice = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VOICE_OF_YOGG_SARON)))
+ voice->AI()->JustSummoned(me);
+ }
+
+ private:
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<npc_constrictor_tentacleAI>(creature);
+ }
+};
+
+class npc_crusher_tentacle : public CreatureScript
+{
+ public:
+ npc_crusher_tentacle() : CreatureScript("npc_crusher_tentacle") { }
+
+ struct npc_crusher_tentacleAI : public ScriptedAI
+ {
+ npc_crusher_tentacleAI(Creature* creature) : ScriptedAI(creature)
+ {
+ SetCombatMovement(false);
+ }
+
+ void Reset()
+ {
+ DoCast(me, SPELL_CRUSH);
+ DoCast(me, SPELL_TENTACLE_VOID_ZONE);
+ DoCast(me, SPELL_DIMINSH_POWER);
+ DoCast(me, SPELL_FOCUSED_ANGER);
+ DoCastAOE(SPELL_ERUPT);
+
+ _events.ScheduleEvent(EVENT_DIMINISH_POWER, urand(6000, 8000));
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (me->HasAura(SPELL_SHATTERED_ILLUSION) || me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ // update timers when the Diminish Power is not being channeled so the next one
+ // is not cast immediately after interrupt
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_DIMINISH_POWER:
+ DoCast(SPELL_DIMINISH_POWER);
+ _events.ScheduleEvent(EVENT_DIMINISH_POWER, urand(20000, 30000));
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<npc_crusher_tentacleAI>(creature);
+ }
+};
+
+class npc_influence_tentacle : public CreatureScript
+{
+ public:
+ npc_influence_tentacle() : CreatureScript("npc_influence_tentacle") { }
+
+ struct npc_influence_tentacleAI : public PassiveAI
+ {
+ npc_influence_tentacleAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { }
+
+ void Reset()
+ {
+ DoCast(me, me->GetEntry() == NPC_SUIT_OF_ARMOR ? SPELL_NONDESCRIPT_1 : SPELL_NONDESCRIPT_2);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (Creature* brain = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_BRAIN_OF_YOGG_SARON)))
+ brain->AI()->DoAction(ACTION_TENTACLE_KILLED);
+ }
+
+ void UpdateAI(uint32 /*diff*/) { }
+
+ private:
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<npc_influence_tentacleAI>(creature);
+ }
+};
+
+typedef boss_sara::boss_saraAI SaraAI;
+
+class npc_descend_into_madness : public CreatureScript
+{
+ public:
+ npc_descend_into_madness() : CreatureScript("npc_descend_into_madness") { }
+
+ struct npc_descend_into_madnessAI : public PassiveAI
+ {
+ npc_descend_into_madnessAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { }
+
+ void OnSpellClick(Unit* clicker)
+ {
+ clicker->RemoveAurasDueToSpell(SPELL_BRAIN_LINK);
+ me->DespawnOrUnsummon();
+ }
+
+ void UpdateAI(uint32 /*diff*/) { }
+
+ private:
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<npc_descend_into_madnessAI>(creature);
+ }
+};
+
+class npc_immortal_guardian : public CreatureScript
+{
+ public:
+ npc_immortal_guardian() : CreatureScript("npc_immortal_guardian") { }
+
+ struct npc_immortal_guardianAI : public ScriptedAI
+ {
+ npc_immortal_guardianAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset()
+ {
+ DoCast(me, SPELL_EMPOWERED);
+ DoCast(me, SPELL_RECENTLY_SPAWNED);
+ _events.ScheduleEvent(EVENT_DRAIN_LIFE, urand(3000, 13000));
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage)
+ {
+ if (me->HealthBelowPctDamaged(1, damage))
+ damage = me->GetHealth() - me->CountPctFromMaxHealth(1); // or set immune to damage? should be done here or in SPELL_WEAKENED spell script?
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_DRAIN_LIFE:
+ DoCast(SPELL_DRAIN_LIFE);
+ _events.ScheduleEvent(EVENT_DRAIN_LIFE, urand(20000, 30000));
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<npc_immortal_guardianAI>(creature);
+ }
+};
+
+class npc_observation_ring_keeper : public CreatureScript
+{
+ public:
+ npc_observation_ring_keeper() : CreatureScript("npc_observation_ring_keeper") { }
+
+ struct npc_observation_ring_keeperAI : public ScriptedAI
+ {
+ npc_observation_ring_keeperAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset()
+ {
+ DoCast(SPELL_SIMPLE_TELEPORT_KEEPERS); // not visible here
+ DoCast(SPELL_KEEPER_ACTIVE);
+ }
+
+ void sGossipSelect(Player* player, uint32 sender, uint32 /*action*/)
+ {
+ if (sender != 10333)
+ return;
+
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ me->DespawnOrUnsummon(2000);
+ DoCast(SPELL_TELEPORT);
+ Talk(SAY_KEEPER_CHOSEN_1, player->GetGUID());
+ Talk(SAY_KEEPER_CHOSEN_2, player->GetGUID());
+
+ switch (me->GetEntry())
+ {
+ case NPC_FREYA_OBSERVATION_RING:
+ me->SummonCreature(NPC_FREYA_YS, YSKeepersPos[0]);
+ break;
+ case NPC_HODIR_OBSERVATION_RING:
+ me->SummonCreature(NPC_HODIR_YS, YSKeepersPos[1]);
+ break;
+ case NPC_THORIM_OBSERVATION_RING:
+ me->SummonCreature(NPC_THORIM_YS, YSKeepersPos[2]);
+ break;
+ case NPC_MIMIRON_OBSERVATION_RING:
+ me->SummonCreature(NPC_MIMIRON_YS, YSKeepersPos[3]);
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 /*diff*/) { }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<npc_observation_ring_keeperAI>(creature);
+ }
+};
+
+class npc_yogg_saron_keeper : public CreatureScript
+{
+ public:
+ npc_yogg_saron_keeper() : CreatureScript("npc_yogg_saron_keeper") { }
+
+ struct npc_yogg_saron_keeperAI : public ScriptedAI
+ {
+ npc_yogg_saron_keeperAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void IsSummonedBy(Unit* /*summoner*/)
+ {
+ DoCast(SPELL_SIMPLE_TELEPORT_KEEPERS);
+ }
+
+ void Reset()
+ {
+ _events.Reset();
+ _events.SetPhase(PHASE_ONE);
+ me->SetReactState(REACT_PASSIVE);
+ me->RemoveAllAuras();
+
+ DoCast(SPELL_KEEPER_ACTIVE); // can we skip removing this aura somehow?
+
+ if (me->GetEntry() == NPC_FREYA_YS)
+ {
+ std::list<Creature*> wells;
+ GetCreatureListWithEntryInGrid(wells, me, NPC_SANITY_WELL, 200.0f);
+ for (std::list<Creature*>::const_iterator itr = wells.begin(); itr != wells.end(); ++itr)
+ {
+ (*itr)->RemoveAurasDueToSpell(SPELL_SANITY_WELL);
+ (*itr)->RemoveAurasDueToSpell(SPELL_SANITY_WELL_VISUAL);
+ }
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ switch (me->GetEntry())
+ {
+ case NPC_FREYA_YS:
+ DoCast(SPELL_RESILIENCE_OF_NATURE);
+ DoCast(SPELL_SANITY_WELL_SUMMON);
+ break;
+ case NPC_HODIR_YS:
+ DoCast(SPELL_FORTITUDE_OF_FROST);
+ DoCast(SPELL_HODIRS_PROTECTIVE_GAZE);
+ break;
+ case NPC_THORIM_YS:
+ DoCast(SPELL_FURY_OF_THE_STORM);
+ break;
+ case NPC_MIMIRON_YS:
+ DoCast(SPELL_SPEED_OF_INVENTION);
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ if (!me->isInCombat())
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_DESTABILIZATION_MATRIX:
+ me->CastCustomSpell(SPELL_DESTABILIZATION_MATRIX, SPELLVALUE_MAX_TARGETS, 1);
+ _events.ScheduleEvent(EVENT_DESTABILIZATION_MATRIX, urand(15000, 25000), 0, PHASE_TWO);
+ break;
+ case EVENT_HODIRS_PROTECTIVE_GAZE:
+ DoCast(SPELL_HODIRS_PROTECTIVE_GAZE);
+ break;
+ }
+ }
+ }
+
+ void DoAction(int32 action)
+ {
+ switch (action)
+ {
+ // setting the phases is only for Thorim and Mimiron
+ case ACTION_PHASE_TWO:
+ _events.SetPhase(PHASE_TWO);
+ _events.ScheduleEvent(EVENT_DESTABILIZATION_MATRIX, urand(5000, 15000), 0, PHASE_TWO);
+ break;
+ case ACTION_PHASE_THREE:
+ _events.SetPhase(PHASE_THREE);
+ if (me->GetEntry() == NPC_THORIM_YS)
+ DoCast(SPELL_TITANIC_STORM);
+ break;
+ case ACTION_SANITY_WELLS:
+ {
+ std::list<Creature*> wells;
+ GetCreatureListWithEntryInGrid(wells, me, NPC_SANITY_WELL, 200.0f);
+ for (std::list<Creature*>::const_iterator itr = wells.begin(); itr != wells.end(); ++itr)
+ {
+ (*itr)->CastSpell(*itr, SPELL_SANITY_WELL);
+ (*itr)->CastSpell(*itr, SPELL_SANITY_WELL_VISUAL);
+ }
+ break;
+ }
+ case ACTION_FLASH_FREEZE:
+ DoCast(SPELL_FLASH_FREEZE_VISUAL);
+ _events.ScheduleEvent(EVENT_HODIRS_PROTECTIVE_GAZE, urand(25000, 30000));
+ break;
+ }
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<npc_yogg_saron_keeperAI>(creature);
+ }
+};
+
+class npc_yogg_saron_illusions : public CreatureScript
+{
+ public:
+ npc_yogg_saron_illusions() : CreatureScript("npc_yogg_saron_illusions") { }
+
+ struct npc_yogg_saron_illusionsAI : public ScriptedAI
+ {
+ npc_yogg_saron_illusionsAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
+
+ void IsSummonedBy(Unit* /*summoner*/)
+ {
+ switch (_instance->GetData(DATA_ILLUSION))
+ {
+ case CHAMBER_ILLUSION:
+ // i think the first Talk should be delayed as in this moment
+ // players are too far away to be able to see it
+ if (Creature* neltharion = me->FindNearestCreature(NPC_NELTHARION, 50.0f))
+ neltharion->AI()->Talk(SAY_CHAMBER_ROLEPLAY_1);
+
+ _events.ScheduleEvent(EVENT_CHAMBER_ROLEPLAY_1, 16000);
+ _events.ScheduleEvent(EVENT_CHAMBER_ROLEPLAY_2, 22000);
+ _events.ScheduleEvent(EVENT_CHAMBER_ROLEPLAY_3, 28000);
+ _events.ScheduleEvent(EVENT_CHAMBER_ROLEPLAY_4, 36000);
+ break;
+ case ICECROWN_ILLUSION:
+ // same here
+ _events.ScheduleEvent(EVENT_ICECROWN_ROLEPLAY_1, 1000);
+ _events.ScheduleEvent(EVENT_ICECROWN_ROLEPLAY_2, 7500);
+ _events.ScheduleEvent(EVENT_ICECROWN_ROLEPLAY_3, 19500);
+ _events.ScheduleEvent(EVENT_ICECROWN_ROLEPLAY_4, 25500);
+ _events.ScheduleEvent(EVENT_ICECROWN_ROLEPLAY_5, 33000);
+ _events.ScheduleEvent(EVENT_ICECROWN_ROLEPLAY_6, 41300);
+ break;
+ case STORMWIND_ILLUSION:
+ _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_4, 33800); // "A thousand deaths..."
+ _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_5, 38850);
+ _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_7, 58750);
+ // TODO: use "or one murder." sound and split the text in DB
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_CHAMBER_ROLEPLAY_1:
+ if (Creature* ysera = me->FindNearestCreature(NPC_YSERA, 50.0f))
+ ysera->AI()->Talk(SAY_CHAMBER_ROLEPLAY_2);
+ break;
+ case EVENT_CHAMBER_ROLEPLAY_2:
+ if (Creature* neltharion = me->FindNearestCreature(NPC_NELTHARION, 50.0f))
+ neltharion->AI()->Talk(SAY_CHAMBER_ROLEPLAY_3);
+ break;
+ case EVENT_CHAMBER_ROLEPLAY_3:
+ if (Creature* malygos = me->FindNearestCreature(NPC_MALYGOS, 50.0f))
+ malygos->AI()->Talk(SAY_CHAMBER_ROLEPLAY_4);
+ break;
+ case EVENT_CHAMBER_ROLEPLAY_4:
+ Talk(SAY_CHAMBER_ROLEPLAY_5);
+ break;
+ case EVENT_ICECROWN_ROLEPLAY_1:
+ if (Creature* bolvar = me->FindNearestCreature(NPC_IMMOLATED_CHAMPION, 50.0f))
+ {
+ bolvar->AI()->Talk(SAY_ICECROWN_ROLEPLAY_1);
+
+ if (Creature* lichKing = me->FindNearestCreature(NPC_THE_LICH_KING, 50.0f))
+ lichKing->CastSpell(bolvar, SPELL_DEATHGRASP);
+ }
+ break;
+ case EVENT_ICECROWN_ROLEPLAY_2:
+ if (Creature* lichKing = me->FindNearestCreature(NPC_THE_LICH_KING, 50.0f))
+ lichKing->AI()->Talk(SAY_ICECROWN_ROLEPLAY_2);
+ break;
+ case EVENT_ICECROWN_ROLEPLAY_3:
+ if (Creature* bolvar = me->FindNearestCreature(NPC_IMMOLATED_CHAMPION, 50.0f))
+ bolvar->AI()->Talk(SAY_ICECROWN_ROLEPLAY_3);
+ if (Creature* saurfang = me->FindNearestCreature(NPC_TURNED_CHAMPION, 50.0f))
+ saurfang->AI()->DoAction(ACTION_START_ROLEPLAY);
+ break;
+ case EVENT_ICECROWN_ROLEPLAY_4:
+ if (Creature* lichKing = me->FindNearestCreature(NPC_THE_LICH_KING, 50.0f))
+ lichKing->AI()->Talk(SAY_ICECROWN_ROLEPLAY_4);
+ break;
+ case EVENT_ICECROWN_ROLEPLAY_5:
+ Talk(SAY_ICECROWN_ROLEPLAY_5);
+ break;
+ case EVENT_ICECROWN_ROLEPLAY_6:
+ Talk(SAY_ICECROWN_ROLEPLAY_6);
+ break;
+ case EVENT_STORMWIND_ROLEPLAY_4:
+ Talk(SAY_STORMWIND_ROLEPLAY_4);
+ break;
+ case EVENT_STORMWIND_ROLEPLAY_5:
+ if (Creature* llane = me->FindNearestCreature(NPC_KING_LLANE, 50.0f))
+ llane->AI()->Talk(SAY_STORMWIND_ROLEPLAY_5);
+ break;
+ case EVENT_STORMWIND_ROLEPLAY_7:
+ Talk(SAY_STORMWIND_ROLEPLAY_7);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap _events;
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<npc_yogg_saron_illusionsAI>(creature);
+ }
+};
+
+class npc_garona : public CreatureScript
+{
+ public:
+ npc_garona() : CreatureScript("npc_garona") { }
+
+ struct npc_garonaAI : public ScriptedAI
+ {
+ npc_garonaAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset()
+ {
+ _events.Reset();
+
+ me->SetWalk(true);
+ me->GetMotionMaster()->MovePoint(0, IllusionsMiscPos[0]);
+
+ _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_1, 9250);
+ _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_2, 16700);
+ _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_3, 24150);
+ _events.ScheduleEvent(EVENT_STORMWIND_ROLEPLAY_6, 52700);
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_STORMWIND_ROLEPLAY_1:
+ Talk(SAY_STORMWIND_ROLEPLAY_1);
+ break;
+ case EVENT_STORMWIND_ROLEPLAY_2:
+ Talk(SAY_STORMWIND_ROLEPLAY_2);
+ break;
+ case EVENT_STORMWIND_ROLEPLAY_3:
+ Talk(SAY_STORMWIND_ROLEPLAY_3);
+ break;
+ case EVENT_STORMWIND_ROLEPLAY_6:
+ Talk(SAY_STORMWIND_ROLEPLAY_6);
+ if (Creature* llane = me->FindNearestCreature(NPC_KING_LLANE, 50.0f))
+ {
+ DoCast(SPELL_ASSASSINATE);
+ llane->CastSpell(llane, SPELL_PERMANENT_FEIGN_DEATH);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<npc_garonaAI>(creature);
+ }
+};
+
+class npc_turned_champion : public CreatureScript
+{
+ public:
+ npc_turned_champion() : CreatureScript("npc_turned_champion") { }
+
+ struct npc_turned_championAI : public ScriptedAI
+ {
+ npc_turned_championAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset()
+ {
+ DoCast(SPELL_VERTEX_COLOR_BLACK);
+ }
+
+ void MovementInform(uint32 type, uint32 pointId)
+ {
+ if (type != POINT_MOTION_TYPE || pointId != 0)
+ return;
+
+ me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
+ }
+
+ void DoAction(int32 action)
+ {
+ if (action != ACTION_START_ROLEPLAY)
+ return;
+
+ me->SetWalk(true);
+ me->GetMotionMaster()->MovePoint(0, IllusionsMiscPos[1]);
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<npc_turned_championAI>(creature);
+ }
+};
+
+class npc_laughing_skull : public CreatureScript
+{
+ public:
+ npc_laughing_skull() : CreatureScript("npc_laughing_skull") { }
+
+ struct npc_laughing_skullAI : public ScriptedAI
+ {
+ npc_laughing_skullAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset()
+ {
+ me->SetReactState(REACT_PASSIVE);
+ DoCast(me, SPELL_LUNATIC_GAZE_SKULL);
+ }
+
+ // don't evade, otherwise the Lunatic Gaze aura is removed
+ void UpdateAI(uint32 /*diff*/) { }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetUlduarAI<npc_laughing_skullAI>(creature);
+ }
+};
+
+class spell_yogg_saron_target_selectors : public SpellScriptLoader // 63744, 63745, 63747, 65206
+{
+ public:
+ spell_yogg_saron_target_selectors() : SpellScriptLoader("spell_yogg_saron_target_selectors") { }
+
+ class spell_yogg_saron_target_selectors_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_target_selectors_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ GetCaster()->CastSpell(target, uint32(GetEffectValue()));
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_target_selectors_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_target_selectors_SpellScript();
+ }
+};
+
+class SanityReduction : public SpellScript
+{
+ public:
+ SanityReduction() : SpellScript() { }
+ SanityReduction(uint8 stacks) : SpellScript(), _stacks(stacks) { }
+
+ void RemoveSanity(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ if (Aura* sanity = target->GetAura(SPELL_SANITY))
+ sanity->ModStackAmount(-int32(_stacks), AURA_REMOVE_BY_ENEMY_SPELL);
+ }
+
+ protected:
+ uint8 _stacks;
+};
+
+class HighSanityTargetSelector
+{
+ public:
+ HighSanityTargetSelector() { }
+
+ bool operator()(WorldObject* object)
+ {
+ if (Unit* unit = object->ToUnit())
+ if (Aura* sanity = unit->GetAura(SPELL_SANITY))
+ return sanity->GetStackAmount() <= 40;
+ return true;
+ }
+};
+
+class spell_yogg_saron_psychosis : public SpellScriptLoader // 63795, 65301
+{
+ public:
+ spell_yogg_saron_psychosis() : SpellScriptLoader("spell_yogg_saron_psychosis") { }
+
+ class spell_yogg_saron_psychosis_SpellScript : public SanityReduction
+ {
+ PrepareSpellScript(spell_yogg_saron_psychosis_SpellScript);
+
+ bool Load()
+ {
+ _stacks = GetSpellInfo()->Id == SPELL_PSYCHOSIS ? 9 : 12;
+ return true;
+ }
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(HighSanityTargetSelector());
+ targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_ILLUSION_ROOM));
+ }
+
+ void Register()
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_yogg_saron_psychosis_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_yogg_saron_psychosis_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_psychosis_SpellScript::RemoveSanity, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_psychosis_SpellScript();
+ }
+};
+
+class spell_yogg_saron_malady_of_the_mind : public SpellScriptLoader // 63830, 63881
+{
+ public:
+ spell_yogg_saron_malady_of_the_mind() : SpellScriptLoader("spell_yogg_saron_malady_of_the_mind") { }
+
+ class spell_yogg_saron_malady_of_the_mind_SpellScript : public SanityReduction
+ {
+ public:
+ spell_yogg_saron_malady_of_the_mind_SpellScript() : SanityReduction(3) { }
+
+ PrepareSpellScript(spell_yogg_saron_malady_of_the_mind_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(HighSanityTargetSelector());
+ targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_ILLUSION_ROOM));
+ }
+
+ void Register()
+ {
+ if (m_scriptSpellId == SPELL_MALADY_OF_THE_MIND)
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_yogg_saron_malady_of_the_mind_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_yogg_saron_malady_of_the_mind_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_yogg_saron_malady_of_the_mind_SpellScript::FilterTargets, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_malady_of_the_mind_SpellScript::RemoveSanity, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ class spell_yogg_saron_malady_of_the_mind_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_yogg_saron_malady_of_the_mind_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_MALADY_OF_THE_MIND_JUMP))
+ return false;
+ return true;
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ switch (GetTargetApplication()->GetRemoveMode())
+ {
+ case AURA_REMOVE_BY_ENEMY_SPELL:
+ case AURA_REMOVE_BY_EXPIRE:
+ case AURA_REMOVE_BY_DEATH:
+ break;
+ default:
+ return;
+ }
+
+ GetTarget()->CastSpell(GetTarget(), SPELL_MALADY_OF_THE_MIND_JUMP);
+ }
+
+ void Register()
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_yogg_saron_malady_of_the_mind_AuraScript::OnRemove, EFFECT_1, SPELL_AURA_MOD_FEAR, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_malady_of_the_mind_SpellScript();
+ }
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_yogg_saron_malady_of_the_mind_AuraScript();
+ }
+};
+
+class spell_yogg_saron_brain_link : public SpellScriptLoader // 63802
+{
+ public:
+ spell_yogg_saron_brain_link() : SpellScriptLoader("spell_yogg_saron_brain_link") { }
+
+ class spell_yogg_saron_brain_link_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_brain_link_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_ILLUSION_ROOM));
+
+ if (targets.size() != 2)
+ {
+ targets.clear();
+ return;
+ }
+
+ if (SaraAI* ai = CAST_AI(SaraAI, GetCaster()->GetAI()))
+ ai->SetLinkBetween(targets.front()->GetGUID(), targets.back()->GetGUID());
+ }
+
+ void Register()
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_yogg_saron_brain_link_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+ };
+
+ class spell_yogg_saron_brain_link_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_yogg_saron_brain_link_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_BRAIN_LINK_DAMAGE))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_BRAIN_LINK_NO_DAMAGE))
+ return false;
+ return true;
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* caster = GetCaster();
+ if (!caster)
+ return;
+
+ if (SaraAI* ai = CAST_AI(SaraAI, caster->GetAI()))
+ {
+ if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
+ ai->RemoveLinkFrom(GetTarget()->GetGUID());
+ else
+ {
+ if (Player* player = ObjectAccessor::GetPlayer(*GetTarget(), ai->GetLinkedPlayerGUID(GetTarget()->GetGUID())))
+ {
+ ai->RemoveLinkFrom(GetTarget()->GetGUID());
+ player->RemoveAurasDueToSpell(SPELL_BRAIN_LINK);
+ }
+ }
+ }
+ }
+
+ void DummyTick(AuraEffect const* aurEff)
+ {
+ Unit* caster = GetCaster();
+ if (!caster)
+ return;
+
+ SaraAI* ai = CAST_AI(SaraAI, caster->GetAI());
+ if (!ai)
+ return;
+
+ Player* linked = ObjectAccessor::GetPlayer(*GetTarget(), ai->GetLinkedPlayerGUID(GetTarget()->GetGUID()));
+ if (!linked)
+ return;
+
+ GetTarget()->CastSpell(linked, (GetTarget()->GetDistance(linked) > (float)aurEff->GetAmount()) ? SPELL_BRAIN_LINK_DAMAGE : SPELL_BRAIN_LINK_NO_DAMAGE, true);
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_yogg_saron_brain_link_AuraScript::DummyTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ OnEffectRemove += AuraEffectRemoveFn(spell_yogg_saron_brain_link_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_brain_link_SpellScript();
+ }
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_yogg_saron_brain_link_AuraScript();
+ }
+};
+
+class spell_yogg_saron_brain_link_damage : public SpellScriptLoader // 63803
+{
+ public:
+ spell_yogg_saron_brain_link_damage() : SpellScriptLoader("spell_yogg_saron_brain_link_damage") { }
+
+ class spell_yogg_saron_brain_link_damage_SpellScript : public SanityReduction
+ {
+ public:
+ spell_yogg_saron_brain_link_damage_SpellScript() : SanityReduction(2) { }
+
+ PrepareSpellScript(spell_yogg_saron_brain_link_damage_SpellScript);
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_brain_link_damage_SpellScript::RemoveSanity, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_brain_link_damage_SpellScript();
+ }
+};
+
+class spell_yogg_saron_boil_ominously : public SpellScriptLoader // 63030
+{
+ public:
+ spell_yogg_saron_boil_ominously() : SpellScriptLoader("spell_yogg_saron_boil_ominously") { }
+
+ class spell_yogg_saron_boil_ominously_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_boil_ominously_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_GUARDIAN_1))
+ return false;
+ return true;
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ if (!target->HasAura(SPELL_FLASH_FREEZE) && !GetCaster()->HasAura(SPELL_SUMMON_GUARDIAN_1) && !GetCaster()->HasAura(SPELL_SUMMON_GUARDIAN_2))
+ {
+ if (Creature* caster = GetCaster()->ToCreature())
+ caster->AI()->Talk(EMOTE_OMINOUS_CLOUD_PLAYER_TOUCH, target->GetGUID());
+
+ GetCaster()->CastSpell(GetCaster(), SPELL_SUMMON_GUARDIAN_1, true);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_boil_ominously_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_boil_ominously_SpellScript();
+ }
+};
+
+class spell_yogg_saron_shadow_beacon : public SpellScriptLoader // 64465
+{
+ public:
+ spell_yogg_saron_shadow_beacon() : SpellScriptLoader("spell_yogg_saron_shadow_beacon") { }
+
+ class spell_yogg_saron_shadow_beacon_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_yogg_saron_shadow_beacon_AuraScript);
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Creature* target = GetTarget()->ToCreature())
+ target->SetEntry(NPC_MARKED_IMMORTAL_GUARDIAN);
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Creature* target = GetTarget()->ToCreature())
+ target->SetEntry(NPC_IMMORTAL_GUARDIAN);
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_yogg_saron_shadow_beacon_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_yogg_saron_shadow_beacon_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_yogg_saron_shadow_beacon_AuraScript();
+ }
+};
+
+class spell_yogg_saron_empowering_shadows_range_check : public SpellScriptLoader // 64466
+{
+ public:
+ spell_yogg_saron_empowering_shadows_range_check() : SpellScriptLoader("spell_yogg_saron_empowering_shadows_range_check") { }
+
+ class spell_yogg_saron_empowering_shadows_range_check_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_empowering_shadows_range_check_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ target->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_empowering_shadows_range_check_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_empowering_shadows_range_check_SpellScript();
+ }
+};
+
+class spell_yogg_saron_empowering_shadows_missile : public SpellScriptLoader // 64467
+{
+ public:
+ spell_yogg_saron_empowering_shadows_missile() : SpellScriptLoader("spell_yogg_saron_empowering_shadows_missile") { }
+
+ class spell_yogg_saron_empowering_shadows_missile_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_empowering_shadows_missile_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_EMPOWERING_SHADOWS))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ target->CastSpell((Unit*)NULL, SPELL_EMPOWERING_SHADOWS, true);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_empowering_shadows_missile_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_empowering_shadows_missile_SpellScript();
+ }
+};
+
+// it works, but is it scripted correctly? why is it aura with 2500ms duration?
+class spell_yogg_saron_constrictor_tentacle : public SpellScriptLoader // 64132
+{
+ public:
+ spell_yogg_saron_constrictor_tentacle() : SpellScriptLoader("spell_yogg_saron_constrictor_tentacle") { }
+
+ class spell_yogg_saron_constrictor_tentacle_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_yogg_saron_constrictor_tentacle_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_CONSTRICTOR_TENTACLE_SUMMON))
+ return false;
+ return true;
+ }
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->CastSpell(GetTarget(), SPELL_CONSTRICTOR_TENTACLE_SUMMON);
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_yogg_saron_constrictor_tentacle_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_yogg_saron_constrictor_tentacle_AuraScript();
+ }
+};
+
+class spell_yogg_saron_lunge : public SpellScriptLoader // 64131
+{
+ public:
+ spell_yogg_saron_lunge() : SpellScriptLoader("spell_yogg_saron_lunge") { }
+
+ class spell_yogg_saron_lunge_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_lunge_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_SQUEEZE))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ {
+ target->CastSpell(target, SPELL_SQUEEZE, true);
+ target->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_lunge_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_lunge_SpellScript();
+ }
+};
+
+class spell_yogg_saron_squeeze : public SpellScriptLoader // 64125
+{
+ public:
+ spell_yogg_saron_squeeze() : SpellScriptLoader("spell_yogg_saron_squeeze") { }
+
+ class spell_yogg_saron_squeeze_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_yogg_saron_squeeze_AuraScript);
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* vehicle = GetTarget()->GetVehicleBase())
+ if (vehicle->isAlive())
+ vehicle->Kill(vehicle); // should tentacle die or just release its target?
+ }
+
+ void Register()
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_yogg_saron_squeeze_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_yogg_saron_squeeze_AuraScript();
+ }
+};
+
+class spell_yogg_saron_diminsh_power : public SpellScriptLoader // 64148
+{
+ public:
+ spell_yogg_saron_diminsh_power() : SpellScriptLoader("spell_yogg_saron_diminsh_power") { }
+
+ class spell_yogg_saron_diminsh_power_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_yogg_saron_diminsh_power_AuraScript);
+
+ void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ if (Spell* spell = GetTarget()->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
+ if (spell->getState() == SPELL_STATE_CASTING)
+ GetTarget()->InterruptSpell(CURRENT_CHANNELED_SPELL);
+ }
+
+ void Register()
+ {
+ OnEffectProc += AuraEffectProcFn(spell_yogg_saron_diminsh_power_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_yogg_saron_diminsh_power_AuraScript();
+ }
+};
+
+// not sure about SPELL_WEAKENED part, where should it be handled?
+class spell_yogg_saron_empowered : public SpellScriptLoader // 64161
+{
+ public:
+ spell_yogg_saron_empowered() : SpellScriptLoader("spell_yogg_saron_empowered") { }
+
+ class spell_yogg_saron_empowered_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_yogg_saron_empowered_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_EMPOWERED_BUFF))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_WEAKENED))
+ return false;
+ return true;
+ }
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->CastCustomSpell(SPELL_EMPOWERED_BUFF, SPELLVALUE_AURA_STACK, 9, GetTarget(), TRIGGERED_FULL_MASK);
+ }
+
+ void OnPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ Unit* target = GetTarget();
+ float stack = ceil((target->GetHealthPct() / 10) - 1);
+ target->RemoveAurasDueToSpell(SPELL_EMPOWERED_BUFF);
+
+ if (stack)
+ {
+ target->RemoveAurasDueToSpell(SPELL_WEAKENED);
+ target->CastCustomSpell(SPELL_EMPOWERED_BUFF, SPELLVALUE_AURA_STACK, stack, target, TRIGGERED_FULL_MASK);
+ }
+ else if (!target->HealthAbovePct(1) && !target->HasAura(SPELL_WEAKENED))
+ target->CastSpell(target, SPELL_WEAKENED, true);
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_yogg_saron_empowered_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_yogg_saron_empowered_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_yogg_saron_empowered_AuraScript();
+ }
+};
+
+class spell_yogg_saron_match_health : public SpellScriptLoader // 64069
+{
+ public:
+ spell_yogg_saron_match_health() : SpellScriptLoader("spell_yogg_saron_match_health") { }
+
+ class spell_yogg_saron_match_health_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_match_health_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ target->SetHealth(target->CountPctFromMaxHealth((int32)GetCaster()->GetHealthPct()));
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_match_health_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_match_health_SpellScript();
+ }
+};
+
+class spell_yogg_saron_shattered_illusion : public SpellScriptLoader // 65238
+{
+ public:
+ spell_yogg_saron_shattered_illusion() : SpellScriptLoader("spell_yogg_saron_shattered_illusion") { }
+
+ class spell_yogg_saron_shattered_illusion_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_shattered_illusion_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ target->RemoveAurasDueToSpell(uint32(GetEffectValue()));
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_shattered_illusion_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_shattered_illusion_SpellScript();
+ }
+};
+
+class spell_yogg_saron_death_ray_warning_visual : public SpellScriptLoader // 63882
+{
+ public:
+ spell_yogg_saron_death_ray_warning_visual() : SpellScriptLoader("spell_yogg_saron_death_ray_warning_visual") { }
+
+ class spell_yogg_saron_death_ray_warning_visual_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_yogg_saron_death_ray_warning_visual_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DEATH_RAY_PERIODIC))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_DEATH_RAY_DAMAGE_VISUAL))
+ return false;
+ return true;
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ {
+ caster->CastSpell(caster, SPELL_DEATH_RAY_PERIODIC, true);
+ caster->CastSpell((Unit*)NULL, SPELL_DEATH_RAY_DAMAGE_VISUAL, true);
+ // TODO: set better movement
+ caster->GetMotionMaster()->MoveConfused();
+ }
+ }
+
+ void Register()
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_yogg_saron_death_ray_warning_visual_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_yogg_saron_death_ray_warning_visual_AuraScript();
+ }
+};
+
+class spell_yogg_saron_cancel_illusion_room_aura : public SpellScriptLoader // 63993
+{
+ public:
+ spell_yogg_saron_cancel_illusion_room_aura() : SpellScriptLoader("spell_yogg_saron_cancel_illusion_room_aura") { }
+
+ class spell_yogg_saron_cancel_illusion_room_aura_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_cancel_illusion_room_aura_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_TELEPORT_BACK_TO_MAIN_ROOM))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ {
+ target->CastSpell(target, SPELL_TELEPORT_BACK_TO_MAIN_ROOM);
+ target->RemoveAurasDueToSpell(uint32(GetEffectValue()));
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_cancel_illusion_room_aura_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_cancel_illusion_room_aura_SpellScript();
+ }
+};
+
+class spell_yogg_saron_nondescript : public SpellScriptLoader // 64010, 64013
+{
+ public:
+ spell_yogg_saron_nondescript() : SpellScriptLoader("spell_yogg_saron_nondescript") { }
+
+ class spell_yogg_saron_nondescript_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_yogg_saron_nondescript_AuraScript);
+
+ void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->CastSpell(GetTarget(), uint32(aurEff->GetAmount()), true);
+ }
+
+ void Register()
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_yogg_saron_nondescript_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_yogg_saron_nondescript_AuraScript();
+ }
+};
+
+class spell_yogg_saron_revealed_tentacle : public SpellScriptLoader // 64012
+{
+ public:
+ spell_yogg_saron_revealed_tentacle() : SpellScriptLoader("spell_yogg_saron_revealed_tentacle") { }
+
+ class spell_yogg_saron_revealed_tentacle_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_revealed_tentacle_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_TENTACLE_VOID_ZONE))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_GRIM_REPRISAL))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Creature* caster = GetCaster()->ToCreature())
+ {
+ caster->CastSpell(caster, SPELL_TENTACLE_VOID_ZONE, true);
+ caster->CastSpell(caster, SPELL_GRIM_REPRISAL, true);
+ caster->UpdateEntry(NPC_INFLUENCE_TENTACLE, 0, caster->GetCreatureData());
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_revealed_tentacle_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_revealed_tentacle_SpellScript();
+ }
+};
+
+class spell_yogg_saron_grim_reprisal : public SpellScriptLoader // 63305
+{
+ public:
+ spell_yogg_saron_grim_reprisal() : SpellScriptLoader("spell_yogg_saron_grim_reprisal") { }
+
+ class spell_yogg_saron_grim_reprisal_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_yogg_saron_grim_reprisal_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_GRIM_REPRISAL_DAMAGE))
+ return false;
+ return true;
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ int32 damage = CalculatePct(int32(eventInfo.GetDamageInfo()->GetDamage()), 60);
+ GetTarget()->CastCustomSpell(SPELL_GRIM_REPRISAL_DAMAGE, SPELLVALUE_BASE_POINT0, damage, eventInfo.GetDamageInfo()->GetAttacker(), true, NULL, aurEff);
+ }
+
+ void Register()
+ {
+ OnEffectProc += AuraEffectProcFn(spell_yogg_saron_grim_reprisal_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_yogg_saron_grim_reprisal_AuraScript();
+ }
+};
+
+class spell_yogg_saron_induce_madness : public SpellScriptLoader // 64059
+{
+ public:
+ spell_yogg_saron_induce_madness() : SpellScriptLoader("spell_yogg_saron_induce_madness") { }
+
+ class spell_yogg_saron_induce_madness_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_induce_madness_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_TELEPORT_BACK_TO_MAIN_ROOM))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHATTERED_ILLUSION_REMOVE))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ {
+ target->CastSpell(target, SPELL_TELEPORT_BACK_TO_MAIN_ROOM);
+ target->RemoveAurasDueToSpell(SPELL_SANITY, 0, 0, AURA_REMOVE_BY_ENEMY_SPELL);
+ target->RemoveAurasDueToSpell(uint32(GetEffectValue()));
+ }
+ }
+
+ void ClearShatteredIllusion()
+ {
+ GetCaster()->CastSpell((Unit*)NULL, SPELL_SHATTERED_ILLUSION_REMOVE);
+
+ if (InstanceScript* instance = GetCaster()->GetInstanceScript())
+ if (Creature* voice = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(DATA_VOICE_OF_YOGG_SARON)))
+ voice->AI()->DoAction(ACTION_TOGGLE_SHATTERED_ILLUSION);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_induce_madness_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ AfterCast += SpellCastFn(spell_yogg_saron_induce_madness_SpellScript::ClearShatteredIllusion);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_induce_madness_SpellScript();
+ }
+};
+
+class spell_yogg_saron_sanity : public SpellScriptLoader // 63050
+{
+ public:
+ spell_yogg_saron_sanity() : SpellScriptLoader("spell_yogg_saron_sanity") { }
+
+ class spell_yogg_saron_sanity_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_sanity_SpellScript);
+
+ // don't target players outside of room or handle it in SPELL_INSANE_PERIODIC?
+
+ void ModSanityStacks()
+ {
+ GetSpell()->SetSpellValue(SPELLVALUE_AURA_STACK, 100);
+ }
+
+ void Register()
+ {
+ BeforeCast += SpellCastFn(spell_yogg_saron_sanity_SpellScript::ModSanityStacks);
+ }
+ };
+
+ class spell_yogg_saron_sanity_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_yogg_saron_sanity_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_LOW_SANITY_SCREEN_EFFECT))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_INSANE))
+ return false;
+ return true;
+ }
+
+ void DummyTick(AuraEffect const* /*aurEff*/)
+ {
+ if (GetTarget()->HasAura(SPELL_SANITY_WELL))
+ ModStackAmount(20);
+
+ if (GetStackAmount() <= 40 && !GetTarget()->HasAura(SPELL_LOW_SANITY_SCREEN_EFFECT))
+ GetTarget()->CastSpell(GetTarget(), SPELL_LOW_SANITY_SCREEN_EFFECT, true);
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
+ return;
+
+ if (InstanceScript* instance = GetTarget()->GetInstanceScript())
+ instance->SetData(DATA_DRIVE_ME_CRAZY, uint32(false));
+
+ GetTarget()->RemoveAurasDueToSpell(SPELL_BRAIN_LINK);
+
+ if (Unit* caster = GetCaster())
+ caster->CastSpell(GetTarget(), SPELL_INSANE, true);
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_yogg_saron_sanity_AuraScript::DummyTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_yogg_saron_sanity_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_sanity_SpellScript();
+ }
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_yogg_saron_sanity_AuraScript();
+ }
+};
+
+class spell_yogg_saron_insane : public SpellScriptLoader // 63120
+{
+ public:
+ spell_yogg_saron_insane() : SpellScriptLoader("spell_yogg_saron_insane") { }
+
+ class spell_yogg_saron_insane_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_yogg_saron_insane_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_INSANE_VISUAL))
+ return false;
+ return true;
+ }
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (Creature* yogg = caster->ToCreature())
+ yogg->AI()->Talk(WHISPER_VOICE_INSANE, GetTarget()->GetGUID());
+
+ GetTarget()->CastSpell(GetTarget(), SPELL_INSANE_VISUAL, true);
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTarget()->isAlive())
+ GetTarget()->Kill(GetTarget());
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_yogg_saron_insane_AuraScript::OnApply, EFFECT_0, SPELL_AURA_AOE_CHARM, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_yogg_saron_insane_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_AOE_CHARM, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_yogg_saron_insane_AuraScript();
+ }
+};
+
+class spell_yogg_saron_insane_periodic : public SpellScriptLoader // 64555
+{
+ public:
+ spell_yogg_saron_insane_periodic() : SpellScriptLoader("spell_yogg_saron_insane_periodic") { }
+
+ class spell_yogg_saron_insane_periodic_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_insane_periodic_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ GetCaster()->CastSpell(target, uint32(GetEffectValue()), true);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_insane_periodic_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_insane_periodic_SpellScript();
+ }
+};
+
+class LunaticGazeTargetSelector
+{
+ public:
+ LunaticGazeTargetSelector(Unit* caster) : _caster(caster) { }
+
+ bool operator()(WorldObject* object)
+ {
+ return !object->HasInArc(static_cast<float>(M_PI), _caster);
+ }
+
+ private:
+ Unit* _caster;
+};
+
+class spell_yogg_saron_lunatic_gaze : public SpellScriptLoader // 64164, 64168
+{
+ public:
+ spell_yogg_saron_lunatic_gaze() : SpellScriptLoader("spell_yogg_saron_lunatic_gaze") { }
+
+ class spell_yogg_saron_lunatic_gaze_SpellScript : public SanityReduction
+ {
+ PrepareSpellScript(spell_yogg_saron_lunatic_gaze_SpellScript);
+
+ bool Load()
+ {
+ _stacks = GetSpellInfo()->Id == SPELL_LUNATIC_GAZE_DAMAGE ? 4 : 2;
+ return true;
+ }
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(LunaticGazeTargetSelector(GetCaster()));
+ }
+
+ void Register()
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_yogg_saron_lunatic_gaze_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_yogg_saron_lunatic_gaze_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_lunatic_gaze_SpellScript::RemoveSanity, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_lunatic_gaze_SpellScript();
+ }
+};
+
+class spell_yogg_saron_keeper_aura : public SpellScriptLoader // 62650, 62670, 62671, 62702
+{
+ public:
+ spell_yogg_saron_keeper_aura() : SpellScriptLoader("spell_yogg_saron_keeper_aura") { }
+
+ class spell_yogg_saron_keeper_aura_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_yogg_saron_keeper_aura_AuraScript);
+
+ bool CanApply(Unit* target)
+ {
+ if (target->GetTypeId() != TYPEID_PLAYER && target != GetCaster())
+ return false;
+ return true;
+ }
+
+ void Register()
+ {
+ DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_yogg_saron_keeper_aura_AuraScript::CanApply);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_yogg_saron_keeper_aura_AuraScript();
+ }
+};
+
+class spell_yogg_saron_hate_to_zero : public SpellScriptLoader // 63984
+{
+ public:
+ spell_yogg_saron_hate_to_zero() : SpellScriptLoader("spell_yogg_saron_hate_to_zero") { }
+
+ class spell_yogg_saron_hate_to_zero_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_hate_to_zero_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ if (target->CanHaveThreatList())
+ target->getThreatManager().modifyThreatPercent(GetCaster(), -100);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_hate_to_zero_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_hate_to_zero_SpellScript();
+ }
+};
+
+class spell_yogg_saron_in_the_maws_of_the_old_god : public SpellScriptLoader // 64184
+{
+ public:
+ spell_yogg_saron_in_the_maws_of_the_old_god() : SpellScriptLoader("spell_yogg_saron_in_the_maws_of_the_old_god") { }
+
+ class spell_yogg_saron_in_the_maws_of_the_old_god_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_in_the_maws_of_the_old_god_SpellScript);
+
+ SpellCastResult CheckRequirement()
+ {
+ if (InstanceScript* instance = GetCaster()->GetInstanceScript())
+ if (Creature* yogg = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(BOSS_YOGG_SARON)))
+ if (yogg->FindCurrentSpellBySpellId(SPELL_DEAFENING_ROAR))
+ {
+ if (GetCaster()->GetDistance(yogg) > 20.0f)
+ return SPELL_FAILED_OUT_OF_RANGE;
+ else
+ return SPELL_CAST_OK;
+ }
+
+ return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
+ }
+
+ void Register()
+ {
+ OnCheckCast += SpellCheckCastFn(spell_yogg_saron_in_the_maws_of_the_old_god_SpellScript::CheckRequirement);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_in_the_maws_of_the_old_god_SpellScript();
+ }
+};
+
+class spell_yogg_saron_titanic_storm : public SpellScriptLoader // 64172
+{
+ public:
+ spell_yogg_saron_titanic_storm() : SpellScriptLoader("spell_yogg_saron_titanic_storm") { }
+
+ class spell_yogg_saron_titanic_storm_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_yogg_saron_titanic_storm_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ GetCaster()->Kill(target);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_yogg_saron_titanic_storm_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_yogg_saron_titanic_storm_SpellScript();
+ }
+};
+
+class spell_yogg_saron_hodirs_protective_gaze : public SpellScriptLoader // 64174
+{
+ public:
+ spell_yogg_saron_hodirs_protective_gaze() : SpellScriptLoader("spell_yogg_saron_hodirs_protective_gaze") { }
+
+ class spell_yogg_saron_hodirs_protective_gaze_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_yogg_saron_hodirs_protective_gaze_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_FLASH_FREEZE))
+ return false;
+ return true;
+ }
+
+ bool CanApply(Unit* target)
+ {
+ if (target->GetTypeId() != TYPEID_PLAYER && target != GetCaster())
+ return false;
+ return true;
+ }
+
+ void OnAbsorb(AuraEffect* /*aurEff*/, DamageInfo& dmgInfo, uint32& absorbAmount)
+ {
+ if (dmgInfo.GetDamage() >= GetTarget()->GetHealth())
+ {
+ absorbAmount = dmgInfo.GetDamage();
+ // or absorbAmount = dmgInfo.GetDamage() - GetTarget()->GetHealth() + 1
+ GetTarget()->CastSpell(GetTarget(), SPELL_FLASH_FREEZE, true);
+ }
+ else
+ PreventDefaultAction();
+ }
+
+ void Register()
+ {
+ DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_yogg_saron_hodirs_protective_gaze_AuraScript::CanApply);
+ OnEffectAbsorb += AuraEffectAbsorbFn(spell_yogg_saron_hodirs_protective_gaze_AuraScript::OnAbsorb, EFFECT_0);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_yogg_saron_hodirs_protective_gaze_AuraScript();
+ }
+};
+
+void AddSC_boss_yogg_saron()
+{
+ new boss_voice_of_yogg_saron();
+ new boss_sara();
+ new boss_yogg_saron();
+ new boss_brain_of_yogg_saron();
+ new npc_ominous_cloud();
+ new npc_guardian_of_yogg_saron();
+ new npc_corruptor_tentacle();
+ new npc_constrictor_tentacle();
+ new npc_crusher_tentacle();
+ new npc_influence_tentacle();
+ new npc_descend_into_madness();
+ new npc_immortal_guardian();
+ new npc_observation_ring_keeper();
+ new npc_yogg_saron_keeper();
+ new npc_yogg_saron_illusions();
+ new npc_garona();
+ new npc_turned_champion();
+ new npc_laughing_skull();
+ new spell_yogg_saron_target_selectors();
+ new spell_yogg_saron_psychosis();
+ new spell_yogg_saron_malady_of_the_mind();
+ new spell_yogg_saron_brain_link();
+ new spell_yogg_saron_brain_link_damage();
+ new spell_yogg_saron_boil_ominously();
+ new spell_yogg_saron_shadow_beacon();
+ new spell_yogg_saron_empowering_shadows_range_check();
+ new spell_yogg_saron_empowering_shadows_missile();
+ new spell_yogg_saron_constrictor_tentacle();
+ new spell_yogg_saron_lunge();
+ new spell_yogg_saron_squeeze();
+ new spell_yogg_saron_diminsh_power();
+ new spell_yogg_saron_empowered();
+ new spell_yogg_saron_match_health();
+ new spell_yogg_saron_shattered_illusion();
+ new spell_yogg_saron_death_ray_warning_visual();
+ new spell_yogg_saron_cancel_illusion_room_aura();
+ new spell_yogg_saron_nondescript();
+ new spell_yogg_saron_revealed_tentacle();
+ new spell_yogg_saron_grim_reprisal();
+ new spell_yogg_saron_induce_madness();
+ new spell_yogg_saron_sanity();
+ new spell_yogg_saron_insane();
+ new spell_yogg_saron_insane_periodic();
+ new spell_yogg_saron_lunatic_gaze();
+ new spell_yogg_saron_keeper_aura();
+ new spell_yogg_saron_hate_to_zero();
+ new spell_yogg_saron_in_the_maws_of_the_old_god();
+ new spell_yogg_saron_titanic_storm();
+ new spell_yogg_saron_hodirs_protective_gaze();
+}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp
deleted file mode 100644
index 4bcb1b9e584..00000000000
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_yoggsaron.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "ScriptMgr.h"
-#include "ulduar.h"
-
-enum Sara
-{
- // text
- YELL_SARA_PREFIGHT = 0,
- YELL_COMBAT_PHASE_1 = 1,
- YELL_COMBAT_PHASE_2 = 2,
- YELL_SLAY = 3,
-
- // Phase 1 spells
- SPELL_SARAS_ANGER_1 = 63147, // Target Entry 33136
- SPELL_SARAS_ANGER_2 = 63744, // Target Entry 33136
- SPELL_SARAS_FEVOR_1 = 63138, // Target Player
- SPELL_SARAS_FEVOR_2 = 63747, // Target Player
- SPELL_SARAS_BLESSING_1 = 63134, // Target Player
- SPELL_SARAS_BLESSING_2 = 63745, // Target Self
-
- // Phase 2 spells
- SPELL_PHYCHOSIS = 63795, // Target Self
- SPELL_MALADY_OF_THE_MIND = 63830, // Target Self
- SPELL_DEATH_RAY = 63891, // Target Self
- SPELL_BRAIN_LINK = 63802, // Target Self
-};
-
-enum YoggSaron_Yells
-{
-};
-
-enum
-{
- ACHIEV_TIMED_START_EVENT = 21001,
-};
-//not in scriptloader yet just to remove warning boss_yoggsaron.obj : warning LNK4221: no public symbols found; archive member will be inaccessible
-void AddSC_boss_yoggsaron()
-{
-}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
index 125f66497bf..421d0ecf3c9 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
@@ -24,14 +24,15 @@
static DoorData const doorData[] =
{
- {GO_LEVIATHAN_DOOR, BOSS_LEVIATHAN, DOOR_TYPE_ROOM, BOUNDARY_S },
- {GO_XT_002_DOOR, BOSS_XT002, DOOR_TYPE_ROOM, BOUNDARY_S },
- {GO_DOODAD_UL_SIGILDOOR_03, BOSS_ALGALON, DOOR_TYPE_ROOM, BOUNDARY_W },
- {GO_DOODAD_UL_UNIVERSEFLOOR_01, BOSS_ALGALON, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- {GO_DOODAD_UL_UNIVERSEFLOOR_02, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE },
- {GO_DOODAD_UL_UNIVERSEGLOBE01, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE },
- {GO_DOODAD_UL_ULDUAR_TRAPDOOR_03, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE },
- {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE },
+ {GO_LEVIATHAN_DOOR, BOSS_LEVIATHAN, DOOR_TYPE_ROOM, BOUNDARY_S },
+ {GO_XT_002_DOOR, BOSS_XT002, DOOR_TYPE_ROOM, BOUNDARY_S },
+ {GO_YOGG_SARON_DOOR, BOSS_YOGG_SARON, DOOR_TYPE_ROOM, BOUNDARY_S },
+ {GO_DOODAD_UL_SIGILDOOR_03, BOSS_ALGALON, DOOR_TYPE_ROOM, BOUNDARY_W },
+ {GO_DOODAD_UL_UNIVERSEFLOOR_01, BOSS_ALGALON, DOOR_TYPE_ROOM, BOUNDARY_NONE },
+ {GO_DOODAD_UL_UNIVERSEFLOOR_02, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE },
+ {GO_DOODAD_UL_UNIVERSEGLOBE01, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE },
+ {GO_DOODAD_UL_ULDUAR_TRAPDOOR_03, BOSS_ALGALON, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_NONE },
+ {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE },
};
MinionData const minionData[] =
@@ -56,7 +57,6 @@ class instance_ulduar : public InstanceMapScript
uint64 IgnisGUID;
uint64 RazorscaleGUID;
uint64 RazorscaleController;
- uint64 RazorHarpoonGUIDs[4];
uint64 ExpeditionCommanderGUID;
uint64 XT002GUID;
uint64 XTToyPileGUIDs[4];
@@ -67,14 +67,18 @@ class instance_ulduar : public InstanceMapScript
uint64 HodirGUID;
uint64 ThorimGUID;
uint64 FreyaGUID;
- uint64 KeeperGUIDs[3];
+ uint64 ElderGUIDs[3];
uint64 VezaxGUID;
uint64 YoggSaronGUID;
+ uint64 VoiceOfYoggSaronGUID;
+ uint64 SaraGUID;
+ uint64 BrainOfYoggSaronGUID;
uint64 AlgalonGUID;
- uint64 LeviathanGateGUID;
- uint64 VezaxDoorGUID;
+ uint64 BrannBronzebeardAlgGUID;
// GameObjects
+ uint64 LeviathanGateGUID;
+ uint64 RazorHarpoonGUIDs[4];
uint64 KologarnChestGUID;
uint64 KologarnBridgeGUID;
uint64 KologarnDoorGUID;
@@ -84,11 +88,13 @@ class instance_ulduar : public InstanceMapScript
uint64 HodirDoorGUID;
uint64 HodirIceDoorGUID;
uint64 ArchivumDoorGUID;
+ uint64 VezaxDoorGUID;
+ uint64 BrainRoomDoorGUIDs[3];
+ uint64 KeeperGUIDs[4];
uint64 AlgalonSigilDoorGUID[3];
uint64 AlgalonFloorGUID[2];
uint64 AlgalonUniverseGUID;
uint64 AlgalonTrapdoorGUID;
- uint64 BrannBronzebeardAlgGUID;
uint64 GiftOfTheObserverGUID;
// Miscellaneous
@@ -96,8 +102,11 @@ class instance_ulduar : public InstanceMapScript
uint32 HodirRareCacheData;
uint32 ColossusData;
uint8 elderCount;
+ uint8 illusion;
+ uint8 keepersCount;
bool conSpeedAtory;
bool Unbroken;
+ bool IsDriveMeCrazyEligible;
std::set<uint64> mRubbleSpawns;
@@ -119,6 +128,9 @@ class instance_ulduar : public InstanceMapScript
FreyaGUID = 0;
VezaxGUID = 0;
YoggSaronGUID = 0;
+ VoiceOfYoggSaronGUID = 0;
+ SaraGUID = 0;
+ BrainOfYoggSaronGUID = 0;
AlgalonGUID = 0;
KologarnChestGUID = 0;
KologarnBridgeGUID = 0;
@@ -141,6 +153,8 @@ class instance_ulduar : public InstanceMapScript
HodirRareCacheData = 0;
ColossusData = 0;
elderCount = 0;
+ illusion = 0;
+ keepersCount = 0;
conSpeedAtory = false;
Unbroken = true;
_algalonSummoned = false;
@@ -151,7 +165,11 @@ class instance_ulduar : public InstanceMapScript
memset(XTToyPileGUIDs, 0, sizeof(XTToyPileGUIDs));
memset(AssemblyGUIDs, 0, sizeof(AssemblyGUIDs));
memset(RazorHarpoonGUIDs, 0, sizeof(RazorHarpoonGUIDs));
+ memset(ElderGUIDs, 0, sizeof(ElderGUIDs));
+ memset(BrainRoomDoorGUIDs, 0, sizeof(BrainRoomDoorGUIDs));
memset(KeeperGUIDs, 0, sizeof(KeeperGUIDs));
+ memset(_summonObservationRingKeeper, false, sizeof(_summonObservationRingKeeper));
+ memset(_summonYSKeeper, false, sizeof(_summonYSKeeper));
}
void FillInitialWorldStates(WorldPacket& packet)
@@ -174,6 +192,38 @@ class instance_ulduar : public InstanceMapScript
else
algalon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
}
+
+ // Keepers at Observation Ring
+ if (GetBossState(BOSS_FREYA) == DONE && _summonObservationRingKeeper[0] && !KeeperGUIDs[0])
+ {
+ _summonObservationRingKeeper[0] = false;
+ instance->SummonCreature(NPC_FREYA_OBSERVATION_RING, ObservationRingKeepersPos[0]);
+ }
+ if (GetBossState(BOSS_HODIR) == DONE && _summonObservationRingKeeper[1] && !KeeperGUIDs[1])
+ {
+ _summonObservationRingKeeper[1] = false;
+ instance->SummonCreature(NPC_HODIR_OBSERVATION_RING, ObservationRingKeepersPos[1]);
+ }
+ if (GetBossState(BOSS_THORIM) == DONE && _summonObservationRingKeeper[2] && !KeeperGUIDs[2])
+ {
+ _summonObservationRingKeeper[2] = false;
+ instance->SummonCreature(NPC_THORIM_OBSERVATION_RING, ObservationRingKeepersPos[2]);
+ }
+ if (GetBossState(BOSS_MIMIRON) == DONE && _summonObservationRingKeeper[3] && !KeeperGUIDs[3])
+ {
+ _summonObservationRingKeeper[3] = false;
+ instance->SummonCreature(NPC_MIMIRON_OBSERVATION_RING, ObservationRingKeepersPos[3]);
+ }
+
+ // Keepers in Yogg-Saron's room
+ if (_summonYSKeeper[0])
+ instance->SummonCreature(NPC_FREYA_YS, YSKeepersPos[0]);
+ if (_summonYSKeeper[1])
+ instance->SummonCreature(NPC_HODIR_YS, YSKeepersPos[1]);
+ if (_summonYSKeeper[2])
+ instance->SummonCreature(NPC_THORIM_YS, YSKeepersPos[2]);
+ if (_summonYSKeeper[3])
+ instance->SummonCreature(NPC_MIMIRON_YS, YSKeepersPos[3]);
}
void OnCreatureCreate(Creature* creature)
@@ -194,6 +244,8 @@ class instance_ulduar : public InstanceMapScript
case NPC_IGNIS:
IgnisGUID = creature->GetGUID();
break;
+
+ // Razorscale
case NPC_RAZORSCALE:
RazorscaleGUID = creature->GetGUID();
break;
@@ -203,6 +255,8 @@ class instance_ulduar : public InstanceMapScript
case NPC_EXPEDITION_COMMANDER:
ExpeditionCommanderGUID = creature->GetGUID();
break;
+
+ // XT-002 Deconstructor
case NPC_XT002:
XT002GUID = creature->GetGUID();
break;
@@ -229,24 +283,6 @@ class instance_ulduar : public InstanceMapScript
AddMinion(creature, true);
break;
- // Freya's Keeper
- case NPC_IRONBRANCH:
- KeeperGUIDs[0] = creature->GetGUID();
- if (GetBossState(BOSS_FREYA) == DONE)
- creature->DespawnOrUnsummon();
- break;
- case NPC_BRIGHTLEAF:
- KeeperGUIDs[1] = creature->GetGUID();
- if (GetBossState(BOSS_FREYA) == DONE)
- creature->DespawnOrUnsummon();
- break;
- case NPC_STONEBARK:
- KeeperGUIDs[2] = creature->GetGUID();
- if (GetBossState(BOSS_FREYA) == DONE)
- creature->DespawnOrUnsummon();
- break;
-
- // Kologarn
case NPC_KOLOGARN:
KologarnGUID = creature->GetGUID();
break;
@@ -256,25 +292,11 @@ class instance_ulduar : public InstanceMapScript
case NPC_MIMIRON:
MimironGUID = creature->GetGUID();
break;
+
+ // Hodir
case NPC_HODIR:
HodirGUID = creature->GetGUID();
break;
- case NPC_THORIM:
- ThorimGUID = creature->GetGUID();
- break;
- case NPC_FREYA:
- FreyaGUID = creature->GetGUID();
- break;
- case NPC_VEZAX:
- VezaxGUID = creature->GetGUID();
- break;
- case NPC_YOGGSARON:
- YoggSaronGUID = creature->GetGUID();
- break;
- case NPC_ALGALON:
- AlgalonGUID = creature->GetGUID();
- break;
- // Hodir's Helper NPCs
case NPC_EIVI_NIGHTFEATHER:
if (TeamInInstance == HORDE)
creature->UpdateEntry(NPC_TOR_GREYCLOUD, HORDE);
@@ -307,6 +329,80 @@ class instance_ulduar : public InstanceMapScript
if (TeamInInstance == HORDE)
creature->UpdateEntry(NPC_BATTLE_PRIEST_GINA, HORDE);
break;
+
+ case NPC_THORIM:
+ ThorimGUID = creature->GetGUID();
+ break;
+
+ // Freya
+ case NPC_FREYA:
+ FreyaGUID = creature->GetGUID();
+ break;
+ case NPC_IRONBRANCH:
+ ElderGUIDs[0] = creature->GetGUID();
+ if (GetBossState(BOSS_FREYA) == DONE)
+ creature->DespawnOrUnsummon();
+ break;
+ case NPC_BRIGHTLEAF:
+ ElderGUIDs[1] = creature->GetGUID();
+ if (GetBossState(BOSS_FREYA) == DONE)
+ creature->DespawnOrUnsummon();
+ break;
+ case NPC_STONEBARK:
+ ElderGUIDs[2] = creature->GetGUID();
+ if (GetBossState(BOSS_FREYA) == DONE)
+ creature->DespawnOrUnsummon();
+ break;
+
+ case NPC_VEZAX:
+ VezaxGUID = creature->GetGUID();
+ break;
+
+ // Yogg-Saron
+ case NPC_YOGG_SARON:
+ YoggSaronGUID = creature->GetGUID();
+ break;
+ case NPC_VOICE_OF_YOGG_SARON:
+ VoiceOfYoggSaronGUID = creature->GetGUID();
+ break;
+ case NPC_BRAIN_OF_YOGG_SARON:
+ BrainOfYoggSaronGUID = creature->GetGUID();
+ break;
+ case NPC_SARA:
+ SaraGUID = creature->GetGUID();
+ break;
+ case NPC_FREYA_YS:
+ KeeperGUIDs[0] = creature->GetGUID();
+ _summonYSKeeper[0] = false;
+ SaveToDB();
+ ++keepersCount;
+ break;
+ case NPC_HODIR_YS:
+ KeeperGUIDs[1] = creature->GetGUID();
+ _summonYSKeeper[1] = false;
+ SaveToDB();
+ ++keepersCount;
+ break;
+ case NPC_THORIM_YS:
+ KeeperGUIDs[2] = creature->GetGUID();
+ _summonYSKeeper[2] = false;
+ SaveToDB();
+ ++keepersCount;
+ break;
+ case NPC_MIMIRON_YS:
+ KeeperGUIDs[3] = creature->GetGUID();
+ _summonYSKeeper[3] = false;
+ SaveToDB();
+ ++keepersCount;
+ break;
+ case NPC_SANITY_WELL:
+ creature->SetReactState(REACT_PASSIVE);
+ break;
+
+ // Algalon
+ case NPC_ALGALON:
+ AlgalonGUID = creature->GetGUID();
+ break;
case NPC_BRANN_BRONZBEARD_ALG:
BrannBronzebeardAlgGUID = creature->GetGUID();
break;
@@ -418,6 +514,18 @@ class instance_ulduar : public InstanceMapScript
if (GetBossState(BOSS_ASSEMBLY_OF_IRON) != DONE)
HandleGameObject(ArchivumDoorGUID, false);
break;
+ case GO_YOGG_SARON_DOOR:
+ AddDoor(gameObject, true);
+ break;
+ case GO_BRAIN_ROOM_DOOR_1:
+ BrainRoomDoorGUIDs[0] = gameObject->GetGUID();
+ break;
+ case GO_BRAIN_ROOM_DOOR_2:
+ BrainRoomDoorGUIDs[1] = gameObject->GetGUID();
+ break;
+ case GO_BRAIN_ROOM_DOOR_3:
+ BrainRoomDoorGUIDs[2] = gameObject->GetGUID();
+ break;
case GO_CELESTIAL_PLANETARIUM_ACCESS_10:
case GO_CELESTIAL_PLANETARIUM_ACCESS_25:
if (_algalonSummoned)
@@ -509,27 +617,36 @@ class instance_ulduar : public InstanceMapScript
{
// Flame Leviathan's Tower Event triggers
Creature* FlameLeviathan = instance->GetCreature(LeviathanGUID);
- if (FlameLeviathan && FlameLeviathan->isAlive()) // No leviathan, no event triggering ;)
+
+ switch (eventId)
{
- switch (eventId)
- {
- case EVENT_TOWER_OF_STORM_DESTROYED:
+ case EVENT_TOWER_OF_STORM_DESTROYED:
+ if (FlameLeviathan && FlameLeviathan->isAlive())
FlameLeviathan->AI()->DoAction(ACTION_TOWER_OF_STORM_DESTROYED);
- break;
- case EVENT_TOWER_OF_FROST_DESTROYED:
+ break;
+ case EVENT_TOWER_OF_FROST_DESTROYED:
+ if (FlameLeviathan && FlameLeviathan->isAlive())
FlameLeviathan->AI()->DoAction(ACTION_TOWER_OF_FROST_DESTROYED);
- break;
- case EVENT_TOWER_OF_FLAMES_DESTROYED:
+ break;
+ case EVENT_TOWER_OF_FLAMES_DESTROYED:
+ if (FlameLeviathan && FlameLeviathan->isAlive())
FlameLeviathan->AI()->DoAction(ACTION_TOWER_OF_FLAMES_DESTROYED);
- break;
- case EVENT_TOWER_OF_LIFE_DESTROYED:
+ break;
+ case EVENT_TOWER_OF_LIFE_DESTROYED:
+ if (FlameLeviathan && FlameLeviathan->isAlive())
FlameLeviathan->AI()->DoAction(ACTION_TOWER_OF_LIFE_DESTROYED);
- break;
- }
+ break;
+ case EVENT_ACTIVATE_SANITY_WELL:
+ if (Creature* freya = instance->GetCreature(KeeperGUIDs[0]))
+ freya->AI()->DoAction(4/*ACTION_SANITY_WELLS*/);
+ break;
+ case EVENT_HODIRS_PROTECTIVE_GAZE_PROC:
+ if (Creature* hodir = instance->GetCreature(KeeperGUIDs[1]))
+ hodir->AI()->DoAction(5/*ACTION_FLASH_FREEZE*/);
+ break;
}
}
-
bool SetBossState(uint32 type, EncounterState state)
{
if (!InstanceScript::SetBossState(type, state))
@@ -542,8 +659,14 @@ class instance_ulduar : public InstanceMapScript
case BOSS_RAZORSCALE:
case BOSS_XT002:
case BOSS_AURIAYA:
+ break;
case BOSS_MIMIRON:
+ if (state == DONE)
+ instance->SummonCreature(NPC_MIMIRON_OBSERVATION_RING, ObservationRingKeepersPos[3]);
+ break;
case BOSS_FREYA:
+ if (state == DONE)
+ instance->SummonCreature(NPC_FREYA_OBSERVATION_RING, ObservationRingKeepersPos[0]);
break;
case BOSS_ASSEMBLY_OF_IRON:
if (state == DONE)
@@ -553,7 +676,7 @@ class instance_ulduar : public InstanceMapScript
if (state == DONE)
HandleGameObject(VezaxDoorGUID, true);
break;
- case BOSS_YOGGSARON:
+ case BOSS_YOGG_SARON:
break;
case BOSS_KOLOGARN:
if (state == DONE)
@@ -576,12 +699,18 @@ class instance_ulduar : public InstanceMapScript
HodirChest->SetRespawnTime(HodirChest->GetRespawnDelay());
HandleGameObject(HodirDoorGUID, true);
HandleGameObject(HodirIceDoorGUID, true);
+
+ instance->SummonCreature(NPC_HODIR_OBSERVATION_RING, ObservationRingKeepersPos[1]);
}
break;
case BOSS_THORIM:
if (state == DONE)
+ {
if (GameObject* gameObject = instance->GetGameObject(ThorimChestGUID))
gameObject->SetRespawnTime(gameObject->GetRespawnDelay());
+
+ instance->SummonCreature(NPC_THORIM_OBSERVATION_RING, ObservationRingKeepersPos[2]);
+ }
break;
case BOSS_ALGALON:
if (state == DONE)
@@ -661,6 +790,12 @@ class instance_ulduar : public InstanceMapScript
case DATA_UNBROKEN:
Unbroken = bool(data);
break;
+ case DATA_ILLUSION:
+ illusion = data;
+ break;
+ case DATA_DRIVE_ME_CRAZY:
+ IsDriveMeCrazyEligible = data ? true : false;
+ break;
case EVENT_DESPAWN_ALGALON:
DoUpdateWorldState(WORLD_STATE_ALGALON_TIMER_ENABLED, 1);
DoUpdateWorldState(WORLD_STATE_ALGALON_DESPAWN_TIMER, 60);
@@ -688,10 +823,24 @@ class instance_ulduar : public InstanceMapScript
return LeviathanGUID;
case BOSS_IGNIS:
return IgnisGUID;
+
+ // Razorscale
case BOSS_RAZORSCALE:
return RazorscaleGUID;
case DATA_RAZORSCALE_CONTROL:
return RazorscaleController;
+ case DATA_EXPEDITION_COMMANDER:
+ return ExpeditionCommanderGUID;
+ case GO_RAZOR_HARPOON_1:
+ return RazorHarpoonGUIDs[0];
+ case GO_RAZOR_HARPOON_2:
+ return RazorHarpoonGUIDs[1];
+ case GO_RAZOR_HARPOON_3:
+ return RazorHarpoonGUIDs[2];
+ case GO_RAZOR_HARPOON_4:
+ return RazorHarpoonGUIDs[3];
+
+ // XT-002 Deconstructor
case BOSS_XT002:
return XT002GUID;
case DATA_TOY_PILE_0:
@@ -699,6 +848,15 @@ class instance_ulduar : public InstanceMapScript
case DATA_TOY_PILE_2:
case DATA_TOY_PILE_3:
return XTToyPileGUIDs[data - DATA_TOY_PILE_0];
+
+ // Assembly of Iron
+ case DATA_STEELBREAKER:
+ return AssemblyGUIDs[0];
+ case DATA_MOLGEIM:
+ return AssemblyGUIDs[1];
+ case DATA_BRUNDIR:
+ return AssemblyGUIDs[2];
+
case BOSS_KOLOGARN:
return KologarnGUID;
case BOSS_AURIAYA:
@@ -709,42 +867,47 @@ class instance_ulduar : public InstanceMapScript
return HodirGUID;
case BOSS_THORIM:
return ThorimGUID;
+
+ // Freya
case BOSS_FREYA:
return FreyaGUID;
+ case BOSS_BRIGHTLEAF:
+ return ElderGUIDs[0];
+ case BOSS_IRONBRANCH:
+ return ElderGUIDs[1];
+ case BOSS_STONEBARK:
+ return ElderGUIDs[2];
+
case BOSS_VEZAX:
return VezaxGUID;
- case BOSS_YOGGSARON:
- return YoggSaronGUID;
- case BOSS_ALGALON:
- return AlgalonGUID;
- // Razorscale expedition commander
- case DATA_EXPEDITION_COMMANDER:
- return ExpeditionCommanderGUID;
- case GO_RAZOR_HARPOON_1:
- return RazorHarpoonGUIDs[0];
- case GO_RAZOR_HARPOON_2:
- return RazorHarpoonGUIDs[1];
- case GO_RAZOR_HARPOON_3:
- return RazorHarpoonGUIDs[2];
- case GO_RAZOR_HARPOON_4:
- return RazorHarpoonGUIDs[3];
-
- // Assembly of Iron
- case DATA_STEELBREAKER:
- return AssemblyGUIDs[0];
- case DATA_MOLGEIM:
- return AssemblyGUIDs[1];
- case DATA_BRUNDIR:
- return AssemblyGUIDs[2];
-
- // Freya's Keepers
- case BOSS_BRIGHTLEAF:
+ // Yogg-Saron
+ case BOSS_YOGG_SARON:
+ return YoggSaronGUID;
+ case DATA_VOICE_OF_YOGG_SARON:
+ return VoiceOfYoggSaronGUID;
+ case DATA_BRAIN_OF_YOGG_SARON:
+ return BrainOfYoggSaronGUID;
+ case DATA_SARA:
+ return SaraGUID;
+ case GO_BRAIN_ROOM_DOOR_1:
+ return BrainRoomDoorGUIDs[0];
+ case GO_BRAIN_ROOM_DOOR_2:
+ return BrainRoomDoorGUIDs[1];
+ case GO_BRAIN_ROOM_DOOR_3:
+ return BrainRoomDoorGUIDs[2];
+ case DATA_FREYA_YS:
return KeeperGUIDs[0];
- case BOSS_IRONBRANCH:
+ case DATA_HODIR_YS:
return KeeperGUIDs[1];
- case BOSS_STONEBARK:
+ case DATA_THORIM_YS:
return KeeperGUIDs[2];
+ case DATA_MIMIRON_YS:
+ return KeeperGUIDs[3];
+
+ // Algalon
+ case BOSS_ALGALON:
+ return AlgalonGUID;
case DATA_SIGILDOOR_01:
return AlgalonSigilDoorGUID[0];
case DATA_SIGILDOOR_02:
@@ -776,6 +939,10 @@ class instance_ulduar : public InstanceMapScript
return HodirRareCacheData;
case DATA_UNBROKEN:
return uint32(Unbroken);
+ case DATA_ILLUSION:
+ return illusion;
+ case DATA_KEEPERS_COUNT:
+ return keepersCount;
default:
break;
}
@@ -789,6 +956,30 @@ class instance_ulduar : public InstanceMapScript
{
case CRITERIA_HERALD_OF_TITANS:
return _maxArmorItemLevel <= MAX_HERALD_ARMOR_ITEMLEVEL && _maxWeaponItemLevel <= MAX_HERALD_WEAPON_ITEMLEVEL;
+ case CRITERIA_WAITS_DREAMING_STORMWIND_25:
+ case CRITERIA_WAITS_DREAMING_STORMWIND_10:
+ return illusion == STORMWIND_ILLUSION;
+ case CRITERIA_WAITS_DREAMING_CHAMBER_25:
+ case CRITERIA_WAITS_DREAMING_CHAMBER_10:
+ return illusion == CHAMBER_ILLUSION;
+ case CRITERIA_WAITS_DREAMING_ICECROWN_25:
+ case CRITERIA_WAITS_DREAMING_ICECROWN_10:
+ return illusion == ICECROWN_ILLUSION;
+ case CRITERIA_DRIVE_ME_CRAZY_10:
+ case CRITERIA_DRIVE_ME_CRAZY_25:
+ return IsDriveMeCrazyEligible;
+ case CRITERIA_THREE_LIGHTS_IN_THE_DARKNESS_10:
+ case CRITERIA_THREE_LIGHTS_IN_THE_DARKNESS_25:
+ return keepersCount <= 3;
+ case CRITERIA_TWO_LIGHTS_IN_THE_DARKNESS_10:
+ case CRITERIA_TWO_LIGHTS_IN_THE_DARKNESS_25:
+ return keepersCount <= 2;
+ case CRITERIA_ONE_LIGHT_IN_THE_DARKNESS_10:
+ case CRITERIA_ONE_LIGHT_IN_THE_DARKNESS_25:
+ return keepersCount <= 1;
+ case CRITERIA_ALONE_IN_THE_DARKNESS_10:
+ case CRITERIA_ALONE_IN_THE_DARKNESS_25:
+ return keepersCount == 0;
}
return false;
@@ -801,6 +992,9 @@ class instance_ulduar : public InstanceMapScript
std::ostringstream saveStream;
saveStream << "U U " << GetBossSaveData() << GetData(DATA_COLOSSUS) << ' ' << _algalonTimer << ' ' << (_algalonSummoned ? 1 : 0);
+ for (uint8 i = 0; i < 4; ++i)
+ saveStream << ' ' << (KeeperGUIDs[i] ? 1 : 0);
+
OUT_SAVE_INST_DATA_COMPLETE;
return saveStream.str();
}
@@ -851,6 +1045,21 @@ class instance_ulduar : public InstanceMapScript
DoUpdateWorldState(WORLD_STATE_ALGALON_DESPAWN_TIMER, _algalonTimer);
}
}
+
+ for (uint8 i = 0; i < 4; ++i)
+ {
+ loadStream >> tempState;
+ _summonYSKeeper[i] = tempState != 0;
+ }
+
+ if (GetBossState(BOSS_FREYA) == DONE && !_summonYSKeeper[0])
+ _summonObservationRingKeeper[0] = true;
+ if (GetBossState(BOSS_HODIR) == DONE && !_summonYSKeeper[1])
+ _summonObservationRingKeeper[1] = true;
+ if (GetBossState(BOSS_THORIM) == DONE && !_summonYSKeeper[2])
+ _summonObservationRingKeeper[2] = true;
+ if (GetBossState(BOSS_MIMIRON) == DONE && !_summonYSKeeper[3])
+ _summonObservationRingKeeper[3] = true;
}
OUT_LOAD_INST_DATA_COMPLETE;
@@ -889,6 +1098,8 @@ class instance_ulduar : public InstanceMapScript
uint32 _algalonTimer;
bool _summonAlgalon;
bool _algalonSummoned;
+ bool _summonObservationRingKeeper[4];
+ bool _summonYSKeeper[4];
uint32 _maxArmorItemLevel;
uint32 _maxWeaponItemLevel;
};
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
index 08fd95d0e26..612be3b71e8 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
@@ -21,6 +21,8 @@
#include "ObjectMgr.h"
#define UlduarScriptName "instance_ulduar"
+extern Position const ObservationRingKeepersPos[4];
+extern Position const YSKeepersPos[4];
extern Position const AlgalonLandPos;
enum UlduarBosses
@@ -42,7 +44,7 @@ enum UlduarBosses
BOSS_IRONBRANCH = 12,
BOSS_STONEBARK = 13,
BOSS_VEZAX = 14,
- BOSS_YOGGSARON = 15,
+ BOSS_YOGG_SARON = 15,
BOSS_ALGALON = 16,
};
@@ -74,7 +76,7 @@ enum UlduarNPCs
NPC_THORIM = 32865,
NPC_FREYA = 32906,
NPC_VEZAX = 33271,
- NPC_YOGGSARON = 33288,
+ NPC_YOGG_SARON = 33288,
NPC_ALGALON = 32871,
// Mimiron
@@ -115,6 +117,39 @@ enum UlduarNPCs
NPC_NATURES_BLADE = 33527,
NPC_GUARDIAN_OF_LIFE = 33528,
+ // Yogg-Saron
+ NPC_SARA = 33134,
+ NPC_GUARDIAN_OF_YOGG_SARON = 33136,
+ NPC_HODIR_OBSERVATION_RING = 33213,
+ NPC_FREYA_OBSERVATION_RING = 33241,
+ NPC_THORIM_OBSERVATION_RING = 33242,
+ NPC_MIMIRON_OBSERVATION_RING = 33244,
+ NPC_VOICE_OF_YOGG_SARON = 33280,
+ NPC_OMINOUS_CLOUD = 33292,
+ NPC_FREYA_YS = 33410,
+ NPC_HODIR_YS = 33411,
+ NPC_MIMIRON_YS = 33412,
+ NPC_THORIM_YS = 33413,
+ NPC_SUIT_OF_ARMOR = 33433,
+ NPC_KING_LLANE = 33437,
+ NPC_THE_LICH_KING = 33441,
+ NPC_IMMOLATED_CHAMPION = 33442,
+ NPC_YSERA = 33495,
+ NPC_NELTHARION = 33523,
+ NPC_MALYGOS = 33535,
+ NPC_DEATH_RAY = 33881,
+ NPC_DEATH_ORB = 33882,
+ NPC_BRAIN_OF_YOGG_SARON = 33890,
+ NPC_INFLUENCE_TENTACLE = 33943,
+ NPC_TURNED_CHAMPION = 33962,
+ NPC_CRUSHER_TENTACLE = 33966,
+ NPC_CONSTRICTOR_TENTACLE = 33983,
+ NPC_CORRUPTOR_TENTACLE = 33985,
+ NPC_IMMORTAL_GUARDIAN = 33988,
+ NPC_SANITY_WELL = 33991,
+ NPC_DESCEND_INTO_MADNESS = 34072,
+ NPC_MARKED_IMMORTAL_GUARDIAN = 36064,
+
// Algalon the Observer
NPC_BRANN_BRONZBEARD_ALG = 34064,
NPC_AZEROTH = 34246,
@@ -155,6 +190,12 @@ enum UlduarGameObjects
GO_HODIR_ICE_DOOR = 194441,
GO_ARCHIVUM_DOOR = 194556,
+ // Yogg-Saron
+ GO_YOGG_SARON_DOOR = 194773,
+ GO_BRAIN_ROOM_DOOR_1 = 194635,
+ GO_BRAIN_ROOM_DOOR_2 = 194636,
+ GO_BRAIN_ROOM_DOOR_3 = 194637,
+
// Algalon the Observer
GO_CELESTIAL_PLANETARIUM_ACCESS_10 = 194628,
GO_CELESTIAL_PLANETARIUM_ACCESS_25 = 194752,
@@ -169,12 +210,18 @@ enum UlduarGameObjects
GO_GIFT_OF_THE_OBSERVER_25 = 194822,
};
-enum LeviathanData
+enum EventIds
{
EVENT_TOWER_OF_STORM_DESTROYED = 21031,
EVENT_TOWER_OF_FROST_DESTROYED = 21032,
EVENT_TOWER_OF_FLAMES_DESTROYED = 21033,
EVENT_TOWER_OF_LIFE_DESTROYED = 21030,
+ EVENT_ACTIVATE_SANITY_WELL = 21432,
+ EVENT_HODIRS_PROTECTIVE_GAZE_PROC = 21437,
+};
+
+enum LeviathanActions
+{
ACTION_TOWER_OF_STORM_DESTROYED = 1,
ACTION_TOWER_OF_FROST_DESTROYED = 2,
ACTION_TOWER_OF_FLAMES_DESTROYED = 3,
@@ -184,14 +231,30 @@ enum LeviathanData
enum UlduarAchievementCriteriaIds
{
- CRITERIA_CON_SPEED_ATORY = 21597,
- CRITERIA_DISARMED = 21687,
- CRITERIA_HERALD_OF_TITANS = 10678,
+ CRITERIA_CON_SPEED_ATORY = 21597,
+ CRITERIA_DISARMED = 21687,
+ CRITERIA_WAITS_DREAMING_STORMWIND_25 = 10321,
+ CRITERIA_WAITS_DREAMING_CHAMBER_25 = 10322,
+ CRITERIA_WAITS_DREAMING_ICECROWN_25 = 10323,
+ CRITERIA_WAITS_DREAMING_STORMWIND_10 = 10324,
+ CRITERIA_WAITS_DREAMING_CHAMBER_10 = 10325,
+ CRITERIA_WAITS_DREAMING_ICECROWN_10 = 10326,
+ CRITERIA_DRIVE_ME_CRAZY_10 = 10185,
+ CRITERIA_DRIVE_ME_CRAZY_25 = 10296,
+ CRITERIA_THREE_LIGHTS_IN_THE_DARKNESS_10 = 10410,
+ CRITERIA_THREE_LIGHTS_IN_THE_DARKNESS_25 = 10414,
+ CRITERIA_TWO_LIGHTS_IN_THE_DARKNESS_10 = 10388,
+ CRITERIA_TWO_LIGHTS_IN_THE_DARKNESS_25 = 10415,
+ CRITERIA_ONE_LIGHT_IN_THE_DARKNESS_10 = 10409,
+ CRITERIA_ONE_LIGHT_IN_THE_DARKNESS_25 = 10416,
+ CRITERIA_ALONE_IN_THE_DARKNESS_10 = 10412,
+ CRITERIA_ALONE_IN_THE_DARKNESS_25 = 10417,
+ CRITERIA_HERALD_OF_TITANS = 10678,
};
enum UlduarData
{
- // Collosus (Leviathan)
+ // Colossus (Leviathan)
DATA_COLOSSUS = 20,
// Razorscale
@@ -212,6 +275,18 @@ enum UlduarData
// Hodir
DATA_HODIR_RARE_CACHE,
+ // Yogg-Saron
+ DATA_VOICE_OF_YOGG_SARON,
+ DATA_SARA,
+ DATA_BRAIN_OF_YOGG_SARON,
+ DATA_FREYA_YS,
+ DATA_HODIR_YS,
+ DATA_THORIM_YS,
+ DATA_MIMIRON_YS,
+ DATA_ILLUSION,
+ DATA_DRIVE_ME_CRAZY,
+ DATA_KEEPERS_COUNT,
+
// Algalon the Observer
DATA_ALGALON_SUMMON_STATE,
DATA_SIGILDOOR_01,
@@ -245,6 +320,13 @@ enum UlduarEvents
ACTION_INIT_ALGALON = 6,
};
+enum YoggSaronIllusions
+{
+ CHAMBER_ILLUSION = 0,
+ ICECROWN_ILLUSION = 1,
+ STORMWIND_ILLUSION = 2,
+};
+
template<class AI>
CreatureAI* GetUlduarAI(Creature* creature)
{
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp
index 2b1d850ab25..8e726c10fca 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_palehoof.cpp
@@ -23,6 +23,7 @@ SDComment:
SDCategory:
Script Data End */
+#include <algorithm>
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "utgarde_pinnacle.h"
@@ -105,20 +106,25 @@ public:
uint32 uiWaitingTimer;
Phase currentPhase;
uint8 AddCount;
- bool DoneAdds[4];
+ Phase Sequence[4];
InstanceScript* instance;
void Reset()
{
+ /// There is a good reason to store them like this, we are going to shuffle the order.
+ for (uint32 i = PHASE_FRENZIED_WORGEN; i < PHASE_GORTOK_PALEHOOF; ++i)
+ Sequence[i] = Phase(i);
+
+ /// This ensures a random order and only executes each phase once.
+ std::random_shuffle(Sequence, Sequence + PHASE_GORTOK_PALEHOOF);
+
uiArcingSmashTimer = 15000;
uiImpaleTimer = 12000;
uiWhiteringRoarTimer = 10000;
me->GetMotionMaster()->MoveTargetedHome();
- for (uint32 i = 0; i < 4; i++)
- DoneAdds[i] = false;
AddCount = 0;
currentPhase = PHASE_NONE;
@@ -235,26 +241,7 @@ public:
if (AddCount >= DUNGEON_MODE(2, 4))
move = PHASE_GORTOK_PALEHOOF;
else
- {
- //select random not yet defeated add
- uint8 next = urand(0, 3);
- for (uint8 i = 0; i < 16; i++)
- {
- if (!DoneAdds[i % 4])
- {
- if (next == 0)
- {
- move = (Phase)(i % 4);
- break;
- }
- else if (next > 0)
- --next;
- }
- }
- ++AddCount;
- DoneAdds[move] = true;
- move = (Phase)(move % 4);
- }
+ move = Sequence[AddCount++];
//send orb to summon spot
Creature* pOrb = Unit::GetCreature((*me), instance ? instance->GetData64(DATA_MOB_ORB) : 0);
if (pOrb && pOrb->isAlive())
diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp
index 70b500166c9..0447d70b502 100644
--- a/src/server/scripts/Northrend/zone_icecrown.cpp
+++ b/src/server/scripts/Northrend/zone_icecrown.cpp
@@ -921,7 +921,7 @@ class npc_frostbrood_skytalon : public CreatureScript
if (id == POINT_GRAB_DECOY)
if (TempSummon* summon = me->ToTempSummon())
if (Unit* summoner = summon->GetSummoner())
- DoCast(summoner, SPELL_GRAB);
+ DoCast(summoner, SPELL_GRAB);
}
void UpdateAI(uint32 diff)
diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPHP.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPHP.cpp
index 55bb61b8c42..0ffab435a9c 100644
--- a/src/server/scripts/OutdoorPvP/OutdoorPvPHP.cpp
+++ b/src/server/scripts/OutdoorPvP/OutdoorPvPHP.cpp
@@ -62,6 +62,8 @@ OPvPCapturePointHP::OPvPCapturePointHP(OutdoorPvP* pvp, OutdoorPvPHPTowerType ty
OutdoorPvPHP::OutdoorPvPHP()
{
m_TypeId = OUTDOOR_PVP_HP;
+ m_AllianceTowersControlled = 0;
+ m_HordeTowersControlled = 0;
}
bool OutdoorPvPHP::SetupOutdoorPvP()
diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp
index bd6fd96451f..fe3489b4a7e 100644
--- a/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp
+++ b/src/server/scripts/OutdoorPvP/OutdoorPvPNA.cpp
@@ -27,6 +27,7 @@
OutdoorPvPNA::OutdoorPvPNA()
{
m_TypeId = OUTDOOR_PVP_NA;
+ m_obj = NULL;
}
void OutdoorPvPNA::HandleKillImpl(Player* player, Unit* killed)
@@ -216,8 +217,8 @@ bool OutdoorPvPNA::SetupOutdoorPvP()
m_obj = new OPvPCapturePointNA(this);
if (!m_obj)
return false;
- AddCapturePoint(m_obj);
+ AddCapturePoint(m_obj);
return true;
}
diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp
index bd8b6cfd982..98b0ee5c5f4 100644
--- a/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp
+++ b/src/server/scripts/OutdoorPvP/OutdoorPvPTF.cpp
@@ -28,6 +28,17 @@
OutdoorPvPTF::OutdoorPvPTF()
{
m_TypeId = OUTDOOR_PVP_TF;
+
+ m_IsLocked = false;
+ m_LockTimer = TF_LOCK_TIME;
+ m_LockTimerUpdate = 0;
+
+ m_AllianceTowersControlled = 0;
+ m_HordeTowersControlled = 0;
+
+ hours_left = 6;
+ second_digit = 0;
+ first_digit = 0;
}
OPvPCapturePointTF::OPvPCapturePointTF(OutdoorPvP* pvp, OutdoorPvPTF_TowerType type)
diff --git a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_gatewatcher_gyrokill.cpp b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_gatewatcher_gyrokill.cpp
index 2b597be8a9f..18ea83f7121 100644
--- a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_gatewatcher_gyrokill.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_gatewatcher_gyrokill.cpp
@@ -45,9 +45,9 @@ enum Spells
enum Events
{
- EVENT_STREAM_OF_MACHINE_FLUID = 0,
- EVENT_SAW_BLADE = 1,
- EVENT_SHADOW_POWER = 2
+ EVENT_STREAM_OF_MACHINE_FLUID = 1,
+ EVENT_SAW_BLADE = 2,
+ EVENT_SHADOW_POWER = 3
};
class boss_gatewatcher_gyrokill : public CreatureScript
diff --git a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp
index 902fb8e76b3..ce1322088e2 100644
--- a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp
@@ -52,11 +52,11 @@ enum Spells
enum Events
{
- EVENT_FROST_ATTACK = 0,
- EVENT_ARCANE_BLAST = 1,
- EVENT_DRAGONS_BREATH = 2,
- EVENT_KNOCKBACK = 3,
- EVENT_SOLARBURN = 4
+ EVENT_FROST_ATTACK = 1,
+ EVENT_ARCANE_BLAST = 2,
+ EVENT_DRAGONS_BREATH = 3,
+ EVENT_KNOCKBACK = 4,
+ EVENT_SOLARBURN = 5
};
class boss_nethermancer_sepethrea : public CreatureScript
diff --git a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp
index 65cd195fb80..d179e47b942 100644
--- a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp
@@ -54,11 +54,11 @@ enum Spells
enum Events
{
- EVENT_SUMMON = 0,
- EVENT_MANA_TAP = 1,
- EVENT_ARCANE_TORRENT = 2,
- EVENT_DOMINATION = 3,
- EVENT_ARCANE_EXPLOSION = 4
+ EVENT_SUMMON = 1,
+ EVENT_MANA_TAP = 2,
+ EVENT_ARCANE_TORRENT = 3,
+ EVENT_DOMINATION = 4,
+ EVENT_ARCANE_EXPLOSION = 5
};
enum Creatures
diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp
index b7719ae09fa..c1edf4b05d4 100644
--- a/src/server/scripts/Spells/spell_mage.cpp
+++ b/src/server/scripts/Spells/spell_mage.cpp
@@ -918,7 +918,7 @@ class spell_mage_ring_of_frost : public SpellScriptLoader
return true;
}
- void HandleEffectPeriodic(AuraEffect const* aurEff)
+ void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
{
if (ringOfFrost)
if (GetMaxDuration() - (int32)ringOfFrost->GetTimer() >= sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_DUMMY)->GetDuration())
@@ -1018,7 +1018,7 @@ class spell_mage_ring_of_frost_freeze : public SpellScriptLoader
return true;
}
- void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
if (GetCaster())
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index f430c93ccae..a5058cbf1d7 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -1745,7 +1745,7 @@ public:
{
me->HandleEmoteCommand(emote);
Unit* owner = me->GetOwner();
- if (emote != TEXT_EMOTE_KISS || owner || owner->GetTypeId() != TYPEID_PLAYER ||
+ if (emote != TEXT_EMOTE_KISS || !owner || owner->GetTypeId() != TYPEID_PLAYER ||
owner->ToPlayer()->GetTeam() != player->GetTeam())
{
return;
diff --git a/src/server/shared/Cryptography/SHA1.cpp b/src/server/shared/Cryptography/SHA1.cpp
index d02e9711014..00d7e520d51 100644
--- a/src/server/shared/Cryptography/SHA1.cpp
+++ b/src/server/shared/Cryptography/SHA1.cpp
@@ -23,6 +23,7 @@
SHA1Hash::SHA1Hash()
{
SHA1_Init(&mC);
+ memset(mDigest, 0, SHA_DIGEST_LENGTH * sizeof(uint8));
}
SHA1Hash::~SHA1Hash()
diff --git a/src/server/shared/Database/Field.cpp b/src/server/shared/Database/Field.cpp
index 9bd37641813..51d918e716e 100644
--- a/src/server/shared/Database/Field.cpp
+++ b/src/server/shared/Database/Field.cpp
@@ -22,6 +22,7 @@ Field::Field()
data.value = NULL;
data.type = MYSQL_TYPE_NULL;
data.length = 0;
+ data.raw = false;
}
Field::~Field()
diff --git a/src/server/shared/Database/MySQLConnection.cpp b/src/server/shared/Database/MySQLConnection.cpp
index 846c8ce72fe..4307cab98f2 100644
--- a/src/server/shared/Database/MySQLConnection.cpp
+++ b/src/server/shared/Database/MySQLConnection.cpp
@@ -84,8 +84,10 @@ bool MySQLConnection::Open()
int port;
char const* unix_socket;
+ //unsigned int timeout = 10;
mysql_options(mysqlInit, MYSQL_SET_CHARSET_NAME, "utf8");
+ //mysql_options(mysqlInit, MYSQL_OPT_READ_TIMEOUT, (char const*)&timeout);
#ifdef _WIN32
if (m_connectionInfo.host == ".") // named pipe use option (Windows)
{
diff --git a/src/server/shared/Database/PreparedStatement.cpp b/src/server/shared/Database/PreparedStatement.cpp
index 06f9ff51132..24097ca41c5 100644
--- a/src/server/shared/Database/PreparedStatement.cpp
+++ b/src/server/shared/Database/PreparedStatement.cpp
@@ -203,6 +203,7 @@ void PreparedStatement::setNull(const uint8 index)
}
MySQLPreparedStatement::MySQLPreparedStatement(MYSQL_STMT* stmt) :
+m_stmt(NULL),
m_Mstmt(stmt),
m_bind(NULL)
{
diff --git a/src/server/shared/Debugging/Errors.cpp b/src/server/shared/Debugging/Errors.cpp
index 10ede3ae402..1bfe8c8e949 100644
--- a/src/server/shared/Debugging/Errors.cpp
+++ b/src/server/shared/Debugging/Errors.cpp
@@ -20,33 +20,37 @@
#include <ace/Stack_Trace.h>
#include <ace/OS_NS_unistd.h>
+#include <cstdlib>
namespace Trinity {
-void Assert(char const *file, int line, char const *function, char const *message)
+void Assert(char const* file, int line, char const* function, char const* message)
{
ACE_Stack_Trace st;
fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n",
file, line, function, message, st.c_str());
*((volatile int*)NULL) = 0;
+ exit(1);
}
-void Fatal(char const *file, int line, char const *function, char const *message)
+void Fatal(char const* file, int line, char const* function, char const* message)
{
fprintf(stderr, "\n%s:%i in %s FATAL ERROR:\n %s\n",
file, line, function, message);
ACE_OS::sleep(10);
*((volatile int*)NULL) = 0;
+ exit(1);
}
-void Error(char const *file, int line, char const *function, char const *message)
+void Error(char const* file, int line, char const* function, char const* message)
{
fprintf(stderr, "\n%s:%i in %s ERROR:\n %s\n",
file, line, function, message);
*((volatile int*)NULL) = 0;
+ exit(1);
}
-void Warning(char const *file, int line, char const *function, char const *message)
+void Warning(char const* file, int line, char const* function, char const* message)
{
fprintf(stderr, "\n%s:%i in %s WARNING:\n %s\n",
file, line, function, message);
diff --git a/src/server/shared/Debugging/Errors.h b/src/server/shared/Debugging/Errors.h
index 554b20c3648..2821ca504e7 100644
--- a/src/server/shared/Debugging/Errors.h
+++ b/src/server/shared/Debugging/Errors.h
@@ -19,22 +19,25 @@
#ifndef TRINITYCORE_ERRORS_H
#define TRINITYCORE_ERRORS_H
-namespace Trinity {
+#include "Define.h"
-void Assert(char const *file, int line, char const *function, char const *message);
+namespace Trinity
+{
-void Fatal(char const *file, int line, char const *function, char const *message);
+ DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
-void Error(char const *file, int line, char const *function, char const *message);
+ DECLSPEC_NORETURN void Fatal(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
-void Warning(char const *file, int line, char const *function, char const *message);
+ DECLSPEC_NORETURN void Error(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
+
+ void Warning(char const* file, int line, char const* function, char const* message);
} // namespace Trinity
-#define WPAssert(cond) do { if (!(cond)) Trinity::Assert(__FILE__, __LINE__, __FUNCTION__, #cond); } while(0)
-#define WPFatal(cond, msg) do { if (!(cond)) Trinity::Fatal(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0)
-#define WPError(cond, msg) do { if (!(cond)) Trinity::Error(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0)
-#define WPWarning(cond, msg) do { if (!(cond)) Trinity::Warning(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0)
+#define WPAssert(cond) do { if (!(cond)) Trinity::Assert(__FILE__, __LINE__, __FUNCTION__, #cond); } while (0)
+#define WPFatal(cond, msg) do { if (!(cond)) Trinity::Fatal(__FILE__, __LINE__, __FUNCTION__, (msg)); } while (0)
+#define WPError(cond, msg) do { if (!(cond)) Trinity::Error(__FILE__, __LINE__, __FUNCTION__, (msg)); } while (0)
+#define WPWarning(cond, msg) do { if (!(cond)) Trinity::Warning(__FILE__, __LINE__, __FUNCTION__, (msg)); } while (0)
#define ASSERT WPAssert
diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h
index d7612c76738..e35e4f3ab7f 100644
--- a/src/server/shared/Logging/Log.h
+++ b/src/server/shared/Logging/Log.h
@@ -96,14 +96,14 @@ inline bool Log::ShouldLog(LogFilterType type, LogLevel level) const
#define sLog ACE_Singleton<Log, ACE_Thread_Mutex>::instance()
-#if PLATFORM != PLATFORM_WINDOWS
-# define TC_LOG_MESSAGE_BODY(level__, call__, filterType__, ...) \
+#if COMPILER != COMPILER_MICROSOFT
+#define TC_LOG_MESSAGE_BODY(level__, call__, filterType__, ...) \
do { \
if (sLog->ShouldLog(filterType__, level__)) \
sLog->call__(filterType__, __VA_ARGS__); \
} while (0)
#else
-# define TC_LOG_MESSAGE_BODY(level__, call__, filterType__, ...) \
+#define TC_LOG_MESSAGE_BODY(level__, call__, filterType__, ...) \
__pragma(warning(push)) \
__pragma(warning(disable:4127)) \
do { \
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index 0bbaff38be1..51b1a615bf1 100644
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -37,7 +37,7 @@ class ByteBufferException : public std::exception
public:
~ByteBufferException() throw() { }
- char const * what() const throw() { return msg_.c_str(); }
+ char const* what() const throw() { return msg_.c_str(); }
protected:
std::string & message() throw() { return msg_; }
diff --git a/src/server/shared/Threading/Callback.h b/src/server/shared/Threading/Callback.h
index f6bc1581857..e0215f5b3d3 100644
--- a/src/server/shared/Threading/Callback.h
+++ b/src/server/shared/Threading/Callback.h
@@ -35,7 +35,7 @@ template <typename Result, typename ParamType, bool chain = false>
class QueryCallback
{
public:
- QueryCallback() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) {}
+ QueryCallback() : _param(), _stage(chain ? 0 : CALLBACK_STAGE_INVALID) {}
//! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
void SetFutureResult(ACE_Future<Result> value)
diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt
index 1f9231ac0b8..e269c799f42 100644
--- a/src/server/worldserver/CMakeLists.txt
+++ b/src/server/worldserver/CMakeLists.txt
@@ -178,6 +178,7 @@ target_link_libraries(worldserver
${MYSQL_LIBRARY}
${OPENSSL_LIBRARIES}
${ZLIB_LIBRARIES}
+ ${CMAKE_THREAD_LIBS_INIT}
)
if( WIN32 )
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp
index 3f6a6d56c8b..f9c672b4945 100644
--- a/src/server/worldserver/Main.cpp
+++ b/src/server/worldserver/Main.cpp
@@ -58,15 +58,15 @@ uint32 realmID; ///< Id of the realm
/// Print out the usage string for this program on the console.
void usage(const char *prog)
{
- TC_LOG_INFO(LOG_FILTER_WORLDSERVER, "Usage: \n %s [<options>]\n"
- " -c config_file use config_file as configuration file\n\r"
- #ifdef _WIN32
- " Running as service functions:\n\r"
- " --service run as service\n\r"
- " -s install install service\n\r"
- " -s uninstall uninstall service\n\r"
- #endif
- , prog);
+ printf("Usage:\n");
+ printf(" %s [<options>]\n", prog);
+ printf(" -c config_file use config_file as configuration file\n");
+#ifdef _WIN32
+ printf(" Running as service functions:\n");
+ printf(" --service run as service\n");
+ printf(" -s install install service\n");
+ printf(" -s uninstall uninstall service\n");
+#endif
}
/// Launch the Trinity server
@@ -135,6 +135,7 @@ extern int main(int argc, char **argv)
printf("Verify that the file exists and has \'[worldserver]' written in the top of the file!\n");
return 1;
}
+
TC_LOG_INFO(LOG_FILTER_WORLDSERVER, "Using configuration file %s.", cfg_file);
TC_LOG_INFO(LOG_FILTER_WORLDSERVER, "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
diff --git a/src/server/worldserver/TCSoap/TCSoap.h b/src/server/worldserver/TCSoap/TCSoap.h
index b786ee94e81..63ccb6b304e 100644
--- a/src/server/worldserver/TCSoap/TCSoap.h
+++ b/src/server/worldserver/TCSoap/TCSoap.h
@@ -27,7 +27,7 @@
class TCSoapRunnable: public ACE_Based::Runnable
{
public:
- TCSoapRunnable() { }
+ TCSoapRunnable() : m_host(""), m_port(0) { }
void run();
void setListenArguments(std::string host, uint16 port)
{
diff --git a/src/tools/mmaps_generator/Info/readme.txt b/src/tools/mmaps_generator/Info/readme.txt
index 8d7c4f9d2e0..ff3f2f43526 100644
--- a/src/tools/mmaps_generator/Info/readme.txt
+++ b/src/tools/mmaps_generator/Info/readme.txt
@@ -1,5 +1,8 @@
Generator command line args
+--threads [#] Max number of threads used by the generator
+ Default: 3
+
--offMeshInput [file.*] Path to file containing off mesh connections data.
Format must be: (see offmesh_example.txt)
"map_id tile_x,tile_y (start_x start_y start_z) (end_x end_y end_z) size //optional comments"
@@ -63,4 +66,4 @@ movement_extractor 0
builds all tiles of map 0
movement_extractor 0 --tile 34,46
-builds only tile 34,46 of map 0 (this is the southern face of blackrock mountain) \ No newline at end of file
+builds only tile 34,46 of map 0 (this is the southern face of blackrock mountain)