aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMeji <alvaro.megias@outlook.com>2024-12-29 00:44:05 +0100
committerOvahlord <dreadkiller@gmx.de>2024-12-29 12:18:00 +0100
commitcfc13bc2806857f4c1511221cf479ee09a248c20 (patch)
treed5db0363416003a27711f60199b8bc1c32fa3aec
parent01bf45468b19707d1c3b80cf9069cd7e17bb2c02 (diff)
Core/Units: Added helper methods to cancel mount/shapeshift auras (#30477)
(cherry picked from commit 0b16756172b2c3cc78b0861af86b93daae60edda)
-rw-r--r--src/server/game/Entities/Player/Player.cpp2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp49
-rw-r--r--src/server/game/Entities/Unit/Unit.h3
3 files changed, 53 insertions, 1 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index d43ba20eb74..659eef44495 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -24724,7 +24724,7 @@ void Player::UpdateAreaDependentAuras(uint32 newArea)
{
// use m_zoneUpdateId for speed: UpdateArea called from UpdateZone or instead UpdateZone in both cases m_zoneUpdateId up-to-date
if (iter->second->GetSpellInfo()->CheckLocation(GetMapId(), m_zoneUpdateId, newArea, this) != SPELL_CAST_OK)
- RemoveOwnedAura(iter);
+ RemoveOwnedAura(iter, AURA_REMOVE_BY_INTERRUPT);
else
++iter;
}
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index e477a89df02..83d32dbd701 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -8164,6 +8164,18 @@ void Unit::Dismount()
}
}
+void Unit::CancelMountAura(bool force)
+{
+ if (!HasAuraType(SPELL_AURA_MOUNTED))
+ return;
+
+ RemoveAurasByType(SPELL_AURA_MOUNTED, [force](AuraApplication const* aurApp)
+ {
+ SpellInfo const* spellInfo = aurApp->GetBase()->GetSpellInfo();
+ return force || (!spellInfo->HasAttribute(SPELL_ATTR0_NO_AURA_CANCEL) && spellInfo->IsPositive() && !spellInfo->IsPassive());
+ });
+}
+
MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const
{
if (!mountType)
@@ -8262,6 +8274,11 @@ void Unit::UpdateMountCapability()
if (IsLoading())
return;
+ if (SpellShapeshiftFormEntry const* spellShapeshiftForm = sSpellShapeshiftFormStore.LookupEntry(GetShapeshiftForm()))
+ if (uint32 mountType = spellShapeshiftForm->MountTypeID)
+ if (!GetMountCapability(mountType))
+ CancelTravelShapeshiftForm(AURA_REMOVE_BY_INTERRUPT);
+
AuraEffectVector mounts = CopyAuraEffectList(GetAuraEffectsByType(SPELL_AURA_MOUNTED));
for (AuraEffect* aurEff : mounts)
{
@@ -9121,6 +9138,38 @@ void Unit::SetShapeshiftForm(ShapeshiftForm form)
SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::ShapeshiftForm), form);
}
+void Unit::CancelShapeshiftForm(bool onlyTravelShapeshiftForm /*= false*/, AuraRemoveMode removeMode /*= AURA_REMOVE_BY_DEFAULT*/, bool force /*= false*/)
+{
+ ShapeshiftForm form = GetShapeshiftForm();
+ if (form == FORM_NONE)
+ return;
+
+ bool isTravelShapeshiftForm = [form]()
+ {
+ if (SpellShapeshiftFormEntry const* shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form))
+ {
+ if (shapeInfo->MountTypeID)
+ return true;
+
+ if (shapeInfo->ID == FORM_TRAVEL_FORM || shapeInfo->ID == FORM_AQUATIC_FORM)
+ return true;
+ }
+
+ return false;
+ }();
+
+ if (onlyTravelShapeshiftForm && !isTravelShapeshiftForm)
+ return;
+
+ AuraEffectVector shapeshifts = CopyAuraEffectList(GetAuraEffectsByType(SPELL_AURA_MOD_SHAPESHIFT));
+ for (AuraEffect* aurEff : shapeshifts)
+ {
+ SpellInfo const* spellInfo = aurEff->GetBase()->GetSpellInfo();
+ if (force || (!spellInfo->HasAttribute(SPELL_ATTR0_NO_AURA_CANCEL) && spellInfo->IsPositive() && !spellInfo->IsPassive()))
+ aurEff->GetBase()->Remove(removeMode);
+ }
+}
+
bool Unit::IsInFeralForm() const
{
ShapeshiftForm form = GetShapeshiftForm();
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 6b82216c0c8..be913cbda5b 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -901,6 +901,7 @@ class TC_GAME_API Unit : public WorldObject
void SetMountDisplayId(uint32 mountDisplayId) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::MountDisplayID), mountDisplayId); }
void Mount(uint32 mount, uint32 vehicleId = 0, uint32 creatureEntry = 0);
void Dismount();
+ void CancelMountAura(bool force = false);
MountCapabilityEntry const* GetMountCapability(uint32 mountType) const;
void UpdateMountCapability();
@@ -1469,6 +1470,8 @@ class TC_GAME_API Unit : public WorldObject
ShapeshiftForm GetShapeshiftForm() const { return ShapeshiftForm(*m_unitData->ShapeshiftForm); }
void SetShapeshiftForm(ShapeshiftForm form);
+ void CancelShapeshiftForm(bool onlyTravelShapeshiftForm = false, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT, bool force = false);
+ void CancelTravelShapeshiftForm(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT, bool force = false) { CancelShapeshiftForm(true, removeMode, force); };
bool IsInFeralForm() const;