From 5bd2878a4e5acfe38529e4c622d66cd79ad84b5c Mon Sep 17 00:00:00 2001 From: hondacrx Date: Thu, 17 Feb 2022 16:55:41 -0500 Subject: [PATCH] Core/Objects: cache current liquid status of objects when updating position data and use it to replace unnecessary vmap lookups Port From (https://github.com/TrinityCore/TrinityCore/commit/d18d2b84f2c3e6e1005316625da80c99dd414bcc) --- Source/Game/Entities/Object/WorldObject.cs | 4 ++ Source/Game/Entities/Player/Player.Fields.cs | 1 - Source/Game/Entities/Player/Player.Map.cs | 20 +++++----- Source/Game/Entities/Player/Player.cs | 24 ------------ Source/Game/Entities/Unit/Unit.Movement.cs | 39 +++++++++----------- 5 files changed, 32 insertions(+), 56 deletions(-) diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index bd5af29cb..5be5613da 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -131,6 +131,7 @@ namespace Game.Entities m_outdoors = data.outdoors; m_staticFloorZ = data.FloorZ; + m_liquidStatus = data.LiquidStatus; } public virtual void BuildCreateUpdateBlockForPlayer(UpdateData data, Player target) @@ -979,6 +980,8 @@ namespace Game.Entities public bool IsOutdoors() { return m_outdoors; } + public ZLiquidStatus GetLiquidStatus() { return m_liquidStatus; } + public bool IsInWorldPvpZone() { switch (GetZoneId()) @@ -3528,6 +3531,7 @@ namespace Game.Entities uint m_areaId; float m_staticFloorZ; bool m_outdoors; + ZLiquidStatus m_liquidStatus; // Event handler public EventSystem m_Events = new(); diff --git a/Source/Game/Entities/Player/Player.Fields.cs b/Source/Game/Entities/Player/Player.Fields.cs index f8046043f..e030decfc 100644 --- a/Source/Game/Entities/Player/Player.Fields.cs +++ b/Source/Game/Entities/Player/Player.Fields.cs @@ -104,7 +104,6 @@ namespace Game.Entities PlayerUnderwaterState m_MirrorTimerFlags; PlayerUnderwaterState m_MirrorTimerFlagsLast; - bool m_isInWater; //Stats uint m_baseSpellPower; diff --git a/Source/Game/Entities/Player/Player.Map.cs b/Source/Game/Entities/Player/Player.Map.cs index ec26686df..3f53ac0ab 100644 --- a/Source/Game/Entities/Player/Player.Map.cs +++ b/Source/Game/Entities/Player/Player.Map.cs @@ -787,42 +787,42 @@ namespace Game.Entities SendPacket(raidInstanceMessage); } - public override void ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional liquidData) + public override void ProcessTerrainStatusUpdate(ZLiquidStatus oldLiquidStatus, Optional newLiquidData) { // process liquid auras using generic unit code - base.ProcessTerrainStatusUpdate(status, liquidData); + base.ProcessTerrainStatusUpdate(oldLiquidStatus, newLiquidData); // player specific logic for mirror timers - if (status != 0 && liquidData.HasValue) + if (GetLiquidStatus() != 0 && newLiquidData.HasValue) { // Breath bar state (under water in any liquid type) - if (liquidData.Value.type_flags.HasAnyFlag(LiquidHeaderTypeFlags.AllLiquids)) + if (newLiquidData.Value.type_flags.HasAnyFlag(LiquidHeaderTypeFlags.AllLiquids)) { - if (status.HasAnyFlag(ZLiquidStatus.UnderWater)) + if (GetLiquidStatus().HasAnyFlag(ZLiquidStatus.UnderWater)) m_MirrorTimerFlags |= PlayerUnderwaterState.InWater; else m_MirrorTimerFlags &= ~PlayerUnderwaterState.InWater; } // Fatigue bar state (if not on flight path or transport) - if (liquidData.Value.type_flags.HasAnyFlag(LiquidHeaderTypeFlags.DarkWater) && !IsInFlight() && !GetTransport()) + if (newLiquidData.Value.type_flags.HasAnyFlag(LiquidHeaderTypeFlags.DarkWater) && !IsInFlight() && !GetTransport()) m_MirrorTimerFlags |= PlayerUnderwaterState.InDarkWater; else m_MirrorTimerFlags &= ~PlayerUnderwaterState.InDarkWater; // Lava state (any contact) - if (liquidData.Value.type_flags.HasAnyFlag(LiquidHeaderTypeFlags.Magma)) + if (newLiquidData.Value.type_flags.HasAnyFlag(LiquidHeaderTypeFlags.Magma)) { - if (status.HasAnyFlag(ZLiquidStatus.InContact)) + if (GetLiquidStatus().HasAnyFlag(ZLiquidStatus.InContact)) m_MirrorTimerFlags |= PlayerUnderwaterState.InLava; else m_MirrorTimerFlags &= ~PlayerUnderwaterState.InLava; } // Slime state (any contact) - if (liquidData.Value.type_flags.HasAnyFlag(LiquidHeaderTypeFlags.Slime)) + if (newLiquidData.Value.type_flags.HasAnyFlag(LiquidHeaderTypeFlags.Slime)) { - if (status.HasAnyFlag(ZLiquidStatus.InContact)) + if (GetLiquidStatus().HasAnyFlag(ZLiquidStatus.InContact)) m_MirrorTimerFlags |= PlayerUnderwaterState.InSlime; else m_MirrorTimerFlags &= ~PlayerUnderwaterState.InSlime; diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 5fc9ead12..3235aff42 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -1914,30 +1914,6 @@ namespace Game.Entities return startLevel; } - public override bool IsUnderWater() - { - return IsInWater() && - GetPositionZ() < (GetMap().GetWaterLevel(GetPhaseShift(), GetPositionX(), GetPositionY()) - 2); - } - public override bool IsInWater() - { - return m_isInWater; - } - public override void 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 - base.SetInWater(inWater); - } public void ValidateMovementInfo(MovementInfo mi) { var RemoveViolatingFlags = new Action((check, maskToRemove) => diff --git a/Source/Game/Entities/Unit/Unit.Movement.cs b/Source/Game/Entities/Unit/Unit.Movement.cs index f6fe2e64c..5a7762545 100644 --- a/Source/Game/Entities/Unit/Unit.Movement.cs +++ b/Source/Game/Entities/Unit/Unit.Movement.cs @@ -63,13 +63,13 @@ namespace Game.Entities return HasUnitFlag(UnitFlags.Rename | UnitFlags.Swimming); } - public virtual bool IsInWater() + public bool IsInWater() { - return GetMap().IsInWater(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ()); + return GetLiquidStatus().HasAnyFlag(ZLiquidStatus.InWater | ZLiquidStatus.UnderWater); } - public virtual bool IsUnderWater() + public bool IsUnderWater() { - return GetMap().IsUnderWater(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ()); + return GetLiquidStatus().HasFlag(ZLiquidStatus.UnderWater); } void PropagateSpeedChange() { GetMotionMaster().PropagateSpeedChange(); } @@ -820,30 +820,26 @@ namespace Game.Entities public override void ProcessPositionDataChanged(PositionFullTerrainStatus data) { + ZLiquidStatus oldLiquidStatus = GetLiquidStatus(); base.ProcessPositionDataChanged(data); - ProcessTerrainStatusUpdate(data.LiquidStatus, data.LiquidInfo); + ProcessTerrainStatusUpdate(oldLiquidStatus, data.LiquidInfo); } - public virtual void SetInWater(bool inWater) - { - // remove appropriate auras if we are swimming/not swimming respectively - if (inWater) - RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.UnderWater); - else - RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.AboveWater); - } - - public virtual void ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional liquidData) + public virtual void ProcessTerrainStatusUpdate(ZLiquidStatus oldLiquidStatus, Optional newLiquidData) { if (!IsControlledByPlayer()) return; - SetInWater(status.HasAnyFlag(ZLiquidStatus.Swimming)); + // remove appropriate auras if we are swimming/not swimming respectively + if (IsInWater()) + RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.UnderWater); + else + RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.AboveWater); // liquid aura handling LiquidTypeRecord curLiquid = null; - if (status.HasAnyFlag(ZLiquidStatus.Swimming) && liquidData.HasValue) - curLiquid = CliDB.LiquidTypeStorage.LookupByKey(liquidData.Value.entry); + if (IsInWater() && newLiquidData.HasValue) + curLiquid = CliDB.LiquidTypeStorage.LookupByKey(newLiquidData.Value.entry); if (curLiquid != _lastLiquid) { if (_lastLiquid != null && _lastLiquid.SpellID != 0) @@ -856,10 +852,11 @@ namespace Game.Entities if (curLiquid != null && curLiquid.SpellID != 0 && (!player || !player.IsGameMaster())) CastSpell(this, curLiquid.SpellID, true); - - // mount capability depends on liquid state change - UpdateMountCapability(); } + + // mount capability depends on liquid state change + if (oldLiquidStatus != GetLiquidStatus()) + UpdateMountCapability(); } public bool SetWalk(bool enable)