public static void SetLocation(IExportEntry export, float x, float y, float z) { StructProperty prop = export.GetProperty <StructProperty>("location"); SetLocation(prop, x, y, z); export.WriteProperty(prop); }
public static Point3D GetLocation(IExportEntry export) { float x = 0, y = 0, z = int.MinValue; var prop = export.GetProperty <StructProperty>("location"); if (prop != null) { foreach (var locprop in prop.Properties) { switch (locprop) { case FloatProperty fltProp when fltProp.Name == "X": x = fltProp; break; case FloatProperty fltProp when fltProp.Name == "Y": y = fltProp; break; case FloatProperty fltProp when fltProp.Name == "Z": z = fltProp; break; } } return(new Point3D(x, y, z)); } return(null); }
private static void UpdateOffsets(IExportEntry export) { //update offsets for pcc-stored audio in wwisestreams if (export.ClassName == "WwiseStream" && export.GetProperty <NameProperty>("Filename") == null) { byte[] binData = export.getBinaryData(); binData.OverwriteRange(12, BitConverter.GetBytes(export.DataOffset + export.propsEnd() + 16)); export.setBinaryData(binData); } //update offsets for pcc-stored movies in texturemovies if (export.ClassName == "TextureMovie" && export.GetProperty <NameProperty>("TextureFileCacheName") == null) { byte[] binData = export.getBinaryData(); binData.OverwriteRange(12, BitConverter.GetBytes(export.DataOffset + export.propsEnd() + 16)); export.setBinaryData(binData); } //update offsets for pcc-stored mips in Textures else if (export.ClassName == "Texture2D" || export.ClassName == "LightMapTexture2D" || export.ClassName == "TextureFlipBook") { int baseOffset = export.DataOffset + export.propsEnd(); MemoryStream binData = new MemoryStream(export.getBinaryData()); for (int i = binData.ReadValueS32(); i > 0 && binData.Position < binData.Length; i--) { if (binData.ReadValueS32() == 0) //pcc-stored { int uncompressedSize = binData.ReadValueS32(); binData.Seek(4, SeekOrigin.Current); //skip compressed size binData.WriteValueS32(baseOffset + (int)binData.Position + 4); //update offset binData.Seek(uncompressedSize + 8, SeekOrigin.Current); //skip texture and width + height values } else { binData.Seek(20, SeekOrigin.Current);//skip whole rest of mip definition } } export.setBinaryData(binData.ToArray()); } }
/// <summary> /// Fetches the NavGuid object as a UnrealGUID /// </summary> /// <param name="export"></param> /// <returns></returns> public static UnrealGUID GetNavGUID(IExportEntry export) { StructProperty navGuid = export.GetProperty <StructProperty>("NavGuid"); if (navGuid != null) { return(new UnrealGUID(navGuid) { export = export }); } return(null); }
/// <summary> /// Fetches the NavGuid object as a UnrealGUID /// </summary> /// <param name="export"></param> /// <returns></returns> public static UnrealGUID GetNavGUID(IExportEntry export) { StructProperty navGuid = export.GetProperty <StructProperty>("NavGuid"); if (navGuid != null) { UnrealGUID guid = GetGUIDFromStruct(navGuid); guid.export = export; return(guid); } else { return(null); } }
public StaticMeshActorNode(int idx, float x, float y, IMEPackage p, PathingGraphEditor grapheditor) : base(idx, x, y, p, grapheditor) { ObjectProperty smc = export.GetProperty <ObjectProperty>("StaticMeshComponent"); if (smc != null) { IExportEntry smce = pcc.Exports[smc.Value - 1]; //smce.GetProperty<ObjectProperty>("St") var meshObj = smce.GetProperty <ObjectProperty>("StaticMesh"); if (meshObj != null) { IExportEntry sme = pcc.Exports[meshObj.Value - 1]; comment.Text = sme.ObjectName; } } }
public ReachSpecCreatorForm(IMEPackage package, int sourceExportIndex) { InitializeComponent(); specSizeCombobox.Items.Clear(); specSizeCombobox.Items.AddRange(PathfindingNodeInfoPanel.getDropdownItems().ToArray()); this.pcc = package; this.sourceExport = pcc.Exports[sourceExportIndex]; string sourceExportClass = sourceExport.ClassName; sourceNodeLabel.Text = "Export " + sourceExportIndex + " | " + sourceExportClass; //Get Source Location StructProperty locationProp = sourceExport.GetProperty <StructProperty>("location"); Unreal.PropertyCollection nodelocprops = locationProp.Properties; //X offset is 0x20 //Y offset is 0x24 //Z offset is 0x28 float sourceX = 0, sourceY = 0, sourceZ = 0; foreach (var locprop in nodelocprops) { switch (locprop.Name) { case "X": sourceX = Convert.ToInt32((locprop as FloatProperty).Value); break; case "Y": sourceY = Convert.ToInt32((locprop as FloatProperty).Value); break; case "Z": sourceZ = Convert.ToInt32((locprop as FloatProperty).Value); break; } } sourcePoint = new Point3D(sourceX, sourceY, sourceZ); reachSpecTypeComboBox.SelectedIndex = 0; specSizeCombobox.SelectedIndex = 1; StartPosition = FormStartPosition.CenterParent; }
public static void GenerateNewRandomGUID(IExportEntry export) { StructProperty guidProp = export.GetProperty <StructProperty>("NavGuid"); if (guidProp != null) { Random rnd = new Random(); IntProperty A = guidProp.GetProp <IntProperty>("A"); IntProperty B = guidProp.GetProp <IntProperty>("B"); IntProperty C = guidProp.GetProp <IntProperty>("C"); IntProperty D = guidProp.GetProp <IntProperty>("D"); byte[] data = export.Data; data.OverwriteRange((int)A.ValueOffset, BitConverter.GetBytes(rnd.Next())); data.OverwriteRange((int)B.ValueOffset, BitConverter.GetBytes(rnd.Next())); data.OverwriteRange((int)C.ValueOffset, BitConverter.GetBytes(rnd.Next())); data.OverwriteRange((int)D.ValueOffset, BitConverter.GetBytes(rnd.Next())); export.Data = data; } }
/// <summary> /// Gets a list of the reachspec exports listed in the PathList array property /// </summary> /// <param name="export">export to read PathList from</param> /// <returns></returns> internal static List <IExportEntry> GetReachspecExports(IExportEntry export) { var pathlist = export.GetProperty <ArrayProperty <ObjectProperty> >("PathList"); if (pathlist == null) { return(new List <IExportEntry>()); //nothing } var returnlist = new List <IExportEntry>(pathlist.Count); foreach (ObjectProperty prop in pathlist) { if (prop.Value > 0) { returnlist.Add(export.FileRef.getUExport(prop.Value)); } } return(returnlist); }
protected virtual string GetComment() { NameProperty tagProp = export.GetProperty<NameProperty>("Tag"); if (tagProp != null) { string name = tagProp.Value; if (name != export.ObjectName) { string retval = name; if (tagProp.Value.Number != 0) { retval += "_" + tagProp.Value.Number; } NodeTag = retval; return retval; } } return ""; }
public StaticMeshActorNode(int idx, float x, float y, IMEPackage p, PathingGraphEditor grapheditor) : base(idx, p, grapheditor) { string s = export.ObjectName; // = getType(s); float w = 50; float h = 50; shape = PPath.CreatePolygon(aShape); outlinePen = new Pen(color); shape.Pen = outlinePen; shape.Brush = actorNodeBrush; shape.Pickable = false; this.AddChild(shape); this.Bounds = new RectangleF(0, 0, w, h); val = new SText(idx.ToString()); val.Pickable = false; val.TextAlignment = StringAlignment.Center; val.X = w / 2 - val.Width / 2; val.Y = h / 2 - val.Height / 2; this.AddChild(val); this.TranslateBy(x, y); ObjectProperty smc = export.GetProperty <ObjectProperty>("StaticMeshComponent"); if (smc != null) { IExportEntry smce = pcc.Exports[smc.Value - 1]; //smce.GetProperty<ObjectProperty>("St") var meshObj = smce.GetProperty <ObjectProperty>("StaticMesh"); if (meshObj != null) { IExportEntry sme = pcc.Exports[meshObj.Value - 1]; comment.Text = sme.ObjectName; } } }
private void SetupJSON(IExportEntry export) { string objectName = System.Text.RegularExpressions.Regex.Replace(export.ObjectName, @"[<>:""/\\|?*]", ""); bool isClonedSeqRef = false; var defaultViewZoomProp = export.GetProperty<FloatProperty>("DefaultViewZoom"); if (defaultViewZoomProp != null && Math.Abs(defaultViewZoomProp.Value - CLONED_SEQREF_MAGIC) < 1.0E-30f) { isClonedSeqRef = true; } string packageFullName = export.PackageFullName; if (useGlobalSequenceRefSavesToolStripMenuItem.Checked && packageFullName.Contains("SequenceReference") && !isClonedSeqRef) { if (pcc.Game == MEGame.ME3) { JSONpath = ME3ViewsPath + packageFullName.Substring(packageFullName.LastIndexOf("SequenceReference")) + "." + objectName + ".JSON"; } else { string packageName = export.PackageFullName.Substring(export.PackageFullName.LastIndexOf("SequenceReference")); packageName = packageName.Replace("SequenceReference", ""); int idx = export.Index; string ObjName = ""; while (idx > 0) { if (pcc.getExport(pcc.getExport(idx).idxLink - 1).ClassName == "SequenceReference") { var objNameProp = pcc.getExport(idx).GetProperty<StrProperty>("ObjName"); if (objNameProp != null) { ObjName = objNameProp.Value; break; } } idx = pcc.getExport(idx).idxLink - 1; } if (objectName == "Sequence") { objectName = ObjName; packageName = "." + packageName; } else packageName = packageName.Replace("Sequence", ObjName) + "."; if (pcc.Game == MEGame.ME2) { JSONpath = ME2ViewsPath + "SequenceReference" + packageName + objectName + ".JSON"; } else { JSONpath = ME1ViewsPath + "SequenceReference" + packageName + objectName + ".JSON"; } } RefOrRefChild = true; } else { string viewsPath = ME3ViewsPath; if (pcc.Game == MEGame.ME2) { viewsPath = ME2ViewsPath; } else if (pcc.Game == MEGame.ME1) { viewsPath = ME1ViewsPath; } JSONpath = viewsPath + CurrentFile.Substring(CurrentFile.LastIndexOf(@"\") + 1) + ".#" + export.Index + objectName + ".JSON"; RefOrRefChild = false; } }
static void cloneSequence(IExportEntry exp, IExportEntry parentSequence) { IMEPackage pcc = exp.FileRef; if (exp.ClassName == "Sequence") { var seqObjs = exp.GetProperty<ArrayProperty<ObjectProperty>>("SequenceObjects"); if (seqObjs == null || seqObjs.Count == 0) { return; } //store original list of sequence objects; List<int> oldObjects = seqObjs.Select(x => x.Value).ToList(); //clear original sequence objects seqObjs.Clear(); exp.WriteProperty(seqObjs); //clone all children for (int i = 0; i < oldObjects.Count; i++) { cloneObject(oldObjects[i] - 1, exp, false); } //re-point children's links to new objects seqObjs = exp.GetProperty<ArrayProperty<ObjectProperty>>("SequenceObjects"); foreach (var seqObj in seqObjs) { IExportEntry obj = pcc.getExport(seqObj.Value - 1); var props = obj.GetProperties(); var outLinksProp = props.GetProp<ArrayProperty<StructProperty>>("OutputLinks"); if (outLinksProp != null) { foreach (var outLinkStruct in outLinksProp) { var links = outLinkStruct.GetProp<ArrayProperty<StructProperty>>("Links"); foreach (var link in links) { var linkedOp = link.GetProp<ObjectProperty>("LinkedOp"); linkedOp.Value = seqObjs[oldObjects.IndexOf(linkedOp.Value)].Value; } } } var varLinksProp = props.GetProp<ArrayProperty<StructProperty>>("VariableLinks"); if (varLinksProp != null) { foreach (var varLinkStruct in varLinksProp) { var links = varLinkStruct.GetProp<ArrayProperty<ObjectProperty>>("LinkedVariables"); foreach (var link in links) { link.Value = seqObjs[oldObjects.IndexOf(link.Value)].Value; } } } var eventLinksProp = props.GetProp<ArrayProperty<StructProperty>>("EventLinks"); if (eventLinksProp != null) { foreach (var eventLinkStruct in eventLinksProp) { var links = eventLinkStruct.GetProp<ArrayProperty<ObjectProperty>>("LinkedEvents"); foreach (var link in links) { link.Value = seqObjs[oldObjects.IndexOf(link.Value)].Value; } } } obj.WriteProperties(props); } //re-point sequence links to new objects int oldObj = 0; int newObj = 0; var propCollection = exp.GetProperties(); var inputLinksProp = propCollection.GetProp<ArrayProperty<StructProperty>>("InputLinks"); if (inputLinksProp != null) { foreach (var inLinkStruct in inputLinksProp) { var linkedOp = inLinkStruct.GetProp<ObjectProperty>("LinkedOp"); oldObj = linkedOp.Value; if (oldObj != 0) { newObj = seqObjs[oldObjects.IndexOf(oldObj)].Value; linkedOp.Value = newObj; NameProperty linkAction = inLinkStruct.GetProp<NameProperty>("LinkAction"); var nameRef = linkAction.Value; nameRef.count = pcc.getExport(newObj - 1).indexValue; linkAction.Value = nameRef; } } } var outputLinksProp = propCollection.GetProp<ArrayProperty<StructProperty>>("OutputLinks"); if (outputLinksProp != null) { foreach (var outLinkStruct in outputLinksProp) { var linkedOp = outLinkStruct.GetProp<ObjectProperty>("LinkedOp"); oldObj = linkedOp.Value; if (oldObj != 0) { newObj = seqObjs[oldObjects.IndexOf(oldObj)].Value; linkedOp.Value = newObj; NameProperty linkAction = outLinkStruct.GetProp<NameProperty>("LinkAction"); var nameRef = linkAction.Value; nameRef.count = pcc.getExport(newObj - 1).indexValue; linkAction.Value = nameRef; } } } exp.WriteProperties(propCollection); } else if (exp.ClassName == "SequenceReference") { //set OSequenceReference to new sequence var oSeqRefProp = exp.GetProperty<ObjectProperty>("oSequenceReference"); if (oSeqRefProp == null || oSeqRefProp.Value == 0) { return; } int oldSeqIndex = oSeqRefProp.Value; oSeqRefProp.Value = exp.UIndex + 1; exp.WriteProperty(oSeqRefProp); //clone sequence cloneObject(oldSeqIndex - 1, parentSequence, false); //remove cloned sequence from SeqRef's parent's sequenceobjects var seqObjs = parentSequence.GetProperty<ArrayProperty<ObjectProperty>>("SequenceObjects"); seqObjs.RemoveAt(seqObjs.Count - 1); parentSequence.WriteProperty(seqObjs); //set SequenceReference's linked name indices List<int> inputIndices = new List<int>(); List<int> outputIndices = new List<int>(); IExportEntry newSequence = pcc.getExport(exp.Index + 1); var props = newSequence.GetProperties(); var inLinksProp = props.GetProp<ArrayProperty<StructProperty>>("InputLinks"); if (inLinksProp != null) { foreach (var inLink in inLinksProp) { inputIndices.Add(inLink.GetProp<NameProperty>("LinkAction").Value.count); } } var outLinksProp = props.GetProp<ArrayProperty<StructProperty>>("OutputLinks"); if (outLinksProp != null) { foreach (var outLinks in outLinksProp) { outputIndices.Add(outLinks.GetProp<NameProperty>("LinkAction").Value.count); } } props = exp.GetProperties(); inLinksProp = props.GetProp<ArrayProperty<StructProperty>>("InputLinks"); if (inLinksProp != null) { for (int i = 0; i < inLinksProp.Count; i++) { NameProperty linkAction = inLinksProp[i].GetProp<NameProperty>("LinkAction"); var nameRef = linkAction.Value; nameRef.count = inputIndices[i]; linkAction.Value = nameRef; } } outLinksProp = props.GetProp<ArrayProperty<StructProperty>>("OutputLinks"); if (outLinksProp != null) { for (int i = 0; i < outLinksProp.Count; i++) { NameProperty linkAction = outLinksProp[i].GetProp<NameProperty>("LinkAction"); var nameRef = linkAction.Value; nameRef.count = outputIndices[i]; linkAction.Value = nameRef; } } exp.WriteProperties(props); //set new Sequence's link and ParentSequence prop to SeqRef newSequence.WriteProperty(new ObjectProperty(exp.UIndex, "ParentSequence")); newSequence.idxLink = exp.UIndex; //set DefaultViewZoom to magic number to flag that this is a cloned Sequence Reference and global saves cannot be used with it //ugly, but it should work newSequence.WriteProperty(new FloatProperty(CLONED_SEQREF_MAGIC, "DefaultViewZoom")); } }
public Bio2DA(IExportEntry export) { Console.WriteLine("Loading " + export.ObjectName); this.export = export; IMEPackage pcc = export.FileRef; byte[] data = export.Data; RowNames = new List <string>(); if (export.ClassName == "Bio2DA") { string rowLabelsVar = "m_sRowLabel"; var properties = export.GetProperties(); var props = export.GetProperty <ArrayProperty <NameProperty> >(rowLabelsVar); if (props != null) { foreach (NameProperty n in props) { RowNames.Add(n.ToString()); } } else { Console.WriteLine("Unable to find row names property!"); Debugger.Break(); return; } } else { string rowLabelsVar = "m_lstRowNumbers"; //Bio2DANumberedRows var props = export.GetProperty <ArrayProperty <IntProperty> >(rowLabelsVar); if (props != null) { foreach (IntProperty n in props) { RowNames.Add(n.Value.ToString()); } } else { Console.WriteLine("Unable to find row names property!"); Debugger.Break(); return; } } //Get Columns ColumnNames = new List <string>(); int colcount = BitConverter.ToInt32(data, data.Length - 4); int currentcoloffset = 0; while (colcount >= 0) { currentcoloffset += 4; int colindex = BitConverter.ToInt32(data, data.Length - currentcoloffset); currentcoloffset += 8; //names in this case don't use nameindex values. int nameindex = BitConverter.ToInt32(data, data.Length - currentcoloffset); string name = pcc.getNameEntry(nameindex); ColumnNames.Insert(0, name); colcount--; } Cells = new Bio2DACell[RowNames.Count(), ColumnNames.Count()]; currentcoloffset += 4; //column count. int infilecolcount = BitConverter.ToInt32(data, data.Length - currentcoloffset); //start of binary data int binstartoffset = export.propsEnd(); //arrayheader + nonenamesize + number of items in this list int curroffset = binstartoffset; int cellcount = BitConverter.ToInt32(data, curroffset); if (cellcount > 0) { curroffset += 4; for (int rowindex = 0; rowindex < RowNames.Count(); rowindex++) { for (int colindex = 0; colindex < ColumnNames.Count() && curroffset < data.Length - currentcoloffset; colindex++) { byte dataType = 255; dataType = data[curroffset]; curroffset++; int dataSize = dataType == Bio2DACell.TYPE_NAME ? 8 : 4; byte[] celldata = new byte[dataSize]; Buffer.BlockCopy(data, curroffset, celldata, 0, dataSize); Bio2DACell cell = new Bio2DACell(pcc, curroffset, dataType, celldata); Cells[rowindex, colindex] = cell; curroffset += dataSize; } } CellCount = RowNames.Count() * ColumnNames.Count(); } else { IsIndexed = true; curroffset += 4; //theres a 0 here for some reason cellcount = BitConverter.ToInt32(data, curroffset); curroffset += 4; //curroffset += 4; while (CellCount < cellcount) { int index = BitConverter.ToInt32(data, curroffset); int row = index / ColumnNames.Count(); int col = index % ColumnNames.Count(); curroffset += 4; byte dataType = data[curroffset]; int dataSize = dataType == Bio2DACell.TYPE_NAME ? 8 : 4; curroffset++; byte[] celldata = new byte[dataSize]; Buffer.BlockCopy(data, curroffset, celldata, 0, dataSize); Bio2DACell cell = new Bio2DACell(pcc, curroffset, dataType, celldata); Cells[row, col] = cell; CellCount++; curroffset += dataSize; } } Console.WriteLine("Finished loading " + export.ObjectName); }
public static void CreateReachSpec(IExportEntry startNode, bool createTwoWay, IExportEntry destinationNode, string reachSpecClass, ReachSpecSize size, PropertyCollection externalGUIDProperties = null) { IMEPackage Pcc = startNode.FileRef; IExportEntry reachSpectoClone = Pcc.Exports.FirstOrDefault(x => x.ClassName == "ReachSpec"); if (externalGUIDProperties != null) //EXTERNAL { //external node //Debug.WriteLine("Num Exports: " + pcc.Exports.Count); if (reachSpectoClone != null) { IExportEntry outgoingSpec = reachSpectoClone.Clone(); Pcc.addExport(outgoingSpec); IEntry reachSpecClassImp = GetEntryOrAddImport(Pcc, reachSpecClass); //new class type. outgoingSpec.idxClass = reachSpecClassImp.UIndex; outgoingSpec.idxObjectName = reachSpecClassImp.idxObjectName; var properties = outgoingSpec.GetProperties(); ObjectProperty outgoingSpecStartProp = properties.GetProp <ObjectProperty>("Start"); //START StructProperty outgoingEndStructProp = properties.GetProp <StructProperty>("End"); //Embeds END ObjectProperty outgoingSpecEndProp = outgoingEndStructProp.Properties.GetProp <ObjectProperty>(SharedPathfinding.GetReachSpecEndName(outgoingSpec)); //END outgoingSpecStartProp.Value = startNode.UIndex; outgoingSpecEndProp.Value = 0; var endGuid = outgoingEndStructProp.GetProp <StructProperty>("Guid"); endGuid.Properties = externalGUIDProperties; //set the other guid values to our guid values //Add to source node prop ArrayProperty <ObjectProperty> PathList = startNode.GetProperty <ArrayProperty <ObjectProperty> >("PathList"); PathList.Add(new ObjectProperty(outgoingSpec.UIndex)); startNode.WriteProperty(PathList); outgoingSpec.WriteProperties(properties); //Write Spec Size SharedPathfinding.SetReachSpecSize(outgoingSpec, size.SpecRadius, size.SpecHeight); //Reindex reachspecs. SharedPathfinding.ReindexMatchingObjects(outgoingSpec); } } else { //Debug.WriteLine("Source Node: " + startNode.Index); //Debug.WriteLine("Num Exports: " + pcc.Exports.Count); //int outgoingSpec = pcc.ExportCount; //int incomingSpec = pcc.ExportCount + 1; if (reachSpectoClone != null) { IExportEntry outgoingSpec = reachSpectoClone.Clone(); Pcc.addExport(outgoingSpec); IExportEntry incomingSpec = null; if (createTwoWay) { incomingSpec = reachSpectoClone.Clone(); Pcc.addExport(incomingSpec); } IEntry reachSpecClassImp = GetEntryOrAddImport(Pcc, reachSpecClass); //new class type. outgoingSpec.idxClass = reachSpecClassImp.UIndex; outgoingSpec.idxObjectName = reachSpecClassImp.idxObjectName; var outgoingSpecProperties = outgoingSpec.GetProperties(); if (reachSpecClass == "Engine.SlotToSlotReachSpec") { outgoingSpecProperties.Add(new ByteProperty(1, "SpecDirection")); //We might need to find a way to support this edit } //Debug.WriteLine("Outgoing UIndex: " + outgoingSpecExp.UIndex); ObjectProperty outgoingSpecStartProp = outgoingSpecProperties.GetProp <ObjectProperty>("Start"); //START StructProperty outgoingEndStructProp = outgoingSpecProperties.GetProp <StructProperty>("End"); //Embeds END ObjectProperty outgoingSpecEndProp = outgoingEndStructProp.Properties.GetProp <ObjectProperty>(SharedPathfinding.GetReachSpecEndName(outgoingSpec)); //END outgoingSpecStartProp.Value = startNode.UIndex; outgoingSpecEndProp.Value = destinationNode.UIndex; //Add to source node prop var PathList = startNode.GetProperty <ArrayProperty <ObjectProperty> >("PathList"); PathList.Add(new ObjectProperty(outgoingSpec.UIndex)); startNode.WriteProperty(PathList); //Write Spec Size SetReachSpecSize(outgoingSpecProperties, size.SpecRadius, size.SpecHeight); outgoingSpec.WriteProperties(outgoingSpecProperties); if (createTwoWay) { incomingSpec.idxClass = reachSpecClassImp.UIndex; incomingSpec.idxObjectName = reachSpecClassImp.idxObjectName; var incomingSpecProperties = incomingSpec.GetProperties(); if (reachSpecClass == "Engine.SlotToSlotReachSpec") { incomingSpecProperties.Add(new ByteProperty(2, "SpecDirection")); } ObjectProperty incomingSpecStartProp = incomingSpecProperties.GetProp <ObjectProperty>("Start"); //START StructProperty incomingEndStructProp = incomingSpecProperties.GetProp <StructProperty>("End"); //Embeds END ObjectProperty incomingSpecEndProp = incomingEndStructProp.Properties.GetProp <ObjectProperty>(SharedPathfinding.GetReachSpecEndName(incomingSpec)); //END incomingSpecStartProp.Value = destinationNode.UIndex; //Uindex incomingSpecEndProp.Value = startNode.UIndex; //Add reachspec to destination node's path list (returning) var DestPathList = destinationNode.GetProperty <ArrayProperty <ObjectProperty> >("PathList"); DestPathList.Add(new ObjectProperty(incomingSpec.UIndex)); destinationNode.WriteProperty(DestPathList); //destNode.WriteProperty(DestPathList); SetReachSpecSize(incomingSpecProperties, size.SpecRadius, size.SpecHeight); incomingSpec.WriteProperties(incomingSpecProperties); } //Reindex reachspecs. SharedPathfinding.ReindexMatchingObjects(outgoingSpec); } } }
private void destinationNodeTextBox_TextChanged(object sender, EventArgs e) { int destIndex = -1; Int32.TryParse(destinationNodeTextBox.Text, out destIndex); if (destIndex >= 0 && destIndex < pcc.Exports.Count) { //Parse IExportEntry destExport = pcc.Exports[destIndex]; float destX = 0, destY = 0, destZ = 0; StructProperty locationProp = destExport.GetProperty <StructProperty>("location"); if (locationProp != null) { Unreal.PropertyCollection nodelocprops = locationProp.Properties; //X offset is 0x20 //Y offset is 0x24 //Z offset is 0x28 foreach (var locprop in nodelocprops) { switch (locprop.Name) { case "X": destX = Convert.ToInt32((locprop as FloatProperty).Value); break; case "Y": destY = Convert.ToInt32((locprop as FloatProperty).Value); break; case "Z": destZ = Convert.ToInt32((locprop as FloatProperty).Value); break; } } Point3D destPoint = new Point3D(destX, destY, destZ); double distance = sourcePoint.getDistanceToOtherPoint(destPoint); //Calculate direction vectors if (distance != 0) { float dirX = (float)((destPoint.X - sourcePoint.X) / distance); float dirY = (float)((destPoint.Y - sourcePoint.Y) / distance); float dirZ = (float)((destPoint.Z - sourcePoint.Z) / distance); distanceLabel.Text = "Distance: " + distance.ToString("0.##"); directionX.Text = "X: " + dirX.ToString("0.#####"); directionY.Text = "Y: " + dirY.ToString("0.#####"); directionZ.Text = "Z: " + dirZ.ToString("0.#####"); destinationLabel.Text = "| " + destExport.ClassName; if ((string)reachSpecTypeComboBox.SelectedItem != "") { createSpecButton.Enabled = true; } } else { float dirX = (float)((destPoint.X - sourcePoint.X) / distance); float dirY = (float)((destPoint.Y - sourcePoint.Y) / distance); float dirZ = (float)((destPoint.Z - sourcePoint.Z) / distance); distanceLabel.Text = "Distance: 0 - move one of the nodes"; directionX.Text = "X: N/A"; directionY.Text = "Y: N/A"; directionZ.Text = "Z: N/A"; destinationLabel.Text = "| " + destExport.ClassName; createSpecButton.Enabled = false; } } } else { emptyAutoFields(); } }
public void LoadExport(IExportEntry export) { AllowChanges = false; this.export = export; reachableNodesList.Items.Clear(); reachSpecSizeSelector.Enabled = false; sfxCombatZoneList.Items.Clear(); combatZones = new List <int>(); reachSpecs = new List <int>(); var props = export.GetProperties(); exportTitleLabel.Text = export.ObjectName + "_" + export.indexValue; //Get Location StructProperty location = props.GetProp <StructProperty>("location"); if (location != null) { float x = location.GetProp <FloatProperty>("X"); float y = location.GetProp <FloatProperty>("Y"); float z = location.GetProp <FloatProperty>("Z"); xLabel.Text = "X: " + x; yLabel.Text = "Y: " + y; zLabel.Text = "Z: " + z; } else { xLabel.Text = "X: "; yLabel.Text = "Y: "; zLabel.Text = "Z: "; } //Calculate size StructProperty maxPathSize = props.GetProp <StructProperty>("MaxPathSize"); if (maxPathSize != null) { float height = maxPathSize.GetProp <FloatProperty>("Height"); float radius = maxPathSize.GetProp <FloatProperty>("Radius"); exportTitleLabel.Text += " - " + radius + "x" + height; pathNodeSizeComboBox.SelectedIndex = findClosestNextSizeIndex((int)radius, (int)height); pathNodeSizeComboBox.Enabled = true; } else { pathNodeSizeComboBox.Enabled = false; } //Calculate reachspecs ArrayProperty <ObjectProperty> PathList = props.GetProp <ArrayProperty <ObjectProperty> >("PathList"); if (PathList != null) { foreach (ObjectProperty prop in PathList) { IExportEntry outgoingSpec = export.FileRef.Exports[prop.Value - 1]; StructProperty outgoingEndStructProp = outgoingSpec.GetProperty <StructProperty>("End"); //Embeds END ObjectProperty outgoingSpecEndProp = outgoingEndStructProp.Properties.GetProp <ObjectProperty>("Actor"); //END if (outgoingSpecEndProp.Value - 1 > 0) { IExportEntry endNode = export.FileRef.Exports[outgoingSpecEndProp.Value - 1]; string targetNodeName = endNode.ObjectName + "_" + endNode.indexValue; reachableNodesList.Items.Add(endNode.Index + " " + targetNodeName + " via " + outgoingSpec.ObjectName + "_" + outgoingSpec.indexValue + " (" + outgoingSpec.Index + ")"); reachSpecs.Add(outgoingSpec.Index); } else { reachableNodesList.Items.Add("External File Node via " + outgoingSpec.ObjectName + "_" + outgoingSpec.indexValue + " (" + outgoingSpec.Index + ")"); reachSpecs.Add(outgoingSpec.Index); } } } //Calculate SFXCombatZones ArrayProperty <StructProperty> volumes = props.GetProp <ArrayProperty <StructProperty> >("Volumes"); if (volumes != null) { foreach (StructProperty volume in volumes) { ObjectProperty actorRef = volume.GetProp <ObjectProperty>("Actor"); if (actorRef != null && actorRef.Value > 0) { IExportEntry combatZoneExport = export.FileRef.Exports[actorRef.Value - 1]; combatZones.Add(combatZoneExport.Index); sfxCombatZoneList.Items.Add(combatZoneExport.ObjectName + "_" + combatZoneExport.indexValue + "(" + combatZoneExport.Index + ")"); } } } AllowChanges = true; }
/// <summary> /// Creates the reachspec connections from this pathfinding node to others. /// </summary> public override void CreateConnections(ref List <PathfindingNodeMaster> Objects) { var outLinksProp = export.GetProperty <ArrayProperty <ObjectProperty> >("PathList"); if (outLinksProp != null) { foreach (var prop in outLinksProp) { int reachspecexport = prop.Value; ReachSpecs.Add(pcc.Exports[reachspecexport - 1]); } foreach (IExportEntry spec in ReachSpecs) { Pen penToUse = halfReachSpecPen; switch (spec.ObjectName) { case "SlotToSlotReachSpec": penToUse = slotToSlotPen; break; case "SFXLadderReachSpec": penToUse = sfxLadderPen; break; case "SFXLargeBoostReachSpec": penToUse = sfxLargeBoostPen; break; case "SFXBoostReachSpec": penToUse = sfxBoostPen; break; case "SFXJumpDownReachSpec": penToUse = sfxJumpDownPen; break; } //Get ending PNode othernode = null; int othernodeidx = 0; PropertyCollection props = spec.GetProperties(); foreach (var prop in props) { if (prop.Name == "End") { PropertyCollection reachspecprops = (prop as StructProperty).Properties; foreach (var rprop in reachspecprops) { if (rprop.Name == "Actor") { othernodeidx = (rprop as ObjectProperty).Value; break; } } } } if (othernodeidx != 0) { foreach (PathfindingNodeMaster node in Objects) { if (node.export.UIndex == othernodeidx) { othernode = node; //Check for returning reachspec for pen drawing. This is going to incur a significant performance penalty... IExportEntry otherNode = node.export; var otherNodePathList = otherNode.GetProperty <ArrayProperty <ObjectProperty> >("PathList"); if (otherNodePathList != null) { bool keepParsing = true; foreach (var path in otherNodePathList) { int reachspecexport = path.Value; IExportEntry possibleIncomingSpec = pcc.Exports[reachspecexport - 1]; PropertyCollection otherSpecProperties = possibleIncomingSpec.GetProperties(); foreach (var otherSpecProp in otherSpecProperties) { if (otherSpecProp.Name == "End") { PropertyCollection reachspecprops = (otherSpecProp as StructProperty).Properties; foreach (var rprop in reachspecprops) { if (rprop.Name == "Actor") { othernodeidx = (rprop as ObjectProperty).Value; if (othernodeidx == export.UIndex) { keepParsing = false; if (penToUse == halfReachSpecPen) { penToUse = blackPen; } break; } } } } } if (!keepParsing) { break; } } break; } } } if (othernode != null) { IntProperty radius = props.GetProp <IntProperty>("CollisionRadius"); IntProperty height = props.GetProp <IntProperty>("CollisionHeight"); if (radius != null && height != null && (radius >= PathfindingNodeInfoPanel.MINIBOSS_RADIUS || height >= PathfindingNodeInfoPanel.MINIBOSS_HEIGHT)) { penToUse = (Pen)penToUse.Clone(); if (radius >= PathfindingNodeInfoPanel.BOSS_RADIUS && height >= PathfindingNodeInfoPanel.BOSS_HEIGHT) { penToUse.Width = 3; } else { penToUse.Width = 2; } } PPath edge = new PPath(); edge.Pen = penToUse; ((ArrayList)Tag).Add(edge); ((ArrayList)othernode.Tag).Add(edge); edge.Tag = new ArrayList(); ((ArrayList)edge.Tag).Add(this); ((ArrayList)edge.Tag).Add(othernode); g.edgeLayer.AddChild(edge); } } } } }
private bool calculateReachSpec(IExportEntry reachSpecExport, bool readOnly, IExportEntry startNodeExport = null) { //Get start and end exports. var properties = reachSpecExport.GetProperties(); ObjectProperty start = properties.GetProp <ObjectProperty>("Start"); StructProperty end = properties.GetProp <StructProperty>("End"); ObjectProperty endActorObj = end.GetProp <ObjectProperty>("Actor"); if (start.Value > 0 && endActorObj.Value > 0) { //We should capture GUID here IExportEntry startNode = reachSpecExport.FileRef.Exports[start.Value - 1]; IExportEntry endNode = reachSpecExport.FileRef.Exports[endActorObj.Value - 1]; if (startNodeExport != null && startNode.Index != startNodeExport.Index) { //ERROR! MessageBox.Show(reachSpecExport.Index + " " + reachSpecExport.ObjectName + " start does not match it's containing pathlist reference (" + startNodeExport.Index + " " + startNodeExport.ObjectName + ")"); } float startX = 0, startY = 0, startZ = 0; float destX = 0, destY = 0, destZ = 0; StructProperty startLocationProp = startNode.GetProperty <StructProperty>("location"); StructProperty endLocationProp = endNode.GetProperty <StructProperty>("location"); if (startLocationProp != null && endLocationProp != null) { startX = startLocationProp.GetProp <FloatProperty>("X"); startY = startLocationProp.GetProp <FloatProperty>("Y"); startZ = startLocationProp.GetProp <FloatProperty>("Z"); destX = endLocationProp.GetProp <FloatProperty>("X"); destY = endLocationProp.GetProp <FloatProperty>("Y"); destZ = endLocationProp.GetProp <FloatProperty>("Z"); Point3D startPoint = new Point3D(startX, startY, startZ); Point3D destPoint = new Point3D(destX, destY, destZ); double distance = startPoint.getDistanceToOtherPoint(destPoint); if (distance != 0) { float dirX = (float)((destPoint.X - startPoint.X) / distance); float dirY = (float)((destPoint.Y - startPoint.Y) / distance); float dirZ = (float)((destPoint.Z - startPoint.Z) / distance); //Get Original Values, for comparison. StructProperty specDirection = properties.GetProp <StructProperty>("Direction"); float origX = 0, origY = 0, origZ = 0; if (specDirection != null) { origX = specDirection.GetProp <FloatProperty>("X"); origY = specDirection.GetProp <FloatProperty>("Y"); origZ = specDirection.GetProp <FloatProperty>("Z"); IntProperty origDistanceProp = properties.GetProp <IntProperty>("Distance"); if (origDistanceProp != null) { int origDistance = origDistanceProp.Value; int calculatedProperDistance = RoundDoubleToInt(distance); int distanceDiff = Math.Abs(origDistance - calculatedProperDistance); ReachSpecUpdaterUIThreadOptions recalcOption = new ReachSpecUpdaterUIThreadOptions(reachSpecExport, calculatedProperDistance, dirX, dirY, dirZ); if (distanceDiff > MAX_DISTANCE_TOLERANCE) { // Difference. Debug.WriteLine("Diff Distance is > tolerance: " + distanceDiff + ", should be " + calculatedProperDistance); if (!readOnly) { worker.ReportProgress(-2, recalcOption); } return(true); } float diffX = origX - dirX; float diffY = origY - dirY; float diffZ = origZ - dirZ; if (Math.Abs(diffX) > MAX_DIRECTION_TOLERANCE) { // Difference. Debug.WriteLine("Diff Direction X is > tolerance: " + diffX + ", should be " + dirX); if (!readOnly) { worker.ReportProgress(-2, recalcOption); } return(true); } if (Math.Abs(diffY) > MAX_DIRECTION_TOLERANCE) { // Difference. Debug.WriteLine("Diff Direction Y is > tolerance: " + diffY + ", should be " + dirY); if (!readOnly) { worker.ReportProgress(-2, recalcOption); } return(true); } if (Math.Abs(diffZ) > MAX_DIRECTION_TOLERANCE) { // Difference. Debug.WriteLine("Diff Direction Z is > tolerance: " + diffZ + ", should be " + dirZ); if (!readOnly) { worker.ReportProgress(-2, recalcOption); } return(true); } return(false); } } } } } //We really shouldn't reach here, hopefully. return(false); }
public void GetObjects(IExportEntry export) { CurrentObjects = new List<int>(); listBox1.Items.Clear(); var seqObjs = export.GetProperty<ArrayProperty<ObjectProperty>>("SequenceObjects"); if (seqObjs != null) foreach (ObjectProperty seqObj in seqObjs) { int m = seqObj.Value - 1; CurrentObjects.Add(m); listBox1.Items.Add("#" + m + " :" + pcc.getExport(m).ObjectName + " class: " + pcc.getExport(m).ClassName); } }
static void addObjectToSequence(int index, bool removeLinks, IExportEntry sequenceExport) { var seqObjs = sequenceExport.GetProperty<ArrayProperty<ObjectProperty>>("SequenceObjects"); if (seqObjs != null) { seqObjs.Add(new ObjectProperty(index + 1)); sequenceExport.WriteProperty(seqObjs); PropertyCollection props = sequenceExport.GetProperties(); IExportEntry newObject = sequenceExport.FileRef.getExport(index); PropertyCollection newObjectProps = newObject.GetProperties(); newObjectProps.AddOrReplaceProp(new ObjectProperty(sequenceExport.UIndex, "ParentSequence")); if (removeLinks) { var outLinksProp = newObjectProps.GetProp<ArrayProperty<StructProperty>>("OutputLinks"); if (outLinksProp != null) { foreach (var prop in outLinksProp) { prop.GetProp<ArrayProperty<StructProperty>>("Links").Clear(); } } var varLinksProp = newObjectProps.GetProp<ArrayProperty<StructProperty>>("VariableLinks"); if (varLinksProp != null) { foreach (var prop in varLinksProp) { prop.GetProp<ArrayProperty<ObjectProperty>>("LinkedVariables").Clear(); } } } newObject.WriteProperties(newObjectProps); newObject.idxLink = sequenceExport.UIndex; } }
private void populateDuplicateGUIDs() { navGuidLists = new Dictionary <string, List <UnrealGUID> >(); duplicateGuids = new List <UnrealGUID>(); IExportEntry level = null; foreach (IExportEntry exp in pcc.Exports) { if (exp.ClassName == "Level" && exp.ObjectName == "PersistentLevel") { level = exp; break; } } int start = 0x4; if (level != null) { start = PathfindingEditor.findEndOfProps(level); } //Read persistent level binary byte[] data = level.Data; uint exportid = BitConverter.ToUInt32(data, start); start += 4; uint numberofitems = BitConverter.ToUInt32(data, start); int countoffset = start; int itemcount = 2; start += 8; while (itemcount < numberofitems) { //get header. uint itemexportid = BitConverter.ToUInt32(data, start); if (itemexportid - 1 < pcc.Exports.Count && itemexportid > 0) { IExportEntry exportEntry = pcc.Exports[(int)itemexportid - 1]; StructProperty navguid = exportEntry.GetProperty <StructProperty>("NavGuid"); if (navguid != null) { int a = navguid.GetProp <IntProperty>("A"); int b = navguid.GetProp <IntProperty>("B"); int c = navguid.GetProp <IntProperty>("C"); int d = navguid.GetProp <IntProperty>("D"); UnrealGUID nav = new UnrealGUID(); nav.A = a; nav.B = b; nav.C = c; nav.D = d; nav.export = exportEntry; nav.levelListIndex = itemcount; List <UnrealGUID> list; if (navGuidLists.TryGetValue(nav.ToString(), out list)) { list.Add(nav); } else { list = new List <UnrealGUID>(); navGuidLists[nav.ToString()] = list; list.Add(nav); } } start += 4; itemcount++; } else { //INVALID or empty item encountered. We don't care right now though. start += 4; itemcount++; } } duplicatesListBox.Items.Clear(); foreach (List <UnrealGUID> guidList in navGuidLists.Values) { if (guidList.Count > 1) { Debug.WriteLine("Number of duplicates: " + guidList.Count); //contains duplicates foreach (UnrealGUID guid in guidList) { //Debug.WriteLine(guid.levelListIndex + " Duplicate: " + guid.export.ObjectName); duplicateGuids.Add(guid); duplicatesListBox.Items.Add(guid.levelListIndex + " " + guid.export.Index + " " + guid.export.ObjectName + "_" + guid.export.indexValue); } } else { Debug.WriteLine("Not a duplicate "); } } }