/// <summary> /// Directory under which the stage is contained. /// </summary> /// <param name="StageDirectoryX">Subdirectory of the mod folder where the stage is contained.</param> public Feature_Inject_Stage(string StageDirectoryX) { // Get folder locations. Mod_Folder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); Heroes_Game_Directory = Environment.CurrentDirectory; StageDirectory = StageDirectoryX; // Get Stage Properties based off of level configuration. Read_Config_File(); // Read Original Memory Stuff. ASM_PushPointerTable_Old = Program.Sonic_Heroes_Process.ReadMemory((IntPtr)PUSH_INSTRUCTION_POINTER, 5); STAGE_START_ORIGINAL_BYTES = Program.Sonic_Heroes_Process.ReadMemory((IntPtr)STAGE_START_POSITION_POINTER + 4, 0x8C); STAGE_END_ORIGINAL_BYTES = Program.Sonic_Heroes_Process.ReadMemory((IntPtr)STAGE_END_POSITION_POINTER + 4, 0x64); // Get all trigger files and construct them. try { string[] TriggerFiles = Directory.GetFiles(Mod_Folder + "\\" + StageDirectory + "\\Triggers\\", "*.obj"); for (int x = 0; x < TriggerFiles.Length; x++) { FrameDelegates.Add(ConstructBox(TriggerFiles[x])); } } catch { } // No trigger files. // Get All Files & Construct All Splines. // If your stage has no splines, place one offscreen. string[] SplineFiles = Directory.GetFiles(Mod_Folder + "\\" + StageDirectory + "\\Splines\\", "*.obj"); for (int x = 0; x < SplineFiles.Length; x++) { SplineHeader Spline = ConstructSpline(SplineFiles[x]); WriteSpline(Spline); } // Generate Spline Pointer Table Generate_Pointer_Table(); // Backup Old Files BackupFiles(); }
/// <summary> /// Writes a spline onto game memory. /// </summary> /// <param name="Spline"></param> private void WriteSpline(SplineHeader Spline) { // Write Spline Vertices to Memory List <byte> VertexData = new List <byte>(); // Add data fo all vertices. for (int x = 0; x < Spline.Vertices.Count(); x++) { VertexData.AddRange(BitConverter.GetBytes(Spline.Vertices[x].UnknownFlags)); VertexData.AddRange(BitConverter.GetBytes(Spline.Vertices[x].DistanceToNextVertex)); VertexData.AddRange(BitConverter.GetBytes(Spline.Vertices[x].PositionX)); VertexData.AddRange(BitConverter.GetBytes(Spline.Vertices[x].PositionY)); VertexData.AddRange(BitConverter.GetBytes(Spline.Vertices[x].PositionZ)); } // Write Vertices to Memory Spline.Pointer_Vertex_List = (int)Program.Sonic_Heroes_Process.AllocateMemory(VertexData.Count); Program.Sonic_Heroes_Process.WriteMemory((IntPtr)Spline.Pointer_Vertex_List, VertexData.ToArray()); // Construct Header File and Add to Header List. List <byte> HeaderData = new List <byte>(); HeaderData.AddRange(BitConverter.GetBytes(Spline.Enabler)); HeaderData.AddRange(BitConverter.GetBytes(Spline.Number_Of_Vertices)); HeaderData.AddRange(BitConverter.GetBytes(Spline.Total_Spline_Length)); HeaderData.AddRange(BitConverter.GetBytes(Spline.Pointer_Vertex_List)); HeaderData.AddRange(BitConverter.GetBytes(Spline.Spline_Type)); // Add spline to pointer list. int SplineHeaderPointer = (int)Program.Sonic_Heroes_Process.AllocateMemory(HeaderData.Count); Program.Sonic_Heroes_Process.WriteMemory((IntPtr)SplineHeaderPointer, HeaderData.ToArray()); // Add Spline Header Pointer to List SplinePointers.Add(SplineHeaderPointer); }
/// <summary> /// Constructs a spline from scratch. /// </summary> /// <param name="SplinePath"></param> private SplineHeader ConstructSpline(string SplinePath) { SplineHeader SplineFile = new SplineHeader(); // Properties bool CalculateSplineDistanceFlag = false; float SplineVertexDistance = 0.0F; int SplineVertexFlags = 0; // Defaults SplineFile.Spline_Type = (int)Spline_Type.Autoloop; // Read Spline File List <HeroesVertexStruct> Vertices = new List <HeroesVertexStruct>(); // List of vertices for spline. string[] OBJ_File = File.ReadAllLines(SplinePath); // Read all of the lines. string[] Vertex_XYZ; // Used when splitting current lines of OBJ Files. // Iterate over all lines. for (int x = 0; x < OBJ_File.Length; x++) { try { string Value = OBJ_File[x].Substring(OBJ_File[x].IndexOf("=") + 1); // Check Spline Type if (OBJ_File[x].StartsWith("SPLINE_TYPE")) { if (Value == "Loop") { SplineFile.Spline_Type = (int)Spline_Type.Autoloop; } else if (Value == "Rail") { SplineFile.Spline_Type = (int)Spline_Type.Rail; } } else if (OBJ_File[x].StartsWith("SPLINE_VERTEX_FLAGS")) { SplineVertexFlags = Convert.ToInt32(Value, 16); } else if (OBJ_File[x].StartsWith("DISTANCE_TO_NEXT_POINT")) { if (Value == "Auto") { CalculateSplineDistanceFlag = true; } else { SplineVertexDistance = Convert.ToSingle(Value); } } else if (OBJ_File[x].StartsWith("v")) { // Remove spaces, place strings to array. Vertex_XYZ = OBJ_File[x].Split(' '); // Define a new Vertex. HeroesVertexStruct TempVertex; // Set Flags TempVertex.UnknownFlags = SplineVertexFlags; // Set Distance between Verts. if (!CalculateSplineDistanceFlag) { TempVertex.DistanceToNextVertex = SplineVertexDistance; } else { TempVertex.DistanceToNextVertex = 0.0F; } // Get coordinates. TempVertex.PositionX = Convert.ToSingle(Vertex_XYZ[1]); TempVertex.PositionY = Convert.ToSingle(Vertex_XYZ[2]); TempVertex.PositionZ = Convert.ToSingle(Vertex_XYZ[3]); Vertices.Add(TempVertex); } } catch { } } // Read all vertices. SplineFile.Vertices = Vertices; // Set properties SplineFile.Enabler = 1; SplineFile.Number_Of_Vertices = (ushort)SplineFile.Vertices.Count; // Calculate Distance to Next Vertex if Auto if (CalculateSplineDistanceFlag) { for (int x = 0; x < SplineFile.Vertices.Count; x++) { try { HeroesVertexStruct TempVertex = SplineFile.Vertices[x]; // Get the difference in current and location of next spline. float X_Delta_Position = SplineFile.Vertices[x].PositionX - SplineFile.Vertices[x + 1].PositionX; float Y_Delta_Position = SplineFile.Vertices[x].PositionY - SplineFile.Vertices[x + 1].PositionY; float Z_Delta_Position = SplineFile.Vertices[x].PositionZ - SplineFile.Vertices[x + 1].PositionZ; float Length_Squared = (X_Delta_Position * X_Delta_Position) + (Y_Delta_Position * Y_Delta_Position) + (Z_Delta_Position * Z_Delta_Position); TempVertex.DistanceToNextVertex = (float)Math.Sqrt(Length_Squared); SplineFile.Vertices[x] = TempVertex; } catch { } // Throws exception on last vertex, leaving it untouched. } } // Calculate Spline Length SplineFile.Total_Spline_Length = 0F; for (int x = 0; x < SplineFile.Vertices.Count; x++) { SplineFile.Total_Spline_Length += SplineFile.Vertices[x].DistanceToNextVertex; } return(SplineFile); }