diff options
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.h | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 43 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 7 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 31 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 7 |
6 files changed, 34 insertions, 62 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index a530c580be8..ae18e8422d9 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -796,8 +796,8 @@ void MovementInfo::OutDebug() WorldObject::WorldObject(bool isWorldObject) : Object(), WorldLocation(), LastUsedScriptID(0), m_movementInfo(), m_name(), m_isActive(false), m_isFarVisible(false), m_isWorldObject(isWorldObject), m_zoneScript(nullptr), -m_transport(nullptr), m_zoneId(0), m_areaId(0), m_staticFloorZ(VMAP_INVALID_HEIGHT), m_outdoors(false), m_currMap(nullptr), m_InstanceId(0), -_dbPhase(0), m_notifyflags(0) +m_transport(nullptr), m_zoneId(0), m_areaId(0), m_staticFloorZ(VMAP_INVALID_HEIGHT), m_outdoors(false), m_liquidStatus(LIQUID_MAP_NO_WATER), +m_currMap(nullptr), m_InstanceId(0), _dbPhase(0), m_notifyflags(0) { m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE | GHOST_VISIBILITY_GHOST); m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE); @@ -896,6 +896,7 @@ void WorldObject::ProcessPositionDataChanged(PositionFullTerrainStatus const& da m_zoneId = area->ParentAreaID; m_outdoors = data.outdoors; m_staticFloorZ = data.floorZ; + m_liquidStatus = data.liquidStatus; } void WorldObject::AddToWorld() diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 0d7e237e937..5af44a47e69 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -63,6 +63,7 @@ class ZoneScript; struct FactionTemplateEntry; struct PositionFullTerrainStatus; struct QuaternionData; +enum ZLiquidStatus : uint32; namespace WorldPackets { @@ -486,6 +487,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation uint32 GetAreaId() const { return m_areaId; } void GetZoneAndAreaId(uint32& zoneid, uint32& areaid) const { zoneid = m_zoneId, areaid = m_areaId; } bool IsOutdoors() const { return m_outdoors; } + ZLiquidStatus GetLiquidStatus() const { return m_liquidStatus; } bool IsInWorldPvpZone() const; InstanceScript* GetInstanceScript() const; @@ -733,6 +735,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation uint32 m_areaId; float m_staticFloorZ; bool m_outdoors; + ZLiquidStatus m_liquidStatus; //these functions are used mostly for Relocate() and Corpse/Player specific stuff... //use them ONLY in LoadFromDB()/Create() funcs and nowhere else! diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index b6d79ccccb1..baf02061bd4 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -217,7 +217,6 @@ Player::Player(WorldSession* session) : Unit(true), m_sceneMgr(this) m_MirrorTimerFlags = UNDERWATER_NONE; m_MirrorTimerFlagsLast = UNDERWATER_NONE; - m_isInWater = false; m_hostileReferenceCheckTimer = 0; m_drunkTimer = 0; m_deathTimer = 0; @@ -2084,28 +2083,6 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid const& guid, Gameo return go; } -bool Player::IsUnderWater() const -{ - return IsInWater() && - GetPositionZ() < (GetMap()->GetWaterLevel(GetPhaseShift(), GetPositionX(), GetPositionY()) - 2); -} - -void Player::SetInWater(bool inWater) -{ - if (m_isInWater == inWater) - return; - - //define player in water by opcodes - //move player's guid into HateOfflineList of those mobs - //which can't swim and move guid back into ThreatList when - //on surface. - /// @todo exist also swimming mobs, and function must be symmetric to enter/leave water - m_isInWater = inWater; - - // Call base - Unit::SetInWater(inWater); -} - bool Player::IsInAreaTriggerRadius(AreaTriggerEntry const* trigger) const { if (!trigger) @@ -26108,42 +26085,42 @@ int32 Player::NextGroupUpdateSequenceNumber(GroupCategory category) return m_groupUpdateSequences[category].UpdateSequenceNumber++; } -void Player::ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional<LiquidData> const& liquidData) +void Player::ProcessTerrainStatusUpdate(ZLiquidStatus oldLiquidStatus, Optional<LiquidData> const& newLiquidData) { // process liquid auras using generic unit code - Unit::ProcessTerrainStatusUpdate(status, liquidData); + Unit::ProcessTerrainStatusUpdate(oldLiquidStatus, newLiquidData); // player specific logic for mirror timers - if (status && liquidData) + if (GetLiquidStatus() && newLiquidData) { // Breath bar state (under water in any liquid type) - if (liquidData->type_flags.HasFlag(map_liquidHeaderTypeFlags::AllLiquids)) + if (newLiquidData->type_flags.HasFlag(map_liquidHeaderTypeFlags::AllLiquids)) { - if (status & LIQUID_MAP_UNDER_WATER) + if (GetLiquidStatus() & LIQUID_MAP_UNDER_WATER) m_MirrorTimerFlags |= UNDERWATER_INWATER; else m_MirrorTimerFlags &= ~UNDERWATER_INWATER; } // Fatigue bar state (if not on flight path or transport) - if (liquidData->type_flags.HasFlag(map_liquidHeaderTypeFlags::DarkWater) && !IsInFlight() && !GetTransport()) + if (newLiquidData->type_flags.HasFlag(map_liquidHeaderTypeFlags::DarkWater) && !IsInFlight() && !GetTransport()) m_MirrorTimerFlags |= UNDERWATER_INDARKWATER; else m_MirrorTimerFlags &= ~UNDERWATER_INDARKWATER; // Lava state (any contact) - if (liquidData->type_flags.HasFlag(map_liquidHeaderTypeFlags::Magma)) + if (newLiquidData->type_flags.HasFlag(map_liquidHeaderTypeFlags::Magma)) { - if (status & MAP_LIQUID_STATUS_IN_CONTACT) + if (GetLiquidStatus() & MAP_LIQUID_STATUS_IN_CONTACT) m_MirrorTimerFlags |= UNDERWATER_INLAVA; else m_MirrorTimerFlags &= ~UNDERWATER_INLAVA; } // Slime state (any contact) - if (liquidData->type_flags.HasFlag(map_liquidHeaderTypeFlags::Slime)) + if (newLiquidData->type_flags.HasFlag(map_liquidHeaderTypeFlags::Slime)) { - if (status & MAP_LIQUID_STATUS_IN_CONTACT) + if (GetLiquidStatus() & MAP_LIQUID_STATUS_IN_CONTACT) m_MirrorTimerFlags |= UNDERWATER_INSLIME; else m_MirrorTimerFlags &= ~UNDERWATER_INSLIME; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 5c892d33e73..c58e6420e9c 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1124,10 +1124,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, SpellEffectInfo const& spellEffectInfo, WorldObject const* caster) const override; - void SetInWater(bool inWater) override; - - bool IsInWater() const override { return m_isInWater; } - bool IsUnderWater() const override; bool IsInAreaTriggerRadius(AreaTriggerEntry const* trigger) const; void SendInitialPacketsBeforeAddToMap(); @@ -2077,7 +2073,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> bool UpdatePosition(float x, float y, float z, float orientation, bool teleport = false) override; bool UpdatePosition(Position const& pos, bool teleport = false) override { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); } - void ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional<LiquidData> const& liquidData) override; + void ProcessTerrainStatusUpdate(ZLiquidStatus oldLiquidStatus, Optional<LiquidData> const& newLiquidData) override; void AtEnterCombat() override; void AtExitCombat() override; @@ -3058,7 +3054,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> int32 m_MirrorTimer[MAX_TIMERS]; uint8 m_MirrorTimerFlags; uint8 m_MirrorTimerFlagsLast; - bool m_isInWater; // Current teleport data WorldLocation m_teleport_dest; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index e10a7f333d5..377fe90c0f3 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -2999,40 +2999,36 @@ bool Unit::isInAccessiblePlaceFor(Creature const* c) const bool Unit::IsInWater() const { - return GetMap()->IsInWater(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ()); + return GetLiquidStatus() & (LIQUID_MAP_IN_WATER | LIQUID_MAP_UNDER_WATER); } bool Unit::IsUnderWater() const { - return GetMap()->IsUnderWater(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ()); + return GetLiquidStatus() & LIQUID_MAP_UNDER_WATER; } void Unit::ProcessPositionDataChanged(PositionFullTerrainStatus const& data) { + ZLiquidStatus oldLiquidStatus = GetLiquidStatus(); WorldObject::ProcessPositionDataChanged(data); - ProcessTerrainStatusUpdate(data.liquidStatus, data.liquidInfo); + ProcessTerrainStatusUpdate(oldLiquidStatus, data.liquidInfo); } -void Unit::SetInWater(bool inWater) +void Unit::ProcessTerrainStatusUpdate(ZLiquidStatus oldLiquidStatus, Optional<LiquidData> const& newLiquidData) { + if (!IsControlledByPlayer()) + return; + // remove appropriate auras if we are swimming/not swimming respectively - if (inWater) + if (IsInWater()) RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::UnderWater); else RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::AboveWater); -} - -void Unit::ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional<LiquidData> const& liquidData) -{ - if (!IsControlledByPlayer()) - return; - - SetInWater(status & MAP_LIQUID_STATUS_SWIMMING); // liquid aura handling LiquidTypeEntry const* curLiquid = nullptr; - if ((status & MAP_LIQUID_STATUS_SWIMMING) && liquidData) - curLiquid = sLiquidTypeStore.LookupEntry(liquidData->entry); + if (IsInWater() && newLiquidData) + curLiquid = sLiquidTypeStore.LookupEntry(newLiquidData->entry); if (curLiquid != _lastLiquid) { if (_lastLiquid && _lastLiquid->SpellID) @@ -3044,10 +3040,11 @@ void Unit::ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional<LiquidData> if (curLiquid && curLiquid->SpellID && (!player || !player->IsGameMaster())) CastSpell(this, curLiquid->SpellID, true); + } - // mount capability depends on liquid state change + // mount capability depends on liquid state change + if (oldLiquidStatus != GetLiquidStatus()) UpdateMountCapability(); - } } void Unit::DeMorph() diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index f85f43731e7..320d62804b9 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1156,8 +1156,8 @@ class TC_GAME_API Unit : public WorldObject bool isTargetableForAttack(bool checkFakeDeath = true) const; - virtual bool IsInWater() const; - virtual bool IsUnderWater() const; + bool IsInWater() const; + bool IsUnderWater() const; bool isInAccessiblePlaceFor(Creature const* c) const; void SendHealSpellLog(HealInfo& healInfo, bool critical = false); @@ -1945,8 +1945,7 @@ class TC_GAME_API Unit : public WorldObject void DisableSpline(); void ProcessPositionDataChanged(PositionFullTerrainStatus const& data) override; - virtual void ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional<LiquidData> const& liquidData); - virtual void SetInWater(bool inWater); + virtual void ProcessTerrainStatusUpdate(ZLiquidStatus oldLiquidStatus, Optional<LiquidData> const& newLiquidData); // notifiers virtual void AtEnterCombat(); |