aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2015-01-10 01:35:47 +0100
committerShauren <shauren.trinity@gmail.com>2015-01-10 01:35:47 +0100
commitfaa583c7843af37d757bd46ca0bd226175dabc38 (patch)
tree5af657d84903b337bdb22c341bb01f4e6aab1392 /src/server/game
parentf6b30fdf616bd289dd668f98a0aed8dbfb14eba8 (diff)
Core/Maps: Updated map difficulties
Diffstat (limited to 'src/server/game')
-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
53 files changed, 730 insertions, 422 deletions
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;
};