BFA Update (still lots of testing to do tho)
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
using Framework.GameMath;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Framework.Constants;
|
||||
|
||||
namespace Game.Collision
|
||||
{
|
||||
@@ -168,7 +169,7 @@ namespace Game.Collision
|
||||
|
||||
public class MapRayCallback : WorkerCallback
|
||||
{
|
||||
public MapRayCallback(ModelInstance[] val)
|
||||
public MapRayCallback(ModelInstance[] val, ModelIgnoreFlags ignoreFlags)
|
||||
{
|
||||
prims = val;
|
||||
hit = false;
|
||||
@@ -177,7 +178,7 @@ namespace Game.Collision
|
||||
{
|
||||
if (prims[entry] == null)
|
||||
return false;
|
||||
bool result = prims[entry].intersectRay(ray, ref distance, pStopAtFirstHit);
|
||||
bool result = prims[entry].intersectRay(ray, ref distance, pStopAtFirstHit, flags);
|
||||
if (result)
|
||||
hit = true;
|
||||
return result;
|
||||
@@ -186,6 +187,7 @@ namespace Game.Collision
|
||||
|
||||
ModelInstance[] prims;
|
||||
bool hit;
|
||||
ModelIgnoreFlags flags;
|
||||
}
|
||||
|
||||
public class AreaInfoCallback : WorkerCallback
|
||||
@@ -236,7 +238,7 @@ namespace Game.Collision
|
||||
|
||||
public override bool Invoke(Ray r, IModel obj, ref float distance)
|
||||
{
|
||||
_didHit = obj.IntersectRay(r, ref distance, true, _phaseShift);
|
||||
_didHit = obj.IntersectRay(r, ref distance, true, _phaseShift, ModelIgnoreFlags.Nothing);
|
||||
return _didHit;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,13 @@ namespace Game.Collision
|
||||
Ignored
|
||||
}
|
||||
|
||||
public enum LoadResult
|
||||
{
|
||||
Success,
|
||||
FileNotFound,
|
||||
VersionMismatch
|
||||
}
|
||||
|
||||
public class VMapManager : Singleton<VMapManager>
|
||||
{
|
||||
VMapManager() { }
|
||||
@@ -124,7 +131,7 @@ namespace Game.Collision
|
||||
}
|
||||
}
|
||||
|
||||
public bool isInLineOfSight(uint mapId, float x1, float y1, float z1, float x2, float y2, float z2)
|
||||
public bool isInLineOfSight(uint mapId, float x1, float y1, float z1, float x2, float y2, float z2, ModelIgnoreFlags ignoreFlags)
|
||||
{
|
||||
if (!isLineOfSightCalcEnabled() || Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapLOS))
|
||||
return true;
|
||||
@@ -135,7 +142,7 @@ namespace Game.Collision
|
||||
Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
|
||||
Vector3 pos2 = convertPositionToInternalRep(x2, y2, z2);
|
||||
if (pos1 != pos2)
|
||||
return instanceTree.isInLineOfSight(pos1, pos2);
|
||||
return instanceTree.isInLineOfSight(pos1, pos2, ignoreFlags);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -232,7 +239,7 @@ namespace Game.Collision
|
||||
return false;
|
||||
}
|
||||
|
||||
public WorldModel acquireModelInstance(string filename)
|
||||
public WorldModel acquireModelInstance(string filename, uint flags = 0)
|
||||
{
|
||||
lock (LoadedModelFilesLock)
|
||||
{
|
||||
@@ -248,6 +255,9 @@ namespace Game.Collision
|
||||
}
|
||||
|
||||
Log.outDebug(LogFilter.Maps, "VMapManager: loading file '{0}'", filename);
|
||||
|
||||
worldmodel.Flags = flags;
|
||||
|
||||
model = new ManagedModel();
|
||||
model.setModel(worldmodel);
|
||||
|
||||
@@ -277,7 +287,7 @@ namespace Game.Collision
|
||||
}
|
||||
}
|
||||
|
||||
public bool existsMap(uint mapId, uint x, uint y)
|
||||
public LoadResult existsMap(uint mapId, uint x, uint y)
|
||||
{
|
||||
return StaticMapTree.CanLoadMap(VMapPath, mapId, x, y, this);
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace Game.Collision
|
||||
if (result)
|
||||
{
|
||||
// acquire model instance
|
||||
WorldModel model = vm.acquireModelInstance(spawn.name);
|
||||
WorldModel model = vm.acquireModelInstance(spawn.name, spawn.flags);
|
||||
if (model == null)
|
||||
Log.outError(LogFilter.Server, "StaticMapTree.LoadMapTile() : could not acquire WorldModel [{0}, {1}]", tileX, tileY);
|
||||
|
||||
@@ -243,29 +243,29 @@ namespace Game.Collision
|
||||
return new FileStream(tilefile, FileMode.Open, FileAccess.Read);
|
||||
}
|
||||
|
||||
public static bool CanLoadMap(string vmapPath, uint mapID, uint tileX, uint tileY, VMapManager vm)
|
||||
public static LoadResult CanLoadMap(string vmapPath, uint mapID, uint tileX, uint tileY, VMapManager vm)
|
||||
{
|
||||
string fullname = vmapPath + VMapManager.getMapFileName(mapID);
|
||||
if (!File.Exists(fullname))
|
||||
return false;
|
||||
return LoadResult.FileNotFound;
|
||||
|
||||
using (BinaryReader reader = new BinaryReader(new FileStream(fullname, FileMode.Open, FileAccess.Read)))
|
||||
{
|
||||
if (reader.ReadStringFromChars(8) != MapConst.VMapMagic)
|
||||
return false;
|
||||
return LoadResult.VersionMismatch;
|
||||
}
|
||||
|
||||
FileStream stream = OpenMapTileFile(vmapPath, mapID, tileX, tileY, vm);
|
||||
if (stream == null)
|
||||
return false;
|
||||
return LoadResult.FileNotFound;
|
||||
|
||||
using (BinaryReader reader = new BinaryReader(stream))
|
||||
{
|
||||
if (reader.ReadStringFromChars(8) != MapConst.VMapMagic)
|
||||
return false;
|
||||
return LoadResult.VersionMismatch;
|
||||
}
|
||||
|
||||
return true;
|
||||
return LoadResult.Success;
|
||||
}
|
||||
|
||||
public static string getTileFileName(uint mapID, uint tileX, uint tileY)
|
||||
@@ -307,15 +307,15 @@ namespace Game.Collision
|
||||
Vector3 dir = new Vector3(0, 0, -1);
|
||||
Ray ray = new Ray(pPos, dir); // direction with length of 1
|
||||
float maxDist = maxSearchDist;
|
||||
if (getIntersectionTime(ray, ref maxDist, false))
|
||||
if (getIntersectionTime(ray, ref maxDist, false, ModelIgnoreFlags.Nothing))
|
||||
height = pPos.Z - maxDist;
|
||||
|
||||
return height;
|
||||
}
|
||||
bool getIntersectionTime(Ray pRay, ref float pMaxDist, bool pStopAtFirstHit)
|
||||
bool getIntersectionTime(Ray pRay, ref float pMaxDist, bool pStopAtFirstHit, ModelIgnoreFlags ignoreFlags)
|
||||
{
|
||||
float distance = pMaxDist;
|
||||
MapRayCallback intersectionCallBack = new MapRayCallback(iTreeValues);
|
||||
MapRayCallback intersectionCallBack = new MapRayCallback(iTreeValues, ignoreFlags);
|
||||
iTree.intersectRay(pRay, intersectionCallBack, ref distance, pStopAtFirstHit);
|
||||
if (intersectionCallBack.didHit())
|
||||
pMaxDist = distance;
|
||||
@@ -337,7 +337,7 @@ namespace Game.Collision
|
||||
Vector3 dir = (pPos2 - pPos1) / maxDist; // direction with length of 1
|
||||
Ray ray = new Ray(pPos1, dir);
|
||||
float dist = maxDist;
|
||||
if (getIntersectionTime(ray, ref dist, false))
|
||||
if (getIntersectionTime(ray, ref dist, false, ModelIgnoreFlags.Nothing))
|
||||
{
|
||||
pResultHitPos = pPos1 + dir * dist;
|
||||
if (pModifyDist < 0)
|
||||
@@ -365,7 +365,7 @@ namespace Game.Collision
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool isInLineOfSight(Vector3 pos1, Vector3 pos2)
|
||||
public bool isInLineOfSight(Vector3 pos1, Vector3 pos2, ModelIgnoreFlags ignoreFlags)
|
||||
{
|
||||
float maxDist = (pos2 - pos1).magnitude();
|
||||
// return false if distance is over max float, in case of cheater teleporting to the end of the universe
|
||||
@@ -380,7 +380,7 @@ namespace Game.Collision
|
||||
return true;
|
||||
// direction with length of 1
|
||||
Ray ray = new Ray(pos1, (pos2 - pos1) / maxDist);
|
||||
if (getIntersectionTime(ray, ref maxDist, true))
|
||||
if (getIntersectionTime(ray, ref maxDist, true, ignoreFlags))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace Game.Collision
|
||||
return mdl;
|
||||
}
|
||||
|
||||
public override bool IntersectRay(Ray ray, ref float maxDist, bool stopAtFirstHit, PhaseShift phaseShift)
|
||||
public override bool IntersectRay(Ray ray, ref float maxDist, bool stopAtFirstHit, PhaseShift phaseShift, ModelIgnoreFlags ignoreFlags)
|
||||
{
|
||||
if (!isCollisionEnabled() || !owner.IsSpawned())
|
||||
return false;
|
||||
@@ -104,7 +104,7 @@ namespace Game.Collision
|
||||
Vector3 p = iInvRot * (ray.Origin - iPos) * iInvScale;
|
||||
Ray modRay = new Ray(p, iInvRot * ray.Direction);
|
||||
float distance = maxDist * iInvScale;
|
||||
bool hit = iModel.IntersectRay(modRay, ref distance, stopAtFirstHit);
|
||||
bool hit = iModel.IntersectRay(modRay, ref distance, stopAtFirstHit, ignoreFlags);
|
||||
if (hit)
|
||||
{
|
||||
distance *= iScale;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
using Framework.GameMath;
|
||||
using System.Collections.Generic;
|
||||
using Framework.Constants;
|
||||
|
||||
namespace Game.Collision
|
||||
{
|
||||
@@ -25,7 +26,8 @@ namespace Game.Collision
|
||||
public virtual Vector3 getPosition() { return default(Vector3); }
|
||||
public virtual AxisAlignedBox getBounds() { return default(AxisAlignedBox); }
|
||||
|
||||
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, ModelIgnoreFlags ignoreFlags) { return false; }
|
||||
public virtual bool IntersectRay(Ray ray, ref float distance, bool stopAtFirstHit, ModelIgnoreFlags ignoreFlags) { 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) { }
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using Framework.Constants;
|
||||
using Framework.GameMath;
|
||||
using System;
|
||||
using System.IO;
|
||||
@@ -93,7 +94,7 @@ namespace Game.Collision
|
||||
iInvScale = 1.0f / iScale;
|
||||
}
|
||||
|
||||
public bool intersectRay(Ray pRay, ref float pMaxDist, bool pStopAtFirstHit)
|
||||
public bool intersectRay(Ray pRay, ref float pMaxDist, bool pStopAtFirstHit, ModelIgnoreFlags ignoreFlags)
|
||||
{
|
||||
if (iModel == null)
|
||||
return false;
|
||||
@@ -106,7 +107,7 @@ namespace Game.Collision
|
||||
Vector3 p = iInvRot * (pRay.Origin - iPos) * iInvScale;
|
||||
Ray modRay = new Ray(p, iInvRot * pRay.Direction);
|
||||
float distance = pMaxDist * iInvScale;
|
||||
bool hit = iModel.IntersectRay(modRay, ref distance, pStopAtFirstHit);
|
||||
bool hit = iModel.IntersectRay(modRay, ref distance, pStopAtFirstHit, ignoreFlags);
|
||||
if (hit)
|
||||
{
|
||||
distance *= iScale;
|
||||
|
||||
@@ -312,8 +312,16 @@ namespace Game.Collision
|
||||
RootWMOID = 0;
|
||||
}
|
||||
|
||||
public override bool IntersectRay(Ray ray, ref float distance, bool stopAtFirstHit)
|
||||
public override bool IntersectRay(Ray ray, ref float distance, bool stopAtFirstHit, ModelIgnoreFlags ignoreFlags)
|
||||
{
|
||||
// If the caller asked us to ignore certain objects we should check flags
|
||||
if ((ignoreFlags & ModelIgnoreFlags.M2) != ModelIgnoreFlags.Nothing)
|
||||
{
|
||||
// M2 models are not taken into account for LoS calculation if caller requested their ignoring.
|
||||
if ((Flags & (uint)ModelFlags.M2) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
// small M2 workaround, maybe better make separate class with virtual intersection funcs
|
||||
// in any case, there's no need to use a bound tree if we only have one submodel
|
||||
if (groupModels.Count == 1)
|
||||
@@ -404,5 +412,6 @@ namespace Game.Collision
|
||||
List<GroupModel> groupModels = new List<GroupModel>();
|
||||
BIH groupTree = new BIH();
|
||||
uint RootWMOID;
|
||||
public uint Flags;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user