diff options
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandTags.cpp | 15 | ||||
-rw-r--r-- | src/server/game/Chat/ChatCommands/ChatCommandTags.h | 14 | ||||
-rw-r--r-- | src/server/game/Entities/Conversation/Conversation.cpp | 10 | ||||
-rw-r--r-- | src/server/game/Entities/Conversation/Conversation.h | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.cpp | 89 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.h | 11 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 62 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 3 | ||||
-rw-r--r-- | src/server/game/Handlers/MovementHandler.cpp | 16 | ||||
-rw-r--r-- | src/server/game/Scripting/ScriptMgr.h | 40 | ||||
-rw-r--r-- | src/server/game/Scripting/ScriptReloadMgr.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.cpp | 1 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 10 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_account.cpp | 1 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_battlenet_account.cpp | 1 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_misc.cpp | 1 |
16 files changed, 154 insertions, 127 deletions
diff --git a/src/server/game/Chat/ChatCommands/ChatCommandTags.cpp b/src/server/game/Chat/ChatCommands/ChatCommandTags.cpp index 9caf55b9723..bc64636319c 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommandTags.cpp +++ b/src/server/game/Chat/ChatCommands/ChatCommandTags.cpp @@ -29,6 +29,21 @@ using namespace Trinity::Impl::ChatCommands; +ChatCommandResult Trinity::Impl::ChatCommands::TryConsumExactSequencee(std::string_view sequence, ChatHandler const* handler, std::string_view args) +{ + if (args.empty()) + return std::nullopt; + std::string_view start = args.substr(0, sequence.length()); + if (StringEqualI(start, sequence)) + { + auto [remainingToken, tail] = Trinity::Impl::ChatCommands::tokenize(args.substr(sequence.length())); + if (remainingToken.empty()) // if this is not empty, then we did not consume the full token + return tail; + start = args.substr(0, sequence.length() + remainingToken.length()); + } + return Trinity::Impl::ChatCommands::FormatTrinityString(handler, LANG_CMDPARSER_EXACT_SEQ_MISMATCH, STRING_VIEW_FMT_ARG(sequence), STRING_VIEW_FMT_ARG(start)); +} + ChatCommandResult Trinity::ChatCommands::QuotedString::TryConsume(ChatHandler const* handler, std::string_view args) { if (args.empty()) diff --git a/src/server/game/Chat/ChatCommands/ChatCommandTags.h b/src/server/game/Chat/ChatCommands/ChatCommandTags.h index ed627a50111..c84d85c671f 100644 --- a/src/server/game/Chat/ChatCommands/ChatCommandTags.h +++ b/src/server/game/Chat/ChatCommands/ChatCommandTags.h @@ -65,6 +65,8 @@ namespace Trinity::Impl::ChatCommands // this creates always 25 elements - "abc" -> 'a', 'b', 'c', '\0', '\0', ... up to 25 #define CHATCOMMANDS_IMPL_SPLIT_LITERAL(strliteral) CHATCOMMANDS_IMPL_SPLIT_LITERAL_CONSTRAINED(25, strliteral) + + TC_GAME_API ChatCommandResult TryConsumExactSequencee(std::string_view sequence, ChatHandler const* handler, std::string_view args); } namespace Trinity::ChatCommands @@ -90,17 +92,7 @@ namespace Trinity::ChatCommands ChatCommandResult TryConsume(ChatHandler const* handler, std::string_view args) const { - if (args.empty()) - return std::nullopt; - std::string_view start = args.substr(0, _string.length()); - if (StringEqualI(start, _string)) - { - auto [remainingToken, tail] = Trinity::Impl::ChatCommands::tokenize(args.substr(_string.length())); - if (remainingToken.empty()) // if this is not empty, then we did not consume the full token - return tail; - start = args.substr(0, _string.length() + remainingToken.length()); - } - return Trinity::Impl::ChatCommands::FormatTrinityString(handler, LANG_CMDPARSER_EXACT_SEQ_MISMATCH, STRING_VIEW_FMT_ARG(_string), STRING_VIEW_FMT_ARG(start)); + return Trinity::Impl::ChatCommands::TryConsumExactSequencee(_string, handler, args); } private: diff --git a/src/server/game/Entities/Conversation/Conversation.cpp b/src/server/game/Entities/Conversation/Conversation.cpp index 60c03073507..e5e59f49542 100644 --- a/src/server/game/Entities/Conversation/Conversation.cpp +++ b/src/server/game/Entities/Conversation/Conversation.cpp @@ -209,12 +209,13 @@ void Conversation::Create(ObjectGuid::LowType lowGuid, uint32 conversationEntry, lineField.Flags = line->Flags; lineField.ChatType = line->ChatType; + std::array<Milliseconds, TOTAL_LOCALES>& startTimes = _lineStartTimes[line->Id]; for (LocaleConstant locale = LOCALE_enUS; locale < TOTAL_LOCALES; locale = LocaleConstant(locale + 1)) { if (locale == LOCALE_none) continue; - _lineStartTimes[{ locale, line->Id }] = _lastLineEndTimes[locale]; + startTimes[locale] = _lastLineEndTimes[locale]; if (locale == DEFAULT_LOCALE) lineField.StartTime = _lastLineEndTimes[locale].count(); @@ -225,7 +226,7 @@ void Conversation::Create(ObjectGuid::LowType lowGuid, uint32 conversationEntry, } } - _duration = Milliseconds(*std::max_element(_lastLineEndTimes.begin(), _lastLineEndTimes.end())); + _duration = *std::ranges::max_element(_lastLineEndTimes); SetUpdateFieldValue(m_values.ModifyValue(&Conversation::m_conversationData).ModifyValue(&UF::ConversationData::LastLineEndTime), _duration.count()); SetUpdateFieldValue(m_values.ModifyValue(&Conversation::m_conversationData).ModifyValue(&UF::ConversationData::Lines), std::move(lines)); @@ -288,7 +289,10 @@ void Conversation::AddActor(int32 actorId, uint32 actorIdx, ConversationActorTyp Milliseconds const* Conversation::GetLineStartTime(LocaleConstant locale, int32 lineId) const { - return Trinity::Containers::MapGetValuePtr(_lineStartTimes, { locale, lineId }); + if (std::array<Milliseconds, TOTAL_LOCALES> const* durations = Trinity::Containers::MapGetValuePtr(_lineStartTimes, lineId)) + return &(*durations)[locale]; + + return nullptr; } Milliseconds Conversation::GetLastLineEndTime(LocaleConstant locale) const diff --git a/src/server/game/Entities/Conversation/Conversation.h b/src/server/game/Entities/Conversation/Conversation.h index 4f85809b5ba..96cfd6dda77 100644 --- a/src/server/game/Entities/Conversation/Conversation.h +++ b/src/server/game/Entities/Conversation/Conversation.h @@ -20,7 +20,6 @@ #include "Object.h" #include "GridObject.h" -#include "Hash.h" class ConversationAI; class Unit; @@ -100,7 +99,7 @@ class TC_GAME_API Conversation final : public WorldObject, public GridObject<Con Milliseconds _duration; uint32 _textureKitId; - std::unordered_map<std::pair<LocaleConstant /*locale*/, int32 /*lineId*/>, Milliseconds /*startTime*/> _lineStartTimes; + std::unordered_map<int32 /*lineId*/, std::array<Milliseconds, TOTAL_LOCALES> /*startTime*/> _lineStartTimes; std::array<Milliseconds /*endTime*/, TOTAL_LOCALES> _lastLineEndTimes; std::unique_ptr<ConversationAI> _ai; diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index be3ef59c975..89a36b1d026 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -63,6 +63,13 @@ Item* NewItemOrBag(ItemTemplate const* proto) return new Item(); } +struct ItemSetEffect +{ + uint32 ItemSetID; + std::unordered_set<Item const*> EquippedItems; + std::unordered_set<ItemSetSpellEntry const*> SetBonuses; +}; + void AddItemsSetItem(Player* player, Item const* item) { ItemTemplate const* proto = item->GetTemplate(); @@ -205,6 +212,34 @@ void RemoveItemsSetItem(Player* player, Item const* item) } } +void UpdateItemSetAuras(Player* player, bool formChange) +{ + // item set bonuses not dependent from item broken state + for (ItemSetEffect* eff : player->ItemSetEff) + { + if (!eff) + continue; + + for (ItemSetSpellEntry const* itemSetSpell : eff->SetBonuses) + { + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itemSetSpell->SpellID, DIFFICULTY_NONE); + + if (itemSetSpell->ChrSpecID && ChrSpecialization(itemSetSpell->ChrSpecID) != player->GetPrimarySpecialization()) + player->ApplyEquipSpell(spellInfo, nullptr, false, false); // item set aura is not for current spec + else + { + player->ApplyEquipSpell(spellInfo, nullptr, false, formChange); // remove spells that not fit to form - removal is skipped if shapeshift condition is satisfied + player->ApplyEquipSpell(spellInfo, nullptr, true, formChange); // add spells that fit form but not active + } + } + } +} + +void DeleteItemSetEffects(ItemSetEffect* itemSetEffect) +{ + delete itemSetEffect; +} + bool ItemCanGoIntoBag(ItemTemplate const* pProto, ItemTemplate const* pBagProto) { if (!pProto || !pBagProto) @@ -1041,6 +1076,21 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie return true; } +void Item::LoadAdditionalDataFromDB(Player const* owner, ItemAdditionalLoadInfo* addionalData) +{ + if (GetTemplate()->GetArtifactID() && addionalData->Artifact) + LoadArtifactData(owner, addionalData->Artifact->Xp, addionalData->Artifact->ArtifactAppearanceId, + addionalData->Artifact->ArtifactTierId, addionalData->Artifact->ArtifactPowers); + + if (addionalData->AzeriteItem) + if (AzeriteItem* azeriteItem = ToAzeriteItem()) + azeriteItem->LoadAzeriteItemData(owner, *addionalData->AzeriteItem); + + if (addionalData->AzeriteEmpoweredItem) + if (AzeriteEmpoweredItem* azeriteEmpoweredItem = ToAzeriteEmpoweredItem()) + azeriteEmpoweredItem->LoadAzeriteEmpoweredItemData(owner, *addionalData->AzeriteEmpoweredItem); +} + void Item::LoadArtifactData(Player const* owner, uint64 xp, uint32 artifactAppearanceId, uint32 artifactTier, std::vector<ArtifactPowerData>& powers) { for (uint8 i = 0; i <= artifactTier; ++i) @@ -2597,20 +2647,25 @@ bool Item::IsArtifactDisabled() const return true; } +int32 Item::GetArtifactPowerIndex(uint32 artifactPowerId) const +{ + return m_itemData->ArtifactPowers.FindIndexIf([artifactPowerId](UF::ArtifactPower const& artifactPower) + { + return uint32(artifactPower.ArtifactPowerID) == artifactPowerId; + }); +} + UF::ArtifactPower const* Item::GetArtifactPower(uint32 artifactPowerId) const { - auto indexItr = m_artifactPowerIdToIndex.find(artifactPowerId); - if (indexItr != m_artifactPowerIdToIndex.end()) - return &m_itemData->ArtifactPowers[indexItr->second]; + int32 index = GetArtifactPowerIndex(artifactPowerId); + if (index >= 0) + return &m_itemData->ArtifactPowers[index]; return nullptr; } void Item::AddArtifactPower(ArtifactPowerData const* artifactPower) { - uint16 index = uint16(m_artifactPowerIdToIndex.size()); - m_artifactPowerIdToIndex[artifactPower->ArtifactPowerId] = index; - UF::ArtifactPower& powerField = AddDynamicUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::ArtifactPowers)); powerField.ArtifactPowerID = artifactPower->ArtifactPowerId; powerField.PurchasedRank = artifactPower->PurchasedRank; @@ -2619,27 +2674,31 @@ void Item::AddArtifactPower(ArtifactPowerData const* artifactPower) void Item::SetArtifactPower(uint16 artifactPowerId, uint8 purchasedRank, uint8 currentRankWithBonus) { - auto indexItr = m_artifactPowerIdToIndex.find(artifactPowerId); - if (indexItr != m_artifactPowerIdToIndex.end()) + int32 index = GetArtifactPowerIndex(artifactPowerId); + if (index >= 0) { SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData) - .ModifyValue(&UF::ItemData::ArtifactPowers, indexItr->second) + .ModifyValue(&UF::ItemData::ArtifactPowers, index) .ModifyValue(&UF::ArtifactPower::PurchasedRank), purchasedRank); SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData) - .ModifyValue(&UF::ItemData::ArtifactPowers, indexItr->second) + .ModifyValue(&UF::ItemData::ArtifactPowers, index) .ModifyValue(&UF::ArtifactPower::CurrentRankWithBonus), currentRankWithBonus); } } void Item::InitArtifactPowers(uint8 artifactId, uint8 artifactTier) { + std::unordered_set<uint32> knownPowers; + for (UF::ArtifactPower const& power : m_itemData->ArtifactPowers) + knownPowers.insert(power.ArtifactPowerID); + for (ArtifactPowerEntry const* artifactPower : sDB2Manager.GetArtifactPowers(artifactId)) { if (artifactPower->Tier != artifactTier) continue; - if (m_artifactPowerIdToIndex.find(artifactPower->ID) != m_artifactPowerIdToIndex.end()) + if (knownPowers.contains(artifactPower->ID)) continue; ArtifactPowerData powerData; @@ -2714,20 +2773,20 @@ void Item::ApplyArtifactPowerEnchantmentBonuses(EnchantmentSlot slot, uint32 enc break; case ITEM_ENCHANTMENT_TYPE_ARTIFACT_POWER_BONUS_RANK_BY_ID: { - if (uint16 const* artifactPowerIndex = Trinity::Containers::MapGetValuePtr(m_artifactPowerIdToIndex, enchant->EffectArg[i])) + if (int32 artifactPowerIndex = GetArtifactPowerIndex(enchant->EffectArg[i]); artifactPowerIndex >= 0) { - uint8 newRank = m_itemData->ArtifactPowers[*artifactPowerIndex].CurrentRankWithBonus; + uint8 newRank = m_itemData->ArtifactPowers[artifactPowerIndex].CurrentRankWithBonus; if (apply) newRank += enchant->EffectPointsMin[i]; else newRank -= enchant->EffectPointsMin[i]; SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData) - .ModifyValue(&UF::ItemData::ArtifactPowers, *artifactPowerIndex) + .ModifyValue(&UF::ItemData::ArtifactPowers, artifactPowerIndex) .ModifyValue(&UF::ArtifactPower::CurrentRankWithBonus), newRank); if (IsEquipped()) - if (ArtifactPowerRankEntry const* artifactPowerRank = sDB2Manager.GetArtifactPowerRank(m_itemData->ArtifactPowers[*artifactPowerIndex].ArtifactPowerID, newRank ? newRank - 1 : 0)) + if (ArtifactPowerRankEntry const* artifactPowerRank = sDB2Manager.GetArtifactPowerRank(m_itemData->ArtifactPowers[artifactPowerIndex].ArtifactPowerID, newRank ? newRank - 1 : 0)) owner->ApplyArtifactPowerRank(this, artifactPowerRank, newRank != 0); } break; diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 231af9bfb08..527f5e50068 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -37,13 +37,6 @@ namespace WorldPackets } } -struct ItemSetEffect -{ - uint32 ItemSetID; - std::unordered_set<Item const*> EquippedItems; - std::unordered_set<ItemSetSpellEntry const*> SetBonuses; -}; - #define MAX_GEM_SOCKETS MAX_ITEM_PROTO_SOCKETS// (BONUS_ENCHANTMENT_SLOT-SOCK_ENCHANTMENT_SLOT) and item proto size, equal value expected #define MAX_ENCHANTMENT_OFFSET 3 @@ -222,6 +215,7 @@ class TC_GAME_API Item : public Object bool IsBoundByEnchant() const; virtual void SaveToDB(CharacterDatabaseTransaction trans); virtual bool LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fields, uint32 entry); + void LoadAdditionalDataFromDB(Player const* owner, ItemAdditionalLoadInfo* addionalData); void LoadArtifactData(Player const* owner, uint64 xp, uint32 artifactAppearanceId, uint32 artifactTier, std::vector<ArtifactPowerData>& powers); // must be called after LoadFromDB to have gems (relics) initialized void CheckArtifactRelicSlotUnlock(Player const* owner); @@ -465,7 +459,8 @@ class TC_GAME_API Item : public Object GuidSet allowedGUIDs; ItemRandomBonusListId m_randomBonusListId; // store separately to easily find which bonus list is the one randomly given for stat rerolling ObjectGuid m_childItem; - std::unordered_map<uint32, uint16> m_artifactPowerIdToIndex; std::array<uint32, MAX_ITEM_PROTO_SOCKETS> m_gemScalingLevels; + + int32 GetArtifactPowerIndex(uint32 artifactPowerId) const; }; #endif diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 206be44af06..5b5adc24b31 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -371,8 +371,8 @@ Player::~Player() for (ItemMap::iterator iter = mMitems.begin(); iter != mMitems.end(); ++iter) delete iter->second; //if item is duplicated... then server may crash ... but that item should be deallocated - for (size_t x = 0; x < ItemSetEff.size(); x++) - delete ItemSetEff[x]; + for (ItemSetEffect* itemSetEff : ItemSetEff) + DeleteItemSetEffects(itemSetEff); for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i) delete _voidStorageItems[i]; @@ -8481,31 +8481,7 @@ void Player::UpdateEquipSpellsAtFormChange() } } - UpdateItemSetAuras(true); -} - -void Player::UpdateItemSetAuras(bool formChange /*= false*/) -{ - // item set bonuses not dependent from item broken state - for (size_t setindex = 0; setindex < ItemSetEff.size(); ++setindex) - { - ItemSetEffect* eff = ItemSetEff[setindex]; - if (!eff) - continue; - - for (ItemSetSpellEntry const* itemSetSpell : eff->SetBonuses) - { - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itemSetSpell->SpellID, DIFFICULTY_NONE); - - if (itemSetSpell->ChrSpecID && ChrSpecialization(itemSetSpell->ChrSpecID) != GetPrimarySpecialization()) - ApplyEquipSpell(spellInfo, nullptr, false, false); // item set aura is not for current spec - else - { - ApplyEquipSpell(spellInfo, nullptr, false, formChange); // remove spells that not fit to form - removal is skipped if shapeshift condition is satisfied - ApplyEquipSpell(spellInfo, nullptr, true, formChange); // add spells that fit form but not active - } - } - } + UpdateItemSetAuras(this, true); } void Player::ApplyArtifactPowers(Item* item, bool apply) @@ -19038,19 +19014,7 @@ void Player::_LoadInventory(PreparedQueryResult result, PreparedQueryResult arti if (Item* item = _LoadItem(trans, zoneId, timeDiff, fields)) { if (ItemAdditionalLoadInfo* addionalDataPtr = Trinity::Containers::MapGetValuePtr(additionalData, fields[0].GetUInt64())) - { - if (item->GetTemplate()->GetArtifactID() && addionalDataPtr->Artifact) - item->LoadArtifactData(this, addionalDataPtr->Artifact->Xp, addionalDataPtr->Artifact->ArtifactAppearanceId, - addionalDataPtr->Artifact->ArtifactTierId, addionalDataPtr->Artifact->ArtifactPowers); - - if (addionalDataPtr->AzeriteItem) - if (AzeriteItem* azeriteItem = item->ToAzeriteItem()) - azeriteItem->LoadAzeriteItemData(this, *addionalDataPtr->AzeriteItem); - - if (addionalDataPtr->AzeriteEmpoweredItem) - if (AzeriteEmpoweredItem* azeriteEmpoweredItem = item->ToAzeriteEmpoweredItem()) - azeriteEmpoweredItem->LoadAzeriteEmpoweredItemData(this, *addionalDataPtr->AzeriteEmpoweredItem); - } + item->LoadAdditionalDataFromDB(this, addionalDataPtr); ObjectGuid bagGuid = fields[52].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[52].GetUInt64()) : ObjectGuid::Empty; uint8 slot = fields[53].GetUInt8(); @@ -19410,19 +19374,7 @@ Item* Player::_LoadMailedItem(ObjectGuid const& playerGuid, Player* player, uint } if (addionalData) - { - if (item->GetTemplate()->GetArtifactID() && addionalData->Artifact) - item->LoadArtifactData(player, addionalData->Artifact->Xp, addionalData->Artifact->ArtifactAppearanceId, - addionalData->Artifact->ArtifactTierId, addionalData->Artifact->ArtifactPowers); - - if (addionalData->AzeriteItem) - if (AzeriteItem* azeriteItem = item->ToAzeriteItem()) - azeriteItem->LoadAzeriteItemData(player, *addionalData->AzeriteItem); - - if (addionalData->AzeriteEmpoweredItem) - if (AzeriteEmpoweredItem* azeriteEmpoweredItem = item->ToAzeriteEmpoweredItem()) - azeriteEmpoweredItem->LoadAzeriteEmpoweredItemData(player, *addionalData->AzeriteEmpoweredItem); - } + item->LoadAdditionalDataFromDB(player, addionalData); if (mail) mail->AddItem(itemGuid, itemEntry); @@ -27363,7 +27315,7 @@ void Player::ResetTalentSpecialization() LearnSpecializationSpells(); SendTalentsInfoData(); - UpdateItemSetAuras(false); + UpdateItemSetAuras(this, false); } TalentLearnResult Player::LearnPvpTalent(uint32 talentID, uint8 slot, int32* spellOnCooldown) @@ -28575,7 +28527,7 @@ void Player::ActivateTalentGroup(ChrSpecializationEntry const* spec) SetPower(POWER_MANA, 0); // Mana must be 0 even if it isn't the active power type. SetPower(pw, 0); - UpdateItemSetAuras(false); + UpdateItemSetAuras(this, false); // update visible transmog for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i) if (Item* equippedItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 69329a69358..67af3272b27 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2455,7 +2455,6 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player> void ApplyItemEquipSpell(Item* item, bool apply, bool formChange = false); void ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply, bool formChange = false); void UpdateEquipSpellsAtFormChange(); - void UpdateItemSetAuras(bool formChange = false); void ApplyArtifactPowers(Item* item, bool apply); void ApplyArtifactPowerRank(Item* artifact, ArtifactPowerRankEntry const* artifactPowerRank, bool apply); void ApplyAzeritePowers(Item* item, bool apply); @@ -3343,6 +3342,8 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player> TC_GAME_API void AddItemsSetItem(Player* player, Item const* item); TC_GAME_API void RemoveItemsSetItem(Player* player, Item const* item); +TC_GAME_API void UpdateItemSetAuras(Player* player, bool formChange); +TC_GAME_API void DeleteItemSetEffects(ItemSetEffect* itemSetEffect); // Transforms a container of customization choices with continuous storage into iterator pair that does not depend on container // and doesn't force implementations in header files diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index b150e7668d2..f5e72332351 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -15,8 +15,8 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "AuthenticationPackets.h" #include "WorldSession.h" +#include "AuthenticationPackets.h" #include "Battleground.h" #include "Corpse.h" #include "DB2Stores.h" @@ -29,18 +29,20 @@ #include "Map.h" #include "MapManager.h" #include "MiscPackets.h" +#include "MotionMaster.h" +#include "MoveSpline.h" +#include "MovementGenerator.h" #include "MovementPackets.h" #include "Player.h" #include "SpellInfo.h" -#include "MotionMaster.h" -#include "MovementGenerator.h" -#include "MoveSpline.h" +#include "SpellMgr.h" #include "Transport.h" #include "Vehicle.h" -#include "SpellMgr.h" +#include <boost/accumulators/framework/accumulator_set.hpp> +#include <boost/accumulators/framework/features.hpp> +#include <boost/accumulators/statistics/mean.hpp> +#include <boost/accumulators/statistics/median.hpp> #include <boost/accumulators/statistics/variance.hpp> -#include <boost/accumulators/accumulators.hpp> -#include <boost/accumulators/statistics.hpp> #include <boost/circular_buffer.hpp> void WorldSession::HandleMoveWorldportAckOpcode(WorldPackets::Movement::WorldPortResponse& /*packet*/) diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index e3b7dc63981..39924cc3b57 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -21,7 +21,6 @@ #include "Common.h" #include "ObjectGuid.h" #include "Tuples.h" -#include "Types.h" #include <boost/preprocessor/punctuation/remove_parens.hpp> #include <memory> #include <vector> @@ -1307,37 +1306,46 @@ class TC_GAME_API ScriptMgr namespace Trinity::SpellScripts { template<typename T> - using is_SpellScript = std::is_base_of<SpellScript, T>; + concept IsSpellScript = std::is_base_of_v<SpellScript, T>; template<typename T> - using is_AuraScript = std::is_base_of<AuraScript, T>; + concept IsAuraScript = std::is_base_of_v<AuraScript, T>; + + template<typename T> + concept IsSpellOrAuraScript = IsSpellScript<T> || IsAuraScript<T>; + + template<typename T, typename Other> + concept ComplementScriptFor = (IsSpellScript<T> && IsAuraScript<Other>) + || (IsAuraScript<T> && IsSpellScript<Other>) + || std::same_as<T, void>; + + template<typename T> + concept ArgsTuple = Trinity::is_tuple_v<T>; } -template <typename... Ts> +template <Trinity::SpellScripts::IsSpellOrAuraScript Script1, Trinity::SpellScripts::ComplementScriptFor<Script1> Script2, Trinity::SpellScripts::ArgsTuple ArgsType> class GenericSpellAndAuraScriptLoader : public SpellScriptLoader { - using SpellScriptType = typename Trinity::find_type_if_t<Trinity::SpellScripts::is_SpellScript, Ts...>; - using AuraScriptType = typename Trinity::find_type_if_t<Trinity::SpellScripts::is_AuraScript, Ts...>; - using ArgsType = typename Trinity::find_type_if_t<Trinity::is_tuple, Ts...>; - - static_assert(!std::conjunction_v<std::is_same<SpellScriptType, Trinity::find_type_end>, std::is_same<AuraScriptType, Trinity::find_type_end>>, "At least one of SpellScript/AuraScript arguments must be provided for GenericSpellAndAuraScriptLoader"); - public: GenericSpellAndAuraScriptLoader(char const* name, ArgsType&& args) : SpellScriptLoader(name), _args(std::move(args)) { } private: SpellScript* GetSpellScript() const override { - if constexpr (!std::is_same_v<SpellScriptType, Trinity::find_type_end>) - return Trinity::new_from_tuple<SpellScriptType>(_args); + if constexpr (Trinity::SpellScripts::IsSpellScript<Script1>) + return Trinity::new_from_tuple<Script1>(_args); + else if constexpr (Trinity::SpellScripts::IsSpellScript<Script2>) + return Trinity::new_from_tuple<Script2>(_args); else return nullptr; } AuraScript* GetAuraScript() const override { - if constexpr (!std::is_same_v<AuraScriptType, Trinity::find_type_end>) - return Trinity::new_from_tuple<AuraScriptType>(_args); + if constexpr (Trinity::SpellScripts::IsAuraScript<Script1>) + return Trinity::new_from_tuple<Script1>(_args); + else if constexpr (Trinity::SpellScripts::IsAuraScript<Script2>) + return Trinity::new_from_tuple<Script2>(_args); else return nullptr; } @@ -1345,10 +1353,10 @@ private: ArgsType _args; }; -#define RegisterSpellScriptWithArgs(spell_script, script_name, ...) new GenericSpellAndAuraScriptLoader<BOOST_PP_REMOVE_PARENS(spell_script), decltype(std::make_tuple(__VA_ARGS__))>(script_name, std::make_tuple(__VA_ARGS__)) -#define RegisterSpellScript(spell_script) RegisterSpellScriptWithArgs(spell_script, #spell_script) #define RegisterSpellAndAuraScriptPairWithArgs(script_1, script_2, script_name, ...) new GenericSpellAndAuraScriptLoader<BOOST_PP_REMOVE_PARENS(script_1), BOOST_PP_REMOVE_PARENS(script_2), decltype(std::make_tuple(__VA_ARGS__))>(script_name, std::make_tuple(__VA_ARGS__)) #define RegisterSpellAndAuraScriptPair(script_1, script_2) RegisterSpellAndAuraScriptPairWithArgs(script_1, script_2, #script_1) +#define RegisterSpellScriptWithArgs(spell_script, script_name, ...) RegisterSpellAndAuraScriptPairWithArgs(spell_script, void, script_name, __VA_ARGS__) +#define RegisterSpellScript(spell_script) RegisterSpellAndAuraScriptPairWithArgs(spell_script, void, #spell_script) template <class AI> class GenericCreatureScript : public CreatureScript diff --git a/src/server/game/Scripting/ScriptReloadMgr.cpp b/src/server/game/Scripting/ScriptReloadMgr.cpp index 17e9530818c..d61dd8a318a 100644 --- a/src/server/game/Scripting/ScriptReloadMgr.cpp +++ b/src/server/game/Scripting/ScriptReloadMgr.cpp @@ -50,9 +50,9 @@ ScriptReloadMgr* ScriptReloadMgr::instance() #include "Timer.h" #include "Util.h" #include "World.h" -#include <boost/algorithm/string/replace.hpp> #include <boost/dll/runtime_symbol_info.hpp> -#include <boost/filesystem.hpp> +#include <boost/filesystem/directory.hpp> +#include <boost/filesystem/operations.hpp> #include <boost/system/system_error.hpp> #include <efsw/efsw.hpp> #include <algorithm> diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 7f2bd595776..a62b71b66ea 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -34,7 +34,6 @@ #include "RealmList.pb.h" #include "ScriptMgr.h" #include "SessionKeyGenerator.h" -#include "SslStream.h" #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 920386c1fd5..226ef8a8514 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -108,8 +108,6 @@ #include "WorldSocket.h" #include "WorldStateMgr.h" -#include <boost/algorithm/string.hpp> - TC_GAME_API std::atomic<bool> World::m_stopEvent(false); TC_GAME_API uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE; @@ -265,7 +263,13 @@ void World::SetMotd(std::string motd) sScriptMgr->OnMotdChange(motd); _motd.clear(); - boost::split(_motd, motd, boost::is_any_of("@")); + + std::vector<std::string_view> tokens = Trinity::Tokenize(motd, '@', true); + + _motd.reserve(tokens.size()); + + for (std::string_view const& token : tokens) + _motd.emplace_back(token); } std::vector<std::string> const& World::GetMotd() const diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp index 2fd6e7dd557..ad0fa770a94 100644 --- a/src/server/scripts/Commands/cs_account.cpp +++ b/src/server/scripts/Commands/cs_account.cpp @@ -30,7 +30,6 @@ EndScriptData */ #include "CryptoGenerics.h" #include "CryptoRandom.h" #include "DatabaseEnv.h" -#include "IpAddress.h" #include "IPLocation.h" #include "Language.h" #include "Log.h" diff --git a/src/server/scripts/Commands/cs_battlenet_account.cpp b/src/server/scripts/Commands/cs_battlenet_account.cpp index 6f38ac768ac..254ff517538 100644 --- a/src/server/scripts/Commands/cs_battlenet_account.cpp +++ b/src/server/scripts/Commands/cs_battlenet_account.cpp @@ -21,7 +21,6 @@ #include "ChatCommand.h" #include "CryptoRandom.h" #include "DatabaseEnv.h" -#include "IpAddress.h" #include "IPLocation.h" #include "Language.h" #include "Log.h" diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 43e0f1498a4..9377a3abf97 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -27,7 +27,6 @@ #include "DisableMgr.h" #include "GridNotifiers.h" #include "Group.h" -#include "IpAddress.h" #include "IPLocation.h" #include "Item.h" #include "ItemBonusMgr.h" |