public MultiComponentList( MultiComponentList toCopy ) { m_Min = toCopy.m_Min; m_Max = toCopy.m_Max; m_Center = toCopy.m_Center; m_Width = toCopy.m_Width; m_Height = toCopy.m_Height; m_Tiles = new StaticTile[m_Width][][]; for ( int x = 0; x < m_Width; ++x ) { m_Tiles[x] = new StaticTile[m_Height][]; for ( int y = 0; y < m_Height; ++y ) { m_Tiles[x][y] = new StaticTile[toCopy.m_Tiles[x][y].Length]; for ( int i = 0; i < m_Tiles[x][y].Length; ++i ) m_Tiles[x][y][i] = toCopy.m_Tiles[x][y][i]; } } m_List = new MultiTileEntry[toCopy.m_List.Length]; for ( int i = 0; i < m_List.Length; ++i ) m_List[i] = toCopy.m_List[i]; }
public void AddRange(StaticTile[] tiles) { if ((this.m_Count + tiles.Length) > this.m_Tiles.Length) { StaticTile[] old = this.m_Tiles; this.m_Tiles = new StaticTile[(this.m_Count + tiles.Length) * 2]; for (int i = 0; i < old.Length; ++i) this.m_Tiles[i] = old[i]; } for (int i = 0; i < tiles.Length; ++i) this.m_Tiles[this.m_Count++] = tiles[i]; }
public void AddRange( StaticTile[] tiles ) { if ( (m_Count + tiles.Length) > m_Tiles.Length ) { StaticTile[] old = m_Tiles; m_Tiles = new StaticTile[(m_Count + tiles.Length) * 2]; for ( int i = 0; i < old.Length; ++i ) m_Tiles[i] = old[i]; } for ( int i = 0; i < tiles.Length; ++i ) m_Tiles[m_Count++] = tiles[i]; }
public StaticTile[] ToArray() { if (this.m_Count == 0) return m_EmptyTiles; StaticTile[] tiles = new StaticTile[this.m_Count]; for (int i = 0; i < this.m_Count; ++i) tiles[i] = this.m_Tiles[i]; this.m_Count = 0; return tiles; }
public static StaticTile[] PatchTiles(StaticTile[] tiles, int season) { if ( season <= 0 || season >= SeasonCount ) return tiles; var tileChanges = m_TileChanges[season]; if ( tileChanges != null ) { for ( int i = 0; i < tiles.Length; i++ ) { if (tileChanges.ContainsKey(tiles[i].ID)) tiles[i].ID = tileChanges[tiles[i].ID]; } } return tiles; }
private bool IsOk( bool ignoreDoors, bool ignoreSpellFields, int ourZ, int ourTop, StaticTile[] tiles, List<Item> items ) { for ( int i = 0; i < tiles.Length; ++i ) { StaticTile check = tiles[i]; ItemData itemData = TileData.ItemTable[check.ID & TileData.MaxItemValue]; if ( (itemData.Flags & ImpassableSurface) != 0 ) // Impassable || Surface { int checkZ = check.Z; int checkTop = checkZ + itemData.CalcHeight; if ( checkTop > ourZ && ourTop > checkZ ) return false; } } for ( int i = 0; i < items.Count; ++i ) { Item item = items[i]; int itemID = item.ItemID & TileData.MaxItemValue; ItemData itemData = TileData.ItemTable[itemID]; TileFlag flags = itemData.Flags; if ( (flags & ImpassableSurface) != 0 ) // Impassable || Surface { if ( ignoreDoors && ((flags & TileFlag.Door) != 0 || itemID == 0x692 || itemID == 0x846 || itemID == 0x873 || (itemID >= 0x6F5 && itemID <= 0x6F6)) ) continue; if ( ignoreSpellFields && ( itemID == 0x82 || itemID == 0x3946 || itemID == 0x3956 ) ) continue; int checkZ = item.Z; int checkTop = checkZ + itemData.CalcHeight; if ( checkTop > ourZ && ourTop > checkZ ) return false; } } return true; }
public MultiComponentList(BinaryReader reader, int count) { MultiTileEntry[] allTiles = 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.m_X) { m_Min.m_X = e.m_OffsetX; } if (e.m_OffsetY < m_Min.m_Y) { m_Min.m_Y = e.m_OffsetY; } if (e.m_OffsetX > m_Max.m_X) { m_Max.m_X = e.m_OffsetX; } if (e.m_OffsetY > m_Max.m_Y) { m_Max.m_Y = e.m_OffsetY; } } } m_Center = new Point2D(-m_Min.m_X, -m_Min.m_Y); Width = (m_Max.m_X - m_Min.m_X) + 1; Height = (m_Max.m_Y - m_Min.m_Y) + 1; TileList[][] tiles = new TileList[Width][]; Tiles = new StaticTile[Width][][]; for (int x = 0; x < Width; ++x) { tiles[x] = new TileList[Height]; Tiles[x] = new StaticTile[Height][]; for (int y = 0; y < 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.m_X; int yOffset = allTiles[i].m_OffsetY + m_Center.m_Y; tiles[xOffset][yOffset].Add(allTiles[i].m_ItemID, (sbyte)allTiles[i].m_OffsetZ); } } for (int x = 0; x < Width; ++x) { for (int y = 0; y < Height; ++y) { Tiles[x][y] = tiles[x][y].ToArray(); } } }
public MultiComponentList(GenericReader reader) { var version = reader.ReadInt(); m_Min = reader.ReadPoint2D(); m_Max = reader.ReadPoint2D(); m_Center = reader.ReadPoint2D(); Width = reader.ReadInt(); Height = reader.ReadInt(); var length = reader.ReadInt(); var allTiles = m_List = new MultiTileEntry[length]; if (version == 0) { for (var 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 = (TileFlag)reader.ReadUInt(); } } else { for (var 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(); if (version > 1) { allTiles[i].m_Flags = (TileFlag)reader.ReadULong(); } else { allTiles[i].m_Flags = (TileFlag)reader.ReadUInt(); } } } var tiles = new TileList[Width][]; Tiles = new StaticTile[Width][][]; for (var x = 0; x < Width; ++x) { tiles[x] = new TileList[Height]; Tiles[x] = new StaticTile[Height][]; for (var y = 0; y < Height; ++y) { tiles[x][y] = new TileList(); } } for (var i = 0; i < allTiles.Length; ++i) { if (i == 0 || allTiles[i].m_Flags != 0) { var xOffset = allTiles[i].m_OffsetX + m_Center.m_X; var yOffset = allTiles[i].m_OffsetY + m_Center.m_Y; var itemID = (allTiles[i].m_ItemID & TileData.MaxItemValue) | 0x10000; tiles[xOffset][yOffset].Add((ushort)itemID, (sbyte)allTiles[i].m_OffsetZ); } } for (var x = 0; x < Width; ++x) { for (var y = 0; y < Height; ++y) { Tiles[x][y] = tiles[x][y].ToArray(); } } }
public MultiComponentList(BinaryReader reader, int count) { var allTiles = List = new MultiTileEntry[count]; for (var i = 0; i < count; ++i) { allTiles[i].ItemId = reader.ReadUInt16(); allTiles[i].OffsetX = reader.ReadInt16(); allTiles[i].OffsetY = reader.ReadInt16(); allTiles[i].OffsetZ = reader.ReadInt16(); if (PostHSFormat) { allTiles[i].Flags = (TileFlag)reader.ReadUInt64(); } else { allTiles[i].Flags = (TileFlag)reader.ReadUInt32(); } var e = allTiles[i]; if (i == 0 || e.Flags != 0) { if (e.OffsetX < m_Min.m_X) { m_Min.m_X = e.OffsetX; } if (e.OffsetY < m_Min.m_Y) { m_Min.m_Y = e.OffsetY; } if (e.OffsetX > m_Max.m_X) { m_Max.m_X = e.OffsetX; } if (e.OffsetY > m_Max.m_Y) { m_Max.m_Y = e.OffsetY; } } } Center = new Point2D(-m_Min.m_X, -m_Min.m_Y); Width = m_Max.m_X - m_Min.m_X + 1; Height = m_Max.m_Y - m_Min.m_Y + 1; var tiles = new TileList[Width][]; Tiles = new StaticTile[Width][][]; for (var x = 0; x < Width; ++x) { tiles[x] = new TileList[Height]; Tiles[x] = new StaticTile[Height][]; for (var y = 0; y < Height; ++y) { tiles[x][y] = new TileList(); } } for (var i = 0; i < allTiles.Length; ++i) { if (i == 0 || allTiles[i].Flags != 0) { var xOffset = allTiles[i].OffsetX + Center.m_X; var yOffset = allTiles[i].OffsetY + Center.m_Y; tiles[xOffset][yOffset].Add(allTiles[i].ItemId, (sbyte)allTiles[i].OffsetZ); } } for (var x = 0; x < Width; ++x) { for (var y = 0; y < Height; ++y) { Tiles[x][y] = tiles[x][y].ToArray(); } } }
public void Add(int itemID, int x, int y, int z) { int vx = x + m_Center.m_X; int vy = y + m_Center.m_Y; if (vx >= 0 && vx < Width && vy >= 0 && vy < Height) { StaticTile[] oldTiles = 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 = 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); Tiles[vx][vy] = newTiles; MultiTileEntry[] oldList = 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); List = newList; if (x < m_Min.m_X) { m_Min.m_X = x; } if (y < m_Min.m_Y) { m_Min.m_Y = y; } if (x > m_Max.m_X) { m_Max.m_X = x; } if (y > m_Max.m_Y) { m_Max.m_Y = y; } } }
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.m_X ) m_Min.m_X = vx; if ( vy < m_Min.m_Y ) m_Min.m_Y = vy; if ( vx > m_Max.m_X ) m_Max.m_X = vx; if ( vy > m_Max.m_Y ) m_Max.m_Y = vy; m_List[index++] = new MultiTileEntry( (ushort)tile.ID, (short)vx, (short)vy, (short)tile.Z, 1 ); } } } }
public void Remove(int itemID, int x, int y, int z) { var vx = x + Center.m_X; var vy = y + Center.m_Y; if (vx >= 0 && vx < Width && vy >= 0 && vy < Height) { var oldTiles = Tiles[vx][vy]; for (var i = 0; i < oldTiles.Length; ++i) { var tile = oldTiles[i]; if (tile.ID == itemID && tile.Z == z) { var newTiles = new StaticTile[oldTiles.Length - 1]; for (var j = 0; j < i; ++j) { newTiles[j] = oldTiles[j]; } for (var j = i + 1; j < oldTiles.Length; ++j) { newTiles[j - 1] = oldTiles[j]; } Tiles[vx][vy] = newTiles; break; } } var oldList = List; for (var i = 0; i < oldList.Length; ++i) { var tile = oldList[i]; if (tile.ItemId == itemID && tile.OffsetX == (short)x && tile.OffsetY == (short)y && tile.OffsetZ == (short)z) { var newList = new MultiTileEntry[oldList.Length - 1]; for (var j = 0; j < i; ++j) { newList[j] = oldList[j]; } for (var j = i + 1; j < oldList.Length; ++j) { newList[j - 1] = oldList[j]; } List = newList; break; } } } }
private Tile[][][] 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_Buffer == null || length > m_Buffer.Length) { m_Buffer = new byte[length]; } GCHandle handle = GCHandle.Alloc(m_Buffer, GCHandleType.Pinned); try { m_Statics.Read(m_Buffer, 0, length); 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; for (int i = 0; i < count; i++) { IntPtr ptr = new IntPtr((long)handle.AddrOfPinnedObject() + i * 7); StaticTile cur = (StaticTile)Marshal.PtrToStructure(ptr, typeof(StaticTile)); lists[cur.m_X & 0x7][cur.m_Y & 0x7].Add((short)((cur.m_ID & 0x3FFF) + 0x4000), cur.m_Z); } Tile[][][] tiles = new Tile[8][][]; for (int i = 0; i < 8; ++i) { tiles[i] = new Tile[8][]; for (int j = 0; j < 8; ++j) { tiles[i][j] = lists[i][j].ToArray(); } } return(tiles); } finally { handle.Free(); } } } catch (EndOfStreamException) { if (Core.Now >= m_NextStaticWarning) { log.WarnFormat("Static EOS for {0} ({1}, {2})", m_Owner, x, y); m_NextStaticWarning = Core.Now + TimeSpan.FromMinutes(1.0); } return(m_EmptyStaticBlock); } }
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.m_X; int yOffset = allTiles[i].m_OffsetY + m_Center.m_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 static Point3D ToPoint3D(this StaticTile t) { return(new Point3D(t.X, t.Y, t.Z)); }
public static Coords ToCoords(this StaticTile t, Map m) { return(new Coords(m, ToPoint3D(t))); }
public static Point2D ToPoint2D(this StaticTile t) { return(new Point2D(t.X, t.Y)); }
public static MapPoint ToMapPoint(this StaticTile t, Map m) { return(new MapPoint(m, ToPoint3D(t))); }
public void RemoveXYZH(int x, int y, int z, int minHeight) { int vx = x + m_Center.m_X; int vy = y + m_Center.m_Y; if (vx >= 0 && vx < m_Width && vy >= 0 && vy < m_Height) { var oldTiles = m_Tiles[vx][vy]; for (int i = 0; i < oldTiles.Length; ++i) { StaticTile tile = oldTiles[i]; if (tile.Z == z && tile.Height >= minHeight) { var newTiles = new StaticTile[oldTiles.Length - 1]; for (int j = 0; j < i; ++j) { newTiles[j] = oldTiles[j]; } for (int j = i + 1; j < oldTiles.Length; ++j) { newTiles[j - 1] = oldTiles[j]; } m_Tiles[vx][vy] = newTiles; break; } } var oldList = m_List; for (int i = 0; i < oldList.Length; ++i) { MultiTileEntry tile = oldList[i]; if (tile.m_OffsetX == (short)x && tile.m_OffsetY == (short)y && tile.m_OffsetZ == (short)z && TileData.ItemTable[tile.m_ItemID & TileData.MaxItemValue].Height >= minHeight) { var newList = new MultiTileEntry[oldList.Length - 1]; for (int j = 0; j < i; ++j) { newList[j] = oldList[j]; } for (int j = i + 1; j < oldList.Length; ++j) { newList[j - 1] = oldList[j]; } m_List = newList; break; } } } }
public void SetStaticBlock( int x, int y, StaticTile[][][] value ) { if ( x < 0 || y < 0 || x >= m_BlockWidth || y >= m_BlockHeight ) return; if ( m_StaticTiles[x] == null ) m_StaticTiles[x] = new StaticTile[m_BlockHeight][][][]; m_StaticTiles[x][y] = value; if ( m_StaticPatches[x] == null ) m_StaticPatches[x] = new int[(m_BlockHeight + 31) >> 5]; m_StaticPatches[x][y >> 5] |= 1 << (y & 0x1F); }
public override bool IsExcludedTile(StaticTile tile) { return IsMastTile(tile); }
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.Now >= m_NextStaticWarning ) { Console.WriteLine( "Warning: Static EOS for {0} ({1}, {2})", m_Owner, x, y ); m_NextStaticWarning = DateTime.Now + TimeSpan.FromMinutes( 1.0 ); } return m_EmptyStaticBlock; } }
public override bool IsExcludedTile(StaticTile[] tiles) { foreach(StaticTile tile in tiles) { if (!IsMastTile(tile)) return false; } return true; }
public void Add( int itemID, int x, int y, int z ) { int vx = x + m_Center.m_X; int vy = y + m_Center.m_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.m_X ) m_Min.m_X = x; if ( y < m_Min.m_Y ) m_Min.m_Y = y; if ( x > m_Max.m_X ) m_Max.m_X = x; if ( y > m_Max.m_Y ) m_Max.m_Y = y; } }
public bool IsMastTile(StaticTile tile) { int id = tile.ID; if ((id >= 30150 && id <= 30193) || (id >= 30650 && id <= 30693)) return true; if ((id >= 30650 && id <= 30693) || (id >= 31150 && id <= 31193)) return true; if ((id >= 31150 && id <= 31193) || (id >= 31650 && id <= 31693)) return true; if ((id >= 31840 && id <= 31883) || (id >= 32040 && id <= 32083)) return true; if ((id >= 32240 && id <= 32283) || (id >= 32440 && id <= 32483)) return true; if ((id >= 32640 && id <= 32683) || (id >= 32840 && id <= 32883)) return true; if ((id >= 33040 && id <= 33083) || (id >= 33240 && id <= 33283)) return true; if ((id >= 23720 && id <= 23740) || (id >= 23742 && id <= 23892)) return true; if ((id >= 23894 && id <= 23902) || (id >= 23904 && id <= 23935)) return true; if (id >= 25256 && id <= 25471) return true; return false; }
public void RemoveXYZH(int x, int y, int z, int minHeight) { var vx = x + Center.m_X; var vy = y + Center.m_Y; if (vx >= 0 && vx < Width && vy >= 0 && vy < Height) { var oldTiles = Tiles[vx][vy]; for (var i = 0; i < oldTiles.Length; ++i) { var tile = oldTiles[i]; if (tile.Z == z && tile.Height >= minHeight) { var newTiles = new StaticTile[oldTiles.Length - 1]; for (var j = 0; j < i; ++j) { newTiles[j] = oldTiles[j]; } for (var j = i + 1; j < oldTiles.Length; ++j) { newTiles[j - 1] = oldTiles[j]; } Tiles[vx][vy] = newTiles; break; } } var oldList = List; for (var i = 0; i < oldList.Length; ++i) { var tile = oldList[i]; if (tile.OffsetX == (short)x && tile.OffsetY == (short)y && tile.OffsetZ == (short)z && TileData.ItemTable[tile.ItemId & TileData.MaxItemValue].Height >= minHeight) { var newList = new MultiTileEntry[oldList.Length - 1]; for (var j = 0; j < i; ++j) { newList[j] = oldList[j]; } for (var j = i + 1; j < oldList.Length; ++j) { newList[j - 1] = oldList[j]; } List = newList; break; } } } }
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); }
public static void Freeze( Mobile from, Map targetMap, Point3D start3d, Point3D end3d ) { Hashtable mapTable = new Hashtable(); if ( start3d == NullP3D && end3d == NullP3D ) { if ( targetMap == null ) CommandLogging.WriteLine( from, "{0} {1} invoking freeze for every item in every map", from.AccessLevel, CommandLogging.Format( from ) ); else CommandLogging.WriteLine( from, "{0} {1} invoking freeze for every item in {0}", from.AccessLevel, CommandLogging.Format( from ), targetMap ); foreach ( Item item in World.Items.Values ) { if ( targetMap != null && item.Map != targetMap ) continue; if ( item.Parent != null ) continue; if ( item is Static || item is BaseFloor || item is BaseWall ) { Map itemMap = item.Map; if ( itemMap == null || itemMap == Map.Internal ) continue; Hashtable table = (Hashtable)mapTable[itemMap]; if ( table == null ) mapTable[itemMap] = table = new Hashtable(); Point2D p = new Point2D( item.X >> 3, item.Y >> 3 ); DeltaState state = (DeltaState)table[p]; if ( state == null ) table[p] = state = new DeltaState( p ); state.m_List.Add( item ); } } } else if ( targetMap != null ) { Point2D start = targetMap.Bound( new Point2D( start3d ) ), end = targetMap.Bound( new Point2D( end3d ) ); CommandLogging.WriteLine( from, "{0} {1} invoking freeze from {2} to {3} in {4}", from.AccessLevel, CommandLogging.Format( from ), start, end, targetMap ); IPooledEnumerable eable = targetMap.GetItemsInBounds( new Rectangle2D( start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1 ) ); foreach ( Item item in eable ) { if ( item is Static || item is BaseFloor || item is BaseWall ) { Map itemMap = item.Map; if ( itemMap == null || itemMap == Map.Internal ) continue; Hashtable table = (Hashtable)mapTable[itemMap]; if ( table == null ) mapTable[itemMap] = table = new Hashtable(); Point2D p = new Point2D( item.X >> 3, item.Y >> 3 ); DeltaState state = (DeltaState)table[p]; if ( state == null ) table[p] = state = new DeltaState( p ); state.m_List.Add( item ); } } eable.Free(); } if ( mapTable.Count == 0 ) { from.SendGump( new NoticeGump( 1060637, 30720, "No freezable items were found. Only the following item types are frozen:<br> - Static<br> - BaseFloor<br> - BaseWall", 0xFFC000, 320, 240, null, null ) ); return; } bool badDataFile = false; int totalFrozen = 0; foreach ( DictionaryEntry de in mapTable ) { Map map = (Map)de.Key; Hashtable table = (Hashtable)de.Value; TileMatrix matrix = map.Tiles; using ( FileStream idxStream = OpenWrite( matrix.IndexStream ) ) { using ( FileStream mulStream = OpenWrite( matrix.DataStream ) ) { if ( idxStream == null || mulStream == null ) { badDataFile = true; continue; } BinaryReader idxReader = new BinaryReader( idxStream ); BinaryWriter idxWriter = new BinaryWriter( idxStream ); BinaryWriter mulWriter = new BinaryWriter( mulStream ); foreach ( DeltaState state in table.Values ) { int oldTileCount; StaticTile[] oldTiles = ReadStaticBlock( idxReader, mulStream, state.m_X, state.m_Y, matrix.BlockWidth, matrix.BlockHeight, out oldTileCount ); if ( oldTileCount < 0 ) continue; int newTileCount = 0; StaticTile[] newTiles = new StaticTile[state.m_List.Count]; for ( int i = 0; i < state.m_List.Count; ++i ) { Item item = (Item)state.m_List[i]; int xOffset = item.X - (state.m_X * 8); int yOffset = item.Y - (state.m_Y * 8); if ( xOffset < 0 || xOffset >= 8 || yOffset < 0 || yOffset >= 8 ) continue; StaticTile newTile = new StaticTile(); newTile.m_ID = (short)(item.ItemID & 0x3FFF); newTile.m_X = (byte)xOffset; newTile.m_Y = (byte)yOffset; newTile.m_Z = (sbyte)item.Z; newTile.m_Hue = (short)item.Hue; newTiles[newTileCount++] = newTile; item.Delete(); ++totalFrozen; } int mulPos = -1; int length = -1; int extra = 0; if ( (oldTileCount + newTileCount) > 0 ) { mulWriter.Seek( 0, SeekOrigin.End ); mulPos = (int)mulWriter.BaseStream.Position; length = (oldTileCount + newTileCount) * 7; extra = 1; for ( int i = 0; i < oldTileCount; ++i ) { StaticTile toWrite = oldTiles[i]; mulWriter.Write( (short) toWrite.m_ID ); mulWriter.Write( (byte) toWrite.m_X ); mulWriter.Write( (byte) toWrite.m_Y ); mulWriter.Write( (sbyte) toWrite.m_Z ); mulWriter.Write( (short) toWrite.m_Hue ); } for ( int i = 0; i < newTileCount; ++i ) { StaticTile toWrite = newTiles[i]; mulWriter.Write( (short) toWrite.m_ID ); mulWriter.Write( (byte) toWrite.m_X ); mulWriter.Write( (byte) toWrite.m_Y ); mulWriter.Write( (sbyte) toWrite.m_Z ); mulWriter.Write( (short) toWrite.m_Hue ); } mulWriter.Flush(); } int idxPos = ((state.m_X * matrix.BlockHeight) + state.m_Y) * 12; idxWriter.Seek( idxPos, SeekOrigin.Begin ); idxWriter.Write( mulPos ); idxWriter.Write( length ); idxWriter.Write( extra ); idxWriter.Flush(); matrix.SetStaticBlock( state.m_X, state.m_Y, null ); } } } } if ( totalFrozen == 0 && badDataFile ) from.SendGump( new NoticeGump( 1060637, 30720, "Output data files could not be opened and the freeze operation has been aborted.<br><br>This probably means your server and client are using the same data files. Instructions on how to resolve this can be found in the first warning window.", 0xFFC000, 320, 240, null, null ) ); else from.SendGump( new NoticeGump( 1060637, 30720, String.Format( "Freeze operation completed successfully.<br><br>{0} item{1} frozen.<br><br>You must restart your client and update it's data files to see the changes.", totalFrozen, totalFrozen != 1 ? "s were" : " was" ), 0xFFC000, 320, 240, null, null ) ); }
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(); var 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(); } } var 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.m_X; int yOffset = allTiles[i].m_OffsetY + m_Center.m_Y; #region Stygian Abyss //tiles[xOffset][yOffset].Add( (ushort)allTiles[i].m_ItemID, (sbyte)allTiles[i].m_OffsetZ ); tiles[xOffset][yOffset].Add( (ushort)((allTiles[i].m_ItemID & TileData.MaxItemValue) | 0x10000), (sbyte)allTiles[i].m_OffsetZ); #endregion } } for (int x = 0; x < m_Width; ++x) { for (int y = 0; y < m_Height; ++y) { m_Tiles[x][y] = tiles[x][y].ToArray(); } } }
private unsafe int PatchStatics(TileMatrix matrix, string dataPath, string indexPath, string lookupPath) { using FileStream fsData = new(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read); using FileStream fsIndex = new(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read); using FileStream fsLookup = new(lookupPath, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReader indexReader = new(fsIndex); BinaryReader lookupReader = new(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(pCur->m_ID, pCur->m_Z); 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); }
public void Resize(int newWidth, int newHeight) { int oldWidth = Width, oldHeight = Height; var oldTiles = Tiles; var totalLength = 0; var newTiles = new StaticTile[newWidth][][]; for (var x = 0; x < newWidth; ++x) { newTiles[x] = new StaticTile[newHeight][]; for (var y = 0; y < newHeight; ++y) { if (x < oldWidth && y < oldHeight) { newTiles[x][y] = oldTiles[x][y]; } else { newTiles[x][y] = Array.Empty <StaticTile>(); } totalLength += newTiles[x][y].Length; } } Tiles = newTiles; List = new MultiTileEntry[totalLength]; Width = newWidth; Height = newHeight; m_Min = Point2D.Zero; m_Max = Point2D.Zero; var index = 0; for (var x = 0; x < newWidth; ++x) { for (var y = 0; y < newHeight; ++y) { var tiles = newTiles[x][y]; for (var i = 0; i < tiles.Length; ++i) { var tile = tiles[i]; var vx = x - Center.X; var vy = y - Center.Y; if (vx < m_Min.m_X) { m_Min.m_X = vx; } if (vy < m_Min.m_Y) { m_Min.m_Y = vy; } if (vx > m_Max.m_X) { m_Max.m_X = vx; } if (vy > m_Max.m_Y) { m_Max.m_Y = vy; } List[index++] = new MultiTileEntry( (ushort)tile.ID, (short)vx, (short)vy, (short)tile.Z, TileFlag.Background ); } } } }
public void Resize(int newWidth, int newHeight) { int oldWidth = Width, oldHeight = Height; StaticTile[][][] oldTiles = 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] = Array.Empty <StaticTile>(); } totalLength += newTiles[x][y].Length; } } Tiles = newTiles; List = new MultiTileEntry[totalLength]; Width = newWidth; 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.m_X) { m_Min.m_X = vx; } if (vy < m_Min.m_Y) { m_Min.m_Y = vy; } if (vx > m_Max.m_X) { m_Max.m_X = vx; } if (vy > m_Max.m_Y) { m_Max.m_Y = vy; } List[index++] = new MultiTileEntry((ushort)tile.ID, (short)vx, (short)vy, (short)tile.Z, 1); } } } }
public void Remove(int itemID, int x, int y, int z) { int vx = x + this.m_Center.m_X; int vy = y + this.m_Center.m_Y; if (vx >= 0 && vx < this.m_Width && vy >= 0 && vy < this.m_Height) { StaticTile[] oldTiles = this.m_Tiles[vx][vy]; for (int i = 0; i < oldTiles.Length; ++i) { StaticTile tile = oldTiles[i]; if (tile.ID == itemID && tile.Z == z) { StaticTile[] newTiles = new StaticTile[oldTiles.Length - 1]; for (int j = 0; j < i; ++j) newTiles[j] = oldTiles[j]; for (int j = i + 1; j < oldTiles.Length; ++j) newTiles[j - 1] = oldTiles[j]; this.m_Tiles[vx][vy] = newTiles; break; } } MultiTileEntry[] oldList = this.m_List; for (int i = 0; i < oldList.Length; ++i) { MultiTileEntry tile = oldList[i]; if (tile.m_ItemID == itemID && tile.m_OffsetX == (short)x && tile.m_OffsetY == (short)y && tile.m_OffsetZ == (short)z) { MultiTileEntry[] newList = new MultiTileEntry[oldList.Length - 1]; for (int j = 0; j < i; ++j) newList[j] = oldList[j]; for (int j = i + 1; j < oldList.Length; ++j) newList[j - 1] = oldList[j]; this.m_List = newList; break; } } } }
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]; } var 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(); } } } var 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); lists[pCur->m_X & 0x7][pCur->m_Y & 0x7].Add(pCur->m_ID, pCur->m_Z, pCur->m_Hue); //UltimaLive pCur = pCur + 1; } var 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 void Add(int itemID, int x, int y, int z) { itemID &= TileData.MaxItemValue; itemID |= 0x10000; var vx = x + m_Center.m_X; var vy = y + m_Center.m_Y; if (vx >= 0 && vx < Width && vy >= 0 && vy < Height) { var oldTiles = Tiles[vx][vy]; for (var i = oldTiles.Length - 1; i >= 0; --i) { var data = TileData.ItemTable[itemID & TileData.MaxItemValue]; if (oldTiles[i].Z == z && (oldTiles[i].Height > 0 == data.Height > 0)) { var newIsRoof = (data.Flags & TileFlag.Roof) != 0; var oldIsRoof = (TileData.ItemTable[oldTiles[i].ID & TileData.MaxItemValue].Flags & TileFlag.Roof) != 0; if (newIsRoof == oldIsRoof) { Remove(oldTiles[i].ID, x, y, z); } } } oldTiles = Tiles[vx][vy]; var newTiles = new StaticTile[oldTiles.Length + 1]; for (var i = 0; i < oldTiles.Length; ++i) { newTiles[i] = oldTiles[i]; } newTiles[oldTiles.Length] = new StaticTile((ushort)itemID, (sbyte)z); Tiles[vx][vy] = newTiles; var oldList = m_List; var newList = new MultiTileEntry[oldList.Length + 1]; for (var i = 0; i < oldList.Length; ++i) { newList[i] = oldList[i]; } newList[oldList.Length] = new MultiTileEntry((ushort)itemID, (short)x, (short)y, (short)z, TileFlag.Background); m_List = newList; if (x < m_Min.m_X) { m_Min.m_X = x; } if (y < m_Min.m_Y) { m_Min.m_Y = y; } if (x > m_Max.m_X) { m_Max.m_X = x; } if (y > m_Max.m_Y) { m_Max.m_Y = y; } } }
public MultiComponentList(BinaryReader reader, int count) { var 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.m_X) { m_Min.m_X = e.m_OffsetX; } if (e.m_OffsetY < m_Min.m_Y) { m_Min.m_Y = e.m_OffsetY; } if (e.m_OffsetX > m_Max.m_X) { m_Max.m_X = e.m_OffsetX; } if (e.m_OffsetY > m_Max.m_Y) { m_Max.m_Y = e.m_OffsetY; } } } m_Center = new Point2D(-m_Min.m_X, -m_Min.m_Y); m_Width = (m_Max.m_X - m_Min.m_X) + 1; m_Height = (m_Max.m_Y - m_Min.m_Y) + 1; var 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.m_X; int yOffset = allTiles[i].m_OffsetY + m_Center.m_Y; #region Stygian Abyss //tiles[xOffset][yOffset].Add( (ushort)allTiles[i].m_ItemID, (sbyte)allTiles[i].m_OffsetZ ); tiles[xOffset][yOffset].Add( (ushort)((allTiles[i].m_ItemID & TileData.MaxItemValue) | 0x10000), (sbyte)allTiles[i].m_OffsetZ); #endregion } } 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 Remove(int itemID, int x, int y, int z) { int vx = x + m_Center.m_X; int vy = y + m_Center.m_Y; if (vx >= 0 && vx < m_Width && vy >= 0 && vy < m_Height) { StaticTile[] oldTiles = m_Tiles[vx][vy]; for (int i = 0; i < oldTiles.Length; ++i) { StaticTile tile = oldTiles[i]; if (tile.ID == itemID && tile.Z == z) { StaticTile[] newTiles = new StaticTile[oldTiles.Length - 1]; for (int j = 0; j < i; ++j) { newTiles[j] = oldTiles[j]; } for (int j = i + 1; j < oldTiles.Length; ++j) { newTiles[j - 1] = oldTiles[j]; } m_Tiles[vx][vy] = newTiles; break; } } MultiTileEntry[] oldList = m_List; for (int i = 0; i < oldList.Length; ++i) { MultiTileEntry tile = oldList[i]; if (tile.m_ItemID == itemID && tile.m_OffsetX == (short)x && tile.m_OffsetY == (short)y && tile.m_OffsetZ == (short)z) { MultiTileEntry[] newList = new MultiTileEntry[oldList.Length - 1]; for (int j = 0; j < i; ++j) { newList[j] = oldList[j]; } for (int j = i + 1; j < oldList.Length; ++j) { newList[j - 1] = oldList[j]; } m_List = newList; break; } } } }
public virtual bool IsExcludedTile(StaticTile[] tile) { return false; }
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]; foreach (StaticTile tile in tiles) { int vx = x - m_Center.X; int vy = y - m_Center.Y; if (vx < m_Min.m_X) { m_Min.m_X = vx; } if (vy < m_Min.m_Y) { m_Min.m_Y = vy; } if (vx > m_Max.m_X) { m_Max.m_X = vx; } if (vy > m_Max.m_Y) { m_Max.m_Y = vy; } m_List[index++] = new MultiTileEntry((ushort)tile.ID, (short)vx, (short)vy, (short)tile.Z, TileFlag.Background); } } } }
public TileMatrix( Map owner, int fileIndex, int mapID, int width, int height ) { for ( int i = 0; i < m_Instances.Count; ++i ) { TileMatrix tm = m_Instances[i]; if ( tm.m_FileIndex == fileIndex ) { 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 ); 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 ); }
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(); if (PostHSFormat) { allTiles[i].m_Flags = (TileFlag)reader.ReadUInt64(); } else { allTiles[i].m_Flags = (TileFlag)reader.ReadUInt32(); } MultiTileEntry e = allTiles[i]; if (i == 0 || e.m_Flags != 0) { if (e.m_OffsetX < m_Min.m_X) { m_Min.m_X = e.m_OffsetX; } if (e.m_OffsetY < m_Min.m_Y) { m_Min.m_Y = e.m_OffsetY; } if (e.m_OffsetX > m_Max.m_X) { m_Max.m_X = e.m_OffsetX; } if (e.m_OffsetY > m_Max.m_Y) { m_Max.m_Y = e.m_OffsetY; } } } m_Center = new Point2D(-m_Min.m_X, -m_Min.m_Y); m_Width = m_Max.m_X - m_Min.m_X + 1; m_Height = m_Max.m_Y - m_Min.m_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.m_X; int yOffset = allTiles[i].m_OffsetY + m_Center.m_Y; int itemID = (allTiles[i].m_ItemID & TileData.MaxItemValue) | 0x10000; tiles[xOffset][yOffset].Add((ushort)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 StaticTile[][][] GetStaticBlock( int x, int y ) { if ( x < 0 || y < 0 || x >= m_BlockWidth || y >= m_BlockHeight || m_Statics == null || m_Index == null ) return m_EmptyStaticBlock; if ( m_StaticTiles[x] == null ) m_StaticTiles[x] = new StaticTile[m_BlockHeight][][][]; StaticTile[][][] tiles = m_StaticTiles[x][y]; if ( tiles == null ) { for ( int i = 0; tiles == null && i < m_FileShare.Count; ++i ) { TileMatrix shared = m_FileShare[i]; if ( x >= 0 && x < shared.m_BlockWidth && y >= 0 && y < shared.m_BlockHeight ) { StaticTile[][][][] theirTiles = shared.m_StaticTiles[x]; if ( theirTiles != null ) tiles = theirTiles[y]; if ( tiles != null ) { int[] theirBits = shared.m_StaticPatches[x]; if ( theirBits != null && (theirBits[y >> 5] & (1 << (y & 0x1F))) != 0 ) tiles = null; } } } if ( tiles == null ) tiles = ReadStaticBlock( x, y ); m_StaticTiles[x][y] = tiles; } return tiles; }
public MultiComponentList(List <MultiTileEntry> list) { MultiTileEntry[] allTiles = m_List = new MultiTileEntry[list.Count]; for (int i = 0; i < list.Count; ++i) { allTiles[i].m_ItemID = list[i].m_ItemID; allTiles[i].m_OffsetX = list[i].m_OffsetX; allTiles[i].m_OffsetY = list[i].m_OffsetY; allTiles[i].m_OffsetZ = list[i].m_OffsetZ; allTiles[i].m_Flags = list[i].m_Flags; MultiTileEntry e = allTiles[i]; if (i == 0 || e.m_Flags != 0) { if (e.m_OffsetX < m_Min.m_X) { m_Min.m_X = e.m_OffsetX; } if (e.m_OffsetY < m_Min.m_Y) { m_Min.m_Y = e.m_OffsetY; } if (e.m_OffsetX > m_Max.m_X) { m_Max.m_X = e.m_OffsetX; } if (e.m_OffsetY > m_Max.m_Y) { m_Max.m_Y = e.m_OffsetY; } } } m_Center = new Point2D(-m_Min.m_X, -m_Min.m_Y); m_Width = m_Max.m_X - m_Min.m_X + 1; m_Height = m_Max.m_Y - m_Min.m_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.m_X; int yOffset = allTiles[i].m_OffsetY + m_Center.m_Y; int itemID = (allTiles[i].m_ItemID & TileData.MaxItemValue) | 0x10000; tiles[xOffset][yOffset].Add((ushort)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(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.m_X; int yOffset = allTiles[i].m_OffsetY + m_Center.m_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(); } } }
// END ALAN MOD 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(); /* * // BEGIN ALAN PARSING OUT STUFF (THIS IS TEMPORARY) ================================================== * if (allTiles[i].m_Flags == 0) // invisible * { * int[,] transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; // transformation matrix * * //Console.WriteLine(allTiles[i].m_ItemID + "\t" + allTiles[i].m_OffsetX + "\t" + allTiles[i].m_OffsetY + "\t" + allTiles[i].m_OffsetZ + "\t" + allTiles[i].m_Flags); * int baseMultiID = 0; // this is the "base" multi (northern undamaged boat) used to rotate from in order to connect the pieces * int damageLevel = 0; * int direction = 0; * if (MultiData.currentMultiID == 24) // orc north BASE * { * if (!MultiEntries.ContainsKey(24)) MultiEntries.Add(24, new MultiEntry(24)); * baseMultiID = 24; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 0; direction = 0; * } * else if (MultiData.currentMultiID == 25) // orc east * { * baseMultiID = 24; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 0; direction = 1; * } * else if (MultiData.currentMultiID == 26) // orc south * { * baseMultiID = 24; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 0; direction =2 ; * } * else if (MultiData.currentMultiID == 27) // orc west * { * baseMultiID = 24; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 0; direction = 3; * } * else if (MultiData.currentMultiID == 28) // orc north damaged 1 * { * baseMultiID = 24; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 1; direction = 0; * } * else if (MultiData.currentMultiID == 29) // orc east damaged 1 * { * baseMultiID = 24; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 1; direction = 1; * } * else if (MultiData.currentMultiID == 30) // orc south damaged 1 * { * baseMultiID = 24; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 1; direction = 2; * } * else if (MultiData.currentMultiID == 31) // orc west damaged 1 * { * baseMultiID = 24; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 1; direction = 3; * } * else if (MultiData.currentMultiID == 32) // orc north damaged 2 * { * baseMultiID = 24; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 2; direction = 0; * } * else if (MultiData.currentMultiID == 33) // orc east damaged 2 * { * baseMultiID = 24; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 2; direction = 1; * } * else if (MultiData.currentMultiID == 34) // orc south damaged 2 * { * baseMultiID = 24; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 2; direction = 2; * } * else if (MultiData.currentMultiID == 35) // orc west damaged 2 * { * baseMultiID = 24; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 2; direction = 3; * } * * * * * * * else if (MultiData.currentMultiID == 36) // gargoyle north BASE * { * if (!MultiEntries.ContainsKey(36)) MultiEntries.Add(36, new MultiEntry(36)); * baseMultiID = 36; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 0; direction = 0; * } * else if (MultiData.currentMultiID == 37) // gargoyle east * { * baseMultiID = 36; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 0; direction = 1; * } * else if (MultiData.currentMultiID == 38) // gargoyle south * { * baseMultiID = 36; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 0; direction = 2; * } * else if (MultiData.currentMultiID == 39) // gargoyle west * { * baseMultiID = 36; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 0; direction = 3; * } * else if (MultiData.currentMultiID == 40) // gargoyle north damaged 1 * { * baseMultiID = 36; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 1; direction = 0; * } * else if (MultiData.currentMultiID == 41) // gargoyle east damaged 1 * { * baseMultiID = 36; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 1; direction = 1; * } * else if (MultiData.currentMultiID == 42) // gargoyle south damaged 1 * { * baseMultiID = 36; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 1; direction = 2; * } * else if (MultiData.currentMultiID == 43) // gargoyle west damaged 1 * { * baseMultiID = 36; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 1; direction = 3; * } * else if (MultiData.currentMultiID == 44) // gargoyle north damaged 2 * { * baseMultiID = 36; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 2; direction = 0; * } * else if (MultiData.currentMultiID == 45) // gargoyle east damaged 2 * { * baseMultiID = 36; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 2; direction = 1; * } * else if (MultiData.currentMultiID == 46) // gargoyle south damaged 2 * { * baseMultiID = 36; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 2; direction = 2; * } * else if (MultiData.currentMultiID == 47) // gargoyle west damaged 2 * { * baseMultiID = 36; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 2; direction = 3; * } * * * * * else if (MultiData.currentMultiID == 48) // tokuno north BASE * { * if (!MultiEntries.ContainsKey(48)) MultiEntries.Add(48, new MultiEntry(48)); * baseMultiID = 48; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 0; direction = 0; * } * else if (MultiData.currentMultiID == 49) // tokuno east * { * baseMultiID = 48; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 0; direction = 1; * } * else if (MultiData.currentMultiID == 50) // tokuno south * { * baseMultiID = 48; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 0; direction = 2; * } * else if (MultiData.currentMultiID == 51) // tokuno west * { * baseMultiID = 48; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 0; direction = 3; * } * else if (MultiData.currentMultiID == 52) // tokuno north damaged 1 * { * baseMultiID = 48; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 1; direction = 0; * } * else if (MultiData.currentMultiID == 53) // tokuno east damaged 1 * { * baseMultiID = 48; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 1; direction = 1; * } * else if (MultiData.currentMultiID == 54) // tokuno south damaged 1 * { * baseMultiID = 48; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 1; direction = 2; * } * else if (MultiData.currentMultiID == 55) // tokuno west damaged 1 * { * baseMultiID = 48; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 1; direction = 3; * } * else if (MultiData.currentMultiID == 56) // tokuno north damaged 2 * { * baseMultiID = 48; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 2; direction = 0; * } * else if (MultiData.currentMultiID == 57) // tokuno east damaged 2 * { * baseMultiID = 48; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 2; direction = 1; * } * else if (MultiData.currentMultiID == 58) // tokuno south damaged 2 * { * baseMultiID = 48; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 2; direction = 2; * } * else if (MultiData.currentMultiID == 59) // tokuno west damaged 2 * { * baseMultiID = 48; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 2; direction = 3; * } * * * * if (MultiEntries.ContainsKey(baseMultiID)) * { * MultiEntry entry = MultiEntries[baseMultiID]; * entry.AddMultiEntryComponent(damageLevel, direction, allTiles[i].m_ItemID, new Point3D(allTiles[i].m_OffsetX, allTiles[i].m_OffsetY, allTiles[i].m_OffsetZ), transformation); * } * else * { * Console.WriteLine("MultiEntries did not yet contain key " + baseMultiID); * } * } * * // END ALAN PARSING OUT STUFF =================================================================== */ if (_PostHSFormat) { reader.ReadInt32(); // ?? } MultiTileEntry e = allTiles[i]; if (i == 0 || e.m_Flags != 0) { if (e.m_OffsetX < m_Min.m_X) { m_Min.m_X = e.m_OffsetX; } if (e.m_OffsetY < m_Min.m_Y) { m_Min.m_Y = e.m_OffsetY; } if (e.m_OffsetX > m_Max.m_X) { m_Max.m_X = e.m_OffsetX; } if (e.m_OffsetY > m_Max.m_Y) { m_Max.m_Y = e.m_OffsetY; } } } m_Center = new Point2D(-m_Min.m_X, -m_Min.m_Y); m_Width = (m_Max.m_X - m_Min.m_X) + 1; m_Height = (m_Max.m_Y - m_Min.m_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.m_X; int yOffset = allTiles[i].m_OffsetY + m_Center.m_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.m_X ) m_Min.m_X = e.m_OffsetX; if ( e.m_OffsetY < m_Min.m_Y ) m_Min.m_Y = e.m_OffsetY; if ( e.m_OffsetX > m_Max.m_X ) m_Max.m_X = e.m_OffsetX; if ( e.m_OffsetY > m_Max.m_Y ) m_Max.m_Y = e.m_OffsetY; } } m_Center = new Point2D( -m_Min.m_X, -m_Min.m_Y ); m_Width = (m_Max.m_X - m_Min.m_X) + 1; m_Height = (m_Max.m_Y - m_Min.m_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.m_X; int yOffset = allTiles[i].m_OffsetY + m_Center.m_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(); }
//-------------------------------------------------------------------------- // Is this an invalid tile which also blocks vix? //-------------------------------------------------------------------------- public bool IsVizBlockingInvalidLand( LandTile landTile, StaticTile[] staticTiles, int x, int y ) { if( IsInvalidLandTile( landTile ) ) { if( staticTiles.Length == 0 ) { if( !ContainsVisibleItem( x, y ) ) { return true; } } } return false; }
public void RemoveXYZH( int x, int y, int z, int minHeight ) { int vx = x + m_Center.m_X; int vy = y + m_Center.m_Y; if ( vx >= 0 && vx < m_Width && vy >= 0 && vy < m_Height ) { StaticTile[] oldTiles = m_Tiles[vx][vy]; for ( int i = 0; i < oldTiles.Length; ++i ) { StaticTile tile = oldTiles[i]; if ( tile.Z == z && tile.Height >= minHeight ) { StaticTile[] newTiles = new StaticTile[oldTiles.Length - 1]; for ( int j = 0; j < i; ++j ) newTiles[j] = oldTiles[j]; for ( int j = i + 1; j < oldTiles.Length; ++j ) newTiles[j - 1] = oldTiles[j]; m_Tiles[vx][vy] = newTiles; break; } } MultiTileEntry[] oldList = m_List; for ( int i = 0; i < oldList.Length; ++i ) { MultiTileEntry tile = oldList[i]; if ( tile.m_OffsetX == (short)x && tile.m_OffsetY == (short)y && tile.m_OffsetZ == (short)z && TileData.ItemTable[tile.m_ItemID & TileData.MaxItemValue].Height >= minHeight ) { MultiTileEntry[] newList = new MultiTileEntry[oldList.Length - 1]; for ( int j = 0; j < i; ++j ) newList[j] = oldList[j]; for ( int j = i + 1; j < oldList.Length; ++j ) newList[j - 1] = oldList[j]; m_List = newList; break; } } } }
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; } } } }
public static void Delete(Rectangle2D region) { for (int rx = 0; rx < region.Width; ++rx) { for (int ry = 0; ry < region.Height; ++ry) { int vx = rx + region.X; int vy = ry + region.Y; StaticTile[] tiles = m_Map.Tiles.GetStaticTiles(vx, vy); for (int i = 0; i < tiles.Length; ++i) { StaticTile tile = tiles[i]; int id = tile.ID; int z = tile.Z; if (IsWestFrame(id)) { if (IsEastFrame(vx + 2, vy, z)) { DeleteDoor(vx + 1, vy, z); } else if (IsEastFrame(vx + 3, vy, z)) { /*BaseDoor first = */ DeleteDoor(vx + 1, vy, z); /*BaseDoor second = */ DeleteDoor(vx + 2, vy, z); /*if (first != null && second != null) * { * first.Link = second; * second.Link = first; * } * else * { * if (first != null) * first.Delete(); * if (second != null) * second.Delete(); * }*/ } } else if (IsNorthFrame(id)) { if (IsSouthFrame(vx, vy + 2, z)) { DeleteDoor(vx, vy + 1, z); } else if (IsSouthFrame(vx, vy + 3, z)) { /*BaseDoor first = */ DeleteDoor(vx, vy + 1, z); /*BaseDoor second = */ DeleteDoor(vx, vy + 2, z); /*if (first != null && second != null) * { * first.Link = second; * second.Link = first; * } * else * { * if (first != null) * first.Delete(); * if (second != null) * second.Delete(); * }*/ } } } } } }
public MultiComponentList(List <MultiTileEntry> list) { var allTiles = List = new MultiTileEntry[list.Count]; for (var i = 0; i < list.Count; ++i) { allTiles[i].ItemId = list[i].ItemId; allTiles[i].OffsetX = list[i].OffsetX; allTiles[i].OffsetY = list[i].OffsetY; allTiles[i].OffsetZ = list[i].OffsetZ; allTiles[i].Flags = list[i].Flags; var e = allTiles[i]; if (i == 0 || e.Flags != 0) { if (e.OffsetX < m_Min.m_X) { m_Min.m_X = e.OffsetX; } if (e.OffsetY < m_Min.m_Y) { m_Min.m_Y = e.OffsetY; } if (e.OffsetX > m_Max.m_X) { m_Max.m_X = e.OffsetX; } if (e.OffsetY > m_Max.m_Y) { m_Max.m_Y = e.OffsetY; } } } Center = new Point2D(-m_Min.m_X, -m_Min.m_Y); Width = m_Max.m_X - m_Min.m_X + 1; Height = m_Max.m_Y - m_Min.m_Y + 1; var tiles = new TileList[Width][]; Tiles = new StaticTile[Width][][]; for (var x = 0; x < Width; ++x) { tiles[x] = new TileList[Height]; Tiles[x] = new StaticTile[Height][]; for (var y = 0; y < Height; ++y) { tiles[x][y] = new TileList(); } } for (var i = 0; i < allTiles.Length; ++i) { if (i == 0 || allTiles[i].Flags != 0) { var xOffset = allTiles[i].OffsetX + Center.m_X; var yOffset = allTiles[i].OffsetY + Center.m_Y; var itemID = (allTiles[i].ItemId & TileData.MaxItemValue) | 0x10000; tiles[xOffset][yOffset].Add((ushort)itemID, (sbyte)allTiles[i].OffsetZ); } } for (var x = 0; x < Width; ++x) { for (var y = 0; y < Height; ++y) { Tiles[x][y] = tiles[x][y].ToArray(); } } }
//-------------------------------------------------------------------------- // Does a tile block my vision? //-------------------------------------------------------------------------- public bool TileBlocksVis( StaticTile tile, int eyelevel, int x, int y, Point3D beholder ) { ItemData data = TileData.ItemTable[tile.ID & 0x3FFF]; int height = data.CalcHeight; int windowRange = LOS.Config.GetInstance().WindowRange; //---------------------------------------------------------------------- // tiles starting higher than eyelevel don't block LOS //---------------------------------------------------------------------- if( tile.Z > eyelevel ) return false; //---------------------------------------------------------------------- // whitelisted tils dont block vis //---------------------------------------------------------------------- if( Config.GetInstance().WhiteListed( tile.ID ) ) return false; //---------------------------------------------------------------------- // Windows //---------------------------------------------------------------------- if ( // Some tiles are windows but not flagged properly; we can tell by the name ( data.Flags & TileFlag.Window ) != 0 || data.Name == "window" ) { if( windowRange > 0 ) { if( Utility.InRange( new Point3D( x, y, 0 ), beholder, windowRange ) ) return false; else return true; } else return false; } //---------------------------------------------------------------------- // Trees //---------------------------------------------------------------------- if( Config.GetInstance().Tree( tile.ID )) { int treeRange = LOS.Config.GetInstance().TreeRange; if( treeRange > 0 ) { if( Utility.InRange( new Point3D( x, y, 0), beholder, treeRange ) ) return false; else return true; } else return false; } //---------------------------------------------------------------------- // Walls //---------------------------------------------------------------------- bool tallEnough = tile.Z + height >= eyelevel; if( ( data.Flags & TileFlag.Wall ) != 0 ) { //------------------------------------------------------------------ // high walls: walls that block LOS regardless of player Z //------------------------------------------------------------------ if( Config.GetInstance().HighWalls ) { // solid-wall if( ( data.Flags & TileFlag.NoShoot ) != 0 ) { if( Utility.InRange( new Point3D( x, y, 0), beholder, Config.GetInstance().EdgeRange ) ) { if( tallEnough ) return true; else return false; } return true; } // window-wall else { if( !tallEnough ) return false; // window walls never infinitely high if( windowRange > 0 ) { if( Utility.InRange( new Point3D( x, y, 0 ), beholder, windowRange ) ) return false; else return true; } else return false; } } //------------------------------------------------------------------ // ordinary walls //------------------------------------------------------------------ else { if( !tallEnough ) return false; // solid-wall if( ( data.Flags & TileFlag.NoShoot ) != 0 ) { return true; } // window-wall else { if( windowRange > 0 ) { if( Utility.InRange( new Point3D( x, y, 0 ), beholder, windowRange ) ) return false; else return true; } else return false; } } } //---------------------------------------------------------------------- // Other Physical Obstructions //---------------------------------------------------------------------- if( !tallEnough ) return false; if( ( data.Flags & TileFlag.NoShoot ) != 0 )// is NOT see-thru { return true; } //---------------------------------------------------------------------- // Blacklisted Items //---------------------------------------------------------------------- if( Config.GetInstance().BlackListed( tile.ID )) { return true; } //---------------------------------------------------------------------- // Otherwise, not: //---------------------------------------------------------------------- return false; }
private unsafe int PatchStatics(TileMatrix matrix, string dataPath, string indexPath, string lookupPath) { using var fsData = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read); using var fsIndex = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read); using var fsLookup = new FileStream(lookupPath, FileMode.Open, FileAccess.Read, FileShare.Read); var indexReader = new BinaryReader(fsIndex); var lookupReader = new BinaryReader(fsLookup); var count = (int)(indexReader.BaseStream.Length / 4); var lists = new TileList[8][]; for (var x = 0; x < 8; ++x) { lists[x] = new TileList[8]; for (var y = 0; y < 8; ++y) { lists[x][y] = new TileList(); } } for (var i = 0; i < count; ++i) { var blockID = indexReader.ReadInt32(); var blockX = blockID / matrix.BlockHeight; var blockY = blockID % matrix.BlockHeight; var offset = lookupReader.ReadInt32(); var length = lookupReader.ReadInt32(); lookupReader.ReadInt32(); // Extra if (offset < 0 || length <= 0) { matrix.SetStaticBlock(blockX, blockY, matrix.EmptyStaticBlock); continue; } fsData.Seek(offset, SeekOrigin.Begin); var tileCount = length / 7; if (m_TileBuffer.Length < tileCount) { m_TileBuffer = new StaticTile[tileCount]; } var staTiles = m_TileBuffer; fixed(StaticTile *pTiles = staTiles) { var ptr = fsData.SafeFileHandle?.DangerousGetHandle(); if (ptr == null) { throw new Exception($"Cannot open {fsData.Name}"); } NativeReader.Read(ptr.Value, pTiles, length); StaticTile *pCur = pTiles, pEnd = pTiles + tileCount; while (pCur < pEnd) { lists[pCur->m_X & 0x7][pCur->m_Y & 0x7].Add(pCur->m_ID, pCur->m_Z); pCur += 1; } var tiles = new StaticTile[8][][]; for (var x = 0; x < 8; ++x) { tiles[x] = new StaticTile[8][]; for (var y = 0; y < 8; ++y) { tiles[x][y] = lists[x][y].ToArray(); } } matrix.SetStaticBlock(blockX, blockY, tiles); } } indexReader.Close(); lookupReader.Close(); return(count); }
public static void Freeze(Mobile from, Map targetMap, Point3D start3d, Point3D end3d) { Hashtable mapTable = new Hashtable(); if (start3d == NullP3D && end3d == NullP3D) { if (targetMap == null) { CommandLogging.WriteLine(from, "{0} {1} invoking freeze for every item in every map", from.AccessLevel, CommandLogging.Format(from)); } else { CommandLogging.WriteLine(from, "{0} {1} invoking freeze for every item in {0}", from.AccessLevel, CommandLogging.Format(from), targetMap); } foreach (Item item in World.Items.Values) { if (targetMap != null && item.Map != targetMap) { continue; } if (item.Parent != null) { continue; } if (item is Static || item is BaseFloor || item is BaseWall) { Map itemMap = item.Map; if (itemMap == null || itemMap == Map.Internal) { continue; } Hashtable table = (Hashtable)mapTable[itemMap]; if (table == null) { mapTable[itemMap] = table = new Hashtable(); } Point2D p = new Point2D(item.X >> 3, item.Y >> 3); DeltaState state = (DeltaState)table[p]; if (state == null) { table[p] = state = new DeltaState(p); } state.m_List.Add(item); } } } else if (targetMap != null) { Point2D start = targetMap.Bound(new Point2D(start3d)), end = targetMap.Bound(new Point2D(end3d)); CommandLogging.WriteLine(from, "{0} {1} invoking freeze from {2} to {3} in {4}", from.AccessLevel, CommandLogging.Format(from), start, end, targetMap); IPooledEnumerable eable = targetMap.GetItemsInBounds(new Rectangle2D(start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1)); foreach (Item item in eable) { if (item is Static || item is BaseFloor || item is BaseWall) { Map itemMap = item.Map; if (itemMap == null || itemMap == Map.Internal) { continue; } Hashtable table = (Hashtable)mapTable[itemMap]; if (table == null) { mapTable[itemMap] = table = new Hashtable(); } Point2D p = new Point2D(item.X >> 3, item.Y >> 3); DeltaState state = (DeltaState)table[p]; if (state == null) { table[p] = state = new DeltaState(p); } state.m_List.Add(item); } } eable.Free(); } if (mapTable.Count == 0) { from.SendGump(new NoticeGump(1060637, 30720, "No freezable items were found. Only the following item types are frozen:<br> - Static<br> - BaseFloor<br> - BaseWall", 0xFFC000, 320, 240, null, null)); return; } bool badDataFile = false; int totalFrozen = 0; foreach (DictionaryEntry de in mapTable) { Map map = (Map)de.Key; Hashtable table = (Hashtable)de.Value; TileMatrix matrix = map.Tiles; using (FileStream idxStream = OpenWrite(matrix.IndexStream)) { using (FileStream mulStream = OpenWrite(matrix.DataStream)) { if (idxStream == null || mulStream == null) { badDataFile = true; continue; } BinaryReader idxReader = new BinaryReader(idxStream); BinaryWriter idxWriter = new BinaryWriter(idxStream); BinaryWriter mulWriter = new BinaryWriter(mulStream); foreach (DeltaState state in table.Values) { int oldTileCount; StaticTile[] oldTiles = ReadStaticBlock(idxReader, mulStream, state.m_X, state.m_Y, matrix.BlockWidth, matrix.BlockHeight, out oldTileCount); if (oldTileCount < 0) { continue; } int newTileCount = 0; StaticTile[] newTiles = new StaticTile[state.m_List.Count]; for (int i = 0; i < state.m_List.Count; ++i) { Item item = (Item)state.m_List[i]; int xOffset = item.X - (state.m_X * 8); int yOffset = item.Y - (state.m_Y * 8); if (xOffset < 0 || xOffset >= 8 || yOffset < 0 || yOffset >= 8) { continue; } StaticTile newTile = new StaticTile(); newTile.m_ID = (short)(item.ItemID & 0x3FFF); newTile.m_X = (byte)xOffset; newTile.m_Y = (byte)yOffset; newTile.m_Z = (sbyte)item.Z; newTile.m_Hue = (short)item.Hue; newTiles[newTileCount++] = newTile; item.Delete(); ++totalFrozen; } int mulPos = -1; int length = -1; int extra = 0; if ((oldTileCount + newTileCount) > 0) { mulWriter.Seek(0, SeekOrigin.End); mulPos = (int)mulWriter.BaseStream.Position; length = (oldTileCount + newTileCount) * 7; extra = 1; for (int i = 0; i < oldTileCount; ++i) { StaticTile toWrite = oldTiles[i]; mulWriter.Write((short)toWrite.m_ID); mulWriter.Write((byte)toWrite.m_X); mulWriter.Write((byte)toWrite.m_Y); mulWriter.Write((sbyte)toWrite.m_Z); mulWriter.Write((short)toWrite.m_Hue); } for (int i = 0; i < newTileCount; ++i) { StaticTile toWrite = newTiles[i]; mulWriter.Write((short)toWrite.m_ID); mulWriter.Write((byte)toWrite.m_X); mulWriter.Write((byte)toWrite.m_Y); mulWriter.Write((sbyte)toWrite.m_Z); mulWriter.Write((short)toWrite.m_Hue); } mulWriter.Flush(); } int idxPos = ((state.m_X * matrix.BlockHeight) + state.m_Y) * 12; idxWriter.Seek(idxPos, SeekOrigin.Begin); idxWriter.Write(mulPos); idxWriter.Write(length); idxWriter.Write(extra); idxWriter.Flush(); matrix.SetStaticBlock(state.m_X, state.m_Y, null); } } } } if (totalFrozen == 0 && badDataFile) { from.SendGump(new NoticeGump(1060637, 30720, "Output data files could not be opened and the freeze operation has been aborted.<br><br>This probably means your server and client are using the same data files. Instructions on how to resolve this can be found in the first warning window.", 0xFFC000, 320, 240, null, null)); } else { from.SendGump(new NoticeGump(1060637, 30720, String.Format("Freeze operation completed successfully.<br><br>{0} item{1} frozen.<br><br>You must restart your client and update it's data files to see the changes.", totalFrozen, totalFrozen != 1 ? "s were" : " was"), 0xFFC000, 320, 240, null, null)); } }
private static void DoUnfreeze(Map map, Point2D start, Point2D end, ref bool badDataFile, ref int totalUnfrozen) { start = map.Bound(start); end = map.Bound(end); int xStartBlock = start.X >> 3; int yStartBlock = start.Y >> 3; int xEndBlock = end.X >> 3; int yEndBlock = end.Y >> 3; int xTileStart = start.X, yTileStart = start.Y; int xTileWidth = end.X - start.X + 1, yTileHeight = end.Y - start.Y + 1; TileMatrix matrix = map.Tiles; using (FileStream idxStream = OpenWrite(matrix.IndexStream)) { using (FileStream mulStream = OpenWrite(matrix.DataStream)) { if (idxStream == null || mulStream == null) { badDataFile = true; return; } BinaryReader idxReader = new BinaryReader(idxStream); BinaryWriter idxWriter = new BinaryWriter(idxStream); BinaryWriter mulWriter = new BinaryWriter(mulStream); for (int x = xStartBlock; x <= xEndBlock; ++x) { for (int y = yStartBlock; y <= yEndBlock; ++y) { int oldTileCount; StaticTile[] oldTiles = ReadStaticBlock(idxReader, mulStream, x, y, matrix.BlockWidth, matrix.BlockHeight, out oldTileCount); if (oldTileCount < 0) { continue; } int newTileCount = 0; StaticTile[] newTiles = new StaticTile[oldTileCount]; int baseX = (x << 3) - xTileStart, baseY = (y << 3) - yTileStart; for (int i = 0; i < oldTileCount; ++i) { StaticTile oldTile = oldTiles[i]; int px = baseX + oldTile.m_X; int py = baseY + oldTile.m_Y; if (px < 0 || px >= xTileWidth || py < 0 || py >= yTileHeight) { newTiles[newTileCount++] = oldTile; } else { ++totalUnfrozen; Item item = new Static(oldTile.m_ID & 0x3FFF); item.Hue = oldTile.m_Hue; item.MoveToWorld(new Point3D(px + xTileStart, py + yTileStart, oldTile.m_Z), map); } } int mulPos = -1; int length = -1; int extra = 0; if (newTileCount > 0) { mulWriter.Seek(0, SeekOrigin.End); mulPos = (int)mulWriter.BaseStream.Position; length = newTileCount * 7; extra = 1; for (int i = 0; i < newTileCount; ++i) { StaticTile toWrite = newTiles[i]; mulWriter.Write((short)toWrite.m_ID); mulWriter.Write((byte)toWrite.m_X); mulWriter.Write((byte)toWrite.m_Y); mulWriter.Write((sbyte)toWrite.m_Z); mulWriter.Write((short)toWrite.m_Hue); } mulWriter.Flush(); } int idxPos = ((x * matrix.BlockHeight) + y) * 12; idxWriter.Seek(idxPos, SeekOrigin.Begin); idxWriter.Write(mulPos); idxWriter.Write(length); idxWriter.Write(extra); idxWriter.Flush(); matrix.SetStaticBlock(x, y, null); } } } } }
private static void DoUnfreeze( Map map, Point2D start, Point2D end, ref bool badDataFile, ref int totalUnfrozen ) { start = map.Bound( start ); end = map.Bound( end ); int xStartBlock = start.X >> 3; int yStartBlock = start.Y >> 3; int xEndBlock = end.X >> 3; int yEndBlock = end.Y >> 3; int xTileStart = start.X, yTileStart = start.Y; int xTileWidth = end.X - start.X + 1, yTileHeight = end.Y - start.Y + 1; TileMatrix matrix = map.Tiles; using ( FileStream idxStream = OpenWrite( matrix.IndexStream ) ) { using ( FileStream mulStream = OpenWrite( matrix.DataStream ) ) { if ( idxStream == null || mulStream == null ) { badDataFile = true; return; } BinaryReader idxReader = new BinaryReader( idxStream ); BinaryWriter idxWriter = new BinaryWriter( idxStream ); BinaryWriter mulWriter = new BinaryWriter( mulStream ); for ( int x = xStartBlock; x <= xEndBlock; ++x ) { for ( int y = yStartBlock; y <= yEndBlock; ++y ) { int oldTileCount; StaticTile[] oldTiles = ReadStaticBlock( idxReader, mulStream, x, y, matrix.BlockWidth, matrix.BlockHeight, out oldTileCount ); if ( oldTileCount < 0 ) continue; int newTileCount = 0; StaticTile[] newTiles = new StaticTile[oldTileCount]; int baseX = (x << 3) - xTileStart, baseY = (y << 3) - yTileStart; for ( int i = 0; i < oldTileCount; ++i ) { StaticTile oldTile = oldTiles[i]; int px = baseX + oldTile.m_X; int py = baseY + oldTile.m_Y; if ( px < 0 || px >= xTileWidth || py < 0 || py >= yTileHeight ) { newTiles[newTileCount++] = oldTile; } else { ++totalUnfrozen; Item item = new Static( oldTile.m_ID & 0x3FFF ); item.Hue = oldTile.m_Hue; item.MoveToWorld( new Point3D( px + xTileStart, py + yTileStart, oldTile.m_Z ), map ); } } int mulPos = -1; int length = -1; int extra = 0; if ( newTileCount > 0 ) { mulWriter.Seek( 0, SeekOrigin.End ); mulPos = (int)mulWriter.BaseStream.Position; length = newTileCount * 7; extra = 1; for ( int i = 0; i < newTileCount; ++i ) { StaticTile toWrite = newTiles[i]; mulWriter.Write( (short) toWrite.m_ID ); mulWriter.Write( (byte) toWrite.m_X ); mulWriter.Write( (byte) toWrite.m_Y ); mulWriter.Write( (sbyte) toWrite.m_Z ); mulWriter.Write( (short) toWrite.m_Hue ); } mulWriter.Flush(); } int idxPos = ((x * matrix.BlockHeight) + y) * 12; idxWriter.Seek( idxPos, SeekOrigin.Begin ); idxWriter.Write( mulPos ); idxWriter.Write( length ); idxWriter.Write( extra ); idxWriter.Flush(); matrix.SetStaticBlock( x, y, null ); } } } } }
public static void Generate(Rectangle2D region) { for (int rx = 0; rx < region.Width; ++rx) { for (int ry = 0; ry < region.Height; ++ry) { int vx = rx + region.X; int vy = ry + region.Y; StaticTile[] tiles = m_Map.Tiles.GetStaticTiles(vx, vy); for (int i = 0; i < tiles.Length; ++i) { StaticTile tile = tiles[i]; int id = tile.ID; int z = tile.Z; if (IsWestFrame(id)) { if (IsEastFrame(vx + 2, vy, z)) { AddDoor(vx + 1, vy, z, DoorFacing.WestCW); } else if (IsEastFrame(vx + 3, vy, z)) { BaseDoor first = AddDoor(vx + 1, vy, z, DoorFacing.WestCW); BaseDoor second = AddDoor(vx + 2, vy, z, DoorFacing.EastCCW); if (first != null && second != null) { first.Link = second; second.Link = first; } else { first?.Delete(); second?.Delete(); } } } else if (IsNorthFrame(id)) { if (IsSouthFrame(vx, vy + 2, z)) { AddDoor(vx, vy + 1, z, DoorFacing.SouthCW); } else if (IsSouthFrame(vx, vy + 3, z)) { BaseDoor first = AddDoor(vx, vy + 1, z, DoorFacing.NorthCCW); BaseDoor second = AddDoor(vx, vy + 2, z, DoorFacing.SouthCW); if (first != null && second != null) { first.Link = second; second.Link = first; } else { first?.Delete(); second?.Delete(); } } } } } } }
private static void ProcessDisplayCase( Map map, StaticTile[] tiles, int x, int y ) { ShopFlags flags = ShopFlags.None; for ( int i = 0; i < tiles.Length; ++i ) flags |= ProcessDisplayedItem( tiles[i].ID ); if ( flags != ShopFlags.None ) { Point2D p = new Point2D( x, y ); ShopInfo si = (ShopInfo)m_ShopTable[p]; if ( si == null ) { ArrayList floor = new ArrayList(); RecurseFindFloor( map, x, y, floor ); if ( floor.Count == 0 ) return; si = new ShopInfo(); si.m_Flags = flags; si.m_Floor = floor; m_ShopList.Add( si ); for ( int i = 0; i < floor.Count; ++i ) m_ShopTable[(Point2D)floor[i]] = si; } else { si.m_Flags |= flags; } } }
// END ALAN MOD 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(); /* // BEGIN ALAN PARSING OUT STUFF (THIS IS TEMPORARY) ================================================== if (allTiles[i].m_Flags == 0) // invisible { int[,] transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; // transformation matrix //Console.WriteLine(allTiles[i].m_ItemID + "\t" + allTiles[i].m_OffsetX + "\t" + allTiles[i].m_OffsetY + "\t" + allTiles[i].m_OffsetZ + "\t" + allTiles[i].m_Flags); int baseMultiID = 0; // this is the "base" multi (northern undamaged boat) used to rotate from in order to connect the pieces int damageLevel = 0; int direction = 0; if (MultiData.currentMultiID == 24) // orc north BASE { if (!MultiEntries.ContainsKey(24)) MultiEntries.Add(24, new MultiEntry(24)); baseMultiID = 24; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 0; direction = 0; } else if (MultiData.currentMultiID == 25) // orc east { baseMultiID = 24; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 0; direction = 1; } else if (MultiData.currentMultiID == 26) // orc south { baseMultiID = 24; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 0; direction =2 ; } else if (MultiData.currentMultiID == 27) // orc west { baseMultiID = 24; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 0; direction = 3; } else if (MultiData.currentMultiID == 28) // orc north damaged 1 { baseMultiID = 24; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 1; direction = 0; } else if (MultiData.currentMultiID == 29) // orc east damaged 1 { baseMultiID = 24; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 1; direction = 1; } else if (MultiData.currentMultiID == 30) // orc south damaged 1 { baseMultiID = 24; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 1; direction = 2; } else if (MultiData.currentMultiID == 31) // orc west damaged 1 { baseMultiID = 24; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 1; direction = 3; } else if (MultiData.currentMultiID == 32) // orc north damaged 2 { baseMultiID = 24; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 2; direction = 0; } else if (MultiData.currentMultiID == 33) // orc east damaged 2 { baseMultiID = 24; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 2; direction = 1; } else if (MultiData.currentMultiID == 34) // orc south damaged 2 { baseMultiID = 24; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 2; direction = 2; } else if (MultiData.currentMultiID == 35) // orc west damaged 2 { baseMultiID = 24; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 2; direction = 3; } else if (MultiData.currentMultiID == 36) // gargoyle north BASE { if (!MultiEntries.ContainsKey(36)) MultiEntries.Add(36, new MultiEntry(36)); baseMultiID = 36; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 0; direction = 0; } else if (MultiData.currentMultiID == 37) // gargoyle east { baseMultiID = 36; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 0; direction = 1; } else if (MultiData.currentMultiID == 38) // gargoyle south { baseMultiID = 36; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 0; direction = 2; } else if (MultiData.currentMultiID == 39) // gargoyle west { baseMultiID = 36; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 0; direction = 3; } else if (MultiData.currentMultiID == 40) // gargoyle north damaged 1 { baseMultiID = 36; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 1; direction = 0; } else if (MultiData.currentMultiID == 41) // gargoyle east damaged 1 { baseMultiID = 36; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 1; direction = 1; } else if (MultiData.currentMultiID == 42) // gargoyle south damaged 1 { baseMultiID = 36; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 1; direction = 2; } else if (MultiData.currentMultiID == 43) // gargoyle west damaged 1 { baseMultiID = 36; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 1; direction = 3; } else if (MultiData.currentMultiID == 44) // gargoyle north damaged 2 { baseMultiID = 36; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 2; direction = 0; } else if (MultiData.currentMultiID == 45) // gargoyle east damaged 2 { baseMultiID = 36; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 2; direction = 1; } else if (MultiData.currentMultiID == 46) // gargoyle south damaged 2 { baseMultiID = 36; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 2; direction = 2; } else if (MultiData.currentMultiID == 47) // gargoyle west damaged 2 { baseMultiID = 36; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 2; direction = 3; } else if (MultiData.currentMultiID == 48) // tokuno north BASE { if (!MultiEntries.ContainsKey(48)) MultiEntries.Add(48, new MultiEntry(48)); baseMultiID = 48; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 0; direction = 0; } else if (MultiData.currentMultiID == 49) // tokuno east { baseMultiID = 48; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 0; direction = 1; } else if (MultiData.currentMultiID == 50) // tokuno south { baseMultiID = 48; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 0; direction = 2; } else if (MultiData.currentMultiID == 51) // tokuno west { baseMultiID = 48; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 0; direction = 3; } else if (MultiData.currentMultiID == 52) // tokuno north damaged 1 { baseMultiID = 48; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 1; direction = 0; } else if (MultiData.currentMultiID == 53) // tokuno east damaged 1 { baseMultiID = 48; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 1; direction = 1; } else if (MultiData.currentMultiID == 54) // tokuno south damaged 1 { baseMultiID = 48; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 1; direction = 2; } else if (MultiData.currentMultiID == 55) // tokuno west damaged 1 { baseMultiID = 48; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 1; direction = 3; } else if (MultiData.currentMultiID == 56) // tokuno north damaged 2 { baseMultiID = 48; transformation = new int[2, 2] { { 1, 0 }, { 0, 1 } }; damageLevel = 2; direction = 0; } else if (MultiData.currentMultiID == 57) // tokuno east damaged 2 { baseMultiID = 48; transformation = new int[2, 2] { { 0, -1 }, { 1, 0 } }; damageLevel = 2; direction = 1; } else if (MultiData.currentMultiID == 58) // tokuno south damaged 2 { baseMultiID = 48; transformation = new int[2, 2] { { -1, 0 }, { 0, -1 } }; damageLevel = 2; direction = 2; } else if (MultiData.currentMultiID == 59) // tokuno west damaged 2 { baseMultiID = 48; transformation = new int[2, 2] { { 0, 1 }, { -1, 0 } }; damageLevel = 2; direction = 3; } if (MultiEntries.ContainsKey(baseMultiID)) { MultiEntry entry = MultiEntries[baseMultiID]; entry.AddMultiEntryComponent(damageLevel, direction, allTiles[i].m_ItemID, new Point3D(allTiles[i].m_OffsetX, allTiles[i].m_OffsetY, allTiles[i].m_OffsetZ), transformation); } else { Console.WriteLine("MultiEntries did not yet contain key " + baseMultiID); } } // END ALAN PARSING OUT STUFF =================================================================== */ if ( _PostHSFormat ) reader.ReadInt32(); // ?? MultiTileEntry e = allTiles[i]; if ( i == 0 || e.m_Flags != 0 ) { if ( e.m_OffsetX < m_Min.m_X ) m_Min.m_X = e.m_OffsetX; if ( e.m_OffsetY < m_Min.m_Y ) m_Min.m_Y = e.m_OffsetY; if ( e.m_OffsetX > m_Max.m_X ) m_Max.m_X = e.m_OffsetX; if ( e.m_OffsetY > m_Max.m_Y ) m_Max.m_Y = e.m_OffsetY; } } m_Center = new Point2D( -m_Min.m_X, -m_Min.m_Y ); m_Width = (m_Max.m_X - m_Min.m_X) + 1; m_Height = (m_Max.m_Y - m_Min.m_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.m_X; int yOffset = allTiles[i].m_OffsetY + m_Center.m_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(); }