Core/Maps: Implemented getting area id from gameobject spawns
This commit is contained in:
@@ -24,6 +24,7 @@ namespace Game.Collision
|
|||||||
public class WorkerCallback
|
public class WorkerCallback
|
||||||
{
|
{
|
||||||
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 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; }
|
||||||
public virtual bool Invoke(Ray ray, uint idx, ref float maxDist) { return false; }
|
public virtual bool Invoke(Ray ray, uint idx, ref float maxDist) { return false; }
|
||||||
@@ -59,7 +60,7 @@ namespace Game.Collision
|
|||||||
zDist = float.PositiveInfinity;
|
zDist = float.PositiveInfinity;
|
||||||
zVec = down;
|
zVec = down;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<GroupModel> prims;
|
List<GroupModel> prims;
|
||||||
public GroupModel hit;
|
public GroupModel hit;
|
||||||
public float zDist;
|
public float zDist;
|
||||||
@@ -245,5 +246,21 @@ namespace Game.Collision
|
|||||||
PhaseShift _phaseShift;
|
PhaseShift _phaseShift;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class DynamicTreeAreaInfoCallback : WorkerCallback
|
||||||
|
{
|
||||||
|
public DynamicTreeAreaInfoCallback(PhaseShift phaseShift)
|
||||||
|
{
|
||||||
|
_phaseShift = phaseShift;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Invoke(Vector3 p, IModel obj)
|
||||||
|
{
|
||||||
|
obj.IntersectPoint(p, _areaInfo, _phaseShift);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AreaInfo GetAreaInfo() { return _areaInfo; }
|
||||||
|
|
||||||
|
PhaseShift _phaseShift;
|
||||||
|
AreaInfo _areaInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,12 +23,11 @@ namespace Game.Collision
|
|||||||
{
|
{
|
||||||
public class DynamicMapTree
|
public class DynamicMapTree
|
||||||
{
|
{
|
||||||
DynTreeImpl impl;
|
|
||||||
|
|
||||||
public DynamicMapTree()
|
public DynamicMapTree()
|
||||||
{
|
{
|
||||||
impl = new DynTreeImpl();
|
impl = new DynTreeImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insert(GameObjectModel mdl)
|
public void insert(GameObjectModel mdl)
|
||||||
{
|
{
|
||||||
impl.insert(mdl);
|
impl.insert(mdl);
|
||||||
@@ -128,6 +127,30 @@ namespace Game.Collision
|
|||||||
else
|
else
|
||||||
return float.NegativeInfinity;
|
return float.NegativeInfinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool getAreaInfo(float x, float y, ref float z, PhaseShift phaseShift, out uint flags, out int adtId, out int rootId, out int groupId)
|
||||||
|
{
|
||||||
|
flags = 0;
|
||||||
|
adtId = 0;
|
||||||
|
rootId = 0;
|
||||||
|
groupId = 0;
|
||||||
|
|
||||||
|
Vector3 v = new Vector3(x, y, z + 0.5f);
|
||||||
|
DynamicTreeAreaInfoCallback intersectionCallBack = new DynamicTreeAreaInfoCallback(phaseShift);
|
||||||
|
impl.intersectPoint(v, intersectionCallBack);
|
||||||
|
if (intersectionCallBack.GetAreaInfo().result)
|
||||||
|
{
|
||||||
|
flags = intersectionCallBack.GetAreaInfo().flags;
|
||||||
|
adtId = intersectionCallBack.GetAreaInfo().adtId;
|
||||||
|
rootId = intersectionCallBack.GetAreaInfo().rootId;
|
||||||
|
groupId = intersectionCallBack.GetAreaInfo().groupId;
|
||||||
|
z = intersectionCallBack.GetAreaInfo().ground_Z;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynTreeImpl impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DynTreeImpl : RegularGrid2D<GameObjectModel, BIHWrap<GameObjectModel>>
|
public class DynTreeImpl : RegularGrid2D<GameObjectModel, BIHWrap<GameObjectModel>>
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ namespace Game.Collision
|
|||||||
{
|
{
|
||||||
public virtual bool IsSpawned() { return false; }
|
public virtual bool IsSpawned() { return false; }
|
||||||
public virtual uint GetDisplayId() { return 0; }
|
public virtual uint GetDisplayId() { return 0; }
|
||||||
|
public virtual byte GetNameSetId() { return 0; }
|
||||||
public virtual bool IsInPhase(PhaseShift phaseShift) { return false; }
|
public virtual bool IsInPhase(PhaseShift phaseShift) { return false; }
|
||||||
public virtual Vector3 GetPosition() { return Vector3.Zero; }
|
public virtual Vector3 GetPosition() { return Vector3.Zero; }
|
||||||
public virtual float GetOrientation() { return 0.0f; }
|
public virtual float GetOrientation() { return 0.0f; }
|
||||||
@@ -111,6 +112,33 @@ namespace Game.Collision
|
|||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void IntersectPoint(Vector3 point, AreaInfo info, PhaseShift phaseShift)
|
||||||
|
{
|
||||||
|
if (!isCollisionEnabled() || !owner.IsSpawned())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!owner.IsInPhase(phaseShift))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!iBound.contains(point))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 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.IntersectPoint(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;
|
||||||
|
info.adtId = owner.GetNameSetId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool UpdatePosition()
|
public bool UpdatePosition()
|
||||||
{
|
{
|
||||||
if (iModel == null)
|
if (iModel == null)
|
||||||
|
|||||||
@@ -27,5 +27,6 @@ namespace Game.Collision
|
|||||||
|
|
||||||
public virtual bool IntersectRay(Ray ray, ref float maxDist, bool stopAtFirstHit, PhaseShift phaseShift) { return false; }
|
public virtual bool IntersectRay(Ray ray, ref float maxDist, bool stopAtFirstHit, PhaseShift phaseShift) { return false; }
|
||||||
public virtual bool IntersectRay(Ray ray, ref float distance, bool stopAtFirstHit) { return false; }
|
public virtual bool IntersectRay(Ray ray, ref float distance, bool stopAtFirstHit) { return false; }
|
||||||
|
public virtual void IntersectPoint(Vector3 point, AreaInfo info, PhaseShift phaseShift) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ namespace Game.Collision
|
|||||||
} while (cell.isValid());
|
} while (cell.isValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
void intersectPoint(Vector3 point, WorkerCallback intersectCallback)
|
public void intersectPoint(Vector3 point, WorkerCallback intersectCallback)
|
||||||
{
|
{
|
||||||
Cell cell = Cell.ComputeCell(point.X, point.Y);
|
Cell cell = Cell.ComputeCell(point.X, point.Y);
|
||||||
if (!cell.isValid())
|
if (!cell.isValid())
|
||||||
|
|||||||
@@ -2157,8 +2157,8 @@ namespace Game.Entities
|
|||||||
uint modelId = m_goInfo.displayId;
|
uint modelId = m_goInfo.displayId;
|
||||||
DestructibleModelDataRecord modelData = CliDB.DestructibleModelDataStorage.LookupByKey(m_goInfo.DestructibleBuilding.DestructibleModelRec);
|
DestructibleModelDataRecord modelData = CliDB.DestructibleModelDataStorage.LookupByKey(m_goInfo.DestructibleBuilding.DestructibleModelRec);
|
||||||
if (modelData != null)
|
if (modelData != null)
|
||||||
if (modelData.State0Wmo != 0)
|
if (modelData.State1Wmo != 0)
|
||||||
modelId = modelData.State0Wmo;
|
modelId = modelData.State1Wmo;
|
||||||
SetDisplayId(modelId);
|
SetDisplayId(modelId);
|
||||||
|
|
||||||
if (setHealth)
|
if (setHealth)
|
||||||
@@ -2189,8 +2189,8 @@ namespace Game.Entities
|
|||||||
uint modelId = m_goInfo.displayId;
|
uint modelId = m_goInfo.displayId;
|
||||||
DestructibleModelDataRecord modelData = CliDB.DestructibleModelDataStorage.LookupByKey(m_goInfo.DestructibleBuilding.DestructibleModelRec);
|
DestructibleModelDataRecord modelData = CliDB.DestructibleModelDataStorage.LookupByKey(m_goInfo.DestructibleBuilding.DestructibleModelRec);
|
||||||
if (modelData != null)
|
if (modelData != null)
|
||||||
if (modelData.State1Wmo != 0)
|
if (modelData.State2Wmo != 0)
|
||||||
modelId = modelData.State1Wmo;
|
modelId = modelData.State2Wmo;
|
||||||
SetDisplayId(modelId);
|
SetDisplayId(modelId);
|
||||||
|
|
||||||
if (setHealth)
|
if (setHealth)
|
||||||
@@ -2209,8 +2209,8 @@ namespace Game.Entities
|
|||||||
uint modelId = m_goInfo.displayId;
|
uint modelId = m_goInfo.displayId;
|
||||||
DestructibleModelDataRecord modelData = CliDB.DestructibleModelDataStorage.LookupByKey(m_goInfo.DestructibleBuilding.DestructibleModelRec);
|
DestructibleModelDataRecord modelData = CliDB.DestructibleModelDataStorage.LookupByKey(m_goInfo.DestructibleBuilding.DestructibleModelRec);
|
||||||
if (modelData != null)
|
if (modelData != null)
|
||||||
if (modelData.State2Wmo != 0)
|
if (modelData.State3Wmo != 0)
|
||||||
modelId = modelData.State2Wmo;
|
modelId = modelData.State3Wmo;
|
||||||
SetDisplayId(modelId);
|
SetDisplayId(modelId);
|
||||||
|
|
||||||
// restores to full health
|
// restores to full health
|
||||||
@@ -2303,6 +2303,40 @@ namespace Game.Entities
|
|||||||
UpdateModel();
|
UpdateModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte GetNameSetId()
|
||||||
|
{
|
||||||
|
switch (GetGoType())
|
||||||
|
{
|
||||||
|
case GameObjectTypes.DestructibleBuilding:
|
||||||
|
DestructibleModelDataRecord modelData = CliDB.DestructibleModelDataStorage.LookupByKey(m_goInfo.DestructibleBuilding.DestructibleModelRec);
|
||||||
|
if (modelData != null)
|
||||||
|
{
|
||||||
|
switch (GetDestructibleState())
|
||||||
|
{
|
||||||
|
case GameObjectDestructibleState.Intact:
|
||||||
|
return modelData.State0NameSet;
|
||||||
|
case GameObjectDestructibleState.Damaged:
|
||||||
|
return modelData.State1NameSet;
|
||||||
|
case GameObjectDestructibleState.Destroyed:
|
||||||
|
return modelData.State2NameSet;
|
||||||
|
case GameObjectDestructibleState.Rebuilding:
|
||||||
|
return modelData.State3NameSet;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GameObjectTypes.GarrisonBuilding:
|
||||||
|
case GameObjectTypes.GarrisonPlot:
|
||||||
|
case GameObjectTypes.PhaseableMo:
|
||||||
|
return (byte)(GetByteValue(GameObjectFields.Flags, 1) & 0xF);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void EnableCollision(bool enable)
|
void EnableCollision(bool enable)
|
||||||
{
|
{
|
||||||
if (m_model == null)
|
if (m_model == null)
|
||||||
@@ -2753,12 +2787,9 @@ namespace Game.Entities
|
|||||||
_owner = owner;
|
_owner = owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsSpawned()
|
public override bool IsSpawned() { return _owner.isSpawned(); }
|
||||||
{
|
|
||||||
return _owner.isSpawned();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override uint GetDisplayId() { return _owner.GetDisplayId(); }
|
public override uint GetDisplayId() { return _owner.GetDisplayId(); }
|
||||||
|
public override byte GetNameSetId() { return _owner.GetNameSetId(); }
|
||||||
public override bool IsInPhase(PhaseShift phaseShift) { return _owner.GetPhaseShift().CanSee(phaseShift); }
|
public override bool IsInPhase(PhaseShift phaseShift) { return _owner.GetPhaseShift().CanSee(phaseShift); }
|
||||||
public override Vector3 GetPosition() { return new Vector3(_owner.GetPositionX(), _owner.GetPositionY(), _owner.GetPositionZ()); }
|
public override Vector3 GetPosition() { return new Vector3(_owner.GetPositionX(), _owner.GetPositionY(), _owner.GetPositionZ()); }
|
||||||
public override float GetOrientation() { return _owner.GetOrientation(); }
|
public override float GetOrientation() { return _owner.GetOrientation(); }
|
||||||
|
|||||||
+46
-3
@@ -1834,16 +1834,59 @@ namespace Game.Maps
|
|||||||
groupId = 0;
|
groupId = 0;
|
||||||
|
|
||||||
float vmap_z = z;
|
float vmap_z = z;
|
||||||
|
float dynamic_z = z;
|
||||||
|
float check_z = z;
|
||||||
uint terrainMapId = PhasingHandler.GetTerrainMapId(phaseShift, this, x, y);
|
uint terrainMapId = PhasingHandler.GetTerrainMapId(phaseShift, this, x, y);
|
||||||
if (Global.VMapMgr.getAreaInfo(terrainMapId, x, y, ref vmap_z, out flags, out adtId, out rootId, out groupId))
|
uint vflags;
|
||||||
|
int vadtId;
|
||||||
|
int vrootId;
|
||||||
|
int vgroupId;
|
||||||
|
uint dflags;
|
||||||
|
int dadtId;
|
||||||
|
int drootId;
|
||||||
|
int dgroupId;
|
||||||
|
|
||||||
|
bool hasVmapAreaInfo = Global.VMapMgr.getAreaInfo(terrainMapId, x, y, ref vmap_z, out vflags, out vadtId, out vrootId, out vgroupId);
|
||||||
|
bool hasDynamicAreaInfo = _dynamicTree.getAreaInfo(x, y, ref dynamic_z, phaseShift, out dflags, out dadtId, out drootId, out dgroupId);
|
||||||
|
|
||||||
|
if (hasVmapAreaInfo)
|
||||||
|
{
|
||||||
|
if (hasDynamicAreaInfo && dynamic_z > vmap_z)
|
||||||
|
{
|
||||||
|
check_z = dynamic_z;
|
||||||
|
flags = dflags;
|
||||||
|
adtId = dadtId;
|
||||||
|
rootId = drootId;
|
||||||
|
groupId = dgroupId;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
check_z = vmap_z;
|
||||||
|
flags = vflags;
|
||||||
|
adtId = vadtId;
|
||||||
|
rootId = vrootId;
|
||||||
|
groupId = vgroupId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (hasDynamicAreaInfo)
|
||||||
|
{
|
||||||
|
check_z = dynamic_z;
|
||||||
|
flags = dflags;
|
||||||
|
adtId = dadtId;
|
||||||
|
rootId = drootId;
|
||||||
|
groupId = dgroupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (hasVmapAreaInfo || hasDynamicAreaInfo)
|
||||||
{
|
{
|
||||||
// check if there's terrain between player height and object height
|
// check if there's terrain between player height and object height
|
||||||
GridMap gmap = GetGridMap(terrainMapId, x, y);
|
GridMap gmap = GetGridMap(terrainMapId, x, y);
|
||||||
if (gmap != null)
|
if (gmap != null)
|
||||||
{
|
{
|
||||||
float _mapheight = gmap.getHeight(x, y);
|
float mapHeight = gmap.getHeight(x, y);
|
||||||
// z + 2.0f condition taken from GetHeight(), not sure if it's such a great choice...
|
// z + 2.0f condition taken from GetHeight(), not sure if it's such a great choice...
|
||||||
if (z + 2.0f > _mapheight && _mapheight > vmap_z)
|
if (z + 2.0f > mapHeight && mapHeight > check_z)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user