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:
hondacrx
2021-09-26 11:32:01 -04:00
parent 9d5cf1d4ae
commit 7befdbd11b
9 changed files with 275 additions and 174 deletions
+23 -4
View File
@@ -26,6 +26,7 @@ namespace Game.Collision
{
public virtual void Invoke(Vector3 point, uint 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 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)
{
bool result = IntersectTriangle(triangles[(int)entry], vertices, ray, ref distance);
if (result)
hit = true;
hit = IntersectTriangle(triangles[(int)entry], vertices, ray, ref distance) || hit;
return hit;
}
@@ -266,4 +264,25 @@ namespace Game.Collision
PhaseShift _phaseShift;
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;
}
}
+25
View File
@@ -148,6 +148,31 @@ namespace Game.Collision
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;
}
@@ -225,7 +225,7 @@ namespace Game.Collision
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))
{
@@ -239,6 +239,7 @@ namespace Game.Collision
floor = info.ground_Z;
Cypher.Assert(floor < float.MaxValue);
type = info.hitModel.GetLiquidType(); // entry from LiquidType.dbc
mogpFlags = info.hitModel.GetMogpFlags();
if (reqLiquidType != 0 && !Convert.ToBoolean(Global.DB2Mgr.GetLiquidFlags(type) & reqLiquidType))
return false;
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()
{
if (iModel == null)
@@ -177,7 +222,8 @@ namespace Game.Collision
public void EnableCollision(bool enable) { _collisionEnabled = enable; }
bool IsCollisionEnabled() { return _collisionEnabled; }
public bool IsMapObject() { return isWmo; }
public byte GetNameSetId() { return owner.GetNameSetId(); }
public static void LoadGameObjectModelList()
{
uint oldMSTime = Time.GetMSTime();