/// <summary> /// The build meta. /// </summary> /// <param name="metasplit">The metasplit.</param> /// <param name="map">The map.</param> /// <returns></returns> /// <remarks></remarks> public static Meta BuildMeta(MetaSplitter metasplit, Map map) { metasize = 0; MetaStream = new MemoryStream(metasplit.Header.chunksize); BinaryWriter BW = new BinaryWriter(MetaStream); // BW.BaseStream.Position = 0; // BW.Write(metasplit.Header.MS.ToArray(), 0, metasplit.Header.chunksize); metasize += metasplit.Header.chunksize; TagIndex = metasplit.TagIndex; Meta m = new Meta(map); List<Meta.Item> NewItems = new List<Meta.Item>(); // Major error here! Size is not calculated right! RecursivelyAddPiecesToMeta(metasplit.Header, ref NewItems, ref BW); m.items = NewItems; if (MetaStream.Length % 4 != 0) { metasize += (int)MetaStream.Length % 4; MetaStream.SetLength(MetaStream.Length + MetaStream.Length % 4); } m.MS = MetaStream; m.size = metasize; m.type = metasplit.type; m.name = metasplit.name; m.rawType = metasplit.rawtype; m.raw = metasplit.raw; m.magic = metasplit.magic; m.offset = metasplit.offset; m.TagIndex = TagIndex; m.RelinkReferences(); m.WriteReferences(); // m.items.Clear(); // MetaScanner Ms = new MetaScanner(); if (m.rawType != RawDataContainerType.Empty) { map.OpenMap(MapTypes.Internal); m.raw = map.Functions.ForMeta.ReadRaw(m.TagIndex, false); map.CloseMap(); } // map.OpenMap(MapTypes.Internal); // IFPIO ifp=IFP.IFPHashMap.GetIfp(m.type); // m.parsed = true; // Ms.ScanWithIFP(ref ifp, ref m, map) ; // map.CloseMap(); return m; }
/// <summary> /// The build meta. /// </summary> /// <param name="metasplit">The metasplit.</param> /// <param name="map">The map.</param> /// <returns></returns> /// <remarks></remarks> public static Meta BuildMeta(MetaSplitter metasplit, Map map) { metasize = 0; MetaStream = new MemoryStream(metasplit.Header.chunksize); BinaryWriter BW = new BinaryWriter(MetaStream); // BW.BaseStream.Position = 0; // BW.Write(metasplit.Header.MS.ToArray(), 0, metasplit.Header.chunksize); metasize += metasplit.Header.chunksize; TagIndex = metasplit.TagIndex; Meta m = new Meta(map); List <Meta.Item> NewItems = new List <Meta.Item>(); // Major error here! Size is not calculated right! RecursivelyAddPiecesToMeta(metasplit.Header, ref NewItems, ref BW); m.items = NewItems; if (MetaStream.Length % 4 != 0) { metasize += (int)MetaStream.Length % 4; MetaStream.SetLength(MetaStream.Length + MetaStream.Length % 4); } m.MS = MetaStream; m.size = metasize; m.type = metasplit.type; m.name = metasplit.name; m.rawType = metasplit.rawtype; m.raw = metasplit.raw; m.magic = metasplit.magic; m.offset = metasplit.offset; m.TagIndex = TagIndex; m.RelinkReferences(); m.WriteReferences(); // m.items.Clear(); // MetaScanner Ms = new MetaScanner(); if (m.rawType != RawDataContainerType.Empty) { map.OpenMap(MapTypes.Internal); m.raw = map.Functions.ForMeta.ReadRaw(m.TagIndex, false); map.CloseMap(); } // map.OpenMap(MapTypes.Internal); // IFPIO ifp=IFP.IFPHashMap.GetIfp(m.type); // m.parsed = true; // Ms.ScanWithIFP(ref ifp, ref m, map) ; // map.CloseMap(); return(m); }
/// <summary> /// The add. /// </summary> /// <param name="tagIndex">Index of the tag.</param> /// <param name="metasplit">The metasplit.</param> /// <remarks></remarks> public void Add(int tagIndex, MetaSplitter metasplit) { // TagIndex - Global Variable this.TagIndex = tagIndex; ArrayList metas = new ArrayList(0); for (int x = 0; x < map.IndexHeader.metaCount; x++) { // sender.setProgressBar(x / map.IndexHeader.metaCount); Meta m = new Meta(map); m.ReadMetaFromMap(x, true); // Read meta layout of TAG from .ENT file IFPIO ifpx = IFPHashMap.GetIfp(m.type, map.HaloVersion); m.headersize = ifpx.headerSize; if (m.type == "sbsp") { } else { // anything but "sbsp" m.scanner.ScanWithIFP(ref ifpx); // metaScanner.ScanManually(ref m, ref map); } metas.Add(m); } // sender.setProgressBar(0); Meta targetTag = (Meta)metas[tagIndex]; Meta tempm = MetaBuilder.BuildMeta(metasplit, map); // (Meta) metas[TagIndex]; metas[tagIndex] = tempm; // ((Meta)metas[TagIndex]).RelinkReferences(map); SizeOfShift = tempm.size - targetTag.size; // Map IS already open? I guess it's a safety check. map.OpenMap(MapTypes.Internal); FixReflexives(metas); map.CloseMap(); }
/// <summary> /// The split ifp. /// </summary> /// <remarks></remarks> private void SplitIFP() { Meta m = new Meta(map); // Reads the current TAGNumber Meta m.ReadMetaFromMap(TagNumber, false); try { IFPIO ifpx = IFPHashMap.GetIfp(m.type, map.HaloVersion); m.headersize = ifpx.headerSize; // Scans IFP and loads IDENTS, REFLEXIVES & STRINGS into "m" for Reference List m.scanner.ScanWithIFP(ref ifpx); metasplit = new MetaSplitter(); metasplit.SplitWithIFP(ref ifpx, ref m, map); } catch (Exception ex) { Globals.Global.ShowErrorMsg(string.Empty, ex); } }
/// <summary> /// The display split. /// </summary> /// <param name="reflex">The reflex.</param> /// <param name="tn">The tn.</param> /// <remarks></remarks> private void DisplaySplit(MetaSplitter.SplitReflexive reflex, TreeNode tn) { for (int x = 0; x < reflex.Chunks.Count; x++) { string tempchunk = reflex.description; /**** This uses the labels in the .ENT plugins ***/ foreach (Meta.Item mi in reflex.Chunks[x].ChunkResources) { if (mi.description == reflex.label) { if (mi.type == Meta.ItemType.String) { tempchunk = ((Meta.String)mi).name; break; } if (mi.type == Meta.ItemType.Ident) { tempchunk = ((Meta.Ident)mi).pointstotagname; string[] splits = tempchunk.Split('\\'); tempchunk = splits[splits.Length - 1] + "." + ((Meta.Ident)mi).pointstotagtype; break; } } } /**/ string tempchunkname = "Chunk - #" + x + " - Name: " + tempchunk + " - Size: " + reflex.Chunks[x].chunksize; TreeNode ChunkNumberNode = new TreeNode(tempchunkname); MetaSplitter.SplitReflexive split = reflex.Chunks[x]; for (int y = 0; y < split.ChunkResources.Count; y++) { if (split.ChunkResources[y].type == Meta.ItemType.Reflexive) { TreeNode reflexnode = new TreeNode( "Reflexive - Name: " + split.ChunkResources[y].description + " - Size: " + ((MetaSplitter.SplitReflexive)split.ChunkResources[y]).chunksize + " - Offset: " + split.ChunkResources[y].offset); DisplaySplit((MetaSplitter.SplitReflexive)split.ChunkResources[y], reflexnode); ChunkNumberNode.Nodes.Add(reflexnode); } } tn.Nodes.Add(ChunkNumberNode); } }
/// <summary> /// The find selected node and over write. /// </summary> /// <param name="reflex">The reflex.</param> /// <param name="tn">The tn.</param> /// <returns></returns> /// <remarks></remarks> public MetaSplitter.SplitReflexive FindSelectedNodeAndOverWrite(MetaSplitter.SplitReflexive reflex, TreeNode tn) { if (reflex.ChunkResources.Count == 0 && reflex.Chunks.Count == 0) { return reflex; } int refcount = 0; foreach (TreeNode node in tn.Nodes) { if (node == treeView1.SelectedNode) { if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Container) { if (map.ChunkTools.ChunkClipBoard.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Chunk) { reflex.Chunks[refcount] = map.ChunkTools.ChunkClipBoard; } else { MessageBox.Show("Overwrite chunks with chunks"); } return reflex; } else if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Chunk) { do { if (reflex.ChunkResources[refcount].type == Meta.ItemType.Reflexive) { if (map.ChunkTools.ChunkClipBoard.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Container) { reflex.ChunkResources[refcount] = map.ChunkTools.ChunkClipBoard; } else { MessageBox.Show("Overwrite reflexives with reflexives"); } return reflex; } refcount++; } while (refcount != -1); } } if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Container) { reflex.Chunks[refcount] = FindSelectedNodeAndOverWrite(reflex.Chunks[refcount], node); refcount++; } else if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Chunk) { do { if (reflex.ChunkResources[refcount].type == Meta.ItemType.Reflexive) { reflex.ChunkResources[refcount] = FindSelectedNodeAndOverWrite( (MetaSplitter.SplitReflexive)reflex.ChunkResources[refcount], node); refcount++; break; } refcount++; } while (refcount != -1); // refcount++; } } return reflex; }
/// <summary> /// The find selected node and delete. /// </summary> /// <param name="reflex">The reflex.</param> /// <param name="tn">The tn.</param> /// <returns></returns> /// <remarks></remarks> public MetaSplitter.SplitReflexive FindSelectedNodeAndDelete(MetaSplitter.SplitReflexive reflex, TreeNode tn) { if (reflex.ChunkResources.Count == 0 && reflex.Chunks.Count == 0) { return reflex; } int refcount = 0; foreach (TreeNode node in tn.Nodes) { if (node == treeView1.SelectedNode) { if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Container) { reflex.Chunks.RemoveAt(refcount); return reflex; // reflex.chunkcount += map.ChunkTools.ChunkClipBoard.Chunks.Count; } else if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Chunk) { do { if (reflex.ChunkResources[refcount].type == Meta.ItemType.Reflexive) { reflex.ChunkResources.RemoveAt(refcount); return reflex; } refcount++; } while (refcount != -1); } } if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Container) { reflex.Chunks[refcount] = FindSelectedNodeAndDelete(reflex.Chunks[refcount], node); refcount++; } else if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Chunk) { do { if (reflex.ChunkResources[refcount].type == Meta.ItemType.Reflexive) { reflex.ChunkResources[refcount] = FindSelectedNodeAndDelete( (MetaSplitter.SplitReflexive)reflex.ChunkResources[refcount], node); refcount++; break; } refcount++; } while (refcount != -1); // refcount++; } } return reflex; }
/// <summary> /// The find selected node and clone. /// </summary> /// <param name="reflex">The reflex.</param> /// <param name="tn">The tn.</param> /// <returns></returns> /// <remarks></remarks> public MetaSplitter.SplitReflexive FindSelectedNodeAndClone(MetaSplitter.SplitReflexive reflex, TreeNode tn) { if (reflex.ChunkResources.Count == 0 && reflex.Chunks.Count == 0) { return reflex; } int refcount = 0; foreach (TreeNode node in tn.Nodes) { if (node == treeView1.SelectedNode) { if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Container) { int fff = Convert.ToInt32(chunkamount.Text); for (int x = 0; x < fff; x++) { reflex.Chunks.Insert(refcount + 1, reflex.Chunks[refcount]); /***** * I thought we had to do this, but I really don't know. The offsets are messed, but * I think fixed when the map is refreshed. ***** MetaSplitter.SplitReflexive newChunk = new MetaSplitter.SplitReflexive(reflex.Chunks[refcount]); // Is there ever any more than one ChunkResource? for (int xx = 0; xx < newChunk.ChunkResources.Count; xx++) { newChunk.ChunkResources[xx].mapOffset += (x + 1) * newChunk.chunksize; ((MetaSplitter.SplitIdent)newChunk.ChunkResources[xx]).inchunknumber = ((MetaSplitter.SplitIdent)(reflex.Chunks[refcount].ChunkResources[xx])).inchunknumber + x; ((MetaSplitter.SplitIdent)newChunk.ChunkResources[xx]).ident = ((MetaSplitter.SplitIdent)(reflex.Chunks[refcount].ChunkResources[xx])).ident; ((MetaSplitter.SplitIdent)newChunk.ChunkResources[xx]).pointstotagname = ((MetaSplitter.SplitIdent)(reflex.Chunks[refcount].ChunkResources[xx])).pointstotagname; ((MetaSplitter.SplitIdent)newChunk.ChunkResources[xx]).pointstoTagIndex = ((MetaSplitter.SplitIdent)(reflex.Chunks[refcount].ChunkResources[xx])).pointstoTagIndex; ((MetaSplitter.SplitIdent)newChunk.ChunkResources[xx]).pointstotagtype = ((MetaSplitter.SplitIdent)(reflex.Chunks[refcount].ChunkResources[xx])).pointstotagtype; } reflex.Chunks.Insert(refcount+1,newChunk); */ } return reflex; // reflex.chunkcount += map.ChunkTools.ChunkClipBoard.Chunks.Count; } else if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Chunk) { MessageBox.Show("Only Clone Chunks"); return reflex; } } if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Container) { reflex.Chunks[refcount] = FindSelectedNodeAndClone(reflex.Chunks[refcount], node); refcount++; } else if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Chunk) { do { if (reflex.ChunkResources[refcount].type == Meta.ItemType.Reflexive) { reflex.ChunkResources[refcount] = FindSelectedNodeAndClone( (MetaSplitter.SplitReflexive)reflex.ChunkResources[refcount], node); refcount++; break; } refcount++; } while (refcount != -1); // refcount++; } } return reflex; }
/// <summary> /// The find selected node. /// </summary> /// <param name="reflex">The reflex.</param> /// <param name="tn">The tn.</param> /// <remarks></remarks> public void FindSelectedNode(MetaSplitter.SplitReflexive reflex, TreeNode tn) { if (reflex.ChunkResources.Count == 0 && reflex.Chunks.Count == 0) { return; } int refcount = 0; foreach (TreeNode node in tn.Nodes) { if (node == treeView1.SelectedNode) { if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Container) { map.ChunkTools.ChunkClipBoard = reflex.Chunks[refcount]; return; } else if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Chunk) { do { if (reflex.ChunkResources[refcount].type == Meta.ItemType.Reflexive) { map.ChunkTools.ChunkClipBoard = (MetaSplitter.SplitReflexive)reflex.ChunkResources[refcount]; // map.ChunkTools.ChunkClipBoard=(MetaSplitter.SplitReflexive)reflex.ChunkResources[refcount]; return; } refcount++; } while (refcount != -1); } } if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Container) { FindSelectedNode(reflex.Chunks[refcount], node); refcount++; } else if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Chunk) { do { if (reflex.ChunkResources[refcount].type == Meta.ItemType.Reflexive) { FindSelectedNode((MetaSplitter.SplitReflexive)reflex.ChunkResources[refcount], node); refcount++; break; } refcount++; } while (refcount != -1); // refcount++; } } }
/// <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 tree view 1_ before expand. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> /// <remarks></remarks> private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e) { if (metaView != FormFunctions.MetaView.InfoView) { return; } string[] mReflex = e.Node.Text.Split('.'); if (mReflex.Length != 3) { return; } for (int x = 0; x < map.IndexHeader.metaCount; x++) { if ((mReflex[2] == map.FileNames.Name[x]) && (mReflex[1] == "[" + map.MetaInfo.TagType[x] + "]")) { map.OpenMap(MapTypes.Internal); Meta m = new Meta(map); m.ReadMetaFromMap(x, false); try { IFPIO ifpx = IFPHashMap.GetIfp(m.type, map.HaloVersion); m.headersize = ifpx.headerSize; // Scans IFP and loads IDENTS, REFLEXIVES & STRINGS into "m" for Reference List m.scanner.ScanWithIFP(ref ifpx); MetaSplitter metasplit = new MetaSplitter(); metasplit.SplitWithIFP(ref ifpx, ref m, map); e.Node.Nodes.Clear(); if (map.MetaInfo.TagType[x] != "sbsp") { DisplaySplit(metasplit.Header, e.Node); } } catch (Exception ex) { Global.ShowErrorMsg(string.Empty, ex); } map.CloseMap(); } } }
/// <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); } }
/// <summary> /// Recursively adds nodes to Chunk Tree Listing /// </summary> /// <param name="reflex">The reflex.</param> /// <param name="tn">The tn.</param> /// <remarks></remarks> private void DisplaySplit(MetaSplitter.SplitReflexive reflex, TreeNode tn) { for (int x = 0; x < reflex.Chunks.Count; x++) { string tempchunk = reflex.description; foreach (Meta.Item mi in reflex.Chunks[x].ChunkResources) { if (mi.type == Meta.ItemType.Ident) { tempchunk = "[" + ((Meta.Ident)mi).pointstotagtype + "] " + ((Meta.Ident)mi).pointstotagname; TreeNode ChunkNumberNode = new TreeNode(tempchunk); tn.Nodes.Add(ChunkNumberNode); // break; } } string tempchunkname = tempchunk; MetaSplitter.SplitReflexive split = reflex.Chunks[x]; for (int y = 0; y < split.ChunkResources.Count; y++) { if (split.ChunkResources[y].type == Meta.ItemType.Reflexive) { DisplaySplit((MetaSplitter.SplitReflexive)split.ChunkResources[y], tn); } } } }
/// <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 inject model. /// </summary> /// <param name="FilePath">The file path.</param> /// <param name="meta">The meta.</param> /// <returns></returns> /// <remarks></remarks> public virtual Meta InjectModel(string FilePath, Meta meta) { LoadFromOBJ(FilePath); char[] crsr = new[] { 'c', 'r', 's', 'r' }; char[] fklb = new[] { 'f', 'k', 'l', 'b' }; for (int x = 0; x < this.RawDataMetaChunks.Length; x++) { MemoryStream raw = new MemoryStream(); BinaryWriter newraw = new BinaryWriter(raw); BinaryReader oldraw = new BinaryReader(meta.raw.rawChunks[x].MS); int newrawsize = 0; int rawchunkid = 0; #region Write Header oldraw.BaseStream.Position = 0; newraw.BaseStream.Position = 0; newraw.Write(oldraw.ReadBytes(this.RawDataMetaChunks[x].HeaderSize)); newrawsize += this.RawDataMetaChunks[x].HeaderSize; #endregion #region Write Submesh Info newraw.BaseStream.Position = newrawsize; newraw.Write(crsr); newrawsize += 4; for (int y = 0; y < this.RawDataMetaChunks[x].SubMeshInfo.Length; y++) { oldraw.BaseStream.Position = this.RawDataMetaChunks[x].HeaderSize + this.RawDataMetaChunks[x].RawDataChunkInfo[0].Offset; newraw.BaseStream.Position = newrawsize + (y * 72); newraw.Write(oldraw.ReadBytes(72)); newraw.BaseStream.Position = newrawsize + (y * 72) + 4; newraw.Write((short)this.RawDataMetaChunks[x].SubMeshInfo[y].ShaderNumber); newraw.Write((short)this.RawDataMetaChunks[x].SubMeshInfo[y].IndiceStart); newraw.Write((short)this.RawDataMetaChunks[x].SubMeshInfo[y].IndiceCount); } this.RawDataMetaChunks[x].RawDataChunkInfo[0].ChunkCount = this.RawDataMetaChunks[x].SubMeshInfo.Length; this.RawDataMetaChunks[x].RawDataChunkInfo[0].Size = this.RawDataMetaChunks[x].SubMeshInfo.Length * 72; newrawsize += this.RawDataMetaChunks[x].SubMeshInfo.Length * 72; // write count newraw.BaseStream.Position = 8; newraw.Write(this.RawDataMetaChunks[x].SubMeshInfo.Length); #endregion #region Write Unknown rawchunkid = 1; while (newrawsize > 0) { if (this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].ChunkSize == 2) { break; } oldraw.BaseStream.Position = this.RawDataMetaChunks[x].HeaderSize + this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Offset; newraw.BaseStream.Position = newrawsize; newraw.Write(crsr); newrawsize += 4; newraw.Write(oldraw.ReadBytes(this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Size)); this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Offset = newrawsize - this.RawDataMetaChunks[x].HeaderSize; newrawsize += this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Size; rawchunkid++; } #endregion #region Write Indices int indicechunkid = rawchunkid; newraw.BaseStream.Position = newrawsize; newraw.Write(crsr); newrawsize += 4; for (int y = 0; y < this.RawDataMetaChunks[x].Indices.Length; y++) { newraw.Write(this.RawDataMetaChunks[x].Indices[y]); } this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Offset = newrawsize - this.RawDataMetaChunks[x].HeaderSize; this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].ChunkCount = this.RawDataMetaChunks[x].Indices.Length; this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Size = this.RawDataMetaChunks[x].Indices.Length * 2; newrawsize += this.RawDataMetaChunks[x].Indices.Length * 2; rawchunkid++; // indice count newraw.BaseStream.Position = 40; newraw.Write((short)this.RawDataMetaChunks[x].Indices.Length); #endregion #region Write Unknown oldraw.BaseStream.Position = this.RawDataMetaChunks[x].HeaderSize + this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Offset; newraw.BaseStream.Position = newrawsize; newraw.Write(crsr); newrawsize += 4; newraw.Write(oldraw.ReadBytes(this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Size)); this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Offset = newrawsize - this.RawDataMetaChunks[x].HeaderSize; newrawsize += this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Size; rawchunkid++; #endregion #region Write Vertices int verticechunkid = indicechunkid + 2; newraw.BaseStream.Position = newrawsize; newraw.Write(crsr); newrawsize += 4; newraw.Write( new byte[ this.RawDataMetaChunks[x].RawDataChunkInfo[verticechunkid].ChunkSize * this.RawDataMetaChunks[x].VerticeCount]); for (int y = 0; y < this.RawDataMetaChunks[x].VerticeCount; y++) { newraw.BaseStream.Position = newrawsize + (y * this.RawDataMetaChunks[x].RawDataChunkInfo[verticechunkid].ChunkSize); short vx = (short) this.RawDataMetaChunks[x].CompressVertice( this.RawDataMetaChunks[x].Vertices[y].X, this.BoundingBox.MinX, this.BoundingBox.MaxX); short vy = (short) this.RawDataMetaChunks[x].CompressVertice( this.RawDataMetaChunks[x].Vertices[y].Y, this.BoundingBox.MinY, this.BoundingBox.MaxY); short vz = (short) this.RawDataMetaChunks[x].CompressVertice( this.RawDataMetaChunks[x].Vertices[y].Z, this.BoundingBox.MinZ, this.BoundingBox.MaxZ); newraw.Write(vx); newraw.Write(vy); newraw.Write(vz); } this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Offset = newrawsize - this.RawDataMetaChunks[x].HeaderSize; newrawsize += this.RawDataMetaChunks[x].RawDataChunkInfo[verticechunkid].ChunkSize * this.RawDataMetaChunks[x].VerticeCount; this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Size = this.RawDataMetaChunks[x].RawDataChunkInfo[verticechunkid].ChunkSize * this.RawDataMetaChunks[x].VerticeCount; this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].ChunkSize = 0; // this.RawDataMetaChunks[x].RawDataChunkInfo[verticechunkid].ChunkSize * this.RawDataMetaChunks[x].VerticeCount; ; newraw.BaseStream.Position = 100; newraw.Write(this.RawDataMetaChunks[x].VerticeCount); rawchunkid++; #endregion #region Write UVs int uvchunkid = verticechunkid + 1; newraw.BaseStream.Position = newrawsize; newraw.Write(crsr); newrawsize += 4; for (int y = 0; y < this.RawDataMetaChunks[x].VerticeCount; y++) { short u = (short) this.RawDataMetaChunks[x].CompressVertice( this.RawDataMetaChunks[x].UVs[y].X, this.BoundingBox.MinU, this.BoundingBox.MaxU); short v = (short) this.RawDataMetaChunks[x].CompressVertice( this.RawDataMetaChunks[x].UVs[y].Y, this.BoundingBox.MinV, this.BoundingBox.MaxV); newraw.Write(u); newraw.Write(v); } this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Offset = newrawsize - this.RawDataMetaChunks[x].HeaderSize; this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].ChunkSize = 1; this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Size = 4 * this.RawDataMetaChunks[x].VerticeCount; newrawsize += 4 * this.RawDataMetaChunks[x].VerticeCount; rawchunkid++; #endregion #region Write Normals newraw.BaseStream.Position = newrawsize; newraw.Write(crsr); newrawsize += 4; for (int y = 0; y < this.RawDataMetaChunks[x].VerticeCount; y++) { int u = CompressNormal(this.RawDataMetaChunks[x].Normals[y]); int v = 1; newraw.Write(u); newraw.Write(v); newraw.Write(v); } this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Offset = newrawsize - this.RawDataMetaChunks[x].HeaderSize; this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].ChunkSize = 2; this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Size = 4 * this.RawDataMetaChunks[x].VerticeCount; newrawsize += 12 * this.RawDataMetaChunks[x].VerticeCount; rawchunkid++; #endregion #region Write Other Stuff Not Yet Implemented while (rawchunkid < this.RawDataMetaChunks[x].RawDataChunkInfo.Length) { oldraw.BaseStream.Position = this.RawDataMetaChunks[x].HeaderSize + this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Offset; newraw.BaseStream.Position = newrawsize; newraw.Write(crsr); newrawsize += 4; newraw.Write(oldraw.ReadBytes(this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Size)); this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Offset = newrawsize - this.RawDataMetaChunks[x].HeaderSize; newrawsize += this.RawDataMetaChunks[x].RawDataChunkInfo[rawchunkid].Size; rawchunkid++; } #endregion // footer newraw.Write(fklb); newrawsize += 4; // raw size int rawsize = newrawsize - this.RawDataMetaChunks[x].HeaderSize - 4; newraw.BaseStream.Position = 4; newraw.Write(rawsize); meta.raw.rawChunks[x].MS = raw; meta.raw.rawChunks[x].size = newrawsize; } MetaSplitter ms = new MetaSplitter(); IFPIO io = IFPHashMap.GetIfp(meta.type, map.HaloVersion); ms.SplitWithIFP(ref io, ref meta, map); #region Write Bounding Box int c = 0; while (c != -1) { if (ms.Header.Chunks[0].ChunkResources[c].offset == 20) { break; } c++; } MetaSplitter.SplitReflexive reflex = ms.Header.Chunks[0].ChunkResources[c] as MetaSplitter.SplitReflexive; BinaryWriter BW = new BinaryWriter(reflex.Chunks[0].MS); BW.BaseStream.Position = 0; BW.Write(this.BoundingBox.MinX); BW.Write(this.BoundingBox.MaxX); BW.Write(this.BoundingBox.MinY); BW.Write(this.BoundingBox.MaxY); BW.Write(this.BoundingBox.MinZ); BW.Write(this.BoundingBox.MaxZ); BW.Write(this.BoundingBox.MinU); BW.Write(this.BoundingBox.MaxU); BW.Write(this.BoundingBox.MinV); BW.Write(this.BoundingBox.MaxV); ms.Header.Chunks[0].ChunkResources[c] = reflex; #endregion #region metachunks while (c != -1) { if (ms.Header.Chunks[0].ChunkResources[c].offset == 36) { break; } c++; } MetaSplitter.SplitReflexive reflexe = ms.Header.Chunks[0].ChunkResources[c] as MetaSplitter.SplitReflexive; for (int l = 0; l < reflexe.Chunks.Count; l++) { BW = new BinaryWriter(reflexe.Chunks[l].MS); BW.BaseStream.Position = 4; short facecount = (short)this.RawDataMetaChunks[l].FaceCount; BW.Write((short)this.RawDataMetaChunks[l].VerticeCount); BW.Write(facecount); BW.BaseStream.Position = 68; BW.Write(meta.raw.rawChunks[l].size - this.RawDataMetaChunks[l].HeaderSize - 4); for (int h = 0; h < reflexe.Chunks[l].ChunkResources.Count; h++) { if (reflexe.Chunks[l].ChunkResources[h].offset == 72) { MetaSplitter.SplitReflexive reflexx = reflexe.Chunks[l].ChunkResources[h] as MetaSplitter.SplitReflexive; for (int k = 0; k < reflexx.Chunks.Count; k++) { BinaryWriter BWX = new BinaryWriter(reflexx.Chunks[k].MS); BWX.BaseStream.Position = 6; BWX.Write((short)this.RawDataMetaChunks[l].RawDataChunkInfo[k].ChunkSize); BWX.Write(this.RawDataMetaChunks[l].RawDataChunkInfo[k].Size); BWX.Write(this.RawDataMetaChunks[l].RawDataChunkInfo[k].Offset); } reflexe.Chunks[l].ChunkResources[h] = reflexx; break; } } } while (c != -1) { if (ms.Header.Chunks[0].ChunkResources[c].offset == 96) { break; } c++; } reflexe = ms.Header.Chunks[0].ChunkResources[c] as MetaSplitter.SplitReflexive; if (this.Shaders.Shader.Length > this.Shaders.count) { int diff = this.Shaders.Shader.Length - reflexe.Chunks.Count; for (int x = 0; x < diff; x++) { reflexe.Chunks.Add(reflexe.Chunks[0]); } } else { } #endregion Meta m = MetaBuilder.BuildMeta(ms, map); m.raw = meta.raw; return m; }
/// <summary> /// The find selected node and add. /// </summary> /// <param name="reflex">The reflex.</param> /// <param name="tn">The tn.</param> /// <returns></returns> /// <remarks></remarks> public MetaSplitter.SplitReflexive FindSelectedNodeAndAdd(MetaSplitter.SplitReflexive reflex, TreeNode tn) { if (reflex.ChunkResources.Count == 0 && reflex.Chunks.Count == 0) { return reflex; } int refcount = 0; foreach (TreeNode node in tn.Nodes) { if (node == treeView1.SelectedNode) { if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Container) { if (map.ChunkTools.ChunkClipBoard.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Container) { MetaSplitter.SplitReflexive split; split = reflex.Chunks[refcount]; for (int x = 0; x < split.ChunkResources.Count; x++) { if (split.ChunkResources[x].type == Meta.ItemType.Reflexive) { MetaSplitter.SplitReflexive tempref; tempref = split.ChunkResources[x] as MetaSplitter.SplitReflexive; if (tempref.description == map.ChunkTools.ChunkClipBoard.description && tempref.chunksize == map.ChunkTools.ChunkClipBoard.chunksize) { tempref.Chunks.AddRange(map.ChunkTools.ChunkClipBoard.Chunks); // } split.ChunkResources[x] = tempref; reflex.Chunks[refcount] = split; return reflex; } } } if (reflex != map.ChunkTools.ChunkClipBoard) { if (reflex.offset <= reflex.Chunks[refcount].chunksize - 8) { int lowindex = -1; int lowoffset = 0; int highoffset = reflex.Chunks[refcount].chunksize; for (int e = 0; e < reflex.Chunks[refcount].ChunkResources.Count; e++) { Meta.Item mi = reflex.Chunks[refcount].ChunkResources[e]; if (mi.offset < map.ChunkTools.ChunkClipBoard.offset && mi.offset > lowoffset) { lowindex = e; lowoffset = mi.offset; } } if (lowindex == -1) { reflex.Chunks[refcount].ChunkResources.Insert(0, map.ChunkTools.ChunkClipBoard); } else { reflex.Chunks[refcount].ChunkResources.Insert( lowindex + 1, map.ChunkTools.ChunkClipBoard); } } else { MessageBox.Show( "The offset of the reflexive you are trying to paste is too high for this chunk size"); } } else { MessageBox.Show("You can not add a reflexive inside of itself"); } } else { reflex.Chunks.Insert(refcount + 1, map.ChunkTools.ChunkClipBoard); // MessageBox.Show("Add chunks to reflexives not other chunks"); } return reflex; // reflex.chunkcount += map.ChunkTools.ChunkClipBoard.Chunks.Count; } else if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Chunk) { do { if (reflex.ChunkResources[refcount].type == Meta.ItemType.Reflexive) { // ((MetaSplitter.SplitReflexive)reflex.ChunkResources[refcount]).Chunks.Add(ChunkAdder.ChunkClipBoard); if (map.ChunkTools.ChunkClipBoard.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Chunk) { ((MetaSplitter.SplitReflexive)reflex.ChunkResources[refcount]).Chunks.Add( map.ChunkTools.ChunkClipBoard); } else { MessageBox.Show("Add reflexives to chunks not other reflexives"); } // reflex.chunkcount += map.ChunkTools.ChunkClipBoard.ChunkResources.Count; return reflex; } refcount++; } while (refcount != -1); } } if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Container) { reflex.Chunks[refcount] = FindSelectedNodeAndAdd(reflex.Chunks[refcount], node); refcount++; } else if (reflex.splitReflexiveType == MetaSplitter.SplitReflexive.SplitReflexiveType.Chunk) { do { if (reflex.ChunkResources[refcount].type == Meta.ItemType.Reflexive) { reflex.ChunkResources[refcount] = FindSelectedNodeAndAdd( (MetaSplitter.SplitReflexive)reflex.ChunkResources[refcount], node); refcount++; break; } refcount++; } while (refcount != -1); // refcount++; } } return reflex; }