diff --git a/ME3Explorer/BinaryInterpreter/BinaryInterpreter.cs b/ME3Explorer/BinaryInterpreter/BinaryInterpreter.cs index 5a7b5d715..f4f356ac6 100644 --- a/ME3Explorer/BinaryInterpreter/BinaryInterpreter.cs +++ b/ME3Explorer/BinaryInterpreter/BinaryInterpreter.cs @@ -117,7 +117,7 @@ public enum nodeType int? selectedNodePos = null; - public static readonly string[] ParsableBinaryClasses = { "Level", "StaticMeshCollectionActor", "Class", "Material", "StaticMesh", "MaterialInstanceConstant", "StaticMeshComponent", "SkeletalMeshComponent", "SkeletalMesh", "Model", "Polys" }; //classes that have binary parse code + public static readonly string[] ParsableBinaryClasses = { "Level", "StaticMeshCollectionActor", "Class", "WwiseEvent", "Material", "StaticMesh", "MaterialInstanceConstant", "BioDynamicAnimSet", "StaticMeshComponent", "SkeletalMeshComponent", "SkeletalMesh", "Model", "Polys" }; //classes that have binary parse code public BinaryInterpreter() @@ -257,6 +257,12 @@ private void StartScan(string topNodeName = null, string selectedNodeName = null case "Material": StartMaterialScan(); break; + case "BioDynamicAnimSet": + StartBioDynamicAnimSetScan(); + break; + case "WwiseEvent": + StartWWiseEventScan(); + break; default: StartGenericScan(); break; @@ -279,6 +285,154 @@ private void StartScan(string topNodeName = null, string selectedNodeName = null } } + private void StartWWiseEventScan(string nodeNameToSelect = null) + { + resetPropEditingControls(); + treeView1.BeginUpdate(); + treeView1.Nodes.Clear(); + addPropButton.Visible = false; + + byte[] data = export.Data; + + int binarystart = findEndOfProps(); + //find start of class binary (end of props). This should + TreeNode topLevelTree = new TreeNode("0000 : " + export.ObjectName); + topLevelTree.Tag = nodeType.Root; + topLevelTree.Name = "0"; + try + { + int binarypos = binarystart; + List subnodes = new List(); + int count = BitConverter.ToInt32(data, binarypos); + TreeNode node = new TreeNode("0x" + binarypos.ToString("X4") + " Count: " + count.ToString()); + subnodes.Add(node); + binarypos += 4; //+ int + if (count > 0) + { + string nodeText = "0x" + binarypos.ToString("X4") + " "; + int val = BitConverter.ToInt32(data, binarypos); + string name = val.ToString(); + if (val > 0 && val <= pcc.Exports.Count) + { + IExportEntry exp = pcc.Exports[val - 1]; + nodeText += name + " " + exp.PackageFullName + "." + exp.ObjectName + " (" + exp.ClassName + ")"; + } + else if (val < 0 && val != int.MinValue && Math.Abs(val) <= pcc.Imports.Count) + { + int csImportVal = Math.Abs(val) - 1; + ImportEntry imp = pcc.Imports[csImportVal]; + nodeText += name + " " + imp.PackageFullName + "." + imp.ObjectName + " (" + imp.ClassName + ")"; + } + + node = new TreeNode(nodeText); + node.Tag = nodeType.StructLeafObject; + node.Name = binarypos.ToString(); + subnodes.Add(node); + /* + + int objectindex = BitConverter.ToInt32(data, binarypos); + IEntry obj = pcc.getEntry(objectindex); + string nodeValue = obj.GetFullPath; + node.Tag = nodeType.StructLeafObject; + */ + } + topLevelTree.Nodes.AddRange(subnodes.ToArray()); + } + catch (Exception ex) + { + topLevelTree.Nodes.Add("An error occured parsing the wwiseevent: " + ex.Message); + } + treeView1.Nodes.Add(topLevelTree); + treeView1.CollapseAll(); + treeView1.Nodes[0].Expand(); + TreeNode[] nodes; + if (nodeNameToSelect != null) + { + nodes = treeView1.Nodes.Find(nodeNameToSelect, true); + if (nodes.Length > 0) + { + treeView1.SelectedNode = nodes[0]; + } + else + { + treeView1.SelectedNode = treeView1.Nodes[0]; + } + } + + treeView1.EndUpdate(); + memsize = memory.Length; + } + + private void StartBioDynamicAnimSetScan(string nodeNameToSelect = null) + { + resetPropEditingControls(); + treeView1.BeginUpdate(); + treeView1.Nodes.Clear(); + addPropButton.Visible = false; + + byte[] data = export.Data; + + int binarystart = findEndOfProps(); + //find start of class binary (end of props). This should + + + + TreeNode topLevelTree = new TreeNode("0000 : " + export.ObjectName); + topLevelTree.Tag = nodeType.Root; + topLevelTree.Name = "0"; + try + { + int binarypos = binarystart; + List subnodes = new List(); + int count = BitConverter.ToInt32(data, binarypos); + TreeNode node = new TreeNode("0x" + binarypos.ToString("X4") + " Count: " + count.ToString()); + subnodes.Add(node); + binarypos += 4; //+ int + for (int i = 0; i < count; i++) + { + int nameIndex = BitConverter.ToInt32(data, binarypos); + int nameIndexNum = BitConverter.ToInt32(data, binarypos + 4); + int shouldBe1 = BitConverter.ToInt32(data, binarypos + 8); + string nodeValue = pcc.Names[nameIndex] + "_" + nameIndexNum; + if (shouldBe1 != 1) + { + //ERROR + nodeValue += " - Not followed by 1 (integer)!"; + } + + node = new TreeNode("0x" + binarypos.ToString("X4") + " Name: " + nodeValue); + node.Tag = nodeType.StructLeafName; + node.Name = binarypos.ToString(); + subnodes.Add(node); + binarypos += 12; + } + topLevelTree.Nodes.AddRange(subnodes.ToArray()); + } + catch (Exception ex) + { + topLevelTree.Nodes.Add("An error occured parsing the biodynamicanimset: " + ex.Message); + } + treeView1.Nodes.Add(topLevelTree); + treeView1.CollapseAll(); + treeView1.Nodes[0].Expand(); + TreeNode[] nodes; + if (nodeNameToSelect != null) + { + nodes = treeView1.Nodes.Find(nodeNameToSelect, true); + if (nodes.Length > 0) + { + treeView1.SelectedNode = nodes[0]; + } + else + { + treeView1.SelectedNode = treeView1.Nodes[0]; + } + } + + treeView1.EndUpdate(); + memsize = memory.Length; + } + private void StartGenericScan(string nodeNameToSelect = null) { resetPropEditingControls(); @@ -1328,8 +1482,14 @@ private void TryParseStructPropertyOrArrayLeaf(TreeNode node) { nodeType type = (nodeType)node.Tag; int pos = (int)hb1.SelectionStart; - if (memory.Length - pos < 8) + if (memory.Length - pos < 4 && type == nodeType.StructLeafObject) + { return; + } + else if (memory.Length - pos < 8 && type != nodeType.StructLeafObject) + { + return; + } switch (type) { case nodeType.ArrayLeafInt: diff --git a/ME3Explorer/Pathfinding Editor/PathfindingEditor.cs b/ME3Explorer/Pathfinding Editor/PathfindingEditor.cs index 807aa6c63..2114fb734 100644 --- a/ME3Explorer/Pathfinding Editor/PathfindingEditor.cs +++ b/ME3Explorer/Pathfinding Editor/PathfindingEditor.cs @@ -67,7 +67,7 @@ public partial class PathfindingEditor : WinFormsBase public static Dictionary> importclassdb = new Dictionary>(); //SFXGame.Default__SFXEnemySpawnPoint -> class, packagefile (can infer link and name) public static Dictionary> exportclassdb = new Dictionary>(); //SFXEnemy SpawnPoint -> class, name, ...etc - public string[] pathfindingNodeClasses = { "PathNode", "SFXEnemySpawnPoint", "MantleMarker", "SFXNav_InteractionHenchOmniToolCrouch", "BioPathPoint", "SFXNav_LargeBoostNode", "SFXNav_LargeMantleNode", "SFXNav_InteractionStandGuard", "SFXNav_TurretPoint", "CoverLink", "SFXDynamicCoverLink", "SFXDynamicCoverSlotMarker", "SFXNav_SpawnEntrance", "SFXNav_LadderNode", "SFXDoorMarker", "SFXNav_JumpNode", "SFXNav_JumpDownNode", "NavigationPoint", "CoverSlotMarker", "SFXOperation_ObjectiveSpawnPoint", "SFXNav_BoostNode", "SFXNav_LargeClimbNode", "SFXNav_LargeMantleNode", "SFXNav_ClimbWallNode", "WwiseAmbientSound", "SFXNav_InteractionHenchOmniTool", "SFXNav_InteractionHenchOmniToolCrouch", "SFXNav_InteractionHenchBeckonFront", "SFXNav_InteractionHenchBeckonRear", "SFXNav_InteractionHenchCustom", "SFXNav_InteractionHenchCover", "SFXNav_InteractionHenchCrouch", "SFXNav_InteractionHenchInteractLow", "SFXNav_InteractionHenchManual", "SFXNav_InteractionHenchStandIdle", "SFXNav_InteractionHenchStandTyping", "SFXNav_InteractionUseConsole", "SFXNav_InteractionStandGuard" }; + public string[] pathfindingNodeClasses = { "PathNode", "SFXEnemySpawnPoint", "PathNode_Dynamic", "MantleMarker", "SFXNav_InteractionHenchOmniToolCrouch", "BioPathPoint", "SFXNav_LargeBoostNode", "SFXNav_LargeMantleNode", "SFXNav_InteractionStandGuard", "SFXNav_TurretPoint", "CoverLink", "SFXDynamicCoverLink", "SFXDynamicCoverSlotMarker", "SFXNav_SpawnEntrance", "SFXNav_LadderNode", "SFXDoorMarker", "SFXNav_JumpNode", "SFXNav_JumpDownNode", "NavigationPoint", "CoverSlotMarker", "SFXOperation_ObjectiveSpawnPoint", "SFXNav_BoostNode", "SFXNav_LargeClimbNode", "SFXNav_LargeMantleNode", "SFXNav_ClimbWallNode", "WwiseAmbientSound", "SFXNav_InteractionHenchOmniTool", "SFXNav_InteractionHenchOmniToolCrouch", "SFXNav_InteractionHenchBeckonFront", "SFXNav_InteractionHenchBeckonRear", "SFXNav_InteractionHenchCustom", "SFXNav_InteractionHenchCover", "SFXNav_InteractionHenchCrouch", "SFXNav_InteractionHenchInteractLow", "SFXNav_InteractionHenchManual", "SFXNav_InteractionHenchStandIdle", "SFXNav_InteractionHenchStandTyping", "SFXNav_InteractionUseConsole", "SFXNav_InteractionStandGuard" }; public string[] actorNodeClasses = { "BlockingVolume", "StaticMeshActor", "InterpActor", "SFXDoor", "BioTriggerVolume", "SFXPlaceable_Generator", "SFXPlaceable_ShieldGenerator", "SFXBlockingVolume_Ledge", "SFXAmmoContainer", "SFXGrenadeContainer", "SFXCombatZone", "BioStartLocation", "BioStartLocationMP", "SFXStuntActor", "SkeletalMeshActor" }; public string[] ignoredobjectnames = { "PREFAB_Ladders_3M_Arc0", "PREFAB_Ladders_3M_Arc1" }; //These come up as parsed classes but aren't actually part of the level, only prefabs. They should be ignored public bool ActorNodesActive = false; @@ -656,6 +656,9 @@ public void LoadObject(int index) case "BioPathPoint": pathNode = new PathfindingNodes.BioPathPoint(index, x, y, pcc, graphEditor); break; + case "PathNode_Dynamic": + pathNode = new PathfindingNodes.PathNode_Dynamic(index, x, y, pcc, graphEditor); + break; case "SFXNav_LargeBoostNode": pathNode = new PathfindingNodes.SFXNav_LargeBoostNode(index, x, y, pcc, graphEditor); break; diff --git a/ME3Explorer/Pathfinding Editor/PathfindingNodeMaster.cs b/ME3Explorer/Pathfinding Editor/PathfindingNodeMaster.cs index 39c15003e..69c40fad5 100644 --- a/ME3Explorer/Pathfinding Editor/PathfindingNodeMaster.cs +++ b/ME3Explorer/Pathfinding Editor/PathfindingNodeMaster.cs @@ -34,6 +34,7 @@ public abstract class PathfindingNodeMaster : PNode protected static Brush actorNodeBrush = new SolidBrush(Color.FromArgb(80, 80, 80)); protected static Brush pathfindingNodeBrush = new SolidBrush(Color.FromArgb(140, 140, 140)); protected static Brush dynamicPathfindingNodeBrush = new SolidBrush(Color.FromArgb(46, 184, 25)); + protected static Brush dynamicPathnodefindingNodeBrush = new SolidBrush(Color.FromArgb(80, 184, 25)); protected static Pen selectedPen = new Pen(Color.FromArgb(255, 255, 0)); diff --git a/ME3Explorer/Pathfinding Editor/PathfindingNodes.cs b/ME3Explorer/Pathfinding Editor/PathfindingNodes.cs index eaf61c237..83b92cfc3 100644 --- a/ME3Explorer/Pathfinding Editor/PathfindingNodes.cs +++ b/ME3Explorer/Pathfinding Editor/PathfindingNodes.cs @@ -314,6 +314,15 @@ public BioPathPoint(int idx, float x, float y, IMEPackage p, PathingGraphEditor } } //SFXDynamicCoverLink, SFXDynamicCoverSlotMarker + public class PathNode_Dynamic : PathNode + { + public PathNode_Dynamic(int idx, float x, float y, IMEPackage p, PathingGraphEditor grapheditor) + : base(idx, x, y, p, grapheditor) + { + shape.Brush = dynamicPathnodefindingNodeBrush; + } + } //SFXDynamicCoverLink, SFXDynamicCoverSlotMarker + public class CoverLink : PathfindingNode { public VarTypes type { get; set; }