Core/DataStores: Refactor MapDifficulty storage to get rid of map of maps

This commit is contained in:
Shauren
2026-07-30 21:18:14 +02:00
parent d58f783588
commit 7cd0e081b7
6 changed files with 60 additions and 62 deletions
+4 -2
View File
@@ -376,8 +376,10 @@ bool IsDisabledFor(DisableType type, uint32 entry, WorldObject const* ref, uint8
uint8 disabledModes = itr->second.flags;
Group const* group = player->GetGroup();
Difficulty targetDifficulty = group ? group->GetDifficultyID(mapEntry) : player->GetDifficultyID(mapEntry);
sDB2Manager.GetDownscaledMapDifficultyData(entry, targetDifficulty);
switch (targetDifficulty)
MapDifficultyEntry const* mapDifficulty = sDB2Manager.GetDownscaledMapDifficultyData(entry, targetDifficulty);
if (!mapDifficulty)
return false;
switch (Difficulty(mapDifficulty->DifficultyID))
{
case DIFFICULTY_NORMAL:
return (disabledModes & DUNGEON_STATUSFLAG_NORMAL) != 0;
+50 -51
View File
@@ -434,7 +434,7 @@ typedef std::array<ItemClassEntry const*, 21> ItemClassByOldEnumContainer;
typedef std::unordered_map<uint32, std::vector<ItemLimitCategoryConditionEntry const*>> ItemLimitCategoryConditionContainer;
typedef std::unordered_map<uint32, std::vector<ItemSetSpellEntry const*>> ItemSetSpellContainer;
typedef std::unordered_map<uint32, std::vector<ItemSpecOverrideEntry const*>> ItemSpecOverridesContainer;
typedef std::unordered_map<uint32, std::unordered_map<uint32, MapDifficultyEntry const*>> MapDifficultyContainer;
typedef std::vector<MapDifficultyEntry const*> MapDifficultyContainer;
typedef std::unordered_map<uint32, DB2Manager::MountTypeXCapabilitySet> MountCapabilitiesByTypeContainer;
typedef std::unordered_map<uint32, DB2Manager::MountXDisplayContainer> MountDisplaysCointainer;
typedef std::unordered_map<uint32, std::array<std::vector<NameGenEntry const*>, 2>> NameGenContainer;
@@ -1382,8 +1382,11 @@ void DB2Manager::IndexLoadedStores()
_journalTiersByIndex.push_back(journalTier);
for (MapDifficultyEntry const* entry : sMapDifficultyStore)
if (sMapStore.HasRecord(entry->MapID))
_mapDifficulties[entry->MapID][entry->DifficultyID] = entry;
if (sMapStore.HasRecord(entry->MapID) && (!entry->DifficultyID || sDifficultyStore.HasRecord(entry->DifficultyID)))
_mapDifficulties.push_back(entry);
std::ranges::sort(_mapDifficulties, std::ranges::less(),
[](MapDifficultyEntry const* entry) { return std::pair(entry->MapID, entry->DifficultyID); });
std::vector<MapDifficultyXConditionEntry const*> mapDifficultyConditions;
mapDifficultyConditions.reserve(sMapDifficultyXConditionStore.GetNumRows());
@@ -2706,72 +2709,68 @@ uint32 DB2Manager::GetLiquidFlags(uint32 liquidType)
return 0;
}
MapDifficultyEntry const* DB2Manager::GetDefaultMapDifficulty(uint32 mapId, Difficulty* difficulty /*= nullptr*/) const
MapDifficultyEntry const* DB2Manager::GetDefaultMapDifficulty(uint32 mapId) const
{
std::unordered_map<uint32, MapDifficultyEntry const*>* difficultiesForMap = Trinity::Containers::MapGetValuePtr(_mapDifficulties, mapId);
if (!difficultiesForMap)
return nullptr;
auto difficultyEnd = difficultiesForMap->end();
// first find any valid difficulty
auto foundDifficulty = std::ranges::find_if(difficultiesForMap->begin(), difficultyEnd,
[](uint32 difficultyId) { return sDifficultyStore.HasRecord(difficultyId); },
Trinity::Containers::MapKey);
if (foundDifficulty == difficultyEnd)
return nullptr; // nothing valid was found
if (!(sDifficultyStore.AssertEntry(foundDifficulty->first)->Flags & DIFFICULTY_FLAG_DEFAULT))
auto difficultyBegin = std::ranges::lower_bound(_mapDifficulties, mapId, std::ranges::less(), &MapDifficultyEntry::MapID);
struct
{
// first valid difficulty wasn't default, try finding one
auto defaultDifficulty = std::ranges::find_if(foundDifficulty, difficultyEnd,
[](DifficultyEntry const* difficultyEntry) { return difficultyEntry && (difficultyEntry->Flags & DIFFICULTY_FLAG_DEFAULT) != 0; },
[](std::pair<uint32 const, MapDifficultyEntry const*> const& p) { return sDifficultyStore.LookupEntry(p.first); });
bool operator==(MapDifficultyContainer::const_iterator const& itr) const { return itr == end || (*itr)->MapID != mapId; }
MapDifficultyContainer::const_iterator end = _mapDifficulties.end();
uint32 mapId;
} difficultyEnd { .mapId = mapId };
if (defaultDifficulty != difficultyEnd)
foundDifficulty = defaultDifficulty; // got a default
MapDifficultyEntry const* defaultDifficulty = nullptr;
while (difficultyBegin != difficultyEnd)
{
if (DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry((*difficultyBegin)->DifficultyID))
{
// if a default difficulty exists then use that
if (difficultyEntry->Flags & DIFFICULTY_FLAG_DEFAULT)
{
defaultDifficulty = *difficultyBegin;
break;
}
// otherwise pick first existing difficulty
if (!defaultDifficulty)
defaultDifficulty = *difficultyBegin;
}
++difficultyBegin;
}
if (difficulty)
*difficulty = Difficulty(foundDifficulty->first);
// if no difficulty waa found in Difficulty.db2 then we should only have DIFFICULTY_NONE
return foundDifficulty->second;
return defaultDifficulty;
}
MapDifficultyEntry const* DB2Manager::GetMapDifficultyData(uint32 mapId, Difficulty difficulty) const
{
auto itr = _mapDifficulties.find(mapId);
if (itr == _mapDifficulties.end())
return nullptr;
auto itr = std::ranges::lower_bound(_mapDifficulties, std::pair(mapId, difficulty) , std::ranges::less(),
[](MapDifficultyEntry const* mapDifficulty) { return std::pair(mapDifficulty->MapID, Difficulty(mapDifficulty->DifficultyID)); });
auto diffItr = itr->second.find(difficulty);
if (diffItr == itr->second.end())
return nullptr;
if (itr != _mapDifficulties.end() && (*itr)->MapID == mapId && (*itr)->DifficultyID == difficulty)
return *itr;
return diffItr->second;
return nullptr;
}
MapDifficultyEntry const* DB2Manager::GetDownscaledMapDifficultyData(uint32 mapId, Difficulty& difficulty) const
MapDifficultyEntry const* DB2Manager::GetDownscaledMapDifficultyData(uint32 mapId, Difficulty difficulty) const
{
DifficultyEntry const* diffEntry = sDifficultyStore.LookupEntry(difficulty);
if (!diffEntry)
return GetDefaultMapDifficulty(mapId, &difficulty);
uint32 tmpDiff = difficulty;
MapDifficultyEntry const* mapDiff = GetMapDifficultyData(mapId, Difficulty(tmpDiff));
while (!mapDiff)
MapDifficultyEntry const* mapDiff = nullptr;
Difficulty currentDifficulty = difficulty;
do
{
tmpDiff = diffEntry->FallbackDifficultyID;
diffEntry = sDifficultyStore.LookupEntry(tmpDiff);
if (!diffEntry)
return GetDefaultMapDifficulty(mapId, &difficulty);
mapDiff = GetMapDifficultyData(mapId, currentDifficulty);
DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(currentDifficulty);
if (!currentDifficulty)
break;
// pull new data
mapDiff = GetMapDifficultyData(mapId, Difficulty(tmpDiff)); // we are 10 normal or 25 normal
}
currentDifficulty = Difficulty(difficultyEntry->FallbackDifficultyID);
} while (!mapDiff);
if (!mapDiff)
mapDiff = GetDefaultMapDifficulty(mapId);
difficulty = Difficulty(tmpDiff);
return mapDiff;
}
+2 -2
View File
@@ -522,9 +522,9 @@ public:
static LFGDungeonsEntry const* GetLfgDungeon(uint32 mapId, Difficulty difficulty);
static uint32 GetDefaultMapLight(uint32 mapId);
static uint32 GetLiquidFlags(uint32 liquidType);
MapDifficultyEntry const* GetDefaultMapDifficulty(uint32 mapId, Difficulty* difficulty = nullptr) const;
MapDifficultyEntry const* GetDefaultMapDifficulty(uint32 mapId) const;
MapDifficultyEntry const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty) const;
MapDifficultyEntry const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &difficulty) const;
MapDifficultyEntry const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty difficulty) const;
MapDifficultyConditionsContainer const* GetMapDifficultyConditions(uint32 mapDifficultyId) const;
MountEntry const* GetMount(uint32 spellId) const;
MountEntry const* GetMountById(uint32 id) const;
+1 -1
View File
@@ -20124,7 +20124,7 @@ bool Player::Satisfy(AccessRequirement const* ar, uint32 target_map, TransferAbo
if (params)
{
params->Reason = TRANSFER_ABORT_DIFFICULTY;
params->Arg = target_difficulty;
params->Arg = mapDiff->DifficultyID;
params->MapDifficultyXConditionId = failedMapDifficultyXCondition;
}
}
+1 -1
View File
@@ -1827,7 +1827,7 @@ TransferAbortParams Map::PlayerCannotEnter(uint32 mapid, Player* player)
//Other requirements
{
TransferAbortParams params(TRANSFER_ABORT_NONE);
if (!player->Satisfy(sObjectMgr->GetAccessRequirement(mapid, targetDifficulty), mapid, &params, true))
if (!player->Satisfy(sObjectMgr->GetAccessRequirement(mapid, Difficulty(mapDiff->DifficultyID)), mapid, &params, true))
return params;
}
+2 -5
View File
@@ -99,9 +99,6 @@ InstanceMap* MapManager::CreateInstance(uint32 mapId, uint32 instanceId, Instanc
ABORT();
}
// some instances only have one difficulty
sDB2Manager.GetDownscaledMapDifficultyData(mapId, difficulty);
TC_LOG_DEBUG("maps", "MapInstanced::CreateInstance: {}map instance {} for {} created with difficulty {}",
instanceLock && instanceLock->IsNew() ? "" : "new ", instanceId, mapId, DB2Manager::GetDifficultyName(difficulty));
@@ -201,7 +198,7 @@ Map* MapManager::CreateMap(uint32 mapId, Player* player, Optional<uint32> lfgDun
// Reset difficulty to the one used in instance lock
if (!entries.Map->IsFlexLocking())
difficulty = instanceLock->GetDifficultyId();
entries.MapDifficulty = sDB2Manager.GetDownscaledMapDifficultyData(mapId, instanceLock->GetDifficultyId());
}
else
{
@@ -229,7 +226,7 @@ Map* MapManager::CreateMap(uint32 mapId, Player* player, Optional<uint32> lfgDun
if (!map)
{
map = CreateInstance(mapId, newInstanceId, instanceLock, difficulty, GetTeamIdForTeam(sCharacterCache->GetCharacterTeamByGuid(instanceOwnerGuid)), group,
map = CreateInstance(mapId, newInstanceId, instanceLock, Difficulty(entries.MapDifficulty->DifficultyID), GetTeamIdForTeam(sCharacterCache->GetCharacterTeamByGuid(instanceOwnerGuid)), group,
lfgDungeonsId);
if (group)
group->SetRecentInstance(mapId, instanceOwnerGuid, newInstanceId);