Core/Movement: Get zone/area IDs from vmap data in the liquid update

Port From (https://github.com/TrinityCore/TrinityCore/commit/51ce3b1c1dc6a53938ed6f240bac00681d18a44f)
This commit is contained in:
hondacrx
2020-07-23 18:22:46 -04:00
parent db44970987
commit 286a200178
10 changed files with 325 additions and 137 deletions
+1 -1
View File
@@ -2688,7 +2688,7 @@ namespace Game.Entities
return;
// Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
float ground = GetMap().GetHeight(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZMinusOffset());
float ground = GetFloorZ();
bool isInAir = (MathFunctions.fuzzyGt(GetPositionZMinusOffset(), ground + 0.05f) || MathFunctions.fuzzyLt(GetPositionZMinusOffset(), ground - 0.05f)); // Can be underground too, prevent the falling
+40 -15
View File
@@ -26,6 +26,7 @@ using Game.Networking.Packets;
using Game.Scenarios;
using System;
using System.Collections.Generic;
using Game.DataStorage;
namespace Game.Entities
{
@@ -48,6 +49,8 @@ namespace Game.Entities
m_updateFlag.Clear();
m_objectData = new ObjectFieldData();
m_staticFloorZ = MapConst.VMAPInvalidHeightValue;
}
public virtual void Dispose()
@@ -91,6 +94,8 @@ namespace Game.Entities
IsInWorld = true;
ClearUpdateMask(true);
GetMap().GetZoneAndAreaId(_phaseShift, out m_zoneId, out m_areaId, GetPositionX(), GetPositionY(), GetPositionZ());
}
public virtual void RemoveFromWorld()
@@ -105,6 +110,25 @@ namespace Game.Entities
ClearUpdateMask(true);
}
public void UpdatePositionData()
{
PositionFullTerrainStatus data = new PositionFullTerrainStatus();
GetMap().GetFullTerrainStatusForPosition(_phaseShift, GetPositionX(), GetPositionY(), GetPositionZ(), data);
ProcessPositionDataChanged(data);
}
public virtual void ProcessPositionDataChanged(PositionFullTerrainStatus data)
{
m_zoneId = m_areaId = data.AreaId;
var area = CliDB.AreaTableStorage.LookupByKey(m_areaId);
if (area != null)
if (area.Id != 0)
m_zoneId = area.Id;
m_staticFloorZ = data.FloorZ;
}
public virtual void BuildCreateUpdateBlockForPlayer(UpdateData data, Player target)
{
if (!target)
@@ -990,22 +1014,12 @@ namespace Game.Entities
if (transport)
transport.RemovePassenger(this);
}
public uint GetZoneId() { return m_zoneId; }
public uint GetAreaId() { return m_areaId; }
public uint GetZoneId()
{
return GetMap().GetZoneId(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ());
}
public uint GetAreaId()
{
return GetMap().GetAreaId(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ());
}
public void GetZoneAndAreaId(out uint zoneid, out uint areaid)
{
GetMap().GetZoneAndAreaId(GetPhaseShift(), out zoneid, out areaid, posX, posY, posZ);
}
public void GetZoneAndAreaId(out uint zoneid, out uint areaid) { zoneid = m_zoneId; areaid = m_areaId; }
public bool IsInWorldPvpZone()
{
switch (GetZoneId())
@@ -2306,6 +2320,13 @@ namespace Game.Entities
pos.SetOrientation(GetOrientation());
}
public float GetFloorZ()
{
if (!IsInWorld)
return m_staticFloorZ;
return Math.Max(m_staticFloorZ, GetMap().GetGameObjectFloor(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ()));
}
public void SetLocationInstanceId(uint _instanceId) { instanceId = _instanceId; }
#region Fields
@@ -2321,6 +2342,10 @@ namespace Game.Entities
bool m_objectUpdated;
uint m_zoneId;
uint m_areaId;
float m_staticFloorZ;
public MovementInfo m_movementInfo;
string _name;
protected bool m_isActive;
+37 -61
View File
@@ -24,6 +24,7 @@ using Game.Maps;
using Game.Networking.Packets;
using System;
using System.Collections.Generic;
using Framework.Dynamic;
namespace Game.Entities
{
@@ -712,77 +713,52 @@ namespace Game.Entities
SendPacket(raidInstanceMessage);
}
public override void UpdateUnderwaterState(Map m, float x, float y, float z)
public override void ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional<LiquidData> liquidData)
{
LiquidData liquid_status;
ZLiquidStatus res = m.GetLiquidStatus(GetPhaseShift(), x, y, z, MapConst.MapAllLiquidTypes, out liquid_status);
if (res == 0)
{
m_MirrorTimerFlags &= ~(PlayerUnderwaterState.InWater | PlayerUnderwaterState.InLava | PlayerUnderwaterState.InSlime | PlayerUnderwaterState.InDarkWater);
if (_lastLiquid != null && _lastLiquid.SpellID != 0)
RemoveAurasDueToSpell(_lastLiquid.SpellID);
_lastLiquid = null;
if (IsFlying())
return;
}
uint liqEntry = liquid_status.entry;
if (liqEntry != 0)
{
LiquidTypeRecord liquid = CliDB.LiquidTypeStorage.LookupByKey(liqEntry);
if (_lastLiquid != null && _lastLiquid.SpellID != 0 && _lastLiquid != liquid)
RemoveAurasDueToSpell(_lastLiquid.SpellID);
if (liquid != null && liquid.SpellID != 0)
// process liquid auras using generic unit code
base.ProcessTerrainStatusUpdate(status, liquidData);
// player specific logic for mirror timers
if (status != 0 && liquidData.HasValue)
{
// Breath bar state (under water in any liquid type)
if (liquidData.Value.type_flags.HasAnyFlag(MapConst.MapAllLiquidTypes))
{
if (res.HasAnyFlag(ZLiquidStatus.UnderWater | ZLiquidStatus.InWater))
{
if (!HasAura(liquid.SpellID))
CastSpell(this, liquid.SpellID, true);
}
if (status.HasAnyFlag(ZLiquidStatus.UnderWater))
m_MirrorTimerFlags |= PlayerUnderwaterState.InWater;
else
RemoveAurasDueToSpell(liquid.SpellID);
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InWater;
}
_lastLiquid = liquid;
}
else if (_lastLiquid != null && _lastLiquid.SpellID != 0)
{
RemoveAurasDueToSpell(_lastLiquid.SpellID);
_lastLiquid = null;
}
// All liquids type - check under water position
if (liquid_status.type_flags.HasAnyFlag<uint>(MapConst.MapLiquidTypeWater | MapConst.MapLiquidTypeOcean | MapConst.MapLiquidTypeMagma | MapConst.MapLiquidTypeSlime))
{
if (res.HasAnyFlag(ZLiquidStatus.UnderWater))
m_MirrorTimerFlags |= PlayerUnderwaterState.InWater;
// Fatigue bar state (if not on flight path or transport)
if (liquidData.Value.type_flags.HasAnyFlag(MapConst.MapLiquidTypeDarkWater) && !IsInFlight() && !GetTransport())
m_MirrorTimerFlags |= PlayerUnderwaterState.InDarkWater;
else
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InWater;
}
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InDarkWater;
// Allow travel in dark water on taxi or transport
if (liquid_status.type_flags.HasAnyFlag<uint>(MapConst.MapLiquidTypeDarkWater) && !IsInFlight() && GetTransport() == null)
m_MirrorTimerFlags |= PlayerUnderwaterState.InDarkWater;
// Lava state (any contact)
if (liquidData.Value.type_flags.HasAnyFlag(MapConst.MapLiquidTypeMagma))
{
if (status.HasAnyFlag(ZLiquidStatus.InContact))
m_MirrorTimerFlags |= PlayerUnderwaterState.InLava;
else
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InLava;
}
// Slime state (any contact)
if (liquidData.Value.type_flags.HasAnyFlag(MapConst.MapLiquidTypeSlime))
{
if (status.HasAnyFlag(ZLiquidStatus.InContact))
m_MirrorTimerFlags |= PlayerUnderwaterState.InSlime;
else
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InSlime;
}
}
else
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InDarkWater;
// in lava check, anywhere in lava level
if (liquid_status.type_flags.HasAnyFlag<uint>(MapConst.MapLiquidTypeMagma))
{
if (res.HasAnyFlag(ZLiquidStatus.UnderWater | ZLiquidStatus.InWater | ZLiquidStatus.WaterWalk))
m_MirrorTimerFlags |= PlayerUnderwaterState.InLava;
else
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InLava;
}
// in slime check, anywhere in slime level
if (liquid_status.type_flags.HasAnyFlag<uint>(MapConst.MapLiquidTypeSlime))
{
if (res.HasAnyFlag(ZLiquidStatus.UnderWater | ZLiquidStatus.InWater | ZLiquidStatus.WaterWalk))
m_MirrorTimerFlags |= PlayerUnderwaterState.InSlime;
else
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InSlime;
}
m_MirrorTimerFlags &= ~(PlayerUnderwaterState.InWater | PlayerUnderwaterState.InLava | PlayerUnderwaterState.InSlime | PlayerUnderwaterState.InDarkWater);
}
}
}
+24 -38
View File
@@ -25,6 +25,7 @@ using Game.Networking.Packets;
using System;
using System.Collections.Generic;
using Game.Spells;
using Framework.Dynamic;
namespace Game.Entities
{
@@ -569,8 +570,7 @@ namespace Game.Entities
else if (turn)
UpdateOrientation(orientation);
// code block for underwater state update
UpdateUnderwaterState(GetMap(), x, y, z);
UpdatePositionData();
return (relocated || turn);
}
@@ -754,48 +754,34 @@ namespace Game.Entities
return null;
}
public virtual void UpdateUnderwaterState(Map m, float x, float y, float z)
public override void ProcessPositionDataChanged(PositionFullTerrainStatus data)
{
if (IsFlying() || (!IsPet() && !IsVehicle()))
base.ProcessPositionDataChanged(data);
ProcessTerrainStatusUpdate(data.LiquidStatus, data.LiquidInfo);
}
public virtual void ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional<LiquidData> liquidData)
{
if (IsFlying() || !IsControlledByPlayer())
return;
LiquidData liquid_status;
ZLiquidStatus res = m.GetLiquidStatus(GetPhaseShift(), x, y, z, MapConst.MapAllLiquidTypes, out liquid_status);
if (res == 0)
// remove appropriate auras if we are swimming/not swimming respectively
if (status.HasAnyFlag(ZLiquidStatus.Swimming))
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.NotAbovewater);
else
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.NotUnderwater);
// liquid aura handling
LiquidTypeRecord curLiquid = null;
if (status.HasAnyFlag(ZLiquidStatus.Swimming) && liquidData.HasValue)
curLiquid = CliDB.LiquidTypeStorage.LookupByKey(liquidData.Value.entry);
if (curLiquid != _lastLiquid)
{
if (_lastLiquid != null && _lastLiquid.SpellID != 0)
RemoveAurasDueToSpell(_lastLiquid.SpellID);
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.NotUnderwater);
_lastLiquid = null;
return;
}
uint liqEntry = liquid_status.entry;
if (liqEntry != 0)
{
LiquidTypeRecord liquid = CliDB.LiquidTypeStorage.LookupByKey(liqEntry);
if (_lastLiquid != null && _lastLiquid.SpellID != 0 && _lastLiquid.Id != liqEntry)
RemoveAurasDueToSpell(_lastLiquid.SpellID);
if (liquid != null && liquid.SpellID != 0)
{
if (res.HasAnyFlag(ZLiquidStatus.UnderWater | ZLiquidStatus.InWater))
{
if (!HasAura(liquid.SpellID))
CastSpell(this, liquid.SpellID, true);
}
else
RemoveAurasDueToSpell(liquid.SpellID);
}
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.NotAbovewater);
_lastLiquid = liquid;
}
else if (_lastLiquid != null && _lastLiquid.SpellID != 0)
{
RemoveAurasDueToSpell(_lastLiquid.SpellID);
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.NotUnderwater);
_lastLiquid = null;
if (curLiquid != null && curLiquid.SpellID != 0)
CastSpell(this, curLiquid.SpellID, true);
_lastLiquid = curLiquid;
}
}
-1
View File
@@ -191,7 +191,6 @@ namespace Game.Entities
UpdateSplineMovement(diff);
GetMotionMaster().UpdateMotion(diff);
UpdateUnderwaterState(GetMap(), GetPositionX(), GetPositionY(), GetPositionZ());
}
void _UpdateSpells(uint diff)
{