Core/Maps: Updated vmaps and some cleaups

This commit is contained in:
hondacrx
2018-05-03 00:05:50 -04:00
parent 3ca70aae30
commit 1a7f31d4f2
14 changed files with 204 additions and 269 deletions
+53 -62
View File
@@ -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;
+54 -45
View File
@@ -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)
+3 -8
View File
@@ -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
View File
@@ -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);
}