diff --git a/Source/Game/Entities/Player/Player.Spells.cs b/Source/Game/Entities/Player/Player.Spells.cs index b50644d2e..d6ae68971 100644 --- a/Source/Game/Entities/Player/Player.Spells.cs +++ b/Source/Game/Entities/Player/Player.Spells.cs @@ -2024,7 +2024,7 @@ namespace Game.Entities { // use m_zoneUpdateId for speed: UpdateArea called from UpdateZone or instead UpdateZone in both cases m_zoneUpdateId up-to-date if (pair.Value.GetSpellInfo().CheckLocation(GetMapId(), m_zoneUpdateId, newArea, this) != SpellCastResult.SpellCastOk) - RemoveOwnedAura(pair); + RemoveOwnedAura(pair, AuraRemoveMode.Interrupt); } // some auras applied at subzone enter diff --git a/Source/Game/Entities/Unit/Unit.Movement.cs b/Source/Game/Entities/Unit/Unit.Movement.cs index f80d307fa..98bf0cdcc 100644 --- a/Source/Game/Entities/Unit/Unit.Movement.cs +++ b/Source/Game/Entities/Unit/Unit.Movement.cs @@ -938,6 +938,18 @@ namespace Game.Entities return true; } + void CancelMountAura(bool force) + { + if (!HasAuraType(AuraType.Mounted)) + return; + + RemoveAurasByType(AuraType.Mounted, aurApp => + { + SpellInfo spellInfo = aurApp.GetBase().GetSpellInfo(); + return force || (!spellInfo.HasAttribute(SpellAttr0.NoAuraCancel) && spellInfo.IsPositive() && !spellInfo.IsPassive()); + }); + } + public MountCapabilityRecord GetMountCapability(uint mountType) { if (mountType == 0) @@ -1043,6 +1055,14 @@ namespace Game.Entities if (IsLoading()) return; + var spellShapeshiftForm = CliDB.SpellShapeshiftFormStorage.LookupByKey(GetShapeshiftForm()); + if (spellShapeshiftForm != null) + { + uint mountType = spellShapeshiftForm.MountTypeID; + if (mountType != 0 && GetMountCapability(mountType) == null) + CancelTravelShapeshiftForm(AuraRemoveMode.Interrupt); + } + var mounts = GetAuraEffectsByType(AuraType.Mounted); foreach (AuraEffect aurEff in mounts.ToArray()) { diff --git a/Source/Game/Entities/Unit/Unit.cs b/Source/Game/Entities/Unit/Unit.cs index 03dc9345c..6abee7f1a 100644 --- a/Source/Game/Entities/Unit/Unit.cs +++ b/Source/Game/Entities/Unit/Unit.cs @@ -1645,6 +1645,41 @@ namespace Game.Entities SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ShapeshiftForm), (byte)form); } + void CancelTravelShapeshiftForm(AuraRemoveMode removeMode = AuraRemoveMode.Default, bool force = false) { CancelShapeshiftForm(true, removeMode, force); } + + void CancelShapeshiftForm(bool onlyTravelShapeshiftForm = false, AuraRemoveMode removeMode = AuraRemoveMode.Default, bool force = false) + { + ShapeShiftForm form = GetShapeshiftForm(); + if (form == ShapeShiftForm.None) + return; + + bool isTravelShapeshiftForm() + { + var shapeInfo = CliDB.SpellShapeshiftFormStorage.LookupByKey(form); + if (shapeInfo != null) + { + if (shapeInfo.MountTypeID != 0) + return true; + + if (shapeInfo.Id == (uint)ShapeShiftForm.TravelForm || shapeInfo.Id == (uint)ShapeShiftForm.AquaticForm) + return true; + } + + return false; + } + + if (onlyTravelShapeshiftForm && !isTravelShapeshiftForm()) + return; + + var shapeshifts = GetAuraEffectsByType(AuraType.ModShapeshift); + foreach (AuraEffect aurEff in shapeshifts) + { + SpellInfo spellInfo = aurEff.GetBase().GetSpellInfo(); + if (force || (!spellInfo.HasAttribute(SpellAttr0.NoAuraCancel) && spellInfo.IsPositive() && !spellInfo.IsPassive())) + aurEff.GetBase().Remove(removeMode); + } + } + // creates aura application instance and registers it in lists // aura application effects are handled separately to prevent aura list corruption public AuraApplication _CreateAuraApplication(Aura aura, uint effMask) @@ -2873,7 +2908,8 @@ namespace Game.Entities return true; return false; - }; + } + ; bool isCastDelayed() {