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:
@@ -119,13 +119,17 @@ namespace Framework.Constants
|
|||||||
AllWorld = Player | Creature | Corpse | DynamicObject
|
AllWorld = Player | Creature | Corpse | DynamicObject
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
public enum ZLiquidStatus
|
public enum ZLiquidStatus
|
||||||
{
|
{
|
||||||
NoWater = 0x00,
|
NoWater = 0x00,
|
||||||
AboveWater = 0x01,
|
AboveWater = 0x01,
|
||||||
WaterWalk = 0x02,
|
WaterWalk = 0x02,
|
||||||
InWater = 0x04,
|
InWater = 0x04,
|
||||||
UnderWater = 0x08
|
UnderWater = 0x08,
|
||||||
|
|
||||||
|
Swimming = InWater | UnderWater,
|
||||||
|
InContact = Swimming | WaterWalk
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum EncounterFrameType
|
public enum EncounterFrameType
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ using Framework.Constants;
|
|||||||
using Framework.GameMath;
|
using Framework.GameMath;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Framework.Dynamic;
|
||||||
|
|
||||||
namespace Game.Collision
|
namespace Game.Collision
|
||||||
{
|
{
|
||||||
@@ -240,6 +241,41 @@ namespace Game.Collision
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AreaAndLiquidData GetAreaAndLiquidData(uint mapId, float x, float y, float z, uint reqLiquidType)
|
||||||
|
{
|
||||||
|
var data = new AreaAndLiquidData();
|
||||||
|
|
||||||
|
if (!Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapLiquidStatus))
|
||||||
|
{
|
||||||
|
data.floorZ = z;
|
||||||
|
int adtId, rootId, groupId;
|
||||||
|
uint flags;
|
||||||
|
if (GetAreaInfo(mapId, x, y, ref data.floorZ, out flags, out adtId, out rootId, out groupId))
|
||||||
|
data.areaInfo.Set(new AreaAndLiquidData.AreaInfo(adtId, rootId, groupId, flags));
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
|
||||||
|
if (instanceTree != null)
|
||||||
|
{
|
||||||
|
LocationInfo info = new LocationInfo();
|
||||||
|
Vector3 pos = ConvertPositionToInternalRep(x, y, z);
|
||||||
|
if (instanceTree.GetLocationInfo(pos, info))
|
||||||
|
{
|
||||||
|
data.floorZ = info.ground_Z;
|
||||||
|
uint liquidType = info.hitModel.GetLiquidType();
|
||||||
|
float liquidLevel = 0;
|
||||||
|
if (reqLiquidType == 0 || Convert.ToBoolean(Global.DB2Mgr.GetLiquidFlags(liquidType) & reqLiquidType))
|
||||||
|
if (info.hitInstance.GetLiquidLevel(pos, info, ref liquidLevel))
|
||||||
|
data.liquidInfo.Set(new AreaAndLiquidData.LiquidInfo(liquidType, liquidLevel));
|
||||||
|
|
||||||
|
if (!Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapLiquidStatus))
|
||||||
|
data.areaInfo.Set(new AreaAndLiquidData.AreaInfo(info.hitInstance.adtId, info.rootId, (int)info.hitModel.GetWmoID(), info.hitModel.GetMogpFlags()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
public WorldModel AcquireModelInstance(string filename, uint flags = 0)
|
public WorldModel AcquireModelInstance(string filename, uint flags = 0)
|
||||||
{
|
{
|
||||||
lock (LoadedModelFilesLock)
|
lock (LoadedModelFilesLock)
|
||||||
@@ -350,4 +386,38 @@ namespace Game.Collision
|
|||||||
WorldModel iModel;
|
WorldModel iModel;
|
||||||
int iRefCount;
|
int iRefCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AreaAndLiquidData
|
||||||
|
{
|
||||||
|
public struct AreaInfo
|
||||||
|
{
|
||||||
|
public int AdtId;
|
||||||
|
public int RootId;
|
||||||
|
public int GroupId;
|
||||||
|
public uint MogpFlags;
|
||||||
|
|
||||||
|
public AreaInfo(int adtId, int rootId, int groupId, uint flags)
|
||||||
|
{
|
||||||
|
AdtId = adtId;
|
||||||
|
RootId = rootId;
|
||||||
|
GroupId = groupId;
|
||||||
|
MogpFlags = flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct LiquidInfo
|
||||||
|
{
|
||||||
|
public uint LiquidType;
|
||||||
|
public float Level;
|
||||||
|
|
||||||
|
public LiquidInfo(uint type, float level)
|
||||||
|
{
|
||||||
|
LiquidType = type;
|
||||||
|
Level = level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public float floorZ = MapConst.VMAPInvalidHeightValue;
|
||||||
|
public Optional<AreaInfo> areaInfo;
|
||||||
|
public Optional<LiquidInfo> liquidInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ namespace Game.Collision
|
|||||||
ground_Z = float.NegativeInfinity;
|
ground_Z = float.NegativeInfinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int rootId;
|
||||||
public ModelInstance hitInstance;
|
public ModelInstance hitInstance;
|
||||||
public GroupModel hitModel;
|
public GroupModel hitModel;
|
||||||
public float ground_Z;
|
public float ground_Z;
|
||||||
|
|||||||
@@ -361,6 +361,7 @@ namespace Game.Collision
|
|||||||
groupTree.IntersectPoint(p, callback);
|
groupTree.IntersectPoint(p, callback);
|
||||||
if (callback.hit != null)
|
if (callback.hit != null)
|
||||||
{
|
{
|
||||||
|
info.rootId = (int)RootWMOID;
|
||||||
info.hitModel = callback.hit;
|
info.hitModel = callback.hit;
|
||||||
dist = callback.zDist;
|
dist = callback.zDist;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -2688,7 +2688,7 @@ namespace Game.Entities
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
|
// 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
|
bool isInAir = (MathFunctions.fuzzyGt(GetPositionZMinusOffset(), ground + 0.05f) || MathFunctions.fuzzyLt(GetPositionZMinusOffset(), ground - 0.05f)); // Can be underground too, prevent the falling
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ using Game.Networking.Packets;
|
|||||||
using Game.Scenarios;
|
using Game.Scenarios;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Game.DataStorage;
|
||||||
|
|
||||||
namespace Game.Entities
|
namespace Game.Entities
|
||||||
{
|
{
|
||||||
@@ -48,6 +49,8 @@ namespace Game.Entities
|
|||||||
m_updateFlag.Clear();
|
m_updateFlag.Clear();
|
||||||
|
|
||||||
m_objectData = new ObjectFieldData();
|
m_objectData = new ObjectFieldData();
|
||||||
|
|
||||||
|
m_staticFloorZ = MapConst.VMAPInvalidHeightValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Dispose()
|
public virtual void Dispose()
|
||||||
@@ -91,6 +94,8 @@ namespace Game.Entities
|
|||||||
|
|
||||||
IsInWorld = true;
|
IsInWorld = true;
|
||||||
ClearUpdateMask(true);
|
ClearUpdateMask(true);
|
||||||
|
|
||||||
|
GetMap().GetZoneAndAreaId(_phaseShift, out m_zoneId, out m_areaId, GetPositionX(), GetPositionY(), GetPositionZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void RemoveFromWorld()
|
public virtual void RemoveFromWorld()
|
||||||
@@ -105,6 +110,25 @@ namespace Game.Entities
|
|||||||
ClearUpdateMask(true);
|
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)
|
public virtual void BuildCreateUpdateBlockForPlayer(UpdateData data, Player target)
|
||||||
{
|
{
|
||||||
if (!target)
|
if (!target)
|
||||||
@@ -991,20 +1015,10 @@ namespace Game.Entities
|
|||||||
transport.RemovePassenger(this);
|
transport.RemovePassenger(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint GetZoneId()
|
public uint GetZoneId() { return m_zoneId; }
|
||||||
{
|
public uint GetAreaId() { return m_areaId; }
|
||||||
return GetMap().GetZoneId(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint GetAreaId()
|
public void GetZoneAndAreaId(out uint zoneid, out uint areaid) { zoneid = m_zoneId; areaid = m_areaId; }
|
||||||
{
|
|
||||||
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 bool IsInWorldPvpZone()
|
public bool IsInWorldPvpZone()
|
||||||
{
|
{
|
||||||
@@ -2306,6 +2320,13 @@ namespace Game.Entities
|
|||||||
pos.SetOrientation(GetOrientation());
|
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; }
|
public void SetLocationInstanceId(uint _instanceId) { instanceId = _instanceId; }
|
||||||
|
|
||||||
#region Fields
|
#region Fields
|
||||||
@@ -2321,6 +2342,10 @@ namespace Game.Entities
|
|||||||
|
|
||||||
bool m_objectUpdated;
|
bool m_objectUpdated;
|
||||||
|
|
||||||
|
uint m_zoneId;
|
||||||
|
uint m_areaId;
|
||||||
|
float m_staticFloorZ;
|
||||||
|
|
||||||
public MovementInfo m_movementInfo;
|
public MovementInfo m_movementInfo;
|
||||||
string _name;
|
string _name;
|
||||||
protected bool m_isActive;
|
protected bool m_isActive;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ using Game.Maps;
|
|||||||
using Game.Networking.Packets;
|
using Game.Networking.Packets;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Framework.Dynamic;
|
||||||
|
|
||||||
namespace Game.Entities
|
namespace Game.Entities
|
||||||
{
|
{
|
||||||
@@ -712,77 +713,52 @@ namespace Game.Entities
|
|||||||
SendPacket(raidInstanceMessage);
|
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;
|
if (IsFlying())
|
||||||
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;
|
|
||||||
return;
|
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 (status.HasAnyFlag(ZLiquidStatus.UnderWater))
|
||||||
{
|
m_MirrorTimerFlags |= PlayerUnderwaterState.InWater;
|
||||||
if (!HasAura(liquid.SpellID))
|
|
||||||
CastSpell(this, liquid.SpellID, true);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
RemoveAurasDueToSpell(liquid.SpellID);
|
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InWater;
|
||||||
}
|
}
|
||||||
|
|
||||||
_lastLiquid = liquid;
|
// Fatigue bar state (if not on flight path or transport)
|
||||||
}
|
if (liquidData.Value.type_flags.HasAnyFlag(MapConst.MapLiquidTypeDarkWater) && !IsInFlight() && !GetTransport())
|
||||||
else if (_lastLiquid != null && _lastLiquid.SpellID != 0)
|
m_MirrorTimerFlags |= PlayerUnderwaterState.InDarkWater;
|
||||||
{
|
|
||||||
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;
|
|
||||||
else
|
else
|
||||||
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InWater;
|
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InDarkWater;
|
||||||
}
|
|
||||||
|
|
||||||
// Allow travel in dark water on taxi or transport
|
// Lava state (any contact)
|
||||||
if (liquid_status.type_flags.HasAnyFlag<uint>(MapConst.MapLiquidTypeDarkWater) && !IsInFlight() && GetTransport() == null)
|
if (liquidData.Value.type_flags.HasAnyFlag(MapConst.MapLiquidTypeMagma))
|
||||||
m_MirrorTimerFlags |= PlayerUnderwaterState.InDarkWater;
|
{
|
||||||
|
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
|
else
|
||||||
m_MirrorTimerFlags &= ~PlayerUnderwaterState.InDarkWater;
|
m_MirrorTimerFlags &= ~(PlayerUnderwaterState.InWater | PlayerUnderwaterState.InLava | PlayerUnderwaterState.InSlime | 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ using Game.Networking.Packets;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Game.Spells;
|
using Game.Spells;
|
||||||
|
using Framework.Dynamic;
|
||||||
|
|
||||||
namespace Game.Entities
|
namespace Game.Entities
|
||||||
{
|
{
|
||||||
@@ -569,8 +570,7 @@ namespace Game.Entities
|
|||||||
else if (turn)
|
else if (turn)
|
||||||
UpdateOrientation(orientation);
|
UpdateOrientation(orientation);
|
||||||
|
|
||||||
// code block for underwater state update
|
UpdatePositionData();
|
||||||
UpdateUnderwaterState(GetMap(), x, y, z);
|
|
||||||
|
|
||||||
return (relocated || turn);
|
return (relocated || turn);
|
||||||
}
|
}
|
||||||
@@ -754,48 +754,34 @@ namespace Game.Entities
|
|||||||
return null;
|
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;
|
return;
|
||||||
|
|
||||||
LiquidData liquid_status;
|
// remove appropriate auras if we are swimming/not swimming respectively
|
||||||
ZLiquidStatus res = m.GetLiquidStatus(GetPhaseShift(), x, y, z, MapConst.MapAllLiquidTypes, out liquid_status);
|
if (status.HasAnyFlag(ZLiquidStatus.Swimming))
|
||||||
if (res == 0)
|
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)
|
if (_lastLiquid != null && _lastLiquid.SpellID != 0)
|
||||||
RemoveAurasDueToSpell(_lastLiquid.SpellID);
|
RemoveAurasDueToSpell(_lastLiquid.SpellID);
|
||||||
|
if (curLiquid != null && curLiquid.SpellID != 0)
|
||||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.NotUnderwater);
|
CastSpell(this, curLiquid.SpellID, true);
|
||||||
_lastLiquid = null;
|
_lastLiquid = curLiquid;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -191,7 +191,6 @@ namespace Game.Entities
|
|||||||
|
|
||||||
UpdateSplineMovement(diff);
|
UpdateSplineMovement(diff);
|
||||||
GetMotionMaster().UpdateMotion(diff);
|
GetMotionMaster().UpdateMotion(diff);
|
||||||
UpdateUnderwaterState(GetMap(), GetPositionX(), GetPositionY(), GetPositionZ());
|
|
||||||
}
|
}
|
||||||
void _UpdateSpells(uint diff)
|
void _UpdateSpells(uint diff)
|
||||||
{
|
{
|
||||||
|
|||||||
+146
-20
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
using Framework.Constants;
|
using Framework.Constants;
|
||||||
using Framework.Database;
|
using Framework.Database;
|
||||||
|
using Framework.Dynamic;
|
||||||
using Framework.GameMath;
|
using Framework.GameMath;
|
||||||
using Game.BattleGrounds;
|
using Game.BattleGrounds;
|
||||||
using Game.Collision;
|
using Game.Collision;
|
||||||
@@ -32,7 +33,6 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Game.Maps
|
namespace Game.Maps
|
||||||
{
|
{
|
||||||
@@ -850,7 +850,7 @@ namespace Game.Maps
|
|||||||
SendRemoveTransports(player);
|
SendRemoveTransports(player);
|
||||||
|
|
||||||
if (!inWorld) // if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
|
if (!inWorld) // if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
|
||||||
player.DestroyForNearbyPlayers(); // previous player->UpdateObjectVisibility(true)
|
player.DestroyForNearbyPlayers(); // previous player.UpdateObjectVisibility(true)
|
||||||
|
|
||||||
Cell cell = player.GetCurrentCell();
|
Cell cell = player.GetCurrentCell();
|
||||||
RemoveFromGrid(player, cell);
|
RemoveFromGrid(player, cell);
|
||||||
@@ -869,7 +869,7 @@ namespace Game.Maps
|
|||||||
RemoveFromActive(obj);
|
RemoveFromActive(obj);
|
||||||
|
|
||||||
if (!inWorld) // if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
|
if (!inWorld) // if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
|
||||||
obj.DestroyForNearbyPlayers(); // previous obj->UpdateObjectVisibility(true)
|
obj.DestroyForNearbyPlayers(); // previous obj.UpdateObjectVisibility(true)
|
||||||
|
|
||||||
Cell cell = obj.GetCurrentCell();
|
Cell cell = obj.GetCurrentCell();
|
||||||
RemoveFromGrid(obj, cell);
|
RemoveFromGrid(obj, cell);
|
||||||
@@ -950,6 +950,7 @@ namespace Game.Maps
|
|||||||
AddToGrid(player, newcell);
|
AddToGrid(player, newcell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player.UpdatePositionData();
|
||||||
player.UpdateObjectVisibility(false);
|
player.UpdateObjectVisibility(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -981,6 +982,7 @@ namespace Game.Maps
|
|||||||
if (creature.IsVehicle())
|
if (creature.IsVehicle())
|
||||||
creature.GetVehicleKit().RelocatePassengers();
|
creature.GetVehicleKit().RelocatePassengers();
|
||||||
creature.UpdateObjectVisibility(false);
|
creature.UpdateObjectVisibility(false);
|
||||||
|
creature.UpdatePositionData();
|
||||||
RemoveCreatureFromMoveList(creature);
|
RemoveCreatureFromMoveList(creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1010,6 +1012,7 @@ namespace Game.Maps
|
|||||||
{
|
{
|
||||||
go.Relocate(x, y, z, orientation);
|
go.Relocate(x, y, z, orientation);
|
||||||
go.UpdateModelPosition();
|
go.UpdateModelPosition();
|
||||||
|
go.UpdatePositionData();
|
||||||
go.UpdateObjectVisibility(false);
|
go.UpdateObjectVisibility(false);
|
||||||
RemoveGameObjectFromMoveList(go);
|
RemoveGameObjectFromMoveList(go);
|
||||||
}
|
}
|
||||||
@@ -1040,6 +1043,7 @@ namespace Game.Maps
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
dynObj.Relocate(x, y, z, orientation);
|
dynObj.Relocate(x, y, z, orientation);
|
||||||
|
dynObj.UpdatePositionData();
|
||||||
dynObj.UpdateObjectVisibility(false);
|
dynObj.UpdateObjectVisibility(false);
|
||||||
RemoveDynamicObjectFromMoveList(dynObj);
|
RemoveDynamicObjectFromMoveList(dynObj);
|
||||||
}
|
}
|
||||||
@@ -1186,6 +1190,7 @@ namespace Game.Maps
|
|||||||
creature.Relocate(creature._newPosition);
|
creature.Relocate(creature._newPosition);
|
||||||
if (creature.IsVehicle())
|
if (creature.IsVehicle())
|
||||||
creature.GetVehicleKit().RelocatePassengers();
|
creature.GetVehicleKit().RelocatePassengers();
|
||||||
|
creature.UpdatePositionData();
|
||||||
creature.UpdateObjectVisibility(false);
|
creature.UpdateObjectVisibility(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1238,6 +1243,7 @@ namespace Game.Maps
|
|||||||
// update pos
|
// update pos
|
||||||
go.Relocate(go._newPosition);
|
go.Relocate(go._newPosition);
|
||||||
go.UpdateModelPosition();
|
go.UpdateModelPosition();
|
||||||
|
go.UpdatePositionData();
|
||||||
go.UpdateObjectVisibility(false);
|
go.UpdateObjectVisibility(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1284,6 +1290,7 @@ namespace Game.Maps
|
|||||||
{
|
{
|
||||||
// update pos
|
// update pos
|
||||||
dynObj.Relocate(dynObj._newPosition);
|
dynObj.Relocate(dynObj._newPosition);
|
||||||
|
dynObj.UpdatePositionData();
|
||||||
dynObj.UpdateObjectVisibility(false);
|
dynObj.UpdateObjectVisibility(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1548,6 +1555,7 @@ namespace Game.Maps
|
|||||||
{
|
{
|
||||||
c.Relocate(resp_x, resp_y, resp_z, resp_o);
|
c.Relocate(resp_x, resp_y, resp_z, resp_o);
|
||||||
c.GetMotionMaster().Initialize(); // prevent possible problems with default move generators
|
c.GetMotionMaster().Initialize(); // prevent possible problems with default move generators
|
||||||
|
c.UpdatePositionData();
|
||||||
c.UpdateObjectVisibility(false);
|
c.UpdateObjectVisibility(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1574,6 +1582,7 @@ namespace Game.Maps
|
|||||||
if (GameObjectCellRelocation(go, resp_cell))
|
if (GameObjectCellRelocation(go, resp_cell))
|
||||||
{
|
{
|
||||||
go.Relocate(resp_x, resp_y, resp_z, resp_o);
|
go.Relocate(resp_x, resp_y, resp_z, resp_o);
|
||||||
|
go.UpdatePositionData();
|
||||||
go.UpdateObjectVisibility(false);
|
go.UpdateObjectVisibility(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1705,18 +1714,6 @@ namespace Game.Maps
|
|||||||
_corpseBones.Clear();
|
_corpseBones.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private GridMap GetGridMap(float x, float y)
|
|
||||||
{
|
|
||||||
// half opt method
|
|
||||||
var gx = (uint)(MapConst.CenterGridId - x / MapConst.SizeofGrids); //grid x
|
|
||||||
var gy = (uint)(MapConst.CenterGridId - y / MapConst.SizeofGrids); //grid y
|
|
||||||
|
|
||||||
// ensure GridMap is loaded
|
|
||||||
EnsureGridCreated(new GridCoord((MapConst.MaxGrids - 1) - gx, (MapConst.MaxGrids - 1) - gy));
|
|
||||||
|
|
||||||
return GridMaps[gx][gy];
|
|
||||||
}
|
|
||||||
|
|
||||||
GridMap GetGridMap(uint mapId, float x, float y)
|
GridMap GetGridMap(uint mapId, float x, float y)
|
||||||
{
|
{
|
||||||
// half opt method
|
// half opt method
|
||||||
@@ -1816,8 +1813,6 @@ namespace Game.Maps
|
|||||||
|
|
||||||
private bool IsOutdoorWMO(uint mogpFlags, int adtId, int rootId, int groupId, WMOAreaTableRecord wmoEntry, AreaTableRecord atEntry)
|
private bool IsOutdoorWMO(uint mogpFlags, int adtId, int rootId, int groupId, WMOAreaTableRecord wmoEntry, AreaTableRecord atEntry)
|
||||||
{
|
{
|
||||||
bool outdoor = true;
|
|
||||||
|
|
||||||
if (wmoEntry != null && atEntry != null)
|
if (wmoEntry != null && atEntry != null)
|
||||||
{
|
{
|
||||||
if (atEntry.Flags[0].HasAnyFlag(AreaFlags.Outside))
|
if (atEntry.Flags[0].HasAnyFlag(AreaFlags.Outside))
|
||||||
@@ -1826,7 +1821,7 @@ namespace Game.Maps
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
outdoor = Convert.ToBoolean(mogpFlags & 0x8);
|
bool outdoor = Convert.ToBoolean(mogpFlags & 0x8);
|
||||||
|
|
||||||
if (wmoEntry != null)
|
if (wmoEntry != null)
|
||||||
{
|
{
|
||||||
@@ -1929,8 +1924,7 @@ namespace Game.Maps
|
|||||||
|
|
||||||
public uint GetAreaId(PhaseShift phaseShift, float x, float y, float z)
|
public uint GetAreaId(PhaseShift phaseShift, float x, float y, float z)
|
||||||
{
|
{
|
||||||
bool throwaway;
|
return GetAreaId(phaseShift, x, y, z, out _);
|
||||||
return GetAreaId(phaseShift, x, y, z, out throwaway);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint GetAreaId(PhaseShift phaseShift, float x, float y, float z, out bool isOutdoors)
|
public uint GetAreaId(PhaseShift phaseShift, float x, float y, float z, out bool isOutdoors)
|
||||||
@@ -2092,6 +2086,108 @@ namespace Game.Maps
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void GetFullTerrainStatusForPosition(PhaseShift phaseShift, float x, float y, float z, PositionFullTerrainStatus data, uint reqLiquidType = MapConst.MapAllLiquidTypes)
|
||||||
|
{
|
||||||
|
uint terrainMapId = PhasingHandler.GetTerrainMapId(phaseShift, this, x, y);
|
||||||
|
AreaAndLiquidData vmapData = Global.VMapMgr.GetAreaAndLiquidData(terrainMapId, x, y, z, reqLiquidType);
|
||||||
|
if (vmapData.areaInfo.HasValue)
|
||||||
|
data.areaInfo.Set(new PositionFullTerrainStatus.AreaInfo(vmapData.areaInfo.Value.AdtId, vmapData.areaInfo.Value.RootId, vmapData.areaInfo.Value.GroupId, vmapData.areaInfo.Value.MogpFlags));
|
||||||
|
|
||||||
|
GridMap gmap = GetGridMap(terrainMapId, x, y);
|
||||||
|
float mapHeight = gmap.GetHeight(x, y);
|
||||||
|
|
||||||
|
// area lookup
|
||||||
|
AreaTableRecord areaEntry = null;
|
||||||
|
if (vmapData.areaInfo.HasValue && (z + 2.0f <= mapHeight || mapHeight <= vmapData.floorZ))
|
||||||
|
{
|
||||||
|
WMOAreaTableRecord wmoEntry = Global.DB2Mgr.GetWMOAreaTable(vmapData.areaInfo.Value.RootId, vmapData.areaInfo.Value.AdtId, vmapData.areaInfo.Value.GroupId);
|
||||||
|
if (wmoEntry != null)
|
||||||
|
areaEntry = CliDB.AreaTableStorage.LookupByKey(wmoEntry.AreaTableID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (areaEntry != null)
|
||||||
|
{
|
||||||
|
data.FloorZ = vmapData.floorZ;
|
||||||
|
data.AreaId = areaEntry.Id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.FloorZ = mapHeight;
|
||||||
|
if (gmap != null)
|
||||||
|
data.AreaId = gmap.GetArea(x, y);
|
||||||
|
else
|
||||||
|
data.AreaId = 0;
|
||||||
|
|
||||||
|
if (data.AreaId == 0)
|
||||||
|
data.AreaId = i_mapRecord.AreaTableID;
|
||||||
|
|
||||||
|
if (data.AreaId != 0)
|
||||||
|
areaEntry = CliDB.AreaTableStorage.LookupByKey(data.AreaId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// liquid processing
|
||||||
|
data.LiquidStatus = ZLiquidStatus.NoWater;
|
||||||
|
if (vmapData.liquidInfo.HasValue && vmapData.liquidInfo.Value.Level > vmapData.floorZ && z + 2.0f > vmapData.floorZ)
|
||||||
|
{
|
||||||
|
uint liquidType = vmapData.liquidInfo.Value.LiquidType;
|
||||||
|
if (GetId() == 530 && liquidType == 2) // gotta love blizzard hacks
|
||||||
|
liquidType = 15;
|
||||||
|
|
||||||
|
uint liquidFlagType = 0;
|
||||||
|
LiquidTypeRecord liquidData = CliDB.LiquidTypeStorage.LookupByKey(liquidType);
|
||||||
|
if (liquidData != null)
|
||||||
|
liquidFlagType = liquidData.SoundBank;
|
||||||
|
|
||||||
|
if (liquidType != 0 && liquidType < 21 && areaEntry != null)
|
||||||
|
{
|
||||||
|
uint overrideLiquid = areaEntry.LiquidTypeID[liquidFlagType];
|
||||||
|
if (overrideLiquid == 0 && areaEntry.ParentAreaID != 0)
|
||||||
|
{
|
||||||
|
AreaTableRecord zoneEntry = CliDB.AreaTableStorage.LookupByKey(areaEntry.ParentAreaID);
|
||||||
|
if (zoneEntry != null)
|
||||||
|
overrideLiquid = zoneEntry.LiquidTypeID[liquidFlagType];
|
||||||
|
}
|
||||||
|
|
||||||
|
LiquidTypeRecord overrideData = CliDB.LiquidTypeStorage.LookupByKey(overrideLiquid);
|
||||||
|
if (overrideData != null)
|
||||||
|
{
|
||||||
|
liquidType = overrideLiquid;
|
||||||
|
liquidFlagType = overrideData.SoundBank;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var liquidInfo = new LiquidData();
|
||||||
|
liquidInfo.level = vmapData.liquidInfo.Value.Level;
|
||||||
|
liquidInfo.depth_level = vmapData.floorZ;
|
||||||
|
liquidInfo.entry = liquidType;
|
||||||
|
liquidInfo.type_flags = 1u << (int)liquidFlagType;
|
||||||
|
data.LiquidInfo.Set(liquidInfo);
|
||||||
|
|
||||||
|
float delta = vmapData.liquidInfo.Value.Level - z;
|
||||||
|
if (delta > 2.0f)
|
||||||
|
data.LiquidStatus = ZLiquidStatus.UnderWater;
|
||||||
|
else if (delta > 0.0f)
|
||||||
|
data.LiquidStatus = ZLiquidStatus.InWater;
|
||||||
|
else if (delta > -0.1f)
|
||||||
|
data.LiquidStatus = ZLiquidStatus.WaterWalk;
|
||||||
|
else
|
||||||
|
data.LiquidStatus = ZLiquidStatus.AboveWater;
|
||||||
|
}
|
||||||
|
// look up liquid data from grid map
|
||||||
|
if (gmap != null && (data.LiquidStatus == ZLiquidStatus.AboveWater || data.LiquidStatus == ZLiquidStatus.NoWater))
|
||||||
|
{
|
||||||
|
LiquidData gridMapLiquid = new LiquidData();
|
||||||
|
ZLiquidStatus gridMapStatus = gmap.GetLiquidStatus(x, y, z, reqLiquidType, gridMapLiquid);
|
||||||
|
if (gridMapStatus != ZLiquidStatus.NoWater && (gridMapLiquid.level > vmapData.floorZ))
|
||||||
|
{
|
||||||
|
if (GetId() == 530 && gridMapLiquid.entry == 2)
|
||||||
|
gridMapLiquid.entry = 15;
|
||||||
|
data.LiquidInfo.Set(gridMapLiquid);
|
||||||
|
data.LiquidStatus = gridMapStatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public float GetWaterLevel(PhaseShift phaseShift, float x, float y)
|
public float GetWaterLevel(PhaseShift phaseShift, float x, float y)
|
||||||
{
|
{
|
||||||
GridMap gmap = GetGridMap(PhasingHandler.GetTerrainMapId(phaseShift, this, x, y), x, y);
|
GridMap gmap = GetGridMap(PhasingHandler.GetTerrainMapId(phaseShift, this, x, y), x, y);
|
||||||
@@ -3207,6 +3303,11 @@ namespace Game.Maps
|
|||||||
return _dynamicTree.Contains(model);
|
return _dynamicTree.Contains(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float GetGameObjectFloor(PhaseShift phaseShift, float x, float y, float z, float maxSearchDist = MapConst.DefaultHeightSearch)
|
||||||
|
{
|
||||||
|
return _dynamicTree.GetHeight(x, y, z, maxSearchDist, phaseShift);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual uint GetOwnerGuildId(Team team = Team.Other)
|
public virtual uint GetOwnerGuildId(Team team = Team.Other)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@@ -4911,4 +5012,29 @@ namespace Game.Maps
|
|||||||
public uint OverrideLightId;
|
public uint OverrideLightId;
|
||||||
public uint LightFadeInTime;
|
public uint LightFadeInTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct PositionFullTerrainStatus
|
||||||
|
{
|
||||||
|
public struct AreaInfo
|
||||||
|
{
|
||||||
|
public int AdtId;
|
||||||
|
public int RootId;
|
||||||
|
public int GroupId;
|
||||||
|
public uint MogpFlags;
|
||||||
|
|
||||||
|
public AreaInfo(int adtId, int rootId, int groupId, uint flags)
|
||||||
|
{
|
||||||
|
AdtId = adtId;
|
||||||
|
RootId = rootId;
|
||||||
|
GroupId = groupId;
|
||||||
|
MogpFlags = flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint AreaId;
|
||||||
|
public float FloorZ;
|
||||||
|
public ZLiquidStatus LiquidStatus;
|
||||||
|
public Optional<AreaInfo> areaInfo;
|
||||||
|
public Optional<LiquidData> LiquidInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user