public static void DefragStatics(string path, Map map, int width, int height, bool remove) { string indexPath = Files.GetFilePath("staidx{0}.mul", map.FileIndex); FileStream m_Index; BinaryReader m_IndexReader; if (indexPath != null) { m_Index = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_IndexReader = new BinaryReader(m_Index); } else { return; } string staticsPath = Files.GetFilePath("statics{0}.mul", map.FileIndex); FileStream m_Statics; BinaryReader m_StaticsReader; if (staticsPath != null) { m_Statics = new FileStream(staticsPath, FileMode.Open, FileAccess.Read, FileShare.Read); m_StaticsReader = new BinaryReader(m_Statics); } else { return; } int blockx = width >> 3; int blocky = height >> 3; string idx = Path.Combine(path, String.Format("staidx{0}.mul", map.FileIndex)); string mul = Path.Combine(path, String.Format("statics{0}.mul", map.FileIndex)); using ( FileStream fsidx = new FileStream(idx, FileMode.Create, FileAccess.Write, FileShare.Write), fsmul = new FileStream(mul, FileMode.Create, FileAccess.Write, FileShare.Write)) { var memidx = new MemoryStream(); var memmul = new MemoryStream(); using (BinaryWriter binidx = new BinaryWriter(memidx), binmul = new BinaryWriter(memmul)) { for (int x = 0; x < blockx; ++x) { for (int y = 0; y < blocky; ++y) { try { m_IndexReader.BaseStream.Seek(((x * blocky) + y) * 12, SeekOrigin.Begin); int lookup = m_IndexReader.ReadInt32(); int length = m_IndexReader.ReadInt32(); int extra = m_IndexReader.ReadInt32(); if (((lookup < 0 || length <= 0) && (!map.Tiles.PendingStatic(x, y))) || (map.Tiles.IsStaticBlockRemoved(x, y))) { binidx.Write(-1); // lookup binidx.Write(-1); // length binidx.Write(-1); // extra } else { if ((lookup >= 0) && (length > 0)) { m_Statics.Seek(lookup, SeekOrigin.Begin); } var fsmullength = (int)binmul.BaseStream.Position; int count = length / 7; if (!remove) //without duplicate remove { bool firstitem = true; for (int i = 0; i < count; ++i) { ushort graphic = m_StaticsReader.ReadUInt16(); byte sx = m_StaticsReader.ReadByte(); byte sy = m_StaticsReader.ReadByte(); sbyte sz = m_StaticsReader.ReadSByte(); short shue = m_StaticsReader.ReadInt16(); if ((graphic >= 0) && (graphic <= Art.GetMaxItemID())) { if (shue < 0) { shue = 0; } if (firstitem) { binidx.Write((int)binmul.BaseStream.Position); //lookup firstitem = false; } binmul.Write(graphic); binmul.Write(sx); binmul.Write(sy); binmul.Write(sz); binmul.Write(shue); } } StaticTile[] tilelist = map.Tiles.GetPendingStatics(x, y); if (tilelist != null) { for (int i = 0; i < tilelist.Length; ++i) { if ((tilelist[i].m_ID >= 0) && (tilelist[i].m_ID <= Art.GetMaxItemID())) { if (tilelist[i].m_Hue < 0) { tilelist[i].m_Hue = 0; } if (firstitem) { binidx.Write((int)binmul.BaseStream.Position); //lookup firstitem = false; } binmul.Write(tilelist[i].m_ID); binmul.Write(tilelist[i].m_X); binmul.Write(tilelist[i].m_Y); binmul.Write(tilelist[i].m_Z); binmul.Write(tilelist[i].m_Hue); } } } } else //with duplicate remove { var tilelist = new StaticTile[count]; int j = 0; for (int i = 0; i < count; ++i) { var tile = new StaticTile(); tile.m_ID = m_StaticsReader.ReadUInt16(); tile.m_X = m_StaticsReader.ReadByte(); tile.m_Y = m_StaticsReader.ReadByte(); tile.m_Z = m_StaticsReader.ReadSByte(); tile.m_Hue = m_StaticsReader.ReadInt16(); if ((tile.m_ID >= 0) && (tile.m_ID <= Art.GetMaxItemID())) { if (tile.m_Hue < 0) { tile.m_Hue = 0; } bool first = true; for (int k = 0; k < j; ++k) { if ((tilelist[k].m_ID == tile.m_ID) && ((tilelist[k].m_X == tile.m_X) && (tilelist[k].m_Y == tile.m_Y)) && (tilelist[k].m_Z == tile.m_Z) && (tilelist[k].m_Hue == tile.m_Hue)) { first = false; break; } } if (first) { tilelist[j] = tile; j++; } } } if (map.Tiles.PendingStatic(x, y)) { StaticTile[] pending = map.Tiles.GetPendingStatics(x, y); StaticTile[] old = tilelist; tilelist = new StaticTile[old.Length + pending.Length]; old.CopyTo(tilelist, 0); for (int i = 0; i < pending.Length; ++i) { if ((pending[i].m_ID >= 0) && (pending[i].m_ID <= Art.GetMaxItemID())) { if (pending[i].m_Hue < 0) { pending[i].m_Hue = 0; } bool first = true; for (int k = 0; k < j; ++k) { if ((tilelist[k].m_ID == pending[i].m_ID) && ((tilelist[k].m_X == pending[i].m_X) && (tilelist[k].m_Y == pending[i].m_Y)) && (tilelist[k].m_Z == pending[i].m_Z) && (tilelist[k].m_Hue == pending[i].m_Hue)) { first = false; break; } } if (first) { tilelist[j++] = pending[i]; } } } } if (j > 0) { binidx.Write((int)binmul.BaseStream.Position); //lookup for (int i = 0; i < j; ++i) { binmul.Write(tilelist[i].m_ID); binmul.Write(tilelist[i].m_X); binmul.Write(tilelist[i].m_Y); binmul.Write(tilelist[i].m_Z); binmul.Write(tilelist[i].m_Hue); } } } fsmullength = (int)binmul.BaseStream.Position - fsmullength; if (fsmullength > 0) { binidx.Write(fsmullength); //length if (extra == -1) { extra = 0; } binidx.Write(extra); //extra } else { binidx.Write(-1); //lookup binidx.Write(-1); //length binidx.Write(-1); //extra } } } catch // fill the rest { binidx.BaseStream.Seek(((x * blocky) + y) * 12, SeekOrigin.Begin); for (; x < blockx; ++x) { for (; y < blocky; ++y) { binidx.Write(-1); //lookup binidx.Write(-1); //length binidx.Write(-1); //extra } y = 0; } } } } memidx.WriteTo(fsidx); memmul.WriteTo(fsmul); } } m_IndexReader.Close(); m_StaticsReader.Close(); }