diff options
| author | Shauren <shauren.trinity@gmail.com> | 2021-01-02 17:55:43 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2021-01-02 17:55:43 +0100 |
| commit | 3afed1788a81fe65ee414c590936be65d69f9314 (patch) | |
| tree | 48835f2416cb9e54301daa758adb3ef3c8b906db /src | |
| parent | a68bc20b242650fb8f8c448dc02f5287bf3b3631 (diff) | |
Core/Instances: Use level requirements from MapDifficultyXCondition.db2 instead of access_requirement db table
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/database/Database/Implementation/HotfixDatabase.cpp | 7 | ||||
| -rw-r--r-- | src/server/database/Database/Implementation/HotfixDatabase.h | 4 | ||||
| -rw-r--r-- | src/server/game/DataStores/DB2LoadInfo.h | 17 | ||||
| -rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 22 | ||||
| -rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 2 | ||||
| -rw-r--r-- | src/server/game/DataStores/DB2Structure.h | 9 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 94 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.h | 2 |
8 files changed, 119 insertions, 38 deletions
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp index 89cb1191e4c..e181cef4a6b 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.cpp +++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp @@ -934,6 +934,13 @@ void HotfixDatabaseConnection::DoPrepareStatements() PREPARE_MAX_ID_STMT(HOTFIX_SEL_MAP_DIFFICULTY, "SELECT MAX(ID) + 1 FROM map_difficulty", CONNECTION_SYNCH); PREPARE_LOCALE_STMT(HOTFIX_SEL_MAP_DIFFICULTY, "SELECT ID, Message_lang FROM map_difficulty_locale WHERE (`VerifiedBuild` > 0) = ? AND locale = ?", CONNECTION_SYNCH); + // MapDifficultyXCondition.db2 + PrepareStatement(HOTFIX_SEL_MAP_DIFFICULTY_X_CONDITION, "SELECT ID, FailureDescription, PlayerConditionID, OrderIndex, MapDifficultyID" + " FROM map_difficulty_x_condition WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); + PREPARE_MAX_ID_STMT(HOTFIX_SEL_MAP_DIFFICULTY_X_CONDITION, "SELECT MAX(ID) + 1 FROM map_difficulty_x_condition", CONNECTION_SYNCH); + PREPARE_LOCALE_STMT(HOTFIX_SEL_MAP_DIFFICULTY_X_CONDITION, "SELECT ID, FailureDescription_lang FROM map_difficulty_x_condition_locale" + " WHERE (`VerifiedBuild` > 0) = ? AND locale = ?", CONNECTION_SYNCH); + // ModifierTree.db2 PrepareStatement(HOTFIX_SEL_MODIFIER_TREE, "SELECT ID, Parent, Operator, Amount, Type, Asset, SecondaryAsset, TertiaryAsset FROM modifier_tree" " WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h index 820b11720f5..d1b18a3ec5f 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.h +++ b/src/server/database/Database/Implementation/HotfixDatabase.h @@ -539,6 +539,10 @@ enum HotfixDatabaseStatements : uint32 HOTFIX_SEL_MAP_DIFFICULTY_MAX_ID, HOTFIX_SEL_MAP_DIFFICULTY_LOCALE, + HOTFIX_SEL_MAP_DIFFICULTY_X_CONDITION, + HOTFIX_SEL_MAP_DIFFICULTY_X_CONDITION_MAX_ID, + HOTFIX_SEL_MAP_DIFFICULTY_X_CONDITION_LOCALE, + HOTFIX_SEL_MODIFIER_TREE, HOTFIX_SEL_MODIFIER_TREE_MAX_ID, diff --git a/src/server/game/DataStores/DB2LoadInfo.h b/src/server/game/DataStores/DB2LoadInfo.h index d50b7548174..4316faff9f4 100644 --- a/src/server/game/DataStores/DB2LoadInfo.h +++ b/src/server/game/DataStores/DB2LoadInfo.h @@ -3561,6 +3561,23 @@ struct MapDifficultyLoadInfo } }; +struct MapDifficultyXConditionLoadInfo +{ + static DB2LoadInfo const* Instance() + { + static DB2FieldMeta const fields[] = + { + { false, FT_INT, "ID" }, + { false, FT_STRING, "FailureDescription" }, + { false, FT_INT, "PlayerConditionID" }, + { true, FT_INT, "OrderIndex" }, + { false, FT_INT, "MapDifficultyID" }, + }; + static DB2LoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, MapDifficultyXConditionMeta::Instance(), HOTFIX_SEL_MAP_DIFFICULTY_X_CONDITION); + return &loadInfo; + } +}; + struct ModifierTreeLoadInfo { static DB2LoadInfo const* Instance() diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index 72b2967f832..602bc2a1718 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -196,6 +196,7 @@ DB2Storage<LockEntry> sLockStore("Lock.db2", LockLoadI DB2Storage<MailTemplateEntry> sMailTemplateStore("MailTemplate.db2", MailTemplateLoadInfo::Instance()); DB2Storage<MapEntry> sMapStore("Map.db2", MapLoadInfo::Instance()); DB2Storage<MapDifficultyEntry> sMapDifficultyStore("MapDifficulty.db2", MapDifficultyLoadInfo::Instance()); +DB2Storage<MapDifficultyXConditionEntry> sMapDifficultyXConditionStore("MapDifficultyXCondition.db2", MapDifficultyXConditionLoadInfo::Instance()); DB2Storage<ModifierTreeEntry> sModifierTreeStore("ModifierTree.db2", ModifierTreeLoadInfo::Instance()); DB2Storage<MountCapabilityEntry> sMountCapabilityStore("MountCapability.db2", MountCapabilityLoadInfo::Instance()); DB2Storage<MountEntry> sMountStore("Mount.db2", MountLoadInfo::Instance()); @@ -418,6 +419,7 @@ namespace ItemSetSpellContainer _itemSetSpells; ItemSpecOverridesContainer _itemSpecOverrides; DB2Manager::MapDifficultyContainer _mapDifficulties; + std::unordered_map<uint32, DB2Manager::MapDifficultyConditionsContainer> _mapDifficultyConditions; std::unordered_map<uint32, MountEntry const*> _mountsBySpellId; MountCapabilitiesByTypeContainer _mountCapabilitiesByType; MountDisplaysCointainer _mountDisplays; @@ -725,6 +727,7 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul LOAD_DB2(sMailTemplateStore); LOAD_DB2(sMapStore); LOAD_DB2(sMapDifficultyStore); + LOAD_DB2(sMapDifficultyXConditionStore); LOAD_DB2(sModifierTreeStore); LOAD_DB2(sMountCapabilityStore); LOAD_DB2(sMountStore); @@ -1125,6 +1128,20 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul _mapDifficulties[entry->MapID][entry->DifficultyID] = entry; _mapDifficulties[0][0] = _mapDifficulties[1][0]; // map 0 is missing from MapDifficulty.dbc so we cheat a bit + std::vector<MapDifficultyXConditionEntry const*> mapDifficultyConditions; + mapDifficultyConditions.reserve(sMapDifficultyXConditionStore.GetNumRows()); + for (MapDifficultyXConditionEntry const* mapDifficultyCondition : sMapDifficultyXConditionStore) + mapDifficultyConditions.push_back(mapDifficultyCondition); + + std::sort(mapDifficultyConditions.begin(), mapDifficultyConditions.end(), [](MapDifficultyXConditionEntry const* left, MapDifficultyXConditionEntry const* right) + { + return left->OrderIndex < right->OrderIndex; + }); + + for (MapDifficultyXConditionEntry const* mapDifficultyCondition : mapDifficultyConditions) + if (PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(mapDifficultyCondition->PlayerConditionID)) + _mapDifficultyConditions[mapDifficultyCondition->MapDifficultyID].emplace_back(mapDifficultyCondition->ID, playerCondition); + for (MountEntry const* mount : sMountStore) _mountsBySpellId[mount->SourceSpellID] = mount; @@ -2557,6 +2574,11 @@ MapDifficultyEntry const* DB2Manager::GetDownscaledMapDifficultyData(uint32 mapI return mapDiff; } +DB2Manager::MapDifficultyConditionsContainer const* DB2Manager::GetMapDifficultyConditions(uint32 mapDifficultyId) const +{ + return Trinity::Containers::MapGetValuePtr(_mapDifficultyConditions, mapDifficultyId); +} + MountEntry const* DB2Manager::GetMount(uint32 spellId) const { auto itr = _mountsBySpellId.find(spellId); diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index 69acbe8ef2a..0cb82d7ff70 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -297,6 +297,7 @@ public: using ItemBonusList = std::vector<ItemBonusEntry const*>; using MapDifficultyContainer = std::unordered_map<uint32, std::unordered_map<uint32, MapDifficultyEntry const*>>; + using MapDifficultyConditionsContainer = std::vector<std::pair<uint32, PlayerConditionEntry const*>>; using MountTypeXCapabilitySet = std::set<MountTypeXCapabilityEntry const*, MountTypeXCapabilityEntryComparator>; using MountXDisplayContainer = std::vector<MountXDisplayEntry const*>; @@ -364,6 +365,7 @@ public: MapDifficultyEntry const* GetDefaultMapDifficulty(uint32 mapId, Difficulty* difficulty = nullptr) const; MapDifficultyEntry const* GetMapDifficultyData(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; MountTypeXCapabilitySet const* GetMountCapabilities(uint32 mountType) const; diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index d533ef062c4..a7c4e2fbd37 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -2223,6 +2223,15 @@ struct MapDifficultyEntry } }; +struct MapDifficultyXConditionEntry +{ + uint32 ID; + LocalizedString FailureDescription; + uint32 PlayerConditionID; + int32 OrderIndex; + uint32 MapDifficultyID; +}; + struct ModifierTreeEntry { uint32 ID; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 858aa6dceab..b6242939522 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -20169,65 +20169,84 @@ void Player::SendRaidInfo() bool Player::Satisfy(AccessRequirement const* ar, uint32 target_map, bool report) { - if (!IsGameMaster() && ar) + if (!IsGameMaster()) { uint8 LevelMin = 0; uint8 LevelMax = 0; + int32 failedMapDifficultyXCondition = 0; + uint32 missingItem = 0; + uint32 missingQuest = 0; + uint32 missingAchievement = 0; MapEntry const* mapEntry = sMapStore.LookupEntry(target_map); if (!mapEntry) return false; + Difficulty target_difficulty = GetDifficultyID(mapEntry); + MapDifficultyEntry const* mapDiff = sDB2Manager.GetDownscaledMapDifficultyData(target_map, target_difficulty); if (!sWorld->getBoolConfig(CONFIG_INSTANCE_IGNORE_LEVEL)) { - if (ar->levelMin && getLevel() < ar->levelMin) - LevelMin = ar->levelMin; - if (ar->levelMax && getLevel() > ar->levelMax) - LevelMax = ar->levelMax; + if (DB2Manager::MapDifficultyConditionsContainer const* mapDifficultyConditions = sDB2Manager.GetMapDifficultyConditions(mapDiff->ID)) + { + for (auto&& itr : *mapDifficultyConditions) + { + if (!ConditionMgr::IsPlayerMeetingCondition(this, itr.second)) + { + failedMapDifficultyXCondition = itr.first; + break; + } + } + } } - uint32 missingItem = 0; - if (ar->item) + if (ar) { - if (!HasItemCount(ar->item) && - (!ar->item2 || !HasItemCount(ar->item2))) - missingItem = ar->item; - } - else if (ar->item2 && !HasItemCount(ar->item2)) - missingItem = ar->item2; + if (!sWorld->getBoolConfig(CONFIG_INSTANCE_IGNORE_LEVEL)) + { + if (ar->levelMin && getLevel() < ar->levelMin) + LevelMin = ar->levelMin; + if (ar->levelMax && getLevel() > ar->levelMax) + LevelMax = ar->levelMax; + } - if (DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, target_map, this)) - { - GetSession()->SendNotification("%s", GetSession()->GetTrinityString(LANG_INSTANCE_CLOSED)); - return false; - } + if (ar->item) + { + if (!HasItemCount(ar->item) && + (!ar->item2 || !HasItemCount(ar->item2))) + missingItem = ar->item; + } + else if (ar->item2 && !HasItemCount(ar->item2)) + missingItem = ar->item2; - uint32 missingQuest = 0; - if (GetTeam() == ALLIANCE && ar->quest_A && !GetQuestRewardStatus(ar->quest_A)) - missingQuest = ar->quest_A; - else if (GetTeam() == HORDE && ar->quest_H && !GetQuestRewardStatus(ar->quest_H)) - missingQuest = ar->quest_H; + if (DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, target_map, this)) + { + GetSession()->SendNotification("%s", GetSession()->GetTrinityString(LANG_INSTANCE_CLOSED)); + return false; + } - uint32 missingAchievement = 0; - Player* leader = this; - ObjectGuid leaderGuid = GetGroup() ? GetGroup()->GetLeaderGUID() : GetGUID(); - if (leaderGuid != GetGUID()) - leader = ObjectAccessor::FindPlayer(leaderGuid); + if (GetTeam() == ALLIANCE && ar->quest_A && !GetQuestRewardStatus(ar->quest_A)) + missingQuest = ar->quest_A; + else if (GetTeam() == HORDE && ar->quest_H && !GetQuestRewardStatus(ar->quest_H)) + missingQuest = ar->quest_H; - if (ar->achievement) - if (!leader || !leader->HasAchieved(ar->achievement)) - missingAchievement = ar->achievement; + Player* leader = this; + ObjectGuid leaderGuid = GetGroup() ? GetGroup()->GetLeaderGUID() : GetGUID(); + if (leaderGuid != GetGUID()) + leader = ObjectAccessor::FindPlayer(leaderGuid); - Difficulty target_difficulty = GetDifficultyID(mapEntry); - MapDifficultyEntry const* mapDiff = sDB2Manager.GetDownscaledMapDifficultyData(target_map, target_difficulty); - if (LevelMin || LevelMax || missingItem || missingQuest || missingAchievement) + if (ar->achievement) + if (!leader || !leader->HasAchieved(ar->achievement)) + missingAchievement = ar->achievement; + } + + if (LevelMin || LevelMax || failedMapDifficultyXCondition || missingItem || missingQuest || missingAchievement) { if (report) { if (missingQuest && !ar->questFailedText.empty()) ChatHandler(GetSession()).PSendSysMessage("%s", ar->questFailedText.c_str()); - else if (mapDiff->Message[sWorld->GetDefaultDbcLocale()][0] != '\0') // if (missingAchievement) covered by this case - SendTransferAborted(target_map, TRANSFER_ABORT_DIFFICULTY, target_difficulty); + else if (mapDiff->Message[sWorld->GetDefaultDbcLocale()][0] != '\0' || failedMapDifficultyXCondition) // if (missingAchievement) covered by this case + SendTransferAborted(target_map, TRANSFER_ABORT_DIFFICULTY, target_difficulty, failedMapDifficultyXCondition); else if (missingItem) GetSession()->SendNotification(GetSession()->GetTrinityString(LANG_LEVEL_MINREQUIRED_AND_ITEM), LevelMin, ASSERT_NOTNULL(sObjectMgr->GetItemTemplate(missingItem))->GetName(GetSession()->GetSessionDbcLocale())); else if (LevelMin) @@ -24396,12 +24415,13 @@ void Player::SendUpdateToOutOfRangeGroupMembers() pet->ResetGroupUpdateFlag(); } -void Player::SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 arg) const +void Player::SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 arg /*= 0*/, int32 mapDifficultyXConditionID /*= 0*/) const { WorldPackets::Movement::TransferAborted transferAborted; transferAborted.MapID = mapid; transferAborted.Arg = arg; transferAborted.TransfertAbort = reason; + transferAborted.MapDifficultyXConditionID = mapDifficultyXConditionID; SendDirectMessage(transferAborted.Write()); } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 647ca6f73cf..ba0fe9628c7 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1053,7 +1053,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SendInitialPacketsBeforeAddToMap(); void SendInitialPacketsAfterAddToMap(); void SendSupercededSpell(uint32 oldSpell, uint32 newSpell) const; - void SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 arg = 0) const; + void SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 arg = 0, int32 mapDifficultyXConditionID = 0) const; void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool welcome) const; bool CanInteractWithQuestGiver(Object* questGiver) const; |
