Core/Maps: Updated vmaps and some cleaups
This commit is contained in:
+53
-62
@@ -46,22 +46,33 @@ namespace Game.Maps
|
||||
_fileExists = true;
|
||||
using (BinaryReader reader = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read)))
|
||||
{
|
||||
mapFileHeader header = reader.ReadStruct<mapFileHeader>();
|
||||
if (new string(header.mapMagic) != MapConst.MapMagic || new string(header.versionMagic) != MapConst.MapVersionMagic)
|
||||
mapFileHeader header = reader.Read<mapFileHeader>();
|
||||
if (header.mapMagic != MapConst.MapMagic || header.versionMagic != MapConst.MapVersionMagic)
|
||||
{
|
||||
Log.outError(LogFilter.Maps, "Map file '{0}' is from an incompatible map version. Please recreate using the mapextractor.", filename);
|
||||
Log.outError(LogFilter.Maps, $"Map file '{filename}' is from an incompatible map version. Please recreate using the mapextractor.");
|
||||
return false;
|
||||
}
|
||||
if (header.areaMapOffset != 0)
|
||||
LoadAreaData(reader, header.areaMapOffset);
|
||||
|
||||
if (header.heightMapOffset != 0)
|
||||
LoadHeightData(reader, header.heightMapOffset);
|
||||
if (header.areaMapOffset != 0 && !LoadAreaData(reader, header.areaMapOffset))
|
||||
{
|
||||
Log.outError(LogFilter.Maps, "Error loading map area data");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (header.liquidMapOffset != 0)
|
||||
LoadLiquidData(reader, header.liquidMapOffset);
|
||||
if (header.heightMapOffset != 0 && !LoadHeightData(reader, header.heightMapOffset))
|
||||
{
|
||||
Log.outError(LogFilter.Maps, "Error loading map height data");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (header.liquidMapOffset != 0 && !LoadLiquidData(reader, header.liquidMapOffset))
|
||||
{
|
||||
Log.outError(LogFilter.Maps, "Error loading map liquids data");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void unloadData()
|
||||
@@ -76,25 +87,28 @@ namespace Game.Maps
|
||||
_fileExists = false;
|
||||
}
|
||||
|
||||
void LoadAreaData(BinaryReader reader, uint offset)
|
||||
bool LoadAreaData(BinaryReader reader, uint offset)
|
||||
{
|
||||
reader.BaseStream.Seek(offset, SeekOrigin.Begin);
|
||||
map_AreaHeader areaHeader = reader.ReadStruct<map_AreaHeader>();
|
||||
map_AreaHeader areaHeader = reader.Read<map_AreaHeader>();
|
||||
if (areaHeader.fourcc != MapConst.MapAreaMagic)
|
||||
return false;
|
||||
|
||||
_gridArea = areaHeader.gridArea;
|
||||
|
||||
if (!areaHeader.flags.HasAnyFlag(AreaHeaderFlags.NoArea))
|
||||
{
|
||||
_areaMap = new ushort[16 * 16];
|
||||
for (var i = 0; i < _areaMap.Length; ++i)
|
||||
_areaMap[i] = reader.ReadUInt16();
|
||||
}
|
||||
_areaMap = reader.ReadArray<ushort>(16 * 16);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LoadHeightData(BinaryReader reader, uint offset)
|
||||
bool LoadHeightData(BinaryReader reader, uint offset)
|
||||
{
|
||||
reader.BaseStream.Seek(offset, SeekOrigin.Begin);
|
||||
map_HeightHeader mapHeader = reader.ReadStruct<map_HeightHeader>();
|
||||
map_HeightHeader mapHeader = reader.Read<map_HeightHeader>();
|
||||
|
||||
if (mapHeader.fourcc != MapConst.MapHeightMagic)
|
||||
return false;
|
||||
|
||||
_gridHeight = mapHeader.gridHeight;
|
||||
_flags = (uint)mapHeader.flags;
|
||||
@@ -103,13 +117,8 @@ namespace Game.Maps
|
||||
{
|
||||
if (mapHeader.flags.HasAnyFlag(HeightHeaderFlags.HeightAsInt16))
|
||||
{
|
||||
m_uint16_V9 = new ushort[129 * 129];
|
||||
for (var i = 0; i < m_uint16_V9.Length; ++i)
|
||||
m_uint16_V9[i] = reader.ReadUInt16();
|
||||
|
||||
m_uint16_V8 = new ushort[128 * 128];
|
||||
for (var i = 0; i < m_uint16_V8.Length; ++i)
|
||||
m_uint16_V8[i] = reader.ReadUInt16();
|
||||
m_uint16_V9 = reader.ReadArray<ushort>(129 * 129);
|
||||
m_uint16_V8 = reader.ReadArray<ushort>(128 * 128);
|
||||
|
||||
_gridIntHeightMultiplier = (mapHeader.gridMaxHeight - mapHeader.gridHeight) / 65535;
|
||||
_gridGetHeight = getHeightFromUint16;
|
||||
@@ -123,13 +132,8 @@ namespace Game.Maps
|
||||
}
|
||||
else
|
||||
{
|
||||
m_V9 = new float[129 * 129];
|
||||
for (var i = 0; i < m_V9.Length; ++i)
|
||||
m_V9[i] = reader.ReadSingle();
|
||||
|
||||
m_V8 = new float[128 * 128];
|
||||
for (var i = 0; i < m_V8.Length; ++i)
|
||||
m_V8[i] = reader.ReadSingle();
|
||||
m_V9 = reader.ReadArray<float>(129 * 129);
|
||||
m_V8 = reader.ReadArray<float>(128 * 128);
|
||||
|
||||
_gridGetHeight = getHeightFromFloat;
|
||||
}
|
||||
@@ -139,13 +143,8 @@ namespace Game.Maps
|
||||
|
||||
if (mapHeader.flags.HasAnyFlag(HeightHeaderFlags.HeightHasFlightBounds))
|
||||
{
|
||||
short[] maxHeights = new short[3 * 3];
|
||||
short[] minHeights = new short[3 * 3];
|
||||
for (var i = 0; i < maxHeights.Length; ++i)
|
||||
maxHeights[i] = reader.ReadInt16();
|
||||
|
||||
for (var i = 0; i < minHeights.Length; ++i)
|
||||
minHeights[i] = reader.ReadInt16();
|
||||
short[] maxHeights = reader.ReadArray<short>(3 * 3);
|
||||
short[] minHeights = reader.ReadArray<short>(3 * 3);
|
||||
|
||||
uint[][] indices =
|
||||
{
|
||||
@@ -180,15 +179,20 @@ namespace Game.Maps
|
||||
new Vector3(boundGridCoords[indices[quarterIndex][2]][0], boundGridCoords[indices[quarterIndex][2]][1], minHeights[indices[quarterIndex][2]])
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LoadLiquidData(BinaryReader reader, uint offset)
|
||||
bool LoadLiquidData(BinaryReader reader, uint offset)
|
||||
{
|
||||
reader.BaseStream.Seek(offset, SeekOrigin.Begin);
|
||||
map_LiquidHeader liquidHeader = reader.ReadStruct<map_LiquidHeader>();
|
||||
map_LiquidHeader liquidHeader = reader.Read<map_LiquidHeader>();
|
||||
|
||||
if (liquidHeader.fourcc != MapConst.MapLiquidMagic)
|
||||
return false;
|
||||
|
||||
_liquidGlobalEntry = liquidHeader.liquidType;
|
||||
_liquidGlobalFlags = (byte)liquidHeader.liquidFlags;
|
||||
_liquidGlobalFlags = liquidHeader.liquidFlags;
|
||||
_liquidOffX = liquidHeader.offsetX;
|
||||
_liquidOffY = liquidHeader.offsetY;
|
||||
_liquidWidth = liquidHeader.width;
|
||||
@@ -197,19 +201,14 @@ namespace Game.Maps
|
||||
|
||||
if (!liquidHeader.flags.HasAnyFlag(LiquidHeaderFlags.LiquidNoType))
|
||||
{
|
||||
_liquidEntry = new ushort[16 * 16];
|
||||
for (var i = 0; i < _liquidEntry.Length; ++i)
|
||||
_liquidEntry[i] = reader.ReadUInt16();
|
||||
|
||||
_liquidEntry = reader.ReadArray<ushort>(16 * 16);
|
||||
_liquidFlags = reader.ReadBytes(16 * 16);
|
||||
}
|
||||
|
||||
if (!liquidHeader.flags.HasAnyFlag(LiquidHeaderFlags.LiquidNoHeight))
|
||||
{
|
||||
_liquidMap = new float[_liquidWidth * _liquidHeight];
|
||||
for (var i = 0; i < _liquidMap.Length; ++i)
|
||||
_liquidMap[i] = reader.ReadSingle();
|
||||
}
|
||||
_liquidMap = reader.ReadArray<float>((uint)(_liquidWidth * _liquidHeight));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ushort getArea(float x, float y)
|
||||
@@ -636,14 +635,10 @@ namespace Game.Maps
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct mapFileHeader
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public char[] mapMagic;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public char[] versionMagic;
|
||||
public uint mapMagic;
|
||||
public uint versionMagic;
|
||||
public uint buildMagic;
|
||||
public uint areaMapOffset;
|
||||
public uint areaMapSize;
|
||||
@@ -655,7 +650,6 @@ namespace Game.Maps
|
||||
public uint holesSize;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct map_AreaHeader
|
||||
{
|
||||
public uint fourcc;
|
||||
@@ -663,7 +657,6 @@ namespace Game.Maps
|
||||
public ushort gridArea;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct map_HeightHeader
|
||||
{
|
||||
public uint fourcc;
|
||||
@@ -672,7 +665,6 @@ namespace Game.Maps
|
||||
public float gridMaxHeight;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct map_LiquidHeader
|
||||
{
|
||||
public uint fourcc;
|
||||
@@ -686,7 +678,6 @@ namespace Game.Maps
|
||||
public float liquidLevel;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class LiquidData
|
||||
{
|
||||
public uint type_flags;
|
||||
|
||||
@@ -178,64 +178,73 @@ namespace Game.Maps
|
||||
|
||||
InstanceMap CreateInstance(uint InstanceId, InstanceSave save, Difficulty difficulty, int teamId)
|
||||
{
|
||||
// make sure we have a valid map id
|
||||
MapRecord entry = CliDB.MapStorage.LookupByKey(GetId());
|
||||
if (entry == null)
|
||||
lock (_mapLock)
|
||||
{
|
||||
Log.outError(LogFilter.Maps, "CreateInstance: no record for map {0}", GetId());
|
||||
Contract.Assert(false);
|
||||
// make sure we have a valid map id
|
||||
MapRecord entry = CliDB.MapStorage.LookupByKey(GetId());
|
||||
if (entry == null)
|
||||
{
|
||||
Log.outError(LogFilter.Maps, "CreateInstance: no record for map {0}", GetId());
|
||||
Contract.Assert(false);
|
||||
}
|
||||
InstanceTemplate iTemplate = Global.ObjectMgr.GetInstanceTemplate(GetId());
|
||||
if (iTemplate == null)
|
||||
{
|
||||
Log.outError(LogFilter.Maps, "CreateInstance: no instance template for map {0}", GetId());
|
||||
Contract.Assert(false);
|
||||
}
|
||||
|
||||
// some instances only have one difficulty
|
||||
Global.DB2Mgr.GetDownscaledMapDifficultyData(GetId(), ref difficulty);
|
||||
|
||||
Log.outDebug(LogFilter.Maps, "MapInstanced.CreateInstance: {0} map instance {1} for {2} created with difficulty {3}", save != null ? "" : "new ", InstanceId, GetId(), difficulty);
|
||||
|
||||
InstanceMap map = new InstanceMap(GetId(), GetGridExpiry(), InstanceId, difficulty, this);
|
||||
Contract.Assert(map.IsDungeon());
|
||||
|
||||
map.LoadRespawnTimes();
|
||||
map.LoadCorpseData();
|
||||
|
||||
bool load_data = save != null;
|
||||
map.CreateInstanceData(load_data);
|
||||
InstanceScenario instanceScenario = Global.ScenarioMgr.CreateInstanceScenario(map, teamId);
|
||||
if (instanceScenario != null)
|
||||
map.SetInstanceScenario(instanceScenario);
|
||||
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.InstancemapLoadGrids))
|
||||
map.LoadAllCells();
|
||||
|
||||
m_InstancedMaps[InstanceId] = map;
|
||||
return map;
|
||||
}
|
||||
InstanceTemplate iTemplate = Global.ObjectMgr.GetInstanceTemplate(GetId());
|
||||
if (iTemplate == null)
|
||||
{
|
||||
Log.outError(LogFilter.Maps, "CreateInstance: no instance template for map {0}", GetId());
|
||||
Contract.Assert(false);
|
||||
}
|
||||
|
||||
// some instances only have one difficulty
|
||||
Global.DB2Mgr.GetDownscaledMapDifficultyData(GetId(), ref difficulty);
|
||||
|
||||
Log.outDebug(LogFilter.Maps, "MapInstanced.CreateInstance: {0} map instance {1} for {2} created with difficulty {3}", save != null ? "" : "new ", InstanceId, GetId(), difficulty);
|
||||
|
||||
InstanceMap map = new InstanceMap(GetId(), GetGridExpiry(), InstanceId, difficulty, this);
|
||||
Contract.Assert(map.IsDungeon());
|
||||
|
||||
map.LoadRespawnTimes();
|
||||
map.LoadCorpseData();
|
||||
|
||||
bool load_data = save != null;
|
||||
map.CreateInstanceData(load_data);
|
||||
InstanceScenario instanceScenario = Global.ScenarioMgr.CreateInstanceScenario(map, teamId);
|
||||
if (instanceScenario != null)
|
||||
map.SetInstanceScenario(instanceScenario);
|
||||
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.InstancemapLoadGrids))
|
||||
map.LoadAllCells();
|
||||
|
||||
m_InstancedMaps[InstanceId] = map;
|
||||
return map;
|
||||
}
|
||||
|
||||
BattlegroundMap CreateBattleground(uint InstanceId, Battleground bg)
|
||||
{
|
||||
Log.outDebug(LogFilter.Maps, "MapInstanced.CreateBattleground: map bg {0} for {1} created.", InstanceId, GetId());
|
||||
lock (_mapLock)
|
||||
{
|
||||
Log.outDebug(LogFilter.Maps, "MapInstanced.CreateBattleground: map bg {0} for {1} created.", InstanceId, GetId());
|
||||
|
||||
BattlegroundMap map = new BattlegroundMap(GetId(), (uint)GetGridExpiry(), InstanceId, this, Difficulty.None);
|
||||
Contract.Assert(map.IsBattlegroundOrArena());
|
||||
map.SetBG(bg);
|
||||
bg.SetBgMap(map);
|
||||
BattlegroundMap map = new BattlegroundMap(GetId(), (uint)GetGridExpiry(), InstanceId, this, Difficulty.None);
|
||||
Contract.Assert(map.IsBattlegroundOrArena());
|
||||
map.SetBG(bg);
|
||||
bg.SetBgMap(map);
|
||||
|
||||
m_InstancedMaps[InstanceId] = map;
|
||||
return map;
|
||||
m_InstancedMaps[InstanceId] = map;
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
GarrisonMap CreateGarrison(uint instanceId, Player owner)
|
||||
{
|
||||
GarrisonMap map = new GarrisonMap(GetId(), GetGridExpiry(), instanceId, this, owner.GetGUID());
|
||||
Contract.Assert(map.IsGarrison());
|
||||
lock (_mapLock)
|
||||
{
|
||||
GarrisonMap map = new GarrisonMap(GetId(), GetGridExpiry(), instanceId, this, owner.GetGUID());
|
||||
Contract.Assert(map.IsGarrison());
|
||||
|
||||
m_InstancedMaps[instanceId] = map;
|
||||
return map;
|
||||
m_InstancedMaps[instanceId] = map;
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
bool DestroyInstance(KeyValuePair<uint, Map> pair)
|
||||
|
||||
@@ -139,9 +139,8 @@ namespace Game
|
||||
|
||||
using (BinaryReader reader = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read)))
|
||||
{
|
||||
MmapTileHeader fileHeader = reader.ReadStruct<MmapTileHeader>();
|
||||
Array.Reverse(fileHeader.mmapMagic);
|
||||
if (new string(fileHeader.mmapMagic) != MapConst.mmapMagic)
|
||||
MmapTileHeader fileHeader = reader.Read<MmapTileHeader>();
|
||||
if (fileHeader.mmapMagic != MapConst.mmapMagic)
|
||||
{
|
||||
Log.outError(LogFilter.Maps, "MMAP:loadMap: Bad header in mmap {0:D4}{1:D2}{2:D2}.mmtile", mapId, x, y);
|
||||
return false;
|
||||
@@ -356,16 +355,12 @@ namespace Game
|
||||
public Dictionary<uint, ulong> loadedTileRefs = new Dictionary<uint, ulong>(); // maps [map grid coords] to [dtTile]
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct MmapTileHeader
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public char[] mmapMagic;
|
||||
public uint mmapMagic;
|
||||
public uint dtVersion;
|
||||
public uint mmapVersion;
|
||||
public uint size;
|
||||
public byte usesLiquids;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] padding;
|
||||
}
|
||||
}
|
||||
|
||||
+14
-5
@@ -96,11 +96,11 @@ namespace Game.Maps
|
||||
|
||||
using (var reader = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read)))
|
||||
{
|
||||
var header = reader.ReadStruct<mapFileHeader>();
|
||||
if (new string(header.mapMagic) != MapConst.MapMagic || new string(header.versionMagic) != MapConst.MapVersionMagic)
|
||||
var header = reader.Read<mapFileHeader>();
|
||||
if (header.mapMagic != MapConst.MapMagic || header.versionMagic != MapConst.MapVersionMagic)
|
||||
{
|
||||
Log.outError(LogFilter.Maps, "Map file '{0}' is from an incompatible map version ({1}), {2} is expected. Please recreate using the mapextractor.",
|
||||
fileName, new string(header.versionMagic), MapConst.MapVersionMagic);
|
||||
fileName, header.versionMagic, MapConst.MapVersionMagic);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -136,6 +136,9 @@ namespace Game.Maps
|
||||
|
||||
void LoadVMap(uint gx, uint gy)
|
||||
{
|
||||
if (!Global.VMapMgr.isMapLoadingEnabled())
|
||||
return;
|
||||
|
||||
// x and y are swapped !!
|
||||
VMAPLoadResult vmapLoadResult = Global.VMapMgr.loadMap(GetId(), gx, gy);
|
||||
switch (vmapLoadResult)
|
||||
@@ -363,7 +366,7 @@ namespace Game.Maps
|
||||
|
||||
void EnsureGridCreated(GridCoord p)
|
||||
{
|
||||
lock (this)
|
||||
lock (_gridLock)
|
||||
{
|
||||
EnsureGridCreated_i(p);
|
||||
}
|
||||
@@ -4338,6 +4341,9 @@ namespace Game.Maps
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
internal object _mapLock = new object();
|
||||
object _gridLock = new object();
|
||||
|
||||
bool _creatureToMoveLock;
|
||||
List<Creature> creaturesToMove = new List<Creature>();
|
||||
|
||||
@@ -4455,6 +4461,7 @@ namespace Game.Maps
|
||||
/// @todo Not sure about checking player level: already done in HandleAreaTriggerOpcode
|
||||
// GMs still can teleport player in instance.
|
||||
// Is it needed?
|
||||
lock(_mapLock)
|
||||
{
|
||||
// Dungeon only code
|
||||
if (IsDungeon())
|
||||
@@ -4878,7 +4885,9 @@ namespace Game.Maps
|
||||
|
||||
public override bool AddPlayerToMap(Player player, bool initPlayer = true)
|
||||
{
|
||||
player.m_InstanceValid = true;
|
||||
lock (_mapLock)
|
||||
player.m_InstanceValid = true;
|
||||
|
||||
return base.AddPlayerToMap(player, initPlayer);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user