aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp71
-rw-r--r--src/server/game/Entities/Unit/Unit.h10
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp20
-rw-r--r--src/server/game/Handlers/SpellHandler.cpp18
-rw-r--r--src/server/game/Server/Packets/SpellPackets.h16
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp6
-rw-r--r--src/server/game/Server/WorldSession.h6
7 files changed, 121 insertions, 26 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 6a17f4f34c8..95d2708760e 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -3462,6 +3462,77 @@ void Unit::RemoveAura(Aura* aura, AuraRemoveMode mode)
RemoveAura(aurApp, mode);
}
+void Unit::RemoveAppliedAuras(std::function<bool(AuraApplication const*)> const& check)
+{
+ for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
+ {
+ if (check(iter->second))
+ {
+ RemoveAura(iter);
+ continue;
+ }
+ ++iter;
+ }
+}
+
+void Unit::RemoveOwnedAuras(std::function<bool(Aura const*)> const& check)
+{
+ for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
+ {
+ if (check(iter->second))
+ {
+ RemoveOwnedAura(iter);
+ continue;
+ }
+ ++iter;
+ }
+}
+
+void Unit::RemoveAppliedAuras(uint32 spellId, std::function<bool(AuraApplication const*)> const& check)
+{
+ for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
+ {
+ if (check(iter->second))
+ {
+ RemoveAura(iter);
+ continue;
+ }
+ ++iter;
+ }
+}
+
+void Unit::RemoveOwnedAuras(uint32 spellId, std::function<bool(Aura const*)> const& check)
+{
+ for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);)
+ {
+ if (check(iter->second))
+ {
+ RemoveOwnedAura(iter);
+ continue;
+ }
+ ++iter;
+ }
+}
+
+void Unit::RemoveAurasByType(AuraType auraType, std::function<bool(AuraApplication const*)> const& check)
+{
+ for (AuraEffectList::iterator iter = m_modAuras[auraType].begin(); iter != m_modAuras[auraType].end();)
+ {
+ Aura* aura = (*iter)->GetBase();
+ AuraApplication * aurApp = aura->GetApplicationOfTarget(GetGUID());
+ ASSERT(aurApp);
+
+ ++iter;
+ if (check(aurApp))
+ {
+ uint32 removedAuras = m_removedAurasCount;
+ RemoveAura(aurApp);
+ if (m_removedAurasCount > removedAuras + 1)
+ iter = m_modAuras[auraType].begin();
+ }
+ }
+}
+
void Unit::RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID, uint32 reqEffMask, AuraRemoveMode removeMode)
{
for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 87254d230e6..e6f6ff13f37 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1779,6 +1779,16 @@ class Unit : public WorldObject
void RemoveAura(AuraApplication * aurApp, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
void RemoveAura(Aura* aur, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
+ // Convenience methods removing auras by predicate
+ void RemoveAppliedAuras(std::function<bool(AuraApplication const*)> const& check);
+ void RemoveOwnedAuras(std::function<bool(Aura const*)> const& check);
+
+ // Optimized overloads taking advantage of map key
+ void RemoveAppliedAuras(uint32 spellId, std::function<bool(AuraApplication const*)> const& check);
+ void RemoveOwnedAuras(uint32 spellId, std::function<bool(Aura const*)> const& check);
+
+ void RemoveAurasByType(AuraType auraType, std::function<bool(AuraApplication const*)> const& check);
+
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit* dispeller, uint8 chargesRemoved = 1);
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 8bf789947b4..58de1e4c007 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -1318,26 +1318,6 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPackets::Misc::SetRaidDiff
}
}
-void WorldSession::HandleCancelMountAuraOpcode(WorldPacket& /*recvData*/)
-{
- TC_LOG_DEBUG("network", "WORLD: CMSG_CANCEL_MOUNT_AURA");
-
- //If player is not mounted, so go out :)
- if (!_player->IsMounted()) // not blizz like; no any messages on blizz
- {
- ChatHandler(this).SendSysMessage(LANG_CHAR_NON_MOUNTED);
- return;
- }
-
- if (_player->IsInFlight()) // not blizz like; no any messages on blizz
- {
- ChatHandler(this).SendSysMessage(LANG_YOU_IN_FLIGHT);
- return;
- }
-
- _player->RemoveAurasByType(SPELL_AURA_MOUNTED); // Calls Dismount()
-}
-
void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket& /*recvData*/)
{
// fly mode on/off
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index eb8dc67ef91..824b747b9f8 100644
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -408,7 +408,23 @@ void WorldSession::HandlePetCancelAuraOpcode(WorldPacket& recvPacket)
pet->RemoveOwnedAura(spellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_CANCEL);
}
-void WorldSession::HandleCancelGrowthAuraOpcode(WorldPacket& /*recvPacket*/) { }
+void WorldSession::HandleCancelGrowthAuraOpcode(WorldPackets::Spells::CancelGrowthAura& /*cancelGrowthAura*/)
+{
+ _player->RemoveAurasByType(SPELL_AURA_MOD_SCALE, [](AuraApplication const* aurApp)
+ {
+ SpellInfo const* spellInfo = aurApp->GetBase()->GetSpellInfo();
+ return !spellInfo->HasAttribute(SPELL_ATTR0_CANT_CANCEL) && spellInfo->IsPositive() && !spellInfo->IsPassive();
+ });
+}
+
+void WorldSession::HandleCancelMountAuraOpcode(WorldPackets::Spells::CancelMountAura& /*cancelMountAura*/)
+{
+ _player->RemoveAurasByType(SPELL_AURA_MOUNTED, [](AuraApplication const* aurApp)
+ {
+ SpellInfo const* spellInfo = aurApp->GetBase()->GetSpellInfo();
+ return !spellInfo->HasAttribute(SPELL_ATTR0_CANT_CANCEL) && spellInfo->IsPositive() && !spellInfo->IsPassive();
+ });
+}
void WorldSession::HandleCancelAutoRepeatSpellOpcode(WorldPacket& /*recvPacket*/)
{
diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h
index 3bcf5b79039..1f7cdd0b93a 100644
--- a/src/server/game/Server/Packets/SpellPackets.h
+++ b/src/server/game/Server/Packets/SpellPackets.h
@@ -38,6 +38,22 @@ namespace WorldPackets
int32 SpellID = 0;
};
+ class CancelGrowthAura final : public ClientPacket
+ {
+ public:
+ CancelGrowthAura(WorldPacket&& packet) : ClientPacket(CMSG_CANCEL_GROWTH_AURA, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ class CancelMountAura final : public ClientPacket
+ {
+ public:
+ CancelMountAura(WorldPacket&& packet) : ClientPacket(CMSG_CANCEL_MOUNT_AURA, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
class RequestCategoryCooldowns final : public ClientPacket
{
public:
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 8b6836f04ab..79570812b9c 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -235,16 +235,16 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_GET_NUM_PENDING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetNumPending );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_GUILD_FILTER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGuildFilter );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_REMOVE_EVENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarRemoveEvent );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_REMOVE_INVITE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleCalendarEventRemoveInvite );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_REMOVE_INVITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventRemoveInvite );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_UPDATE_EVENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarUpdateEvent );
DEFINE_HANDLER(CMSG_CANCEL_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::CancelAura, &WorldSession::HandleCancelAuraOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_AUTO_REPEAT_SPELL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAutoRepeatSpellOpcode);
DEFINE_HANDLER(CMSG_CANCEL_CAST, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Spells::CancelCast, &WorldSession::HandleCancelCastOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_CHANNELLING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelChanneling );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_GROWTH_AURA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelGrowthAuraOpcode );
+ DEFINE_HANDLER(CMSG_CANCEL_GROWTH_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::CancelGrowthAura, &WorldSession::HandleCancelGrowthAuraOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_MASTER_LOOT_ROLL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_MOD_SPEED_NO_CONTROL_AURAS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_MOUNT_AURA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelMountAuraOpcode );
+ DEFINE_HANDLER(CMSG_CANCEL_MOUNT_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::CancelMountAura, &WorldSession::HandleCancelMountAuraOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_QUEUED_SPELL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_TEMP_ENCHANTMENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTempEnchantmentOpcode);
DEFINE_HANDLER(CMSG_CANCEL_TRADE, STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, PROCESS_THREADUNSAFE, WorldPackets::Trade::CancelTrade, &WorldSession::HandleCancelTradeOpcode);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 27d64da7137..f85a682eb4b 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -380,6 +380,8 @@ namespace WorldPackets
namespace Spells
{
class CancelAura;
+ class CancelGrowthAura;
+ class CancelMountAura;
class RequestCategoryCooldowns;
class CancelCast;
class CastSpell;
@@ -1150,7 +1152,8 @@ class WorldSession
void HandleCastSpellOpcode(WorldPackets::Spells::CastSpell& castRequest);
void HandleCancelCastOpcode(WorldPackets::Spells::CancelCast& packet);
void HandleCancelAuraOpcode(WorldPackets::Spells::CancelAura& cancelAura);
- void HandleCancelGrowthAuraOpcode(WorldPacket& recvPacket);
+ void HandleCancelGrowthAuraOpcode(WorldPackets::Spells::CancelGrowthAura& cancelGrowthAura);
+ void HandleCancelMountAuraOpcode(WorldPackets::Spells::CancelMountAura& cancelMountAura);
void HandleCancelAutoRepeatSpellOpcode(WorldPacket& recvPacket);
void HandleLearnTalentsOpcode(WorldPackets::Talent::LearnTalents& packet);
@@ -1306,7 +1309,6 @@ class WorldSession
void SendLfgOfferContinue(uint32 dungeonEntry);
void SendLfgTeleportError(uint8 err);
- void HandleCancelMountAuraOpcode(WorldPacket& recvData);
void HandleSelfResOpcode(WorldPacket& recvData);
void HandleComplainOpcode(WorldPacket& recvData);
void HandleRequestPetInfoOpcode(WorldPacket& recvData);