public static void Save(string path) { bool isUOAHS = PostHSFormat || Art.IsUOAHS(); string idx = Path.Combine(path, "multi.idx"); string mul = Path.Combine(path, "multi.mul"); using ( FileStream fsidx = new FileStream(idx, FileMode.Create, FileAccess.Write, FileShare.Write), fsmul = new FileStream(mul, FileMode.Create, FileAccess.Write, FileShare.Write)) { using (BinaryWriter binidx = new BinaryWriter(fsidx), binmul = new BinaryWriter(fsmul)) { for (int index = 0; index < 0x2000; ++index) { MultiComponentList comp = GetComponents(index); if (comp == MultiComponentList.Empty) { binidx.Write(-1); // lookup binidx.Write(-1); // length binidx.Write(-1); // extra } else { List <MultiComponentList.MultiTileEntry> tiles = RebuildTiles(comp.SortedTiles); binidx.Write((int)fsmul.Position); //lookup if (isUOAHS) { binidx.Write(tiles.Count * 16); //length } else { binidx.Write(tiles.Count * 12); //length } binidx.Write(-1); //extra for (int i = 0; i < tiles.Count; ++i) { binmul.Write(tiles[i].m_ItemID); binmul.Write(tiles[i].m_OffsetX); binmul.Write(tiles[i].m_OffsetY); binmul.Write(tiles[i].m_OffsetZ); if (isUOAHS) { binmul.Write((ulong)tiles[i].m_Flags); } else { binmul.Write((uint)tiles[i].m_Flags); } } } } } } }
public MultiComponentList(BinaryReader reader, int count) { bool useNewMultiFormat = Multis.PostHSFormat || Art.IsUOAHS(); m_Min = m_Max = Point.Empty; m_SortedTiles = new MultiTileEntry[count]; for (int i = 0; i < count; ++i) { m_SortedTiles[i].m_ItemID = Art.GetLegalItemID(reader.ReadUInt16()); m_SortedTiles[i].m_OffsetX = reader.ReadInt16(); m_SortedTiles[i].m_OffsetY = reader.ReadInt16(); m_SortedTiles[i].m_OffsetZ = reader.ReadInt16(); m_SortedTiles[i].m_Flags = reader.ReadInt32(); if (useNewMultiFormat) { m_SortedTiles[i].m_Unk1 = reader.ReadInt32(); } else { m_SortedTiles[i].m_Unk1 = 0; } MultiTileEntry e = m_SortedTiles[i]; if (e.m_OffsetX < m_Min.X) { m_Min.X = e.m_OffsetX; } if (e.m_OffsetY < m_Min.Y) { m_Min.Y = e.m_OffsetY; } if (e.m_OffsetX > m_Max.X) { m_Max.X = e.m_OffsetX; } if (e.m_OffsetY > m_Max.Y) { m_Max.Y = e.m_OffsetY; } if (e.m_OffsetZ > m_maxHeight) { m_maxHeight = e.m_OffsetZ; } } ConvertList(); reader.Close(); }
public static MultiComponentList Load(int index) { try { int length, extra; bool patched; var stream = m_FileIndex.Seek(index, out length, out extra, out patched); if (stream == null) { return(MultiComponentList.Empty); } if (PostHSFormat || Art.IsUOAHS()) { return(new MultiComponentList(new BinaryReader(stream), length / 16)); } return(new MultiComponentList(new BinaryReader(stream), length / 12)); } catch { return(MultiComponentList.Empty); } }
public unsafe static void Initialize() { string filePath = Files.GetFilePath("tiledata.mul"); if (filePath != null) { using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { bool useNeWTileDataFormat = Art.IsUOAHS(); landheader = new int[512]; int j = 0; m_LandData = new LandData[0x4000]; byte[] buffer = new byte[fs.Length]; GCHandle gc = GCHandle.Alloc(buffer, GCHandleType.Pinned); long currpos = 0; try { fs.Read(buffer, 0, buffer.Length); for (int i = 0; i < 0x4000; i += 32) { IntPtr ptrheader = new IntPtr((long)gc.AddrOfPinnedObject() + currpos); currpos += 4; landheader[j++] = (int)Marshal.PtrToStructure(ptrheader, typeof(int)); for (int count = 0; count < 32; ++count) { IntPtr ptr = new IntPtr((long)gc.AddrOfPinnedObject() + currpos); if (useNeWTileDataFormat) { currpos += sizeof(NewLandTileDataMul); NewLandTileDataMul cur = (NewLandTileDataMul)Marshal.PtrToStructure(ptr, typeof(NewLandTileDataMul)); m_LandData[i + count] = new LandData(cur); } else { currpos += sizeof(OldLandTileDataMul); OldLandTileDataMul cur = (OldLandTileDataMul)Marshal.PtrToStructure(ptr, typeof(OldLandTileDataMul)); m_LandData[i + count] = new LandData(cur); } } } long remaining = buffer.Length - currpos; int structsize = useNeWTileDataFormat ? sizeof(NewItemTileDataMul) : sizeof(OldItemTileDataMul); itemheader = new int[(remaining / ((structsize * 32) + 4))]; int itemlength = itemheader.Length * 32; m_ItemData = new ItemData[itemlength]; m_HeightTable = new int[itemlength]; j = 0; for (int i = 0; i < itemlength; i += 32) { IntPtr ptrheader = new IntPtr((long)gc.AddrOfPinnedObject() + currpos); currpos += 4; itemheader[j++] = (int)Marshal.PtrToStructure(ptrheader, typeof(int)); for (int count = 0; count < 32; ++count) { IntPtr ptr = new IntPtr((long)gc.AddrOfPinnedObject() + currpos); if (useNeWTileDataFormat) { currpos += sizeof(NewItemTileDataMul); NewItemTileDataMul cur = (NewItemTileDataMul)Marshal.PtrToStructure(ptr, typeof(NewItemTileDataMul)); m_ItemData[i + count] = new ItemData(cur); m_HeightTable[i + count] = cur.height; } else { currpos += sizeof(OldItemTileDataMul); OldItemTileDataMul cur = (OldItemTileDataMul)Marshal.PtrToStructure(ptr, typeof(OldItemTileDataMul)); m_ItemData[i + count] = new ItemData(cur); m_HeightTable[i + count] = cur.height; } } } } finally { gc.Free(); } } } }
/// <summary> /// Saves <see cref="LandData"/> and <see cref="ItemData"/> to tiledata.mul /// </summary> /// <param name="FileName"></param> public static void SaveTileData(string FileName) { using (FileStream fs = new FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.Write)) { using (BinaryWriter bin = new BinaryWriter(fs)) { int j = 0; bool useNewTileDataFormat = Art.IsUOAHS(); for (int i = 0; i < 0x4000; ++i) { if ((i & 0x1F) == 0) { bin.Write(landheader[j++]); //header } bin.Write((int)m_LandData[i].Flags); if (useNewTileDataFormat) { bin.Write((int)m_LandData[i].Unk1); } bin.Write(m_LandData[i].TextureID); byte[] b = new byte[20]; if (m_LandData[i].Name != null) { byte[] bb = Encoding.Default.GetBytes(m_LandData[i].Name); if (bb.Length > 20) { Array.Resize(ref bb, 20); } bb.CopyTo(b, 0); } bin.Write(b); } j = 0; for (int i = 0; i < m_ItemData.Length; ++i) { if ((i & 0x1F) == 0) { bin.Write(itemheader[j++]); // header } bin.Write((int)m_ItemData[i].Flags); if (useNewTileDataFormat) { bin.Write((int)m_ItemData[i].Unk1); } bin.Write(m_ItemData[i].Weight); bin.Write(m_ItemData[i].Quality); bin.Write(m_ItemData[i].MiscData); bin.Write(m_ItemData[i].Unk2); bin.Write(m_ItemData[i].Quantity); bin.Write(m_ItemData[i].Animation); bin.Write(m_ItemData[i].Unk3); bin.Write(m_ItemData[i].Hue); bin.Write(m_ItemData[i].StackingOffset); //unk4 bin.Write(m_ItemData[i].Value); //unk5 bin.Write(m_ItemData[i].Height); byte[] b = new byte[20]; if (m_ItemData[i].Name != null) { byte[] bb = Encoding.Default.GetBytes(m_ItemData[i].Name); if (bb.Length > 20) { Array.Resize(ref bb, 20); } bb.CopyTo(b, 0); } bin.Write(b); } } } }