/// <summary> /// The recursively add pieces to meta. /// </summary> /// <param name="reflex">The reflex.</param> /// <param name="destination">The destination.</param> /// <param name="BW">The bw.</param> /// <remarks></remarks> public static void RecursivelyAddPiecesToMeta( MetaSplitter.SplitReflexive reflex, ref List <Meta.Item> destination, ref BinaryWriter BW) { for (int x = 0; x < reflex.Chunks.Count; x++) { BW.BaseStream.Position = reflex.translation + (reflex.chunksize * x); BW.Write(reflex.Chunks[x].MS.ToArray(), 0, reflex.chunksize); for (int y = 0; y < reflex.Chunks[x].ChunkResources.Count; y++) { Meta.Item i = reflex.Chunks[x].ChunkResources[y]; switch (i.type) { case Meta.ItemType.Reflexive: MetaSplitter.SplitReflexive treflex = (MetaSplitter.SplitReflexive)i; treflex.offset += reflex.translation + (reflex.chunksize * x); treflex.translation = metasize; treflex.chunkcount = treflex.Chunks.Count; metasize += treflex.chunksize * treflex.chunkcount; treflex.type = Meta.ItemType.Reflexive; treflex.intag = TagIndex; treflex.pointstoTagIndex = TagIndex; destination.Add(treflex); RecursivelyAddPiecesToMeta(treflex, ref destination, ref BW); break; case Meta.ItemType.Ident: MetaSplitter.SplitIdent id = new MetaSplitter.SplitIdent((MetaSplitter.SplitIdent)i); id.offset += reflex.translation + (reflex.chunksize * x); id.intag = TagIndex; destination.Add(id); break; case Meta.ItemType.String: MetaSplitter.SplitString ss = (MetaSplitter.SplitString)i; ss.offset += reflex.translation + (reflex.chunksize * x); ss.intag = TagIndex; destination.Add(ss); break; } } } }
/// <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 fix system link tool strip menu item_ click. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> /// <remarks></remarks> private void fixSystemLinkToolStripMenuItem_Click(object sender, EventArgs e) { int count = 0; List<int> ids = new List<int>(); for (int x = 0; x < map.IndexHeader.metaCount; x++) { switch (map.MetaInfo.TagType[x]) { case "bipd": case "bloc": case "ctrl": case "jpt!": case "mach": case "scen": case "ssce": case "vehi": ids.Add(map.MetaInfo.Ident[x]); count++; break; case "eqip": case "garb": case "proj": ids.Add(map.MetaInfo.Ident[x]); ids.Add(map.MetaInfo.Ident[x]); count += 2; break; case "weap": ids.Add(map.MetaInfo.Ident[x]); ids.Add(map.MetaInfo.Ident[x]); ids.Add(map.MetaInfo.Ident[x]); count += 3; break; } } map.OpenMap(MapTypes.Internal); Meta m = new Meta(map); m.ReadMetaFromMap(3, true); try { IFPIO io = IFPHashMap.GetIfp("scnr", map.HaloVersion); m.headersize = io.headerSize; m.scanner.ScanWithIFP(ref io); MetaSplitter metasplit = new MetaSplitter(); metasplit.SplitWithIFP(ref io, ref m, map); for (int x = 0; x < metasplit.Header.Chunks[0].ChunkResources.Count; x++) { // Offset 984 = [SCNR] Predicted Resources if (metasplit.Header.Chunks[0].ChunkResources[x].offset == 984) { MetaSplitter.SplitReflexive reflex = (MetaSplitter.SplitReflexive)metasplit.Header.Chunks[0].ChunkResources[x]; // count = # of chunks incl. added/removed // reflex.Chunks.Count = # of chunks listed in Predicted Resources (?) int diff = count - reflex.Chunks.Count; // Add/Remove chunks to match the difference for (int y = 0; y < diff; y++) { MetaSplitter.SplitReflexive MetaChunk = new MetaSplitter.SplitReflexive(); MetaChunk.splitReflexiveType = MetaSplitter.SplitReflexive.SplitReflexiveType.Chunk; MetaChunk.chunksize = 4; MetaChunk.MS = new MemoryStream(4); reflex.Chunks.Add(MetaChunk); } for (int y = 0; y < reflex.Chunks.Count; y++) { BinaryWriter BW = new BinaryWriter(reflex.Chunks[y].MS); BW.Write(ids[y]); } metasplit.Header.Chunks[0].ChunkResources[x] = reflex; break; } } Meta newmeta = MetaBuilder.BuildMeta(metasplit, map); map.OpenMap(MapTypes.Internal); map.ChunkTools.Add(newmeta); map.CloseMap(); // info.OpenMap(MapTypes.Internal); // info.BW.BaseStream.Position = m.offset + r.translation; // for (int x = 0; x < count; x++) // { // info.BW.Write(ids[x]); // } // info.CloseMap(); map = Map.Refresh(map); MessageBox.Show("Done"); } catch (Exception ex) { Global.ShowErrorMsg(string.Empty, ex); } }