diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/Containers/Utilities/ListUtils.h | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 34 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 2 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 2 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Server/Packets/ItemPackets.cpp | 23 | ||||
-rw-r--r-- | src/server/game/Server/Packets/ItemPackets.h | 30 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 6 |
8 files changed, 98 insertions, 9 deletions
diff --git a/src/common/Containers/Utilities/ListUtils.h b/src/common/Containers/Utilities/ListUtils.h index f5de0d42ec9..00a7d33c72f 100644 --- a/src/common/Containers/Utilities/ListUtils.h +++ b/src/common/Containers/Utilities/ListUtils.h @@ -24,7 +24,7 @@ namespace Trinity::Containers::Lists { template<typename T, typename Alloc = std::allocator<T>> -inline typename std::list<T, Alloc>::iterator RemoveUnique(std::list<T, Alloc>& list, T const& value) +inline typename std::list<T, Alloc>::iterator RemoveUnique(std::list<T, Alloc>& list, std::type_identity_t<T> const& value) { auto itr = std::find(list.begin(), list.end(), value); if (itr != list.end()) @@ -34,7 +34,7 @@ inline typename std::list<T, Alloc>::iterator RemoveUnique(std::list<T, Alloc>& } template<typename T, typename Alloc = std::allocator<T>> -inline typename std::forward_list<T, Alloc>::iterator RemoveUnique(std::forward_list<T, Alloc>& list, T const& value) +inline typename std::forward_list<T, Alloc>::iterator RemoveUnique(std::forward_list<T, Alloc>& list, std::type_identity_t<T> const& value) { auto itr = list.before_begin(); auto toErase = std::next(itr); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 820934bd338..48ba015a43b 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -78,6 +78,7 @@ #include "Language.h" #include "LanguageMgr.h" #include "LFGMgr.h" +#include "ListUtils.h" #include "Log.h" #include "Loot.h" #include "LootItemStorage.h" @@ -8376,6 +8377,17 @@ void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply, TC_LOG_DEBUG("entities.player", "Player::ApplyEquipSpell: Player '{}' ({}) cast {} equip spell (ID: {})", GetName(), GetGUID().ToString(), (item ? "item" : "itemset"), spellInfo->Id); + if (spellInfo->HasAttribute(SPELL_ATTR9_ITEM_PASSIVE_ON_CLIENT)) + { + m_itemPassives.push_front(spellInfo->Id); + if (IsInWorld()) + { + WorldPackets::Item::AddItemPassive addItemPassive; + addItemPassive.SpellID = spellInfo->Id; + SendDirectMessage(addItemPassive.Write()); + } + } + CastSpell(this, spellInfo->Id, item); } else @@ -8387,6 +8399,17 @@ void Player::ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply, return; // and remove only not compatible at form change } + if (spellInfo->HasAttribute(SPELL_ATTR9_ITEM_PASSIVE_ON_CLIENT)) + { + Trinity::Containers::Lists::RemoveUnique(m_itemPassives, spellInfo->Id); + if (IsInWorld()) + { + WorldPackets::Item::RemoveItemPassive removeItemPassive; + removeItemPassive.SpellID = spellInfo->Id; + SendDirectMessage(removeItemPassive.Write()); + } + } + if (item) RemoveAurasDueToItemSpell(spellInfo->Id, item->GetGUID()); // un-apply all spells, not only at-equipped else @@ -13841,6 +13864,16 @@ void Player::SendItemDurations() (*itr)->SendTimeUpdate(this); } +void Player::SendItemPassives() +{ + if (m_itemPassives.empty()) + return; + + WorldPackets::Item::SendItemPassives sendItemPassives; + sendItemPassives.SpellID.assign(m_itemPassives.begin(), m_itemPassives.end()); + SendDirectMessage(sendItemPassives.Write()); +} + void Player::SendNewItem(Item* item, uint32 quantity, bool pushed, bool created, bool broadcast /*= false*/, uint32 dungeonEncounterId /*= 0*/) { if (!item) // prevent crash @@ -24468,6 +24501,7 @@ void Player::SendInitialPacketsAfterAddToMap() SendAurasForTarget(this); SendEnchantmentDurations(); // must be after add to map SendItemDurations(); // must be after add to map + SendItemPassives(); // must be after add to map if (GetMap()->IsRaid()) { diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index c9e3ca5a0d3..b3d3d9c7466 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1590,6 +1590,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player> void AddItemDurations(Item* item); void RemoveItemDurations(Item* item); void SendItemDurations(); + void SendItemPassives(); void LoadCorpse(PreparedQueryResult result); bool AddItem(uint32 itemId, uint32 count); @@ -3138,6 +3139,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player> EnchantDurationList m_enchantDuration; ItemDurationList m_itemDuration; + std::forward_list<int32> m_itemPassives; GuidUnorderedSet m_itemSoulboundTradeable; std::unique_ptr<ResurrectionData> _resurrectionData; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index e7130338f81..718cbf63e24 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -785,7 +785,7 @@ enum SpellAttr9 : uint32 SPELL_ATTR9_JUMPCHARGE__NO_FACING_CONTROL = 0x00800000, // TITLE JumpCharge - no facing control SPELL_ATTR9_IGNORE_CASTER_HEALING_MODIFIERS = 0x01000000, // TITLE Ignore Caster Healing Modifiers SPELL_ATTR9_DONT_CONSUME_CHARGE_IF_ITEM_DELETED = 0x02000000, /*NYI - some sort of bugfix attribute to prevent double item deletion?*/ // TITLE (Programmer Only) Don't consume charge if item deleted - SPELL_ATTR9_UNK26 = 0x04000000, // TITLE Unknown attribute 26@Attr9 + SPELL_ATTR9_ITEM_PASSIVE_ON_CLIENT = 0x04000000, // TITLE Item Passive On Client SPELL_ATTR9_UNK27 = 0x08000000, // TITLE Unknown attribute 27@Attr9 SPELL_ATTR9_UNK28 = 0x10000000, // TITLE Unknown attribute 28@Attr9 SPELL_ATTR9_UNK29 = 0x20000000, // TITLE Unknown attribute 29@Attr9 diff --git a/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp b/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp index 2140906aece..133026d02c1 100644 --- a/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp +++ b/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp @@ -1461,7 +1461,7 @@ TC_API_EXPORT EnumText EnumUtils<SpellAttr9>::ToString(SpellAttr9 value) case SPELL_ATTR9_JUMPCHARGE__NO_FACING_CONTROL: return { "SPELL_ATTR9_JUMPCHARGE__NO_FACING_CONTROL", "JumpCharge - no facing control", "" }; case SPELL_ATTR9_IGNORE_CASTER_HEALING_MODIFIERS: return { "SPELL_ATTR9_IGNORE_CASTER_HEALING_MODIFIERS", "Ignore Caster Healing Modifiers", "" }; case SPELL_ATTR9_DONT_CONSUME_CHARGE_IF_ITEM_DELETED: return { "SPELL_ATTR9_DONT_CONSUME_CHARGE_IF_ITEM_DELETED", "(Programmer Only) Don't consume charge if item deleted", "" }; - case SPELL_ATTR9_UNK26: return { "SPELL_ATTR9_UNK26", "Unknown attribute 26@Attr9", "" }; + case SPELL_ATTR9_ITEM_PASSIVE_ON_CLIENT: return { "SPELL_ATTR9_ITEM_PASSIVE_ON_CLIENT", "Item Passive On Client", "" }; case SPELL_ATTR9_UNK27: return { "SPELL_ATTR9_UNK27", "Unknown attribute 27@Attr9", "" }; case SPELL_ATTR9_UNK28: return { "SPELL_ATTR9_UNK28", "Unknown attribute 28@Attr9", "" }; case SPELL_ATTR9_UNK29: return { "SPELL_ATTR9_UNK29", "Unknown attribute 29@Attr9", "" }; @@ -1505,7 +1505,7 @@ TC_API_EXPORT SpellAttr9 EnumUtils<SpellAttr9>::FromIndex(size_t index) case 23: return SPELL_ATTR9_JUMPCHARGE__NO_FACING_CONTROL; case 24: return SPELL_ATTR9_IGNORE_CASTER_HEALING_MODIFIERS; case 25: return SPELL_ATTR9_DONT_CONSUME_CHARGE_IF_ITEM_DELETED; - case 26: return SPELL_ATTR9_UNK26; + case 26: return SPELL_ATTR9_ITEM_PASSIVE_ON_CLIENT; case 27: return SPELL_ATTR9_UNK27; case 28: return SPELL_ATTR9_UNK28; case 29: return SPELL_ATTR9_UNK29; @@ -1546,7 +1546,7 @@ TC_API_EXPORT size_t EnumUtils<SpellAttr9>::ToIndex(SpellAttr9 value) case SPELL_ATTR9_JUMPCHARGE__NO_FACING_CONTROL: return 23; case SPELL_ATTR9_IGNORE_CASTER_HEALING_MODIFIERS: return 24; case SPELL_ATTR9_DONT_CONSUME_CHARGE_IF_ITEM_DELETED: return 25; - case SPELL_ATTR9_UNK26: return 26; + case SPELL_ATTR9_ITEM_PASSIVE_ON_CLIENT: return 26; case SPELL_ATTR9_UNK27: return 27; case SPELL_ATTR9_UNK28: return 28; case SPELL_ATTR9_UNK29: return 29; diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp index b4bb558bac6..04c446ff3ae 100644 --- a/src/server/game/Server/Packets/ItemPackets.cpp +++ b/src/server/game/Server/Packets/ItemPackets.cpp @@ -402,3 +402,26 @@ void WorldPackets::Item::SetBankAutosortDisabled::Read() { Disable = _worldPacket.ReadBit(); } + +WorldPacket const* WorldPackets::Item::AddItemPassive::Write() +{ + _worldPacket << int32(SpellID); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Item::RemoveItemPassive::Write() +{ + _worldPacket << int32(SpellID); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Item::SendItemPassives::Write() +{ + _worldPacket << uint32(SpellID.size()); + if (!SpellID.empty()) + _worldPacket.append(SpellID.data(), SpellID.size()); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/ItemPackets.h b/src/server/game/Server/Packets/ItemPackets.h index f0359be4575..60287883441 100644 --- a/src/server/game/Server/Packets/ItemPackets.h +++ b/src/server/game/Server/Packets/ItemPackets.h @@ -591,6 +591,36 @@ namespace WorldPackets bool Disable = false; }; + + class AddItemPassive final : public ServerPacket + { + public: + AddItemPassive() : ServerPacket(SMSG_ADD_ITEM_PASSIVE, 4) { } + + WorldPacket const* Write() override; + + int32 SpellID = 0; + }; + + class RemoveItemPassive final : public ServerPacket + { + public: + RemoveItemPassive() : ServerPacket(SMSG_REMOVE_ITEM_PASSIVE, 4) { } + + WorldPacket const* Write() override; + + int32 SpellID = 0; + }; + + class SendItemPassives final : public ServerPacket + { + public: + SendItemPassives() : ServerPacket(SMSG_SEND_ITEM_PASSIVES, 4) { } + + WorldPacket const* Write() override; + + std::vector<int32> SpellID; + }; } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index f165019734b..d8de9ca04d1 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1037,7 +1037,7 @@ void OpcodeTable::InitializeServerOpcodes() DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACTIVE_SCHEDULED_WORLD_STATE_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADDON_LIST_REQUEST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADD_BATTLENET_FRIEND_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADD_ITEM_PASSIVE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADD_ITEM_PASSIVE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADD_LOSS_OF_CONTROL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADD_RUNE_POWER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADJUST_SPLINE_DURATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -1957,7 +1957,7 @@ void OpcodeTable::InitializeServerOpcodes() DEFINE_SERVER_OPCODE_HANDLER(SMSG_RECRUIT_A_FRIEND_FAILURE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFRESH_COMPONENT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFRESH_SPELL_HISTORY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_REMOVE_ITEM_PASSIVE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_REMOVE_ITEM_PASSIVE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REMOVE_SPELL_FROM_ACTION_BAR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REPLACE_TROPHY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_REPORT_PVP_PLAYER_AFK_RESULT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); @@ -2007,7 +2007,7 @@ void OpcodeTable::InitializeServerOpcodes() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SCRIPT_CAST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEASON_INFO, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SELL_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_ITEM_PASSIVES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_ITEM_PASSIVES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_KNOWN_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_RAID_TARGET_UPDATE_ALL, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_RAID_TARGET_UPDATE_SINGLE, STATUS_NEVER, CONNECTION_TYPE_REALM); |