aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/base/characters_database.sql9
-rw-r--r--sql/updates/characters/2015_01_10_00_characters.sql10
-rw-r--r--sql/updates/world/2015_01_10_00_world.sql13
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.h2
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp2
-rw-r--r--src/server/game/Combat/ThreatManager.cpp2
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp14
-rw-r--r--src/server/game/Conditions/DisableMgr.cpp2
-rw-r--r--src/server/game/DataStores/DBCEnums.h33
-rw-r--r--src/server/game/DataStores/DBCStores.cpp64
-rw-r--r--src/server/game/DataStores/DBCStores.h4
-rw-r--r--src/server/game/DataStores/DBCStructure.h27
-rw-r--r--src/server/game/DataStores/DBCfmt.h3
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp2
-rw-r--r--src/server/game/DungeonFinding/LFGScripts.cpp2
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp42
-rw-r--r--src/server/game/Entities/Creature/Creature.h39
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.h2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp4
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h4
-rw-r--r--src/server/game/Entities/Pet/Pet.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp184
-rw-r--r--src/server/game/Entities/Player/Player.h26
-rw-r--r--src/server/game/Entities/Totem/Totem.cpp2
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp60
-rw-r--r--src/server/game/Entities/Unit/Unit.h15
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp37
-rw-r--r--src/server/game/Globals/ObjectMgr.h4
-rw-r--r--src/server/game/Groups/Group.cpp141
-rw-r--r--src/server/game/Groups/Group.h19
-rw-r--r--src/server/game/Groups/GroupMgr.cpp8
-rw-r--r--src/server/game/Handlers/CalendarHandler.cpp8
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp5
-rw-r--r--src/server/game/Handlers/GroupHandler.cpp2
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp99
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp2
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.cpp92
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.h2
-rw-r--r--src/server/game/Instances/InstanceScript.cpp2
-rw-r--r--src/server/game/Maps/Map.cpp21
-rw-r--r--src/server/game/Maps/Map.h9
-rw-r--r--src/server/game/Maps/MapInstanced.cpp6
-rw-r--r--src/server/game/Maps/MapManager.cpp6
-rw-r--r--src/server/game/Quests/QuestDef.cpp4
-rw-r--r--src/server/game/Server/Packets/MiscPackets.cpp24
-rw-r--r--src/server/game/Server/Packets/MiscPackets.h46
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp7
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h7
-rw-r--r--src/server/game/Server/WorldSession.h6
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp10
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp10
-rw-r--r--src/server/game/Spells/Spell.cpp10
-rw-r--r--src/server/game/Spells/SpellEffects.cpp12
-rw-r--r--src/server/game/Spells/SpellInfo.cpp12
-rw-r--r--src/server/game/Spells/SpellInfo.h2
-rw-r--r--src/server/scripts/Commands/cs_instance.cpp8
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp11
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp4
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp2
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp8
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp10
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp4
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp2
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.cpp15
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.h1
69 files changed, 797 insertions, 458 deletions
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql
index 4fcc88a3a7d..88327122f26 100644
--- a/sql/base/characters_database.sql
+++ b/sql/base/characters_database.sql
@@ -1363,7 +1363,9 @@ CREATE TABLE `characters` (
`position_z` float NOT NULL DEFAULT '0',
`map` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Map Identifier',
`instance_id` int(10) unsigned NOT NULL DEFAULT '0',
- `instance_mode_mask` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `dungeonDifficulty` tinyint(3) unsigned NOT NULL DEFAULT '1',
+ `raidDifficulty` tinyint(3) unsigned NOT NULL DEFAULT '14',
+ `legacyRaidDifficulty` tinyint(3) unsigned NOT NULL DEFAULT '3',
`orientation` float NOT NULL DEFAULT '0',
`taximask` text NOT NULL,
`online` tinyint(3) unsigned NOT NULL DEFAULT '0',
@@ -1731,8 +1733,9 @@ CREATE TABLE `groups` (
`icon7` binary(16) NOT NULL,
`icon8` binary(16) NOT NULL,
`groupType` tinyint(3) unsigned NOT NULL,
- `difficulty` tinyint(3) unsigned NOT NULL DEFAULT '0',
- `raiddifficulty` tinyint(3) unsigned NOT NULL DEFAULT '0',
+ `difficulty` tinyint(3) unsigned NOT NULL DEFAULT '1',
+ `raidDifficulty` tinyint(3) unsigned NOT NULL DEFAULT '14',
+ `legacyRaidDifficulty` tinyint(3) unsigned NOT NULL DEFAULT '3',
`masterLooterGuid` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`guid`),
KEY `leaderGuid` (`leaderGuid`)
diff --git a/sql/updates/characters/2015_01_10_00_characters.sql b/sql/updates/characters/2015_01_10_00_characters.sql
new file mode 100644
index 00000000000..c0070507b6d
--- /dev/null
+++ b/sql/updates/characters/2015_01_10_00_characters.sql
@@ -0,0 +1,10 @@
+ALTER TABLE `characters`
+ DROP `instance_mode_mask`,
+ ADD `dungeonDifficulty` tinyint(3) unsigned NOT NULL DEFAULT '1' AFTER `instance_id`,
+ ADD `raidDifficulty` tinyint(3) unsigned NOT NULL DEFAULT '14' AFTER `dungeonDifficulty`,
+ ADD `legacyRaidDifficulty` tinyint(3) unsigned NOT NULL DEFAULT '3' AFTER `raidDifficulty`;
+
+ALTER TABLE `groups`
+ CHANGE `difficulty` `difficulty` tinyint(3) unsigned NOT NULL DEFAULT '1' AFTER `groupType`,
+ CHANGE `raiddifficulty` `raidDifficulty` tinyint(3) unsigned NOT NULL DEFAULT '14' AFTER `difficulty`,
+ ADD `legacyRaidDifficulty` tinyint(3) unsigned NOT NULL DEFAULT '3' AFTER `raidDifficulty`;
diff --git a/sql/updates/world/2015_01_10_00_world.sql b/sql/updates/world/2015_01_10_00_world.sql
new file mode 100644
index 00000000000..d5943731a50
--- /dev/null
+++ b/sql/updates/world/2015_01_10_00_world.sql
@@ -0,0 +1,13 @@
+ALTER TABLE `creature` CHANGE `spawnMask` `spawnMask` int(10) unsigned not null default '1';
+
+UPDATE `creature` SET `spawnMask`=`spawnMask`<<1 WHERE `map` IN (33,34,36,43,44,47,48,70,90,109,129,189,209,229,230,269,289,309,329,349,389,429,540,542,543,545,546,547,552,553,554,555,556,557,558,560,568,574,575,576,578,585,595,598,599,600,601,602,604,608,619,627,632,637,643,644,645,650,657,658,668,670,721,725,727,728,734,755,859,930,938,939,940,951,977);
+UPDATE `creature` SET `spawnMask`=`spawnMask`<<3 WHERE `map` IN (249,509,532,533,603,615,616,624,631,649,669,671,720,724,754,757,967);
+UPDATE `creature` SET `spawnMask`=`spawnMask`<<4 WHERE `map` IN (534,544,548,550,564,565,580);
+UPDATE `creature` SET `spawnMask`=`spawnMask`<<9 WHERE `map` IN (169,409,469,531,605);
+
+ALTER TABLE `gameobject` CHANGE `spawnMask` `spawnMask` int(10) unsigned not null default '1';
+
+UPDATE `gameobject` SET `spawnMask`=`spawnMask`<<1 WHERE `map` IN (33,34,36,43,44,47,48,70,90,109,129,189,209,229,230,269,289,309,329,349,389,429,540,542,543,545,546,547,552,553,554,555,556,557,558,560,568,574,575,576,578,585,595,598,599,600,601,602,604,608,619,627,632,637,643,644,645,650,657,658,668,670,721,725,727,728,734,755,859,930,938,939,940,951,977);
+UPDATE `gameobject` SET `spawnMask`=`spawnMask`<<3 WHERE `map` IN (249,509,532,533,603,615,616,624,631,649,669,671,720,724,754,757,967);
+UPDATE `gameobject` SET `spawnMask`=`spawnMask`<<4 WHERE `map` IN (534,544,548,550,564,565,580);
+UPDATE `gameobject` SET `spawnMask`=`spawnMask`<<9 WHERE `map` IN (169,409,469,531,605);
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
index 351877fed6f..9b92840ecf0 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
@@ -275,7 +275,7 @@ struct ScriptedAI : public CreatureAI
Difficulty GetDifficulty() const { return _difficulty; }
// return true for 25 man or 25 man heroic mode
- bool Is25ManRaid() const { return _difficulty & RAID_DIFFICULTY_MASK_25MAN; }
+ bool Is25ManRaid() const { return _difficulty == DIFFICULTY_25_N || _difficulty == DIFFICULTY_25_HC; }
template<class T> inline
const T& DUNGEON_MODE(const T& normal5, const T& heroic10) const
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 36edfab420c..ba2571884dc 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -2709,7 +2709,7 @@ bool AchievementMgr<T>::AdditionalRequirementsSatisfied(ModifierTreeNode const*
break;
}
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY: // 20
- if (uint32(referencePlayer->GetMap()->GetDifficulty()) != reqValue)
+ if (uint32(referencePlayer->GetMap()->GetDifficultyID()) != reqValue)
return false;
break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ARENA_TYPE:
diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp
index 406f4702c3b..18ead47c490 100644
--- a/src/server/game/Combat/ThreatManager.cpp
+++ b/src/server/game/Combat/ThreatManager.cpp
@@ -41,7 +41,7 @@ float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float
threat *= threatEntry->pctMod;
// Energize is not affected by Mods
- for (SpellEffectInfo const* effect : threatSpell->GetEffectsForDifficulty(hatedUnit->GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : threatSpell->GetEffectsForDifficulty(hatedUnit->GetMap()->GetDifficultyID()))
if (effect && (effect->Effect == SPELL_EFFECT_ENERGIZE || effect->ApplyAuraName == SPELL_AURA_PERIODIC_ENERGIZE))
return threat;
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 20d49855b8f..2542706e507 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -1234,30 +1234,34 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
SpellEffectInfo const* effect = spellInfo->GetEffect(DIFFICULTY_NONE, i);
if (!effect)
continue;
+
// check if effect is already a part of some shared mask
bool found = false;
for (std::list<uint32>::iterator itr = sharedMasks.begin(); itr != sharedMasks.end(); ++itr)
{
- if ((1<<i) & *itr)
+ if ((1 << i) & *itr)
{
found = true;
break;
}
}
+
if (found)
continue;
// build new shared mask with found effect
- uint32 sharedMask = (1<<i);
+ uint32 sharedMask = 1 << i;
ConditionList* cmp = effect->ImplicitTargetConditions;
- for (uint8 effIndex = i+1; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
+ for (uint8 effIndex = i + 1; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
{
SpellEffectInfo const* inner = spellInfo->GetEffect(DIFFICULTY_NONE, effIndex);
if (!inner)
continue;
+
if (inner->ImplicitTargetConditions == cmp)
- sharedMask |= 1<<effIndex;
+ sharedMask |= 1 << effIndex;
}
+
sharedMasks.push_back(sharedMask);
}
@@ -1304,7 +1308,7 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
if (!eff)
continue;
- if ((1<<i) & commonMask)
+ if ((1 << i) & commonMask)
{
const_cast<SpellEffectInfo*>(eff)->ImplicitTargetConditions = sharedList;
assigned = true;
diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp
index a097605afb1..c2527b1d28f 100644
--- a/src/server/game/Conditions/DisableMgr.cpp
+++ b/src/server/game/Conditions/DisableMgr.cpp
@@ -333,7 +333,7 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags
if (mapEntry->IsDungeon())
{
uint8 disabledModes = itr->second.flags;
- Difficulty targetDifficulty = player->GetDifficulty(mapEntry->IsRaid());
+ Difficulty targetDifficulty = player->GetDifficultyID(mapEntry);
GetDownscaledMapDifficultyData(entry, targetDifficulty);
switch (targetDifficulty)
{
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 671e2816a19..cf8701dc0d7 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -352,21 +352,28 @@ enum Difficulty
DIFFICULTY_40 = 9,
DIFFICULTY_HC_SCENARIO = 11,
DIFFICULTY_N_SCENARIO = 12,
- DIFFICULTY_NORMAL2 = 14,
- DIFFICULTY_HEROIC2 = 15,
- DIFFICULTY_MYTHIC = 16,
- DIFFICULTY_LFR2 = 17,
- DIFFICULTY_EVENT = 18,
- DIFFICULTY_EVENT2 = 19,
+ DIFFICULTY_NORMAL_RAID = 14,
+ DIFFICULTY_HEROIC_RAID = 15,
+ DIFFICULTY_MYTHIC_RAID = 16,
+ DIFFICULTY_LFR_NEW = 17,
+ DIFFICULTY_EVENT_RAID = 18,
+ DIFFICULTY_EVENT_DUNGEON = 19,
DIFFICULTY_EVENT_SCENARIO = 20,
- DIFFICULTY_MAX = 21,
+
+ MAX_DIFFICULTY
};
-#define RAID_DIFFICULTY_MASK_25MAN 1 // since 25man difficulties are 1 and 3, we can check them like that
+enum DifficultyFlags
+{
+ DIFFICULTY_FLAG_HEROIC = 0x01,
+ DIFFICULTY_FLAG_DEFAULT = 0x02,
+ DIFFICULTY_FLAG_CAN_SELECT = 0x04, // Player can select this difficulty in dropdown menu
+ DIFFICULTY_FLAG_CHALLENGE_MODE = 0x08,
-#define MAX_DUNGEON_DIFFICULTY 3
-#define MAX_RAID_DIFFICULTY 4
-#define MAX_DIFFICULTY 4
+ DIFFICULTY_FLAG_LEGACY = 0x20,
+ DIFFICULTY_FLAG_DISPLAY_HEROIC = 0x40, // Controls icon displayed on minimap when inside the instance
+ DIFFICULTY_FLAG_DISPLAY_MYTHIC = 0x80 // Controls icon displayed on minimap when inside the instance
+};
enum SpawnMask
{
@@ -415,7 +422,9 @@ enum MapTypes // Lua_IsInInstance
enum MapFlags
{
- MAP_FLAG_DYNAMIC_DIFFICULTY = 0x100
+ MAP_FLAG_CAN_TOGGLE_DIFFICULTY = 0x0100,
+ MAP_FLAG_FLEX_LOCKING = 0x8000, // All difficulties share completed encounters lock, not bound to a single instance id
+ // heroic difficulty flag overrides it and uses instance id bind
};
enum AbilytyLearnType
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index 6c0cc92550c..783827a4f93 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -90,6 +90,7 @@ DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore(CurrencyTypesfmt);
uint32 PowersByClass[MAX_CLASSES][MAX_POWERS];
DBCStorage <DestructibleModelDataEntry> sDestructibleModelDataStore(DestructibleModelDatafmt);
+DBCStorage <DifficultyEntry> sDifficultyStore(DifficultyFmt);
DBCStorage <DungeonEncounterEntry> sDungeonEncounterStore(DungeonEncounterfmt);
DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore(DurabilityQualityfmt);
DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore(DurabilityCostsfmt);
@@ -415,13 +416,14 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales, bad_dbc_files, sCriteriaTreeStore, dbcPath, "CriteriaTree.dbc");//19342
LoadDBC(availableDbcLocales, bad_dbc_files, sCurrencyTypesStore, dbcPath, "CurrencyTypes.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sDestructibleModelDataStore, dbcPath, "DestructibleModelData.dbc");//19116
+ LoadDBC(availableDbcLocales, bad_dbc_files, sDifficultyStore, dbcPath, "Difficulty.dbc");//19342
LoadDBC(availableDbcLocales, bad_dbc_files, sDungeonEncounterStore, dbcPath, "DungeonEncounter.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityCostsStore, dbcPath, "DurabilityCosts.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityQualityStore, dbcPath, "DurabilityQuality.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesStore, dbcPath, "Emotes.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesTextStore, dbcPath, "EmotesText.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sFactionStore, dbcPath, "Faction.dbc");//19116
- for (uint32 i=0; i<sFactionStore.GetNumRows(); ++i)
+ for (uint32 i = 0; i < sFactionStore.GetNumRows(); ++i)
{
FactionEntry const* faction = sFactionStore.LookupEntry(i);
if (faction && faction->ParentFactionID)
@@ -491,10 +493,10 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales, bad_dbc_files, sMapStore, dbcPath, "Map.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sMapDifficultyStore, dbcPath, "MapDifficulty.dbc");//19116
// fill data
- sMapDifficultyMap[MAKE_PAIR32(0, 0)] = MapDifficulty(0, 0, false);//map 0 is missingg from MapDifficulty.dbc use this till its ported to sql
+ sMapDifficultyMap[0][0] = MapDifficulty(DIFFICULTY_NONE, 0, 0, false);//map 0 is missingg from MapDifficulty.dbc use this till its ported to sql
for (uint32 i = 0; i < sMapDifficultyStore.GetNumRows(); ++i)
if (MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i))
- sMapDifficultyMap[MAKE_PAIR32(entry->MapID, entry->DifficultyID)] = MapDifficulty(entry->RaidDuration, entry->MaxPlayers, entry->Message_lang[0] > 0);
+ sMapDifficultyMap[entry->MapID][entry->DifficultyID] = MapDifficulty(entry->DifficultyID, entry->RaidDuration, entry->MaxPlayers, entry->Message_lang[0] > 0);
sMapDifficultyStore.Clear();
LoadDBC(availableDbcLocales, bad_dbc_files, sModifierTreeStore, dbcPath, "ModifierTree.dbc");//19342
@@ -950,35 +952,63 @@ void Map2ZoneCoordinates(float& x, float& y, uint32 zone)
if (!maEntry)
return;
- x = (x-maEntry->LocTop)/((maEntry->LocBottom-maEntry->LocTop)/100);
- y = (y-maEntry->LocLeft)/((maEntry->LocRight-maEntry->LocLeft)/100); // client y coord from top to down
+ x = (x - maEntry->LocTop) / ((maEntry->LocBottom - maEntry->LocTop) / 100);
+ y = (y - maEntry->LocLeft) / ((maEntry->LocRight - maEntry->LocLeft) / 100); // client y coord from top to down
std::swap(x, y); // client have map coords swapped
}
+MapDifficulty const* GetDefaultMapDifficulty(uint32 mapID)
+{
+ auto itr = sMapDifficultyMap.find(mapID);
+ if (itr == sMapDifficultyMap.end())
+ return nullptr;
+
+ if (itr->second.empty())
+ return nullptr;
+
+ for (auto& p : itr->second)
+ {
+ DifficultyEntry const* difficulty = sDifficultyStore.LookupEntry(p.first);
+ if (!difficulty)
+ continue;
+
+ if (difficulty->Flags & DIFFICULTY_FLAG_DEFAULT)
+ return &p.second;
+ }
+
+ return &itr->second.begin()->second;
+}
+
MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
{
- MapDifficultyMap::const_iterator itr = sMapDifficultyMap.find(MAKE_PAIR32(mapId, difficulty));
- return itr != sMapDifficultyMap.end() ? &itr->second : NULL;
+ auto itr = sMapDifficultyMap.find(mapId);
+ if (itr == sMapDifficultyMap.end())
+ return nullptr;
+
+ auto diffItr = itr->second.find(difficulty);
+ if (diffItr == itr->second.end())
+ return nullptr;
+
+ return &diffItr->second;
}
MapDifficulty const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &difficulty)
{
+ DifficultyEntry const* diffEntry = sDifficultyStore.LookupEntry(difficulty);
+ if (!diffEntry)
+ return GetDefaultMapDifficulty(mapId);
+
uint32 tmpDiff = difficulty;
MapDifficulty const* mapDiff = GetMapDifficultyData(mapId, Difficulty(tmpDiff));
- if (!mapDiff)
+ while (!mapDiff)
{
- if (tmpDiff > DIFFICULTY_25_N) // heroic, downscale to normal
- tmpDiff -= 2;
- else
- tmpDiff -= 1; // any non-normal mode for raids like tbc (only one mode)
+ tmpDiff = diffEntry->FallbackDifficultyID;
+ diffEntry = sDifficultyStore.LookupEntry(tmpDiff);
+ if (!diffEntry)
+ return GetDefaultMapDifficulty(mapId);
// pull new data
mapDiff = GetMapDifficultyData(mapId, Difficulty(tmpDiff)); // we are 10 normal or 25 normal
- if (!mapDiff)
- {
- tmpDiff -= 1;
- mapDiff = GetMapDifficultyData(mapId, Difficulty(tmpDiff)); // 10 normal
- }
}
difficulty = Difficulty(tmpDiff);
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index b73fbcf02f5..7bc8dcf5b64 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -70,7 +70,8 @@ uint32 GetClassBySkillId(uint32 skillId);
uint32 GetSkillIdByClass(uint32 classId);
std::list<uint32> GetSpellsForLevels(uint32 classId, uint32 raceMask, uint32 specializationId, uint32 minLevel, uint32 maxLevel);
-typedef std::map<uint32/*pair32(map, diff)*/, MapDifficulty> MapDifficultyMap;
+typedef std::unordered_map<uint32, std::unordered_map<uint32, MapDifficulty>> MapDifficultyMap;
+MapDifficulty const* GetDefaultMapDifficulty(uint32 mapID);
MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty);
MapDifficulty const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &difficulty);
@@ -156,6 +157,7 @@ extern DBCStorage <CriteriaEntry> sCriteriaStore;
extern DBCStorage <CriteriaTreeEntry> sCriteriaTreeStore;
extern DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore;
extern DBCStorage <DestructibleModelDataEntry> sDestructibleModelDataStore;
+extern DBCStorage <DifficultyEntry> sDifficultyStore;
extern DBCStorage <DungeonEncounterEntry> sDungeonEncounterStore;
extern DBCStorage <DurabilityCostsEntry> sDurabilityCostsStore;
extern DBCStorage <DurabilityQualityEntry> sDurabilityQualityStore;
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index a87083882e2..813f7ba4019 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -620,6 +620,23 @@ struct DestructibleModelDataEntry
//uint32 HealEffectSpeed; // 23
};
+struct DifficultyEntry
+{
+ uint32 ID; // 0
+ uint32 FallbackDifficultyID; // 1
+ uint32 InstanceType; // 2
+ uint32 MinPlayers; // 3
+ uint32 MaxPlayers; // 4
+ //int32 OldEnumValue; // 5
+ uint32 Flags; // 6
+ uint32 ToggleDifficultyID; // 7
+ //uint32 GroupSizeHealthCurveID; // 8
+ //uint32 GroupSizeDmgCurveID; // 9
+ //uint32 GroupSizeSpellPointsCurveID; // 10
+ //char const* NameLang; // 11
+ //uint32 Unk; // 12
+};
+
struct DungeonEncounterEntry
{
uint32 ID; // 0
@@ -1202,7 +1219,7 @@ struct MapEntry
return ID == 0 || ID == 1 || ID == 530 || ID == 571 || ID == 870 || ID == 1116;
}
- bool IsDynamicDifficultyMap() const { return (Flags & MAP_FLAG_DYNAMIC_DIFFICULTY) != 0; }
+ bool IsDynamicDifficultyMap() const { return (Flags & MAP_FLAG_CAN_TOGGLE_DIFFICULTY) != 0; }
};
struct MapDifficultyEntry
@@ -1213,7 +1230,7 @@ struct MapDifficultyEntry
char* Message_lang; // 3 m_message_lang (text showed when transfer to map failed)
uint32 RaidDuration; // 4 m_raidDuration in secs, 0 if no fixed reset time
uint32 MaxPlayers; // 5 m_maxPlayers some heroic versions have 0 when expected same amount as in normal version
- //uint32 Unk1; // 6
+ uint32 LockID; // 6
//uint32 Unk2; // 7
};
@@ -2021,9 +2038,11 @@ typedef std::map<uint32, VectorArray> NameGenContainer;
// Structures not used for casting to loaded DBC data and not required then packing
struct MapDifficulty
{
- MapDifficulty() : resetTime(0), maxPlayers(0), hasErrorMessage(false) { }
- MapDifficulty(uint32 _resetTime, uint32 _maxPlayers, bool _hasErrorMessage) : resetTime(_resetTime), maxPlayers(_maxPlayers), hasErrorMessage(_hasErrorMessage) { }
+ MapDifficulty() : DifficultyID(0), resetTime(0), maxPlayers(0), hasErrorMessage(false) { }
+ MapDifficulty(uint32 difficultyID, uint32 _resetTime, uint32 _maxPlayers, bool _hasErrorMessage)
+ : DifficultyID(difficultyID), resetTime(_resetTime), maxPlayers(_maxPlayers), hasErrorMessage(_hasErrorMessage) { }
+ uint32 DifficultyID;
uint32 resetTime;
uint32 maxPlayers;
bool hasErrorMessage;
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index 540e1951b72..3f9f01cab16 100644
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -52,6 +52,7 @@ char const Criteriafmt[] = "niiiiiiiixii";
char const CriteriaTreefmt[] = "niliixxx";
char const CurrencyTypesfmt[] = "nixxxxxiiixx";
char const DestructibleModelDatafmt[] = "nixxxixxxxixxxxixxxxxxxx";
+char const DifficultyFmt[] = "niiiixiixxxxx";
char const DungeonEncounterfmt[] = "niiixsxxx";
char const DurabilityCostsfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
char const DurabilityQualityfmt[] = "nf";
@@ -106,7 +107,7 @@ char const LockEntryfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
char const PhaseEntryfmt[] = "ni";
char const MailTemplateEntryfmt[] = "nxs";
char const MapEntryfmt[] = "nxiixxsixxixiffxiiiixx";
-char const MapDifficultyEntryfmt[] = "diisiixx";
+char const MapDifficultyEntryfmt[] = "diisiiix";
char const MinorTalentEntryfmt[] = "niii";
char const MovieEntryfmt[] = "nxxxx";
char const ModifierTreefmt[] = "niiiiii";
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index 064c1e4f105..0a2763f97b7 100644
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -924,7 +924,7 @@ void LFGMgr::MakeNewGroup(LfgProposal const& proposal)
}
ASSERT(grp);
- grp->SetDungeonDifficulty(Difficulty(dungeon->difficulty));
+ grp->SetDungeonDifficultyID(Difficulty(dungeon->difficulty));
ObjectGuid gguid = grp->GetGUID();
SetDungeon(gguid, dungeon->Entry());
SetState(gguid, LFG_STATE_DUNGEON);
diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp
index 86edaa2349e..c77ab9a36c5 100644
--- a/src/server/game/DungeonFinding/LFGScripts.cpp
+++ b/src/server/game/DungeonFinding/LFGScripts.cpp
@@ -74,7 +74,7 @@ void LFGPlayerScript::OnMapChanged(Player* player)
{
Map const* map = player->GetMap();
- if (sLFGMgr->inLfgDungeonMap(player->GetGUID(), map->GetId(), map->GetDifficulty()))
+ if (sLFGMgr->inLfgDungeonMap(player->GetGUID(), map->GetId(), map->GetDifficultyID()))
{
Group* group = player->GetGroup();
// This function is also called when players log in
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index f4567fbc1b7..070263cd85e 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -269,27 +269,29 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/)
}
// get difficulty 1 mode entry
- CreatureTemplate const* cinfo = normalInfo;
- for (uint8 diff = uint8(GetMap()->GetSpawnMode()); diff > 0;)
+ CreatureTemplate const* cinfo = nullptr;
+ DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(GetMap()->GetSpawnMode());
+ while (!cinfo && difficultyEntry)
{
- // we already have valid Map pointer for current creature!
- if (normalInfo->DifficultyEntry[diff - 1])
- {
- cinfo = sObjectMgr->GetCreatureTemplate(normalInfo->DifficultyEntry[diff - 1]);
- if (cinfo)
- break; // template found
+ int32 idx = CreatureTemplate::DifficultyIDToDifficultyEntryIndex(difficultyEntry->ID);
+ if (idx == -1)
+ break;
- // check and reported at startup, so just ignore (restore normalInfo)
- cinfo = normalInfo;
+ if (normalInfo->DifficultyEntry[idx])
+ {
+ cinfo = sObjectMgr->GetCreatureTemplate(normalInfo->DifficultyEntry[idx]);
+ break;
}
- // for instances heroic to normal, other cases attempt to retrieve previous difficulty
- if (diff >= DIFFICULTY_10_HC && GetMap()->IsRaid())
- diff -= 2; // to normal raid difficulty cases
- else
- --diff;
+ if (!difficultyEntry->FallbackDifficultyID)
+ break;
+
+ difficultyEntry = sDifficultyStore.LookupEntry(difficultyEntry->FallbackDifficultyID);
}
+ if (!cinfo)
+ cinfo = normalInfo;
+
// Initialize loot duplicate count depending on raid difficulty
if (GetMap()->Is25ManRaid())
loot.maxDuplicates = 3;
@@ -946,7 +948,7 @@ void Creature::SaveToDB()
SaveToDB(mapId, data->spawnMask, GetPhaseMask());
}
-void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
+void Creature::SaveToDB(uint32 mapid, uint32 spawnMask, uint32 phaseMask)
{
// update in loaded data
if (!m_DBTableGuid)
@@ -1620,7 +1622,7 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo) const
// This check must be done instead of 'if (GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1)))' for not break
// the check of mechanic immunity on DB (tested) because GetCreatureTemplate()->MechanicImmuneMask and m_spellImmune[IMMUNITY_MECHANIC] don't have same data.
bool immunedToAllEffects = true;
- for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficultyID()))
{
if (!effect || !effect->IsEffect())
continue;
@@ -1638,7 +1640,7 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo) const
bool Creature::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const
{
- SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficulty());
+ SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficultyID());
if (!effect)
return true;
if (GetCreatureTemplate()->MechanicImmuneMask & (1 << (effect->Mechanic - 1)))
@@ -1684,7 +1686,7 @@ SpellInfo const* Creature::reachWithSpellAttack(Unit* victim)
}
bool bcontinue = true;
- for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficultyID()))
{
if (effect && ((effect->Effect == SPELL_EFFECT_SCHOOL_DAMAGE) ||
(effect->Effect == SPELL_EFFECT_INSTAKILL) ||
@@ -1732,7 +1734,7 @@ SpellInfo const* Creature::reachWithSpellCure(Unit* victim)
}
bool bcontinue = true;
- for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficultyID()))
{
if (effect && (effect->Effect == SPELL_EFFECT_HEAL))
{
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index ff43f73d1c6..842624e0c01 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -72,12 +72,13 @@ enum CreatureFlagsExtra
#define MAX_CREATURE_QUEST_ITEMS 6
#define MAX_CREATURE_NAMES 4
#define CREATURE_MAX_SPELLS 8
+#define MAX_CREATURE_DIFFICULTIES 3
// from `creature_template` table
struct CreatureTemplate
{
uint32 Entry;
- uint32 DifficultyEntry[MAX_DIFFICULTY - 1];
+ uint32 DifficultyEntry[MAX_CREATURE_DIFFICULTIES];
uint32 KillCredit[MAX_KILL_CREDIT];
uint32 Modelid1;
uint32 Modelid2;
@@ -170,6 +171,38 @@ struct CreatureTemplate
// if can tame exotic then can tame any tameable
return canTameExotic || !IsExotic();
}
+
+ static int32 DifficultyIDToDifficultyEntryIndex(uint32 difficulty)
+ {
+ switch (difficulty)
+ {
+ case DIFFICULTY_NONE:
+ case DIFFICULTY_NORMAL:
+ case DIFFICULTY_10_N:
+ case DIFFICULTY_40:
+ case DIFFICULTY_N_SCENARIO:
+ case DIFFICULTY_NORMAL_RAID:
+ return -1;
+ case DIFFICULTY_HEROIC:
+ case DIFFICULTY_25_N:
+ case DIFFICULTY_HC_SCENARIO:
+ case DIFFICULTY_HEROIC_RAID:
+ return 0;
+ case DIFFICULTY_10_HC:
+ case DIFFICULTY_CHALLENGE:
+ case DIFFICULTY_MYTHIC_RAID:
+ return 1;
+ case DIFFICULTY_25_HC:
+ return 2;
+ case DIFFICULTY_LFR:
+ case DIFFICULTY_LFR_NEW:
+ case DIFFICULTY_EVENT_RAID:
+ case DIFFICULTY_EVENT_DUNGEON:
+ case DIFFICULTY_EVENT_SCENARIO:
+ default:
+ return -1;
+ }
+ }
};
// Benchmarked: Faster than std::map (insert/find)
@@ -274,7 +307,7 @@ struct CreatureData
uint32 curhealth;
uint32 curmana;
uint8 movementType;
- uint8 spawnMask;
+ uint32 spawnMask;
uint32 npcflag;
uint32 unit_flags; // enum UnitFlags mask values
uint32 dynamicflags;
@@ -549,7 +582,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
bool LoadCreatureFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true);
void SaveToDB();
// overriden in Pet
- virtual void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
+ virtual void SaveToDB(uint32 mapid, uint32 spawnMask, uint32 phaseMask);
virtual void DeleteFromDB(); // overriden in Pet
Loot loot;
diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h
index 16fd7c11683..378061d2905 100644
--- a/src/server/game/Entities/Creature/TemporarySummon.h
+++ b/src/server/game/Entities/Creature/TemporarySummon.h
@@ -48,7 +48,7 @@ class TempSummon : public Creature
virtual void UnSummon(uint32 msTime = 0);
void RemoveFromWorld() override;
void SetTempSummonType(TempSummonType type);
- void SaveToDB(uint32 /*mapid*/, uint8 /*spawnMask*/, uint32 /*phaseMask*/) override { }
+ void SaveToDB(uint32 /*mapid*/, uint32 /*spawnMask*/, uint32 /*phaseMask*/) override { }
Unit* GetSummoner() const;
Creature* GetSummonerCreatureBase() const;
ObjectGuid GetSummonerGUID() const { return m_summonerGUID; }
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 929f7b90689..78efc590566 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -773,7 +773,7 @@ void GameObject::SaveToDB()
SaveToDB(GetMapId(), data->spawnMask, data->phaseMask);
}
-void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
+void GameObject::SaveToDB(uint32 mapid, uint32 spawnMask, uint32 phaseMask)
{
const GameObjectTemplate* goI = GetGOInfo();
@@ -1809,7 +1809,7 @@ void GameObject::CastSpell(Unit* target, uint32 spellId, bool triggered /*= true
return;
bool self = false;
- for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficultyID()))
{
if (effect && effect->TargetA.GetTarget() == TARGET_UNIT_CASTER)
{
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index a242e04ea37..239324c572d 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -828,7 +828,7 @@ struct GameObjectData
int32 spawntimesecs;
uint32 animprogress;
GOState go_state;
- uint8 spawnMask;
+ uint32 spawnMask;
uint8 artKit;
uint32 phaseid;
uint32 phaseGroup;
@@ -883,7 +883,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map
std::string const& GetNameForLocaleIdx(LocaleConstant locale_idx) const override;
void SaveToDB();
- void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
+ void SaveToDB(uint32 mapid, uint32 spawnMask, uint32 phaseMask);
bool LoadFromDB(ObjectGuid::LowType guid, Map* map) { return LoadGameObjectFromDB(guid, map, false); }
bool LoadGameObjectFromDB(ObjectGuid::LowType guid, Map* map, bool addToMap = true);
void DeleteFromDB();
diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h
index 853eb5c691c..e9ace117dde 100644
--- a/src/server/game/Entities/Pet/Pet.h
+++ b/src/server/game/Entities/Pet/Pet.h
@@ -156,7 +156,7 @@ class Pet : public Guardian
DeclinedName *m_declinedname;
private:
- void SaveToDB(uint32, uint8, uint32) override // override of Creature::SaveToDB - must not be called
+ void SaveToDB(uint32, uint32, uint32) override // override of Creature::SaveToDB - must not be called
{
ASSERT(false);
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 9da2865277e..3ef12a96f8c 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -790,8 +790,9 @@ Player::Player(WorldSession* session): Unit(true)
m_HomebindTimer = 0;
m_InstanceValid = true;
m_dungeonDifficulty = DIFFICULTY_NORMAL;
- m_raidDifficulty = DIFFICULTY_10_N;
- m_raidMapDifficulty = DIFFICULTY_10_N;
+ m_raidDifficulty = DIFFICULTY_NORMAL_RAID;
+ m_legacyRaidDifficulty = DIFFICULTY_10_N;
+ m_raidMapDifficulty = DIFFICULTY_NORMAL_RAID;
m_lastPotionId = 0;
_talentMgr = new PlayerTalentInfo();
@@ -6696,7 +6697,7 @@ void Player::RewardReputation(Unit* victim, float rate)
// support for: Championing - http://www.wowwiki.com/Championing
Map const* map = GetMap();
if (map && map->IsNonRaidDungeon())
- if (LFGDungeonEntry const* dungeon = GetLFGDungeon(map->GetId(), map->GetDifficulty()))
+ if (LFGDungeonEntry const* dungeon = GetLFGDungeon(map->GetId(), map->GetDifficultyID()))
if (dungeon->TargetLevel == 80)
ChampioningFaction = GetChampioningFaction();
}
@@ -11558,7 +11559,7 @@ InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObje
// check if looted object is inside the lfg dungeon
Map const* map = lootedObject->GetMap();
- if (!sLFGMgr->inLfgDungeonMap(GetGroup()->GetGUID(), map->GetId(), map->GetDifficulty()))
+ if (!sLFGMgr->inLfgDungeonMap(GetGroup()->GetGUID(), map->GetId(), map->GetDifficultyID()))
return EQUIP_ERR_OK;
if (!proto)
@@ -15927,7 +15928,7 @@ void Player::KilledMonsterCredit(uint32 entry, ObjectGuid guid /*= ObjectGuid::E
// just if !ingroup || !noraidgroup || raidgroup
QuestStatusData& q_status = m_QuestStatus[questid];
- if (q_status.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid(GetMap()->GetDifficulty())))
+ if (q_status.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid(GetMap()->GetDifficultyID())))
{
if (qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_KILL) /*&& !qInfo->HasSpecialFlag(QUEST_SPECIAL_FLAGS_CAST)*/)
{
@@ -15980,7 +15981,7 @@ void Player::KilledPlayerCredit()
// just if !ingroup || !noraidgroup || raidgroup
QuestStatusData& q_status = m_QuestStatus[questid];
- if (q_status.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid(GetMap()->GetDifficulty())))
+ if (q_status.Status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid(GetMap()->GetDifficultyID())))
{
for (QuestObjective const& obj : qInfo->GetObjectives())
{
@@ -16207,7 +16208,7 @@ bool Player::HasQuestForItem(uint32 itemid) const
continue;
// hide quest if player is in raid-group and quest is no raid quest
- if (GetGroup() && GetGroup()->isRaidGroup() && !qInfo->IsAllowedInRaid(GetMap()->GetDifficulty()))
+ if (GetGroup() && GetGroup()->isRaidGroup() && !qInfo->IsAllowedInRaid(GetMap()->GetDifficultyID()))
if (!InBattleground()) //there are two ways.. we can make every bg-quest a raidquest, or add this code here.. i don't know if this can be exploited by other quests, but i think all other quests depend on a specific area.. but keep this in mind, if something strange happens later
continue;
@@ -16645,13 +16646,13 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
// 12 13 14 15 16 17 18 19 20 21 22 23 24
//"position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, "
// 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
- //"resettalents_time, talentTree, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, "
+ //"resettalents_time, talentTree, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeonDifficulty, "
// 40 41 42 43 44 45
//"totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, "
// 46 47 48 49 50 51 52 53 54 55 56
//"health, power1, power2, power3, power4, power5, instance_id, speccount, activespec, exploredZones, equipmentCache, "
- // 57 58 59
- //"knownTitles, actionBars, grantableLevels FROM characters WHERE guid = '%u'", guid);
+ // 57 58 59 60 61
+ //"knownTitles, actionBars, grantableLevels, raidDifficulty, legacyRaidDifficulty FROM characters WHERE guid = '%u'", guid);
PreparedQueryResult result = holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_FROM);
if (!result)
{
@@ -16777,14 +16778,9 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
uint32 mapId = fields[15].GetUInt16();
uint32 instanceId = fields[52].GetUInt32();
- uint32 dungeonDiff = fields[39].GetUInt8() & 0x0F;
- if (dungeonDiff >= MAX_DUNGEON_DIFFICULTY)
- dungeonDiff = DIFFICULTY_NORMAL;
- uint32 raidDiff = (fields[39].GetUInt8() >> 4) & 0x0F;
- if (raidDiff >= MAX_RAID_DIFFICULTY)
- raidDiff = DIFFICULTY_10_N;
- SetDungeonDifficulty(Difficulty(dungeonDiff)); // may be changed in _LoadGroup
- SetRaidDifficulty(Difficulty(raidDiff)); // may be changed in _LoadGroup
+ SetDungeonDifficultyID(CheckLoadedDungeonDifficultyID(Difficulty(fields[39].GetUInt8())));
+ SetRaidDifficultyID(CheckLoadedRaidDifficultyID(Difficulty(fields[60].GetUInt8())));
+ SetLegacyRaidDifficultyID(CheckLoadedLegacyRaidDifficultyID(Difficulty(fields[61].GetUInt8())));
std::string taxi_nodes = fields[38].GetString();
@@ -16979,7 +16975,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
// fix crash (because of if (Map* map = _FindMap(instanceId)) in MapInstanced::CreateInstance)
if (instanceId)
- if (InstanceSave* save = GetInstanceSave(mapId, mapEntry->IsRaid()))
+ if (InstanceSave* save = GetInstanceSave(mapId))
if (save->GetInstanceId() != instanceId)
instanceId = 0;
}
@@ -17042,7 +17038,6 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
}
SetMap(map);
- StoreRaidMapDifficulty();
// randomize first save time in range [CONFIG_INTERVAL_SAVE] around [CONFIG_INTERVAL_SAVE]
// this must help in case next save after mass player load after server startup
@@ -18300,8 +18295,9 @@ void Player::_LoadGroup(PreparedQueryResult result)
if (getLevel() >= LEVELREQUIREMENT_HEROIC)
{
// the group leader may change the instance difficulty while the player is offline
- SetDungeonDifficulty(group->GetDungeonDifficulty());
- SetRaidDifficulty(group->GetRaidDifficulty());
+ SetDungeonDifficultyID(group->GetDungeonDifficultyID());
+ SetRaidDifficultyID(group->GetRaidDifficultyID());
+ SetLegacyRaidDifficultyID(group->GetLegacyRaidDifficultyID());
}
}
}
@@ -18398,9 +18394,10 @@ InstancePlayerBind* Player::GetBoundInstance(uint32 mapid, Difficulty difficulty
return NULL;
}
-InstanceSave* Player::GetInstanceSave(uint32 mapid, bool raid)
+InstanceSave* Player::GetInstanceSave(uint32 mapid)
{
- InstancePlayerBind* pBind = GetBoundInstance(mapid, GetDifficulty(raid));
+ MapEntry const* mapEntry = sMapStore.LookupEntry(mapid);
+ InstancePlayerBind* pBind = GetBoundInstance(mapid, GetDifficultyID(mapEntry));
InstanceSave* pSave = pBind ? pBind->save : NULL;
if (!pBind || !pBind->perm)
if (Group* group = GetGroup())
@@ -18442,7 +18439,7 @@ InstancePlayerBind* Player::BindToInstance(InstanceSave* save, bool permanent, b
{
if (save)
{
- InstancePlayerBind& bind = m_boundInstances[save->GetDifficulty()][save->GetMapId()];
+ InstancePlayerBind& bind = m_boundInstances[save->GetDifficultyID()][save->GetMapId()];
if (!load)
{
if (bind.save)
@@ -18485,8 +18482,8 @@ InstancePlayerBind* Player::BindToInstance(InstanceSave* save, bool permanent, b
bind.save = save;
bind.perm = permanent;
if (!load)
- TC_LOG_DEBUG("maps", "Player::BindToInstance: %s(%s) is now bound to map %d, instance %d, difficulty %d", GetName().c_str(), GetGUID().ToString().c_str(), save->GetMapId(), save->GetInstanceId(), save->GetDifficulty());
- sScriptMgr->OnPlayerBindToInstance(this, save->GetDifficulty(), save->GetMapId(), permanent);
+ TC_LOG_DEBUG("maps", "Player::BindToInstance: %s(%s) is now bound to map %d, instance %d, difficulty %d", GetName().c_str(), GetGUID().ToString().c_str(), save->GetMapId(), save->GetInstanceId(), save->GetDifficultyID());
+ sScriptMgr->OnPlayerBindToInstance(this, save->GetDifficultyID(), save->GetMapId(), permanent);
return &bind;
}
@@ -18531,14 +18528,14 @@ void Player::SendRaidInfo()
if (itr->second.perm)
{
InstanceSave* save = itr->second.save;
- bool isHeroic = save->GetDifficulty() == DIFFICULTY_10_HC || save->GetDifficulty() == DIFFICULTY_25_HC;
+ bool isHeroic = save->GetDifficultyID() == DIFFICULTY_10_HC || save->GetDifficultyID() == DIFFICULTY_25_HC;
uint32 completedEncounters = 0;
if (Map* map = sMapMgr->FindMap(save->GetMapId(), save->GetInstanceId()))
if (InstanceScript* instanceScript = ((InstanceMap*)map)->GetInstanceScript())
completedEncounters = instanceScript->GetCompletedEncounterMask();
data << uint32(save->GetMapId()); // map id
- data << uint32(save->GetDifficulty()); // difficulty
+ data << uint32(save->GetDifficultyID()); // difficulty
data << uint32(isHeroic); // heroic
data << uint64(save->GetInstanceId()); // instance id
data << uint8(1); // expired = 0
@@ -18606,7 +18603,7 @@ void Player::ConvertInstancesToGroup(Player* player, Group* group, bool switchLe
{
for (BoundInstancesMap::iterator itr = player->m_boundInstances[i].begin(); itr != player->m_boundInstances[i].end();)
{
- if (!switchLeader || !group->GetBoundInstance(itr->second.save->GetDifficulty(), itr->first))
+ if (!switchLeader || !group->GetBoundInstance(itr->second.save->GetDifficultyID(), itr->first))
group->BindToInstance(itr->second.save, itr->second.perm, false);
// permanent binds are not removed
@@ -18672,7 +18669,7 @@ bool Player::Satisfy(AccessRequirement const* ar, uint32 target_map, bool report
if (!leader || !leader->HasAchieved(ar->achievement))
missingAchievement = ar->achievement;
- Difficulty target_difficulty = GetDifficulty(mapEntry->IsRaid());
+ Difficulty target_difficulty = GetDifficultyID(mapEntry);
MapDifficulty const* mapDiff = GetDownscaledMapDifficultyData(target_map, target_difficulty);
if (LevelMin || LevelMax || missingItem || missingQuest || missingAchievement)
{
@@ -18838,7 +18835,7 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setUInt32(index++, GetUInt32Value(PLAYER_FLAGS));
stmt->setUInt16(index++, (uint16)GetMapId());
stmt->setUInt32(index++, (uint32)GetInstanceId());
- stmt->setUInt8(index++, (uint8(GetDungeonDifficulty()) | uint8(GetRaidDifficulty()) << 4));
+ stmt->setUInt8(index++, (uint8(GetDungeonDifficultyID()) | uint8(GetRaidDifficultyID()) << 4));
stmt->setFloat(index++, finiteAlways(GetPositionX()));
stmt->setFloat(index++, finiteAlways(GetPositionY()));
stmt->setFloat(index++, finiteAlways(GetPositionZ()));
@@ -18959,7 +18956,9 @@ void Player::SaveToDB(bool create /*=false*/)
{
stmt->setUInt16(index++, (uint16)GetMapId());
stmt->setUInt32(index++, (uint32)GetInstanceId());
- stmt->setUInt8(index++, (uint8(GetDungeonDifficulty()) | uint8(GetRaidDifficulty()) << 4));
+ stmt->setUInt8(index++, uint8(GetDungeonDifficultyID()));
+ stmt->setUInt8(index++, uint8(GetRaidDifficultyID()));
+ stmt->setUInt8(index++, uint8(GetLegacyRaidDifficultyID()));
stmt->setFloat(index++, finiteAlways(GetPositionX()));
stmt->setFloat(index++, finiteAlways(GetPositionY()));
stmt->setFloat(index++, finiteAlways(GetPositionZ()));
@@ -18969,7 +18968,9 @@ void Player::SaveToDB(bool create /*=false*/)
{
stmt->setUInt16(index++, (uint16)GetTeleportDest().GetMapId());
stmt->setUInt32(index++, (uint32)0);
- stmt->setUInt8(index++, (uint8(GetDungeonDifficulty()) | uint8(GetRaidDifficulty()) << 4));
+ stmt->setUInt8(index++, uint8(GetDungeonDifficultyID()));
+ stmt->setUInt8(index++, uint8(GetRaidDifficultyID()));
+ stmt->setUInt8(index++, uint8(GetLegacyRaidDifficultyID()));
stmt->setFloat(index++, finiteAlways(GetTeleportDest().GetPositionX()));
stmt->setFloat(index++, finiteAlways(GetTeleportDest().GetPositionY()));
stmt->setFloat(index++, finiteAlways(GetTeleportDest().GetPositionZ()));
@@ -19963,24 +19964,19 @@ void Player::SendExplorationExperience(uint32 Area, uint32 Experience)
GetSession()->SendPacket(&data);
}
-void Player::SendDungeonDifficulty(bool IsInGroup)
+void Player::SendDungeonDifficulty()
{
- uint8 val = 0x00000001;
- WorldPacket data(MSG_SET_DUNGEON_DIFFICULTY, 12);
- data << (uint32)GetDungeonDifficulty();
- data << uint32(val);
- data << uint32(IsInGroup);
- GetSession()->SendPacket(&data);
+ WorldPackets::Misc::DungeonDifficultySet dungeonDifficultySet;
+ dungeonDifficultySet.DifficultyID = GetDungeonDifficultyID();
+ GetSession()->SendPacket(dungeonDifficultySet.Write());
}
-void Player::SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty)
+void Player::SendRaidDifficulty(bool legacy, int32 forcedDifficulty /*= -1*/)
{
- uint8 val = 0x00000001;
- WorldPacket data(MSG_SET_RAID_DIFFICULTY, 12);
- data << uint32(forcedDifficulty == -1 ? GetRaidDifficulty() : forcedDifficulty);
- data << uint32(val);
- data << uint32(IsInGroup);
- GetSession()->SendPacket(&data);
+ WorldPackets::Misc::RaidDifficultySet raidDifficultySet;
+ raidDifficultySet.DifficultyID = forcedDifficulty == -1 ? (legacy ? GetLegacyRaidDifficultyID() : GetRaidDifficultyID()) : forcedDifficulty;
+ raidDifficultySet.Legacy = legacy;
+ GetSession()->SendPacket(raidDifficultySet.Write());
}
void Player::SendResetFailedNotify(uint32 /*mapid*/)
@@ -19990,12 +19986,19 @@ void Player::SendResetFailedNotify(uint32 /*mapid*/)
}
/// Reset all solo instances and optionally send a message on success for each
-void Player::ResetInstances(uint8 method, bool isRaid)
+void Player::ResetInstances(uint8 method, bool isRaid, bool isLegacy)
{
// method can be INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_GROUP_JOIN
// we assume that when the difficulty changes, all instances that can be reset will be
- Difficulty diff = GetDifficulty(isRaid);
+ Difficulty diff = GetDungeonDifficultyID();
+ if (isRaid)
+ {
+ if (!isLegacy)
+ diff = GetRaidDifficultyID();
+ else
+ diff = GetLegacyRaidDifficultyID();
+ }
for (BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();)
{
@@ -22867,11 +22870,11 @@ void Player::SendInitialPacketsBeforeAddToMap()
WorldPackets::Misc::WorldServerInfo worldServerInfo;
worldServerInfo.IneligibleForLootMask.Clear(); /// @todo
worldServerInfo.WeeklyReset = sWorld->GetNextWeeklyQuestsResetTime() - WEEK;
- worldServerInfo.InstanceGroupSize.Clear(); /// @todo
+ worldServerInfo.InstanceGroupSize.Set(GetMap()->GetMapDifficulty()->maxPlayers);
worldServerInfo.IsTournamentRealm = 0; /// @todo
worldServerInfo.RestrictedAccountMaxLevel.Clear(); /// @todo
worldServerInfo.RestrictedAccountMaxMoney.Clear(); /// @todo
- worldServerInfo.DifficultyID = GetMap()->GetDifficulty();
+ worldServerInfo.DifficultyID = GetMap()->GetDifficultyID();
SendDirectMessage(worldServerInfo.Write());
// SMSG_TALENTS_INFO x 2 for pet (unspent points and talents in separate packets...)
@@ -22925,17 +22928,13 @@ void Player::SendInitialPacketsAfterAddToMap()
SendEnchantmentDurations(); // must be after add to map
SendItemDurations(); // must be after add to map
- // raid downscaling - send difficulty to player
if (GetMap()->IsRaid())
{
- if (GetMap()->GetDifficulty() != GetRaidDifficulty())
- {
- StoreRaidMapDifficulty();
- SendRaidDifficulty(GetGroup() != NULL, GetStoredRaidDifficulty());
- }
+ DifficultyEntry const* difficulty = sDifficultyStore.LookupEntry(GetMap()->GetDifficultyID());
+ SendRaidDifficulty((difficulty->Flags & DIFFICULTY_FLAG_LEGACY) != 0, GetMap()->GetDifficultyID());
}
- else if (GetRaidDifficulty() != GetStoredRaidDifficulty())
- SendRaidDifficulty(GetGroup() != NULL);
+ else if (GetMap()->IsNonRaidDungeon())
+ SendDungeonDifficulty();
}
void Player::SendUpdateToOutOfRangeGroupMembers()
@@ -23603,7 +23602,7 @@ bool Player::HasQuestForGO(int32 GOId) const
if (!qInfo)
continue;
- if (GetGroup() && GetGroup()->isRaidGroup() && !qInfo->IsAllowedInRaid(GetMap()->GetDifficulty()))
+ if (GetGroup() && GetGroup()->isRaidGroup() && !qInfo->IsAllowedInRaid(GetMap()->GetDifficultyID()))
continue;
for (QuestObjective const& obj : qInfo->GetObjectives())
@@ -24323,7 +24322,7 @@ bool Player::inRandomLfgDungeon()
if (sLFGMgr->selectedRandomLfgDungeon(GetGUID()))
{
Map const* map = GetMap();
- return sLFGMgr->inLfgDungeonMap(GetGUID(), map->GetId(), map->GetDifficulty());
+ return sLFGMgr->inLfgDungeonMap(GetGUID(), map->GetId(), map->GetDifficultyID());
}
return false;
@@ -27070,3 +27069,64 @@ uint32 Player::CalculateTalentsPoints() const
// 1 talent point for every 15 levels
return getLevel() >= 100 ? 7 : uint32(floor(getLevel() / 15.f));
}
+
+Difficulty Player::GetDifficultyID(MapEntry const* mapEntry) const
+{
+ if (!mapEntry->IsRaid())
+ return m_dungeonDifficulty;
+
+ MapDifficulty const* defaultDifficulty = GetDefaultMapDifficulty(mapEntry->ID);
+ if (!defaultDifficulty)
+ return m_legacyRaidDifficulty;
+
+ DifficultyEntry const* difficulty = sDifficultyStore.LookupEntry(defaultDifficulty->DifficultyID);
+ if (!difficulty || difficulty->Flags & DIFFICULTY_FLAG_LEGACY)
+ return m_legacyRaidDifficulty;
+
+ return m_raidDifficulty;
+}
+
+Difficulty Player::CheckLoadedDungeonDifficultyID(Difficulty difficulty)
+{
+ DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(difficulty);
+ if (!difficultyEntry)
+ return DIFFICULTY_NORMAL;
+
+ if (difficultyEntry->InstanceType != MAP_INSTANCE)
+ return DIFFICULTY_NORMAL;
+
+ if (!(difficultyEntry->Flags & DIFFICULTY_FLAG_CAN_SELECT))
+ return DIFFICULTY_NORMAL;
+
+ return difficulty;
+}
+
+Difficulty Player::CheckLoadedRaidDifficultyID(Difficulty difficulty)
+{
+ DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(difficulty);
+ if (!difficultyEntry)
+ return DIFFICULTY_NORMAL_RAID;
+
+ if (difficultyEntry->InstanceType != MAP_INSTANCE)
+ return DIFFICULTY_NORMAL_RAID;
+
+ if (!(difficultyEntry->Flags & DIFFICULTY_FLAG_CAN_SELECT) || (difficultyEntry->Flags & DIFFICULTY_FLAG_LEGACY))
+ return DIFFICULTY_NORMAL_RAID;
+
+ return difficulty;
+}
+
+Difficulty Player::CheckLoadedLegacyRaidDifficultyID(Difficulty difficulty)
+{
+ DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(difficulty);
+ if (!difficultyEntry)
+ return DIFFICULTY_10_N;
+
+ if (difficultyEntry->InstanceType != MAP_INSTANCE)
+ return DIFFICULTY_10_N;
+
+ if (!(difficultyEntry->Flags & DIFFICULTY_FLAG_CAN_SELECT) || !(difficultyEntry->Flags & DIFFICULTY_FLAG_LEGACY))
+ return DIFFICULTY_10_N;
+
+ return difficulty;
+}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 1c76e594236..5b768ceee8d 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2006,13 +2006,16 @@ class Player : public Unit, public GridObject<Player>
uint32 GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; }
uint32 GetRBGPersonalRating() const { return 0; }
- Difficulty GetDifficulty(bool isRaid) const { return isRaid ? m_raidDifficulty : m_dungeonDifficulty; }
- Difficulty GetDungeonDifficulty() const { return m_dungeonDifficulty; }
- Difficulty GetRaidDifficulty() const { return m_raidDifficulty; }
- Difficulty GetStoredRaidDifficulty() const { return m_raidMapDifficulty; } // only for use in difficulty packet after exiting to raid map
- void SetDungeonDifficulty(Difficulty dungeon_difficulty) { m_dungeonDifficulty = dungeon_difficulty; }
- void SetRaidDifficulty(Difficulty raid_difficulty) { m_raidDifficulty = raid_difficulty; }
- void StoreRaidMapDifficulty() { m_raidMapDifficulty = GetMap()->GetDifficulty(); }
+ Difficulty GetDifficultyID(MapEntry const* mapEntry) const;
+ Difficulty GetDungeonDifficultyID() const { return m_dungeonDifficulty; }
+ Difficulty GetRaidDifficultyID() const { return m_raidDifficulty; }
+ Difficulty GetLegacyRaidDifficultyID() const { return m_legacyRaidDifficulty; }
+ void SetDungeonDifficultyID(Difficulty dungeon_difficulty) { m_dungeonDifficulty = dungeon_difficulty; }
+ void SetRaidDifficultyID(Difficulty raid_difficulty) { m_raidDifficulty = raid_difficulty; }
+ void SetLegacyRaidDifficultyID(Difficulty raid_difficulty) { m_legacyRaidDifficulty = raid_difficulty; }
+ static Difficulty CheckLoadedDungeonDifficultyID(Difficulty difficulty);
+ static Difficulty CheckLoadedRaidDifficultyID(Difficulty difficulty);
+ static Difficulty CheckLoadedLegacyRaidDifficultyID(Difficulty difficulty);
bool UpdateSkill(uint32 skill_id, uint32 step);
bool UpdateSkillPro(uint16 skillId, int32 chance, uint32 step);
@@ -2100,9 +2103,9 @@ class Player : public Unit, public GridObject<Player>
void SendAutoRepeatCancel(Unit* target);
void SendExplorationExperience(uint32 Area, uint32 Experience);
- void SendDungeonDifficulty(bool IsInGroup);
- void SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty = -1);
- void ResetInstances(uint8 method, bool isRaid);
+ void SendDungeonDifficulty();
+ void SendRaidDifficulty(bool legacy, int32 forcedDifficulty = -1);
+ void ResetInstances(uint8 method, bool isRaid, bool isLegacy);
void SendResetInstanceSuccess(uint32 MapId);
void SendResetInstanceFailed(uint32 reason, uint32 MapId);
void SendResetFailedNotify(uint32 mapid);
@@ -2468,7 +2471,7 @@ class Player : public Unit, public GridObject<Player>
BoundInstancesMap m_boundInstances[MAX_DIFFICULTY];
InstancePlayerBind* GetBoundInstance(uint32 mapid, Difficulty difficulty);
BoundInstancesMap& GetBoundInstances(Difficulty difficulty) { return m_boundInstances[difficulty]; }
- InstanceSave* GetInstanceSave(uint32 mapid, bool raid);
+ InstanceSave* GetInstanceSave(uint32 mapid);
void UnbindInstance(uint32 mapid, Difficulty difficulty, bool unload = false);
void UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficulty, bool unload = false);
InstancePlayerBind* BindToInstance(InstanceSave* save, bool permanent, bool load = false);
@@ -2732,6 +2735,7 @@ class Player : public Unit, public GridObject<Player>
uint32 m_speakCount;
Difficulty m_dungeonDifficulty;
Difficulty m_raidDifficulty;
+ Difficulty m_legacyRaidDifficulty;
Difficulty m_raidMapDifficulty;
uint32 m_atLoginFlags;
diff --git a/src/server/game/Entities/Totem/Totem.cpp b/src/server/game/Entities/Totem/Totem.cpp
index 3929af2e3e7..1a7a7fbb00a 100644
--- a/src/server/game/Entities/Totem/Totem.cpp
+++ b/src/server/game/Entities/Totem/Totem.cpp
@@ -145,7 +145,7 @@ bool Totem::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) con
/// @todo possibly all negative auras immune?
if (GetEntry() == 5925)
return false;
- if (SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficulty(), index))
+ if (SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficultyID(), index))
{
switch (effect->ApplyAuraName)
{
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index 481d7fb3632..cbb62fcad73 100644
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -990,7 +990,7 @@ bool Guardian::UpdateStats(Stats stat)
if (aurEff)
{
SpellInfo const* spellInfo = aurEff->GetSpellInfo(); // Then get the SpellProto and add the dummy effect value
- if (SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficulty(), EFFECT_1))
+ if (SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficultyID(), EFFECT_1))
AddPct(mod, effect->CalcValue(owner)); // Ravenous Dead edits the original scale
}
// Glyph of the Ghoul
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index a412cf43a7a..1469336a3a8 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -1414,7 +1414,7 @@ bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* s
return false;
// bleeding effects are not reduced by armor
- if (SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficulty(), effIndex))
+ if (SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficultyID(), effIndex))
{
if (effect->ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
effect->Effect == SPELL_EFFECT_SCHOOL_DAMAGE)
@@ -2153,12 +2153,12 @@ int32 Unit::GetMechanicResistChance(SpellInfo const* spellInfo) const
return 0;
int32 resistMech = 0;
- for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficultyID()))
{
if (!effect || !effect->IsEffect())
break;
- int32 effectMech = spellInfo->GetEffectMechanic(effect->EffectIndex, GetMap()->GetDifficulty());
+ int32 effectMech = spellInfo->GetEffectMechanic(effect->EffectIndex, GetMap()->GetDifficultyID());
if (effectMech)
{
int32 temp = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MECHANIC_RESISTANCE, effectMech);
@@ -2213,7 +2213,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo
// Get effects mechanic and chance
for (uint8 eff = 0; eff < MAX_SPELL_EFFECTS; ++eff)
{
- int32 effect_mech = spellInfo->GetEffectMechanic(eff, GetMap()->GetDifficulty());
+ int32 effect_mech = spellInfo->GetEffectMechanic(eff, GetMap()->GetDifficultyID());
if (effect_mech)
{
int32 temp = victim->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MECHANIC_RESISTANCE, effect_mech);
@@ -3107,7 +3107,7 @@ AuraApplication * Unit::_CreateAuraApplication(Aura* aura, uint32 effMask)
AddInterruptMask(aurSpellInfo->AuraInterruptFlags);
}
- if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState(GetMap()->GetDifficulty()))
+ if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState(GetMap()->GetDifficultyID()))
m_auraStateAuras.insert(AuraStateAurasMap::value_type(aState, aurApp));
aura->_ApplyForTarget(this, caster, aurApp);
@@ -3138,7 +3138,7 @@ void Unit::_ApplyAura(AuraApplication * aurApp, uint32 effMask)
return;
// Update target aura state flag
- if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState(GetMap()->GetDifficulty()))
+ if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState(GetMap()->GetDifficultyID()))
ModifyAuraState(aState, true);
if (aurApp->GetRemoveMode())
@@ -3193,7 +3193,7 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMo
}
bool auraStateFound = false;
- AuraStateType auraState = aura->GetSpellInfo()->GetAuraState(GetMap()->GetDifficulty());
+ AuraStateType auraState = aura->GetSpellInfo()->GetAuraState(GetMap()->GetDifficultyID());
if (auraState)
{
bool canBreak = false;
@@ -3269,12 +3269,12 @@ void Unit::_RemoveNoStackAurasDueToAura(Aura* aura)
SpellInfo const* spellProto = aura->GetSpellInfo();
// passive spell special case (only non stackable with ranks)
- if (spellProto->IsPassiveStackableWithRanks(GetMap()->GetDifficulty()))
+ if (spellProto->IsPassiveStackableWithRanks(GetMap()->GetDifficultyID()))
return;
if (!IsHighestExclusiveAura(aura))
{
- if (!aura->GetSpellInfo()->IsAffectingArea(GetMap()->GetDifficulty()))
+ if (!aura->GetSpellInfo()->IsAffectingArea(GetMap()->GetDifficultyID()))
{
Unit* caster = aura->GetCaster();
if (caster && caster->GetTypeId() == TYPEID_PLAYER)
@@ -3866,7 +3866,7 @@ void Unit::RemoveAllAurasExceptType(AuraType type)
for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
{
Aura const* aura = iter->second->GetBase();
- if (aura->GetSpellInfo()->HasAura(GetMap()->GetDifficulty(), type))
+ if (aura->GetSpellInfo()->HasAura(GetMap()->GetDifficultyID(), type))
++iter;
else
_UnapplyAura(iter, AURA_REMOVE_BY_DEFAULT);
@@ -3875,7 +3875,7 @@ void Unit::RemoveAllAurasExceptType(AuraType type)
for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
{
Aura* aura = iter->second;
- if (aura->GetSpellInfo()->HasAura(GetMap()->GetDifficulty(), type))
+ if (aura->GetSpellInfo()->HasAura(GetMap()->GetDifficultyID(), type))
++iter;
else
RemoveOwnedAura(iter, AURA_REMOVE_BY_DEFAULT);
@@ -3887,7 +3887,7 @@ void Unit::RemoveAllAurasExceptType(AuraType type1, AuraType type2)
for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
{
Aura const* aura = iter->second->GetBase();
- if (aura->GetSpellInfo()->HasAura(GetMap()->GetDifficulty(), type1) || aura->GetSpellInfo()->HasAura(GetMap()->GetDifficulty(), type2))
+ if (aura->GetSpellInfo()->HasAura(GetMap()->GetDifficultyID(), type1) || aura->GetSpellInfo()->HasAura(GetMap()->GetDifficultyID(), type2))
++iter;
else
_UnapplyAura(iter, AURA_REMOVE_BY_DEFAULT);
@@ -3896,7 +3896,7 @@ void Unit::RemoveAllAurasExceptType(AuraType type1, AuraType type2)
for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
{
Aura* aura = iter->second;
- if (aura->GetSpellInfo()->HasAura(GetMap()->GetDifficulty(), type1) || aura->GetSpellInfo()->HasAura(GetMap()->GetDifficulty(), type2))
+ if (aura->GetSpellInfo()->HasAura(GetMap()->GetDifficultyID(), type1) || aura->GetSpellInfo()->HasAura(GetMap()->GetDifficultyID(), type2))
++iter;
else
RemoveOwnedAura(iter, AURA_REMOVE_BY_DEFAULT);
@@ -6574,7 +6574,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
}
// not allow proc extra attack spell at extra attack
- if (m_extraAttacks && triggerEntry->HasEffect(GetMap()->GetDifficulty(), SPELL_EFFECT_ADD_EXTRA_ATTACKS))
+ if (m_extraAttacks && triggerEntry->HasEffect(GetMap()->GetDifficultyID(), SPELL_EFFECT_ADD_EXTRA_ATTACKS))
return false;
// Custom requirements (not listed in procEx) Warning! damage dealing after this
@@ -6790,7 +6790,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
return false;
// extra attack should hit same target
- if (triggerEntry->HasEffect(GetMap()->GetDifficulty(), SPELL_EFFECT_ADD_EXTRA_ATTACKS))
+ if (triggerEntry->HasEffect(GetMap()->GetDifficultyID(), SPELL_EFFECT_ADD_EXTRA_ATTACKS))
target = victim;
// try detect target manually if not set
@@ -8838,7 +8838,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
}
- for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficultyID()))
{
if (!effect)
continue;
@@ -8999,7 +8999,7 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u
if (caster->GetGUID() == (*i)->GetCasterGUID() && (*i)->IsAffectingSpell(spellProto))
AddPct(TakenTotalMod, (*i)->GetAmount());
- for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficultyID()))
{
if (!effect)
continue;
@@ -9142,7 +9142,7 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) const
}
bool immuneToAllEffects = true;
- for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficultyID()))
{
// State/effect immunities applied by aura expect full spell immunity
// Ignore effects with mechanic, they are supposed to be checked separately
@@ -9179,7 +9179,7 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) cons
if (!spellInfo)
return false;
- SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficulty(), index);
+ SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficultyID(), index);
if (!effect || !effect->IsEffect())
return false;
@@ -9267,7 +9267,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType
{
bool normalized = false;
if (spellProto)
- for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficultyID()))
if (effect && effect->Effect == SPELL_EFFECT_NORMALIZED_WEAPON_DMG)
{
normalized = true;
@@ -9873,7 +9873,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo
return false;
// can't attack invisible (ignore stealth for aoe spells) also if the area being looked at is from a spell use the dynamic object created instead of the casting unit.
- if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea(GetMap()->GetDifficulty())) : !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea(GetMap()->GetDifficulty()))))
+ if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea(GetMap()->GetDifficultyID())) : !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea(GetMap()->GetDifficultyID()))))
return false;
// can't attack dead
@@ -9994,7 +9994,7 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co
return false;
// can't assist invisible
- if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea(GetMap()->GetDifficulty())))
+ if ((!bySpell || !bySpell->HasAttribute(SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea(GetMap()->GetDifficultyID())))
return false;
// can't assist dead
@@ -10762,7 +10762,7 @@ float Unit::ApplyEffectModifiers(SpellInfo const* spellProto, uint8 effect_index
// function uses real base points (typically value - 1)
int32 Unit::CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints /*= nullptr*/, float* variance /*= nullptr*/) const
{
- SpellEffectInfo const* effect = spellProto->GetEffect(GetMap()->GetDifficulty(), effect_index);
+ SpellEffectInfo const* effect = spellProto->GetEffect(GetMap()->GetDifficultyID(), effect_index);
if (variance)
*variance = 0.0f;
@@ -12785,7 +12785,7 @@ uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectTyp
bool DirectDamage = false;
bool AreaEffect = false;
- for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficultyID()))
{
if (!effect)
continue;
@@ -12844,7 +12844,7 @@ uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectTyp
CastingTime /= 2;
// 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
- for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficultyID()))
{
if (!effect)
continue;
@@ -12912,7 +12912,7 @@ float Unit::CalculateDefaultCoefficient(SpellInfo const* spellInfo, DamageEffect
if (!spellInfo->IsChanneled() && DotDuration > 0)
DotFactor = DotDuration / 15000.0f;
- if (uint32 DotTicks = spellInfo->GetMaxTicks(GetMap()->GetDifficulty()))
+ if (uint32 DotTicks = spellInfo->GetMaxTicks(GetMap()->GetDifficultyID()))
DotFactor /= DotTicks;
}
@@ -15012,7 +15012,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
{
uint8 i = 0;
bool valid = false;
- for (SpellEffectInfo const* effect : spellEntry->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellEntry->GetEffectsForDifficulty(GetMap()->GetDifficultyID()))
{
if (!effect)
continue;
@@ -15036,7 +15036,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
else // This can happen during Player::_LoadAuras
{
int32 bp0[MAX_SPELL_EFFECTS];
- for (SpellEffectInfo const* effect : spellEntry->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellEntry->GetEffectsForDifficulty(GetMap()->GetDifficultyID()))
if (effect)
bp0[effect->EffectIndex] = effect->BasePoints;
@@ -16244,7 +16244,7 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target)
// this also applies for transform auras
if (SpellInfo const* transform = sSpellMgr->GetSpellInfo(getTransForm()))
- for (SpellEffectInfo const* effect : transform->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : transform->GetEffectsForDifficulty(GetMap()->GetDifficultyID()))
if (effect && effect->IsAura(SPELL_AURA_TRANSFORM))
if (CreatureTemplate const* transformInfo = sObjectMgr->GetCreatureTemplate(effect->MiscValue))
{
@@ -16421,7 +16421,7 @@ bool Unit::IsHighestExclusiveAura(Aura const* aura, bool removeOtherAuraApplicat
{
if (AuraApplication* aurApp = existingAurEff->GetBase()->GetApplicationOfTarget(GetGUID()))
{
- bool hasMoreThanOneEffect = base->HasMoreThanOneEffectForType(auraType, GetMap()->GetDifficulty());
+ bool hasMoreThanOneEffect = base->HasMoreThanOneEffectForType(auraType, GetMap()->GetDifficultyID());
uint32 removedAuras = m_removedAurasCount;
RemoveAura(aurApp);
if (hasMoreThanOneEffect || m_removedAurasCount > removedAuras + 1)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 00bb77a5a1e..270674fdba6 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -225,7 +225,20 @@ enum UnitBytes0Offsets
{
UNIT_BYTES_0_OFFSET_RACE = 0,
UNIT_BYTES_0_OFFSET_CLASS = 1,
- UNIT_BYTES_0_OFFSET_GENDER = 3,
+ UNIT_BYTES_0_OFFSET_GENDER = 3
+};
+
+enum UnitBytes1Offsets
+{
+ UNIT_BYTES_1_OFFSET_STAND_STATE = 0,
+ UNIT_BYTES_1_OFFSET_VIS_FLAG = 2,
+ UNIT_BYTES_1_OFFSET_ANIM_TIER = 3
+};
+
+enum UnitBytes2Offsets
+{
+ UNIT_BYTES_2_OFFSET_SHEATH_STATE = 0,
+ UNIT_BYTES_2_OFFSET_PVP_FLAG = 1,
};
// byte flags value (UNIT_FIELD_BYTES_1, 3)
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 72b4d7be0b0..6c29b9a64a9 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -467,7 +467,7 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields)
creatureTemplate.Entry = entry;
- for (uint8 i = 0; i < MAX_DIFFICULTY - 1; ++i)
+ for (uint8 i = 0; i < MAX_CREATURE_DIFFICULTIES; ++i)
creatureTemplate.DifficultyEntry[i] = fields[1 + i].GetUInt32();
for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i)
@@ -626,7 +626,7 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
return;
bool ok = true; // bool to allow continue outside this loop
- for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
+ for (uint32 diff = 0; diff < MAX_CREATURE_DIFFICULTIES && ok; ++diff)
{
if (!cInfo->DifficultyEntry[diff])
continue;
@@ -641,7 +641,7 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
}
bool ok2 = true;
- for (uint32 diff2 = 0; diff2 < MAX_DIFFICULTY - 1 && ok2; ++diff2)
+ for (uint32 diff2 = 0; diff2 < MAX_CREATURE_DIFFICULTIES && ok2; ++diff2)
{
ok2 = false;
if (_difficultyEntries[diff2].find(cInfo->Entry) != _difficultyEntries[diff2].end())
@@ -1660,11 +1660,10 @@ void ObjectMgr::LoadCreatures()
// Build single time for check spawnmask
std::map<uint32, uint32> spawnMasks;
- for (uint32 i = 0; i < sMapStore.GetNumRows(); ++i)
- if (sMapStore.LookupEntry(i))
- for (int k = 0; k < MAX_DIFFICULTY; ++k)
- if (GetMapDifficultyData(i, Difficulty(k)))
- spawnMasks[i] |= (1 << k);
+ for (auto& mapDifficultyPair : sMapDifficultyMap)
+ for (auto& difficultyPair : mapDifficultyPair.second)
+ spawnMasks[mapDifficultyPair.first] |= (1 << difficultyPair.first);
+
_creatureDataStore.rehash(result->GetRowCount());
@@ -1697,7 +1696,7 @@ void ObjectMgr::LoadCreatures()
data.curhealth = fields[12].GetUInt32();
data.curmana = fields[13].GetUInt32();
data.movementType = fields[14].GetUInt8();
- data.spawnMask = fields[15].GetUInt8();
+ data.spawnMask = fields[15].GetUInt32();
data.phaseMask = fields[16].GetUInt32();
int16 gameEvent = fields[17].GetInt8();
uint32 PoolId = fields[18].GetUInt32();
@@ -1719,7 +1718,7 @@ void ObjectMgr::LoadCreatures()
TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: " UI64FMTD ") that have wrong spawn mask %u including unsupported difficulty modes for map (Id: %u).", guid, data.spawnMask, data.mapid);
bool ok = true;
- for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
+ for (uint32 diff = 0; diff < MAX_CREATURE_DIFFICULTIES && ok; ++diff)
{
if (_difficultyEntries[diff].find(data.id) != _difficultyEntries[diff].end())
{
@@ -1813,7 +1812,7 @@ void ObjectMgr::LoadCreatures()
void ObjectMgr::AddCreatureToGrid(ObjectGuid::LowType guid, CreatureData const* data)
{
- uint8 mask = data->spawnMask;
+ uint32 mask = data->spawnMask;
for (uint8 i = 0; mask != 0; i++, mask >>= 1)
{
if (mask & 1)
@@ -1827,7 +1826,7 @@ void ObjectMgr::AddCreatureToGrid(ObjectGuid::LowType guid, CreatureData const*
void ObjectMgr::RemoveCreatureFromGrid(ObjectGuid::LowType guid, CreatureData const* data)
{
- uint8 mask = data->spawnMask;
+ uint32 mask = data->spawnMask;
for (uint8 i = 0; mask != 0; i++, mask >>= 1)
{
if (mask & 1)
@@ -1994,11 +1993,9 @@ void ObjectMgr::LoadGameobjects()
// build single time for check spawnmask
std::map<uint32, uint32> spawnMasks;
- for (uint32 i = 0; i < sMapStore.GetNumRows(); ++i)
- if (sMapStore.LookupEntry(i))
- for (int k = 0; k < MAX_DIFFICULTY; ++k)
- if (GetMapDifficultyData(i, Difficulty(k)))
- spawnMasks[i] |= (1 << k);
+ for (auto& mapDifficultyPair : sMapDifficultyMap)
+ for (auto& difficultyPair : mapDifficultyPair.second)
+ spawnMasks[mapDifficultyPair.first] |= (1 << difficultyPair.first);
_gameObjectDataStore.rehash(result->GetRowCount());
@@ -2075,7 +2072,7 @@ void ObjectMgr::LoadGameobjects()
}
data.go_state = GOState(go_state);
- data.spawnMask = fields[14].GetUInt8();
+ data.spawnMask = fields[14].GetUInt32();
if (!IsTransportMap(data.mapid) && data.spawnMask & ~spawnMasks[data.mapid])
TC_LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: " UI64FMTD " Entry: %u) that has wrong spawn mask %u including unsupported difficulty modes for map (Id: %u), skip", guid, data.id, data.spawnMask, data.mapid);
@@ -2147,7 +2144,7 @@ void ObjectMgr::LoadGameobjects()
void ObjectMgr::AddGameobjectToGrid(ObjectGuid::LowType guid, GameObjectData const* data)
{
- uint8 mask = data->spawnMask;
+ uint32 mask = data->spawnMask;
for (uint8 i = 0; mask != 0; i++, mask >>= 1)
{
if (mask & 1)
@@ -2161,7 +2158,7 @@ void ObjectMgr::AddGameobjectToGrid(ObjectGuid::LowType guid, GameObjectData con
void ObjectMgr::RemoveGameobjectFromGrid(ObjectGuid::LowType guid, GameObjectData const* data)
{
- uint8 mask = data->spawnMask;
+ uint32 mask = data->spawnMask;
for (uint8 i = 0; mask != 0; i++, mask >>= 1)
{
if (mask & 1)
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 5de0862c330..95bbe693335 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -1437,8 +1437,8 @@ class ObjectMgr
CacheVendorItemContainer _cacheVendorItemStore;
CacheTrainerSpellContainer _cacheTrainerSpellStore;
- std::set<uint32> _difficultyEntries[MAX_DIFFICULTY - 1]; // already loaded difficulty 1 value in creatures, used in CheckCreatureTemplate
- std::set<uint32> _hasDifficultyEntries[MAX_DIFFICULTY - 1]; // already loaded creatures with difficulty 1 values, used in CheckCreatureTemplate
+ std::set<uint32> _difficultyEntries[MAX_CREATURE_DIFFICULTIES]; // already loaded difficulty 1 value in creatures, used in CheckCreatureTemplate
+ std::set<uint32> _hasDifficultyEntries[MAX_CREATURE_DIFFICULTIES]; // already loaded creatures with difficulty 1 values, used in CheckCreatureTemplate
ExpansionRequirementContainer _raceExpansionRequirementStore;
ExpansionRequirementContainer _classExpansionRequirementStore;
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 0bc69fc7183..9da1337b065 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -54,7 +54,7 @@ Loot* Roll::getLoot()
}
Group::Group() : m_leaderGuid(), m_leaderName(""), m_groupType(GROUPTYPE_NORMAL),
-m_dungeonDifficulty(DIFFICULTY_NORMAL), m_raidDifficulty(DIFFICULTY_10_N),
+m_dungeonDifficulty(DIFFICULTY_NORMAL), m_raidDifficulty(DIFFICULTY_NORMAL_RAID), m_legacyRaidDifficulty(DIFFICULTY_10_N),
m_bgGroup(NULL), m_bfGroup(NULL), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(),
m_masterLooterGuid(), m_subGroupsCounts(NULL), m_guid(), m_counter(0), m_maxEnchantingLevel(0), m_dbStoreId(0)
{
@@ -112,12 +112,14 @@ bool Group::Create(Player* leader)
m_masterLooterGuid.Clear();
m_dungeonDifficulty = DIFFICULTY_NORMAL;
- m_raidDifficulty = DIFFICULTY_10_N;
+ m_raidDifficulty = DIFFICULTY_NORMAL_RAID;
+ m_legacyRaidDifficulty = DIFFICULTY_10_N;
if (!isBGGroup() && !isBFGroup())
{
- m_dungeonDifficulty = leader->GetDungeonDifficulty();
- m_raidDifficulty = leader->GetRaidDifficulty();
+ m_dungeonDifficulty = leader->GetDungeonDifficultyID();
+ m_raidDifficulty = leader->GetRaidDifficultyID();
+ m_legacyRaidDifficulty = leader->GetLegacyRaidDifficultyID();
m_dbStoreId = sGroupMgr->GenerateNewGroupDbStoreId();
@@ -144,6 +146,7 @@ bool Group::Create(Player* leader)
stmt->setUInt8(index++, uint8(m_groupType));
stmt->setUInt32(index++, uint8(m_dungeonDifficulty));
stmt->setUInt32(index++, uint8(m_raidDifficulty));
+ stmt->setUInt32(index++, uint8(m_legacyRaidDifficulty));
stmt->setUInt64(index++, m_masterLooterGuid.GetCounter());
CharacterDatabase.Execute(stmt);
@@ -180,17 +183,8 @@ void Group::LoadGroupFromDB(Field* fields)
if (m_groupType & GROUPTYPE_RAID)
_initRaidSubGroupsCounter();
- uint32 diff = fields[13].GetUInt8();
- if (diff >= MAX_DUNGEON_DIFFICULTY)
- m_dungeonDifficulty = DIFFICULTY_NORMAL;
- else
- m_dungeonDifficulty = Difficulty(diff);
-
- uint32 r_diff = fields[14].GetUInt8();
- if (r_diff >= MAX_RAID_DIFFICULTY)
- m_raidDifficulty = DIFFICULTY_10_N;
- else
- m_raidDifficulty = Difficulty(r_diff);
+ m_dungeonDifficulty = Player::CheckLoadedDungeonDifficultyID(Difficulty(fields[13].GetUInt8()));
+ m_raidDifficulty = Player::CheckLoadedRaidDifficultyID(Difficulty(fields[14].GetUInt8()));
m_masterLooterGuid = ObjectGuid::Create<HighGuid::Player>(fields[15].GetUInt64());
@@ -437,19 +431,25 @@ bool Group::AddMember(Player* player)
{
// 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);
+ player->ResetInstances(INSTANCE_RESET_GROUP_JOIN, false, false);
+ player->ResetInstances(INSTANCE_RESET_GROUP_JOIN, true, false);
+ player->ResetInstances(INSTANCE_RESET_GROUP_JOIN, true, true);
if (player->getLevel() >= LEVELREQUIREMENT_HEROIC)
{
- if (player->GetDungeonDifficulty() != GetDungeonDifficulty())
+ if (player->GetDungeonDifficultyID() != GetDungeonDifficultyID())
{
- player->SetDungeonDifficulty(GetDungeonDifficulty());
- player->SendDungeonDifficulty(true);
+ player->SetDungeonDifficultyID(GetDungeonDifficultyID());
+ player->SendDungeonDifficulty();
}
- if (player->GetRaidDifficulty() != GetRaidDifficulty())
+ if (player->GetRaidDifficultyID() != GetRaidDifficultyID())
{
- player->SetRaidDifficulty(GetRaidDifficulty());
+ player->SetRaidDifficultyID(GetRaidDifficultyID());
+ player->SendRaidDifficulty(false);
+ }
+ if (player->GetLegacyRaidDifficultyID() != GetLegacyRaidDifficultyID())
+ {
+ player->SetLegacyRaidDifficultyID(GetLegacyRaidDifficultyID());
player->SendRaidDifficulty(true);
}
}
@@ -783,8 +783,9 @@ void Group::Disband(bool hideDestroy /* = false */)
CharacterDatabase.CommitTransaction(trans);
- ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL);
- ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL);
+ ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, false, NULL);
+ ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, false, NULL);
+ ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, true, NULL);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA);
stmt->setUInt32(0, m_dbStoreId);
@@ -1924,7 +1925,7 @@ void Roll::targetObjectBuildLink()
getTarget()->addLootValidatorRef(this);
}
-void Group::SetDungeonDifficulty(Difficulty difficulty)
+void Group::SetDungeonDifficultyID(Difficulty difficulty)
{
m_dungeonDifficulty = difficulty;
if (!isBGGroup() && !isBFGroup())
@@ -1943,12 +1944,12 @@ void Group::SetDungeonDifficulty(Difficulty difficulty)
if (!player->GetSession())
continue;
- player->SetDungeonDifficulty(difficulty);
- player->SendDungeonDifficulty(true);
+ player->SetDungeonDifficultyID(difficulty);
+ player->SendDungeonDifficulty();
}
}
-void Group::SetRaidDifficulty(Difficulty difficulty)
+void Group::SetRaidDifficultyID(Difficulty difficulty)
{
m_raidDifficulty = difficulty;
if (!isBGGroup() && !isBFGroup())
@@ -1967,25 +1968,52 @@ void Group::SetRaidDifficulty(Difficulty difficulty)
if (!player->GetSession())
continue;
- player->SetRaidDifficulty(difficulty);
- player->SendRaidDifficulty(true);
+ player->SetRaidDifficultyID(difficulty);
+ player->SendRaidDifficulty(false);
}
}
-bool Group::InCombatToInstance(uint32 instanceId)
+void Group::SetLegacyRaidDifficultyID(Difficulty difficulty)
{
+ m_legacyRaidDifficulty = difficulty;
+ if (!isBGGroup() && !isBFGroup())
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_LEGACY_RAID_DIFFICULTY);
+
+ stmt->setUInt8(0, uint8(m_legacyRaidDifficulty));
+ stmt->setUInt32(1, m_dbStoreId);
+
+ CharacterDatabase.Execute(stmt);
+ }
+
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
Player* player = itr->GetSource();
- if (player && !player->getAttackers().empty() && player->GetInstanceId() == instanceId && (player->GetMap()->IsRaidOrHeroicDungeon()))
- for (std::set<Unit*>::const_iterator i = player->getAttackers().begin(); i != player->getAttackers().end(); ++i)
- if ((*i) && (*i)->GetTypeId() == TYPEID_UNIT && (*i)->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND)
- return true;
+ if (!player->GetSession())
+ continue;
+
+ player->SetLegacyRaidDifficultyID(difficulty);
+ player->SendRaidDifficulty(true);
}
- return false;
}
-void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo)
+Difficulty Group::GetDifficultyID(MapEntry const* mapEntry) const
+{
+ if (!mapEntry->IsRaid())
+ return m_dungeonDifficulty;
+
+ MapDifficulty const* defaultDifficulty = GetDefaultMapDifficulty(mapEntry->ID);
+ if (!defaultDifficulty)
+ return m_legacyRaidDifficulty;
+
+ DifficultyEntry const* difficulty = sDifficultyStore.LookupEntry(defaultDifficulty->DifficultyID);
+ if (!difficulty || difficulty->Flags & DIFFICULTY_FLAG_LEGACY)
+ return m_legacyRaidDifficulty;
+
+ return m_raidDifficulty;
+}
+
+void Group::ResetInstances(uint8 method, bool isRaid, bool isLegacy, Player* SendMsgTo)
{
if (isBGGroup() || isBFGroup())
return;
@@ -1993,7 +2021,14 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo)
// method can be INSTANCE_RESET_ALL, INSTANCE_RESET_CHANGE_DIFFICULTY, INSTANCE_RESET_GROUP_DISBAND
// we assume that when the difficulty changes, all instances that can be reset will be
- Difficulty diff = GetDifficulty(isRaid);
+ Difficulty diff = GetDungeonDifficultyID();
+ if (isRaid)
+ {
+ if (!isLegacy)
+ diff = GetRaidDifficultyID();
+ else
+ diff = GetLegacyRaidDifficultyID();
+ }
for (BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();)
{
@@ -2082,9 +2117,7 @@ InstanceGroupBind* Group::GetBoundInstance(Player* player)
InstanceGroupBind* Group::GetBoundInstance(Map* aMap)
{
- // Currently spawn numbering not different from map difficulty
- Difficulty difficulty = GetDifficulty(aMap->IsRaid());
- return GetBoundInstance(difficulty, aMap->GetId());
+ return GetBoundInstance(aMap->GetEntry());
}
InstanceGroupBind* Group::GetBoundInstance(MapEntry const* mapEntry)
@@ -2092,7 +2125,7 @@ InstanceGroupBind* Group::GetBoundInstance(MapEntry const* mapEntry)
if (!mapEntry || !mapEntry->IsDungeon())
return NULL;
- Difficulty difficulty = GetDifficulty(mapEntry->IsRaid());
+ Difficulty difficulty = GetDifficultyID(mapEntry);
return GetBoundInstance(difficulty, mapEntry->ID);
}
@@ -2113,7 +2146,7 @@ InstanceGroupBind* Group::BindToInstance(InstanceSave* save, bool permanent, boo
if (!save || isBGGroup() || isBFGroup())
return NULL;
- InstanceGroupBind& bind = m_boundInstances[save->GetDifficulty()][save->GetMapId()];
+ InstanceGroupBind& bind = m_boundInstances[save->GetDifficultyID()][save->GetMapId()];
if (!load && (!bind.save || permanent != bind.perm || save != bind.save))
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GROUP_INSTANCE);
@@ -2136,7 +2169,7 @@ InstanceGroupBind* Group::BindToInstance(InstanceSave* save, bool permanent, boo
bind.perm = permanent;
if (!load)
TC_LOG_DEBUG("maps", "Group::BindToInstance: %s, storage id: %u is now bound to map %d, instance %d, difficulty %d",
- GetGUID().ToString().c_str(), m_dbStoreId, save->GetMapId(), save->GetInstanceId(), save->GetDifficulty());
+ GetGUID().ToString().c_str(), m_dbStoreId, save->GetMapId(), save->GetInstanceId(), save->GetDifficultyID());
return &bind;
}
@@ -2396,26 +2429,6 @@ void Group::SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags fla
SendUpdate();
}
-Difficulty Group::GetDifficulty(bool isRaid) const
-{
- return isRaid ? m_raidDifficulty : m_dungeonDifficulty;
-}
-
-Difficulty Group::GetDungeonDifficulty() const
-{
- return m_dungeonDifficulty;
-}
-
-Difficulty Group::GetRaidDifficulty() const
-{
- return m_raidDifficulty;
-}
-
-bool Group::isRollLootActive() const
-{
- return !RollId.empty();
-}
-
Group::Rolls::iterator Group::GetRoll(ObjectGuid Guid)
{
Rolls::iterator iter;
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index 538be5ea508..ab256704ad5 100644
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -258,14 +258,14 @@ class Group
void SetGroupMemberFlag(ObjectGuid guid, bool apply, GroupMemberFlags flag);
void RemoveUniqueGroupMemberFlag(GroupMemberFlags flag);
- Difficulty GetDifficulty(bool isRaid) const;
- Difficulty GetDungeonDifficulty() const;
- Difficulty GetRaidDifficulty() const;
- void SetDungeonDifficulty(Difficulty difficulty);
- void SetRaidDifficulty(Difficulty difficulty);
- uint16 InInstance();
- bool InCombatToInstance(uint32 instanceId);
- void ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo);
+ void SetDungeonDifficultyID(Difficulty difficulty);
+ void SetRaidDifficultyID(Difficulty difficulty);
+ void SetLegacyRaidDifficultyID(Difficulty difficulty);
+ Difficulty GetDifficultyID(MapEntry const* mapEntry) const;
+ Difficulty GetDungeonDifficultyID() const { return m_dungeonDifficulty; }
+ Difficulty GetRaidDifficultyID() const { return m_raidDifficulty; }
+ Difficulty GetLegacyRaidDifficultyID() const { return m_legacyRaidDifficulty; }
+ void ResetInstances(uint8 method, bool isRaid, bool isLegacy, Player* SendMsgTo);
// -no description-
//void SendInit(WorldSession* session);
@@ -297,7 +297,7 @@ class Group
/*** LOOT SYSTEM ***/
/*********************************************************/
- bool isRollLootActive() const;
+ bool isRollLootActive() const { return !RollId.empty(); }
void SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r);
void SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, bool canNeed, Roll const& r);
void SendLootRoll(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r);
@@ -348,6 +348,7 @@ class Group
GroupType m_groupType;
Difficulty m_dungeonDifficulty;
Difficulty m_raidDifficulty;
+ Difficulty m_legacyRaidDifficulty;
Battleground* m_bgGroup;
Battlefield* m_bfGroup;
ObjectGuid m_targetIcons[TARGETICONCOUNT];
diff --git a/src/server/game/Groups/GroupMgr.cpp b/src/server/game/Groups/GroupMgr.cpp
index 217a2dfd442..f0a0aa5604f 100644
--- a/src/server/game/Groups/GroupMgr.cpp
+++ b/src/server/game/Groups/GroupMgr.cpp
@@ -220,11 +220,9 @@ void GroupMgr::LoadGroups()
}
uint32 diff = fields[4].GetUInt8();
- if (diff >= uint32(mapEntry->IsRaid() ? MAX_RAID_DIFFICULTY : MAX_DUNGEON_DIFFICULTY))
- {
- TC_LOG_ERROR("sql.sql", "Wrong dungeon difficulty use in group_instance table: %d", diff + 1);
- diff = 0; // default for both difficaly types
- }
+ DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(diff);
+ if (!difficultyEntry || difficultyEntry->InstanceType != mapEntry->InstanceType)
+ continue;
InstanceSave* save = sInstanceSaveMgr->AddInstanceSave(mapEntry->ID, fields[2].GetUInt32(), Difficulty(diff), time_t(fields[5].GetUInt32()), fields[6].GetUInt64() != 0, true);
group->BindToInstance(save, fields[3].GetBool(), true);
diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index 457f2ae2faf..f2410f2ffd9 100644
--- a/src/server/game/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
@@ -111,7 +111,7 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/)
{
InstanceSave const* save = itr->second.save;
dataBuffer << uint32(save->GetMapId());
- dataBuffer << uint32(save->GetDifficulty());
+ dataBuffer << uint32(save->GetDifficultyID());
dataBuffer << uint32(save->GetResetTime() - currTime);
dataBuffer << uint64(save->GetInstanceId()); // instance save id as unique instance copy id
++boundCounter;
@@ -726,7 +726,7 @@ void WorldSession::SendCalendarRaidLockout(InstanceSave const* save, bool add)
}
data << uint32(save->GetMapId());
- data << uint32(save->GetDifficulty());
+ data << uint32(save->GetDifficultyID());
data << uint32(save->GetResetTime() - currTime);
data << uint64(save->GetInstanceId());
SendPacket(&data);
@@ -739,14 +739,14 @@ void WorldSession::SendCalendarRaidLockoutUpdated(InstanceSave const* save)
ObjectGuid guid = _player->GetGUID();
TC_LOG_DEBUG("network", "SMSG_CALENDAR_RAID_LOCKOUT_UPDATED [%s] Map: %u, Difficulty %u",
- guid.ToString().c_str(), save->GetMapId(), save->GetDifficulty());
+ guid.ToString().c_str(), save->GetMapId(), save->GetDifficultyID());
time_t currTime = time(NULL);
WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, 4 + 4 + 4 + 4 + 8);
data.AppendPackedTime(currTime);
data << uint32(save->GetMapId());
- data << uint32(save->GetDifficulty());
+ data << uint32(save->GetDifficultyID());
data << uint32(0); // Amount of seconds that has changed to the reset time
data << uint32(save->GetResetTime() - currTime);
SendPacket(&data);
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index de074443a39..84e6ed34bb8 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -845,7 +845,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
SendTutorialsData();
pCurrChar->GetMotionMaster()->Initialize();
- pCurrChar->SendDungeonDifficulty(false);
+ pCurrChar->SendDungeonDifficulty();
WorldPackets::Character::LoginVerifyWorld loginVerifyWorld;
loginVerifyWorld.MapID = pCurrChar->GetMapId();
@@ -873,7 +873,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
features.ScrollOfResurrectionMaxRequestsPerDay = 1;
features.CfgRealmID = 2;
features.CfgRealmRecID = 0;
- features.VoiceEnabled = true;
+ features.VoiceEnabled = false;
/// END OF DUMMY VALUES
features.CharUndeleteEnabled = sWorld->getBoolConfig(CONFIG_FEATURE_SYSTEM_CHARACTER_UNDELETE_ENABLED);
@@ -2489,6 +2489,7 @@ void WorldSession::SendCharRename(ResponseCodes result, WorldPackets::Character:
void WorldSession::SendCharCustomize(ResponseCodes result, WorldPackets::Character::CharCustomizeInfo const* customizeInfo)
{
/// @todo: fix 6.x implementation
+ (void)result;
(void)customizeInfo;
/*
WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1 + 8 + customizeInfo.NewName.size() + 1 + 6);
diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index 97b25d5fc1b..9f42c4591ea 100644
--- a/src/server/game/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
@@ -134,7 +134,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData)
return;
}
// just ignore us
- if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty())
+ if (player->GetInstanceId() != 0 && player->GetDungeonDifficultyID() != GetPlayer()->GetDungeonDifficultyID())
{
SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S);
return;
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 1bdb0fd703e..569bcf73ffa 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -1540,26 +1540,38 @@ void WorldSession::HandleResetInstancesOpcode(WorldPacket& /*recvData*/)
if (Group* group = _player->GetGroup())
{
if (group->IsLeader(_player->GetGUID()))
- group->ResetInstances(INSTANCE_RESET_ALL, false, _player);
+ group->ResetInstances(INSTANCE_RESET_ALL, false, false, _player);
}
else
- _player->ResetInstances(INSTANCE_RESET_ALL, false);
+ _player->ResetInstances(INSTANCE_RESET_ALL, false, false);
}
-void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket& recvData)
+void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPackets::Misc::SetDungeonDifficulty& setDungeonDifficulty)
{
- TC_LOG_DEBUG("network", "MSG_SET_DUNGEON_DIFFICULTY");
+ DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(setDungeonDifficulty.DifficultyID);
+ if (!difficultyEntry)
+ {
+ TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: %s sent an invalid instance mode %d!",
+ _player->GetGUID().ToString().c_str(), setDungeonDifficulty.DifficultyID);
+ return;
+ }
- uint32 mode;
- recvData >> mode;
+ if (difficultyEntry->InstanceType != MAP_INSTANCE)
+ {
+ TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: %s sent an non-dungeon instance mode %d!",
+ _player->GetGUID().ToString().c_str(), difficultyEntry->ID);
+ return;
+ }
- if (mode >= MAX_DUNGEON_DIFFICULTY)
+ if (!(difficultyEntry->Flags & DIFFICULTY_FLAG_CAN_SELECT))
{
- TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: %s sent an invalid instance mode %d!", _player->GetGUID().ToString().c_str(), mode);
+ TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: %s sent unselectable instance mode %d!",
+ _player->GetGUID().ToString().c_str(), difficultyEntry->ID);
return;
}
- if (Difficulty(mode) == _player->GetDungeonDifficulty())
+ Difficulty difficultyID = Difficulty(difficultyEntry->ID);
+ if (difficultyID == _player->GetDungeonDifficultyID())
return;
// cannot reset while in an instance
@@ -1594,41 +1606,62 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket& recvData)
}
// the difficulty is set even if the instances can't be reset
//_player->SendDungeonDifficulty(true);
- group->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false, _player);
- group->SetDungeonDifficulty(Difficulty(mode));
+ group->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false, false, _player);
+ group->SetDungeonDifficultyID(difficultyID);
}
}
else
{
- _player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false);
- _player->SetDungeonDifficulty(Difficulty(mode));
+ _player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, false, false);
+ _player->SetDungeonDifficultyID(difficultyID);
+ _player->SendDungeonDifficulty();
}
}
-void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recvData)
+void WorldSession::HandleSetRaidDifficultyOpcode(WorldPackets::Misc::SetRaidDifficulty& setRaidDifficulty)
{
- TC_LOG_DEBUG("network", "MSG_SET_RAID_DIFFICULTY");
+ DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(setRaidDifficulty.DifficultyID);
+ if (!difficultyEntry)
+ {
+ TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: %s sent an invalid instance mode %u!",
+ _player->GetGUID().ToString().c_str(), setRaidDifficulty.DifficultyID);
+ return;
+ }
- uint32 mode;
- recvData >> mode;
+ if (difficultyEntry->InstanceType != MAP_RAID)
+ {
+ TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: %s sent an non-dungeon instance mode %u!",
+ _player->GetGUID().ToString().c_str(), difficultyEntry->ID);
+ return;
+ }
- if (mode >= MAX_RAID_DIFFICULTY)
+ if (!(difficultyEntry->Flags & DIFFICULTY_FLAG_CAN_SELECT))
{
- TC_LOG_ERROR("network", "WorldSession::HandleSetRaidDifficultyOpcode: %s sent an invalid instance mode %d!", _player->GetGUID().ToString().c_str(), mode);
+ TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: %s sent unselectable instance mode %u!",
+ _player->GetGUID().ToString().c_str(), difficultyEntry->ID);
return;
}
+ if (((difficultyEntry->Flags & DIFFICULTY_FLAG_LEGACY) >> 5) != setRaidDifficulty.Legacy)
+ {
+ TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: %s sent not matching legacy difficulty %u!",
+ _player->GetGUID().ToString().c_str(), difficultyEntry->ID);
+ return;
+ }
+
+ Difficulty difficultyID = Difficulty(difficultyEntry->ID);
+ if (difficultyID == (setRaidDifficulty.Legacy ? _player->GetLegacyRaidDifficultyID() : _player->GetRaidDifficultyID()))
+ return;
+
// cannot reset while in an instance
Map* map = _player->FindMap();
if (map && map->IsDungeon())
{
- TC_LOG_DEBUG("network", "WorldSession::HandleSetRaidDifficultyOpcode: %s tried to reset the instance while inside!", _player->GetGUID().ToString().c_str());
+ TC_LOG_DEBUG("network", "WorldSession::HandleSetRaidDifficultyOpcode: player (Name: %s, %s) tried to reset the instance while player is inside!",
+ _player->GetName().c_str(), _player->GetGUID().ToString().c_str());
return;
}
- if (Difficulty(mode) == _player->GetRaidDifficulty())
- return;
-
Group* group = _player->GetGroup();
if (group)
{
@@ -1645,20 +1678,28 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recvData)
if (groupGuy->GetMap()->IsRaid())
{
- TC_LOG_DEBUG("network", "WorldSession::HandleSetRaidDifficultyOpcode: %s tried to reset the instance while inside!", _player->GetGUID().ToString().c_str());
+ TC_LOG_DEBUG("network", "WorldSession::HandleSetRaidDifficultyOpcode: %s tried to reset the instance while group member (Name: %s, %s) is inside!",
+ _player->GetGUID().ToString().c_str(), groupGuy->GetName().c_str(), groupGuy->GetGUID().ToString().c_str());
return;
}
}
// the difficulty is set even if the instances can't be reset
- //_player->SendDungeonDifficulty(true);
- group->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true, _player);
- group->SetRaidDifficulty(Difficulty(mode));
+ group->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true, setRaidDifficulty.Legacy != 0, _player);
+ if (setRaidDifficulty.Legacy)
+ group->SetLegacyRaidDifficultyID(difficultyID);
+ else
+ group->SetRaidDifficultyID(difficultyID);
}
}
else
{
- _player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true);
- _player->SetRaidDifficulty(Difficulty(mode));
+ _player->ResetInstances(INSTANCE_RESET_CHANGE_DIFFICULTY, true, setRaidDifficulty.Legacy != 0);
+ if (setRaidDifficulty.Legacy)
+ _player->SetLegacyRaidDifficultyID(difficultyID);
+ else
+ _player->SetRaidDifficultyID(difficultyID);
+
+ _player->SendRaidDifficulty(setRaidDifficulty.Legacy != 0);
}
}
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index f4d9c7d10ca..e1e5ae49778 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -158,7 +158,7 @@ void WorldSession::HandleMoveWorldportAckOpcode()
bool allowMount = !mEntry->IsDungeon() || mEntry->IsBattlegroundOrArena();
if (mInstance)
{
- Difficulty diff = GetPlayer()->GetDifficulty(mEntry->IsRaid());
+ Difficulty diff = GetPlayer()->GetDifficultyID(mEntry);
if (MapDifficulty const* mapDiff = GetMapDifficultyData(mEntry->ID, diff))
{
if (mapDiff->resetTime)
diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp
index 2f5d7f9f8f1..9423cd78aa3 100644
--- a/src/server/game/Instances/InstanceSaveMgr.cpp
+++ b/src/server/game/Instances/InstanceSaveMgr.cpp
@@ -51,13 +51,13 @@ void InstanceSaveManager::Unload()
for (InstanceSave::PlayerListType::iterator itr2 = save->m_playerList.begin(), next = itr2; itr2 != save->m_playerList.end(); itr2 = next)
{
++next;
- (*itr2)->UnbindInstance(save->GetMapId(), save->GetDifficulty(), true);
+ (*itr2)->UnbindInstance(save->GetMapId(), save->GetDifficultyID(), true);
}
for (InstanceSave::GroupListType::iterator itr2 = save->m_groupList.begin(), next = itr2; itr2 != save->m_groupList.end(); itr2 = next)
{
++next;
- (*itr2)->UnbindInstance(save->GetMapId(), save->GetDifficulty(), true);
+ (*itr2)->UnbindInstance(save->GetMapId(), save->GetDifficultyID(), true);
}
delete save;
@@ -86,7 +86,8 @@ InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instance
return NULL;
}
- if (difficulty >= (entry->IsRaid() ? MAX_RAID_DIFFICULTY : MAX_DUNGEON_DIFFICULTY))
+ DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(difficulty);
+ if (!difficultyEntry || difficultyEntry->InstanceType != entry->InstanceType)
{
TC_LOG_ERROR("misc", "InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d, wrong dificalty %u!", mapId, instanceId, difficulty);
return NULL;
@@ -203,7 +204,7 @@ void InstanceSave::SaveToDB()
stmt->setUInt32(0, m_instanceid);
stmt->setUInt16(1, GetMapId());
stmt->setUInt32(2, uint32(GetResetTimeForDB()));
- stmt->setUInt8(3, uint8(GetDifficulty()));
+ stmt->setUInt8(3, uint8(GetDifficultyID()));
stmt->setUInt32(4, completedEncounters);
stmt->setString(5, data);
CharacterDatabase.Execute(stmt);
@@ -213,7 +214,7 @@ time_t InstanceSave::GetResetTimeForDB()
{
// only save the reset time for normal instances
const MapEntry* entry = sMapStore.LookupEntry(GetMapId());
- if (!entry || entry->IsRaid() || GetDifficulty() == DIFFICULTY_HEROIC)
+ if (!entry || entry->IsRaid() || GetDifficultyID() == DIFFICULTY_HEROIC)
return 0;
else
return GetResetTime();
@@ -391,50 +392,53 @@ void InstanceSaveManager::LoadResetTimes()
// calculate new global reset times for expired instances and those that have never been reset yet
// add the global reset times to the priority queue
- for (MapDifficultyMap::const_iterator itr = sMapDifficultyMap.begin(); itr != sMapDifficultyMap.end(); ++itr)
+ for (auto& mapDifficultyPair : sMapDifficultyMap)
{
- uint32 map_diff_pair = itr->first;
- uint32 mapid = PAIR32_LOPART(map_diff_pair);
- Difficulty difficulty = Difficulty(PAIR32_HIPART(map_diff_pair));
- MapDifficulty const* mapDiff = &itr->second;
- if (!mapDiff->resetTime)
- continue;
-
- // the reset_delay must be at least one day
- uint32 period = uint32(((mapDiff->resetTime * sWorld->getRate(RATE_INSTANCE_RESET_TIME))/DAY) * DAY);
- if (period < DAY)
- period = DAY;
+ uint32 mapid = mapDifficultyPair.first;
- time_t t = GetResetTimeFor(mapid, difficulty);
- if (!t)
+ for (auto& difficultyPair : mapDifficultyPair.second)
{
- // initialize the reset time
- t = today + period + diff;
- CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u', '%u', '%u')", mapid, difficulty, (uint32)t);
- }
+ Difficulty difficulty = Difficulty(difficultyPair.first);
+ MapDifficulty const* mapDiff = &difficultyPair.second;
+ if (!mapDiff->resetTime)
+ continue;
- if (t < now)
- {
- // assume that expired instances have already been cleaned
- // calculate the next reset time
- t = (t / DAY) * DAY;
- t += ((today - t) / period + 1) * period + diff;
- CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '" UI64FMTD "' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty);
- }
+ // the reset_delay must be at least one day
+ uint32 period = uint32(((mapDiff->resetTime * sWorld->getRate(RATE_INSTANCE_RESET_TIME)) / DAY) * DAY);
+ if (period < DAY)
+ period = DAY;
+
+ time_t t = GetResetTimeFor(mapid, difficulty);
+ if (!t)
+ {
+ // initialize the reset time
+ t = today + period + diff;
+ CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u', '%u', '%u')", mapid, difficulty, (uint32)t);
+ }
- InitializeResetTimeFor(mapid, difficulty, t);
+ if (t < now)
+ {
+ // assume that expired instances have already been cleaned
+ // calculate the next reset time
+ t = (t / DAY) * DAY;
+ t += ((today - t) / period + 1) * period + diff;
+ CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '" UI64FMTD "' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty);
+ }
- // schedule the global reset/warning
- uint8 type;
- for (type = 1; type < 4; ++type)
- if (t - ResetTimeDelay[type-1] > now)
- break;
+ InitializeResetTimeFor(mapid, difficulty, t);
- ScheduleReset(true, t - ResetTimeDelay[type-1], InstResetEvent(type, mapid, difficulty, 0));
+ // schedule the global reset/warning
+ uint8 type;
+ for (type = 1; type < 4; ++type)
+ if (t - ResetTimeDelay[type - 1] > now)
+ break;
- ResetTimeMapDiffInstancesBounds range = mapDiffResetInstances.equal_range(map_diff_pair);
- for (; range.first != range.second; ++range.first)
- ScheduleReset(true, t - ResetTimeDelay[type-1], InstResetEvent(type, mapid, difficulty, range.first->second));
+ ScheduleReset(true, t - ResetTimeDelay[type - 1], InstResetEvent(type, mapid, difficulty, 0));
+
+ ResetTimeMapDiffInstancesBounds range = mapDiffResetInstances.equal_range(MAKE_PAIR32(mapid, difficulty));
+ for (; range.first != range.second; ++range.first)
+ ScheduleReset(true, t - ResetTimeDelay[type - 1], InstResetEvent(type, mapid, difficulty, range.first->second));
+ }
}
}
@@ -519,14 +523,14 @@ void InstanceSaveManager::_ResetSave(InstanceSaveHashMap::iterator &itr)
while (!pList.empty())
{
Player* player = *(pList.begin());
- player->UnbindInstance(itr->second->GetMapId(), itr->second->GetDifficulty(), true);
+ player->UnbindInstance(itr->second->GetMapId(), itr->second->GetDifficultyID(), true);
}
InstanceSave::GroupListType &gList = itr->second->m_groupList;
while (!gList.empty())
{
Group* group = *(gList.begin());
- group->UnbindInstance(itr->second->GetMapId(), itr->second->GetDifficulty(), true);
+ group->UnbindInstance(itr->second->GetMapId(), itr->second->GetDifficultyID(), true);
}
delete itr->second;
@@ -583,7 +587,7 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, b
// remove all binds to instances of the given map
for (InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end();)
{
- if (itr->second->GetMapId() == mapid && itr->second->GetDifficulty() == difficulty)
+ if (itr->second->GetMapId() == mapid && itr->second->GetDifficultyID() == difficulty)
_ResetSave(itr);
else
++itr;
diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h
index bba89a77e42..1b7f5502049 100644
--- a/src/server/game/Instances/InstanceSaveMgr.h
+++ b/src/server/game/Instances/InstanceSaveMgr.h
@@ -118,7 +118,7 @@ class InstanceSave
/* currently it is possible to omit this information from this structure
but that would depend on a lot of things that can easily change in future */
- Difficulty GetDifficulty() const { return m_difficulty; }
+ Difficulty GetDifficultyID() const { return m_difficulty; }
/* used to flag the InstanceSave as to be deleted, so the caller can delete it */
void SetToDelete(bool toDelete)
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index 29a2b96a985..b8f95b9407c 100644
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -589,7 +589,7 @@ void InstanceScript::SendEncounterUnit(uint32 type, Unit* unit /*= NULL*/, uint8
void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit* /*source*/)
{
- DungeonEncounterList const* encounters = sObjectMgr->GetDungeonEncounterList(instance->GetId(), instance->GetDifficulty());
+ DungeonEncounterList const* encounters = sObjectMgr->GetDungeonEncounterList(instance->GetId(), instance->GetDifficultyID());
if (!encounters)
return;
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 20473192f75..29041b5bccb 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -2956,7 +2956,7 @@ bool InstanceMap::AddPlayerToMap(Player* player)
// cannot enter other instances if bound permanently
if (playerBind->save != mapSave)
{
- TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%s) is permanently bound to instance %s %d, %d, %d, %d, %d, %d but he is being put into instance %s %d, %d, %d, %d, %d, %d", player->GetName().c_str(), player->GetGUID().ToString().c_str(), GetMapName(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset());
+ TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%s) is permanently bound to instance %s %d, %d, %d, %d, %d, %d but he is being put into instance %s %d, %d, %d, %d, %d, %d", player->GetName().c_str(), player->GetGUID().ToString().c_str(), GetMapName(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficultyID(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficultyID(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset());
return false;
}
}
@@ -2968,9 +2968,9 @@ bool InstanceMap::AddPlayerToMap(Player* player)
InstanceGroupBind* groupBind = group->GetBoundInstance(this);
if (playerBind && playerBind->save != mapSave)
{
- TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%s) is being put into instance %s %d, %d, %d, %d, %d, %d but he is in group %s and is bound to instance %d, %d, %d, %d, %d, %d!", player->GetName().c_str(), player->GetGUID().ToString().c_str(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), group->GetLeaderGUID().ToString().c_str(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
+ TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%s) is being put into instance %s %d, %d, %d, %d, %d, %d but he is in group %s and is bound to instance %d, %d, %d, %d, %d, %d!", player->GetName().c_str(), player->GetGUID().ToString().c_str(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficultyID(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), group->GetLeaderGUID().ToString().c_str(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficultyID(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
if (groupBind)
- TC_LOG_ERROR("maps", "InstanceMap::Add: the group is bound to the instance %s %d, %d, %d, %d, %d, %d", GetMapName(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset());
+ TC_LOG_ERROR("maps", "InstanceMap::Add: the group is bound to the instance %s %d, %d, %d, %d, %d, %d", GetMapName(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficultyID(), groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset());
//ASSERT(false);
return false;
}
@@ -2982,7 +2982,7 @@ bool InstanceMap::AddPlayerToMap(Player* player)
// cannot jump to a different instance without resetting it
if (groupBind->save != mapSave)
{
- TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%s) is being put into instance %d, %d, %d but he is in group %s which is bound to instance %d, %d, %d!", player->GetName().c_str(), player->GetGUID().ToString().c_str(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), group->GetLeaderGUID().ToString().c_str(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty());
+ TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%s) is being put into instance %d, %d, %d but he is in group %s which is bound to instance %d, %d, %d!", player->GetName().c_str(), player->GetGUID().ToString().c_str(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficultyID(), group->GetLeaderGUID().ToString().c_str(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficultyID());
TC_LOG_ERROR("maps", "MapSave players: %d, group count: %d", mapSave->GetPlayerCount(), mapSave->GetGroupCount());
if (groupBind->save)
TC_LOG_ERROR("maps", "GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount());
@@ -3153,7 +3153,7 @@ void InstanceMap::PermBindAllPlayers(Player* source)
Player* player = itr->GetSource();
// players inside an instance cannot be bound to other instances
// some players may already be permanently bound, in this case nothing happens
- InstancePlayerBind* bind = player->GetBoundInstance(save->GetMapId(), save->GetDifficulty());
+ InstancePlayerBind* bind = player->GetBoundInstance(save->GetMapId(), save->GetDifficultyID());
if (!bind || !bind->perm)
{
player->BindToInstance(save, true);
@@ -3183,7 +3183,7 @@ void InstanceMap::UnloadAll()
void InstanceMap::SendResetWarnings(uint32 timeLeft) const
{
for (MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
- itr->GetSource()->SendInstanceResetWarning(GetId(), itr->GetSource()->GetDifficulty(IsRaid()), timeLeft);
+ itr->GetSource()->SendInstanceResetWarning(GetId(), itr->GetSource()->GetDifficultyID(GetEntry()), timeLeft);
}
void InstanceMap::SetResetSchedule(bool on)
@@ -3203,7 +3203,14 @@ void InstanceMap::SetResetSchedule(bool on)
MapDifficulty const* Map::GetMapDifficulty() const
{
- return GetMapDifficultyData(GetId(), GetDifficulty());
+ return GetMapDifficultyData(GetId(), GetDifficultyID());
+}
+
+bool Map::IsHeroic() const
+{
+ if (DifficultyEntry const* difficulty = sDifficultyStore.LookupEntry(i_spawnMode))
+ return difficulty->Flags & DIFFICULTY_FLAG_HEROIC;
+ return false;
}
uint32 InstanceMap::GetMaxPlayers() const
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 7bd21b57072..94b89484e15 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -385,17 +385,16 @@ class Map : public GridRefManager<NGridType>
const char* GetMapName() const;
// have meaning only for instanced map (that have set real difficulty)
- Difficulty GetDifficulty() const { return Difficulty(GetSpawnMode()); }
- bool IsRegularDifficulty() const { return GetDifficulty() == DIFFICULTY_NONE; }
+ Difficulty GetDifficultyID() const { return Difficulty(GetSpawnMode()); }
MapDifficulty const* GetMapDifficulty() const;
bool Instanceable() const { return i_mapEntry && i_mapEntry->Instanceable(); }
bool IsDungeon() const { return i_mapEntry && i_mapEntry->IsDungeon(); }
bool IsNonRaidDungeon() const { return i_mapEntry && i_mapEntry->IsNonRaidDungeon(); }
bool IsRaid() const { return i_mapEntry && i_mapEntry->IsRaid(); }
- bool IsRaidOrHeroicDungeon() const { return IsRaid() || i_spawnMode > DIFFICULTY_NORMAL; }
- bool IsHeroic() const { return IsRaid() ? i_spawnMode >= DIFFICULTY_10_HC : i_spawnMode >= DIFFICULTY_HEROIC; }
- bool Is25ManRaid() const { return IsRaid() && i_spawnMode & RAID_DIFFICULTY_MASK_25MAN; } // since 25man difficulties are 1 and 3, we can check them like that
+ bool IsRaidOrHeroicDungeon() const { return IsRaid() || IsHeroic(); }
+ bool IsHeroic() const;
+ bool Is25ManRaid() const { return IsRaid() && (i_spawnMode == DIFFICULTY_25_N || i_spawnMode == DIFFICULTY_25_HC); } // since 25man difficulties are 1 and 3, we can check them like that
bool IsBattleground() const { return i_mapEntry && i_mapEntry->IsBattleground(); }
bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); }
bool IsBattlegroundOrArena() const { return i_mapEntry && i_mapEntry->IsBattlegroundOrArena(); }
diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp
index 1a9a5d5698d..cc0c99adc99 100644
--- a/src/server/game/Maps/MapInstanced.cpp
+++ b/src/server/game/Maps/MapInstanced.cpp
@@ -140,7 +140,7 @@ Map* MapInstanced::CreateInstanceForPlayer(const uint32 mapId, Player* player)
}
else
{
- InstancePlayerBind* pBind = player->GetBoundInstance(GetId(), player->GetDifficulty(IsRaid()));
+ InstancePlayerBind* pBind = player->GetBoundInstance(GetId(), player->GetDifficultyID(GetEntry()));
InstanceSave* pSave = pBind ? pBind->save : NULL;
// the player's permanent player bind is taken into consideration first
@@ -164,7 +164,7 @@ Map* MapInstanced::CreateInstanceForPlayer(const uint32 mapId, Player* player)
map = FindInstanceMap(newInstanceId);
// it is possible that the save exists but the map doesn't
if (!map)
- map = CreateInstance(newInstanceId, pSave, pSave->GetDifficulty());
+ map = CreateInstance(newInstanceId, pSave, pSave->GetDifficultyID());
}
else
{
@@ -172,7 +172,7 @@ Map* MapInstanced::CreateInstanceForPlayer(const uint32 mapId, Player* player)
// the instance will be created for the first time
newInstanceId = sMapMgr->GenerateInstanceId();
- Difficulty diff = player->GetGroup() ? player->GetGroup()->GetDifficulty(IsRaid()) : player->GetDifficulty(IsRaid());
+ Difficulty diff = player->GetGroup() ? player->GetGroup()->GetDifficultyID(GetEntry()) : player->GetDifficultyID(GetEntry());
//Seems it is now possible, but I do not know if it should be allowed
//ASSERT(!FindInstanceMap(NewInstanceId));
map = FindInstanceMap(newInstanceId);
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index d2198d02013..a9acb2ef30a 100644
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -133,7 +133,7 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck)
return false;
Difficulty targetDifficulty, requestedDifficulty;
- targetDifficulty = requestedDifficulty = player->GetDifficulty(entry->IsRaid());
+ targetDifficulty = requestedDifficulty = player->GetDifficultyID(entry);
// Get the highest available difficulty if current setting is higher than the instance allows
MapDifficulty const* mapDiff = GetDownscaledMapDifficultyData(entry->ID, targetDifficulty);
if (!mapDiff)
@@ -203,7 +203,7 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck)
/*
This check has to be moved to InstanceMap::CanEnter()
// Player permanently bounded to different instance than groups one
- InstancePlayerBind* playerBoundedInstance = player->GetBoundInstance(mapid, player->GetDifficulty(entry->IsRaid()));
+ InstancePlayerBind* playerBoundedInstance = player->GetBoundInstance(mapid, player->GetDifficultyID(entry));
if (playerBoundedInstance && playerBoundedInstance->perm && playerBoundedInstance->save &&
boundedInstance->save->GetInstanceId() != playerBoundedInstance->save->GetInstanceId())
{
@@ -216,7 +216,7 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck)
if (entry->IsDungeon() && (!player->GetGroup() || (player->GetGroup() && !player->GetGroup()->isLFGGroup())))
{
uint32 instanceIdToCheck = 0;
- if (InstanceSave* save = player->GetInstanceSave(mapid, entry->IsRaid()))
+ if (InstanceSave* save = player->GetInstanceSave(mapid))
instanceIdToCheck = save->GetInstanceId();
// instanceId can never be 0 - will not be found
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index 2801dbead33..cd5b79c95c3 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -316,9 +316,9 @@ bool Quest::IsRaidQuest(Difficulty difficulty) const
case QUEST_INFO_RAID:
return true;
case QUEST_INFO_RAID_10:
- return !(difficulty & RAID_DIFFICULTY_MASK_25MAN);
+ return difficulty == DIFFICULTY_10_N || difficulty == DIFFICULTY_10_HC;
case QUEST_INFO_RAID_25:
- return difficulty & RAID_DIFFICULTY_MASK_25MAN;
+ return difficulty == DIFFICULTY_25_N || difficulty == DIFFICULTY_25_HC;
default:
break;
}
diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp
index a9955bf7449..937bd75c4b9 100644
--- a/src/server/game/Server/Packets/MiscPackets.cpp
+++ b/src/server/game/Server/Packets/MiscPackets.cpp
@@ -183,3 +183,27 @@ void WorldPackets::Misc::AreaTrigger::Read()
Entered = _worldPacket.ReadBit();
FromClient = _worldPacket.ReadBit();
}
+
+void WorldPackets::Misc::SetDungeonDifficulty::Read()
+{
+ _worldPacket >> DifficultyID;
+}
+
+void WorldPackets::Misc::SetRaidDifficulty::Read()
+{
+ _worldPacket >> DifficultyID;
+ _worldPacket >> Legacy;
+}
+
+WorldPacket const* WorldPackets::Misc::DungeonDifficultySet::Write()
+{
+ _worldPacket << int32(DifficultyID);
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Misc::RaidDifficultySet::Write()
+{
+ _worldPacket << int32(DifficultyID);
+ _worldPacket << uint8(Legacy);
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h
index f42d560f36d..ae12389e791 100644
--- a/src/server/game/Server/Packets/MiscPackets.h
+++ b/src/server/game/Server/Packets/MiscPackets.h
@@ -96,10 +96,10 @@ namespace WorldPackets
{
int32 Type = 0; // ID from CurrencyTypes.dbc
int32 Quantity = 0;
- Optional<int32> WeeklyQuantity; // Currency count obtained this Week.
+ Optional<int32> WeeklyQuantity; // Currency count obtained this Week.
Optional<int32> MaxWeeklyQuantity; // Weekly Currency cap.
Optional<int32> TrackedQuantity;
- uint8 Flags = 0; // 0 = none,
+ uint8 Flags = 0; // 0 = none,
};
SetupCurrency() : ServerPacket(SMSG_SETUP_CURRENCY, 22) { }
@@ -221,6 +221,48 @@ namespace WorldPackets
bool Entered = false;
bool FromClient = false;
};
+
+ class SetDungeonDifficulty final : public ClientPacket
+ {
+ public:
+ SetDungeonDifficulty(WorldPacket&& packet) : ClientPacket(CMSG_SET_DUNGEON_DIFFICULTY, std::move(packet)) { }
+
+ void Read() override;
+
+ int32 DifficultyID;
+ };
+
+ class SetRaidDifficulty final : public ClientPacket
+ {
+ public:
+ SetRaidDifficulty(WorldPacket&& packet) : ClientPacket(CMSG_SET_RAID_DIFFICULTY, std::move(packet)) { }
+
+ void Read() override;
+
+ int32 DifficultyID;
+ uint8 Legacy;
+ };
+
+ class DungeonDifficultySet final : public ServerPacket
+ {
+ public:
+ DungeonDifficultySet() : ServerPacket(SMSG_SET_DUNGEON_DIFFICULTY, 4) { }
+
+ WorldPacket const* Write() override;
+
+ int32 DifficultyID;
+ };
+
+ class RaidDifficultySet final : public ServerPacket
+ {
+ public:
+ RaidDifficultySet() : ServerPacket(SMSG_SET_RAID_DIFFICULTY, 4 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ int32 DifficultyID;
+ uint8 Legacy;
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index d2956f64e27..d1502e0c863 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -603,6 +603,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ALLOW_LOW_LEVEL_RAID2, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_CONTACT_NOTES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetContactNotesOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_CURRENCY_FLAGS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_HANDLER(CMSG_SET_DUNGEON_DIFFICULTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::SetDungeonDifficulty, &WorldSession::HandleSetDungeonDifficultyOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_EVERYONE_IS_ASSISTANT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_FACTION_ATWAR, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionAtWar );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_FACTION_INACTIVE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionInactiveOpcode );
@@ -612,7 +613,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PLAYER_DECLINED_NAMES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetPlayerDeclinedNames );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PREFERED_CEMETERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PVP, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_RAID_DIFFICULTY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_HANDLER(CMSG_SET_RAID_DIFFICULTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::SetRaidDifficulty, &WorldSession::HandleSetRaidDifficultyOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_RELATIVE_POSITION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_SAVED_INSTANCE_EXTEND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetSavedInstanceExtend );
DEFINE_HANDLER(CMSG_SET_SELECTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::SetSelection, &WorldSession::HandleSetSelectionOpcode);
@@ -698,8 +699,6 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(MSG_RAID_READY_CHECK_FINISHED, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidReadyCheckFinishedOpcode);
DEFINE_OPCODE_HANDLER_OLD(MSG_RAID_TARGET_UPDATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidTargetUpdateOpcode );
DEFINE_OPCODE_HANDLER_OLD(MSG_SAVE_GUILD_EMBLEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSaveGuildEmblemOpcode );
- DEFINE_OPCODE_HANDLER_OLD(MSG_SET_DUNGEON_DIFFICULTY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetDungeonDifficultyOpcode);
- DEFINE_OPCODE_HANDLER_OLD(MSG_SET_RAID_DIFFICULTY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetRaidDifficultyOpcode );
DEFINE_OPCODE_HANDLER_OLD(MSG_TABARDVENDOR_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTabardVendorActivateOpcode);
DEFINE_OPCODE_HANDLER_OLD(MSG_TALENT_WIPE_CONFIRM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTalentWipeConfirmOpcode );
@@ -1306,6 +1305,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_ALL_TASK_PROGRESS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_CURRENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_DF_FAST_LAUNCH_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_DUNGEON_DIFFICULTY, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_ATWAR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_NOT_VISIBLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_STANDING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1321,6 +1321,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAY_HOVER_ANIM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROJECTILE_POSITION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_RAID_DIFFICULTY, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_TIME_ZONE_INFORMATION, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SETUP_CURRENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOWTAXINODES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index 3177cb77d2a..b33f218c898 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -552,6 +552,7 @@ enum OpcodeClient : uint32
CMSG_SET_ALLOW_LOW_LEVEL_RAID2 = 0xBADD,
CMSG_SET_CONTACT_NOTES = 0xBADD,
CMSG_SET_CURRENCY_FLAGS = 0xBADD,
+ CMSG_SET_DUNGEON_DIFFICULTY = 0x012F,
CMSG_SET_EVERYONE_IS_ASSISTANT = 0xBADD,
CMSG_SET_FACTION_ATWAR = 0xBADD,
CMSG_SET_FACTION_CHEAT = 0xBADD,
@@ -563,7 +564,7 @@ enum OpcodeClient : uint32
CMSG_SET_PLAYER_DECLINED_NAMES = 0xBADD,
CMSG_SET_PREFERED_CEMETERY = 0xBADD,
CMSG_SET_PVP = 0x19B9,
- CMSG_SET_RAID_DIFFICULTY = 0xBADD,
+ CMSG_SET_RAID_DIFFICULTY = 0x1121,
CMSG_SET_RELATIVE_POSITION = 0xBADD,
CMSG_SET_SAVED_INSTANCE_EXTEND = 0xBADD,
CMSG_SET_SELECTION = 0x05BD,
@@ -671,8 +672,6 @@ enum OpcodeClient : uint32
MSG_RAID_READY_CHECK_FINISHED = 0xBADD,
MSG_RAID_TARGET_UPDATE = 0xBADD,
MSG_SAVE_GUILD_EMBLEM = 0xBADD,
- MSG_SET_DUNGEON_DIFFICULTY = 0xBADD,
- MSG_SET_RAID_DIFFICULTY = 0xBADD,
MSG_TABARDVENDOR_ACTIVATE = 0xBADD,
MSG_TALENT_WIPE_CONFIRM = 0xBADD
};
@@ -1309,6 +1308,7 @@ enum OpcodeServer : uint32
SMSG_SET_ALL_TASK_PROGRESS = 0x1B52,
SMSG_SET_CURRENCY = 0x17BE,
SMSG_SET_DF_FAST_LAUNCH_RESULT = 0xBADD,
+ SMSG_SET_DUNGEON_DIFFICULTY = 0x0719,
SMSG_SET_FACTION_ATWAR = 0xBADD,
SMSG_SET_FACTION_NOT_VISIBLE = 0xBADD,
SMSG_SET_FACTION_STANDING = 0xBADD,
@@ -1324,6 +1324,7 @@ enum OpcodeServer : uint32
SMSG_SET_PLAY_HOVER_ANIM = 0x02D4,
SMSG_SET_PROFICIENCY = 0x00D3,
SMSG_SET_PROJECTILE_POSITION = 0xBADD,
+ SMSG_SET_RAID_DIFFICULTY = 0x051F,
SMSG_SET_TIME_ZONE_INFORMATION = 0x153E,
SMSG_SET_VIGNETTE = 0x09AC,
SMSG_SETUP_CURRENCY = 0x0B06,
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 1779530fcba..ae14b0667a9 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -171,6 +171,8 @@ namespace WorldPackets
class ViolenceLevel;
class TimeSyncResponse;
class TutorialSetFlag;
+ class SetDungeonDifficulty;
+ class SetRaidDifficulty;
}
namespace Movement
@@ -1028,8 +1030,8 @@ class WorldSession
void HandleMinimapPingOpcode(WorldPacket& recvData);
void HandleRandomRollOpcode(WorldPacket& recvData);
void HandleFarSightOpcode(WorldPacket& recvData);
- void HandleSetDungeonDifficultyOpcode(WorldPacket& recvData);
- void HandleSetRaidDifficultyOpcode(WorldPacket& recvData);
+ void HandleSetDungeonDifficultyOpcode(WorldPackets::Misc::SetDungeonDifficulty& setDungeonDifficulty);
+ void HandleSetRaidDifficultyOpcode(WorldPackets::Misc::SetRaidDifficulty& setRaidDifficulty);
void HandleMoveSetCanFlyAckOpcode(WorldPacket& recvData);
void HandleSetTitleOpcode(WorldPacket& recvData);
void HandleRealmSplitOpcode(WorldPacket& recvData);
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index b851db186dc..819942901cb 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -5274,7 +5274,7 @@ void AuraEffect::HandleAuraLinked(AuraApplication const* aurApp, uint8 mode, boo
if (!triggeredSpellInfo)
return;
- Unit* caster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, target->GetMap()->GetDifficulty()) ? GetCaster() : target;
+ Unit* caster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, target->GetMap()->GetDifficultyID()) ? GetCaster() : target;
if (!caster)
return;
@@ -5290,13 +5290,13 @@ void AuraEffect::HandleAuraLinked(AuraApplication const* aurApp, uint8 mode, boo
}
else
{
- ObjectGuid casterGUID = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, caster->GetMap()->GetDifficulty()) ? GetCasterGUID() : target->GetGUID();
+ ObjectGuid casterGUID = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, caster->GetMap()->GetDifficultyID()) ? GetCasterGUID() : target->GetGUID();
target->RemoveAura(triggeredSpellId, casterGUID, 0, aurApp->GetRemoveMode());
}
}
else if (mode & AURA_EFFECT_HANDLE_REAPPLY && apply)
{
- ObjectGuid casterGUID = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, caster->GetMap()->GetDifficulty()) ? GetCasterGUID() : target->GetGUID();
+ ObjectGuid casterGUID = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, caster->GetMap()->GetDifficultyID()) ? GetCasterGUID() : target->GetGUID();
// change the stack amount to be equal to stack amount of our aura
if (Aura* triggeredAura = target->GetAura(triggeredSpellId, casterGUID))
triggeredAura->ModStackAmount(GetBase()->GetStackAmount() - triggeredAura->GetStackAmount());
@@ -5848,7 +5848,7 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
if (triggeredSpellInfo)
{
- if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, target->GetMap()->GetDifficulty()) ? caster : target)
+ if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, target->GetMap()->GetDifficultyID()) ? caster : target)
{
triggerCaster->CastSpell(target, triggeredSpellInfo, true, NULL, this);
TC_LOG_DEBUG("spells", "AuraEffect::HandlePeriodicTriggerSpellAuraTick: Spell %u Trigger %u", GetId(), triggeredSpellInfo->Id);
@@ -5868,7 +5868,7 @@ void AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit*
uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId))
{
- if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, target->GetMap()->GetDifficulty()) ? caster : target)
+ if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, target->GetMap()->GetDifficultyID()) ? caster : target)
{
int32 basepoints = GetAmount();
triggerCaster->CastCustomSpell(target, triggerSpellId, &basepoints, &basepoints, &basepoints, true, nullptr, this);
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 435c5097604..28c2927bd8b 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -251,14 +251,14 @@ uint32 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 avalibl
{
case TYPEID_UNIT:
case TYPEID_PLAYER:
- for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(owner->GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(owner->GetMap()->GetDifficultyID()))
{
if (effect && effect->IsUnitOwnedAuraEffect())
effMask |= 1 << effect->EffectIndex;
}
break;
case TYPEID_DYNAMICOBJECT:
- for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(owner->GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(owner->GetMap()->GetDifficultyID()))
{
if (effect && effect->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA)
effMask |= 1 << effect->EffectIndex;
@@ -390,7 +390,7 @@ SpellEffectInfo const* Aura::GetSpellEffectInfo(uint32 index) const
void Aura::_InitEffects(uint32 effMask, Unit* caster, int32 *baseAmount)
{
// shouldn't be in constructor - functions in AuraEffect::AuraEffect use polymorphism
- _spelEffectInfos = m_spellInfo->GetEffectsForDifficulty(GetOwner()->GetMap()->GetDifficulty());
+ _spelEffectInfos = m_spellInfo->GetEffectsForDifficulty(GetOwner()->GetMap()->GetDifficultyID());
ASSERT(!_spelEffectInfos.empty());
@@ -1053,7 +1053,7 @@ bool Aura::CanBeSaved() const
bool Aura::CanBeSentToClient() const
{
- return !IsPassive() || GetSpellInfo()->HasAreaAuraEffect(GetOwner() ? GetOwner()->GetMap()->GetDifficulty() : DIFFICULTY_NONE) || HasEffectType(SPELL_AURA_ABILITY_IGNORE_AURASTATE) || HasEffectType(SPELL_AURA_CAST_WHILE_WALKING);
+ return !IsPassive() || GetSpellInfo()->HasAreaAuraEffect(GetOwner() ? GetOwner()->GetMap()->GetDifficultyID() : DIFFICULTY_NONE) || HasEffectType(SPELL_AURA_ABILITY_IGNORE_AURASTATE) || HasEffectType(SPELL_AURA_CAST_WHILE_WALKING);
}
bool Aura::IsSingleTargetWith(Aura const* aura) const
@@ -1661,7 +1661,7 @@ bool Aura::CanStackWith(Aura const* existingAura) const
// * The minimap tracking list will only show a check mark next to the last skill activated
// Sometimes this bugs out and doesn't switch the check mark. It has no effect on the actual tracking though.
// * The minimap dots are yellow for both resources
- if (m_spellInfo->HasAura(GetOwner()->GetMap()->GetDifficulty(), SPELL_AURA_TRACK_RESOURCES) && existingSpellInfo->HasAura(GetOwner()->GetMap()->GetDifficulty(), SPELL_AURA_TRACK_RESOURCES))
+ if (m_spellInfo->HasAura(GetOwner()->GetMap()->GetDifficultyID(), SPELL_AURA_TRACK_RESOURCES) && existingSpellInfo->HasAura(GetOwner()->GetMap()->GetDifficultyID(), SPELL_AURA_TRACK_RESOURCES))
return sWorld->getBoolConfig(CONFIG_ALLOW_TRACK_BOTH_RESOURCES);
// check spell specific stack rules
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index df1d8239b04..f2793cd0933 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -578,9 +578,9 @@ SpellValue::SpellValue(Difficulty diff, SpellInfo const* proto)
Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID, bool skipCheck) :
m_spellInfo(info), m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster),
-m_spellValue(new SpellValue(caster->GetMap()->GetDifficulty(), m_spellInfo)), m_preGeneratedPath(PathGenerator(m_caster))
+m_spellValue(new SpellValue(caster->GetMap()->GetDifficultyID(), m_spellInfo)), m_preGeneratedPath(PathGenerator(m_caster))
{
- _effects = info->GetEffectsForDifficulty(caster->GetMap()->GetDifficulty());
+ _effects = info->GetEffectsForDifficulty(caster->GetMap()->GetDifficultyID());
m_customError = SPELL_CUSTOM_ERROR_NONE;
m_skipCheck = skipCheck;
@@ -3818,7 +3818,7 @@ void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cas
case SPELL_FAILED_TOO_MANY_OF_ITEM:
{
uint32 item = 0;
- for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(caster->GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(caster->GetMap()->GetDifficultyID()))
if (effect->ItemType)
item = effect->ItemType;
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
@@ -5544,7 +5544,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if (map->IsDungeon())
{
uint32 mapId = m_caster->GetMap()->GetId();
- Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
+ Difficulty difficulty = m_caster->GetMap()->GetDifficultyID();
if (map->IsRaid())
if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
if (InstancePlayerBind* casterBind = m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
@@ -7484,7 +7484,7 @@ void Spell::PrepareTriggersExecutedOnHit()
SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
uint32 auraSpellIdx = (*i)->GetEffIndex();
// todo 6.x
- if (SpellEffectInfo const* auraEffect = auraSpellInfo->GetEffect(m_caster->GetMap()->GetDifficulty(), auraSpellIdx))
+ if (SpellEffectInfo const* auraEffect = auraSpellInfo->GetEffect(m_caster->GetMap()->GetDifficultyID(), auraSpellIdx))
{
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraEffect->TriggerSpell))
{
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 3817cfc9405..ceb16e30536 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -421,7 +421,7 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
{
// Consumption
case 28865:
- damage = (((InstanceMap*)m_caster->GetMap())->GetDifficulty() == DIFFICULTY_NONE ? 2750 : 4250);
+ damage = (((InstanceMap*)m_caster->GetMap())->GetDifficultyID() == DIFFICULTY_NONE ? 2750 : 4250);
break;
// percent from health with min
case 25599: // Thundercrash
@@ -747,13 +747,13 @@ void Spell::EffectTriggerSpell(SpellEffIndex /*effIndex*/)
SpellCastTargets targets;
if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH_TARGET)
{
- if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficulty()))
+ if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficultyID()))
return;
targets.SetUnitTarget(unitTarget);
}
else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
{
- if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficulty()) && (effectInfo->GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
+ if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficultyID()) && (effectInfo->GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
return;
if (spellInfo->GetExplicitTargetMask() & TARGET_FLAG_DEST_LOCATION)
@@ -802,13 +802,13 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex /*effIndex*/)
SpellCastTargets targets;
if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET)
{
- if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficulty()))
+ if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficultyID()))
return;
targets.SetUnitTarget(unitTarget);
}
else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
{
- if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficulty()) && (effectInfo->GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
+ if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficultyID()) && (effectInfo->GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
return;
if (spellInfo->GetExplicitTargetMask() & TARGET_FLAG_DEST_LOCATION)
@@ -2213,7 +2213,7 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
// The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
uint32 spellId = VEHICLE_SPELL_RIDE_HARDCODED;
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(effectInfo->CalcValue());
- if (spellInfo && spellInfo->HasAura(m_originalCaster->GetMap()->GetDifficulty(), SPELL_AURA_CONTROL_VEHICLE))
+ if (spellInfo && spellInfo->HasAura(m_originalCaster->GetMap()->GetDifficultyID(), SPELL_AURA_CONTROL_VEHICLE))
spellId = spellInfo->Id;
// Hard coded enter vehicle spell
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 9474abd6da1..1f6b5238137 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -1739,7 +1739,7 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
// aura limitations
if (player)
{
- for (SpellEffectInfo const* effect : GetEffectsForDifficulty(player->GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(player->GetMap()->GetDifficultyID()))
{
if (!effect || !effect->IsAura())
continue;
@@ -1910,7 +1910,7 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta
return SPELL_FAILED_TARGET_AURASTATE;
if (unitTarget->HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
- if (HasEffect(caster->GetMap()->GetDifficulty(), SPELL_EFFECT_SELF_RESURRECT) || HasEffect(caster->GetMap()->GetDifficulty(), SPELL_EFFECT_RESURRECT) || HasEffect(caster->GetMap()->GetDifficulty(), SPELL_EFFECT_RESURRECT_NEW))
+ if (HasEffect(caster->GetMap()->GetDifficultyID(), SPELL_EFFECT_SELF_RESURRECT) || HasEffect(caster->GetMap()->GetDifficultyID(), SPELL_EFFECT_RESURRECT) || HasEffect(caster->GetMap()->GetDifficultyID(), SPELL_EFFECT_RESURRECT_NEW))
return SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED;
return SPELL_CAST_OK;
@@ -1961,7 +1961,7 @@ SpellCastResult SpellInfo::CheckVehicle(Unit const* caster) const
if (vehicle)
{
uint16 checkMask = 0;
- for (SpellEffectInfo const* effect : GetEffectsForDifficulty(caster->GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(caster->GetMap()->GetDifficultyID()))
{
if (effect && effect->ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
{
@@ -1972,7 +1972,7 @@ SpellCastResult SpellInfo::CheckVehicle(Unit const* caster) const
}
}
- if (HasAura(caster->GetMap()->GetDifficulty(), SPELL_AURA_MOUNTED))
+ if (HasAura(caster->GetMap()->GetDifficultyID(), SPELL_AURA_MOUNTED))
checkMask |= VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL;
if (!checkMask)
@@ -1986,7 +1986,7 @@ SpellCastResult SpellInfo::CheckVehicle(Unit const* caster) const
// Can only summon uncontrolled minions/guardians when on controlled vehicle
if (vehicleSeat->Flags & (VEHICLE_SEAT_FLAG_CAN_CONTROL | VEHICLE_SEAT_FLAG_UNK2))
{
- for (SpellEffectInfo const* effect : GetEffectsForDifficulty(caster->GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(caster->GetMap()->GetDifficultyID()))
{
if (!effect || effect->Effect != SPELL_EFFECT_SUMMON)
continue;
@@ -3076,7 +3076,7 @@ SpellCooldownsEntry const* SpellInfo::GetSpellCooldowns() const
void SpellInfo::_UnloadImplicitTargetConditionLists()
{
// find the same instances of ConditionList and delete them.
- for (uint32 d = 0; d < DIFFICULTY_MAX; ++d)
+ for (uint32 d = 0; d < MAX_DIFFICULTY; ++d)
{
for (uint32 i = 0; i < _effects.size(); ++i)
{
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index f2a671fc968..7e60e11448d 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -574,7 +574,7 @@ public:
SpellEffectInfoVector GetEffectsForDifficulty(uint32 difficulty) const;
SpellEffectInfo const* GetEffect(uint32 difficulty, uint32 index) const;
SpellEffectInfo const* GetEffect(uint32 index) const { return GetEffect(DIFFICULTY_NONE, index); }
- SpellEffectInfo const* GetEffect(WorldObject* obj, uint32 index) const { return GetEffect(obj->GetMap()->GetDifficulty(), index); }
+ SpellEffectInfo const* GetEffect(WorldObject* obj, uint32 index) const { return GetEffect(obj->GetMap()->GetDifficultyID(), index); }
SpellEffectInfoMap _effects;
};
diff --git a/src/server/scripts/Commands/cs_instance.cpp b/src/server/scripts/Commands/cs_instance.cpp
index 78c8f970f52..26b68b7281b 100644
--- a/src/server/scripts/Commands/cs_instance.cpp
+++ b/src/server/scripts/Commands/cs_instance.cpp
@@ -84,7 +84,7 @@ public:
{
InstanceSave* save = itr->second.save;
std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
- handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_INFO, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
+ handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_INFO, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficultyID(), save->CanReset() ? "yes" : "no", timeleft.c_str());
counter++;
}
}
@@ -100,7 +100,7 @@ public:
{
InstanceSave* save = itr->second.save;
std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
- handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_INFO, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
+ handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_INFO, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficultyID(), save->CanReset() ? "yes" : "no", timeleft.c_str());
counter++;
}
}
@@ -140,10 +140,10 @@ public:
for (Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
{
InstanceSave* save = itr->second.save;
- if (itr->first != player->GetMapId() && (!MapId || MapId == itr->first) && (diff == -1 || diff == save->GetDifficulty()))
+ if (itr->first != player->GetMapId() && (!MapId || MapId == itr->first) && (diff == -1 || diff == save->GetDifficultyID()))
{
std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
- handler->PSendSysMessage(LANG_COMMAND_INST_UNBIND_UNBINDING, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
+ handler->PSendSysMessage(LANG_COMMAND_INST_UNBIND_UNBINDING, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficultyID(), save->CanReset() ? "yes" : "no", timeleft.c_str());
player->UnbindInstance(itr, Difficulty(i));
counter++;
}
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 164f53cf9c1..889b24480e6 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -369,7 +369,7 @@ public:
// if the player or the player's group is bound to another instance
// the player will not be bound to another one
- InstancePlayerBind* bind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty(map->IsRaid()));
+ InstancePlayerBind* bind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficultyID(map->GetEntry()));
if (!bind)
{
Group* group = _player->GetGroup();
@@ -381,9 +381,12 @@ public:
}
if (map->IsRaid())
- _player->SetRaidDifficulty(target->GetRaidDifficulty());
+ {
+ _player->SetRaidDifficultyID(target->GetRaidDifficultyID());
+ _player->SetLegacyRaidDifficultyID(target->GetLegacyRaidDifficultyID());
+ }
else
- _player->SetDungeonDifficulty(target->GetDungeonDifficulty());
+ _player->SetDungeonDifficultyID(target->GetDungeonDifficultyID());
}
handler->PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str());
@@ -496,7 +499,7 @@ public:
Map* destMap = target->GetMap();
if (destMap->Instanceable() && destMap->GetInstanceId() != map->GetInstanceId())
- target->UnbindInstance(map->GetInstanceId(), target->GetDungeonDifficulty(), true);
+ target->UnbindInstance(map->GetInstanceId(), target->GetDungeonDifficultyID(), true);
// we are in an instance, and can only summon players in our group with us as leader
if (!handler->GetSession()->GetPlayer()->GetGroup() || !target->GetGroup() ||
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp
index 8e1e74ebbfb..1aaafff45ce 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp
@@ -485,7 +485,7 @@ public:
void SpellHit(Unit* /*pAttacker*/, const SpellInfo* Spell) override
{
//We only care about interrupt effects and only if they are durring a spell currently being cast
- for (SpellEffectInfo const* effect : Spell->GetEffectsForDifficulty(me->GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : Spell->GetEffectsForDifficulty(me->GetMap()->GetDifficultyID()))
if (effect && effect->Effect == SPELL_EFFECT_INTERRUPT_CAST && me->IsNonMeleeSpellCast(false))
{
//Interrupt effect
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
index e37d7613aa6..7a5239b6c3e 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
@@ -78,7 +78,7 @@ enum Shadowmourne
SPELL_THIRST_QUENCHED = 72154,
};
-uint32 const vampireAuras[3][MAX_DIFFICULTY] =
+uint32 const vampireAuras[3][4] =
{
{70867, 71473, 71532, 71533},
{70879, 71525, 71530, 71531},
@@ -129,7 +129,7 @@ Position const mincharPos = {4629.3711f, 2782.6089f, 424.6390f, 0.000000f};
bool IsVampire(Unit const* unit)
{
for (uint8 i = 0; i < 3; ++i)
- if (unit->HasAura(vampireAuras[i][unit->GetMap()->GetSpawnMode()]))
+ if (unit->HasAura(vampireAuras[i][unit->GetMap()->GetSpawnMode() - DIFFICULTY_10_N]))
return true;
return false;
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
index 5f4953e538d..f050136e842 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
@@ -1088,7 +1088,7 @@ class spell_putricide_choking_gas_bomb : public SpellScriptLoader
void HandleScript(SpellEffIndex /*effIndex*/)
{
uint32 skipIndex = urand(0, 2);
- for (SpellEffectInfo const* effect : GetSpellInfo()->GetEffectsForDifficulty(GetCaster()->GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : GetSpellInfo()->GetEffectsForDifficulty(GetCaster()->GetMap()->GetDifficultyID()))
{
if (!effect || effect->EffectIndex == skipIndex)
continue;
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index 26683babf43..937e5d5bed2 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -1171,7 +1171,7 @@ class spell_sindragosa_frost_breath : public SpellScriptLoader
return;
// Check difficulty and quest status
- if (!(target->GetRaidDifficulty() & RAID_DIFFICULTY_MASK_25MAN) || target->GetQuestStatus(QUEST_FROST_INFUSION) != QUEST_STATUS_INCOMPLETE)
+ if (!target->GetMap()->Is25ManRaid() || target->GetQuestStatus(QUEST_FROST_INFUSION) != QUEST_STATUS_INCOMPLETE)
return;
// Check if player has Shadow's Edge equipped and not ready for infusion
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
index a70a4e163ce..abbc7acb004 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
@@ -1786,10 +1786,10 @@ class spell_malygos_arcane_storm : public SpellScriptLoader
{
// Resize list only to objects that are vehicles.
IsCreatureVehicleCheck check(true);
- Trinity::Containers::RandomResizeList(targets, check, (malygos->GetMap()->GetDifficulty() == DIFFICULTY_10_N ? 4 : 10));
+ Trinity::Containers::RandomResizeList(targets, check, (malygos->GetMap()->GetDifficultyID() == DIFFICULTY_10_N ? 4 : 10));
}
else
- Trinity::Containers::RandomResizeList(targets, (malygos->GetMap()->GetDifficulty() == DIFFICULTY_10_N ? 4 : 10));
+ Trinity::Containers::RandomResizeList(targets, (malygos->GetMap()->GetDifficultyID() == DIFFICULTY_10_N ? 4 : 10));
}
void HandleVisual(SpellEffIndex /*effIndex*/)
@@ -2475,9 +2475,9 @@ class spell_alexstrasza_gift_beam_visual : public SpellScriptLoader
{
if (Creature* target = GetTarget()->ToCreature())
{
- if (target->GetMap()->GetDifficulty() == DIFFICULTY_10_N)
+ if (target->GetMap()->GetDifficultyID() == DIFFICULTY_10_N)
_alexstraszaGift = target->SummonGameObject(GO_ALEXSTRASZA_S_GIFT_10, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0);
- else if (target->GetMap()->GetDifficulty() == DIFFICULTY_25_N)
+ else if (target->GetMap()->GetDifficultyID() == DIFFICULTY_25_N)
_alexstraszaGift = target->SummonGameObject(GO_ALEXSTRASZA_S_GIFT_25, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0);
}
}
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp
index 122db0512cc..46fb538d576 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp
@@ -92,14 +92,14 @@ public:
platformGUID = go->GetGUID();
break;
case GO_FOCUSING_IRIS_10:
- if (instance->GetDifficulty() == DIFFICULTY_10_N)
+ if (instance->GetDifficultyID() == DIFFICULTY_10_N)
{
irisGUID = go->GetGUID();
focusingIrisPosition = go->GetPosition();
}
break;
case GO_FOCUSING_IRIS_25:
- if (instance->GetDifficulty() == DIFFICULTY_25_N)
+ if (instance->GetDifficultyID() == DIFFICULTY_25_N)
{
irisGUID = go->GetGUID();
focusingIrisPosition = go->GetPosition();
@@ -110,11 +110,11 @@ public:
exitPortalPosition = go->GetPosition();
break;
case GO_HEART_OF_MAGIC_10:
- if (instance->GetDifficulty() == DIFFICULTY_10_N)
+ if (instance->GetDifficultyID() == DIFFICULTY_10_N)
heartOfMagicGUID = go->GetGUID();
break;
case GO_HEART_OF_MAGIC_25:
- if (instance->GetDifficulty() == DIFFICULTY_25_N)
+ if (instance->GetDifficultyID() == DIFFICULTY_25_N)
heartOfMagicGUID = go->GetGUID();
break;
}
@@ -240,7 +240,7 @@ public:
PowerSparksHandling();
break;
case DATA_RESPAWN_IRIS:
- SpawnGameObject(instance->GetDifficulty() == DIFFICULTY_10_N ? GO_FOCUSING_IRIS_10 : GO_FOCUSING_IRIS_25, focusingIrisPosition);
+ SpawnGameObject(instance->GetDifficultyID() == DIFFICULTY_10_N ? GO_FOCUSING_IRIS_10 : GO_FOCUSING_IRIS_25, focusingIrisPosition);
break;
}
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
index 063271b2d8e..5f5c944ee6c 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
@@ -598,7 +598,7 @@ class boss_freya : public CreatureScript
/* 25N */ {62952, 62954, 62956, 62958}
};
- me->CastSpell((Unit*)NULL, summonSpell[me->GetMap()->GetDifficulty()][elderCount], true);
+ me->CastSpell((Unit*)NULL, summonSpell[me->GetMap()->GetDifficultyID() - DIFFICULTY_10_N][elderCount], true);
Talk(SAY_DEATH);
me->SetReactState(REACT_PASSIVE);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
index 40aa05fd6a9..01c25cbebaf 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
@@ -452,7 +452,7 @@ class spell_ulduar_cancel_stone_grip : public SpellScriptLoader
if (!target || !target->GetVehicle())
return;
- switch (target->GetMap()->GetDifficulty())
+ switch (target->GetMap()->GetDifficultyID())
{
case DIFFICULTY_10_N:
target->RemoveAura(GetSpellInfo()->GetEffect(EFFECT_0)->CalcValue());
@@ -534,7 +534,7 @@ class spell_ulduar_stone_grip_absorb : public SpellScriptLoader
if (!GetOwner()->ToCreature())
return;
- uint32 rubbleStalkerEntry = (GetOwner()->GetMap()->GetDifficulty() == DIFFICULTY_NORMAL ? 33809 : 33942);
+ uint32 rubbleStalkerEntry = (GetOwner()->GetMap()->GetDifficultyID() == DIFFICULTY_NORMAL ? 33809 : 33942);
Creature* rubbleStalker = GetOwner()->FindNearestCreature(rubbleStalkerEntry, 200.0f, true);
if (rubbleStalker)
rubbleStalker->CastSpell(rubbleStalker, SPELL_STONE_GRIP_CANCEL, true);
diff --git a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
index ddea2ac4edc..3437dbbba8a 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
@@ -572,7 +572,7 @@ public:
void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override
{
if (me->GetCurrentSpell(CURRENT_GENERIC_SPELL))
- for (SpellEffectInfo const* effect : spell->GetEffectsForDifficulty(me->GetMap()->GetDifficulty()))
+ for (SpellEffectInfo const* effect : spell->GetEffectsForDifficulty(me->GetMap()->GetDifficultyID()))
if (effect->Effect == SPELL_EFFECT_INTERRUPT_CAST)
if (me->GetCurrentSpell(CURRENT_GENERIC_SPELL)->m_spellInfo->Id == SPELL_SOUL_SHOCK
|| me->GetCurrentSpell(CURRENT_GENERIC_SPELL)->m_spellInfo->Id == SPELL_DEADEN)
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index 1ca0e586200..5e914391bd9 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -72,9 +72,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHARACTER, "SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, "
"position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, "
- "resettalents_time, talentTree, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, "
+ "resettalents_time, talentTree, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeonDifficulty, "
"totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, "
- "health, power1, power2, power3, power4, power5, instance_id, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels "
+ "health, power1, power2, power3, power4, power5, instance_id, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels, raidDifficulty, legacyRaidDifficulty "
"FROM characters WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH);
@@ -369,16 +369,16 @@ void CharacterDatabaseConnection::DoPrepareStatements()
// Player saving
PrepareStatement(CHAR_INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, "
- "map, instance_id, instance_mode_mask, position_x, position_y, position_z, orientation, trans_x, trans_y, trans_z, trans_o, transguid, "
+ "map, instance_id, dungeonDifficulty, raidDifficulty, legacyRaidDifficulty, position_x, position_y, position_z, orientation, trans_x, trans_y, trans_z, trans_o, transguid, "
"taximask, cinematic, "
"totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, talentTree, "
"extra_flags, stable_slots, at_login, zone, "
"death_expire_time, taxi_path, totalKills, "
"todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, health, power1, power2, power3, "
"power4, power5, latency, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels) VALUES "
- "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC);
+ "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,playerBytes=?,playerBytes2=?,playerFlags=?,"
- "map=?,instance_id=?,instance_mode_mask=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?,"
+ "map=?,instance_id=?,dungeonDifficulty=?,raidDifficulty=?,legacyRaidDifficulty=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?,"
"logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,talentTree=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?,"
"totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?,"
"watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,latency=?,talentGroupsCount=?,activeTalentGroup=?,exploredZones=?,"
@@ -391,7 +391,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_PETITION_NAME, "UPDATE petition SET name = ? WHERE petitionguid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_PETITION_SIGNATURE, "INSERT INTO petition_sign (ownerguid, petitionguid, playerguid, player_account) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_ACCOUNT_ONLINE, "UPDATE characters SET online = 0 WHERE account = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_INS_GROUP, "INSERT INTO groups (guid, leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raiddifficulty, masterLooterGuid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_GROUP, "INSERT INTO groups (guid, leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raidDifficulty, legacyRaidDifficulty, masterLooterGuid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_GROUP_MEMBER, "INSERT INTO group_member (guid, memberGuid, memberFlags, subgroup, roles) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GROUP_MEMBER, "DELETE FROM group_member WHERE memberGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING, "DELETE FROM group_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC);
@@ -400,7 +400,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_GROUP_MEMBER_SUBGROUP, "UPDATE group_member SET subgroup = ? WHERE memberGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_GROUP_MEMBER_FLAG, "UPDATE group_member SET memberFlags = ? WHERE memberGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_GROUP_DIFFICULTY, "UPDATE groups SET difficulty = ? WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UPD_GROUP_RAID_DIFFICULTY, "UPDATE groups SET raiddifficulty = ? WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_GROUP_RAID_DIFFICULTY, "UPDATE groups SET raidDifficulty = ? WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_GROUP_LEGACY_RAID_DIFFICULTY, "UPDATE groups SET legacyRaidDifficulty = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_ALL_GM_TICKETS, "TRUNCATE TABLE gm_tickets", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_INVALID_SPELL_TALENTS, "DELETE FROM character_talent WHERE spell = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_INVALID_SPELL_SPELLS, "DELETE FROM character_spell WHERE spell = ?", CONNECTION_ASYNC);
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index a1a93ab1119..81665743c8a 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -334,6 +334,7 @@ enum CharacterDatabaseStatements
CHAR_UPD_GROUP_MEMBER_FLAG,
CHAR_UPD_GROUP_DIFFICULTY,
CHAR_UPD_GROUP_RAID_DIFFICULTY,
+ CHAR_UPD_GROUP_LEGACY_RAID_DIFFICULTY,
CHAR_DEL_INVALID_SPELL_SPELLS,
CHAR_DEL_INVALID_SPELL_TALENTS,
CHAR_UPD_DELETE_INFO,