public MultiComponentList(GenericReader reader) { int version = reader.ReadInt(); m_Min = reader.ReadPoint2D(); m_Max = reader.ReadPoint2D(); m_Center = reader.ReadPoint2D(); m_Width = reader.ReadInt(); m_Height = reader.ReadInt(); int length = reader.ReadInt(); MultiTileEntry[] allTiles = m_List = new MultiTileEntry[length]; if (version == 0) { for (int i = 0; i < length; ++i) { int id = reader.ReadShort(); if (id >= 0x4000) { id -= 0x4000; } allTiles[i].m_ItemID = (ushort)id; allTiles[i].m_OffsetX = reader.ReadShort(); allTiles[i].m_OffsetY = reader.ReadShort(); allTiles[i].m_OffsetZ = reader.ReadShort(); allTiles[i].m_Flags = reader.ReadInt(); } } else { for (int i = 0; i < length; ++i) { allTiles[i].m_ItemID = reader.ReadUShort(); allTiles[i].m_OffsetX = reader.ReadShort(); allTiles[i].m_OffsetY = reader.ReadShort(); allTiles[i].m_OffsetZ = reader.ReadShort(); allTiles[i].m_Flags = reader.ReadInt(); } } TileList[][] tiles = new TileList[m_Width][]; m_Tiles = new StaticTile[m_Width][][]; for (int x = 0; x < m_Width; ++x) { tiles[x] = new TileList[m_Height]; m_Tiles[x] = new StaticTile[m_Height][]; for (int y = 0; y < m_Height; ++y) { tiles[x][y] = new TileList(); } } for (int i = 0; i < allTiles.Length; ++i) { if (i == 0 || allTiles[i].m_Flags != 0) { int xOffset = allTiles[i].m_OffsetX + m_Center.X; int yOffset = allTiles[i].m_OffsetY + m_Center.Y; tiles[xOffset][yOffset].Add((ushort)allTiles[i].m_ItemID, (sbyte)allTiles[i].m_OffsetZ); } } for (int x = 0; x < m_Width; ++x) { for (int y = 0; y < m_Height; ++y) { m_Tiles[x][y] = tiles[x][y].ToArray(); } } }
public MultiComponentList(BinaryReader reader, int count) { MultiTileEntry[] allTiles = m_List = new MultiTileEntry[count]; for (int i = 0; i < count; ++i) { allTiles[i].m_ItemID = reader.ReadUInt16(); allTiles[i].m_OffsetX = reader.ReadInt16(); allTiles[i].m_OffsetY = reader.ReadInt16(); allTiles[i].m_OffsetZ = reader.ReadInt16(); allTiles[i].m_Flags = reader.ReadInt32(); if (_PostHSFormat) { reader.ReadInt32(); // ?? } MultiTileEntry e = allTiles[i]; if (i == 0 || e.m_Flags != 0) { if (e.m_OffsetX < m_Min.X) { m_Min.X = e.m_OffsetX; } if (e.m_OffsetY < m_Min.Y) { m_Min.Y = e.m_OffsetY; } if (e.m_OffsetX > m_Max.X) { m_Max.X = e.m_OffsetX; } if (e.m_OffsetY > m_Max.Y) { m_Max.Y = e.m_OffsetY; } } } m_Center = new Point2D(-m_Min.X, -m_Min.Y); m_Width = (m_Max.X - m_Min.X) + 1; m_Height = (m_Max.Y - m_Min.Y) + 1; TileList[][] tiles = new TileList[m_Width][]; m_Tiles = new StaticTile[m_Width][][]; for (int x = 0; x < m_Width; ++x) { tiles[x] = new TileList[m_Height]; m_Tiles[x] = new StaticTile[m_Height][]; for (int y = 0; y < m_Height; ++y) { tiles[x][y] = new TileList(); } } for (int i = 0; i < allTiles.Length; ++i) { if (i == 0 || allTiles[i].m_Flags != 0) { int xOffset = allTiles[i].m_OffsetX + m_Center.X; int yOffset = allTiles[i].m_OffsetY + m_Center.Y; tiles[xOffset][yOffset].Add((ushort)allTiles[i].m_ItemID, (sbyte)allTiles[i].m_OffsetZ); } } for (int x = 0; x < m_Width; ++x) { for (int y = 0; y < m_Height; ++y) { m_Tiles[x][y] = tiles[x][y].ToArray(); } } }
public void Resize(int newWidth, int newHeight) { int oldWidth = m_Width, oldHeight = m_Height; StaticTile[][][] oldTiles = m_Tiles; int totalLength = 0; StaticTile[][][] newTiles = new StaticTile[newWidth][][]; for (int x = 0; x < newWidth; ++x) { newTiles[x] = new StaticTile[newHeight][]; for (int y = 0; y < newHeight; ++y) { if (x < oldWidth && y < oldHeight) { newTiles[x][y] = oldTiles[x][y]; } else { newTiles[x][y] = new StaticTile[0]; } totalLength += newTiles[x][y].Length; } } m_Tiles = newTiles; m_List = new MultiTileEntry[totalLength]; m_Width = newWidth; m_Height = newHeight; m_Min = Point2D.Zero; m_Max = Point2D.Zero; int index = 0; for (int x = 0; x < newWidth; ++x) { for (int y = 0; y < newHeight; ++y) { StaticTile[] tiles = newTiles[x][y]; for (int i = 0; i < tiles.Length; ++i) { StaticTile tile = tiles[i]; int vx = x - m_Center.X; int vy = y - m_Center.Y; if (vx < m_Min.X) { m_Min.X = vx; } if (vy < m_Min.Y) { m_Min.Y = vy; } if (vx > m_Max.X) { m_Max.X = vx; } if (vy > m_Max.Y) { m_Max.Y = vy; } m_List[index++] = new MultiTileEntry((ushort)tile.ID, (short)vx, (short)vy, (short)tile.Z, 1); } } } }
public void Add(int itemID, int x, int y, int z) { int vx = x + m_Center.X; int vy = y + m_Center.Y; if (vx >= 0 && vx < m_Width && vy >= 0 && vy < m_Height) { StaticTile[] oldTiles = m_Tiles[vx][vy]; for (int i = oldTiles.Length - 1; i >= 0; --i) { ItemData data = TileData.ItemTable[itemID & TileData.MaxItemValue]; if (oldTiles[i].Z == z && (oldTiles[i].Height > 0 == data.Height > 0)) { bool newIsRoof = (data.Flags & TileFlag.Roof) != 0; bool oldIsRoof = (TileData.ItemTable[oldTiles[i].ID & TileData.MaxItemValue].Flags & TileFlag.Roof) != 0; if (newIsRoof == oldIsRoof) { Remove(oldTiles[i].ID, x, y, z); } } } oldTiles = m_Tiles[vx][vy]; StaticTile[] newTiles = new StaticTile[oldTiles.Length + 1]; for (int i = 0; i < oldTiles.Length; ++i) { newTiles[i] = oldTiles[i]; } newTiles[oldTiles.Length] = new StaticTile((ushort)itemID, (sbyte)z); m_Tiles[vx][vy] = newTiles; MultiTileEntry[] oldList = m_List; MultiTileEntry[] newList = new MultiTileEntry[oldList.Length + 1]; for (int i = 0; i < oldList.Length; ++i) { newList[i] = oldList[i]; } newList[oldList.Length] = new MultiTileEntry((ushort)itemID, (short)x, (short)y, (short)z, 1); m_List = newList; if (x < m_Min.X) { m_Min.X = x; } if (y < m_Min.Y) { m_Min.Y = y; } if (x > m_Max.X) { m_Max.X = x; } if (y > m_Max.Y) { m_Max.Y = y; } } }
private unsafe int PatchStatics(TileMatrix matrix, string dataPath, string indexPath, string lookupPath) { using (FileStream fsData = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (FileStream fsIndex = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (FileStream fsLookup = new FileStream(lookupPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { BinaryReader indexReader = new BinaryReader(fsIndex); BinaryReader lookupReader = new BinaryReader(fsLookup); int count = (int)(indexReader.BaseStream.Length / 4); TileList[][] lists = new TileList[8][]; for (int x = 0; x < 8; ++x) { lists[x] = new TileList[8]; for (int y = 0; y < 8; ++y) { lists[x][y] = new TileList(); } } for (int i = 0; i < count; ++i) { int blockID = indexReader.ReadInt32(); int blockX = blockID / matrix.BlockHeight; int blockY = blockID % matrix.BlockHeight; int offset = lookupReader.ReadInt32(); int length = lookupReader.ReadInt32(); lookupReader.ReadInt32(); // Extra if (offset < 0 || length <= 0) { matrix.SetStaticBlock(blockX, blockY, matrix.EmptyStaticBlock); continue; } fsData.Seek(offset, SeekOrigin.Begin); int tileCount = length / 7; if (m_TileBuffer.Length < tileCount) { m_TileBuffer = new StaticTile[tileCount]; } StaticTile[] staTiles = m_TileBuffer; fixed(StaticTile *pTiles = staTiles) { #if !MONO NativeReader.Read(fsData.SafeFileHandle.DangerousGetHandle(), pTiles, length); #else NativeReader.Read(fsData.Handle, pTiles, length); #endif StaticTile *pCur = pTiles, pEnd = pTiles + tileCount; while (pCur < pEnd) { lists[pCur->m_X & 0x7][pCur->m_Y & 0x7].Add((ushort)pCur->m_ID, pCur->m_Z); pCur = pCur + 1; } StaticTile[][][] tiles = new StaticTile[8][][]; for (int x = 0; x < 8; ++x) { tiles[x] = new StaticTile[8][]; for (int y = 0; y < 8; ++y) { tiles[x][y] = lists[x][y].ToArray(); } } matrix.SetStaticBlock(blockX, blockY, tiles); } } indexReader.Close(); lookupReader.Close(); return(count); } } } }
private unsafe StaticTile[][][] ReadStaticBlock(int x, int y) { try { m_IndexReader.BaseStream.Seek(((x * m_BlockHeight) + y) * 12, SeekOrigin.Begin); int lookup = m_IndexReader.ReadInt32(); int length = m_IndexReader.ReadInt32(); if (lookup < 0 || length <= 0) { return(m_EmptyStaticBlock); } else { int count = length / 7; m_Statics.Seek(lookup, SeekOrigin.Begin); if (m_TileBuffer.Length < count) { m_TileBuffer = new StaticTile[count]; } StaticTile[] staTiles = m_TileBuffer;//new StaticTile[tileCount]; fixed(StaticTile *pTiles = staTiles) { #if !MONO NativeReader.Read(m_Statics.SafeFileHandle.DangerousGetHandle(), pTiles, length); #else NativeReader.Read(m_Statics.Handle, pTiles, length); #endif if (m_Lists == null) { m_Lists = new TileList[8][]; for (int i = 0; i < 8; ++i) { m_Lists[i] = new TileList[8]; for (int j = 0; j < 8; ++j) { m_Lists[i][j] = new TileList(); } } } TileList[][] lists = m_Lists; StaticTile *pCur = pTiles, pEnd = pTiles + count; while (pCur < pEnd) { lists[pCur->m_X & 0x7][pCur->m_Y & 0x7].Add(pCur->m_ID, pCur->m_Z); pCur = pCur + 1; } StaticTile[][][] tiles = new StaticTile[8][][]; for (int i = 0; i < 8; ++i) { tiles[i] = new StaticTile[8][]; for (int j = 0; j < 8; ++j) { tiles[i][j] = lists[i][j].ToArray(); } } return(tiles); } } } catch (EndOfStreamException) { if (DateTime.UtcNow >= m_NextStaticWarning) { Console.WriteLine("Warning: Static EOS for {0} ({1}, {2})", m_Owner, x, y); m_NextStaticWarning = DateTime.UtcNow + TimeSpan.FromMinutes(1.0); } return(m_EmptyStaticBlock); } }
public TileMatrix(Map owner, int fileIndex, int mapID, int width, int height) { lock (m_Instances) { for (int i = 0; i < m_Instances.Count; ++i) { TileMatrix tm = m_Instances[i]; if (tm.m_FileIndex == fileIndex) { lock (m_FileShare) { lock (tm.m_FileShare) { tm.m_FileShare.Add(this); m_FileShare.Add(tm); } } } } m_Instances.Add(this); } m_FileIndex = fileIndex; m_Width = width; m_Height = height; m_BlockWidth = width >> 3; m_BlockHeight = height >> 3; m_Owner = owner; if (fileIndex != 0x7F) { string mapPath = Core.FindDataFile("map{0}.mul", fileIndex); if (File.Exists(mapPath)) { m_Map = new FileStream(mapPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); } else { mapPath = Core.FindDataFile("map{0}LegacyMUL.uop", fileIndex); if (File.Exists(mapPath)) { m_Map = new FileStream(mapPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); m_MapIndex = new UOPIndex(m_Map); } } string indexPath = Core.FindDataFile("staidx{0}.mul", fileIndex); if (File.Exists(indexPath)) { m_Index = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); m_IndexReader = new BinaryReader(m_Index); } string staticsPath = Core.FindDataFile("statics{0}.mul", fileIndex); if (File.Exists(staticsPath)) { m_Statics = new FileStream(staticsPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); } } m_EmptyStaticBlock = new StaticTile[8][][]; for (int i = 0; i < 8; ++i) { m_EmptyStaticBlock[i] = new StaticTile[8][]; for (int j = 0; j < 8; ++j) { m_EmptyStaticBlock[i][j] = new StaticTile[0]; } } m_InvalidLandBlock = new LandTile[196]; m_LandTiles = new LandTile[m_BlockWidth][][]; m_StaticTiles = new StaticTile[m_BlockWidth][][][][]; m_StaticPatches = new int[m_BlockWidth][]; m_LandPatches = new int[m_BlockWidth][]; m_Patch = new TileMatrixPatch(this, mapID); }