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]; } }
private IEnumerable <Tile[]> InternalGetMultiTilesAt(int x, int y) { foreach (BaseMulti multi in GetSector(x, y).Multis) { if (multi != null && !multi.Deleted) { MultiComponentList list = multi.Components; int xOffset = x - (multi.Location.X + list.Min.X); int yOffset = y - (multi.Location.Y + list.Min.Y); if (xOffset >= 0 && xOffset < list.Width && yOffset >= 0 && yOffset < list.Height) { Tile[] tiles = list.Tiles[xOffset][yOffset]; if (tiles.Length > 0) { // TODO: How to avoid this copy? Tile[] copy = new Tile[tiles.Length]; for (int i = 0; i < copy.Length; ++i) { copy[i] = tiles[i]; copy[i].Z += multi.Z; } yield return(copy); } } } } }
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 MultiComponentList(MultiComponentList toCopy) { m_Min = toCopy.m_Min; m_Max = toCopy.m_Max; Center = toCopy.Center; Width = toCopy.Width; Height = toCopy.Height; Tiles = new StaticTile[Width][][]; for (int x = 0; x < Width; ++x) { Tiles[x] = new StaticTile[Height][]; for (int y = 0; y < Height; ++y) { Tiles[x][y] = new StaticTile[toCopy.Tiles[x][y].Length]; for (int i = 0; i < Tiles[x][y].Length; ++i) { Tiles[x][y][i] = toCopy.Tiles[x][y][i]; } } } List = new MultiTileEntry[toCopy.List.Length]; for (int i = 0; i < List.Length; ++i) { List[i] = toCopy.List[i]; } }
public GumpMulti(int x, int y, int hue, MultiComponentList components) { _X = x; _Y = y; _Hue = hue; _Components = components ?? MultiComponentList.Empty; }
public void OnMove(Point3D oldLocation, Item item) { if (this == Map.Internal) { return; } Sector oldSector = GetSector(oldLocation); Sector newSector = GetSector(item.Location); if (oldSector != newSector) { oldSector.OnLeave(item); newSector.OnEnter(item); } if (item is BaseMulti) { BaseMulti m = (BaseMulti)item; MultiComponentList mcl = m.Components; Sector start = GetMultiMinSector(item.Location, mcl); Sector end = GetMultiMaxSector(item.Location, mcl); Sector oldStart = GetMultiMinSector(oldLocation, mcl); Sector oldEnd = GetMultiMaxSector(oldLocation, mcl); if (oldStart != start || oldEnd != end) { RemoveMulti(m, oldStart, oldEnd); AddMulti(m, start, end); } } }
public static Size GetImageSize(this Server.MultiComponentList mcl) { if (mcl == null) { return(Size.Empty); } Point o; Size s; int x1 = 0, y1 = 0, x2 = 0, y2 = 0; foreach (var t in OrderByRender(mcl)) { o = GetImageOffset(t.m_ItemID); s = GetImageSize(t.m_ItemID); o.X += (t.m_OffsetX * TileHalfWxH) - (t.m_OffsetY * TileHalfWxH); o.Y += (t.m_OffsetY * TileHalfWxH) + (t.m_OffsetX * TileHalfWxH); o.Y -= t.m_OffsetZ * 4; x1 = Math.Min(x1, o.X); y1 = Math.Min(y1, o.Y); x2 = Math.Max(x2, o.X + s.Width); y2 = Math.Max(y2, o.Y + s.Height); } return(new Size(Math.Max(0, x2 - x1), Math.Max(0, y2 - y1))); }
static MultiData() { string multiUOPPath = Core.FindDataFile("MultiCollection.uop"); if (File.Exists(multiUOPPath)) { LoadUOP(multiUOPPath); UsingUOPFormat = true; return; } string idxPath = Core.FindDataFile("multi.idx"); string mulPath = Core.FindDataFile("multi.mul"); if (File.Exists(idxPath) && File.Exists(mulPath)) { var idx = new FileStream(idxPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_IndexReader = new BinaryReader(idx); var stream = new FileStream(mulPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_StreamReader = new BinaryReader(stream); string vdPath = Core.FindDataFile("verdata.mul"); if (!File.Exists(vdPath)) { return; } using FileStream fs = new FileStream(vdPath, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReader bin = new BinaryReader(fs); int count = bin.ReadInt32(); for (int i = 0; i < count; ++i) { int file = bin.ReadInt32(); int index = bin.ReadInt32(); int lookup = bin.ReadInt32(); int length = bin.ReadInt32(); bin.ReadInt32(); // extra if (file == 14 && index >= 0 && lookup >= 0 && length > 0) { bin.BaseStream.Seek(lookup, SeekOrigin.Begin); Components[index] = new MultiComponentList(bin, length / 12); bin.BaseStream.Seek(24 + i * 20, SeekOrigin.Begin); } } bin.Close(); } else { Console.WriteLine("Warning: Multi data files not found"); } }
static MultiData() { string idxPath = Core.FindDataFile("Multi.idx"); string mulPath = Core.FindDataFile("Multi.mul"); if (File.Exists(idxPath) && File.Exists(mulPath)) { m_Index = new FileStream(idxPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_IndexReader = new BinaryReader(m_Index); m_Stream = new FileStream(mulPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_StreamReader = new BinaryReader(m_Stream); m_Components = new MultiComponentList[(int)(m_Index.Length / 12)]; string vdPath = Core.FindDataFile("Verdata.mul"); if (File.Exists(vdPath)) { using (FileStream fs = new FileStream(vdPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { BinaryReader bin = new BinaryReader(fs); int count = bin.ReadInt32(); for (int i = 0; i < count; ++i) { int file = bin.ReadInt32(); int index = bin.ReadInt32(); int lookup = bin.ReadInt32(); int length = bin.ReadInt32(); /*int extra = */ bin.ReadInt32(); if (file == 14 && index >= 0 && index < m_Components.Length && lookup >= 0 && length > 0) { bin.BaseStream.Seek(lookup, SeekOrigin.Begin); m_Components[index] = new MultiComponentList(bin, length / 12); bin.BaseStream.Seek(24 + (i * 20), SeekOrigin.Begin); } } bin.Close(); } } } else { log.Warning("Multi data files not found"); m_Components = new MultiComponentList[0]; } }
static MultiData() { var multiUOPPath = Core.FindDataFile("MultiCollection.uop", false); if (File.Exists(multiUOPPath)) { LoadUOP(multiUOPPath); UsingUOPFormat = true; return; } var idxPath = Core.FindDataFile("multi.idx"); var mulPath = Core.FindDataFile("multi.mul"); var idx = new FileStream(idxPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_IndexReader = new BinaryReader(idx); var stream = new FileStream(mulPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_StreamReader = new BinaryReader(stream); var vdPath = Core.FindDataFile("verdata.mul", false); if (!File.Exists(vdPath)) { return; } using var fs = new FileStream(vdPath, FileMode.Open, FileAccess.Read, FileShare.Read); var bin = new BinaryReader(fs); var count = bin.ReadInt32(); for (var i = 0; i < count; ++i) { var file = bin.ReadInt32(); var index = bin.ReadInt32(); var lookup = bin.ReadInt32(); var length = bin.ReadInt32(); bin.ReadInt32(); // extra if (file == 14 && index >= 0 && lookup >= 0 && length > 0) { bin.BaseStream.Seek(lookup, SeekOrigin.Begin); Components[index] = new MultiComponentList(bin, length / 12); bin.BaseStream.Seek(24 + i * 20, SeekOrigin.Begin); } } bin.Close(); }
static MultiData() { string idxPath = Core.FindDataFile("multi.idx"); string mulPath = Core.FindDataFile("multi.mul"); if (File.Exists(idxPath) && File.Exists(mulPath)) { Index = new FileStream(idxPath, FileMode.Open, FileAccess.Read, FileShare.Read); IndexReader = new BinaryReader(Index); Stream = new FileStream(mulPath, FileMode.Open, FileAccess.Read, FileShare.Read); StreamReader = new BinaryReader(Stream); Components = new MultiComponentList[(int)(Index.Length / 12)]; string vdPath = Core.FindDataFile("verdata.mul"); if (File.Exists(vdPath)) { using FileStream fs = new(vdPath, FileMode.Open, FileAccess.Read, FileShare.Read); BinaryReader bin = new BinaryReader(fs); int count = bin.ReadInt32(); for (int i = 0; i < count; ++i) { int file = bin.ReadInt32(); int index = bin.ReadInt32(); int lookup = bin.ReadInt32(); int length = bin.ReadInt32(); _ = bin.ReadInt32(); if (file == 14 && index >= 0 && index < Components.Length && lookup >= 0 && length > 0) { bin.BaseStream.Seek(lookup, SeekOrigin.Begin); Components[index] = new MultiComponentList(bin, length / 12); bin.BaseStream.Seek(24 + (i * 20), SeekOrigin.Begin); } } bin.Close(); } } else { Console.WriteLine("Warning: Multi data files not found"); Components = Array.Empty <MultiComponentList>(); } }
public static void TileAdd(this MultiComponentList mcl, int itemID, Rectangle3D bounds) { for (var z = bounds.Start.Z; z < bounds.End.Z; z++) { for (var x = bounds.Start.X; x < bounds.End.X; x++) { for (var y = bounds.Start.Y; y < bounds.End.Y; y++) { mcl.Add(itemID, x, y, z); } } } }
public void OnLeave( Item item ) { if ( this == Map.Internal ) return; GetSector( item ).OnLeave( item ); if ( item is BaseMulti ) { BaseMulti m = (BaseMulti)item; MultiComponentList mcl = m.Components; Sector start = GetMultiMinSector( item.Location, mcl ); Sector end = GetMultiMaxSector( item.Location, mcl ); RemoveMulti( m, start, end ); } }
public static Wireframe GetWireframe(this MultiComponentList mcl) { if (mcl == null) { return(Wireframe.Empty); } var frame = new Block3D[mcl.List.Length]; frame.SetAll( i => new Block3D( mcl.List[i].m_OffsetX, mcl.List[i].m_OffsetY, mcl.List[i].m_OffsetZ, TileData.ItemTable[mcl.List[i].m_ItemID].CalcHeight + 5)); return(new Wireframe(frame)); }
public static Wireframe GetWireframe(this MultiComponentList mcl) { if (mcl == null) { return(Wireframe.Empty); } var frame = new Block3D[mcl.List.Length]; frame.SetAll( i => { var o = mcl.List[i]; var h = Math.Max(5, TileData.ItemTable[o.m_ItemID].Height); return(new Block3D(o.m_OffsetX, o.m_OffsetY, o.m_OffsetZ, h)); }); return(new Wireframe(frame)); }
public static IEnumerable <MultiTileEntry> OrderByRender(this Server.MultiComponentList mcl) { if (mcl == null) { yield break; } // ReSharper disable RedundantCast foreach (var e in mcl.List // .OrderBy(o => ((o.m_OffsetX * mcl.Height) + o.m_OffsetY) * 2) .ThenBy(zt => zt.m_OffsetZ) .ThenByDescending(zt => ((ulong)zt.m_Flags & (ulong)Server.TileFlag.Surface) != 0) .ThenByDescending(zt => ((ulong)zt.m_Flags & (ulong)Server.TileFlag.Wall) != 0) .ThenBy(zt => ((ulong)zt.m_Flags & (ulong)Server.TileFlag.Roof) != 0) .ThenBy(zt => Server.TileData.ItemTable[zt.m_ItemID].CalcHeight)) { yield return(e); } // ReSharper restore RedundantCast }
public static void EnumerateByRender(this Server.MultiComponentList mcl, Action <Point, MultiTileEntry> action) { if (mcl == null || action == null) { return; } Point o; foreach (var t in mcl.OrderByRender()) { o = GetImageOffset(t.m_ItemID); o.X += (t.m_OffsetX * TileHalfWxH) - (t.m_OffsetY * TileHalfWxH); o.Y += (t.m_OffsetY * TileHalfWxH) + (t.m_OffsetX * TileHalfWxH); o.Y -= t.m_OffsetZ * 4; action(o, t); } }
public static int GetImageWidth(this Server.MultiComponentList mcl) { if (mcl == null) { return(0); } Point o; int x1 = 0, x2 = 0, w; foreach (var t in OrderByRender(mcl)) { o = GetImageOffset(t.m_ItemID); w = GetImageWidth(t.m_ItemID); o.X += (t.m_OffsetX * TileHalfWxH) - (t.m_OffsetY * TileHalfWxH); x1 = Math.Min(x1, o.X); x2 = Math.Max(x2, o.X + w); } return(Math.Max(0, x2 - x1)); }
public static Point GetImageOffset(this Server.MultiComponentList mcl) { if (mcl == null) { return(Point.Empty); } Point o, p = Point.Empty; foreach (var t in OrderByRender(mcl)) { o = GetImageOffset(t.m_ItemID); o.X += (t.m_OffsetX * TileHalfWxH) - (t.m_OffsetY * TileHalfWxH); o.Y += (t.m_OffsetY * TileHalfWxH) + (t.m_OffsetX * TileHalfWxH); o.Y -= t.m_OffsetZ * 4; p.X = Math.Min(p.X, o.X); p.Y = Math.Min(p.Y, o.Y); } return(p); }
public bool MoveNext() { while ( ++m_Index < m_List.Count ) { BaseMulti m = m_List[m_Index]; if ( m != null && !m.Deleted ) { MultiComponentList list = m.Components; int xOffset = m_Location.m_X - ( m.Location.m_X + list.Min.m_X ); int yOffset = m_Location.m_Y - ( m.Location.m_Y + list.Min.m_Y ); if ( xOffset >= 0 && xOffset < list.Width && yOffset >= 0 && yOffset < list.Height ) { StaticTile[] tiles = list.Tiles[xOffset][yOffset]; if ( tiles.Length > 0 ) { // TODO: How to avoid this copy? StaticTile[] copy = new StaticTile[tiles.Length]; for ( int i = 0; i < copy.Length; ++i ) { copy[i] = tiles[i]; copy[i].Z += m.Z; } m_Current = copy; return true; } } } } return false; }
public static int GetImageHeight(this Server.MultiComponentList mcl) { if (mcl == null) { return(0); } Point o; int y1 = 0, y2 = 0, h; foreach (var t in OrderByRender(mcl)) { o = GetImageOffset(t.m_ItemID); h = GetImageHeight(t.m_ItemID); o.Y += (t.m_OffsetY * TileHalfWxH) + (t.m_OffsetX * TileHalfWxH); o.Y -= t.m_OffsetZ * 4; y1 = Math.Min(y1, o.Y); y2 = Math.Max(y2, o.Y + h); } return(Math.Max(0, y2 - y1)); }
static MultiData() { Components = new Dictionary <int, MultiComponentList>(); var multicollectionPath = Core.FindDataFile("MultiCollection.uop"); if (File.Exists(multicollectionPath)) { UOPLoad(multicollectionPath); UsingUOPFormat = true; } else { var idxPath = Core.FindDataFile("multi.idx"); var mulPath = Core.FindDataFile("multi.mul"); if (File.Exists(idxPath) && File.Exists(mulPath)) { var idx = new FileStream(idxPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_IndexReader = new BinaryReader(idx); var stream = new FileStream(mulPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_StreamReader = new BinaryReader(stream); var vdPath = Core.FindDataFile("verdata.mul"); if (File.Exists(vdPath)) { using (var fs = new FileStream(vdPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { var bin = new BinaryReader(fs); var count = bin.ReadInt32(); for (var i = 0; i < count; ++i) { var file = bin.ReadInt32(); var index = bin.ReadInt32(); var lookup = bin.ReadInt32(); var length = bin.ReadInt32(); /*int extra = */ bin.ReadInt32(); if (file == 14 && index >= 0 && lookup >= 0 && length > 0) { bin.BaseStream.Seek(lookup, SeekOrigin.Begin); Components[index] = new MultiComponentList(bin, length / 12); bin.BaseStream.Seek(24 + (i * 20), SeekOrigin.Begin); } } bin.Close(); } } else { Console.WriteLine("Warning: Multi data files not found!"); } } } }
public static void UOPLoad(string path) { var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); var streamReader = new BinaryReader(stream); // Head Information Start if (streamReader.ReadInt32() != 0x0050594D) // Not a UOP Files { return; } if (streamReader.ReadInt32() > 5) // Bad Version { return; } // Multi ID List Array Start var chunkIds = new Dictionary <ulong, int>(); var chunkIds2 = new Dictionary <ulong, int>(); UOPHash.BuildChunkIDs(ref chunkIds, ref chunkIds2); // Multi ID List Array End streamReader.ReadUInt32(); // format timestamp? 0xFD23EC43 var startAddress = streamReader.ReadInt64(); var blockSize = streamReader.ReadInt32(); // files in each block var totalSize = streamReader.ReadInt32(); // Total File Count stream.Seek(startAddress, SeekOrigin.Begin); // Head Information End long nextBlock; do { var blockFileCount = streamReader.ReadInt32(); nextBlock = streamReader.ReadInt64(); var index = 0; do { var offset = streamReader.ReadInt64(); var headerSize = streamReader.ReadInt32(); // header length var compressedSize = streamReader.ReadInt32(); // compressed size var decompressedSize = streamReader.ReadInt32(); // decompressed size var filehash = streamReader.ReadUInt64(); // filename hash (HashLittle2) var datablockhash = streamReader.ReadUInt32(); // data hash (Adler32) var flag = streamReader.ReadInt16(); // compression method (0 = none, 1 = zlib) index++; if (offset == 0 || decompressedSize == 0 || filehash == 0x126D1E99DDEDEE0A) // Exclude housing.bin { continue; } // Multi ID Search Start var chunkID = -1; if (!chunkIds.TryGetValue(filehash, out chunkID)) { if (chunkIds2.TryGetValue(filehash, out var tmpChunkID)) { chunkID = tmpChunkID; } } // Multi ID Search End var positionpoint = stream.Position; // save current position // Decompress Data Start stream.Seek(offset + headerSize, SeekOrigin.Begin); var sourceData = new byte[compressedSize]; if (stream.Read(sourceData, 0, compressedSize) != compressedSize) { continue; } byte[] data; if (flag == 1) { var destData = new byte[decompressedSize]; /*ZLibError error = */ Compression.Compressor.Decompress(destData, ref decompressedSize, sourceData, compressedSize); data = destData; } else { data = sourceData; } // End Decompress Data var tileList = new List <MultiTileEntry>(); using (var fs = new MemoryStream(data)) { using (var reader = new BinaryReader(fs)) { var a = reader.ReadUInt32(); var count = reader.ReadUInt32(); for (uint i = 0; i < count; i++) { var ItemId = reader.ReadUInt16(); var x = reader.ReadInt16(); var y = reader.ReadInt16(); var z = reader.ReadInt16(); var flagint = reader.ReadUInt16(); TileFlag flagg; switch (flagint) { default: case 0: flagg = TileFlag.Background; break; case 1: flagg = TileFlag.None; break; case 257: flagg = TileFlag.Generic; break; } var clilocsCount = reader.ReadUInt32(); if (clilocsCount != 0) { fs.Seek(fs.Position + (clilocsCount * 4), SeekOrigin.Begin); // binary block bypass } tileList.Add(new MultiTileEntry(ItemId, x, y, z, flagg)); } reader.Close(); } } Components[chunkID] = new MultiComponentList(tileList); stream.Seek(positionpoint, SeekOrigin.Begin); // back to position }while (index < blockFileCount); }while (stream.Seek(nextBlock, SeekOrigin.Begin) != 0); chunkIds.Clear(); chunkIds2.Clear(); }
public static void TileAdd(this MultiComponentList mcl, int itemID, Rectangle2D bounds, int z = 0, int d = 1) { TileAdd(mcl, itemID, bounds.ToRectangle3D(z, d)); }
public override void SetInitialState() { m_Current = new DesignState(this, GetEmptyFoundation()); // explicitly unused in StaticHousing m_Design = null; m_Backup = null; //init the other two design states just so they don't crash the base's serilization MultiComponentList y = new MultiComponentList(m_Current.Components); MultiComponentList x = new MultiComponentList(StaticHouseHelper.GetComponents(m_HouseBlueprintID)); //merge x into y. //first, remove all in y for (int i = y.List.Length - 1; i >= 0; i--) { y.Remove(y.List[i].m_ItemID, y.List[i].m_OffsetX, y.List[i].m_OffsetY, y.List[i].m_OffsetZ); } //then add all the ones we want to the list for (int i = 0; i < x.List.Length; ++i) { y.Add(x.List[i].m_ItemID, x.List[i].m_OffsetX, x.List[i].m_OffsetY, x.List[i].m_OffsetZ,true); } m_Current.Components = y; return; }
public virtual void ErectBuilding() { m_Components = EmptyList; }
public static void TileAdd(this MultiComponentList mcl, int itemID, int x, int y, int w, int h, int z = 0, int d = 1) { TileAdd(mcl, itemID, new Rectangle2D(x, y, w, h), z, d); }
public DesignState( DesignState toCopy ) { m_Foundation = toCopy.m_Foundation; m_Components = new MultiComponentList( toCopy.m_Components ); m_Revision = toCopy.m_Revision; m_Fixtures = new MultiTileEntry[toCopy.m_Fixtures.Length]; for ( int i = 0; i < m_Fixtures.Length; ++i ) m_Fixtures[i] = toCopy.m_Fixtures[i]; }
public static bool DeleteStairs( MultiComponentList mcl, int id, int x, int y, int z ) { int ax = x + mcl.Center.X; int ay = y + mcl.Center.Y; if ( ax < 0 || ay < 0 || ax >= mcl.Width || ay >= (mcl.Height - 1) || z < 7 || ((z - 7) % 5) != 0 ) return false; if ( IsStairBlock( id ) ) { Tile[] tiles = mcl.Tiles[ax][ay]; for ( int i = 0; i < tiles.Length; ++i ) { Tile tile = tiles[i]; if ( tile.Z == (z + 5) ) { id = tile.ID; z = tile.Z; if ( !IsStairBlock( id ) ) break; } } } int dir = 0; if ( !IsStair( id, ref dir ) ) return false; int height = ((z - 7) % 20) / 5; int xStart, yStart; int xInc, yInc; switch ( dir ) { default: case 0: // North { xStart = x; yStart = y + height; xInc = 0; yInc = -1; break; } case 1: // West { xStart = x + height; yStart = y; xInc = -1; yInc = 0; break; } case 2: // South { xStart = x; yStart = y - height; xInc = 0; yInc = 1; break; } case 3: // East { xStart = x - height; yStart = y; xInc = 1; yInc = 0; break; } } int zStart = z - (height * 5); for ( int i = 0; i < 4; ++i ) { x = xStart + (i * xInc); y = yStart + (i * yInc); for ( int j = 0; j <= i; ++j ) mcl.RemoveXYZH( x, y, zStart + (j * 5), 5 ); ax = x + mcl.Center.X; ay = y + mcl.Center.Y; if ( ax >= 1 && ax < mcl.Width && ay >= 1 && ay < mcl.Height - 1 ) { Tile[] tiles = mcl.Tiles[ax][ay]; bool hasBaseFloor = false; for ( int j = 0; !hasBaseFloor && j < tiles.Length; ++j ) hasBaseFloor = ( tiles[j].Z == 7 && (tiles[j].ID & 0x3FFF) != 1 ); if ( !hasBaseFloor ) mcl.Add( 0x31F4, x, y, 7 ); } } return true; }
public static Wireframe GetWireframe(this MultiComponentList mcl, IBlock3D offset) { return (new Wireframe( GetWireframe(mcl).Select(box => new Block3D(box.Clone3D(offset.X, offset.Y, offset.Z), box.H + offset.H)))); }
public MultiComponentList GetEmptyFoundation() { // Copy original foundation layout MultiComponentList mcl = new MultiComponentList( MultiData.GetComponents( ItemID ) ); mcl.Resize( mcl.Width, mcl.Height + 1 ); int xCenter = mcl.Center.X; int yCenter = mcl.Center.Y; int y = mcl.Height - 1; ApplyFoundation( m_Type, mcl ); for ( int x = 1; x < mcl.Width; ++x ) mcl.Add( 0x751, x - xCenter, y - yCenter, 0 ); return mcl; }
static MultiData() { m_Components = new Dictionary <int, MultiComponentList>(); string multicollectionPath = Core.FindDataFile("MultiCollection.uop"); if (File.Exists(multicollectionPath)) { UOPLoad(multicollectionPath); UsingUOPFormat = true; } else { string idxPath = Core.FindDataFile("multi.idx"); string mulPath = Core.FindDataFile("multi.mul"); if (File.Exists(idxPath) && File.Exists(mulPath)) { FileStream idx = new FileStream(idxPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_IndexReader = new BinaryReader(idx); FileStream stream = new FileStream(mulPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_StreamReader = new BinaryReader(stream); string vdPath = Core.FindDataFile("verdata.mul"); if (File.Exists(vdPath)) { using (FileStream fs = new FileStream(vdPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { BinaryReader bin = new BinaryReader(fs); int count = bin.ReadInt32(); for (int i = 0; i < count; ++i) { int file = bin.ReadInt32(); int index = bin.ReadInt32(); int lookup = bin.ReadInt32(); int length = bin.ReadInt32(); /*int extra = */ bin.ReadInt32(); if (file == 14 && index >= 0 && lookup >= 0 && length > 0) { bin.BaseStream.Seek(lookup, SeekOrigin.Begin); m_Components[index] = new MultiComponentList(bin, length / 12); bin.BaseStream.Seek(24 + (i * 20), SeekOrigin.Begin); } } bin.Close(); } } else { Console.WriteLine("Warning: verdata.mul not found. This is okay, modern clients have this deprecated."); } } } }
public Sector GetMultiMinSector( Point3D loc, MultiComponentList mcl ) { return GetSector( Bound( new Point2D( loc.m_X + mcl.Min.m_X, loc.m_Y + mcl.Min.m_Y ) ) ); }
public static void LoadUOP(string path) { var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); var streamReader = new BinaryReader(stream); // Head Information Start if (streamReader.ReadInt32() != 0x0050594D) // Not a UOP Files { return; } if (streamReader.ReadInt32() > 5) // Bad Version { return; } // Multi ID List Array Start UOPHash.BuildChunkIDs(out var chunkIds); // Multi ID List Array End streamReader.ReadUInt32(); // format timestamp? 0xFD23EC43 var startAddress = streamReader.ReadInt64(); streamReader.ReadInt32(); streamReader.ReadInt32(); stream.Seek(startAddress, SeekOrigin.Begin); // Head Information End long nextBlock; do { var blockFileCount = streamReader.ReadInt32(); nextBlock = streamReader.ReadInt64(); var index = 0; do { var offset = streamReader.ReadInt64(); var headerSize = streamReader.ReadInt32(); // header length var compressedSize = streamReader.ReadInt32(); // compressed size var decompressedSize = streamReader.ReadInt32(); // decompressed size var filehash = streamReader.ReadUInt64(); // filename hash (HashLittle2) streamReader.ReadUInt32(); var compressionMethod = streamReader.ReadInt16(); // compression method (0 = none, 1 = zlib) index++; if (offset == 0 || decompressedSize == 0 || filehash == 0x126D1E99DDEDEE0A) // Exclude housing.bin { continue; } chunkIds.TryGetValue(filehash, out var chunkID); var position = stream.Position; // save current position stream.Seek(offset + headerSize, SeekOrigin.Begin); Span <byte> sourceData = new byte[compressedSize]; if (stream.Read(sourceData) != compressedSize) { continue; } Span <byte> data; if (compressionMethod == 1) { data = new byte[decompressedSize]; Zlib.Unpack(data, ref decompressedSize, sourceData, compressedSize); } else { data = sourceData; } var tileList = new List <MultiTileEntry>(); // Skip the first 4 bytes var reader = new BufferReader <byte>(data); reader.Advance(4); // ??? reader.TryReadLittleEndian(out uint count); for (uint i = 0; i < count; i++) { reader.TryReadLittleEndian(out ushort itemid); reader.TryReadLittleEndian(out short x); reader.TryReadLittleEndian(out short y); reader.TryReadLittleEndian(out short z); reader.TryReadLittleEndian(out ushort flagValue); var tileFlag = flagValue switch { 1 => TileFlag.None, 257 => TileFlag.Generic, _ => TileFlag.Background // 0 }; reader.TryReadLittleEndian(out uint clilocsCount); reader.Advance(clilocsCount * 4); // bypass binary block tileList.Add(new MultiTileEntry(itemid, x, y, z, tileFlag)); } Components[chunkID] = new MultiComponentList(tileList); stream.Seek(position, SeekOrigin.Begin); // back to position } while (index < blockFileCount); } while (stream.Seek(nextBlock, SeekOrigin.Begin) != 0); }
public static void AddStairsTo( ref MultiComponentList mcl ) { // copy the original.. mcl = new MultiComponentList( mcl ); mcl.Resize( mcl.Width, mcl.Height + 1 ); int xCenter = mcl.Center.X; int yCenter = mcl.Center.Y; int y = mcl.Height - 1; for ( int x = 0; x < mcl.Width; ++x ) mcl.Add( 0x63, x - xCenter, y - yCenter, 0 ); }
public override void Deserialize(GenericReader reader) { m_Components = new MultiComponentList(reader); base.Deserialize(reader); }
public static void ApplyFoundation( FoundationType type, MultiComponentList mcl ) { int east, south, post, corner; GetFoundationGraphics( type, out east, out south, out post, out corner ); int xCenter = mcl.Center.X; int yCenter = mcl.Center.Y; mcl.Add( post, 0 - xCenter, 0 - yCenter, 0 ); mcl.Add( corner, mcl.Width - 1 - xCenter, mcl.Height - 2 - yCenter, 0 ); for ( int x = 1; x < mcl.Width; ++x ) { mcl.Add( south, x - xCenter, 0 - yCenter, 0 ); if ( x < mcl.Width-1 ) mcl.Add( south, x - xCenter, mcl.Height - 2 - yCenter, 0 ); } for ( int y = 1; y < mcl.Height - 1; ++y ) { mcl.Add( east, 0 - xCenter, y - yCenter, 0 ); if ( y < mcl.Height - 2 ) mcl.Add( east, mcl.Width - 1 - xCenter, y - yCenter, 0 ); } }
public static Rectangle2D GetAbsoluteBounds(this MultiComponentList mcl) { return(new Rectangle2D(mcl.Min.X, mcl.Min.Y, mcl.Width, mcl.Height)); }
public bool CheckWall( MultiComponentList mcl, int x, int y ) { x += mcl.Center.X; y += mcl.Center.Y; if ( x >= 0 && x < mcl.Width && y >= 0 && y < mcl.Height ) { Tile[] tiles = mcl.Tiles[x][y]; for ( int i = 0; i < tiles.Length; ++i ) { Tile tile = tiles[i]; if ( tile.Z == 7 && tile.Height == 20 ) return true; } } return false; }
static MultiData() { string idxPath = Core.FindDataFile( "multi.idx" ); string mulPath = Core.FindDataFile( "multi.mul" ); if ( File.Exists( idxPath ) && File.Exists( mulPath ) ) { m_Index = new FileStream( idxPath, FileMode.Open, FileAccess.Read, FileShare.Read ); m_IndexReader = new BinaryReader( m_Index ); m_Stream = new FileStream( mulPath, FileMode.Open, FileAccess.Read, FileShare.Read ); m_StreamReader = new BinaryReader( m_Stream ); m_Components = new MultiComponentList[(int)(m_Index.Length / 12)]; string vdPath = Core.FindDataFile( "verdata.mul" ); if ( File.Exists( vdPath ) ) { using ( FileStream fs = new FileStream( vdPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { BinaryReader bin = new BinaryReader( fs ); int count = bin.ReadInt32(); for ( int i = 0; i < count; ++i ) { int file = bin.ReadInt32(); int index = bin.ReadInt32(); int lookup = bin.ReadInt32(); int length = bin.ReadInt32(); int extra = bin.ReadInt32(); if ( file == 14 && index >= 0 && index < m_Components.Length && lookup >= 0 && length > 0 ) { bin.BaseStream.Seek( lookup, SeekOrigin.Begin ); m_Components[index] = new MultiComponentList( bin, length / 12 ); bin.BaseStream.Seek( 24 + (i * 20), SeekOrigin.Begin ); } } bin.Close(); } } } else { Console.WriteLine( "Warning: Multi data files not found" ); m_Components = new MultiComponentList[0]; } }
public DesignState( HouseFoundation foundation, MultiComponentList components ) { m_Foundation = foundation; m_Components = components; m_Fixtures = new MultiTileEntry[0]; }
/* * public static bool Contains(Point2D p) * { * return Contains(p.m_X, p.m_Y); * } * * public static bool Contains(Point3D p) * { * return Contains(p.m_X, p.m_Y); * } * * public static bool Contains(IPoint3D p) * { * return Contains(p.X, p.Y); * } * * public static bool Contains(int x, int y) * { * MultiComponentList mcl = Components; * * x -= X + mcl.Min.m_X; * y -= Y + mcl.Min.m_Y; * * return x >= 0 && x < mcl.Width && y >= 0 && y < mcl.Height && mcl.Tiles[x][y].Length > 0; * } */ public static bool IsEmpty(this MultiComponentList mcl, int x, int y) { return(x < 0 || x >= mcl.Width || y < 0 || y >= mcl.Height || mcl.Tiles[x][y].Length == 0); }
public DesignState( HouseFoundation foundation, GenericReader reader ) { m_Foundation = foundation; int version = reader.ReadInt(); switch ( version ) { case 0: { m_Components = new MultiComponentList( reader ); int length = reader.ReadInt(); m_Fixtures = new MultiTileEntry[length]; for ( int i = 0; i < length; ++i ) { m_Fixtures[i].m_ItemID = reader.ReadShort(); m_Fixtures[i].m_OffsetX = reader.ReadShort(); m_Fixtures[i].m_OffsetY = reader.ReadShort(); m_Fixtures[i].m_OffsetZ = reader.ReadShort(); m_Fixtures[i].m_Flags = reader.ReadInt(); } m_Revision = reader.ReadInt(); break; } } }
public static bool HasEntry(this MultiComponentList mcl, int itemID, int x, int y) { return(!IsEmpty(mcl, x, y) && mcl.Tiles[x][y].Any(t => t.ID == itemID)); }