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)
This commit is contained in:
hondacrx
2022-02-17 16:55:41 -05:00
parent abf34c53b4
commit 5bd2878a4e
5 changed files with 32 additions and 56 deletions
@@ -131,6 +131,7 @@ namespace Game.Entities
m_outdoors = data.outdoors; m_outdoors = data.outdoors;
m_staticFloorZ = data.FloorZ; m_staticFloorZ = data.FloorZ;
m_liquidStatus = data.LiquidStatus;
} }
public virtual void BuildCreateUpdateBlockForPlayer(UpdateData data, Player target) public virtual void BuildCreateUpdateBlockForPlayer(UpdateData data, Player target)
@@ -979,6 +980,8 @@ namespace Game.Entities
public bool IsOutdoors() { return m_outdoors; } public bool IsOutdoors() { return m_outdoors; }
public ZLiquidStatus GetLiquidStatus() { return m_liquidStatus; }
public bool IsInWorldPvpZone() public bool IsInWorldPvpZone()
{ {
switch (GetZoneId()) switch (GetZoneId())
@@ -3528,6 +3531,7 @@ namespace Game.Entities
uint m_areaId; uint m_areaId;
float m_staticFloorZ; float m_staticFloorZ;
bool m_outdoors; bool m_outdoors;
ZLiquidStatus m_liquidStatus;
// Event handler // Event handler
public EventSystem m_Events = new(); public EventSystem m_Events = new();
@@ -104,7 +104,6 @@ namespace Game.Entities
PlayerUnderwaterState m_MirrorTimerFlags; PlayerUnderwaterState m_MirrorTimerFlags;
PlayerUnderwaterState m_MirrorTimerFlagsLast; PlayerUnderwaterState m_MirrorTimerFlagsLast;
bool m_isInWater;
//Stats //Stats
uint m_baseSpellPower; uint m_baseSpellPower;
+10 -10
View File
@@ -787,42 +787,42 @@ namespace Game.Entities
SendPacket(raidInstanceMessage); SendPacket(raidInstanceMessage);
} }
public override void ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional<LiquidData> liquidData) public override void ProcessTerrainStatusUpdate(ZLiquidStatus oldLiquidStatus, Optional<LiquidData> newLiquidData)
{ {
// process liquid auras using generic unit code // process liquid auras using generic unit code
base.ProcessTerrainStatusUpdate(status, liquidData); base.ProcessTerrainStatusUpdate(oldLiquidStatus, newLiquidData);
// player specific logic for mirror timers // 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) // 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; m_MirrorTimerFlags |= PlayerUnderwaterState.InWater;
else else
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InWater; m_MirrorTimerFlags &= ~PlayerUnderwaterState.InWater;
} }
// Fatigue bar state (if not on flight path or transport) // 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; m_MirrorTimerFlags |= PlayerUnderwaterState.InDarkWater;
else else
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InDarkWater; m_MirrorTimerFlags &= ~PlayerUnderwaterState.InDarkWater;
// Lava state (any contact) // 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; m_MirrorTimerFlags |= PlayerUnderwaterState.InLava;
else else
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InLava; m_MirrorTimerFlags &= ~PlayerUnderwaterState.InLava;
} }
// Slime state (any contact) // 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; m_MirrorTimerFlags |= PlayerUnderwaterState.InSlime;
else else
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InSlime; m_MirrorTimerFlags &= ~PlayerUnderwaterState.InSlime;
-24
View File
@@ -1914,30 +1914,6 @@ namespace Game.Entities
return startLevel; 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) public void ValidateMovementInfo(MovementInfo mi)
{ {
var RemoveViolatingFlags = new Action<bool, MovementFlag>((check, maskToRemove) => var RemoveViolatingFlags = new Action<bool, MovementFlag>((check, maskToRemove) =>
+18 -21
View File
@@ -63,13 +63,13 @@ namespace Game.Entities
return HasUnitFlag(UnitFlags.Rename | UnitFlags.Swimming); 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(); } void PropagateSpeedChange() { GetMotionMaster().PropagateSpeedChange(); }
@@ -820,30 +820,26 @@ namespace Game.Entities
public override void ProcessPositionDataChanged(PositionFullTerrainStatus data) public override void ProcessPositionDataChanged(PositionFullTerrainStatus data)
{ {
ZLiquidStatus oldLiquidStatus = GetLiquidStatus();
base.ProcessPositionDataChanged(data); base.ProcessPositionDataChanged(data);
ProcessTerrainStatusUpdate(data.LiquidStatus, data.LiquidInfo); ProcessTerrainStatusUpdate(oldLiquidStatus, data.LiquidInfo);
} }
public virtual void SetInWater(bool inWater) public virtual void ProcessTerrainStatusUpdate(ZLiquidStatus oldLiquidStatus, Optional<LiquidData> newLiquidData)
{
// 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> liquidData)
{ {
if (!IsControlledByPlayer()) if (!IsControlledByPlayer())
return; 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 // liquid aura handling
LiquidTypeRecord curLiquid = null; LiquidTypeRecord curLiquid = null;
if (status.HasAnyFlag(ZLiquidStatus.Swimming) && liquidData.HasValue) if (IsInWater() && newLiquidData.HasValue)
curLiquid = CliDB.LiquidTypeStorage.LookupByKey(liquidData.Value.entry); curLiquid = CliDB.LiquidTypeStorage.LookupByKey(newLiquidData.Value.entry);
if (curLiquid != _lastLiquid) if (curLiquid != _lastLiquid)
{ {
if (_lastLiquid != null && _lastLiquid.SpellID != 0) if (_lastLiquid != null && _lastLiquid.SpellID != 0)
@@ -856,10 +852,11 @@ namespace Game.Entities
if (curLiquid != null && curLiquid.SpellID != 0 && (!player || !player.IsGameMaster())) if (curLiquid != null && curLiquid.SpellID != 0 && (!player || !player.IsGameMaster()))
CastSpell(this, curLiquid.SpellID, true); 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) public bool SetWalk(bool enable)