/// <summary> /// The build map from info file. /// </summary> /// <param name="inputFile">The input file.</param> /// <param name="layout">The layout.</param> /// <param name="map">The map.</param> /// <param name="addsounds">The addsounds.</param> /// <remarks></remarks> public void BuildMapFromInfoFile(string inputFile, ref MapLayout layout, Map map, bool addsounds) { ArrayList metas = new ArrayList(0); string[] split = inputFile.Split('.'); if (split[split.Length - 1] == "info") { FileStream FS = new FileStream(inputFile, FileMode.Open); StreamReader SR = new StreamReader(FS); string temps = string.Empty; do { temps = SR.ReadLine(); if (temps == null) { break; } Meta m = new Meta(map); m.LoadMetaFromFile(temps); if (addsounds == false) { if (m.type == "snd!") { continue; } } bool exists = false; for (int x = 0; x < map.IndexHeader.metaCount; x++) { if (map.FileNames.Name[x] == m.name && map.MetaInfo.TagType[x] == m.type) { exists = true; break; } } if (exists == false) { for (int x = 0; x < metas.Count; x++) { if (((Meta)metas[x]).name == m.name && ((Meta)metas[x]).type == m.type) { exists = true; break; } } } if (exists == false) { metas.Add(m); } } while (temps != null); SR.Close(); FS.Close(); } else { Meta m = new Meta(map); m.LoadMetaFromFile(inputFile); bool exists = false; for (int x = 0; x < map.IndexHeader.metaCount; x++) { if (map.FileNames.Name[x] == m.name && map.MetaInfo.TagType[x] == m.type) { exists = true; break; } } if (exists == false) { metas.Add(m); } } MapBuilder(metas, ref layout, map, addsounds); }
/// <summary> /// The scan map for lay out. /// </summary> /// <param name="map">The map.</param> /// <param name="addexternalchunks">The addexternalchunks.</param> /// <returns></returns> /// <remarks></remarks> public MapLayout ScanMapForLayOut(Map map, bool addexternalchunks) { MapLayout layout = new MapLayout(); for (int x = 0; x < map.BSP.sbsp.Length; x++) { LayOutChunk l = new LayOutChunk(0); l.rawType = RawDataContainerType.BSPMeta; l.startoffset = map.BSP.sbsp[x].offset; l.endoffset = map.BSP.sbsp[x].offset + map.BSP.sbsp[x].size; l.size = map.BSP.sbsp[x].size; layout.chunks.Add(l); } LayOutChunk lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Header; lo.startoffset = 0; lo.size = 2048; lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.StringsIndex; lo.startoffset = map.MapHeader.offsetToStringIndex; lo.size = map.MapHeader.scriptReferenceCount * 4; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Strings1; lo.startoffset = map.MapHeader.offsetToStringNames1; lo.size = map.MapHeader.scriptReferenceCount * 128; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Strings2; lo.startoffset = map.MapHeader.offsetToStringNames2; lo.size = map.MapHeader.sizeOfScriptReference; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Crazy; lo.startoffset = map.MapHeader.offsetToCrazy; lo.size = map.MapHeader.sizeOfCrazy; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.FileNamesIndex; lo.startoffset = map.MapHeader.offsetTofileIndex; lo.size = map.MapHeader.fileCount * 4; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); } lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.FileNames; lo.startoffset = map.MapHeader.offsetTofileNames; lo.size = map.MapHeader.fileNamesSize; if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo.size += map.Functions.Padding(lo.size, 512); } lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.MetaIndex; lo.startoffset = map.MapHeader.indexOffset; if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo.size = map.MapHeader.metaStart; lo.size += map.Functions.Padding(lo.size, 512); // map.MapHeader.fileSize - map.MapHeader.indexOffset; } else { lo.size = map.MapHeader.offsetTofileNames - map.MapHeader.indexOffset; // map.MetaInfo.Offset[map.IndexHeader.metaCount - 1] + map.MetaInfo.Size[map.IndexHeader.metaCount-1]; } lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.MetaData; lo.startoffset = map.MetaInfo.Offset[0]; // How can you adjust for padding past the end of the file??? lo.size = map.MapHeader.fileSize - lo.startoffset; if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { int padding = map.Functions.Padding(lo.startoffset + lo.size, 4096); lo.size += padding; } lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { for (int x = 0; x < map.Unicode.ut.Length; x++) { lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.UnicodeNamesIndex; lo.startoffset = map.Unicode.ut[x].indexOffset; lo.size = map.Unicode.ut[x].count * 8; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.UnicodeNames; lo.startoffset = map.Unicode.ut[x].tableOffset; lo.size = map.Unicode.ut[x].tableSize; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); } } map.OpenMap(MapTypes.Internal); for (int x = 0; x < map.IndexHeader.metaCount; x++) { if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { if (map.MetaInfo.TagType[x] == "snd!" | map.MetaInfo.TagType[x] == "ltmp") { continue; } Application.DoEvents(); } Meta m = new Meta(map); m.offset = map.MetaInfo.Offset[x]; // checks if type has raw data m.rawType = map.Functions.ForMeta.CheckForRaw(map.MetaInfo.TagType[x]); if (m.rawType != RawDataContainerType.Empty) { m.raw = map.Functions.ForMeta.ReadRaw(x, true); LayOutChunk l = new LayOutChunk(map.MapHeader.fileSize); int tempint = layout.FindByType(m.rawType); if (tempint == -1) { l = new LayOutChunk(map.MapHeader.fileSize); l.rawType = m.rawType; layout.chunks.Add(l); tempint = layout.FindByType(m.rawType); } else { l = (LayOutChunk)layout.chunks[tempint]; } for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.offset == -1) { continue; } if (r.rawLocation == MapTypes.Internal) { RawInfoChunk tempr = new RawInfoChunk(); tempr.offset = (uint)r.offset; tempr.size = r.size; tempr.rawType = r.rawDataType; tempr.location = r.rawLocation; tempr.offsetOfPointer = m.offset + r.pointerMetaOffset; l.rawPieces.Add(tempr); } else if (addexternalchunks) { RawInfoChunk tempr = new RawInfoChunk(); tempr.offset = (uint)r.offset; tempr.size = r.size; tempr.rawType = r.rawDataType; tempr.location = r.rawLocation; tempr.offsetOfPointer = m.offset + r.pointerMetaOffset; l.rawPieces.Add(tempr); } if (r.offset < l.startoffset && r.rawLocation == MapTypes.Internal) { l.startoffset = r.offset; l.size = l.endoffset - l.startoffset; layout.chunks[tempint] = l; } if (r.offset + r.size > l.endoffset && r.rawLocation == MapTypes.Internal) { l.endoffset = r.offset + r.size; l.endoffset += map.Functions.Padding(l.endoffset, 512); l.size = l.endoffset - l.startoffset; layout.chunks[tempint] = l; } } } m = null; GC.WaitForPendingFinalizers(); // GC.Collect(); } map.CloseMap(); if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo = new LayOutChunk(0); LayOutChunk templo = (LayOutChunk)layout.chunks[layout.FindByType(RawDataContainerType.Model)]; lo.rawType = RawDataContainerType.Sound; lo.startoffset = 2048; lo.size = templo.startoffset - 2048; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); } for (int y = 0; y < layout.chunks.Count; y++) { LayOutChunk l = (LayOutChunk)layout.chunks[y]; if (l.size == 0) { layout.chunks.RemoveAt(y); y--; } } layout.SortChunksByOffset(); layout.SortRawByOffset(); return layout; }
/// <summary> /// The map builder. /// </summary> /// <param name="metas">The metas.</param> /// <param name="layout">The layout.</param> /// <param name="map">The map.</param> /// <param name="addsounds">The addsounds.</param> /// <remarks></remarks> public void MapBuilder(ArrayList metas, ref MapLayout layout, Map map, bool addsounds) { string[] filestofix = new string[0]; if (map.MapHeader.mapType != MapTypes.Internal) { if ( MessageBox.Show( "This map is an external resource and updating it will effect all the other maps. Continue?", string.Empty, MessageBoxButtons.OKCancel) == DialogResult.Cancel) { return; } OpenFileDialog openfiles = new OpenFileDialog(); openfiles.Multiselect = true; openfiles.Filter = "Halo 2 Map (*.map)| *.map"; openfiles.ShowDialog(); filestofix = openfiles.FileNames; } if (addsounds == false) { for (int x = 0; x < metas.Count; x++) { if (((Meta)metas[x]).type == "snd!") { metas.RemoveAt(x); x--; } } } int totalshift = 0; ArrayList strings = new ArrayList(); for (int x = 0; x < metas.Count; x++) { Meta m = (Meta)metas[x]; for (int y = 0; y < m.items.Count; y++) { Meta.Item ii = m.items[y]; if (ii.type == Meta.ItemType.String) { Meta.String iii = (Meta.String)ii; if (Array.IndexOf(map.Strings.Name, iii.name) == -1) { if (strings.IndexOf(iii.name) == -1) { strings.Add(iii.name); } } } } } map.OpenMap(MapTypes.Internal); Meta ughmeta = new Meta(map); ughmeta.ReadMetaFromMap(map.IndexHeader.metaCount - 1, true); IFPIO ifp = IFPHashMap.GetIfp("ugh!", map.HaloVersion); ughmeta.rawType = RawDataContainerType.Empty; ughmeta.headersize = ifp.headerSize; ughmeta.scanner.ScanWithIFP(ref ifp); #region get model info int tempint = layout.FindByType(RawDataContainerType.Model); LayOutChunk loc = (LayOutChunk)layout.chunks[tempint]; #endregion #region sound raw data int sndshift = 0; int sndpermcount = 0; int sndchoicecount = 0; int sndchunk1count = 0; int addedsoundnames = 0; MetaSplitter metasplit = new MetaSplitter(); metasplit.SplitWithIFP(ref ifp, ref ughmeta, map); map.OpenMap(MapTypes.Internal); int soundnameindex = 0; int soundpermutationindex = 0; int soundchoiceindex = 0; int soundchunk1index = 0; for (int x = 0; x < metasplit.Header.Chunks[0].ChunkResources.Count; x++) { if (metasplit.Header.Chunks[0].ChunkResources[x].type == Meta.ItemType.Reflexive) { Meta.Reflexive r = (Meta.Reflexive)metasplit.Header.Chunks[0].ChunkResources[x]; if (r.offset == 16) { soundnameindex = x; } if (r.offset == 32) { soundpermutationindex = x; } if (r.offset == 40) { soundchoiceindex = x; } if (r.offset == 64) { soundchunk1index = x; } } } MetaSplitter.SplitReflexive soundnamereflexive = metasplit.Header.Chunks[0].ChunkResources[soundnameindex] as MetaSplitter.SplitReflexive; MetaSplitter.SplitReflexive soundpermutationreflexive = metasplit.Header.Chunks[0].ChunkResources[soundpermutationindex] as MetaSplitter.SplitReflexive; MetaSplitter.SplitReflexive soundchoicereflexive = metasplit.Header.Chunks[0].ChunkResources[soundchoiceindex] as MetaSplitter.SplitReflexive; MetaSplitter.SplitReflexive soundchunk1reflexive = metasplit.Header.Chunks[0].ChunkResources[soundchunk1index] as MetaSplitter.SplitReflexive; for (int x = 0; x < metas.Count; x++) { Meta m = (Meta)metas[x]; if (m.rawType == RawDataContainerType.Sound) { Sound tempsound = (Sound)m.raw; BinaryWriter BW = new BinaryWriter(m.MS); int y = 0; // writes new index to meta BW.BaseStream.Position = 8; ushort temppermindex = (ushort)(map.ugh.Permutations.Count + sndpermcount); BW.Write(temppermindex); for (int e = 0; e < tempsound.Permutations.Length; e++) { for (int ee = 0; ee < tempsound.Permutations[e].choicecount; ee++) { int nindex = map.ugh.SoundNames.IndexOf(tempsound.Permutations[e].Choices[ee].Name); if (nindex == -1) { int nindex2 = strings.IndexOf(tempsound.Permutations[e].Choices[ee].Name); if (nindex2 == -1) { strings.Add(tempsound.Permutations[e].Choices[ee].Name); nindex2 = strings.Count - 1; } nindex2 += map.Strings.Name.Length; map.ugh.SoundNames.Add(tempsound.Permutations[e].Choices[ee].Name); tempsound.Permutations[e].Choices[ee].NameIndex = (ushort)(map.ugh.SoundNames.Count - 1); MetaSplitter.SplitReflexive tempss = new MetaSplitter.SplitReflexive(); tempss.chunksize = soundnamereflexive.Chunks[0].chunksize; tempss.MS = new MemoryStream(tempss.chunksize); BinaryWriter soundnameBW = new BinaryWriter(tempss.MS); soundnameBW.BaseStream.Position = 0; byte z = 0; soundnameBW.Write((ushort)nindex2); soundnameBW.Write(z); soundnameBW.Write((byte)tempsound.Permutations[e].Choices[ee].Name.Length); soundnamereflexive.Chunks.Add(tempss); addedsoundnames++; } else { tempsound.Permutations[e].Choices[ee].NameIndex = (ushort)nindex; } } } // cycle through permutations and write them for (int e = 0; e < tempsound.Permutations.Length; e++) { MetaSplitter.SplitReflexive tempss = new MetaSplitter.SplitReflexive(); tempss.chunksize = soundpermutationreflexive.Chunks[0].chunksize; tempss.MS = new MemoryStream(tempss.chunksize); BinaryWriter permBW = new BinaryWriter(tempss.MS); permBW.BaseStream.Position = 0; permBW.Write(tempsound.Permutations[e].unknown1); permBW.Write(tempsound.Permutations[e].unknown2); tempsound.Permutations[e].choiceindex = (ushort)(map.ugh.Choices.Count + sndchoicecount); permBW.Write(tempsound.Permutations[e].choiceindex); permBW.Write(tempsound.Permutations[e].choicecount); soundpermutationreflexive.Chunks.Add(tempss); for (int ee = 0; ee < tempsound.Permutations[e].choicecount; ee++) { MetaSplitter.SplitReflexive tempsss = new MetaSplitter.SplitReflexive(); tempsss.chunksize = soundchoicereflexive.Chunks[0].chunksize; tempsss.MS = new MemoryStream(tempsss.chunksize); BinaryWriter choiceBW = new BinaryWriter(tempsss.MS); choiceBW.BaseStream.Position = 0; choiceBW.Write(tempsound.Permutations[e].Choices[ee].NameIndex); choiceBW.Write(tempsound.Permutations[e].Choices[ee].unknown1); choiceBW.Write(tempsound.Permutations[e].Choices[ee].unknown2); choiceBW.Write(tempsound.Permutations[e].Choices[ee].unknown3); tempsound.Permutations[e].Choices[ee].soundindex = (ushort)(map.ugh.SoundChunks1.Count + sndchunk1count); choiceBW.Write(tempsound.Permutations[e].Choices[ee].soundindex); choiceBW.Write(tempsound.Permutations[e].Choices[ee].soundcount); soundchoicereflexive.Chunks.Add(tempsss); for (int eee = 0; eee < tempsound.Permutations[e].Choices[ee].soundcount; eee++) { RawDataChunk r = m.raw.rawChunks[y]; // write raw to map int tempintx = loc.startoffset + sndshift; map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); sndshift += r.size + tempinty; y++; MetaSplitter.SplitReflexive tempssss = new MetaSplitter.SplitReflexive(); tempssss.chunksize = soundchoicereflexive.Chunks[0].chunksize; tempssss.MS = new MemoryStream(tempssss.chunksize); BinaryWriter sndchnk1BW = new BinaryWriter(tempssss.MS); sndchnk1BW.BaseStream.Position = 0; sndchnk1BW.Write(tempintx); sndchnk1BW.Write(tempsound.Permutations[e].Choices[ee].SoundChunks1[eee].size); sndchnk1BW.Write(tempsound.Permutations[e].Choices[ee].SoundChunks1[eee].unknown1); sndchnk1BW.Write(tempsound.Permutations[e].Choices[ee].SoundChunks1[eee].unknown2); soundchunk1reflexive.Chunks.Add(tempssss); sndchunk1count++; } sndchoicecount++; } sndpermcount++; } metas[x] = m; } } totalshift += sndshift; if (sndshift > 0) { metasplit.Header.Chunks[0].ChunkResources[soundnameindex] = soundnamereflexive; metasplit.Header.Chunks[0].ChunkResources[soundpermutationindex] = soundpermutationreflexive; metasplit.Header.Chunks[0].ChunkResources[soundchoiceindex] = soundchoicereflexive; metasplit.Header.Chunks[0].ChunkResources[soundchunk1index] = soundchunk1reflexive; ughmeta = MetaBuilder.BuildMeta(metasplit, map); } metas.Add(ughmeta); #endregion #region model raw data int modeshift = 0; loc.startoffset += totalshift; loc.endoffset = loc.startoffset + loc.size; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); for (int x = 0; x < metas.Count; x++) { Meta m = (Meta)metas[x]; if (m.rawType == RawDataContainerType.Model) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; int tempintx = loc.endoffset + modeshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); modeshift += r.size + tempinty; } metas[x] = m; } } loc.size += modeshift; loc.endoffset = loc.startoffset + loc.size; layout.chunks[tempint] = loc; totalshift += modeshift; #endregion #region bsp raw tempint = layout.FindByType(RawDataContainerType.BSP); loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset += totalshift; int tempint2 = layout.FindByType(RawDataContainerType.BSPMeta); LayOutChunk loc2 = (LayOutChunk)layout.chunks[tempint2]; uint bsprawsize = (uint)loc.size; uint oldbspsize = (uint)loc.size; int bspshift = 0; int bspmagic = map.BSP.sbsp[0].magic; int newmagicreflexive = bspmagic + loc2.startoffset; bool found = false; Meta tempbspmeta = new Meta(map); bool foundbsptoimport = false; for (int x = 0; x < metas.Count; x++) { Meta m = (Meta)metas[x]; if (m.type == "sbsp") { foundbsptoimport = true; bsprawsize = 0; BinaryWriter BW = new BinaryWriter(m.MS); int[] tempoff = new int[m.raw.rawChunks.Count]; for (int y = 0; y < m.raw.rawChunks.Count; y++) { found = false; RawDataChunk r = m.raw.rawChunks[y]; for (int yy = 0; yy < y; yy++) { RawDataChunk rr = m.raw.rawChunks[yy]; if (rr.offset == r.offset && rr.rawLocation == r.rawLocation) { tempoff[y] = tempoff[yy]; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempoff[y]); BW.Write(r.size); found = true; break; } } if (found) { continue; } tempoff[y] = loc.startoffset + (int)bsprawsize; // MessageBox.Show("Test"); // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempoff[y]); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = loc.startoffset + bsprawsize; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); bsprawsize += (uint)(r.size + tempinty); } totalshift += (int)(bsprawsize - oldbspsize); bspshift += (int)(bsprawsize - oldbspsize); loc.size = (int)bsprawsize; loc.endoffset = (int)(loc.startoffset + bsprawsize); layout.chunks[tempint] = loc; loc2.MS = m.MS; loc2.size = m.size; loc2.endoffset = loc2.startoffset + m.size; layout.chunks[tempint2] = loc2; bspmagic = m.magic; newmagicreflexive = bspmagic + m.offset; tempbspmeta = m; metas.RemoveAt(x); break; } if (x == metas.Count - 1) { map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); loc.endoffset = loc.startoffset + loc.size; layout.chunks[tempint] = loc; } } #endregion #region weather raw data int weathershift = 0; tempint = layout.FindByType(RawDataContainerType.Weather); if (tempint != -1) { loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset += totalshift; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); } else { loc = new LayOutChunk(0); loc.rawType = RawDataContainerType.Weather; int tx = layout.FindByType(RawDataContainerType.BSP); loc.startoffset = ((LayOutChunk)layout.chunks[tx]).endoffset; loc.size = 0; } for (int x = 0; x < metas.Count; x++) { Meta m = (Meta)metas[x]; if (m.rawType == RawDataContainerType.Weather) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; int tempintx = loc.startoffset + loc.size + weathershift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); weathershift += r.size + tempinty; } metas[x] = m; } } loc.size += weathershift; loc.endoffset = loc.startoffset + loc.size; if (tempint == -1) { if (weathershift > 0) { layout.chunks.Add(loc); } ; } else { layout.chunks[tempint] = loc; } totalshift += weathershift; #endregion #region decr raw data int decrshift = 0; tempint = layout.FindByType(RawDataContainerType.DECR); if (tempint != -1) { loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset += totalshift; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); } else { loc = new LayOutChunk(0); loc.rawType = RawDataContainerType.DECR; int tx = layout.FindByType(RawDataContainerType.Weather); if (tx == -1) { tx = layout.FindByType(RawDataContainerType.BSP); } loc.startoffset = ((LayOutChunk)layout.chunks[tx]).endoffset; loc.size = 0; } for (int x = 0; x < metas.Count; x++) { Meta m = (Meta)metas[x]; if (m.rawType == RawDataContainerType.DECR) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; int tempintx = loc.startoffset + loc.size + decrshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); decrshift += r.size + tempinty; } metas[x] = m; } } loc.size += decrshift; loc.endoffset = loc.startoffset + loc.size; if (tempint == -1) { if (decrshift > 0) { layout.chunks.Add(loc); } ; } else { layout.chunks[tempint] = loc; } totalshift += decrshift; #endregion #region prtm raw data int prtmshift = 0; tempint = layout.FindByType(RawDataContainerType.PRTM); if (tempint != -1) { loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset += totalshift; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); } else { loc = new LayOutChunk(0); loc.rawType = RawDataContainerType.PRTM; int tx = layout.FindByType(RawDataContainerType.DECR); if (tx == -1) { tx = layout.FindByType(RawDataContainerType.Weather); if (tx == -1) { tx = layout.FindByType(RawDataContainerType.BSP); } } loc.startoffset = ((LayOutChunk)layout.chunks[tx]).endoffset; loc.size = 0; } for (int x = 0; x < metas.Count; x++) { Meta m = (Meta)metas[x]; if (m.rawType == RawDataContainerType.PRTM) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; int tempintx = loc.startoffset + loc.size + prtmshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); prtmshift += r.size + tempinty; } metas[x] = m; } } loc.size += prtmshift; loc.endoffset = loc.startoffset + loc.size; if (tempint == -1) { if (prtmshift > 0) { layout.chunks.Add(loc); } ; } else { layout.chunks[tempint] = loc; } totalshift += prtmshift; #endregion #region jmad raw data int jmadshift = 0; tempint = layout.FindByType(RawDataContainerType.Animation); if (tempint != -1) { loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset += totalshift; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); } else { loc = new LayOutChunk(0); loc.rawType = RawDataContainerType.Animation; int tx = layout.FindByType(RawDataContainerType.PRTM); if (tx == -1) { tx = layout.FindByType(RawDataContainerType.DECR); if (tx == -1) { tx = layout.FindByType(RawDataContainerType.Weather); if (tx == -1) { tx = layout.FindByType(RawDataContainerType.BSP); } } } loc.startoffset = ((LayOutChunk)layout.chunks[tx]).endoffset; loc.size = 0; } for (int x = 0; x < metas.Count; x++) { Meta m = (Meta)metas[x]; if (m.rawType == RawDataContainerType.Animation) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; int tempintx = loc.startoffset + loc.size + jmadshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset - 4; BW.Write(r.size); BW.Write(tempintx); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); jmadshift += r.size + tempinty; } metas[x] = m; } } loc.size += jmadshift; loc.endoffset = loc.startoffset + loc.size; if (tempint == -1) { if (jmadshift > 0) { layout.chunks.Add(loc); } ; } else { layout.chunks[tempint] = loc; } totalshift += jmadshift; #endregion #region bsp meta data uint bspmetasize = 0; int bspmetashift = 0; uint oldbspmetasize = (uint)map.BSP.sbsp[0].size; tempint = layout.FindByType(RawDataContainerType.BSPMeta); loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset += totalshift; loc.endoffset += totalshift; bspmetasize = (uint)loc.size; int tempinteger = layout.FindByType(RawDataContainerType.MetaData); loc2 = (LayOutChunk)layout.chunks[tempinteger]; int tempintxx = loc.startoffset; if (foundbsptoimport == false) { int tempint3 = layout.FindByType(RawDataContainerType.BSP); LayOutChunk loc3 = (LayOutChunk)layout.chunks[tempint3]; BinaryWriter BWZ = new BinaryWriter(loc.MS); for (int w = 0; w < loc3.rawPieces.Count; w++) { RawInfoChunk r = (RawInfoChunk)loc3.rawPieces[w]; BWZ.BaseStream.Position = r.offsetOfPointer - map.BSP.sbsp[0].offset; r.offset += (uint)(modeshift + sndshift); BWZ.Write(r.offset); } layout.chunks[tempint3] = loc3; } #endregion Should this be here or lower, didn't really look ???? // writes new pointer and magic and size to scenario meta BinaryWriter BWX = new BinaryWriter(loc2.MS); int tempoffx = map.MetaInfo.Offset[3] - map.MapHeader.metaStart - map.MapHeader.indexOffset + map.BSP.sbsp[0].pointerOffset; BWX.BaseStream.Position = tempoffx; BWX.Write(tempintxx); BWX.Write(loc.size); BWX.Write(newmagicreflexive); // writes raw to map file int bspoffset = tempintxx; map.BW.BaseStream.Position = tempintxx; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); // write padding layout.chunks[tempint] = loc; totalshift += (int)(bspmetasize - oldbspmetasize); bspmetashift = (int)(bspmetasize - oldbspmetasize); if (bspmetashift < 0) { bspmetashift = 0; } else { byte[] tempbytesxxxx = new byte[bspmetashift]; map.BW.Write(tempbytesxxxx); totalshift += bspmetashift; } #region stringnames1 tempint = layout.FindByType(RawDataContainerType.Strings1); loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset += totalshift; int tempoldsize = map.MapHeader.scriptReferenceCount * 128; int oldpadding = map.Functions.Padding(tempoldsize, 512); int tempnewsrsize = strings.Count * 128; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, tempoldsize); byte[] tempb = new byte[tempnewsrsize]; map.BW.BaseStream.Write(tempb, 0, tempnewsrsize); int padding = map.Functions.Padding(tempoldsize + tempnewsrsize, 512); tempb = new byte[padding]; map.BW.BaseStream.Write(tempb, 0, padding); for (int x = 0; x < strings.Count; x++) { map.BW.BaseStream.Position = loc.startoffset + tempoldsize + (x * 128); char[] tempc = ((String)strings[x]).ToCharArray(); map.BW.Write(tempc); } loc.size += -oldpadding + tempnewsrsize + padding; loc.endoffset = loc.startoffset + loc.size; totalshift += -oldpadding + tempnewsrsize + padding; map.BW.BaseStream.Position = 352; map.BW.Write(loc.startoffset); int newcount = map.MapHeader.scriptReferenceCount + strings.Count; map.BW.Write(newcount); layout.chunks[tempint] = loc; #endregion // MessageBox.Show("Test"); #region stringsindex tempint = layout.FindByType(RawDataContainerType.StringsIndex); loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset += totalshift; tempoldsize = map.MapHeader.scriptReferenceCount * 4; oldpadding = map.Functions.Padding(tempoldsize, 512); tempnewsrsize = strings.Count * 4; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, tempoldsize); tempb = new byte[tempnewsrsize]; map.BW.BaseStream.Write(tempb, 0, tempnewsrsize); padding = map.Functions.Padding(tempoldsize + tempnewsrsize, 512); tempb = new byte[padding]; map.BW.BaseStream.Write(tempb, 0, padding); int temporary = map.MapHeader.sizeOfScriptReference; for (int x = 0; x < strings.Count; x++) { map.BW.BaseStream.Position = loc.startoffset + tempoldsize + (x * 4); map.BW.Write(temporary); temporary += ((String)strings[x]).Length + 1; } loc.size += -oldpadding + tempnewsrsize + padding; loc.endoffset = loc.startoffset + loc.size; totalshift += -oldpadding + tempnewsrsize + padding; map.BW.BaseStream.Position = 364; map.BW.Write(loc.startoffset); layout.chunks[tempint] = loc; #endregion #region strings2 tempint = layout.FindByType(RawDataContainerType.Strings2); loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset += totalshift; tempoldsize = map.MapHeader.sizeOfScriptReference; oldpadding = map.Functions.Padding(tempoldsize, 512); tempnewsrsize = temporary - map.MapHeader.sizeOfScriptReference; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, tempoldsize); tempb = new byte[tempnewsrsize]; map.BW.BaseStream.Write(tempb, 0, tempnewsrsize); padding = map.Functions.Padding(tempoldsize + tempnewsrsize, 512); tempb = new byte[padding]; map.BW.BaseStream.Write(tempb, 0, padding); temporary = loc.startoffset + map.MapHeader.sizeOfScriptReference; byte zero = 0; for (int x = 0; x < strings.Count; x++) { map.BW.BaseStream.Position = temporary; char[] h = ((String)strings[x]).ToCharArray(); map.BW.Write(h); map.BW.Write(zero); temporary += ((String)strings[x]).Length + 1; } loc.size += -oldpadding + tempnewsrsize + padding; loc.endoffset = loc.startoffset + loc.size; totalshift += -oldpadding + tempnewsrsize + padding; int bleh = loc.size - padding; map.BW.BaseStream.Position = 360; map.BW.Write(bleh); map.BW.BaseStream.Position = 368; map.BW.Write(loc.startoffset); layout.chunks[tempint] = loc; #endregion #region file names tempint = layout.FindByType(RawDataContainerType.FileNames); loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset += totalshift; tempoldsize = map.MapHeader.fileNamesSize; oldpadding = map.Functions.Padding(tempoldsize, 512); map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write( loc.MS.ToArray(), 0, tempoldsize - map.FileNames.Length[map.IndexHeader.metaCount - 1] - 1); temporary = loc.startoffset + tempoldsize - map.FileNames.Length[map.IndexHeader.metaCount - 1] - 1; zero = 0; for (int x = 0; x < metas.Count; x++) { map.BW.BaseStream.Position = temporary; char[] h = ((Meta)metas[x]).name.ToCharArray(); map.BW.Write(h); map.BW.Write(zero); temporary += ((Meta)metas[x]).name.Length + 1; } tempnewsrsize = temporary - loc.startoffset - tempoldsize; padding = map.Functions.Padding(tempoldsize + tempnewsrsize, 512); tempb = new byte[padding]; map.BW.BaseStream.Write(tempb, 0, padding); loc.size += -oldpadding + tempnewsrsize + padding; loc.endoffset = loc.startoffset + loc.size; totalshift += -oldpadding + tempnewsrsize + padding; map.BW.BaseStream.Position = 704; newcount = map.MapHeader.fileCount + metas.Count - 1; map.BW.Write(newcount); map.BW.Write(loc.startoffset); int hhh = temporary - loc.startoffset; map.BW.Write(hhh); layout.chunks[tempint] = loc; #endregion #region files index tempint = layout.FindByType(RawDataContainerType.FileNamesIndex); loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset += totalshift; tempoldsize = map.MapHeader.fileCount * 4; oldpadding = map.Functions.Padding(tempoldsize, 512); tempnewsrsize = (metas.Count * 4) - 4; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, tempoldsize); tempb = new byte[tempnewsrsize]; map.BW.BaseStream.Write(tempb, 0, tempnewsrsize); padding = map.Functions.Padding(tempoldsize + tempnewsrsize, 512); tempb = new byte[padding]; map.BW.BaseStream.Write(tempb, 0, padding); temporary = map.MapHeader.fileNamesSize - map.FileNames.Length[map.IndexHeader.metaCount - 1] - 1; for (int x = 0; x < metas.Count; x++) { map.BW.BaseStream.Position = loc.startoffset + tempoldsize + (x * 4) - 4; map.BW.Write(temporary); temporary += ((Meta)metas[x]).name.Length + 1; } loc.size += -oldpadding + tempnewsrsize + padding; loc.endoffset = loc.startoffset + loc.size; totalshift += -oldpadding + tempnewsrsize + padding; map.BW.BaseStream.Position = 716; map.BW.Write(loc.startoffset); layout.chunks[tempint] = loc; tempint = layout.FindByType(RawDataContainerType.UnicodeNamesIndex); for (int x = 0; x < 8; x++) { loc = (LayOutChunk)layout.chunks[tempint + (x * 2)]; loc.startoffset += totalshift; loc.endoffset += totalshift; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); layout.chunks[tempint + (x * 2)] = loc; loc2 = (LayOutChunk)layout.chunks[tempint + (x * 2) + 1]; loc2.startoffset += totalshift; loc2.endoffset += totalshift; map.BW.BaseStream.Position = loc2.startoffset; map.BW.BaseStream.Write(loc2.MS.ToArray(), 0, loc2.size); layout.chunks[tempint + (x * 2) + 1] = loc2; } tempint = layout.FindByType(RawDataContainerType.MetaData); for (int x = 0; x < 9; x++) { loc = (LayOutChunk)layout.chunks[tempint]; BinaryWriter BW = new BinaryWriter(loc.MS); BW.BaseStream.Position = map.MetaInfo.Offset[0] - map.MapHeader.metaStart - map.MapHeader.indexOffset + map.Unicode.ut[x].indexPointerOffset; map.Unicode.ut[x].indexOffset += totalshift; map.Unicode.ut[x].tableOffset += totalshift; BW.Write(map.Unicode.ut[x].indexOffset); BW.Write(map.Unicode.ut[x].tableOffset); layout.chunks[tempint] = loc; } tempint = layout.FindByType(RawDataContainerType.Crazy); loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset += totalshift; loc.endoffset += totalshift; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); map.BW.BaseStream.Position = 344; map.BW.Write(loc.startoffset); layout.chunks[tempint] = loc; #endregion int bitmshift = 0; tempint = layout.FindByType(RawDataContainerType.Bitmap); loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset += totalshift; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); int bitmappad = 0; for (int x = 0; x < metas.Count; x++) { Meta m = (Meta)metas[x]; if (m.rawType == RawDataContainerType.Bitmap) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; int tempintx = loc.startoffset + loc.size + bitmshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); // BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); bitmshift += r.size + tempinty; bitmappad = tempinty; } metas[x] = m; } } totalshift += bitmshift; loc.size += bitmshift; loc.endoffset = loc.startoffset + loc.size; layout.chunks[tempint] = loc; tempint = layout.FindByType(RawDataContainerType.MetaIndex); loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset += totalshift; loc.endoffset += totalshift; tempint = layout.FindByType(RawDataContainerType.MetaData); loc2 = (LayOutChunk)layout.chunks[tempint]; loc2.startoffset += totalshift; loc2.endoffset += totalshift; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); map.BW.BaseStream.Position = loc2.startoffset; // Changed this line to include Min(MS.Length) as it would pad past end of file. ??? map.BW.BaseStream.Write(loc2.MS.ToArray(), 0, Math.Min(loc2.size, (int)loc2.MS.Length)); map.BW.BaseStream.Position = 16; map.BW.Write(loc.startoffset); newcount = metas.Count + map.IndexHeader.metaCount - 1; map.BW.BaseStream.Position = loc.startoffset + 24; map.BW.Write(newcount); map.BR.BaseStream.Position = map.IndexHeader.tagsOffset + totalshift + 8; map.SecondaryMagic = map.BR.ReadInt32() - (loc.startoffset + map.MapHeader.metaStart); int where = map.MetaInfo.Offset[map.IndexHeader.metaCount - 1] + totalshift; int howfar = 0; // Recreate Meta Table Index int metaTableStart = map.IndexHeader.tagsOffset + ((map.IndexHeader.metaCount - 1) * 16); for (int x = 0; x < metas.Count; x++) { Meta m = (Meta)metas[x]; int metaOffset = metaTableStart + totalshift + (x * 16); char[] metatype = m.type.ToCharArray(); Array.Reverse(metatype); // Create Ident Values? int ident = map.MetaInfo.Ident[map.IndexHeader.metaCount - 1] + (x * 65537); int offset = where + howfar; if (x == metas.Count - 1) { int wherex = map.MetaInfo.Offset[0] + totalshift + 756; map.BW.BaseStream.Position = wherex; map.BW.Write(ident); } // I believe this aligns the folowing tags on a boundry of 16 as is // very important for all HAVOK tags & data #region alignment fix if (m.type == "phmo" | m.type == "coll" | m.type == "spas") { int tempoffset = offset; do { // convert our 'tempoffset', which is our offset increased until the padding lines up, to a hex string tempss = tempoffset.ToString("X"); char[] tempc = tempss.ToCharArray(); // We use the last hex digit to see if our padding is right (0-15) for 16 byte alignment? if (m.padding == tempc[tempc.Length - 1]) { // If we had to add bytes to get our offset to line up, figure out how many and pad // the end of the last tag int diff = tempoffset - offset; tempb = new byte[diff]; map.BW.BaseStream.Position = offset; map.BW.Write(tempb); int tempsize; if (x == 0) { // The first tag has no tag before it, so we pad the MetaInfo instead tempsize = map.MetaInfo.Size[map.IndexHeader.metaCount - 2]; // int temploc = map.IndexHeader.tagsOffset + ((map.IndexHeader.metaCount - 2) * 16) + totalshift + 12; } else { // Retrieve the last tags size and add the difference onto it tempsize = ((Meta)metas[x - 1]).size; // int temploc = metaTableStart + totalshift + ((x - 1) * 16) + 12; } // Update the size of previous tag int temploc = metaTableStart + totalshift + ((x - 1) * 16) + 12; tempsize += diff; map.BW.BaseStream.Position = temploc; map.BW.Write(tempsize); offset = tempoffset; howfar += diff; break; } tempoffset++; } while (0 != 1); } #endregion int offsetwithmagic = offset + map.SecondaryMagic; // each record 16 bytes map.BW.BaseStream.Position = metaOffset; map.BW.Write(metatype); // Offset 0 map.BW.Write(ident); // Offset 4 map.BW.Write(offsetwithmagic); // Offset 8 map.BW.Write(m.size); // Offset 12 howfar += m.size; map.BW.BaseStream.Position = offset; map.BW.BaseStream.Write(m.MS.ToArray(), 0, m.size); for (int xx = 0; xx < m.items.Count; xx++) { Meta.Item i = m.items[xx]; switch (i.type) { case Meta.ItemType.Ident: Meta.Ident id = (Meta.Ident)i; if (id.pointstoTagIndex == -1 | x == metas.Count - 1) { for (int e = 0; e < metas.Count; e++) { Meta tempm = (Meta)metas[e]; if (tempm.name == id.pointstotagname && tempm.type == id.pointstotagtype) { id.ident = map.MetaInfo.Ident[map.IndexHeader.metaCount - 1] + (e * 65537); break; } if (e == metas.Count - 1) { if (id.pointstotagname != "Null") { int sss = Array.IndexOf(map.MetaInfo.TagType, id.pointstotagtype); id.ident = sss != -1 ? map.MetaInfo.Ident[sss] : -1; // id.ident=-1; } else { id.ident = -1; } } } } else { id.ident = map.MetaInfo.Ident[id.pointstoTagIndex]; } map.BW.BaseStream.Position = offset + id.offset; map.BW.Write(id.ident); break; case Meta.ItemType.Reflexive: Meta.Reflexive reflex = (Meta.Reflexive)i; int newreflex = reflex.translation + offset + map.SecondaryMagic; // Handle referenced reflexives if (reflex.pointstoTagIndex != m.TagIndex) { newreflex = totalshift + reflex.translation + map.MetaInfo.Offset[reflex.pointstoTagIndex] + map.SecondaryMagic; } map.BW.BaseStream.Position = offset + reflex.offset; map.BW.Write(reflex.chunkcount); map.BW.Write(newreflex); break; case Meta.ItemType.String: Meta.String s = (Meta.String)i; short stringnum = 0; byte stringlength = 0; for (int e = 0; e < map.MapHeader.scriptReferenceCount; e++) { if (s.name == map.Strings.Name[e]) { stringnum = (short)e; stringlength = (byte)map.Strings.Length[e]; } } for (int e = 0; e < strings.Count; e++) { if (((string)strings[e]) == s.name) { stringnum = (short)(map.MapHeader.scriptReferenceCount + e); stringlength = (byte)s.name.Length; } } map.BW.BaseStream.Position = offset + s.offset; map.BW.Write(stringnum); map.BW.Write(zero); map.BW.Write(stringlength); break; } } } // totalshift+=howfar; int tempfilesize = map.MapHeader.fileSize + totalshift + howfar - map.MetaInfo.Size[map.IndexHeader.metaCount - 1]; // (int)map.BW.BaseStream.Length; // map.MapHeader.fileSize+totalshift+howfar-map.MetaInfo.Size [map.IndexHeader.metaCount-1]; padding = map.Functions.Padding(tempfilesize, 512); tempb = new byte[padding]; map.BW.BaseStream.Position = tempfilesize; map.BW.Write(tempb); tempfilesize += padding; int olddifference = map.MapHeader.fileSize - map.MapHeader.indexOffset; int difference = tempfilesize - (map.MapHeader.indexOffset + totalshift); int metasize = map.MapHeader.metaSize + howfar - map.MetaInfo.Size[map.IndexHeader.metaCount - 1] + padding; // int combined = map.MapHeader.combinedSize + difference; int combined = map.MapHeader.combinedSize - olddifference + difference; // (int)bspmetasize + difference; // MessageBox.Show("test"); // combined // metasize -= bspmetashift; // map.MapHeader.combinedSize + howfar - map.MetaInfo.Size[map.IndexHeader.metaCount - 1] + padding; // (int)bspmetasize + difference - bspmetashift; map.BW.BaseStream.Position = 8; map.BW.Write(tempfilesize); map.BW.BaseStream.Position = 24; map.BW.Write(metasize); map.BW.Write(combined); map.BW.BaseStream.SetLength(tempfilesize); if (bspmagic == map.BSP.sbsp[0].magic) { } else { int tempbspmagic = map.BSP.sbsp[0].magic + map.BSP.sbsp[0].offset - bspoffset; for (int xx = 0; xx < tempbspmeta.items.Count; xx++) { Meta.Item i = tempbspmeta.items[xx]; switch (i.type) { case Meta.ItemType.Ident: Meta.Ident id = (Meta.Ident)i; if (id.pointstoTagIndex == -1) { for (int e = 0; e < metas.Count; e++) { Meta tempm = (Meta)metas[e]; if (tempbspmeta.name == id.pointstotagname && tempbspmeta.type == id.pointstotagtype) { id.ident = map.BSP.sbsp[0].ident; break; } else if (tempm.name == id.pointstotagname && tempm.type == id.pointstotagtype) { id.ident = map.MetaInfo.Ident[map.IndexHeader.metaCount - 1] + (e * 65537); break; } if (e == metas.Count - 1) { int sss = Array.IndexOf(map.MetaInfo.TagType, id.intagtype); id.ident = sss != -1 ? map.MetaInfo.Ident[sss] : -1; } } } else { id.ident = map.MetaInfo.Ident[id.pointstoTagIndex]; } map.BW.BaseStream.Position = bspoffset + id.offset; map.BW.Write(id.ident); break; case Meta.ItemType.String: Meta.String s = (Meta.String)i; short stringnum = 0; byte stringlength = 0; for (int e = 0; e < map.MapHeader.scriptReferenceCount; e++) { if (s.name == map.Strings.Name[e]) { stringnum = (short)e; stringlength = (byte)map.Strings.Length[e]; } } for (int e = 0; e < strings.Count; e++) { if (((string)strings[e]) == s.name) { stringnum = (short)(map.MapHeader.scriptReferenceCount + e); stringlength = (byte)s.name.Length; } } map.BW.BaseStream.Position = bspoffset + s.offset; map.BW.Write(stringnum); map.BW.Write(new byte()); map.BW.Write(stringlength); break; case Meta.ItemType.Reflexive: Meta.Reflexive rr = (Meta.Reflexive)i; int newreflex = bspoffset + rr.translation + tempbspmagic; map.BW.BaseStream.Position = bspoffset + rr.offset + 4; // map.BW.Write(newreflex); break; } } } for (int x = 0; x < layout.chunks.Count; x++) { loc = (LayOutChunk)layout.chunks[x]; for (int xx = 0; xx < loc.rawPieces.Count; xx++) { RawInfoChunk r = (RawInfoChunk)loc.rawPieces[xx]; r.offsetOfPointer += totalshift; map.BW.BaseStream.Position = r.offsetOfPointer; switch (r.rawType) { case RawDataType.bitm: r.offset += (uint)(totalshift - bitmshift); map.BW.Write(r.offset); break; case RawDataType.DECR: r.offset += (uint)(sndshift + modeshift + bspshift + weathershift); map.BW.Write(r.offset); break; // case RawDataType.snd2: case RawDataType.jmad: r.offset += (uint)(sndshift + modeshift + bspshift + weathershift + decrshift + prtmshift); map.BW.Write(r.offset); break; case RawDataType.mode1: r.offset += (uint)sndshift; map.BW.Write(r.offset); break; case RawDataType.mode2: r.offset += (uint)sndshift; map.BW.Write(r.offset); break; case RawDataType.PRTM: r.offset += (uint)(sndshift + modeshift + bspshift + weathershift + decrshift); map.BW.Write(r.offset); break; case RawDataType.weat: r.offset += (uint)(sndshift + modeshift + bspshift); map.BW.Write(r.offset); break; } } } layout.chunks[tempint] = loc; // layout.SortChunksByOffset(); map.CloseMap(); for (int y = 0; y < filestofix.Length; y++) { Map mapid = Map.LoadFromFile(filestofix[y]); MapAnalyzer analyze = new MapAnalyzer(); MapLayout lo = analyze.ScanMapForLayOut(mapid, true); mapid.OpenMap(MapTypes.Internal); for (int x = 0; x < lo.chunks.Count; x++) { loc = (LayOutChunk)lo.chunks[x]; for (int xx = 0; xx < loc.rawPieces.Count; xx++) { RawInfoChunk r = (RawInfoChunk)loc.rawPieces[xx]; if (r.location != map.MapHeader.mapType) { continue; } mapid.BW.BaseStream.Position = r.offsetOfPointer; switch (r.rawType) { case RawDataType.bitm: r.offset += (uint)(totalshift - bitmshift); r.offset |= 0X40000000; mapid.BW.Write(r.offset); break; case RawDataType.DECR: r.offset += (uint)(sndshift + modeshift + bspshift + weathershift); r.offset |= 0X40000000; mapid.BW.Write(r.offset); break; case RawDataType.snd2: case RawDataType.jmad: r.offset += (uint)(sndshift + modeshift + bspshift + weathershift + decrshift + prtmshift); r.offset |= 0X40000000; mapid.BW.Write(r.offset); break; case RawDataType.mode1: r.offset += (uint)sndshift; r.offset |= 0X40000000; mapid.BW.Write(r.offset); break; case RawDataType.mode2: r.offset += (uint)sndshift; r.offset |= 0X40000000; mapid.BW.Write(r.offset); break; case RawDataType.PRTM: r.offset += (uint)(sndshift + modeshift + bspshift + weathershift + decrshift); r.offset |= 0X40000000; mapid.BW.Write(r.offset); break; case RawDataType.weat: r.offset += (uint)(sndshift + modeshift + bspshift); r.offset |= 0X40000000; mapid.BW.Write(r.offset); break; } } } mapid.CloseMap(); mapid.Sign(); } }
/// <summary> /// The scan map for lay out. /// </summary> /// <param name="map">The map.</param> /// <param name="addexternalchunks">The addexternalchunks.</param> /// <returns></returns> /// <remarks></remarks> public MapLayout ScanMapForLayOut(Map map, bool addexternalchunks) { MapLayout layout = new MapLayout(); for (int x = 0; x < map.BSP.sbsp.Length; x++) { LayOutChunk l = new LayOutChunk(0); l.rawType = RawDataContainerType.BSPMeta; l.startoffset = map.BSP.sbsp[x].offset; l.endoffset = map.BSP.sbsp[x].offset + map.BSP.sbsp[x].size; l.size = map.BSP.sbsp[x].size; layout.chunks.Add(l); } LayOutChunk lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Header; lo.startoffset = 0; lo.size = 2048; lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.StringsIndex; lo.startoffset = map.MapHeader.offsetToStringIndex; lo.size = map.MapHeader.scriptReferenceCount * 4; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Strings1; lo.startoffset = map.MapHeader.offsetToStringNames1; lo.size = map.MapHeader.scriptReferenceCount * 128; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Strings2; lo.startoffset = map.MapHeader.offsetToStringNames2; lo.size = map.MapHeader.sizeOfScriptReference; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.Crazy; lo.startoffset = map.MapHeader.offsetToCrazy; lo.size = map.MapHeader.sizeOfCrazy; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.FileNamesIndex; lo.startoffset = map.MapHeader.offsetTofileIndex; lo.size = map.MapHeader.fileCount * 4; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); } lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.FileNames; lo.startoffset = map.MapHeader.offsetTofileNames; lo.size = map.MapHeader.fileNamesSize; if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo.size += map.Functions.Padding(lo.size, 512); } lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.MetaIndex; lo.startoffset = map.MapHeader.indexOffset; if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo.size = map.MapHeader.metaStart; lo.size += map.Functions.Padding(lo.size, 512); // map.MapHeader.fileSize - map.MapHeader.indexOffset; } else { lo.size = map.MapHeader.offsetTofileNames - map.MapHeader.indexOffset; // map.MetaInfo.Offset[map.IndexHeader.metaCount - 1] + map.MetaInfo.Size[map.IndexHeader.metaCount-1]; } lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.MetaData; lo.startoffset = map.MetaInfo.Offset[0]; // How can you adjust for padding past the end of the file??? lo.size = map.MapHeader.fileSize - lo.startoffset; if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { int padding = map.Functions.Padding(lo.startoffset + lo.size, 4096); lo.size += padding; } lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { for (int x = 0; x < map.Unicode.ut.Length; x++) { lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.UnicodeNamesIndex; lo.startoffset = map.Unicode.ut[x].indexOffset; lo.size = map.Unicode.ut[x].count * 8; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); lo = new LayOutChunk(0); lo.rawType = RawDataContainerType.UnicodeNames; lo.startoffset = map.Unicode.ut[x].tableOffset; lo.size = map.Unicode.ut[x].tableSize; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); } } map.OpenMap(MapTypes.Internal); for (int x = 0; x < map.IndexHeader.metaCount; x++) { if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { if (map.MetaInfo.TagType[x] == "snd!" | map.MetaInfo.TagType[x] == "ltmp") { continue; } Application.DoEvents(); } Meta m = new Meta(map); m.offset = map.MetaInfo.Offset[x]; // checks if type has raw data m.rawType = map.Functions.ForMeta.CheckForRaw(map.MetaInfo.TagType[x]); if (m.rawType != RawDataContainerType.Empty) { m.raw = map.Functions.ForMeta.ReadRaw(x, true); LayOutChunk l = new LayOutChunk(map.MapHeader.fileSize); int tempint = layout.FindByType(m.rawType); if (tempint == -1) { l = new LayOutChunk(map.MapHeader.fileSize); l.rawType = m.rawType; layout.chunks.Add(l); tempint = layout.FindByType(m.rawType); } else { l = (LayOutChunk)layout.chunks[tempint]; } for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.offset == -1) { continue; } if (r.rawLocation == MapTypes.Internal) { RawInfoChunk tempr = new RawInfoChunk(); tempr.offset = (uint)r.offset; tempr.size = r.size; tempr.rawType = r.rawDataType; tempr.location = r.rawLocation; tempr.offsetOfPointer = m.offset + r.pointerMetaOffset; l.rawPieces.Add(tempr); } else if (addexternalchunks) { RawInfoChunk tempr = new RawInfoChunk(); tempr.offset = (uint)r.offset; tempr.size = r.size; tempr.rawType = r.rawDataType; tempr.location = r.rawLocation; tempr.offsetOfPointer = m.offset + r.pointerMetaOffset; l.rawPieces.Add(tempr); } if (r.offset < l.startoffset && r.rawLocation == MapTypes.Internal) { l.startoffset = r.offset; l.size = l.endoffset - l.startoffset; layout.chunks[tempint] = l; } if (r.offset + r.size > l.endoffset && r.rawLocation == MapTypes.Internal) { l.endoffset = r.offset + r.size; l.endoffset += map.Functions.Padding(l.endoffset, 512); l.size = l.endoffset - l.startoffset; layout.chunks[tempint] = l; } } } m = null; GC.WaitForPendingFinalizers(); // GC.Collect(); } map.CloseMap(); if (map.HaloVersion == HaloVersionEnum.Halo2 || map.HaloVersion == HaloVersionEnum.Halo2Vista) { lo = new LayOutChunk(0); LayOutChunk templo = (LayOutChunk)layout.chunks[layout.FindByType(RawDataContainerType.Model)]; lo.rawType = RawDataContainerType.Sound; lo.startoffset = 2048; lo.size = templo.startoffset - 2048; lo.size += map.Functions.Padding(lo.size, 512); lo.endoffset = lo.startoffset + lo.size; layout.chunks.Add(lo); } for (int y = 0; y < layout.chunks.Count; y++) { LayOutChunk l = (LayOutChunk)layout.chunks[y]; if (l.size == 0) { layout.chunks.RemoveAt(y); y--; } } layout.SortChunksByOffset(); layout.SortRawByOffset(); return(layout); }
/// <summary> /// The extract map button_ click. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> /// <remarks></remarks> private void extractMapButton_Click(object sender, EventArgs e) { this.Enabled = false; count = 4 + map.BSP.sbsp.Length; // MetaList.Capacity = 10000; StatusLabel1.Text = "Processing Map Metas..."; Application.DoEvents(); if (treeView1.Nodes[0].Checked) { RecursivelyCheckMetas(treeView1.Nodes[0]); } StatusLabel1.Text = "Processing Imported Metas..."; Application.DoEvents(); foreach (ListViewItem l in listView2.Items) { if (l.Checked == false) { continue; } StatusLabel1.Text = "Processing: " + l.Text + "..."; Application.DoEvents(); string[] split = l.Text.Split('.'); if (split[split.Length - 1] != "info") { Meta m = new Meta(map); m.LoadMetaFromFile(l.Text); MetaList.Add(m); } else { FileStream FS = new FileStream(l.Text, FileMode.Open); StreamReader SR = new StreamReader(FS); string temps = string.Empty; do { temps = SR.ReadLine(); if (temps == null) { break; } Meta m = new Meta(map); m.LoadMetaFromFile(temps); bool exists = false; for (int x = 0; x < map.IndexHeader.metaCount; x++) { if (map.FileNames.Name[x] == m.name && map.MetaInfo.TagType[x] == m.type) { exists = true; break; } } if (exists == false) { for (int x = 0; x < MetaList.Count; x++) { if (((Meta)MetaList[x]).name == m.name && ((Meta)MetaList[x]).type == m.type) { exists = true; break; } } } if (exists == false) { switch (m.type.Trim()) { case "matg": matg = m; break; case "sncl": sncl = m; break; case "spk!": spk = m; break; case "scnr": scnr = m; break; case "sky": this.Skies.Add(m); skycount++; break; default: MetaList.Add(m); count++; break; } } }while (temps != null); SR.Close(); FS.Close(); } } for (int x = skycount - 1; x > -1; x--) { MetaList.Insert(0, Skies[x]); } MetaList.Insert(0, scnr); MetaList.Insert(0, spk); MetaList.Insert(0, sncl); MetaList.Insert(0, matg); StatusLabel1.Text = "Starting Rebuild...."; Application.DoEvents(); MapAnalyzer ma = new MapAnalyzer(); MapLayout lay = ma.ScanMapForLayOut(map, false); lay.ReadChunks(map); MapRebuilder(ref lay); MetaList.Clear(); StatusLabel1.Text = "Done"; this.Enabled = true; }
/// <summary> /// The map rebuilder. /// </summary> /// <param name="layout">The layout.</param> /// <remarks></remarks> public void MapRebuilder(ref MapLayout layout) { int totalshift = 0; // find new strings /// /// ArrayList strings = new ArrayList(); foreach (string s in map.Strings.Name) { strings.Add(s); } for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; for (int y = 0; y < m.items.Count; y++) { Meta.Item ii = m.items[y]; if (ii.type == Meta.ItemType.String) { Meta.String iii = (Meta.String)ii; if (strings.IndexOf(iii.name) == -1) { strings.Add(iii.name); } } } } ///read ugh to meta /// /// map.OpenMap(MapTypes.Internal); Meta ughmeta = new Meta(map); ughmeta.ReadMetaFromMap(map.IndexHeader.metaCount - 1, false); IFPIO ifp = IFPHashMap.GetIfp("ugh!", map.HaloVersion); ughmeta.headersize = ifp.headerSize; ughmeta.scanner.ScanWithIFP(ref ifp); MetaList.Add(ughmeta); string temps = string.Empty; ///get model info int tempint = layout.FindByType(RawDataContainerType.Model); LayOutChunk loc = (LayOutChunk)layout.chunks[tempint]; ////////////////////////////////////// ///model raw data /// int modeshift = 0; loc.startoffset += totalshift; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.rawType == RawDataContainerType.Model) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.rawLocation != MapTypes.Internal) { int tempintxx = r.offset; if (r.rawLocation == MapTypes.MPShared) { tempintxx |= int.Parse("80000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.SPShared) { tempintxx |= int.Parse("C0000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.MainMenu) { tempintxx |= int.Parse("40000000", NumberStyles.HexNumber); } // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintxx); BW.Write(r.size); continue; } int tempintx = loc.startoffset + modeshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); modeshift += r.size + tempinty; } MetaList[x] = m; } } loc.size = modeshift; loc.endoffset = loc.startoffset + loc.size; layout.chunks[tempint] = loc; int curroffset = loc.endoffset; ///////////////////////////////////// /// bsp raw /// int bspcount = 0; int[] bspmagic = new int[20]; int[] bspmagicreflexive = new int[20]; int[] bsprawoffset = new int[20]; int[] bsprawsize = new int[20]; int totalbsprawsize = 0; bool found = false; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.type == "sbsp") { BinaryWriter BW = new BinaryWriter(m.MS); int[] tempoff = new int[m.raw.rawChunks.Count]; int thisbsprawsize = 0; for (int y = 0; y < m.raw.rawChunks.Count; y++) { found = false; RawDataChunk r = m.raw.rawChunks[y]; for (int yy = 0; yy < y; yy++) { RawDataChunk rr = m.raw.rawChunks[yy]; if (rr.offset == r.offset && rr.rawLocation == r.rawLocation) { tempoff[y] = tempoff[yy]; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempoff[y]); BW.Write(r.size); found = true; break; } } if (found) { continue; } tempoff[y] = curroffset + thisbsprawsize; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempoff[y]); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = curroffset + thisbsprawsize; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); thisbsprawsize += r.size + tempinty; totalbsprawsize += r.size + tempinty; } bsprawsize[bspcount] = thisbsprawsize; bspmagic[bspcount] = m.magic; bspmagicreflexive[bspcount] = m.magic + m.offset; curroffset += bsprawsize[bspcount]; // bspmagic=m.magic; // newmagicreflexive=bspmagic+m.offset; bspcount += 1; MetaList[x] = m; } } ////////////////////////////////////// ///weather raw data /// int weathershift = 0; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.rawType == RawDataContainerType.Weather) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.rawLocation != MapTypes.Internal) { int tempintxx = r.offset; if (r.rawLocation == MapTypes.MPShared) { tempintxx |= int.Parse("80000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.SPShared) { tempintxx |= int.Parse("C0000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.MainMenu) { tempintxx |= int.Parse("40000000", NumberStyles.HexNumber); } // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintxx); BW.Write(r.size); continue; } int tempintx = curroffset + weathershift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); weathershift += r.size + tempinty; } MetaList[x] = m; } } curroffset += weathershift; ////////////////////////////////////// ///decr raw data /// int decrshift = 0; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.rawType == RawDataContainerType.DECR) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.rawLocation != MapTypes.Internal) { int tempintxx = r.offset; if (r.rawLocation == MapTypes.MPShared) { tempintxx |= int.Parse("80000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.SPShared) { tempintxx |= int.Parse("C0000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.MainMenu) { tempintxx |= int.Parse("40000000", NumberStyles.HexNumber); } // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintxx); BW.Write(r.size); continue; } int tempintx = curroffset + decrshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); decrshift += r.size + tempinty; } MetaList[x] = m; } } curroffset += decrshift; ////////////////////////////////////// ///prtm raw data /// int prtmshift = 0; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.rawType == RawDataContainerType.PRTM) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.rawLocation != MapTypes.Internal) { int tempintxx = r.offset; if (r.rawLocation == MapTypes.MPShared) { tempintxx |= int.Parse("80000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.SPShared) { tempintxx |= int.Parse("C0000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.MainMenu) { tempintxx |= int.Parse("40000000", NumberStyles.HexNumber); } // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintxx); BW.Write(r.size); continue; } int tempintx = curroffset + prtmshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); prtmshift += r.size + tempinty; } MetaList[x] = m; } } curroffset += prtmshift; ////////////////////////////////////// ///jmad raw data /// int jmadshift = 0; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.rawType == RawDataContainerType.Animation) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.rawLocation != MapTypes.Internal) { int tempintxx = r.offset; if (r.rawLocation == MapTypes.MPShared) { tempintxx |= int.Parse("80000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.SPShared) { tempintxx |= int.Parse("C0000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.MainMenu) { tempintxx |= int.Parse("40000000", NumberStyles.HexNumber); } // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset - 4; BW.Write(r.size); BW.Write(tempintxx); continue; } int tempintx = curroffset + jmadshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset - 4; BW.Write(r.size); BW.Write(tempintx); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); jmadshift += r.size + tempinty; } MetaList[x] = m; } } curroffset += jmadshift; ////////////////////////////////////// ///bsp meta data /// int[] bspmetaoffset = new int[20]; int[] bspmetasize = new int[20]; int tempcount = 0; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.type == "sbsp") { Meta mm = (Meta)MetaList[3]; if (mm.type == "scnr") { BinaryWriter BWX = new BinaryWriter(mm.MS); int tempoffx = map.BSP.sbsp[tempcount].pointerOffset; BWX.BaseStream.Position = tempoffx; BWX.Write(curroffset); BWX.Write(m.size); BWX.Write(bspmagicreflexive[tempcount]); MetaList[3] = mm; } map.BW.BaseStream.Position = curroffset; map.BW.BaseStream.Write(m.MS.ToArray(), 0, m.size); bspmetasize[tempcount] = m.size; bspmetaoffset[tempcount] = curroffset; curroffset += m.size; tempcount++; } } ////stringnames1 /// byte[] tempb = new byte[strings.Count * 128]; map.BW.BaseStream.Position = curroffset; map.BW.BaseStream.Write(tempb, 0, strings.Count * 128); for (int x = 0; x < strings.Count; x++) { map.BW.BaseStream.Position = curroffset + (x * 128); char[] tempc = ((String)strings[x]).ToCharArray(); map.BW.Write(tempc); } map.BW.BaseStream.Position = 352; map.BW.Write(curroffset); int newcount = strings.Count; map.BW.Write(newcount); curroffset += strings.Count * 128; int padding = map.Functions.Padding(curroffset, 512); tempb = new byte[padding]; map.BW.BaseStream.Position = curroffset; map.BW.BaseStream.Write(tempb, 0, padding); curroffset += padding; ////stringsindex /// int tempnewsrsize = strings.Count * 4; map.BW.BaseStream.Position = curroffset; int temporary = 0; for (int x = 0; x < strings.Count; x++) { map.BW.BaseStream.Position = curroffset + (x * 4); map.BW.Write(temporary); temporary += ((String)strings[x]).Length + 1; } map.BW.BaseStream.Position = 364; map.BW.Write(curroffset); curroffset += tempnewsrsize; padding = map.Functions.Padding(curroffset, 512); tempb = new byte[padding]; map.BW.BaseStream.Position = curroffset; map.BW.BaseStream.Write(tempb, 0, padding); curroffset += padding; ////strings2 /// temporary = 0; byte zero = 0; for (int x = 0; x < strings.Count; x++) { map.BW.BaseStream.Position = curroffset + temporary; char[] h = ((String)strings[x]).ToCharArray(); map.BW.Write(h); map.BW.Write(zero); temporary += ((String)strings[x]).Length + 1; } map.BW.BaseStream.Position = 360; map.BW.Write(temporary); map.BW.BaseStream.Position = 368; map.BW.Write(curroffset); curroffset += temporary; padding = map.Functions.Padding(curroffset, 512); tempb = new byte[padding]; map.BW.BaseStream.Position = curroffset; map.BW.BaseStream.Write(tempb, 0, padding); curroffset += padding; ////file names /// temporary = 0; for (int x = 0; x < MetaList.Count; x++) { map.BW.BaseStream.Position = curroffset + temporary; char[] h = ((Meta)MetaList[x]).name.ToCharArray(); map.BW.Write(h); map.BW.Write(zero); temporary += ((Meta)MetaList[x]).name.Length + 1; } map.BW.BaseStream.Position = 704; newcount = MetaList.Count; map.BW.Write(newcount); map.BW.Write(curroffset); map.BW.Write(temporary); curroffset += temporary; padding = map.Functions.Padding(curroffset, 512); tempb = new byte[padding]; map.BW.BaseStream.Position = curroffset; map.BW.BaseStream.Write(tempb, 0, padding); curroffset += padding; ////files index /// temporary = 0; for (int x = 0; x < MetaList.Count; x++) { map.BW.BaseStream.Position = curroffset + (x * 4); map.BW.Write(temporary); temporary += ((Meta)MetaList[x]).name.Length + 1; } map.BW.BaseStream.Position = 716; map.BW.Write(curroffset); curroffset += MetaList.Count * 4; padding = map.Functions.Padding(curroffset, 512); tempb = new byte[padding]; map.BW.BaseStream.Position = curroffset; map.BW.BaseStream.Write(tempb, 0, padding); curroffset += padding; tempint = layout.FindByType(RawDataContainerType.UnicodeNamesIndex); for (int x = 0; x < 9; x++) { map.Unicode.ut[x].indexOffset = curroffset; if (x != 8) { loc = (LayOutChunk)layout.chunks[tempint + (x * 2)]; loc.startoffset = curroffset; loc.endoffset = loc.startoffset + loc.size; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); layout.chunks[tempint + (x * 2)] = loc; curroffset += loc.size; } map.Unicode.ut[x].tableOffset = curroffset; if (x != 8) { LayOutChunk loc2 = (LayOutChunk)layout.chunks[tempint + (x * 2) + 1]; loc2.startoffset = curroffset; loc2.endoffset = loc2.startoffset + loc.size; map.BW.BaseStream.Position = loc2.startoffset; map.BW.BaseStream.Write(loc2.MS.ToArray(), 0, loc2.size); layout.chunks[tempint + (x * 2) + 1] = loc2; curroffset += loc2.size; } } Meta tempmatg = (Meta)MetaList[0]; BinaryWriter BWXX = new BinaryWriter(tempmatg.MS); for (int x = 0; x < 9; x++) { BWXX.BaseStream.Position = map.Unicode.ut[x].indexPointerOffset; BWXX.Write(map.Unicode.ut[x].indexOffset); BWXX.Write(map.Unicode.ut[x].tableOffset); } MetaList[0] = tempmatg; tempint = layout.FindByType(RawDataContainerType.Crazy); loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset = curroffset; // loc.endoffset+=totalshift; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); map.BW.BaseStream.Position = 344; map.BW.Write(loc.startoffset); layout.chunks[tempint] = loc; curroffset += loc.size; ////////////////////////////////////// ///bitmap raw data /// int bitmshift = 0; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.rawType == RawDataContainerType.Bitmap) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.rawLocation != MapTypes.Internal) { int tempintxx = r.offset; if (r.rawLocation == MapTypes.MPShared) { tempintxx |= int.Parse("80000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.SPShared) { tempintxx |= int.Parse("C0000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.MainMenu) { tempintxx |= int.Parse("40000000", NumberStyles.HexNumber); } // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintxx); BW.BaseStream.Position = r.pointerMetaOffset + 24; BW.Write(r.size); continue; } int tempintx = curroffset + bitmshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); BW.BaseStream.Position = r.pointerMetaOffset + 24; BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); bitmshift += r.size + tempinty; } MetaList[x] = m; } } curroffset += bitmshift; tempint = layout.FindByType(RawDataContainerType.MetaIndex); loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset = curroffset; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); map.BW.BaseStream.Position = 16; map.BW.Write(loc.startoffset); newcount = MetaList.Count; map.BW.BaseStream.Position = loc.startoffset + 24; map.BW.Write(newcount); int tagsoff = map.IndexHeader.tagsOffset - map.MapHeader.indexOffset; map.PrimaryMagic = map.IndexHeader.constant - (curroffset + 32); map.SecondaryMagic = map.PrimaryMagic + bspmetasize[0]; // map.SecondaryMagic=map.BR.ReadInt32()-(loc.startoffset+map.MapHeader.metaStart); int where = curroffset + map.MapHeader.metaStart; tempcount = 0; int howfar = 0; int[] newoffset = new int[MetaList.Count]; int[] newident = new int[MetaList.Count]; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; int f**k = curroffset + tagsoff + (x * 16); char[] metatype = m.type.ToCharArray(); Array.Reverse(metatype); int ident = map.MetaInfo.Ident[0] + (x * 65537); int offset = where + howfar; if (x == MetaList.Count - 1) { int wherex = curroffset + map.MapHeader.metaStart + 756; map.BW.BaseStream.Position = wherex; map.BW.Write(ident); } if (m.type == "phmo" | m.type == "coll" | m.type == "spas") { int tempoffset = offset; do { string tempss = tempoffset.ToString("X"); char[] tempc = tempss.ToCharArray(); int xxx = tempc.Length; if (m.padding == tempc[xxx - 1]) { int diff = tempoffset - offset; tempb = new byte[diff]; map.BW.BaseStream.Position = offset; map.BW.Write(tempb); int tempsize = ((Meta)MetaList[x - 1]).size; tempsize += diff; int temploc = f**k - 4; map.BW.BaseStream.Position = temploc; map.BW.Write(tempsize); offset = tempoffset; howfar += diff; break; } tempoffset++; }while (temps != null); } newoffset[x] = offset; newident[x] = ident; int offsetwithmagic = offset + map.SecondaryMagic; int size = m.size; map.BW.BaseStream.Position = f**k; map.BW.Write(metatype); map.BW.Write(ident); if (m.type != "sbsp" && m.type != "ltmp") { map.BW.Write(offsetwithmagic); map.BW.Write(size); howfar += m.size; map.BW.BaseStream.Position = offset; map.BW.BaseStream.Write(m.MS.ToArray(), 0, m.size); } else { int zeroi = 0; map.BW.Write(zeroi); map.BW.Write(zeroi); if (m.type == "sbsp") { offset = bspmetaoffset[tempcount]; newoffset[x] = offset; tempcount++; } else { continue; } } } for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; for (int xx = 0; xx < m.items.Count; xx++) { Meta.Item i = m.items[xx]; for (int e = 0; e < MetaList.Count; e++) { Meta tempm = (Meta)MetaList[e]; if (tempm.name == i.intagname && tempm.type == i.intagtype) { i.intag = e; break; } } if (i.intag != x) { continue; } switch (i.type) { case Meta.ItemType.Ident: Meta.Ident id = (Meta.Ident)i; id.ident = -1; for (int e = 0; e < MetaList.Count; e++) { Meta tempm = (Meta)MetaList[e]; if (tempm.name == id.pointstotagname && tempm.type == id.pointstotagtype) { id.ident = newident[e]; break; } } map.BW.BaseStream.Position = newoffset[x] + id.offset; map.BW.Write(id.ident); break; case Meta.ItemType.Reflexive: if (m.type != "sbsp") { Meta.Reflexive reflex = (Meta.Reflexive)i; for (int e = 0; e < MetaList.Count; e++) { Meta tempm = (Meta)MetaList[e]; if (reflex.pointstotagname == tempm.name && reflex.pointstotagtype == tempm.type) { reflex.pointstoTagIndex = e; break; } } int newreflex = reflex.translation + newoffset[reflex.pointstoTagIndex] + map.SecondaryMagic; map.BW.BaseStream.Position = newoffset[x] + reflex.offset; map.BW.Write(reflex.chunkcount); map.BW.Write(newreflex); } break; case Meta.ItemType.String: Meta.String s = (Meta.String)i; short stringnum = 0; byte stringlength = 0; for (int e = 0; e < strings.Count; e++) { if (s.name == (string)strings[e]) { stringnum = (short)e; stringlength = (byte)((string)strings[e]).Length; break; } } map.BW.BaseStream.Position = newoffset[x] + s.offset; map.BW.Write(stringnum); map.BW.Write(zero); map.BW.Write(stringlength); break; } } } // totalshift+=howfar; int tempfilesize = curroffset + map.MapHeader.metaStart + howfar; // map.MapHeader.fileSize+totalshift+howfar-map.MetaInfo.Size [map.IndexHeader.metaCount-1]; padding = map.Functions.Padding(tempfilesize, 512); tempb = new byte[padding]; map.BW.BaseStream.Position = tempfilesize; map.BW.Write(tempb); tempfilesize += padding; int olddifference = map.MapHeader.fileSize - (map.MapHeader.indexOffset); int difference = tempfilesize - (map.MapHeader.indexOffset + totalshift); int metasize = tempfilesize - (curroffset + map.MapHeader.metaStart); int combined = bspmetasize[0] + (tempfilesize - curroffset); map.BW.BaseStream.Position = 8; map.BW.Write(tempfilesize); map.BW.BaseStream.Position = 24; map.BW.Write(metasize); map.BW.Write(combined); map.BW.BaseStream.SetLength(tempfilesize); map.CloseMap(); }
/// <summary> /// The map rebuilder. /// </summary> /// <param name="layout">The layout.</param> /// <remarks></remarks> public void MapRebuilder(ref MapLayout layout) { int totalshift = 0; // find new strings /// /// ArrayList strings = new ArrayList(); foreach (string s in map.Strings.Name) { strings.Add(s); } for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; for (int y = 0; y < m.items.Count; y++) { Meta.Item ii = m.items[y]; if (ii.type == Meta.ItemType.String) { Meta.String iii = (Meta.String)ii; if (strings.IndexOf(iii.name) == -1) { strings.Add(iii.name); } } } } ///read ugh to meta /// /// map.OpenMap(MapTypes.Internal); Meta ughmeta = new Meta(map); ughmeta.ReadMetaFromMap(map.IndexHeader.metaCount - 1, false); IFPIO ifp = IFPHashMap.GetIfp("ugh!", map.HaloVersion); ughmeta.headersize = ifp.headerSize; ughmeta.scanner.ScanWithIFP(ref ifp); MetaList.Add(ughmeta); string temps = string.Empty; ///get model info int tempint = layout.FindByType(RawDataContainerType.Model); LayOutChunk loc = (LayOutChunk)layout.chunks[tempint]; ////////////////////////////////////// ///model raw data /// int modeshift = 0; loc.startoffset += totalshift; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.rawType == RawDataContainerType.Model) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.rawLocation != MapTypes.Internal) { int tempintxx = r.offset; if (r.rawLocation == MapTypes.MPShared) { tempintxx |= int.Parse("80000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.SPShared) { tempintxx |= int.Parse("C0000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.MainMenu) { tempintxx |= int.Parse("40000000", NumberStyles.HexNumber); } // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintxx); BW.Write(r.size); continue; } int tempintx = loc.startoffset + modeshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); modeshift += r.size + tempinty; } MetaList[x] = m; } } loc.size = modeshift; loc.endoffset = loc.startoffset + loc.size; layout.chunks[tempint] = loc; int curroffset = loc.endoffset; ///////////////////////////////////// /// bsp raw /// int bspcount = 0; int[] bspmagic = new int[20]; int[] bspmagicreflexive = new int[20]; int[] bsprawoffset = new int[20]; int[] bsprawsize = new int[20]; int totalbsprawsize = 0; bool found = false; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.type == "sbsp") { BinaryWriter BW = new BinaryWriter(m.MS); int[] tempoff = new int[m.raw.rawChunks.Count]; int thisbsprawsize = 0; for (int y = 0; y < m.raw.rawChunks.Count; y++) { found = false; RawDataChunk r = m.raw.rawChunks[y]; for (int yy = 0; yy < y; yy++) { RawDataChunk rr = m.raw.rawChunks[yy]; if (rr.offset == r.offset && rr.rawLocation == r.rawLocation) { tempoff[y] = tempoff[yy]; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempoff[y]); BW.Write(r.size); found = true; break; } } if (found) { continue; } tempoff[y] = curroffset + thisbsprawsize; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempoff[y]); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = curroffset + thisbsprawsize; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); thisbsprawsize += r.size + tempinty; totalbsprawsize += r.size + tempinty; } bsprawsize[bspcount] = thisbsprawsize; bspmagic[bspcount] = m.magic; bspmagicreflexive[bspcount] = m.magic + m.offset; curroffset += bsprawsize[bspcount]; // bspmagic=m.magic; // newmagicreflexive=bspmagic+m.offset; bspcount += 1; MetaList[x] = m; } } ////////////////////////////////////// ///weather raw data /// int weathershift = 0; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.rawType == RawDataContainerType.Weather) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.rawLocation != MapTypes.Internal) { int tempintxx = r.offset; if (r.rawLocation == MapTypes.MPShared) { tempintxx |= int.Parse("80000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.SPShared) { tempintxx |= int.Parse("C0000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.MainMenu) { tempintxx |= int.Parse("40000000", NumberStyles.HexNumber); } // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintxx); BW.Write(r.size); continue; } int tempintx = curroffset + weathershift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); weathershift += r.size + tempinty; } MetaList[x] = m; } } curroffset += weathershift; ////////////////////////////////////// ///decr raw data /// int decrshift = 0; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.rawType == RawDataContainerType.DECR) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.rawLocation != MapTypes.Internal) { int tempintxx = r.offset; if (r.rawLocation == MapTypes.MPShared) { tempintxx |= int.Parse("80000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.SPShared) { tempintxx |= int.Parse("C0000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.MainMenu) { tempintxx |= int.Parse("40000000", NumberStyles.HexNumber); } // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintxx); BW.Write(r.size); continue; } int tempintx = curroffset + decrshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); decrshift += r.size + tempinty; } MetaList[x] = m; } } curroffset += decrshift; ////////////////////////////////////// ///prtm raw data /// int prtmshift = 0; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.rawType == RawDataContainerType.PRTM) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.rawLocation != MapTypes.Internal) { int tempintxx = r.offset; if (r.rawLocation == MapTypes.MPShared) { tempintxx |= int.Parse("80000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.SPShared) { tempintxx |= int.Parse("C0000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.MainMenu) { tempintxx |= int.Parse("40000000", NumberStyles.HexNumber); } // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintxx); BW.Write(r.size); continue; } int tempintx = curroffset + prtmshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); prtmshift += r.size + tempinty; } MetaList[x] = m; } } curroffset += prtmshift; ////////////////////////////////////// ///jmad raw data /// int jmadshift = 0; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.rawType == RawDataContainerType.Animation) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.rawLocation != MapTypes.Internal) { int tempintxx = r.offset; if (r.rawLocation == MapTypes.MPShared) { tempintxx |= int.Parse("80000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.SPShared) { tempintxx |= int.Parse("C0000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.MainMenu) { tempintxx |= int.Parse("40000000", NumberStyles.HexNumber); } // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset - 4; BW.Write(r.size); BW.Write(tempintxx); continue; } int tempintx = curroffset + jmadshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset - 4; BW.Write(r.size); BW.Write(tempintx); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); jmadshift += r.size + tempinty; } MetaList[x] = m; } } curroffset += jmadshift; ////////////////////////////////////// ///bsp meta data /// int[] bspmetaoffset = new int[20]; int[] bspmetasize = new int[20]; int tempcount = 0; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.type == "sbsp") { Meta mm = (Meta)MetaList[3]; if (mm.type == "scnr") { BinaryWriter BWX = new BinaryWriter(mm.MS); int tempoffx = map.BSP.sbsp[tempcount].pointerOffset; BWX.BaseStream.Position = tempoffx; BWX.Write(curroffset); BWX.Write(m.size); BWX.Write(bspmagicreflexive[tempcount]); MetaList[3] = mm; } map.BW.BaseStream.Position = curroffset; map.BW.BaseStream.Write(m.MS.ToArray(), 0, m.size); bspmetasize[tempcount] = m.size; bspmetaoffset[tempcount] = curroffset; curroffset += m.size; tempcount++; } } ////stringnames1 /// byte[] tempb = new byte[strings.Count * 128]; map.BW.BaseStream.Position = curroffset; map.BW.BaseStream.Write(tempb, 0, strings.Count * 128); for (int x = 0; x < strings.Count; x++) { map.BW.BaseStream.Position = curroffset + (x * 128); char[] tempc = ((String)strings[x]).ToCharArray(); map.BW.Write(tempc); } map.BW.BaseStream.Position = 352; map.BW.Write(curroffset); int newcount = strings.Count; map.BW.Write(newcount); curroffset += strings.Count * 128; int padding = map.Functions.Padding(curroffset, 512); tempb = new byte[padding]; map.BW.BaseStream.Position = curroffset; map.BW.BaseStream.Write(tempb, 0, padding); curroffset += padding; ////stringsindex /// int tempnewsrsize = strings.Count * 4; map.BW.BaseStream.Position = curroffset; int temporary = 0; for (int x = 0; x < strings.Count; x++) { map.BW.BaseStream.Position = curroffset + (x * 4); map.BW.Write(temporary); temporary += ((String)strings[x]).Length + 1; } map.BW.BaseStream.Position = 364; map.BW.Write(curroffset); curroffset += tempnewsrsize; padding = map.Functions.Padding(curroffset, 512); tempb = new byte[padding]; map.BW.BaseStream.Position = curroffset; map.BW.BaseStream.Write(tempb, 0, padding); curroffset += padding; ////strings2 /// temporary = 0; byte zero = 0; for (int x = 0; x < strings.Count; x++) { map.BW.BaseStream.Position = curroffset + temporary; char[] h = ((String)strings[x]).ToCharArray(); map.BW.Write(h); map.BW.Write(zero); temporary += ((String)strings[x]).Length + 1; } map.BW.BaseStream.Position = 360; map.BW.Write(temporary); map.BW.BaseStream.Position = 368; map.BW.Write(curroffset); curroffset += temporary; padding = map.Functions.Padding(curroffset, 512); tempb = new byte[padding]; map.BW.BaseStream.Position = curroffset; map.BW.BaseStream.Write(tempb, 0, padding); curroffset += padding; ////file names /// temporary = 0; for (int x = 0; x < MetaList.Count; x++) { map.BW.BaseStream.Position = curroffset + temporary; char[] h = ((Meta)MetaList[x]).name.ToCharArray(); map.BW.Write(h); map.BW.Write(zero); temporary += ((Meta)MetaList[x]).name.Length + 1; } map.BW.BaseStream.Position = 704; newcount = MetaList.Count; map.BW.Write(newcount); map.BW.Write(curroffset); map.BW.Write(temporary); curroffset += temporary; padding = map.Functions.Padding(curroffset, 512); tempb = new byte[padding]; map.BW.BaseStream.Position = curroffset; map.BW.BaseStream.Write(tempb, 0, padding); curroffset += padding; ////files index /// temporary = 0; for (int x = 0; x < MetaList.Count; x++) { map.BW.BaseStream.Position = curroffset + (x * 4); map.BW.Write(temporary); temporary += ((Meta)MetaList[x]).name.Length + 1; } map.BW.BaseStream.Position = 716; map.BW.Write(curroffset); curroffset += MetaList.Count * 4; padding = map.Functions.Padding(curroffset, 512); tempb = new byte[padding]; map.BW.BaseStream.Position = curroffset; map.BW.BaseStream.Write(tempb, 0, padding); curroffset += padding; tempint = layout.FindByType(RawDataContainerType.UnicodeNamesIndex); for (int x = 0; x < 9; x++) { map.Unicode.ut[x].indexOffset = curroffset; if (x != 8) { loc = (LayOutChunk)layout.chunks[tempint + (x * 2)]; loc.startoffset = curroffset; loc.endoffset = loc.startoffset + loc.size; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); layout.chunks[tempint + (x * 2)] = loc; curroffset += loc.size; } map.Unicode.ut[x].tableOffset = curroffset; if (x != 8) { LayOutChunk loc2 = (LayOutChunk)layout.chunks[tempint + (x * 2) + 1]; loc2.startoffset = curroffset; loc2.endoffset = loc2.startoffset + loc.size; map.BW.BaseStream.Position = loc2.startoffset; map.BW.BaseStream.Write(loc2.MS.ToArray(), 0, loc2.size); layout.chunks[tempint + (x * 2) + 1] = loc2; curroffset += loc2.size; } } Meta tempmatg = (Meta)MetaList[0]; BinaryWriter BWXX = new BinaryWriter(tempmatg.MS); for (int x = 0; x < 9; x++) { BWXX.BaseStream.Position = map.Unicode.ut[x].indexPointerOffset; BWXX.Write(map.Unicode.ut[x].indexOffset); BWXX.Write(map.Unicode.ut[x].tableOffset); } MetaList[0] = tempmatg; tempint = layout.FindByType(RawDataContainerType.Crazy); loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset = curroffset; // loc.endoffset+=totalshift; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); map.BW.BaseStream.Position = 344; map.BW.Write(loc.startoffset); layout.chunks[tempint] = loc; curroffset += loc.size; ////////////////////////////////////// ///bitmap raw data /// int bitmshift = 0; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; if (m.rawType == RawDataContainerType.Bitmap) { BinaryWriter BW = new BinaryWriter(m.MS); for (int y = 0; y < m.raw.rawChunks.Count; y++) { RawDataChunk r = m.raw.rawChunks[y]; if (r.rawLocation != MapTypes.Internal) { int tempintxx = r.offset; if (r.rawLocation == MapTypes.MPShared) { tempintxx |= int.Parse("80000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.SPShared) { tempintxx |= int.Parse("C0000000", NumberStyles.HexNumber); } else if (r.rawLocation == MapTypes.MainMenu) { tempintxx |= int.Parse("40000000", NumberStyles.HexNumber); } // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintxx); BW.BaseStream.Position = r.pointerMetaOffset + 24; BW.Write(r.size); continue; } int tempintx = curroffset + bitmshift; // writes new pointer to loaded meta BW.BaseStream.Position = r.pointerMetaOffset; BW.Write(tempintx); BW.BaseStream.Position = r.pointerMetaOffset + 24; BW.Write(r.size); // writes raw to map file map.BW.BaseStream.Position = tempintx; map.BW.BaseStream.Write(r.MS.ToArray(), 0, r.size); // write padding int tempinty = map.Functions.Padding(r.size, 512); byte[] tempbytes = new byte[tempinty]; map.BW.Write(tempbytes); bitmshift += r.size + tempinty; } MetaList[x] = m; } } curroffset += bitmshift; tempint = layout.FindByType(RawDataContainerType.MetaIndex); loc = (LayOutChunk)layout.chunks[tempint]; loc.startoffset = curroffset; map.BW.BaseStream.Position = loc.startoffset; map.BW.BaseStream.Write(loc.MS.ToArray(), 0, loc.size); map.BW.BaseStream.Position = 16; map.BW.Write(loc.startoffset); newcount = MetaList.Count; map.BW.BaseStream.Position = loc.startoffset + 24; map.BW.Write(newcount); int tagsoff = map.IndexHeader.tagsOffset - map.MapHeader.indexOffset; map.PrimaryMagic = map.IndexHeader.constant - (curroffset + 32); map.SecondaryMagic = map.PrimaryMagic + bspmetasize[0]; // map.SecondaryMagic=map.BR.ReadInt32()-(loc.startoffset+map.MapHeader.metaStart); int where = curroffset + map.MapHeader.metaStart; tempcount = 0; int howfar = 0; int[] newoffset = new int[MetaList.Count]; int[] newident = new int[MetaList.Count]; for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; int f**k = curroffset + tagsoff + (x * 16); char[] metatype = m.type.ToCharArray(); Array.Reverse(metatype); int ident = map.MetaInfo.Ident[0] + (x * 65537); int offset = where + howfar; if (x == MetaList.Count - 1) { int wherex = curroffset + map.MapHeader.metaStart + 756; map.BW.BaseStream.Position = wherex; map.BW.Write(ident); } if (m.type == "phmo" | m.type == "coll" | m.type == "spas") { int tempoffset = offset; do { string tempss = tempoffset.ToString("X"); char[] tempc = tempss.ToCharArray(); int xxx = tempc.Length; if (m.padding == tempc[xxx - 1]) { int diff = tempoffset - offset; tempb = new byte[diff]; map.BW.BaseStream.Position = offset; map.BW.Write(tempb); int tempsize = ((Meta)MetaList[x - 1]).size; tempsize += diff; int temploc = f**k - 4; map.BW.BaseStream.Position = temploc; map.BW.Write(tempsize); offset = tempoffset; howfar += diff; break; } tempoffset++; } while (temps != null); } newoffset[x] = offset; newident[x] = ident; int offsetwithmagic = offset + map.SecondaryMagic; int size = m.size; map.BW.BaseStream.Position = f**k; map.BW.Write(metatype); map.BW.Write(ident); if (m.type != "sbsp" && m.type != "ltmp") { map.BW.Write(offsetwithmagic); map.BW.Write(size); howfar += m.size; map.BW.BaseStream.Position = offset; map.BW.BaseStream.Write(m.MS.ToArray(), 0, m.size); } else { int zeroi = 0; map.BW.Write(zeroi); map.BW.Write(zeroi); if (m.type == "sbsp") { offset = bspmetaoffset[tempcount]; newoffset[x] = offset; tempcount++; } else { continue; } } } for (int x = 0; x < MetaList.Count; x++) { Meta m = (Meta)MetaList[x]; for (int xx = 0; xx < m.items.Count; xx++) { Meta.Item i = m.items[xx]; for (int e = 0; e < MetaList.Count; e++) { Meta tempm = (Meta)MetaList[e]; if (tempm.name == i.intagname && tempm.type == i.intagtype) { i.intag = e; break; } } if (i.intag != x) { continue; } switch (i.type) { case Meta.ItemType.Ident: Meta.Ident id = (Meta.Ident)i; id.ident = -1; for (int e = 0; e < MetaList.Count; e++) { Meta tempm = (Meta)MetaList[e]; if (tempm.name == id.pointstotagname && tempm.type == id.pointstotagtype) { id.ident = newident[e]; break; } } map.BW.BaseStream.Position = newoffset[x] + id.offset; map.BW.Write(id.ident); break; case Meta.ItemType.Reflexive: if (m.type != "sbsp") { Meta.Reflexive reflex = (Meta.Reflexive)i; for (int e = 0; e < MetaList.Count; e++) { Meta tempm = (Meta)MetaList[e]; if (reflex.pointstotagname == tempm.name && reflex.pointstotagtype == tempm.type) { reflex.pointstoTagIndex = e; break; } } int newreflex = reflex.translation + newoffset[reflex.pointstoTagIndex] + map.SecondaryMagic; map.BW.BaseStream.Position = newoffset[x] + reflex.offset; map.BW.Write(reflex.chunkcount); map.BW.Write(newreflex); } break; case Meta.ItemType.String: Meta.String s = (Meta.String)i; short stringnum = 0; byte stringlength = 0; for (int e = 0; e < strings.Count; e++) { if (s.name == (string)strings[e]) { stringnum = (short)e; stringlength = (byte)((string)strings[e]).Length; break; } } map.BW.BaseStream.Position = newoffset[x] + s.offset; map.BW.Write(stringnum); map.BW.Write(zero); map.BW.Write(stringlength); break; } } } // totalshift+=howfar; int tempfilesize = curroffset + map.MapHeader.metaStart + howfar; // map.MapHeader.fileSize+totalshift+howfar-map.MetaInfo.Size [map.IndexHeader.metaCount-1]; padding = map.Functions.Padding(tempfilesize, 512); tempb = new byte[padding]; map.BW.BaseStream.Position = tempfilesize; map.BW.Write(tempb); tempfilesize += padding; int olddifference = map.MapHeader.fileSize - (map.MapHeader.indexOffset); int difference = tempfilesize - (map.MapHeader.indexOffset + totalshift); int metasize = tempfilesize - (curroffset + map.MapHeader.metaStart); int combined = bspmetasize[0] + (tempfilesize - curroffset); map.BW.BaseStream.Position = 8; map.BW.Write(tempfilesize); map.BW.BaseStream.Position = 24; map.BW.Write(metasize); map.BW.Write(combined); map.BW.BaseStream.SetLength(tempfilesize); map.CloseMap(); }