Core/Maps: Adjusted logic in GetFullTerrainStatusForPosition to closer match what the client does regarding being inside WMOs
Port From (https://github.com/TrinityCore/TrinityCore/commit/453b59de57b3502163adc99a6fc9cbeec0645dcf)
This commit is contained in:
@@ -26,6 +26,7 @@ namespace Game.Collision
|
|||||||
{
|
{
|
||||||
public virtual void Invoke(Vector3 point, uint entry) { }
|
public virtual void Invoke(Vector3 point, uint entry) { }
|
||||||
public virtual void Invoke(Vector3 point, IModel entry) { }
|
public virtual void Invoke(Vector3 point, IModel entry) { }
|
||||||
|
public virtual void Invoke(Vector3 point, GameObjectModel obj) { }
|
||||||
public virtual bool Invoke(Ray ray, uint entry, ref float distance, bool pStopAtFirstHit) { return false; }
|
public virtual bool Invoke(Ray ray, uint entry, ref float distance, bool pStopAtFirstHit) { return false; }
|
||||||
public virtual bool Invoke(Ray r, IModel obj, ref float distance) { return false; }
|
public virtual bool Invoke(Ray r, IModel obj, ref float distance) { return false; }
|
||||||
}
|
}
|
||||||
@@ -106,10 +107,7 @@ namespace Game.Collision
|
|||||||
}
|
}
|
||||||
public override bool Invoke(Ray ray, uint entry, ref float distance, bool pStopAtFirstHit)
|
public override bool Invoke(Ray ray, uint entry, ref float distance, bool pStopAtFirstHit)
|
||||||
{
|
{
|
||||||
bool result = IntersectTriangle(triangles[(int)entry], vertices, ray, ref distance);
|
hit = IntersectTriangle(triangles[(int)entry], vertices, ray, ref distance) || hit;
|
||||||
if (result)
|
|
||||||
hit = true;
|
|
||||||
|
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,4 +264,25 @@ namespace Game.Collision
|
|||||||
PhaseShift _phaseShift;
|
PhaseShift _phaseShift;
|
||||||
AreaInfo _areaInfo;
|
AreaInfo _areaInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class DynamicTreeLocationInfoCallback : WorkerCallback
|
||||||
|
{
|
||||||
|
public DynamicTreeLocationInfoCallback(PhaseShift phaseShift)
|
||||||
|
{
|
||||||
|
_phaseShift = phaseShift;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Invoke(Vector3 p, GameObjectModel obj)
|
||||||
|
{
|
||||||
|
if (obj.GetLocationInfo(p, _locationInfo, _phaseShift))
|
||||||
|
_hitModel = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocationInfo GetLocationInfo() { return _locationInfo; }
|
||||||
|
public GameObjectModel GetHitModel() { return _hitModel; }
|
||||||
|
|
||||||
|
PhaseShift _phaseShift;
|
||||||
|
LocationInfo _locationInfo;
|
||||||
|
GameObjectModel _hitModel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,6 +148,31 @@ namespace Game.Collision
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AreaAndLiquidData GetAreaAndLiquidData(float x, float y, float z, PhaseShift phaseShift, byte reqLiquidType)
|
||||||
|
{
|
||||||
|
AreaAndLiquidData data = new();
|
||||||
|
|
||||||
|
Vector3 v = new(x, y, z +0.5f);
|
||||||
|
DynamicTreeLocationInfoCallback intersectionCallBack = new(phaseShift);
|
||||||
|
impl.IntersectPoint(v, intersectionCallBack);
|
||||||
|
if (intersectionCallBack.GetLocationInfo().hitModel != null)
|
||||||
|
{
|
||||||
|
data.floorZ = intersectionCallBack.GetLocationInfo().ground_Z;
|
||||||
|
uint liquidType = intersectionCallBack.GetLocationInfo().hitModel.GetLiquidType();
|
||||||
|
float liquidLevel = 0;
|
||||||
|
if (reqLiquidType == 0 || (Global.DB2Mgr.GetLiquidFlags(liquidType) & reqLiquidType) != 0)
|
||||||
|
if (intersectionCallBack.GetHitModel().GetLiquidLevel(v, intersectionCallBack.GetLocationInfo(), ref liquidLevel))
|
||||||
|
data.liquidInfo.Set(new AreaAndLiquidData.LiquidInfo(liquidType, liquidLevel));
|
||||||
|
|
||||||
|
data.areaInfo.Set(new AreaAndLiquidData.AreaInfo(intersectionCallBack.GetHitModel().GetNameSetId(),
|
||||||
|
intersectionCallBack.GetLocationInfo().rootId,
|
||||||
|
(int)intersectionCallBack.GetLocationInfo().hitModel.GetWmoID(),
|
||||||
|
intersectionCallBack.GetLocationInfo().hitModel.GetMogpFlags()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
DynTreeImpl impl;
|
DynTreeImpl impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ namespace Game.Collision
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool GetLiquidLevel(uint mapId, float x, float y, float z, uint reqLiquidType, ref float level, ref float floor, ref uint type)
|
public bool GetLiquidLevel(uint mapId, float x, float y, float z, uint reqLiquidType, ref float level, ref float floor, ref uint type, ref uint mogpFlags)
|
||||||
{
|
{
|
||||||
if (!Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, (byte)DisableFlags.VmapLiquidStatus))
|
if (!Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, (byte)DisableFlags.VmapLiquidStatus))
|
||||||
{
|
{
|
||||||
@@ -239,6 +239,7 @@ namespace Game.Collision
|
|||||||
floor = info.ground_Z;
|
floor = info.ground_Z;
|
||||||
Cypher.Assert(floor < float.MaxValue);
|
Cypher.Assert(floor < float.MaxValue);
|
||||||
type = info.hitModel.GetLiquidType(); // entry from LiquidType.dbc
|
type = info.hitModel.GetLiquidType(); // entry from LiquidType.dbc
|
||||||
|
mogpFlags = info.hitModel.GetMogpFlags();
|
||||||
if (reqLiquidType != 0 && !Convert.ToBoolean(Global.DB2Mgr.GetLiquidFlags(type) & reqLiquidType))
|
if (reqLiquidType != 0 && !Convert.ToBoolean(Global.DB2Mgr.GetLiquidFlags(type) & reqLiquidType))
|
||||||
return false;
|
return false;
|
||||||
if (info.hitInstance.GetLiquidLevel(pos, info, ref level))
|
if (info.hitInstance.GetLiquidLevel(pos, info, ref level))
|
||||||
|
|||||||
@@ -139,6 +139,51 @@ namespace Game.Collision
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool GetLocationInfo(Vector3 point, LocationInfo info, PhaseShift phaseShift)
|
||||||
|
{
|
||||||
|
if (!IsCollisionEnabled() || !owner.IsSpawned() || !IsMapObject())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!owner.IsInPhase(phaseShift))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!iBound.contains(point))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// child bounds are defined in object space:
|
||||||
|
Vector3 pModel = iInvRot * (point - iPos) * iInvScale;
|
||||||
|
Vector3 zDirModel = iInvRot * new Vector3(0.0f, 0.0f, -1.0f);
|
||||||
|
float zDist;
|
||||||
|
if (iModel.GetLocationInfo(pModel, zDirModel, out zDist, info))
|
||||||
|
{
|
||||||
|
Vector3 modelGround = pModel + zDist * zDirModel;
|
||||||
|
float world_Z = ((modelGround * iInvRot) * iScale + iPos).Z;
|
||||||
|
if (info.ground_Z < world_Z)
|
||||||
|
{
|
||||||
|
info.ground_Z = world_Z;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetLiquidLevel(Vector3 point, LocationInfo info, ref float liqHeight)
|
||||||
|
{
|
||||||
|
// child bounds are defined in object space:
|
||||||
|
Vector3 pModel = iInvRot * (point - iPos) * iInvScale;
|
||||||
|
//Vector3 zDirModel = iInvRot * Vector3(0.f, 0.f, -1.f);
|
||||||
|
float zDist;
|
||||||
|
if (info.hitModel.GetLiquidLevel(pModel, out zDist))
|
||||||
|
{
|
||||||
|
// calculate world height (zDist in model coords):
|
||||||
|
// assume WMO not tilted (wouldn't make much sense anyway)
|
||||||
|
liqHeight = zDist * iScale + iPos.Z;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public bool UpdatePosition()
|
public bool UpdatePosition()
|
||||||
{
|
{
|
||||||
if (iModel == null)
|
if (iModel == null)
|
||||||
@@ -177,7 +222,8 @@ namespace Game.Collision
|
|||||||
public void EnableCollision(bool enable) { _collisionEnabled = enable; }
|
public void EnableCollision(bool enable) { _collisionEnabled = enable; }
|
||||||
bool IsCollisionEnabled() { return _collisionEnabled; }
|
bool IsCollisionEnabled() { return _collisionEnabled; }
|
||||||
public bool IsMapObject() { return isWmo; }
|
public bool IsMapObject() { return isWmo; }
|
||||||
|
public byte GetNameSetId() { return owner.GetNameSetId(); }
|
||||||
|
|
||||||
public static void LoadGameObjectModelList()
|
public static void LoadGameObjectModelList()
|
||||||
{
|
{
|
||||||
uint oldMSTime = Time.GetMSTime();
|
uint oldMSTime = Time.GetMSTime();
|
||||||
|
|||||||
@@ -3306,8 +3306,9 @@ namespace Game.Entities
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float halfHeight = GetCollisionHeight() * 0.5f;
|
||||||
UpdateAllowedPositionZ(destx, desty, ref destz);
|
UpdateAllowedPositionZ(destx, desty, ref destz);
|
||||||
bool col = Global.VMapMgr.GetObjectHitPos(PhasingHandler.GetTerrainMapId(GetPhaseShift(), GetMap(), pos.posX, pos.posY), pos.posX, pos.posY, pos.posZ, destx, desty, destz, out destx, out desty, out destz, -0.5f);
|
bool col = Global.VMapMgr.GetObjectHitPos(PhasingHandler.GetTerrainMapId(GetPhaseShift(), GetMap(), pos.posX, pos.posY), pos.posX, pos.posY, pos.posZ + halfHeight, destx, desty, destz + halfHeight, out destx, out desty, out destz, -0.5f);
|
||||||
|
|
||||||
// collision occured
|
// collision occured
|
||||||
if (col)
|
if (col)
|
||||||
@@ -3319,7 +3320,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check dynamic collision
|
// check dynamic collision
|
||||||
col = GetMap().GetObjectHitPos(GetPhaseShift(), pos.posX, pos.posY, pos.posZ, destx, desty, destz, out destx, out desty, out destz, -0.5f);
|
col = GetMap().GetObjectHitPos(GetPhaseShift(), pos.posX, pos.posY, pos.posZ + halfHeight, destx, desty, destz + halfHeight, out destx, out desty, out destz, -0.5f);
|
||||||
|
|
||||||
// Collided with a gameobject
|
// Collided with a gameobject
|
||||||
if (col)
|
if (col)
|
||||||
@@ -3363,11 +3364,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
float GetMapWaterOrGroundLevel(float x, float y, float z, ref float ground)
|
float GetMapWaterOrGroundLevel(float x, float y, float z, ref float ground)
|
||||||
{
|
{
|
||||||
Unit unit = ToUnit();
|
return GetMap().GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, ref ground, IsTypeMask(TypeMask.Unit) ? !ToUnit().HasAuraType(AuraType.WaterWalk) : false, GetCollisionHeight());
|
||||||
if (unit != null)
|
|
||||||
return GetMap().GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, ref ground, !unit.HasAuraType(AuraType.WaterWalk), GetCollisionHeight());
|
|
||||||
|
|
||||||
return z;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetMapHeight(float x, float y, float z, bool vmap = true, float distanceToSearch = MapConst.DefaultHeightSearch)
|
public float GetMapHeight(float x, float y, float z, bool vmap = true, float distanceToSearch = MapConst.DefaultHeightSearch)
|
||||||
|
|||||||
+41
-13
@@ -69,6 +69,12 @@ namespace Game.Maps
|
|||||||
return LoadResult.ReadFromFileFailed;
|
return LoadResult.ReadFromFileFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (header.holesSize != 0 && !LoadHolesData(reader, header.holesOffset))
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Maps, "Error loading map holes data");
|
||||||
|
return LoadResult.ReadFromFileFailed;
|
||||||
|
}
|
||||||
|
|
||||||
return LoadResult.Success;
|
return LoadResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,6 +213,15 @@ namespace Game.Maps
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LoadHolesData(BinaryReader reader, uint offset)
|
||||||
|
{
|
||||||
|
reader.BaseStream.Seek(offset, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
_holes = reader.ReadArray<byte>(16 * 16 * 8);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public ushort GetArea(float x, float y)
|
public ushort GetArea(float x, float y)
|
||||||
{
|
{
|
||||||
if (_areaMap == null)
|
if (_areaMap == null)
|
||||||
@@ -239,6 +254,9 @@ namespace Game.Maps
|
|||||||
x_int &= (MapConst.MapResolution - 1);
|
x_int &= (MapConst.MapResolution - 1);
|
||||||
y_int &= (MapConst.MapResolution - 1);
|
y_int &= (MapConst.MapResolution - 1);
|
||||||
|
|
||||||
|
if (IsHole(x_int, y_int))
|
||||||
|
return MapConst.InvalidHeight;
|
||||||
|
|
||||||
float a, b, c;
|
float a, b, c;
|
||||||
if (x + y < 1)
|
if (x + y < 1)
|
||||||
{
|
{
|
||||||
@@ -304,6 +322,10 @@ namespace Game.Maps
|
|||||||
y -= y_int;
|
y -= y_int;
|
||||||
x_int &= (MapConst.MapResolution - 1);
|
x_int &= (MapConst.MapResolution - 1);
|
||||||
y_int &= (MapConst.MapResolution - 1);
|
y_int &= (MapConst.MapResolution - 1);
|
||||||
|
|
||||||
|
if (IsHole(x_int, y_int))
|
||||||
|
return MapConst.InvalidHeight;
|
||||||
|
|
||||||
int a, b, c;
|
int a, b, c;
|
||||||
|
|
||||||
unsafe
|
unsafe
|
||||||
@@ -377,6 +399,10 @@ namespace Game.Maps
|
|||||||
y -= y_int;
|
y -= y_int;
|
||||||
x_int &= (MapConst.MapResolution - 1);
|
x_int &= (MapConst.MapResolution - 1);
|
||||||
y_int &= (MapConst.MapResolution - 1);
|
y_int &= (MapConst.MapResolution - 1);
|
||||||
|
|
||||||
|
if (IsHole(x_int, y_int))
|
||||||
|
return MapConst.InvalidHeight;
|
||||||
|
|
||||||
int a, b, c;
|
int a, b, c;
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
@@ -435,6 +461,19 @@ namespace Game.Maps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsHole(int row, int col)
|
||||||
|
{
|
||||||
|
if (_holes == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int cellRow = row / 8; // 8 squares per cell
|
||||||
|
int cellCol = col / 8;
|
||||||
|
int holeRow = row % 8;
|
||||||
|
int holeCol = col % 8;
|
||||||
|
|
||||||
|
return (_holes[cellRow * 16 * 8 + cellCol * 8 + holeRow] & (1 << holeCol)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
public float GetMinHeight(float x, float y)
|
public float GetMinHeight(float x, float y)
|
||||||
{
|
{
|
||||||
if (_minHeightPlanes == null)
|
if (_minHeightPlanes == null)
|
||||||
@@ -485,19 +524,6 @@ namespace Game.Maps
|
|||||||
return _liquidMap[cx_int * _liquidWidth + cy_int];
|
return _liquidMap[cx_int * _liquidWidth + cy_int];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Why does this return LIQUID data?
|
|
||||||
public LiquidHeaderTypeFlags GetTerrainType(float x, float y)
|
|
||||||
{
|
|
||||||
if (_liquidFlags == null)
|
|
||||||
return LiquidHeaderTypeFlags.NoWater;
|
|
||||||
|
|
||||||
x = 16 * (32 - x / MapConst.SizeofGrids);
|
|
||||||
y = 16 * (32 - y / MapConst.SizeofGrids);
|
|
||||||
int lx = (int)x & 15;
|
|
||||||
int ly = (int)y & 15;
|
|
||||||
return (LiquidHeaderTypeFlags)_liquidFlags[lx * 16 + ly];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get water state on map
|
// Get water state on map
|
||||||
public ZLiquidStatus GetLiquidStatus(float x, float y, float z, LiquidHeaderTypeFlags? reqLiquidType, LiquidData data, float collisionHeight)
|
public ZLiquidStatus GetLiquidStatus(float x, float y, float z, LiquidHeaderTypeFlags? reqLiquidType, LiquidData data, float collisionHeight)
|
||||||
{
|
{
|
||||||
@@ -625,6 +651,8 @@ namespace Game.Maps
|
|||||||
byte _liquidOffY;
|
byte _liquidOffY;
|
||||||
byte _liquidWidth;
|
byte _liquidWidth;
|
||||||
byte _liquidHeight;
|
byte _liquidHeight;
|
||||||
|
|
||||||
|
byte[] _holes;
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+129
-147
@@ -1713,7 +1713,7 @@ namespace Game.Maps
|
|||||||
if (gmap != null)
|
if (gmap != null)
|
||||||
{
|
{
|
||||||
float gridHeight = gmap.GetHeight(x, y);
|
float gridHeight = gmap.GetHeight(x, y);
|
||||||
if (z > gridHeight)
|
if (MathFunctions.fuzzyGe(z, gridHeight - MapConst.GroundHeightTolerance))
|
||||||
mapHeight = gridHeight;
|
mapHeight = gridHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1763,50 +1763,14 @@ namespace Game.Maps
|
|||||||
return -500.0f;
|
return -500.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsOutdoorWMO(uint mogpFlags, WMOAreaTableRecord wmoEntry, AreaTableRecord atEntry)
|
public static bool IsInWMOInterior(uint mogpFlags)
|
||||||
{
|
{
|
||||||
if (wmoEntry != null && atEntry != null)
|
return (mogpFlags & 0x2000) != 0;
|
||||||
{
|
|
||||||
if (atEntry.Flags.HasFlag(AreaFlags.Outside))
|
|
||||||
return true;
|
|
||||||
if (atEntry.Flags.HasFlag(AreaFlags.Inside))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wmoEntry != null)
|
|
||||||
{
|
|
||||||
if (Convert.ToBoolean(wmoEntry.Flags & 4))
|
|
||||||
return true;
|
|
||||||
if ((wmoEntry.Flags & 2) != 0)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (mogpFlags & 0x8) != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsOutdoors(PhaseShift phaseShift, float x, float y, float z)
|
private bool GetAreaInfo(PhaseShift phaseShift, float x, float y, float z, out uint mogpflags, out int adtId, out int rootId, out int groupId)
|
||||||
{
|
{
|
||||||
uint mogpFlags;
|
mogpflags = 0;
|
||||||
int adtId, rootId, groupId;
|
|
||||||
|
|
||||||
// no wmo found? . outside by default
|
|
||||||
if (!GetAreaInfo(phaseShift, x, y, z, out mogpFlags, out adtId, out rootId, out groupId))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
AreaTableRecord atEntry = null;
|
|
||||||
WMOAreaTableRecord wmoEntry = Global.DB2Mgr.GetWMOAreaTable(rootId, adtId, groupId);
|
|
||||||
if (wmoEntry != null)
|
|
||||||
{
|
|
||||||
Log.outDebug(LogFilter.Maps, "Got WMOAreaTableEntry! flag {0}, areaid {1}", wmoEntry.Flags,
|
|
||||||
wmoEntry.AreaTableID);
|
|
||||||
atEntry = CliDB.AreaTableStorage.LookupByKey(wmoEntry.AreaTableID);
|
|
||||||
}
|
|
||||||
return IsOutdoorWMO(mogpFlags, wmoEntry, atEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool GetAreaInfo(PhaseShift phaseShift, float x, float y, float z, out uint flags, out int adtId, out int rootId, out int groupId)
|
|
||||||
{
|
|
||||||
flags = 0;
|
|
||||||
adtId = 0;
|
adtId = 0;
|
||||||
rootId = 0;
|
rootId = 0;
|
||||||
groupId = 0;
|
groupId = 0;
|
||||||
@@ -1832,7 +1796,7 @@ namespace Game.Maps
|
|||||||
if (hasDynamicAreaInfo && dynamic_z > vmap_z)
|
if (hasDynamicAreaInfo && dynamic_z > vmap_z)
|
||||||
{
|
{
|
||||||
check_z = dynamic_z;
|
check_z = dynamic_z;
|
||||||
flags = dflags;
|
mogpflags = dflags;
|
||||||
adtId = dadtId;
|
adtId = dadtId;
|
||||||
rootId = drootId;
|
rootId = drootId;
|
||||||
groupId = dgroupId;
|
groupId = dgroupId;
|
||||||
@@ -1840,7 +1804,7 @@ namespace Game.Maps
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
check_z = vmap_z;
|
check_z = vmap_z;
|
||||||
flags = vflags;
|
mogpflags = vflags;
|
||||||
adtId = vadtId;
|
adtId = vadtId;
|
||||||
rootId = vrootId;
|
rootId = vrootId;
|
||||||
groupId = vgroupId;
|
groupId = vgroupId;
|
||||||
@@ -1849,7 +1813,7 @@ namespace Game.Maps
|
|||||||
else if (hasDynamicAreaInfo)
|
else if (hasDynamicAreaInfo)
|
||||||
{
|
{
|
||||||
check_z = dynamic_z;
|
check_z = dynamic_z;
|
||||||
flags = dflags;
|
mogpflags = dflags;
|
||||||
adtId = dadtId;
|
adtId = dadtId;
|
||||||
rootId = drootId;
|
rootId = drootId;
|
||||||
groupId = dgroupId;
|
groupId = dgroupId;
|
||||||
@@ -1863,7 +1827,8 @@ namespace Game.Maps
|
|||||||
if (gmap != null)
|
if (gmap != null)
|
||||||
{
|
{
|
||||||
float mapHeight = gmap.GetHeight(x, y);
|
float mapHeight = gmap.GetHeight(x, y);
|
||||||
if (z > mapHeight && mapHeight > check_z)
|
// z + 2.0f condition taken from GetHeight(), not sure if it's such a great choice...
|
||||||
|
if (z + 2.0f > mapHeight && mapHeight > check_z)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -1873,45 +1838,39 @@ 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)
|
||||||
{
|
|
||||||
return GetAreaId(phaseShift, x, y, z, out _);
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint GetAreaId(PhaseShift phaseShift, float x, float y, float z, out bool isOutdoors)
|
|
||||||
{
|
{
|
||||||
uint mogpFlags;
|
uint mogpFlags;
|
||||||
int adtId, rootId, groupId;
|
int adtId, rootId, groupId;
|
||||||
WMOAreaTableRecord wmoEntry = null;
|
float vmapZ = z;
|
||||||
AreaTableRecord atEntry = null;
|
bool hasVmapArea = GetAreaInfo(phaseShift, x, y, vmapZ, out mogpFlags, out adtId, out rootId, out groupId);
|
||||||
bool haveAreaInfo = false;
|
|
||||||
|
uint gridAreaId = 0;
|
||||||
|
float gridMapHeight = MapConst.InvalidHeight;
|
||||||
|
GridMap gmap = GetGridMap(PhasingHandler.GetTerrainMapId(phaseShift, this, x, y), x, y);
|
||||||
|
if (gmap != null)
|
||||||
|
{
|
||||||
|
gridAreaId = gmap.GetArea(x, y);
|
||||||
|
gridMapHeight = gmap.GetHeight(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
uint areaId = 0;
|
uint areaId = 0;
|
||||||
|
|
||||||
if (GetAreaInfo(phaseShift, x, y, z, out mogpFlags, out adtId, out rootId, out groupId))
|
// floor is the height we are closer to (but only if above)
|
||||||
|
if (hasVmapArea && MathFunctions.fuzzyGe(z, vmapZ - MapConst.GroundHeightTolerance) && (MathFunctions.fuzzyLt(z, gridMapHeight - MapConst.GroundHeightTolerance) || vmapZ > gridMapHeight))
|
||||||
{
|
{
|
||||||
haveAreaInfo = true;
|
// wmo found
|
||||||
wmoEntry = Global.DB2Mgr.GetWMOAreaTable(rootId, adtId, groupId);
|
var wmoEntry = Global.DB2Mgr.GetWMOAreaTable(rootId, adtId, groupId);
|
||||||
if (wmoEntry != null)
|
if (wmoEntry != null)
|
||||||
{
|
|
||||||
areaId = wmoEntry.AreaTableID;
|
areaId = wmoEntry.AreaTableID;
|
||||||
atEntry = CliDB.AreaTableStorage.LookupByKey(wmoEntry.AreaTableID);
|
|
||||||
}
|
if (areaId == 0)
|
||||||
|
areaId = gridAreaId;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
areaId = gridAreaId;
|
||||||
|
|
||||||
if (areaId == 0)
|
if (areaId == 0)
|
||||||
{
|
areaId = i_mapRecord.AreaTableID;
|
||||||
GridMap gmap = GetGridMap(PhasingHandler.GetTerrainMapId(phaseShift, this, x, y), x, y);
|
|
||||||
if (gmap != null)
|
|
||||||
areaId = gmap.GetArea(x, y);
|
|
||||||
|
|
||||||
// this used while not all *.map files generated (instances)
|
|
||||||
if (areaId == 0)
|
|
||||||
areaId = i_mapRecord.AreaTableID;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (haveAreaInfo)
|
|
||||||
isOutdoors = IsOutdoorWMO(mogpFlags, wmoEntry, atEntry);
|
|
||||||
else
|
|
||||||
isOutdoors = true;
|
|
||||||
|
|
||||||
return areaId;
|
return areaId;
|
||||||
}
|
}
|
||||||
@@ -1942,15 +1901,6 @@ namespace Game.Maps
|
|||||||
|
|
||||||
public void GetZoneAndAreaId(PhaseShift phaseShift, out uint zoneid, out uint areaid, Position pos) { GetZoneAndAreaId(phaseShift, out zoneid, out areaid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
|
public void GetZoneAndAreaId(PhaseShift phaseShift, out uint zoneid, out uint areaid, Position pos) { GetZoneAndAreaId(phaseShift, out zoneid, out areaid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); }
|
||||||
|
|
||||||
private LiquidHeaderTypeFlags GetTerrainType(PhaseShift phaseShift, float x, float y)
|
|
||||||
{
|
|
||||||
GridMap gmap = GetGridMap(PhasingHandler.GetTerrainMapId(phaseShift, this, x, y), x, y);
|
|
||||||
if (gmap != null)
|
|
||||||
return gmap.GetTerrainType(x, y);
|
|
||||||
|
|
||||||
return LiquidHeaderTypeFlags.NoWater;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ZLiquidStatus GetLiquidStatus(PhaseShift phaseShift, float x, float y, float z, LiquidHeaderTypeFlags reqLiquidType, float collisionHeight = MapConst.DefaultCollesionHeight)
|
public ZLiquidStatus GetLiquidStatus(PhaseShift phaseShift, float x, float y, float z, LiquidHeaderTypeFlags reqLiquidType, float collisionHeight = MapConst.DefaultCollesionHeight)
|
||||||
{
|
{
|
||||||
return GetLiquidStatus(phaseShift, x, y, z, reqLiquidType, out _, collisionHeight);
|
return GetLiquidStatus(phaseShift, x, y, z, reqLiquidType, out _, collisionHeight);
|
||||||
@@ -1963,13 +1913,17 @@ namespace Game.Maps
|
|||||||
float liquid_level = MapConst.InvalidHeight;
|
float liquid_level = MapConst.InvalidHeight;
|
||||||
float ground_level = MapConst.InvalidHeight;
|
float ground_level = MapConst.InvalidHeight;
|
||||||
uint liquid_type = 0;
|
uint liquid_type = 0;
|
||||||
|
uint mogpFlags = 0;
|
||||||
|
bool useGridLiquid = true;
|
||||||
uint terrainMapId = PhasingHandler.GetTerrainMapId(phaseShift, this, x, y);
|
uint terrainMapId = PhasingHandler.GetTerrainMapId(phaseShift, this, x, y);
|
||||||
if (Global.VMapMgr.GetLiquidLevel(terrainMapId, x, y, z, (byte)reqLiquidType, ref liquid_level, ref ground_level, ref liquid_type))
|
|
||||||
|
if (Global.VMapMgr.GetLiquidLevel(terrainMapId, x, y, z, (byte)reqLiquidType, ref liquid_level, ref ground_level, ref liquid_type, ref mogpFlags))
|
||||||
{
|
{
|
||||||
|
useGridLiquid = !IsInWMOInterior(mogpFlags);
|
||||||
Log.outDebug(LogFilter.Maps, "getLiquidStatus(): vmap liquid level: {0} ground: {1} type: {2}",
|
Log.outDebug(LogFilter.Maps, "getLiquidStatus(): vmap liquid level: {0} ground: {1} type: {2}",
|
||||||
liquid_level, ground_level, liquid_type);
|
liquid_level, ground_level, liquid_type);
|
||||||
// Check water level and ground level
|
// Check water level and ground level
|
||||||
if (liquid_level > ground_level && z > ground_level - 2)
|
if (liquid_level > ground_level && MathFunctions.fuzzyGe(z, ground_level - MapConst.GroundHeightTolerance))
|
||||||
{
|
{
|
||||||
// All ok in water . store data
|
// All ok in water . store data
|
||||||
// hardcoded in client like this
|
// hardcoded in client like this
|
||||||
@@ -2022,21 +1976,24 @@ namespace Game.Maps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GridMap gmap = GetGridMap(terrainMapId, x, y);
|
if (useGridLiquid)
|
||||||
if (gmap != null)
|
|
||||||
{
|
{
|
||||||
var map_data = new LiquidData();
|
GridMap gmap = GetGridMap(terrainMapId, x, y);
|
||||||
ZLiquidStatus map_result = gmap.GetLiquidStatus(x, y, z, reqLiquidType, map_data, collisionHeight);
|
if (gmap != null)
|
||||||
// Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER:
|
|
||||||
if (map_result != ZLiquidStatus.NoWater && (map_data.level > ground_level))
|
|
||||||
{
|
{
|
||||||
// hardcoded in client like this
|
var map_data = new LiquidData();
|
||||||
if (GetId() == 530 && map_data.entry == 2)
|
ZLiquidStatus map_result = gmap.GetLiquidStatus(x, y, z, reqLiquidType, map_data, collisionHeight);
|
||||||
map_data.entry = 15;
|
// Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER:
|
||||||
|
if (map_result != ZLiquidStatus.NoWater && (map_data.level > ground_level))
|
||||||
|
{
|
||||||
|
// hardcoded in client like this
|
||||||
|
if (GetId() == 530 && map_data.entry == 2)
|
||||||
|
map_data.entry = 15;
|
||||||
|
|
||||||
data = map_data;
|
data = map_data;
|
||||||
|
|
||||||
return map_result;
|
return map_result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -2045,66 +2002,92 @@ namespace Game.Maps
|
|||||||
public void GetFullTerrainStatusForPosition(PhaseShift phaseShift, float x, float y, float z, PositionFullTerrainStatus data, LiquidHeaderTypeFlags reqLiquidType, float collisionHeight = MapConst.DefaultCollesionHeight)
|
public void GetFullTerrainStatusForPosition(PhaseShift phaseShift, float x, float y, float z, PositionFullTerrainStatus data, LiquidHeaderTypeFlags reqLiquidType, float collisionHeight = MapConst.DefaultCollesionHeight)
|
||||||
{
|
{
|
||||||
uint terrainMapId = PhasingHandler.GetTerrainMapId(phaseShift, this, x, y);
|
uint terrainMapId = PhasingHandler.GetTerrainMapId(phaseShift, this, x, y);
|
||||||
AreaAndLiquidData vmapData = Global.VMapMgr.GetAreaAndLiquidData(terrainMapId, x, y, z, (byte)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));
|
|
||||||
|
|
||||||
float mapHeight = MapConst.InvalidHeight;
|
|
||||||
GridMap gmap = GetGridMap(terrainMapId, x, y);
|
GridMap gmap = GetGridMap(terrainMapId, x, y);
|
||||||
|
AreaAndLiquidData vmapData = Global.VMapMgr.GetAreaAndLiquidData(terrainMapId, x, y, z, (byte)reqLiquidType);
|
||||||
|
AreaAndLiquidData dynData = _dynamicTree.GetAreaAndLiquidData(x, y, z, phaseShift, (byte)reqLiquidType);
|
||||||
|
|
||||||
|
uint gridAreaId = 0;
|
||||||
|
float gridMapHeight = MapConst.InvalidHeight;
|
||||||
if (gmap != null)
|
if (gmap != null)
|
||||||
mapHeight = gmap.GetHeight(x, y);
|
|
||||||
|
|
||||||
// area lookup
|
|
||||||
AreaTableRecord areaEntry = null;
|
|
||||||
WMOAreaTableRecord wmoEntry = null;
|
|
||||||
|
|
||||||
// the vmap floor is our floor if either
|
|
||||||
// - the vmap floor is above the gridmap floor
|
|
||||||
// or
|
|
||||||
// - we are below the gridmap floor
|
|
||||||
if (vmapData.areaInfo.HasValue && (MathFunctions.fuzzyLt(z, mapHeight - MapConst.GroundHeightTolerance) || mapHeight <= vmapData.floorZ))
|
|
||||||
{
|
{
|
||||||
wmoEntry = Global.DB2Mgr.GetWMOAreaTable(vmapData.areaInfo.Value.RootId, vmapData.areaInfo.Value.AdtId, vmapData.areaInfo.Value.GroupId);
|
gridAreaId = gmap.GetArea(x, y);
|
||||||
if (wmoEntry != null)
|
gridMapHeight = gmap.GetHeight(x, y);
|
||||||
areaEntry = CliDB.AreaTableStorage.LookupByKey(wmoEntry.AreaTableID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (areaEntry != null)
|
bool useGridLiquid = true;
|
||||||
|
AreaAndLiquidData wmoData = null;
|
||||||
|
|
||||||
|
// floor is the height we are closer to (but only if above)
|
||||||
|
data.FloorZ = MapConst.InvalidHeight;
|
||||||
|
if (gridMapHeight > MapConst.InvalidHeight && MathFunctions.fuzzyGe(z, gridMapHeight - MapConst.GroundHeightTolerance))
|
||||||
|
data.FloorZ = gridMapHeight;
|
||||||
|
if (vmapData.floorZ > MapConst.InvalidHeight &&
|
||||||
|
MathFunctions.fuzzyGe(z, vmapData.floorZ - MapConst.GroundHeightTolerance) &&
|
||||||
|
(MathFunctions.fuzzyLt(z, gridMapHeight - MapConst.GroundHeightTolerance) || vmapData.floorZ > gridMapHeight))
|
||||||
{
|
{
|
||||||
data.AreaId = areaEntry.Id;
|
|
||||||
data.FloorZ = vmapData.floorZ;
|
data.FloorZ = vmapData.floorZ;
|
||||||
|
wmoData = vmapData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Objects will not detect a case when a wmo providing area/liquid despawns from under them
|
||||||
|
// but this is fine as these kind of objects are not meant to be spawned and despawned a lot
|
||||||
|
// example: Lich King platform
|
||||||
|
if (dynData.floorZ > MapConst.InvalidHeight &&
|
||||||
|
MathFunctions.fuzzyGe(z, dynData.floorZ - MapConst.GroundHeightTolerance) &&
|
||||||
|
(MathFunctions.fuzzyLt(z, gridMapHeight - MapConst.GroundHeightTolerance) || dynData.floorZ > gridMapHeight) &&
|
||||||
|
(MathFunctions.fuzzyLt(z, vmapData.floorZ - MapConst.GroundHeightTolerance) || dynData.floorZ > vmapData.floorZ))
|
||||||
|
{
|
||||||
|
data.FloorZ = dynData.floorZ;
|
||||||
|
wmoData = dynData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wmoData != null)
|
||||||
|
{
|
||||||
|
if (wmoData.areaInfo.HasValue)
|
||||||
|
{
|
||||||
|
data.areaInfo.Set(new PositionFullTerrainStatus.AreaInfo(wmoData.areaInfo.Value.AdtId, wmoData.areaInfo.Value.RootId, wmoData.areaInfo.Value.GroupId, wmoData.areaInfo.Value.MogpFlags));
|
||||||
|
// wmo found
|
||||||
|
var wmoEntry = Global.DB2Mgr.GetWMOAreaTable(wmoData.areaInfo.Value.RootId, wmoData.areaInfo.Value.AdtId, wmoData.areaInfo.Value.GroupId);
|
||||||
|
data.outdoors = (wmoData.areaInfo.Value.MogpFlags & 0x8) != 0;
|
||||||
|
if (wmoEntry != null)
|
||||||
|
{
|
||||||
|
data.AreaId = wmoEntry.AreaTableID;
|
||||||
|
if ((wmoEntry.Flags & 4) != 0)
|
||||||
|
data.outdoors = true;
|
||||||
|
else if ((wmoEntry.Flags & 2) != 0)
|
||||||
|
data.outdoors = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.AreaId == 0)
|
||||||
|
data.AreaId = gridAreaId;
|
||||||
|
|
||||||
|
useGridLiquid = !IsInWMOInterior(wmoData.areaInfo.Value.MogpFlags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (gmap != null)
|
data.outdoors = true;
|
||||||
data.AreaId = gmap.GetArea(x, y);
|
data.AreaId = gridAreaId;
|
||||||
else
|
var areaEntry1 = CliDB.AreaTableStorage.LookupByKey(data.AreaId);
|
||||||
data.AreaId = 0;
|
if (areaEntry1 != null)
|
||||||
|
data.outdoors = (areaEntry1.Flags & (AreaFlags.Inside | AreaFlags.Outside)) != AreaFlags.Inside;
|
||||||
if (data.AreaId == 0)
|
|
||||||
data.AreaId = i_mapRecord.AreaTableID;
|
|
||||||
|
|
||||||
if (data.AreaId != 0)
|
|
||||||
areaEntry = CliDB.AreaTableStorage.LookupByKey(data.AreaId);
|
|
||||||
|
|
||||||
data.FloorZ = mapHeight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vmapData.areaInfo.HasValue)
|
if (data.AreaId == 0)
|
||||||
data.outdoors = IsOutdoorWMO(vmapData.areaInfo.Value.MogpFlags, wmoEntry, areaEntry);
|
data.AreaId = i_mapRecord.AreaTableID;
|
||||||
else
|
|
||||||
data.outdoors = true; // @todo default true taken from old GetAreaId check, maybe review
|
var areaEntry = CliDB.AreaTableStorage.LookupByKey(data.AreaId);
|
||||||
|
|
||||||
// liquid processing
|
// liquid processing
|
||||||
data.LiquidStatus = ZLiquidStatus.NoWater;
|
data.LiquidStatus = ZLiquidStatus.NoWater;
|
||||||
if (vmapData.liquidInfo.HasValue && vmapData.liquidInfo.Value.Level > vmapData.floorZ && z > vmapData.floorZ)
|
if (wmoData != null && wmoData.liquidInfo.HasValue && wmoData.liquidInfo.Value.Level > wmoData.floorZ)
|
||||||
{
|
{
|
||||||
uint liquidType = vmapData.liquidInfo.Value.LiquidType;
|
uint liquidType = wmoData.liquidInfo.Value.LiquidType;
|
||||||
if (GetId() == 530 && liquidType == 2) // gotta love blizzard hacks
|
if (GetId() == 530 && liquidType == 2) // gotta love blizzard hacks
|
||||||
liquidType = 15;
|
liquidType = 15;
|
||||||
|
|
||||||
uint liquidFlagType = 0;
|
uint liquidFlagType = 0;
|
||||||
LiquidTypeRecord liquidData = CliDB.LiquidTypeStorage.LookupByKey(liquidType);
|
var liquidData = CliDB.LiquidTypeStorage.LookupByKey(liquidType);
|
||||||
if (liquidData != null)
|
if (liquidData != null)
|
||||||
liquidFlagType = liquidData.SoundBank;
|
liquidFlagType = liquidData.SoundBank;
|
||||||
|
|
||||||
@@ -2113,12 +2096,12 @@ namespace Game.Maps
|
|||||||
uint overrideLiquid = areaEntry.LiquidTypeID[liquidFlagType];
|
uint overrideLiquid = areaEntry.LiquidTypeID[liquidFlagType];
|
||||||
if (overrideLiquid == 0 && areaEntry.ParentAreaID != 0)
|
if (overrideLiquid == 0 && areaEntry.ParentAreaID != 0)
|
||||||
{
|
{
|
||||||
AreaTableRecord zoneEntry = CliDB.AreaTableStorage.LookupByKey(areaEntry.ParentAreaID);
|
var zoneEntry = CliDB.AreaTableStorage.LookupByKey(areaEntry.ParentAreaID);
|
||||||
if (zoneEntry != null)
|
if (zoneEntry != null)
|
||||||
overrideLiquid = zoneEntry.LiquidTypeID[liquidFlagType];
|
overrideLiquid = zoneEntry.LiquidTypeID[liquidFlagType];
|
||||||
}
|
}
|
||||||
|
|
||||||
LiquidTypeRecord overrideData = CliDB.LiquidTypeStorage.LookupByKey(overrideLiquid);
|
var overrideData = CliDB.LiquidTypeStorage.LookupByKey(overrideLiquid);
|
||||||
if (overrideData != null)
|
if (overrideData != null)
|
||||||
{
|
{
|
||||||
liquidType = overrideLiquid;
|
liquidType = overrideLiquid;
|
||||||
@@ -2126,14 +2109,13 @@ namespace Game.Maps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var liquidInfo = new LiquidData();
|
data.LiquidInfo.HasValue = true;
|
||||||
liquidInfo.level = vmapData.liquidInfo.Value.Level;
|
data.LiquidInfo.Value.level = wmoData.liquidInfo.Value.Level;
|
||||||
liquidInfo.depth_level = vmapData.floorZ;
|
data.LiquidInfo.Value.depth_level = wmoData.floorZ;
|
||||||
liquidInfo.entry = liquidType;
|
data.LiquidInfo.Value.entry = liquidType;
|
||||||
liquidInfo.type_flags = (LiquidHeaderTypeFlags)(1u << (int)liquidFlagType);
|
data.LiquidInfo.Value.type_flags = (LiquidHeaderTypeFlags)(1 << (int)liquidFlagType);
|
||||||
data.LiquidInfo.Set(liquidInfo);
|
|
||||||
|
|
||||||
float delta = vmapData.liquidInfo.Value.Level - z;
|
float delta = wmoData.liquidInfo.Value.Level - z;
|
||||||
if (delta > collisionHeight)
|
if (delta > collisionHeight)
|
||||||
data.LiquidStatus = ZLiquidStatus.UnderWater;
|
data.LiquidStatus = ZLiquidStatus.UnderWater;
|
||||||
else if (delta > 0.0f)
|
else if (delta > 0.0f)
|
||||||
@@ -2144,11 +2126,11 @@ namespace Game.Maps
|
|||||||
data.LiquidStatus = ZLiquidStatus.AboveWater;
|
data.LiquidStatus = ZLiquidStatus.AboveWater;
|
||||||
}
|
}
|
||||||
// look up liquid data from grid map
|
// look up liquid data from grid map
|
||||||
if (gmap != null && (data.LiquidStatus == ZLiquidStatus.AboveWater || data.LiquidStatus == ZLiquidStatus.NoWater))
|
if (gmap != null && useGridLiquid)
|
||||||
{
|
{
|
||||||
LiquidData gridMapLiquid = new();
|
LiquidData gridMapLiquid = new();
|
||||||
ZLiquidStatus gridMapStatus = gmap.GetLiquidStatus(x, y, z, reqLiquidType, gridMapLiquid, collisionHeight);
|
ZLiquidStatus gridMapStatus = gmap.GetLiquidStatus(x, y, z, reqLiquidType, gridMapLiquid, collisionHeight);
|
||||||
if (gridMapStatus != ZLiquidStatus.NoWater && (gridMapLiquid.level > vmapData.floorZ))
|
if (gridMapStatus != ZLiquidStatus.NoWater && (wmoData == null || gridMapLiquid.level > wmoData.floorZ))
|
||||||
{
|
{
|
||||||
if (GetId() == 530 && gridMapLiquid.entry == 2)
|
if (GetId() == 530 && gridMapLiquid.entry == 2)
|
||||||
gridMapLiquid.entry = 15;
|
gridMapLiquid.entry = 15;
|
||||||
@@ -2629,7 +2611,7 @@ namespace Game.Maps
|
|||||||
else // value changed, update heap position
|
else // value changed, update heap position
|
||||||
{
|
{
|
||||||
Cypher.Assert(now < next.respawnTime); // infinite loop guard
|
Cypher.Assert(now < next.respawnTime); // infinite loop guard
|
||||||
//_respawnTimes.decrease(next->handle);
|
//_respawnTimes.decrease(next.handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -774,7 +774,10 @@ namespace Game.Movement
|
|||||||
void NormalizePath()
|
void NormalizePath()
|
||||||
{
|
{
|
||||||
for (uint i = 0; i < _pathPoints.Length; ++i)
|
for (uint i = 0; i < _pathPoints.Length; ++i)
|
||||||
|
{
|
||||||
|
_pathPoints[i].Z += _sourceUnit.GetCollisionHeight();
|
||||||
_sourceUnit.UpdateAllowedPositionZ(_pathPoints[i].X, _pathPoints[i].Y, ref _pathPoints[i].Z);
|
_sourceUnit.UpdateAllowedPositionZ(_pathPoints[i].X, _pathPoints[i].Y, ref _pathPoints[i].Z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildShortcut()
|
void BuildShortcut()
|
||||||
|
|||||||
@@ -1449,7 +1449,7 @@ namespace Scripts.Spells.Druid
|
|||||||
{
|
{
|
||||||
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id, difficulty);
|
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spell_id, difficulty);
|
||||||
|
|
||||||
if (requireOutdoors && !targetPlayer.GetMap().IsOutdoors(targetPlayer.GetPhaseShift(), targetPlayer.GetPositionX(), targetPlayer.GetPositionY(), targetPlayer.GetPositionZ()))
|
if (requireOutdoors && !targetPlayer.IsOutdoors())
|
||||||
return SpellCastResult.OnlyOutdoors;
|
return SpellCastResult.OnlyOutdoors;
|
||||||
|
|
||||||
return spellInfo.CheckLocation(targetPlayer.GetMapId(), targetPlayer.GetZoneId(), targetPlayer.GetAreaId(), targetPlayer);
|
return spellInfo.CheckLocation(targetPlayer.GetMapId(), targetPlayer.GetZoneId(), targetPlayer.GetAreaId(), targetPlayer);
|
||||||
|
|||||||
Reference in New Issue
Block a user