aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.cpp7
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.h4
-rw-r--r--src/server/game/DataStores/DB2LoadInfo.h17
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp22
-rw-r--r--src/server/game/DataStores/DB2Stores.h2
-rw-r--r--src/server/game/DataStores/DB2Structure.h9
-rw-r--r--src/server/game/Entities/Player/Player.cpp94
-rw-r--r--src/server/game/Entities/Player/Player.h2
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;