Core/Entities: Fix some weird movement due to los issues
Port From (https://github.com/TrinityCore/TrinityCore/commit/446fc391f02d3ca8e1332b58f910a5b7d1c8e226)
This commit is contained in:
@@ -62,6 +62,8 @@ namespace Framework.Constants
|
||||
public const float InvalidHeight = -100000.0f;
|
||||
public const float MaxHeight = 100000.0f;
|
||||
public const float MaxFallDistance = 250000.0f;
|
||||
public const float GroundHeightTolerance = 0.05f;
|
||||
public const float DefaultCollesionHeight = 2.03128f; // Most common value in dbc
|
||||
|
||||
public const uint MapMagic = 0x5350414D; //"MAPS";
|
||||
public const uint MapVersionMagic = 0x392E3176; //"v1.9";
|
||||
|
||||
@@ -902,8 +902,8 @@ namespace Game.Chat
|
||||
Global.DB2Mgr.Map2ZoneCoordinates((int)zoneId, ref zoneX, ref zoneY);
|
||||
|
||||
Map map = obj.GetMap();
|
||||
float groundZ = map.GetHeight(obj.GetPhaseShift(), obj.GetPositionX(), obj.GetPositionY(), MapConst.MaxHeight);
|
||||
float floorZ = map.GetHeight(obj.GetPhaseShift(), obj.GetPositionX(), obj.GetPositionY(), obj.GetPositionZ());
|
||||
float groundZ = obj.GetMapHeight(obj.GetPositionX(), obj.GetPositionY(), MapConst.MaxHeight);
|
||||
float floorZ = obj.GetMapHeight(obj.GetPositionX(), obj.GetPositionY(), obj.GetPositionZ());
|
||||
|
||||
GridCoord gridCoord = GridDefines.ComputeGridCoord(obj.GetPositionX(), obj.GetPositionY());
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace Game.Collision
|
||||
|
||||
public float GetHeight(float x, float y, float z, float maxSearchDist, PhaseShift phaseShift)
|
||||
{
|
||||
Vector3 v = new(x, y, z + 0.5f);
|
||||
Vector3 v = new(x, y, z);
|
||||
Ray r = new(v, new Vector3(0, 0, -1));
|
||||
DynamicTreeIntersectionCallback callback = new(phaseShift);
|
||||
impl.IntersectZAllignedRay(r, callback, ref maxSearchDist);
|
||||
|
||||
@@ -2717,7 +2717,7 @@ namespace Game.Entities
|
||||
// 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 = 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 + MapConst.GroundHeightTolerance) || MathFunctions.fuzzyLt(GetPositionZMinusOffset(), ground - MapConst.GroundHeightTolerance)); // Can be underground too, prevent the falling
|
||||
|
||||
if (GetCreatureTemplate().InhabitType.HasAnyFlag(InhabitType.Air) && isInAir && !IsFalling())
|
||||
{
|
||||
|
||||
@@ -1917,11 +1917,12 @@ namespace Game.Entities
|
||||
{
|
||||
if (IsInWorld)
|
||||
{
|
||||
oz += GetCollisionHeight();
|
||||
float x, y, z;
|
||||
if (IsTypeId(TypeId.Player))
|
||||
{
|
||||
GetPosition(out x, out y, out z);
|
||||
z += GetMidsectionHeight();
|
||||
z += GetCollisionHeight();
|
||||
}
|
||||
else
|
||||
GetHitSpherePointFor(new Position(ox, oy, oz), out x, out y, out z);
|
||||
@@ -1937,21 +1938,30 @@ namespace Game.Entities
|
||||
if (!IsInMap(obj))
|
||||
return false;
|
||||
|
||||
float x, y, z;
|
||||
float ox, oy, oz;
|
||||
if (obj.IsTypeId(TypeId.Player))
|
||||
{
|
||||
obj.GetPosition(out x, out y, out z);
|
||||
z += GetMidsectionHeight();
|
||||
obj.GetPosition(out ox, out oy, out oz);
|
||||
oz += GetCollisionHeight();
|
||||
}
|
||||
else
|
||||
obj.GetHitSpherePointFor(new (GetPositionX(), GetPositionY(), GetPositionZ() + GetMidsectionHeight()), out x, out y, out z);
|
||||
obj.GetHitSpherePointFor(new (GetPositionX(), GetPositionY(), GetPositionZ() + GetCollisionHeight()), out ox, out oy, out oz);
|
||||
|
||||
return IsWithinLOS(x, y, z, checks, ignoreFlags);
|
||||
float x, y, z;
|
||||
if (IsPlayer())
|
||||
{
|
||||
GetPosition(out x, out y, out z);
|
||||
z += GetCollisionHeight();
|
||||
}
|
||||
else
|
||||
GetHitSpherePointFor(new (obj.GetPositionX(), obj.GetPositionY(), obj.GetPositionZ() + obj.GetCollisionHeight()), out x, out y, out z);
|
||||
|
||||
return GetMap().IsInLineOfSight(GetPhaseShift(), x, y, z, ox, oy, oz, checks, ignoreFlags);
|
||||
}
|
||||
|
||||
Position GetHitSpherePointFor(Position dest)
|
||||
{
|
||||
Vector3 vThis = new(GetPositionX(), GetPositionY(), GetPositionZ() + GetMidsectionHeight());
|
||||
Vector3 vThis = new(GetPositionX(), GetPositionY(), GetPositionZ() + GetCollisionHeight());
|
||||
Vector3 vObj = new(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
|
||||
Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * Math.Min(dest.GetExactDist(GetPosition()), GetCombatReach());
|
||||
|
||||
@@ -2076,9 +2086,7 @@ namespace Game.Entities
|
||||
|
||||
public void UpdateGroundPositionZ(float x, float y, ref float z)
|
||||
{
|
||||
float new_z = GetMap().GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
if (new_z > MapConst.InvalidHeight)
|
||||
z = new_z + 0.05f; // just to be sure that we are not a few pixel under the surface
|
||||
z = GetMapHeight(x, y, z);
|
||||
}
|
||||
|
||||
public void UpdateAllowedPositionZ(float x, float y, ref float z)
|
||||
@@ -2098,8 +2106,8 @@ namespace Game.Entities
|
||||
bool canSwim = ToCreature().CanSwim();
|
||||
float ground_z = z;
|
||||
float max_z = canSwim
|
||||
? GetMap().GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, ref ground_z, !ToUnit().HasAuraType(AuraType.WaterWalk))
|
||||
: ((ground_z = GetMap().GetHeight(GetPhaseShift(), x, y, z, true)));
|
||||
? GetMapWaterOrGroundLevel(x, y, z, ref ground_z)
|
||||
: (ground_z = GetMapHeight(x, y, z));
|
||||
if (max_z > MapConst.InvalidHeight)
|
||||
{
|
||||
if (z > max_z)
|
||||
@@ -2110,7 +2118,7 @@ namespace Game.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
float ground_z = GetMap().GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
float ground_z = GetMapHeight(x, y, z);
|
||||
if (z < ground_z)
|
||||
z = ground_z;
|
||||
}
|
||||
@@ -2122,7 +2130,7 @@ namespace Game.Entities
|
||||
if (!ToPlayer().CanFly())
|
||||
{
|
||||
float ground_z = z;
|
||||
float max_z = GetMap().GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, ref ground_z, !ToUnit().HasAuraType(AuraType.WaterWalk));
|
||||
float max_z = GetMapWaterOrGroundLevel(x, y, z, ref ground_z);
|
||||
if (max_z > MapConst.InvalidHeight)
|
||||
{
|
||||
if (z > max_z)
|
||||
@@ -2133,7 +2141,7 @@ namespace Game.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
float ground_z = GetMap().GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
float ground_z = GetMapHeight(x, y, z);
|
||||
if (z < ground_z)
|
||||
z = ground_z;
|
||||
}
|
||||
@@ -2141,7 +2149,7 @@ namespace Game.Entities
|
||||
}
|
||||
default:
|
||||
{
|
||||
float ground_z = GetMap().GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
float ground_z = GetMapHeight(x, y, z);
|
||||
if (ground_z > MapConst.InvalidHeight)
|
||||
z = ground_z;
|
||||
break;
|
||||
@@ -2202,7 +2210,7 @@ namespace Game.Entities
|
||||
public Position GetNearPosition(float dist, float angle)
|
||||
{
|
||||
var pos = GetPosition();
|
||||
MovePosition(ref pos, dist, angle);
|
||||
MovePosition(pos, dist, angle);
|
||||
return pos;
|
||||
}
|
||||
|
||||
@@ -2216,7 +2224,7 @@ namespace Game.Entities
|
||||
public Position GetRandomNearPosition(float radius)
|
||||
{
|
||||
var pos = GetPosition();
|
||||
MovePosition(ref pos, radius * (float)RandomHelper.NextDouble(), (float)RandomHelper.NextDouble() * MathFunctions.PI * 2);
|
||||
MovePosition(pos, radius * (float)RandomHelper.NextDouble(), (float)RandomHelper.NextDouble() * MathFunctions.PI * 2);
|
||||
return pos;
|
||||
}
|
||||
|
||||
@@ -2226,7 +2234,7 @@ namespace Game.Entities
|
||||
GetNearPoint(obj, out x, out y, out z, obj.GetCombatReach(), distance2d, GetAngle(obj));
|
||||
}
|
||||
|
||||
public void MovePosition(ref Position pos, float dist, float angle)
|
||||
public void MovePosition(Position pos, float dist, float angle)
|
||||
{
|
||||
angle += GetOrientation();
|
||||
float destx = pos.posX + dist * (float)Math.Cos(angle);
|
||||
@@ -2239,8 +2247,8 @@ namespace Game.Entities
|
||||
return;
|
||||
}
|
||||
|
||||
float ground = GetMap().GetHeight(GetPhaseShift(), destx, desty, MapConst.MaxHeight, true);
|
||||
float floor = GetMap().GetHeight(GetPhaseShift(), destx, desty, pos.posZ, true);
|
||||
float ground = GetMapHeight(destx, desty, MapConst.MaxHeight);
|
||||
float floor = GetMapHeight(destx, desty, pos.posZ);
|
||||
float destz = Math.Abs(ground - pos.posZ) <= Math.Abs(floor - pos.posZ) ? ground : floor;
|
||||
|
||||
float step = dist / 10.0f;
|
||||
@@ -2270,37 +2278,12 @@ namespace Game.Entities
|
||||
pos.SetOrientation(GetOrientation());
|
||||
}
|
||||
|
||||
float NormalizeZforCollision(WorldObject obj, float x, float y, float z)
|
||||
{
|
||||
float ground = obj.GetMap().GetHeight(obj.GetPhaseShift(), x, y, MapConst.MaxHeight, true);
|
||||
float floor = obj.GetMap().GetHeight(obj.GetPhaseShift(), x, y, z + 2.0f, true);
|
||||
float helper = Math.Abs(ground - z) <= Math.Abs(floor - z) ? ground : floor;
|
||||
if (z > helper) // must be above ground
|
||||
{
|
||||
Unit unit = obj.ToUnit();
|
||||
if (unit)
|
||||
{
|
||||
if (unit.CanFly())
|
||||
return z;
|
||||
}
|
||||
LiquidData liquid_status;
|
||||
ZLiquidStatus res = obj.GetMap().GetLiquidStatus(obj.GetPhaseShift(), x, y, z, MapConst.MapAllLiquidTypes, out liquid_status);
|
||||
if (res != 0 && liquid_status.level > helper) // water must be above ground
|
||||
{
|
||||
if (liquid_status.level > z) // z is underwater
|
||||
return z;
|
||||
else
|
||||
return Math.Abs(liquid_status.level - z) <= Math.Abs(helper - z) ? liquid_status.level : helper;
|
||||
}
|
||||
}
|
||||
return helper;
|
||||
}
|
||||
|
||||
public void MovePositionToFirstCollision(ref Position pos, float dist, float angle)
|
||||
{
|
||||
angle += GetOrientation();
|
||||
float destx = pos.posX + dist * (float)Math.Cos(angle);
|
||||
float desty = pos.posY + dist * (float)Math.Sin(angle);
|
||||
float destz = pos.posZ;
|
||||
|
||||
// Prevent invalid coordinates here, position is unchanged
|
||||
if (!GridDefines.IsValidMapCoord(destx, desty))
|
||||
@@ -2309,8 +2292,8 @@ namespace Game.Entities
|
||||
return;
|
||||
}
|
||||
|
||||
float destz = NormalizeZforCollision(this, destx, desty, pos.GetPositionZ());
|
||||
bool col = Global.VMapMgr.GetObjectHitPos(PhasingHandler.GetTerrainMapId(GetPhaseShift(), GetMap(), pos.posX, pos.posY), pos.posX, pos.posY, pos.posZ + 0.5f, destx, desty, destz + 0.5f, out destx, out desty, out destz, -0.5f);
|
||||
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);
|
||||
|
||||
// collision occured
|
||||
if (col)
|
||||
@@ -2322,7 +2305,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
// check dynamic collision
|
||||
col = GetMap().GetObjectHitPos(GetPhaseShift(), pos.posX, pos.posY, pos.posZ + 0.5f, destx, desty, destz + 0.5f, out destx, out desty, out destz, -0.5f);
|
||||
col = GetMap().GetObjectHitPos(GetPhaseShift(), pos.posX, pos.posY, pos.posZ, destx, desty, destz, out destx, out desty, out destz, -0.5f);
|
||||
|
||||
// Collided with a gameobject
|
||||
if (col)
|
||||
@@ -2341,7 +2324,7 @@ namespace Game.Entities
|
||||
{
|
||||
destx -= step * (float)Math.Cos(angle);
|
||||
desty -= step * (float)Math.Sin(angle);
|
||||
destz = NormalizeZforCollision(this, destx, desty, pos.GetPositionZ());
|
||||
UpdateAllowedPositionZ(destx, desty, ref destz);
|
||||
}
|
||||
// we have correct destz now
|
||||
else
|
||||
@@ -2353,7 +2336,7 @@ namespace Game.Entities
|
||||
|
||||
GridDefines.NormalizeMapCoord(ref pos.posX);
|
||||
GridDefines.NormalizeMapCoord(ref pos.posY);
|
||||
pos.posZ = NormalizeZforCollision(this, destx, desty, pos.GetPositionZ());
|
||||
UpdateAllowedPositionZ(destx, desty, ref pos.posZ);
|
||||
pos.SetOrientation(GetOrientation());
|
||||
}
|
||||
|
||||
@@ -2361,7 +2344,24 @@ namespace Game.Entities
|
||||
{
|
||||
if (!IsInWorld)
|
||||
return m_staticFloorZ;
|
||||
return Math.Max(m_staticFloorZ, GetMap().GetGameObjectFloor(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ()));
|
||||
return Math.Max(m_staticFloorZ, GetMap().GetGameObjectFloor(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ() + GetCollisionHeight()));
|
||||
}
|
||||
|
||||
float GetMapWaterOrGroundLevel(float x, float y, float z, ref float ground)
|
||||
{
|
||||
Unit unit = ToUnit();
|
||||
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)
|
||||
{
|
||||
if (z != MapConst.MaxHeight)
|
||||
z += GetCollisionHeight();
|
||||
|
||||
return GetMap().GetHeight(GetPhaseShift(), x, y, z, vmap, distanceToSearch);
|
||||
}
|
||||
|
||||
public void SetLocationInstanceId(uint _instanceId) { instanceId = _instanceId; }
|
||||
|
||||
@@ -824,7 +824,8 @@ namespace Game.Entities
|
||||
{
|
||||
var displayInfo = CliDB.CreatureDisplayInfoStorage.LookupByKey(GetNativeDisplayId());
|
||||
var modelData = CliDB.CreatureModelDataStorage.LookupByKey(displayInfo.ModelID);
|
||||
return scaleMod * (mountModelData.MountHeight + modelData.CollisionHeight * 0.5f);
|
||||
float collisionHeight = scaleMod * (mountModelData.MountHeight + modelData.CollisionHeight * modelData.ModelScale * displayInfo.CreatureModelScale * 0.5f);
|
||||
return collisionHeight == 0.0f ? MapConst.DefaultCollesionHeight : collisionHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -833,7 +834,8 @@ namespace Game.Entities
|
||||
var defaultDisplayInfo = CliDB.CreatureDisplayInfoStorage.LookupByKey(GetNativeDisplayId());
|
||||
var defaultModelData = CliDB.CreatureModelDataStorage.LookupByKey(defaultDisplayInfo.ModelID);
|
||||
|
||||
return scaleMod * defaultModelData.CollisionHeight;
|
||||
float collisionHeight1 = scaleMod * defaultModelData.CollisionHeight * defaultModelData.ModelScale * defaultDisplayInfo.CreatureModelScale;
|
||||
return collisionHeight1 == 0.0f ? MapConst.DefaultCollesionHeight : collisionHeight1;
|
||||
}
|
||||
|
||||
public Guardian GetGuardianPet()
|
||||
@@ -1005,12 +1007,12 @@ namespace Game.Entities
|
||||
if (player != null)
|
||||
player.SetFallInformation(0, GetPositionZ());
|
||||
|
||||
float height = pos.GetPositionZ();
|
||||
float height = pos.GetPositionZ() + vehicle.GetBase().GetCollisionHeight();
|
||||
|
||||
MoveSplineInit init = new(this);
|
||||
|
||||
// Creatures without inhabit type air should begin falling after exiting the vehicle
|
||||
if (IsTypeId(TypeId.Unit) && !ToCreature().CanFly() && height > GetMap().GetWaterOrGroundLevel(GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), ref height) + 0.1f)
|
||||
if (IsTypeId(TypeId.Unit) && !ToCreature().CanFly() && height > GetMap().GetWaterOrGroundLevel(GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + vehicle.GetBase().GetCollisionHeight(), ref height))
|
||||
init.SetFall();
|
||||
|
||||
init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), height, false);
|
||||
|
||||
@@ -501,7 +501,7 @@ namespace Game.Maps
|
||||
}
|
||||
|
||||
// Get water state on map
|
||||
public ZLiquidStatus GetLiquidStatus(float x, float y, float z, uint ReqLiquidType, LiquidData data)
|
||||
public ZLiquidStatus GetLiquidStatus(float x, float y, float z, uint ReqLiquidType, LiquidData data, float collisionHeight)
|
||||
{
|
||||
// Check water type (if no water return)
|
||||
if (_liquidGlobalFlags == 0 && _liquidFlags == null)
|
||||
@@ -568,7 +568,7 @@ namespace Game.Maps
|
||||
float ground_level = GetHeight(x, y);
|
||||
|
||||
// Check water level and ground level
|
||||
if (liquid_level < ground_level || z < ground_level - 2)
|
||||
if (liquid_level < ground_level || z < ground_level)
|
||||
return ZLiquidStatus.NoWater;
|
||||
|
||||
// All ok in water . store data
|
||||
@@ -583,7 +583,7 @@ namespace Game.Maps
|
||||
// For speed check as int values
|
||||
float delta = liquid_level - z;
|
||||
|
||||
if (delta > 2.0f) // Under water
|
||||
if (delta > collisionHeight) // Under water
|
||||
return ZLiquidStatus.UnderWater;
|
||||
if (delta > 0.0f) // In water
|
||||
return ZLiquidStatus.InWater;
|
||||
|
||||
+17
-21
@@ -1694,23 +1694,23 @@ namespace Game.Maps
|
||||
return childMap != null && childMap.i_gridFileExists[(int)(gx * MapConst.MaxGrids + gy)];
|
||||
}
|
||||
|
||||
public float GetWaterOrGroundLevel(PhaseShift phaseShift, float x, float y, float z)
|
||||
public float GetWaterOrGroundLevel(PhaseShift phaseShift, float x, float y, float z, float collisionHeight = MapConst.DefaultCollesionHeight)
|
||||
{
|
||||
float ground = 0f;
|
||||
return GetWaterOrGroundLevel(phaseShift, x, y, z, ref ground);
|
||||
}
|
||||
|
||||
public float GetWaterOrGroundLevel(PhaseShift phaseShift, float x, float y, float z, ref float ground, bool swim = false)
|
||||
public float GetWaterOrGroundLevel(PhaseShift phaseShift, float x, float y, float z, ref float ground, bool swim = false, float collisionHeight = MapConst.DefaultCollesionHeight)
|
||||
{
|
||||
if (GetGridMap(PhasingHandler.GetTerrainMapId(phaseShift, this, x, y), x, y) != null)
|
||||
{
|
||||
// we need ground level (including grid height version) for proper return water level in point
|
||||
float ground_z = GetHeight(phaseShift, x, y, z, true, 50.0f);
|
||||
float ground_z = GetHeight(phaseShift, x, y, z + collisionHeight, true, 50.0f);
|
||||
ground = ground_z;
|
||||
|
||||
LiquidData liquid_status;
|
||||
|
||||
ZLiquidStatus res = GetLiquidStatus(phaseShift, x, y, ground_z, MapConst.MapAllLiquidTypes, out liquid_status);
|
||||
ZLiquidStatus res = GetLiquidStatus(phaseShift, x, y, ground_z, MapConst.MapAllLiquidTypes, out liquid_status, collisionHeight);
|
||||
switch (res)
|
||||
{
|
||||
case ZLiquidStatus.AboveWater:
|
||||
@@ -1734,8 +1734,7 @@ namespace Game.Maps
|
||||
if (gmap != null)
|
||||
{
|
||||
float gridHeight = gmap.GetHeight(x, y);
|
||||
// look from a bit higher pos to find the floor, ignore under surface case
|
||||
if (z + 2.0f > gridHeight)
|
||||
if (z > gridHeight)
|
||||
mapHeight = gridHeight;
|
||||
}
|
||||
|
||||
@@ -1743,8 +1742,7 @@ namespace Game.Maps
|
||||
if (checkVMap)
|
||||
{
|
||||
if (Global.VMapMgr.IsHeightCalcEnabled())
|
||||
vmapHeight = Global.VMapMgr.GetHeight(terrainMapId, x, y, z + 2.0f, maxSearchDist);
|
||||
// look from a bit higher pos to find the floor
|
||||
vmapHeight = Global.VMapMgr.GetHeight(terrainMapId, x, y, z, maxSearchDist);
|
||||
}
|
||||
|
||||
// mapHeight set for any above raw ground Z or <= INVALID_HEIGHT
|
||||
@@ -1887,8 +1885,7 @@ namespace Game.Maps
|
||||
if (gmap != null)
|
||||
{
|
||||
float mapHeight = gmap.GetHeight(x, y);
|
||||
// z + 2.0f condition taken from GetHeight(), not sure if it's such a great choice...
|
||||
if (z + 2.0f > mapHeight && mapHeight > check_z)
|
||||
if (z > mapHeight && mapHeight > check_z)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -1975,13 +1972,12 @@ namespace Game.Maps
|
||||
return 0;
|
||||
}
|
||||
|
||||
public ZLiquidStatus GetLiquidStatus(PhaseShift phaseShift, float x, float y, float z, uint ReqLiquidType)
|
||||
public ZLiquidStatus GetLiquidStatus(PhaseShift phaseShift, float x, float y, float z, uint ReqLiquidType, float collisionHeight = MapConst.DefaultCollesionHeight)
|
||||
{
|
||||
LiquidData throwaway;
|
||||
return GetLiquidStatus(phaseShift, x, y, z, ReqLiquidType, out throwaway);
|
||||
return GetLiquidStatus(phaseShift, x, y, z, ReqLiquidType, out _, collisionHeight);
|
||||
}
|
||||
|
||||
public ZLiquidStatus GetLiquidStatus(PhaseShift phaseShift, float x, float y, float z, uint ReqLiquidType, out LiquidData data)
|
||||
public ZLiquidStatus GetLiquidStatus(PhaseShift phaseShift, float x, float y, float z, uint ReqLiquidType, out LiquidData data, float collisionHeight = MapConst.DefaultCollesionHeight)
|
||||
{
|
||||
data = new LiquidData();
|
||||
var result = ZLiquidStatus.NoWater;
|
||||
@@ -2037,7 +2033,7 @@ namespace Game.Maps
|
||||
float delta = liquid_level - z;
|
||||
|
||||
// Get position delta
|
||||
if (delta > 2.0f) // Under water
|
||||
if (delta > collisionHeight) // Under water
|
||||
return ZLiquidStatus.UnderWater;
|
||||
if (delta > 0.0f) // In water
|
||||
return ZLiquidStatus.InWater;
|
||||
@@ -2051,7 +2047,7 @@ namespace Game.Maps
|
||||
if (gmap != null)
|
||||
{
|
||||
var map_data = new LiquidData();
|
||||
ZLiquidStatus map_result = gmap.GetLiquidStatus(x, y, z, ReqLiquidType, map_data);
|
||||
ZLiquidStatus map_result = gmap.GetLiquidStatus(x, y, z, ReqLiquidType, map_data, collisionHeight);
|
||||
// Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER:
|
||||
if (map_result != ZLiquidStatus.NoWater && (map_data.level > ground_level))
|
||||
{
|
||||
@@ -2067,7 +2063,7 @@ namespace Game.Maps
|
||||
return result;
|
||||
}
|
||||
|
||||
public void GetFullTerrainStatusForPosition(PhaseShift phaseShift, float x, float y, float z, PositionFullTerrainStatus data, uint reqLiquidType = MapConst.MapAllLiquidTypes)
|
||||
public void GetFullTerrainStatusForPosition(PhaseShift phaseShift, float x, float y, float z, PositionFullTerrainStatus data, uint reqLiquidType = MapConst.MapAllLiquidTypes, float collisionHeight = MapConst.DefaultCollesionHeight)
|
||||
{
|
||||
uint terrainMapId = PhasingHandler.GetTerrainMapId(phaseShift, this, x, y);
|
||||
AreaAndLiquidData vmapData = Global.VMapMgr.GetAreaAndLiquidData(terrainMapId, x, y, z, reqLiquidType);
|
||||
@@ -2081,7 +2077,7 @@ namespace Game.Maps
|
||||
|
||||
// area lookup
|
||||
AreaTableRecord areaEntry = null;
|
||||
if (vmapData.areaInfo.HasValue && (z + 2.0f <= mapHeight || mapHeight <= vmapData.floorZ))
|
||||
if (vmapData.areaInfo.HasValue && (z <= mapHeight || mapHeight <= vmapData.floorZ))
|
||||
{
|
||||
WMOAreaTableRecord wmoEntry = Global.DB2Mgr.GetWMOAreaTable(vmapData.areaInfo.Value.RootId, vmapData.areaInfo.Value.AdtId, vmapData.areaInfo.Value.GroupId);
|
||||
if (wmoEntry != null)
|
||||
@@ -2110,7 +2106,7 @@ namespace Game.Maps
|
||||
|
||||
// liquid processing
|
||||
data.LiquidStatus = ZLiquidStatus.NoWater;
|
||||
if (vmapData.liquidInfo.HasValue && vmapData.liquidInfo.Value.Level > vmapData.floorZ && z + 2.0f > vmapData.floorZ)
|
||||
if (vmapData.liquidInfo.HasValue && vmapData.liquidInfo.Value.Level > vmapData.floorZ && z > vmapData.floorZ)
|
||||
{
|
||||
uint liquidType = vmapData.liquidInfo.Value.LiquidType;
|
||||
if (GetId() == 530 && liquidType == 2) // gotta love blizzard hacks
|
||||
@@ -2147,7 +2143,7 @@ namespace Game.Maps
|
||||
data.LiquidInfo.Set(liquidInfo);
|
||||
|
||||
float delta = vmapData.liquidInfo.Value.Level - z;
|
||||
if (delta > 2.0f)
|
||||
if (delta > collisionHeight)
|
||||
data.LiquidStatus = ZLiquidStatus.UnderWater;
|
||||
else if (delta > 0.0f)
|
||||
data.LiquidStatus = ZLiquidStatus.InWater;
|
||||
@@ -2160,7 +2156,7 @@ namespace Game.Maps
|
||||
if (gmap != null && (data.LiquidStatus == ZLiquidStatus.AboveWater || data.LiquidStatus == ZLiquidStatus.NoWater))
|
||||
{
|
||||
LiquidData gridMapLiquid = new();
|
||||
ZLiquidStatus gridMapStatus = gmap.GetLiquidStatus(x, y, z, reqLiquidType, gridMapLiquid);
|
||||
ZLiquidStatus gridMapStatus = gmap.GetLiquidStatus(x, y, z, reqLiquidType, gridMapLiquid, collisionHeight);
|
||||
if (gridMapStatus != ZLiquidStatus.NoWater && (gridMapLiquid.level > vmapData.floorZ))
|
||||
{
|
||||
if (GetId() == 530 && gridMapLiquid.entry == 2)
|
||||
|
||||
@@ -103,9 +103,7 @@ namespace Game.Movement
|
||||
GetPoint(owner, ref destination);
|
||||
|
||||
// Add LOS check for target point
|
||||
Position currentPosition = owner.GetPosition();
|
||||
bool isInLOS = Global.VMapMgr.IsInLineOfSight(PhasingHandler.GetTerrainMapId(owner.GetPhaseShift(), owner.GetMap(), currentPosition.posX, currentPosition.posY), currentPosition.posX, currentPosition.posY, currentPosition.posZ + 2.0f, destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ() + 2.0f, ModelIgnoreFlags.Nothing);
|
||||
if (!isInLOS)
|
||||
if (!owner.IsWithinLOS(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ()))
|
||||
{
|
||||
_timer.Reset(200);
|
||||
return;
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace Game.Movement
|
||||
// Check both start and end points, if they're both in water, then we can *safely* let the creature move
|
||||
for (uint i = 0; i < _pathPoints.Length; ++i)
|
||||
{
|
||||
ZLiquidStatus status = _sourceUnit.GetMap().GetLiquidStatus(_sourceUnit.GetPhaseShift(), _pathPoints[i].X, _pathPoints[i].Y, _pathPoints[i].Z, MapConst.MapAllLiquidTypes);
|
||||
ZLiquidStatus status = _sourceUnit.GetMap().GetLiquidStatus(_sourceUnit.GetPhaseShift(), _pathPoints[i].X, _pathPoints[i].Y, _pathPoints[i].Z, MapConst.MapAllLiquidTypes, _sourceUnit.GetCollisionHeight());
|
||||
// One of the points is not in the water, cancel movement.
|
||||
if (status == ZLiquidStatus.NoWater)
|
||||
{
|
||||
@@ -839,7 +839,7 @@ namespace Game.Movement
|
||||
NavTerrainFlag GetNavTerrain(float x, float y, float z)
|
||||
{
|
||||
LiquidData data;
|
||||
ZLiquidStatus liquidStatus = _sourceUnit.GetMap().GetLiquidStatus(_sourceUnit.GetPhaseShift(), x, y, z, MapConst.MapAllLiquidTypes, out data);
|
||||
ZLiquidStatus liquidStatus = _sourceUnit.GetMap().GetLiquidStatus(_sourceUnit.GetPhaseShift(), x, y, z, MapConst.MapAllLiquidTypes, out data, _sourceUnit.GetCollisionHeight());
|
||||
if (liquidStatus == ZLiquidStatus.NoWater)
|
||||
return NavTerrainFlag.Ground;
|
||||
|
||||
|
||||
@@ -382,7 +382,7 @@ namespace Game.Movement
|
||||
float moveTimeHalf = (float)(speedZ / gravity);
|
||||
float dist = 2 * moveTimeHalf * speedXY;
|
||||
_owner.GetNearPoint2D(out float x, out float y, dist, _owner.GetOrientation() + angle);
|
||||
float z = _owner.GetPositionZ() + _owner.GetMidsectionHeight();
|
||||
float z = _owner.GetPositionZ();
|
||||
_owner.UpdateAllowedPositionZ(x, y, ref z);
|
||||
MoveJump(x, y, z, 0.0f, speedXY, speedZ);
|
||||
}
|
||||
@@ -440,7 +440,7 @@ namespace Game.Movement
|
||||
if (_owner.IsFlying())
|
||||
point.Z = z;
|
||||
else
|
||||
point.Z = _owner.GetMap().GetHeight(_owner.GetPhaseShift(), point.X, point.Y, z);
|
||||
point.Z = _owner.GetMapHeight(point.X, point.Y, z);
|
||||
|
||||
init.args.path[i] = point;
|
||||
}
|
||||
@@ -518,7 +518,7 @@ namespace Game.Movement
|
||||
public void MoveFall(uint id = 0)
|
||||
{
|
||||
// use larger distance for vmap height search than in most other cases
|
||||
float tz = _owner.GetMap().GetHeight(_owner.GetPhaseShift(), _owner.GetPositionX(), _owner.GetPositionY(), _owner.GetPositionZ(), true, MapConst.MaxFallDistance);
|
||||
float tz = _owner.GetMapHeight(_owner.GetPositionX(), _owner.GetPositionY(), _owner.GetPositionZ(), true, MapConst.MaxFallDistance);
|
||||
if (tz <= MapConst.InvalidHeight)
|
||||
return;
|
||||
|
||||
|
||||
@@ -858,10 +858,10 @@ namespace Game.Spells
|
||||
float angle = (float)RandomHelper.NextDouble() * (MathFunctions.PI * 35.0f / 180.0f) - (float)(Math.PI * 17.5f / 180.0f);
|
||||
m_caster.GetClosePoint(out x, out y, out z, SharedConst.DefaultPlayerBoundingRadius, dis, angle);
|
||||
|
||||
float ground = m_caster.GetMap().GetHeight(m_caster.GetPhaseShift(), x, y, z, true, 50.0f);
|
||||
float ground = m_caster.GetMapHeight(x, y, z);
|
||||
float liquidLevel = MapConst.VMAPInvalidHeightValue;
|
||||
LiquidData liquidData;
|
||||
if (m_caster.GetMap().GetLiquidStatus(m_caster.GetPhaseShift(), x, y, z, MapConst.MapAllLiquidTypes, out liquidData) != 0)
|
||||
if (m_caster.GetMap().GetLiquidStatus(m_caster.GetPhaseShift(), x, y, z, MapConst.MapAllLiquidTypes, out liquidData, m_caster.GetCollisionHeight()) != 0)
|
||||
liquidLevel = liquidData.level;
|
||||
|
||||
if (liquidLevel <= ground) // When there is no liquid Map.GetWaterOrGroundLevel returns ground level
|
||||
|
||||
Reference in New Issue
Block a user