Core/vmaps: Removed vmap lookup functions duplicating functionality of each other

Port From (https://github.com/TrinityCore/TrinityCore/commit/45ee989c70682c001d4467d97bf1ecedcf7dbcc3)
This commit is contained in:
hondacrx
2024-03-12 23:04:13 -04:00
parent 5b938c1a3e
commit ccf73e23e3
16 changed files with 131 additions and 349 deletions
+1 -1
View File
@@ -632,7 +632,7 @@ namespace Game.Chat
zoneX, zoneY, groundZ, floorZ, map.GetMinHeight(obj.GetPhaseShift(), obj.GetPositionX(), obj.GetPositionY()), haveMap, haveVMap, haveMMap);
LiquidData liquidStatus;
ZLiquidStatus status = map.GetLiquidStatus(obj.GetPhaseShift(), obj.GetPositionX(), obj.GetPositionY(), obj.GetPositionZ(), LiquidHeaderTypeFlags.AllLiquids, out liquidStatus);
ZLiquidStatus status = map.GetLiquidStatus(obj.GetPhaseShift(), obj.GetPositionX(), obj.GetPositionY(), obj.GetPositionZ(), out liquidStatus);
if (liquidStatus != null)
handler.SendSysMessage(CypherStrings.LiquidStatus, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status);
-37
View File
@@ -174,24 +174,6 @@ namespace Game.Collision
ModelIgnoreFlags flags;
}
public class AreaInfoCallback : WorkerCallback
{
public AreaInfoCallback(ModelInstance[] val)
{
prims = val;
}
public override void Invoke(Vector3 point, uint entry)
{
if (prims[entry] == null)
return;
prims[entry].IntersectPoint(point, aInfo);
}
ModelInstance[] prims;
public AreaInfo aInfo = new();
}
public class LocationInfoCallback : WorkerCallback
{
public LocationInfoCallback(ModelInstance[] val, LocationInfo info)
@@ -232,25 +214,6 @@ namespace Game.Collision
PhaseShift _phaseShift;
}
public class DynamicTreeAreaInfoCallback : WorkerCallback
{
public DynamicTreeAreaInfoCallback(PhaseShift phaseShift)
{
_phaseShift = phaseShift;
_areaInfo = new AreaInfo();
}
public override void Invoke(Vector3 p, GameObjectModel obj)
{
obj.IntersectPoint(p, _areaInfo, _phaseShift);
}
public AreaInfo GetAreaInfo() { return _areaInfo; }
PhaseShift _phaseShift;
AreaInfo _areaInfo;
}
public class DynamicTreeLocationInfoCallback : WorkerCallback
{
public DynamicTreeLocationInfoCallback(PhaseShift phaseShift)
+7 -29
View File
@@ -113,31 +113,9 @@ namespace Game.Collision
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)
public bool GetAreaAndLiquidData(float x, float y, float z, PhaseShift phaseShift, byte? reqLiquidType, out AreaAndLiquidData data)
{
flags = 0;
adtId = 0;
rootId = 0;
groupId = 0;
Vector3 v = new(x, y, z + 0.5f);
DynamicTreeAreaInfoCallback intersectionCallBack = new(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;
}
public AreaAndLiquidData GetAreaAndLiquidData(float x, float y, float z, PhaseShift phaseShift, byte reqLiquidType)
{
AreaAndLiquidData data = new();
data = new();
Vector3 v = new(x, y, z + 0.5f);
DynamicTreeLocationInfoCallback intersectionCallBack = new(phaseShift);
@@ -147,17 +125,17 @@ namespace Game.Collision
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 (!reqLiquidType.HasValue || (Global.DB2Mgr.GetLiquidFlags(liquidType) & reqLiquidType.Value) != 0)
if (intersectionCallBack.GetHitModel().GetLiquidLevel(v, intersectionCallBack.GetLocationInfo(), ref liquidLevel))
data.liquidInfo = new AreaAndLiquidData.LiquidInfo(liquidType, liquidLevel);
data.areaInfo = new(intersectionCallBack.GetHitModel().GetNameSetId(), intersectionCallBack.GetLocationInfo().rootId,
(int)intersectionCallBack.GetLocationInfo().hitModel.GetWmoID(), intersectionCallBack.GetLocationInfo().hitModel.GetMogpFlags());
data.areaInfo = new((int)intersectionCallBack.GetLocationInfo().hitModel.GetWmoID(), intersectionCallBack.GetHitModel().GetNameSetId(), intersectionCallBack.GetLocationInfo().rootId, intersectionCallBack.GetLocationInfo().hitModel.GetMogpFlags(), 0);
return true;
}
return data;
return false;
}
DynTreeImpl impl;
}
+28 -73
View File
@@ -147,66 +147,12 @@ namespace Game.Collision
return MapConst.VMAPInvalidHeightValue;
}
public bool GetAreaInfo(uint mapId, float x, float y, ref float z, out uint flags, out int adtId, out int rootId, out int groupId)
public bool GetAreaAndLiquidData(uint mapId, float x, float y, float z, byte? reqLiquidType, out AreaAndLiquidData data)
{
flags = 0;
adtId = 0;
rootId = 0;
groupId = 0;
if (!Global.DisableMgr.IsVMAPDisabledFor(mapId, DisableFlags.VmapAreaFlag))
{
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
if (instanceTree != null)
{
Vector3 pos = ConvertPositionToInternalRep(x, y, z);
bool result = instanceTree.GetAreaInfo(ref pos, out flags, out adtId, out rootId, out groupId);
// z is not touched by convertPositionToInternalRep(), so just copy
z = pos.Z;
return result;
}
}
data = new AreaAndLiquidData();
return false;
}
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.IsVMAPDisabledFor(mapId, DisableFlags.VmapLiquidStatus))
{
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
if (instanceTree != null)
{
LocationInfo info = new();
Vector3 pos = ConvertPositionToInternalRep(x, y, z);
if (instanceTree.GetLocationInfo(pos, info))
{
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))
return true;
}
}
}
return false;
}
public AreaAndLiquidData GetAreaAndLiquidData(uint mapId, float x, float y, float z, uint reqLiquidType)
{
var data = new AreaAndLiquidData();
if (Global.DisableMgr.IsVMAPDisabledFor(mapId, DisableFlags.VmapLiquidStatus))
{
data.floorZ = z;
int adtId, rootId, groupId;
uint flags;
if (GetAreaInfo(mapId, x, y, ref data.floorZ, out flags, out adtId, out rootId, out groupId))
data.areaInfo = new(adtId, rootId, groupId, flags);
return data;
}
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
if (instanceTree != null)
{
@@ -215,18 +161,24 @@ namespace Game.Collision
if (instanceTree.GetLocationInfo(pos, info))
{
data.floorZ = info.ground_Z;
uint liquidType = info.hitModel.GetLiquidType();
float liquidLevel = 0;
if (reqLiquidType == 0 || Convert.ToBoolean(Global.DB2Mgr.GetLiquidFlags(liquidType) & reqLiquidType))
if (info.hitInstance.GetLiquidLevel(pos, info, ref liquidLevel))
data.liquidInfo = new(liquidType, liquidLevel);
if (!Global.DisableMgr.IsVMAPDisabledFor(mapId, DisableFlags.VmapLiquidStatus))
data.areaInfo = new(info.hitInstance.adtId, info.rootId, (int)info.hitModel.GetWmoID(), info.hitModel.GetMogpFlags());
{
uint liquidType = info.hitModel.GetLiquidType(); // entry from LiquidType.dbc
float liquidLevel = 0;
if (!reqLiquidType.HasValue || (Global.DB2Mgr.GetLiquidFlags(liquidType) & reqLiquidType.Value) != 0)
if (info.hitInstance.GetLiquidLevel(pos, info, ref liquidLevel))
data.liquidInfo = new(liquidType, liquidLevel);
}
if (!Global.DisableMgr.IsVMAPDisabledFor(mapId, DisableFlags.VmapLiquidStatus))
data.areaInfo = new((int)info.hitModel.GetWmoID(), info.hitInstance.adtId, info.rootId, info.hitModel.GetMogpFlags(), info.hitInstance.Id);
return true;
}
}
return data;
return false;
}
public WorldModel AcquireModelInstance(string filename)
@@ -336,22 +288,25 @@ namespace Game.Collision
public class AreaAndLiquidData
{
public struct AreaInfo
public class AreaInfo
{
public int GroupId;
public int AdtId;
public int RootId;
public int GroupId;
public uint MogpFlags;
public uint UniqueId;
public AreaInfo(int adtId, int rootId, int groupId, uint flags)
public AreaInfo(int groupId, int adtId, int rootId, uint mogpFlags, uint uniqueId)
{
GroupId = groupId;
AdtId = adtId;
RootId = rootId;
GroupId = groupId;
MogpFlags = flags;
MogpFlags = mogpFlags;
UniqueId = uniqueId;
}
}
public struct LiquidInfo
public class LiquidInfo
{
public uint LiquidType;
public float Level;
@@ -364,7 +319,7 @@ namespace Game.Collision
}
public float floorZ = MapConst.VMAPInvalidHeightValue;
public AreaInfo? areaInfo;
public LiquidInfo? liquidInfo;
public AreaInfo areaInfo;
public LiquidInfo liquidInfo;
}
}
-21
View File
@@ -287,27 +287,6 @@ namespace Game.Collision
return $"{mapID:D4}_{tileY:D2}_{tileX:D2}.vmtile";
}
public bool GetAreaInfo(ref Vector3 pos, out uint flags, out int adtId, out int rootId, out int groupId)
{
flags = 0;
adtId = 0;
rootId = 0;
groupId = 0;
AreaInfoCallback intersectionCallBack = new(iTreeValues);
iTree.IntersectPoint(pos, intersectionCallBack);
if (intersectionCallBack.aInfo.result)
{
flags = intersectionCallBack.aInfo.flags;
adtId = intersectionCallBack.aInfo.adtId;
rootId = intersectionCallBack.aInfo.rootId;
groupId = intersectionCallBack.aInfo.groupId;
pos.Z = intersectionCallBack.aInfo.ground_Z;
return true;
}
return false;
}
public bool GetLocationInfo(Vector3 pos, LocationInfo info)
{
LocationInfoCallback intersectionCallBack = new(iTreeValues, info);
@@ -104,33 +104,6 @@ namespace Game.Collision
return hit;
}
public override void IntersectPoint(Vector3 point, AreaInfo info, PhaseShift phaseShift)
{
if (!IsCollisionEnabled() || !owner.IsSpawned() || !IsMapObject())
return;
if (!owner.IsInPhase(phaseShift))
return;
if (!iBound.contains(point))
return;
// child bounds are defined in object space:
Vector3 pModel = iInvRot.Multiply(point - iPos) * iInvScale;
Vector3 zDirModel = iInvRot.Multiply(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 = (iInvRot.Multiply(modelGround) * iScale + iPos).Z;
if (info.ground_Z < world_Z)
{
info.ground_Z = world_Z;
info.adtId = owner.GetNameSetId();
}
}
}
public bool GetLocationInfo(Vector3 point, LocationInfo info, PhaseShift phaseShift)
{
if (!IsCollisionEnabled() || !owner.IsSpawned() || !IsMapObject())
@@ -120,37 +120,6 @@ namespace Game.Collision
return hit;
}
public void IntersectPoint(Vector3 p, AreaInfo info)
{
if (iModel == null)
return;
// M2 files don't contain area info, only WMO files
if (iModel.IsM2())
return;
if (!iBound.contains(p))
return;
// child bounds are defined in object space:
Vector3 pModel = iInvRot.Multiply(p - iPos) * iInvScale;
Vector3 zDirModel = iInvRot.Multiply(new Vector3(0.0f, 0.0f, -1.0f));
float zDist;
if (iModel.IntersectPoint(pModel, zDirModel, out zDist, info))
{
Vector3 modelGround = pModel + zDist * zDirModel;
// Transform back to world space. Note that:
// Mat * vec == vec * Mat.transpose()
// and for rotation matrices: Mat.inverse() == Mat.transpose()
float world_Z = (iInvRot.Multiply(modelGround) * iScale + iPos).Z;
if (info.ground_Z < world_Z)
{
info.ground_Z = world_Z;
info.adtId = adtId;
}
}
}
public bool GetLiquidLevel(Vector3 p, LocationInfo info, ref float liqHeight)
{
// child bounds are defined in object space:
+1 -21
View File
@@ -301,7 +301,7 @@ namespace Game.Collision
if ((ignoreFlags & ModelIgnoreFlags.M2) != ModelIgnoreFlags.Nothing)
{
// M2 models are not taken into account for LoS calculation if caller requested their ignoring.
if (Flags.HasFlag(ModelFlags.None))
if (IsM2())
return false;
}
@@ -315,26 +315,6 @@ namespace Game.Collision
return isc.hit;
}
public bool IntersectPoint(Vector3 p, Vector3 down, out float dist, AreaInfo info)
{
dist = 0f;
if (groupModels.Empty())
return false;
WModelAreaCallback callback = new(groupModels, down);
groupTree.IntersectPoint(p, callback);
if (callback.hit != null)
{
info.rootId = (int)RootWMOID;
info.groupId = (int)callback.hit.GetWmoID();
info.flags = callback.hit.GetMogpFlags();
info.result = true;
dist = callback.zDist;
return true;
}
return false;
}
public bool GetLocationInfo(Vector3 p, Vector3 down, out float dist, GroupLocationInfo info)
{
dist = 0f;
+3 -3
View File
@@ -829,9 +829,9 @@ namespace Game.Entities
{
// area/zone id is needed immediately for ZoneScript::GetCreatureEntry hook before it is known which creature template to load (no model/scale available yet)
PositionFullTerrainStatus positionData = new();
GetMap().GetFullTerrainStatusForPosition(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ(), positionData, LiquidHeaderTypeFlags.AllLiquids, MapConst.DefaultCollesionHeight);
ProcessPositionDataChanged(positionData);
PositionFullTerrainStatus terrainStatus = new();
GetMap().GetFullTerrainStatusForPosition(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ(), terrainStatus);
ProcessPositionDataChanged(terrainStatus);
}
// Allow players to see those units while dead, do it here (mayby altered by addon auras)
+1 -1
View File
@@ -104,7 +104,7 @@ namespace Game.Entities
public void UpdatePositionData()
{
PositionFullTerrainStatus data = new();
GetMap().GetFullTerrainStatusForPosition(_phaseShift, GetPositionX(), GetPositionY(), GetPositionZ(), data, LiquidHeaderTypeFlags.AllLiquids, GetCollisionHeight());
GetMap().GetFullTerrainStatusForPosition(_phaseShift, GetPositionX(), GetPositionY(), GetPositionZ(), data, null, GetCollisionHeight());
ProcessPositionDataChanged(data);
}
+1 -1
View File
@@ -803,7 +803,7 @@ namespace Game.Entities
mountFlags = (AreaMountFlags)areaTable.MountFlags;
}
ZLiquidStatus liquidStatus = GetMap().GetLiquidStatus(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ(), LiquidHeaderTypeFlags.AllLiquids);
ZLiquidStatus liquidStatus = GetMap().GetLiquidStatus(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ());
isSubmerged = liquidStatus.HasAnyFlag(ZLiquidStatus.UnderWater) || HasUnitMovementFlag(MovementFlag.Swimming);
isInWater = liquidStatus.HasAnyFlag(ZLiquidStatus.InWater | ZLiquidStatus.UnderWater);
+24 -29
View File
@@ -1520,24 +1520,19 @@ namespace Game.Maps
return (mogpFlags & 0x2000) != 0;
}
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 = null, float collisionHeight = MapConst.DefaultCollesionHeight)
{
m_terrain.GetFullTerrainStatusForPosition(phaseShift, GetId(), x, y, z, data, reqLiquidType, collisionHeight, _dynamicTree);
}
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 = null, float collisionHeight = MapConst.DefaultCollesionHeight)
{
return m_terrain.GetLiquidStatus(phaseShift, GetId(), x, y, z, reqLiquidType, out _, collisionHeight);
return m_terrain.GetLiquidStatus(phaseShift, GetId(), x, y, z, out _, reqLiquidType, collisionHeight);
}
public ZLiquidStatus GetLiquidStatus(PhaseShift phaseShift, float x, float y, float z, LiquidHeaderTypeFlags reqLiquidType, out LiquidData data, float collisionHeight = MapConst.DefaultCollesionHeight)
public ZLiquidStatus GetLiquidStatus(PhaseShift phaseShift, float x, float y, float z, out LiquidData data, LiquidHeaderTypeFlags? reqLiquidType = null, float collisionHeight = MapConst.DefaultCollesionHeight)
{
return m_terrain.GetLiquidStatus(phaseShift, GetId(), x, y, z, reqLiquidType, out data, collisionHeight);
}
private bool GetAreaInfo(PhaseShift phaseShift, float x, float y, float z, out uint mogpflags, out int adtId, out int rootId, out int groupId)
{
return m_terrain.GetAreaInfo(phaseShift, GetId(), x, y, z, out mogpflags, out adtId, out rootId, out groupId, _dynamicTree);
return m_terrain.GetLiquidStatus(phaseShift, GetId(), x, y, z, out data, reqLiquidType, collisionHeight);
}
public uint GetAreaId(PhaseShift phaseShift, Position pos)
@@ -5013,9 +5008,9 @@ namespace Game.Maps
raidInstanceMessage.DifficultyID = GetDifficultyID();
raidInstanceMessage.Write();
foreach (Player player in GetPlayers())
foreach (Player player in GetPlayers())
player.SendPacket(raidInstanceMessage);
if (i_data != null)
{
PendingRaidLock pendingRaidLock = new();
@@ -5321,29 +5316,29 @@ namespace Game.Maps
}
}
public class WmoLocation
{
public int GroupId;
public int NameSetId;
public int RootId;
public uint UniqueId;
public WmoLocation(int groupId, int nameSetId, int rootId, uint uniqueId)
{
GroupId = groupId;
NameSetId = nameSetId;
RootId = rootId;
UniqueId = uniqueId;
}
}
public class PositionFullTerrainStatus
{
public struct AreaInfo
{
public int AdtId;
public int RootId;
public int GroupId;
public uint MogpFlags;
public AreaInfo(int adtId, int rootId, int groupId, uint flags)
{
AdtId = adtId;
RootId = rootId;
GroupId = groupId;
MogpFlags = flags;
}
}
public uint AreaId;
public float FloorZ;
public bool outdoors = true;
public ZLiquidStatus LiquidStatus;
public AreaInfo? areaInfo;
public WmoLocation? wmoLocation;
public LiquidData LiquidInfo;
}
+60 -70
View File
@@ -266,7 +266,7 @@ namespace Game.Maps
if (++_referenceCountFromMap[gx][gy] != 1) // check if already loaded
return;
lock(_loadLock)
lock (_loadLock)
LoadMapAndVMapImpl(gx, gy);
}
@@ -393,7 +393,7 @@ namespace Game.Maps
// ensure GridMap is loaded
if (!_loadedGrids[GetBitsetIndex(gx, gy)] && loadIfMissing)
{
lock(_loadLock)
lock (_loadLock)
LoadMapAndVMapImpl(gx, gy);
}
@@ -428,16 +428,17 @@ namespace Game.Maps
return (mogpFlags & 0x2000) != 0;
}
public void GetFullTerrainStatusForPosition(PhaseShift phaseShift, uint mapId, float x, float y, float z, PositionFullTerrainStatus data, LiquidHeaderTypeFlags reqLiquidType = LiquidHeaderTypeFlags.AllLiquids, float collisionHeight = MapConst.DefaultCollesionHeight, DynamicMapTree dynamicMapTree = null)
public void GetFullTerrainStatusForPosition(PhaseShift phaseShift, uint mapId, float x, float y, float z, PositionFullTerrainStatus data, LiquidHeaderTypeFlags? reqLiquidType = null, float collisionHeight = MapConst.DefaultCollesionHeight, DynamicMapTree dynamicMapTree = null)
{
AreaAndLiquidData dynData = null;
AreaAndLiquidData wmoData = null;
uint terrainMapId = PhasingHandler.GetTerrainMapId(phaseShift, mapId, this, x, y);
GridMap gmap = GetGrid(terrainMapId, x, y);
AreaAndLiquidData vmapData = Global.VMapMgr.GetAreaAndLiquidData(terrainMapId, x, y, z, (byte)reqLiquidType);
AreaAndLiquidData vmapData;
Global.VMapMgr.GetAreaAndLiquidData(terrainMapId, x, y, z, reqLiquidType.HasValue ? (byte)reqLiquidType : null, out vmapData);
if (dynamicMapTree != null)
dynData = dynamicMapTree.GetAreaAndLiquidData(x, y, z, phaseShift, (byte)reqLiquidType);
dynamicMapTree.GetAreaAndLiquidData(x, y, z, phaseShift, reqLiquidType.HasValue ? (byte)reqLiquidType : null, out dynData);
uint gridAreaId = 0;
float gridMapHeight = MapConst.InvalidHeight;
@@ -475,15 +476,15 @@ namespace Game.Maps
if (wmoData != null)
{
if (wmoData.areaInfo.HasValue)
if (wmoData.areaInfo != null)
{
data.areaInfo = new(wmoData.areaInfo.Value.AdtId, wmoData.areaInfo.Value.RootId, wmoData.areaInfo.Value.GroupId, wmoData.areaInfo.Value.MogpFlags);
data.wmoLocation = new(wmoData.areaInfo.AdtId, wmoData.areaInfo.RootId, wmoData.areaInfo.GroupId, wmoData.areaInfo.MogpFlags);
// wmo found
var wmoEntry = Global.DB2Mgr.GetWMOAreaTable(wmoData.areaInfo.Value.RootId, wmoData.areaInfo.Value.AdtId, wmoData.areaInfo.Value.GroupId);
var wmoEntry = Global.DB2Mgr.GetWMOAreaTable(wmoData.areaInfo.RootId, wmoData.areaInfo.AdtId, wmoData.areaInfo.GroupId);
if (wmoEntry == null)
wmoEntry = Global.DB2Mgr.GetWMOAreaTable(wmoData.areaInfo.Value.RootId, wmoData.areaInfo.Value.AdtId, -1);
wmoEntry = Global.DB2Mgr.GetWMOAreaTable(wmoData.areaInfo.RootId, wmoData.areaInfo.AdtId, -1);
data.outdoors = (wmoData.areaInfo.Value.MogpFlags & 0x8) != 0;
data.outdoors = (wmoData.areaInfo.MogpFlags & 0x8) != 0;
if (wmoEntry != null)
{
data.AreaId = wmoEntry.AreaTableID;
@@ -496,7 +497,7 @@ namespace Game.Maps
if (data.AreaId == 0)
data.AreaId = gridAreaId;
useGridLiquid = !IsInWMOInterior(wmoData.areaInfo.Value.MogpFlags);
useGridLiquid = !IsInWMOInterior(wmoData.areaInfo.MogpFlags);
}
}
else
@@ -515,9 +516,9 @@ namespace Game.Maps
// liquid processing
data.LiquidStatus = ZLiquidStatus.NoWater;
if (wmoData != null && wmoData.liquidInfo.HasValue && wmoData.liquidInfo.Value.Level > wmoData.floorZ)
if (wmoData != null && wmoData.liquidInfo != null && wmoData.liquidInfo.Level > wmoData.floorZ)
{
uint liquidType = wmoData.liquidInfo.Value.LiquidType;
uint liquidType = wmoData.liquidInfo.LiquidType;
if (GetId() == 530 && liquidType == 2) // gotta love hacks
liquidType = 15;
@@ -545,12 +546,12 @@ namespace Game.Maps
}
data.LiquidInfo = new();
data.LiquidInfo.level = wmoData.liquidInfo.Value.Level;
data.LiquidInfo.level = wmoData.liquidInfo.Level;
data.LiquidInfo.depth_level = wmoData.floorZ;
data.LiquidInfo.entry = liquidType;
data.LiquidInfo.type_flags = (LiquidHeaderTypeFlags)(1 << (int)liquidFlagType);
float delta = wmoData.liquidInfo.Value.Level - z;
float delta = wmoData.liquidInfo.Level - z;
ZLiquidStatus status = ZLiquidStatus.AboveWater;
if (delta > collisionHeight)
status = ZLiquidStatus.UnderWater;
@@ -580,38 +581,35 @@ namespace Game.Maps
}
}
public ZLiquidStatus GetLiquidStatus(PhaseShift phaseShift, uint mapId, float x, float y, float z, LiquidHeaderTypeFlags ReqLiquidType, out LiquidData data, float collisionHeight = MapConst.DefaultCollesionHeight)
public ZLiquidStatus GetLiquidStatus(PhaseShift phaseShift, uint mapId, float x, float y, float z, out LiquidData data, LiquidHeaderTypeFlags? ReqLiquidType = null, float collisionHeight = MapConst.DefaultCollesionHeight)
{
data = null;
ZLiquidStatus result = ZLiquidStatus.NoWater;
float liquid_level = MapConst.InvalidHeight;
float ground_level = MapConst.InvalidHeight;
uint liquid_type = 0;
uint mogpFlags = 0;
AreaAndLiquidData vmapData;
bool useGridLiquid = true;
uint terrainMapId = PhasingHandler.GetTerrainMapId(phaseShift, mapId, this, x, y);
if (Global.VMapMgr.GetLiquidLevel(terrainMapId, x, y, z, (byte)ReqLiquidType, ref liquid_level, ref ground_level, ref liquid_type, ref mogpFlags))
if (Global.VMapMgr.GetAreaAndLiquidData(terrainMapId, x, y, z, ReqLiquidType.HasValue ? (byte)ReqLiquidType : null, out vmapData) && vmapData.liquidInfo != null)
{
useGridLiquid = !IsInWMOInterior(mogpFlags);
Log.outDebug(LogFilter.Maps, $"GetLiquidStatus(): vmap liquid level: {liquid_level} ground: {ground_level} type: {liquid_type}");
useGridLiquid = vmapData.areaInfo == null || !IsInWMOInterior(vmapData.areaInfo.MogpFlags);
Log.outDebug(LogFilter.Maps, $"GetLiquidStatus(): vmap liquid level: {vmapData.liquidInfo.Level} ground: {vmapData.floorZ} type: {vmapData.liquidInfo.LiquidType}");
// Check water level and ground level
if (liquid_level > ground_level && MathFunctions.fuzzyGe(z, ground_level - MapConst.GroundHeightTolerance))
if (vmapData.liquidInfo.Level > vmapData.floorZ && MathFunctions.fuzzyGe(z, vmapData.floorZ - MapConst.GroundHeightTolerance))
{
// All ok in water . store data
data = new();
// hardcoded in client like this
if (GetId() == 530 && liquid_type == 2)
liquid_type = 15;
if (GetId() == 530 && vmapData.liquidInfo.LiquidType == 2)
vmapData.liquidInfo.LiquidType = 15;
uint liquidFlagType = 0;
var liq = CliDB.LiquidTypeStorage.LookupByKey(liquid_type);
var liq = CliDB.LiquidTypeStorage.LookupByKey(vmapData.liquidInfo.LiquidType);
if (liq != null)
liquidFlagType = liq.SoundBank;
if (liquid_type != 0 && liquid_type < 21)
if (vmapData.liquidInfo.LiquidType != 0 && vmapData.liquidInfo.LiquidType < 21)
{
var area = CliDB.AreaTableStorage.LookupByKey(GetAreaId(phaseShift, mapId, x, y, z));
if (area != null)
@@ -627,19 +625,19 @@ namespace Game.Maps
var liq1 = CliDB.LiquidTypeStorage.LookupByKey(overrideLiquid);
if (liq1 != null)
{
liquid_type = overrideLiquid;
vmapData.liquidInfo.LiquidType = overrideLiquid;
liquidFlagType = liq1.SoundBank;
}
}
}
data.level = liquid_level;
data.depth_level = ground_level;
data.level = vmapData.liquidInfo.Level;
data.depth_level = vmapData.floorZ;
data.entry = liquid_type;
data.entry = vmapData.liquidInfo.LiquidType;
data.type_flags = (LiquidHeaderTypeFlags)(1 << (int)liquidFlagType);
float delta = liquid_level - z;
float delta = vmapData.liquidInfo.Level - z;
ZLiquidStatus status = ZLiquidStatus.AboveWater; // Above water
@@ -652,7 +650,7 @@ namespace Game.Maps
if (status != ZLiquidStatus.AboveWater)
{
if (MathF.Abs(ground_level - z) <= MapConst.GroundHeightTolerance)
if (MathF.Abs(vmapData.floorZ - z) <= MapConst.GroundHeightTolerance)
status |= ZLiquidStatus.OceanFloor;
return status;
@@ -670,7 +668,7 @@ namespace Game.Maps
LiquidData map_data = new();
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))
if (map_result != ZLiquidStatus.NoWater && (map_data.level > vmapData.floorZ))
{
// hardcoded in client like this
if (GetId() == 530 && map_data.entry == 2)
@@ -692,49 +690,41 @@ namespace Game.Maps
rootId = 0;
groupId = 0;
float vmap_z = z;
float dynamic_z = z;
float check_z = z;
uint terrainMapId = PhasingHandler.GetTerrainMapId(phaseShift, mapId, this, x, y);
uint vflags;
int vadtId;
int vrootId;
int vgroupId;
uint dflags = 0;
int dadtId = 0;
int drootId = 0;
int dgroupId = 0;
AreaAndLiquidData vdata;
AreaAndLiquidData ddata = null;
bool hasVmapAreaInfo = Global.VMapMgr.GetAreaInfo(terrainMapId, x, y, ref vmap_z, out vflags, out vadtId, out vrootId, out vgroupId);
bool hasDynamicAreaInfo = dynamicMapTree != null ? dynamicMapTree.GetAreaInfo(x, y, ref dynamic_z, phaseShift, out dflags, out dadtId, out drootId, out dgroupId) : false;
bool hasVmapAreaInfo = Global.VMapMgr.GetAreaAndLiquidData(terrainMapId, x, y, z, null, out vdata) && vdata.areaInfo != null;
bool hasDynamicAreaInfo = dynamicMapTree != null ? dynamicMapTree.GetAreaAndLiquidData(x, y, z, phaseShift, null, out ddata) && ddata.areaInfo != null : false;
if (hasVmapAreaInfo)
{
if (hasDynamicAreaInfo && dynamic_z > vmap_z)
if (hasDynamicAreaInfo && ddata.floorZ > vdata.floorZ)
{
check_z = dynamic_z;
mogpflags = dflags;
adtId = dadtId;
rootId = drootId;
groupId = dgroupId;
check_z = ddata.floorZ;
groupId = ddata.areaInfo.GroupId;
adtId = ddata.areaInfo.AdtId;
rootId = ddata.areaInfo.RootId;
mogpflags = ddata.areaInfo.MogpFlags;
}
else
{
check_z = vmap_z;
mogpflags = vflags;
adtId = vadtId;
rootId = vrootId;
groupId = vgroupId;
check_z = vdata.floorZ;
groupId = vdata.areaInfo.GroupId;
adtId = vdata.areaInfo.AdtId;
rootId = vdata.areaInfo.RootId;
mogpflags = vdata.areaInfo.MogpFlags;
}
}
else if (hasDynamicAreaInfo)
{
check_z = dynamic_z;
mogpflags = dflags;
adtId = dadtId;
rootId = drootId;
groupId = dgroupId;
check_z = ddata.floorZ;
groupId = ddata.areaInfo.GroupId;
adtId = ddata.areaInfo.AdtId;
rootId = ddata.areaInfo.RootId;
mogpflags = ddata.areaInfo.MogpFlags;
}
if (hasVmapAreaInfo || hasDynamicAreaInfo)
@@ -754,7 +744,7 @@ namespace Game.Maps
}
public uint GetAreaId(PhaseShift phaseShift, uint mapId, Position pos, DynamicMapTree dynamicMapTree = null) { return GetAreaId(phaseShift, mapId, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), dynamicMapTree); }
public uint GetAreaId(PhaseShift phaseShift, uint mapId, float x, float y, float z, DynamicMapTree dynamicMapTree = null)
{
uint mogpFlags;
@@ -794,7 +784,7 @@ namespace Game.Maps
}
public uint GetZoneId(PhaseShift phaseShift, uint mapId, Position pos, DynamicMapTree dynamicMapTree = null) { return GetZoneId(phaseShift, mapId, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), dynamicMapTree); }
public uint GetZoneId(PhaseShift phaseShift, uint mapId, float x, float y, float z, DynamicMapTree dynamicMapTree = null)
{
uint areaId = GetAreaId(phaseShift, mapId, x, y, z, dynamicMapTree);
@@ -807,7 +797,7 @@ namespace Game.Maps
}
public void GetZoneAndAreaId(PhaseShift phaseShift, uint mapId, out uint zoneid, out uint areaid, Position pos, DynamicMapTree dynamicMapTree = null) { GetZoneAndAreaId(phaseShift, mapId, out zoneid, out areaid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), dynamicMapTree); }
public void GetZoneAndAreaId(PhaseShift phaseShift, uint mapId, out uint zoneid, out uint areaid, float x, float y, float z, DynamicMapTree dynamicMapTree = null)
{
areaid = zoneid = GetAreaId(phaseShift, mapId, x, y, z, dynamicMapTree);
@@ -881,18 +871,18 @@ namespace Game.Maps
GridMap gmap = GetGrid(PhasingHandler.GetTerrainMapId(phaseShift, mapId, this, x, y), x, y);
if (gmap != null)
return gmap.GetLiquidLevel(x, y);
return 0;
}
public bool IsInWater(PhaseShift phaseShift, uint mapId, float x, float y, float pZ, out LiquidData data)
{
return (GetLiquidStatus(phaseShift, mapId, x, y, pZ, LiquidHeaderTypeFlags.AllLiquids, out data) & (ZLiquidStatus.InWater | ZLiquidStatus.UnderWater)) != 0;
return (GetLiquidStatus(phaseShift, mapId, x, y, pZ, out data, null) & (ZLiquidStatus.InWater | ZLiquidStatus.UnderWater)) != 0;
}
public bool IsUnderWater(PhaseShift phaseShift, uint mapId, float x, float y, float z)
{
return (GetLiquidStatus(phaseShift, mapId, x, y, z, LiquidHeaderTypeFlags.Water | LiquidHeaderTypeFlags.Ocean, out _) & ZLiquidStatus.UnderWater) != 0;
return (GetLiquidStatus(phaseShift, mapId, x, y, z, out _, LiquidHeaderTypeFlags.Water | LiquidHeaderTypeFlags.Ocean) & ZLiquidStatus.UnderWater) != 0;
}
public float GetWaterOrGroundLevel(PhaseShift phaseShift, uint mapId, float x, float y, float z, ref float ground, bool swim = false, float collisionHeight = MapConst.DefaultCollesionHeight, DynamicMapTree dynamicMapTree = null)
@@ -907,7 +897,7 @@ namespace Game.Maps
ground = ground_z;
LiquidData liquid_status;
ZLiquidStatus res = GetLiquidStatus(phaseShift, mapId, x, y, ground_z, LiquidHeaderTypeFlags.AllLiquids, out liquid_status, collisionHeight);
ZLiquidStatus res = GetLiquidStatus(phaseShift, mapId, x, y, ground_z, out liquid_status, null, collisionHeight);
switch (res)
{
case ZLiquidStatus.AboveWater:
@@ -161,7 +161,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 = _source.GetMap().GetLiquidStatus(_source.GetPhaseShift(), _pathPoints[i].X, _pathPoints[i].Y, _pathPoints[i].Z, LiquidHeaderTypeFlags.AllLiquids, _source.GetCollisionHeight());
ZLiquidStatus status = _source.GetMap().GetLiquidStatus(_source.GetPhaseShift(), _pathPoints[i].X, _pathPoints[i].Y, _pathPoints[i].Z, null, _source.GetCollisionHeight());
// One of the points is not in the water, cancel movement.
if (status == ZLiquidStatus.NoWater)
{
@@ -893,7 +893,7 @@ namespace Game.Movement
NavTerrainFlag GetNavTerrain(float x, float y, float z)
{
ZLiquidStatus liquidStatus = _source.GetMap().GetLiquidStatus(_source.GetPhaseShift(), x, y, z, LiquidHeaderTypeFlags.AllLiquids, out LiquidData data, _source.GetCollisionHeight());
ZLiquidStatus liquidStatus = _source.GetMap().GetLiquidStatus(_source.GetPhaseShift(), x, y, z, out LiquidData data, null, _source.GetCollisionHeight());
if (liquidStatus == ZLiquidStatus.NoWater)
return NavTerrainFlag.Ground;
+2 -2
View File
@@ -311,7 +311,7 @@ namespace Game.Spells
{
if (m_spellInfo.HasAttribute(SpellAttr8.RequiresLocationToBeOnLiquidSurface))
{
ZLiquidStatus status = m_caster.GetMap().GetLiquidStatus(m_caster.GetPhaseShift(), m_targets.GetDstPos().GetPositionX(), m_targets.GetDstPos().GetPositionY(), m_targets.GetDstPos().GetPositionZ(), LiquidHeaderTypeFlags.AllLiquids);
ZLiquidStatus status = m_caster.GetMap().GetLiquidStatus(m_caster.GetPhaseShift(), m_targets.GetDstPos().GetPositionX(), m_targets.GetDstPos().GetPositionY(), m_targets.GetDstPos().GetPositionZ());
if (!status.HasAnyFlag(ZLiquidStatus.WaterWalk | ZLiquidStatus.InWater))
{
SendCastResult(SpellCastResult.NoLiquid);
@@ -1004,7 +1004,7 @@ namespace Game.Spells
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, LiquidHeaderTypeFlags.AllLiquids, out liquidData, m_caster.GetCollisionHeight()) != 0)
if (m_caster.GetMap().GetLiquidStatus(m_caster.GetPhaseShift(), x, y, z, out liquidData, null, m_caster.GetCollisionHeight()) != 0)
liquidLevel = liquidData.level;
if (liquidLevel <= ground) // When there is no liquid Map.GetWaterOrGroundLevel returns ground level
+1 -1
View File
@@ -153,7 +153,7 @@ namespace Scripts.Spells.Generic
Unit caster = GetCaster();
Position summonPos = caster.GetPosition();
LiquidData liquidStatus;
if (caster.GetMap().GetLiquidStatus(caster.GetPhaseShift(), caster.GetPositionX(), caster.GetPositionY(), caster.GetPositionZ(), LiquidHeaderTypeFlags.AllLiquids, out liquidStatus, caster.GetCollisionHeight()) != ZLiquidStatus.NoWater)
if (caster.GetMap().GetLiquidStatus(caster.GetPhaseShift(), caster.GetPositionX(), caster.GetPositionY(), caster.GetPositionZ(), out liquidStatus, null, caster.GetCollisionHeight()) != ZLiquidStatus.NoWater)
summonPos.posZ = liquidStatus.level;
dest.Relocate(summonPos);
}