diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 6afa283771..e2165e2b25 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3213,8 +3213,13 @@ bool Unit::IsUnderWater() const void Unit::ProcessPositionDataChanged(PositionFullTerrainStatus const& data) { + ZLiquidStatus oldLiquidStats = m_liquidStatus; + WorldObject::ProcessPositionDataChanged(data); ProcessTerrainStatusUpdate(data.liquidStatus, data.liquidInfo); + + if (oldLiquidStats != m_liquidStatus) + UpdateMountCapability(); } void Unit::ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional const& liquidData) @@ -3243,9 +3248,6 @@ void Unit::ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional if (curLiquid && curLiquid->SpellID && (!player || !player->IsGameMaster())) CastSpell(this, curLiquid->SpellID, true); - - // mount capability depends on liquid state change - UpdateMountCapability(); } } void Unit::DeMorph() @@ -8293,7 +8295,7 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const uint32 areaId = GetAreaId(); uint32 ridingSkill = 5000; uint32 mountFlags = 0; - bool isSubmerged = false; + bool isUnderwater = false; bool isInWater = false; if (GetTypeId() == TYPEID_PLAYER) @@ -8308,7 +8310,7 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const mountFlags = areaTable->MountFlags; ZLiquidStatus liquidStatus = GetLiquidStatus(); - isSubmerged = (liquidStatus & LIQUID_MAP_UNDER_WATER) != 0 || HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING); + isUnderwater = (liquidStatus & LIQUID_MAP_UNDER_WATER) != 0; isInWater = (liquidStatus & LIQUID_MAP_IN_WATER) != 0; for (uint32 i = MAX_MOUNT_CAPABILITIES; i > 0; --i) @@ -8332,24 +8334,16 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const continue; } + // Do not allow underwater restricted capabilities when not underwater + if (!(mountCapability->Flags & MOUNT_CAPABILITY_FLAG_UNDERWATER) && isUnderwater) + continue; - if (!isSubmerged) - { - if (!isInWater) - { - // player is completely out of water - if (!(mountCapability->Flags & MOUNT_CAPABILITY_FLAG_GROUND)) - continue; - } - else if (!(mountCapability->Flags & MOUNT_CAPABILITY_FLAG_UNDERWATER)) - continue; - } - else if (isInWater) - { - if (!(mountCapability->Flags & MOUNT_CAPABILITY_FLAG_UNDERWATER)) - continue; - } - else if (!(mountCapability->Flags & MOUNT_CAPABILITY_FLAG_FLOAT)) + // Do not allow water surface restricted capabilities when not on water surface + if (!(mountCapability->Flags & MOUNT_CAPABILITY_FLAG_FLOAT) && isInWater) + continue; + + // Do not allow liquid restricted mounts on ground or in air + if (!(mountCapability->Flags & (MOUNT_CAPABILITY_FLAG_GROUND | MOUNT_CAPABILITY_FLAG_FLYING)) && !isUnderwater && !isInWater) continue; if (mountCapability->ReqMapID != -1 && diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 4ad8825e08..5c7c1335c8 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -484,7 +484,7 @@ void AuraEffect::SetAmount(int32 amount) m_amount = amount; m_canBeRecalculated = false; - if (GetSpellInfo()->HasAttribute(SPELL_ATTR8_AURA_SEND_AMOUNT)) + if (GetSpellInfo()->HasAttribute(SPELL_ATTR8_AURA_SEND_AMOUNT) || Aura::EffectTypeNeedsSendingAmount(GetAuraType())) GetBase()->SetNeedClientUpdateForTargets(); } @@ -564,10 +564,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster) break; case SPELL_AURA_MOUNTED: if (MountCapabilityEntry const* mountCapability = GetBase()->GetUnitOwner()->GetMountCapability(uint32(GetMiscValueB()))) - { amount = mountCapability->ID; - m_canBeRecalculated = true; - } break; case SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE: { @@ -743,6 +740,9 @@ void AuraEffect::ChangeAmount(int32 newAmount, bool mark, bool onStackOrReapply) aurApp->GetTarget()->_RegisterAuraEffect(this, true); HandleEffect(aurApp, handleMask, true); } + + if (GetSpellInfo()->HasAttribute(SPELL_ATTR8_AURA_SEND_AMOUNT) || Aura::EffectTypeNeedsSendingAmount(GetAuraType())) + GetBase()->SetNeedClientUpdateForTargets(); } void AuraEffect::HandleEffect(AuraApplication * aurApp, uint8 mode, bool apply) diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index bd5659f0db..859cb8e4e5 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1132,6 +1132,21 @@ bool Aura::HasEffectType(AuraType type) const return false; } +bool Aura::EffectTypeNeedsSendingAmount(AuraType type) +{ + switch (type) + { + case SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS: + case SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_TRIGGERED: + case SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN: + return true; + default: + break; + } + + return false; +} + void Aura::RecalculateAmountOfEffects() { ASSERT (!IsRemoved()); diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 9904cc4a30..37f6796cd5 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -187,6 +187,7 @@ class TC_GAME_API Aura // helpers for aura effects bool HasEffect(uint8 effIndex) const { return GetEffect(effIndex) != nullptr; } bool HasEffectType(AuraType type) const; + static bool EffectTypeNeedsSendingAmount(AuraType type); AuraEffect* GetEffect(uint8 effIndex) const { ASSERT (effIndex < MAX_SPELL_EFFECTS); return m_effects[effIndex]; } uint8 GetEffectMask() const { uint8 effMask = 0; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (m_effects[i]) effMask |= 1<