diff --git a/BaseHandlers/BaseHandlers.csproj b/BaseHandlers/BaseHandlers.csproj
index 0df59b0..0754107 100644
--- a/BaseHandlers/BaseHandlers.csproj
+++ b/BaseHandlers/BaseHandlers.csproj
@@ -42,6 +42,7 @@
+
@@ -55,6 +56,12 @@
+
+ Form
+
+
+ TriggerDataEditor.cs
+
@@ -116,6 +123,9 @@
InstanceListEditor.cs
+
+ TriggerDataEditor.cs
+
diff --git a/BaseHandlers/TriggerData.cs b/BaseHandlers/TriggerData.cs
index d5254e9..22ec201 100644
--- a/BaseHandlers/TriggerData.cs
+++ b/BaseHandlers/TriggerData.cs
@@ -1,405 +1,798 @@
-using BundleFormat;
+using BundleFormat;
using BundleUtilities;
using PluginAPI;
using System;
using System.Collections.Generic;
+using System.ComponentModel;
+using System.ComponentModel.Design;
+using System.Drawing.Design;
using System.IO;
using System.Linq;
+using System.Windows.Forms;
namespace BaseHandlers
{
- public struct LandmarkTrigger
+ class DescriptiveCollectionEditor : CollectionEditor
{
- public float PositionX;
- public float PositionY;
- public float PositionZ;
- public float RotationX;
- public float RotationY;
- public float RotationZ;
- public float SizeX;
- public float SizeY;
- public float SizeZ;
- public int GameDBID;
- public short GlobalIndex;
- public byte Type; // Should be 0
- public byte UnknownByte2B;
- public uint UnknownOffset;
- public byte UnknownByte30;
- public byte LocalIndex;
- public byte Subtype;
- public byte UnknownByte33;
-
- public override string ToString() => $"ID {GameDBID}";
+ public DescriptiveCollectionEditor(Type type) : base(type) { }
+ protected override CollectionForm CreateCollectionForm()
+ {
+ CollectionForm form = base.CreateCollectionForm();
+ form.Shown += delegate
+ {
+ ShowDescription(form);
+ };
+ return form;
+ }
+ static void ShowDescription(Control control)
+ {
+ PropertyGrid grid = control as PropertyGrid;
+ if (grid != null) grid.HelpVisible = true;
+ foreach (Control child in control.Controls)
+ {
+ ShowDescription(child);
+ }
+ }
}
+ public class CgsID
+ {
+ private UInt64 m_id = 0;
- public struct GenericRegionTrigger
+ public UInt64 ID
+ {
+ get { return m_id; }
+ set { m_id = value; }
+ }
+
+ public static CgsID FromByteArray(byte[] data, int startIndex)
+ {
+ UInt64 id = BitConverter.ToUInt64(data, startIndex);
+ CgsID result = new CgsID();
+ result.ID = id;
+ return new CgsID();
+ }
+
+ public byte[] ToByteArray()
+ {
+ return BitConverter.GetBytes(m_id);
+ }
+
+ public void Read(BinaryReader reader)
+ {
+ m_id = reader.ReadUInt64();
+ }
+
+ public void Write(BinaryWriter writer)
+ {
+ writer.Write(m_id);
+ }
+
+ public override string ToString()
+ {
+ return string.Format("{0:X16}", m_id);
+ }
+ }
+ public enum RegionType
{
- public float PositionX;
- public float PositionY;
- public float PositionZ;
- public float RotationX;
- public float RotationY;
- public float RotationZ;
- public float SizeX;
- public float SizeY;
- public float SizeZ;
- public int GameDBID;
- public short Index;
- public byte Type; // Should be 2
- public byte UnknownByte2B;
- public int GameDBID2; // Only used for _some_ super jumps
- public short UnknownShort30;
- public short UnknownShort32;
- public byte UnknownByte34;
- public byte UnknownByte35;
- public byte Subtype;
- public byte UnknownByte37; // most, but not all, super jumps have this set (to 1)
-
- public override string ToString() => $"ID {GameDBID}";
+ E_TYPE_LANDMARK = 0,
+ E_TYPE_BLACKSPOT = 1,
+ E_TYPE_GENERIC_REGION = 2,
+ E_TYPE_VFXBOX_REGION = 3
}
- public struct TriggerSection4Entry
+ public class StartingGrid
{
- public uint TriggerOffsetListOffset;
- public int TriggerOffsetListCount;
- public uint GameDBIDListOffset;
- public int GameDBIDListCount;
+ public List StartingPositions { get; set; } = new List();
+ public List StartingDirections { get; set; } = new List();
+
+ public void Read(BinaryReader reader)
+ {
+ StartingPositions = new List(8);
+ for (int i = 0; i < 8; i++)
+ {
+ StartingPositions[i] = new Vector3I(
+ reader.ReadSingle(),
+ reader.ReadSingle(),
+ reader.ReadSingle(), reader.ReadSingle());
+ }
+
+ StartingDirections = new List(8);
+ for (int i = 0; i < 8; i++)
+ {
+ StartingDirections[i] = new Vector3I(
+ reader.ReadSingle(),
+ reader.ReadSingle(),
+ reader.ReadSingle(), reader.ReadSingle());
+ }
+ }
+
+ public void Write(BinaryWriter writer)
+ {
+ for (int i = 0; i < 8; i++)
+ {
+ writer.Write(StartingPositions[i].X);
+ writer.Write(StartingPositions[i].Y);
+ writer.Write(StartingPositions[i].Z);
+ writer.Write(StartingPositions[i].S);
+ }
- public List Triggers;
- public List GameDBIDs;
+ for (int i = 0; i < 8; i++)
+ {
+ writer.Write(StartingDirections[i].X);
+ writer.Write(StartingDirections[i].Y);
+ writer.Write(StartingDirections[i].Z);
+ writer.Write(StartingDirections[i].S);
+ }
+ }
}
- public struct RoamingLocation
+ public class BoxRegion
{
- public float PositionX;
- public float PositionY;
- public float PositionZ;
- public uint UnknownHash;
- public byte Subdistrict;
- public byte UnknownByte11;
- public byte UnknownByte12;
- public byte UnknownByte13;
- public int UnknownInt14;
- public int UnknownInt18;
- public int UnknownInt1C;
+ public float PositionX { get; set; } = 0;
+ public float PositionY { get; set; } = 0;
+ public float PositionZ { get; set; } = 0;
+ public float RotationX { get; set; } = 0;
+ public float RotationY { get; set; } = 0;
+ public float RotationZ { get; set; } = 0;
+ public float DimensionX { get; set; } = 0;
+ public float DimensionY { get; set; } = 0;
+ public float DimensionZ { get; set; } = 0;
+
+ public void Read(BinaryReader reader)
+ {
+ PositionX = reader.ReadSingle();
+ PositionY = reader.ReadSingle();
+ PositionZ = reader.ReadSingle();
+ RotationX = reader.ReadSingle();
+ RotationY = reader.ReadSingle();
+ RotationZ = reader.ReadSingle();
+ DimensionX = reader.ReadSingle();
+ DimensionY = reader.ReadSingle();
+ DimensionZ = reader.ReadSingle();
+ }
+
+ public void Write(BinaryWriter writer)
+ {
+ writer.Write(PositionX);
+ writer.Write(PositionY);
+ writer.Write(PositionZ);
+ writer.Write(RotationX);
+ writer.Write(RotationY);
+ writer.Write(RotationZ);
+ writer.Write(DimensionX);
+ writer.Write(DimensionY);
+ writer.Write(DimensionZ);
+ }
}
- public struct SpawnLocation
+ public class TriggerRegion
{
- public float PositionX;
- public float PositionY;
- public float PositionZ;
- public uint UnknownHash;
- public float RotationX;
- public float RotationY;
- public float RotationZ;
- public float UnknownFloat1C;
- public long JunkyardGameDBID;
- public GenericRegionTrigger JunkyardTrigger;
- public byte UnknownByte28;
- public byte UnknownByte29;
- public byte UnknownByte30;
- public byte UnknownByte31;
- public int UnknownInt32;
+ [TypeConverter(typeof(ExpandableObjectConverter))]
+ public BoxRegion mBoxRegion { get; set; } = new BoxRegion();
+ public int mId { get; set; } = 0;
+ public short miRegionIndex { get; set; } = 0;
+ public RegionType meType { get; set; } = RegionType.E_TYPE_LANDMARK;
+ private byte[] muPad { get; set; } = new byte[1];
+
+ public virtual void Read(BinaryReader reader)
+ {
+ mBoxRegion = new BoxRegion();
+ mBoxRegion.Read(reader);
+ mId = reader.ReadInt32();
+ miRegionIndex = reader.ReadInt16();
+ meType = (RegionType)reader.ReadByte();
+ muPad = reader.ReadBytes(1);
+ }
+
+ public virtual void Write(BinaryWriter writer)
+ {
+ mBoxRegion.Write(writer);
+
+ writer.Write(mId);
+ writer.Write(miRegionIndex);
+ writer.Write((byte)meType);
+ writer.Write(muPad);
+ }
}
- public class TriggerData : IEntryData
+ public class Landmark : TriggerRegion
{
- public int FormatRevision;
- public uint FileSize;
- public int Unknown0C;
- public int Unknown10;
- public float DevSpawnPositionX;
- public float DevSpawnPositionY;
- public float DevSpawnPositionZ;
- public uint DevSpawnUnknownHash;
- public float DevSpawnRotationX;
- public float DevSpawnRotationY;
- public float DevSpawnRotationZ;
- public float DevSpawnUnknownFloat;
- public uint LandmarkTriggersOffset;
- public int LandmarkTriggersCount;
- public int LandmarkNonFinishLineCount;
- public uint BlackspotTriggersOffset;
- public int BlackspotTriggersCount;
- public uint GenericRegionTriggersOffset;
- public int GenericRegionTriggersCount;
- public uint Section4Offset;
- public int Section4Count;
- public uint VFXBoxRegionOffset;
- public int VFXBoxRegionCount;
- public uint StartPositionsOffset;
- public int StartPositionsCount;
- public uint RoamingLocationsOffset;
- public int RoamingLocationsCount;
- public uint SpawnLocationsOffset;
- public int SpawnLocationsCount;
- public uint TriggerOffsetListOffset;
- public int TriggerOffsetListCount;
-
- public List LandmarkTriggers;
- public SortedDictionary GenericRegionTriggers;
- public List Section4Entries;
- public List RoamingLocationEntries;
- public List SpawnLocationEntries;
- public List TriggerOffsets;
-
- public TriggerData()
- {
- LandmarkTriggers = new List();
- GenericRegionTriggers = new SortedDictionary();
- Section4Entries = new List();
- RoamingLocationEntries = new List();
- SpawnLocationEntries = new List();
- TriggerOffsets = new List();
+ public Landmark() : base()
+ {
+ // Set meType to E_TYPE_LANDMARK
+ meType = RegionType.E_TYPE_LANDMARK;
}
- private void Clear()
- {
- FormatRevision = default;
- FileSize = default;
- Unknown0C = default;
- Unknown10 = default;
- DevSpawnPositionX = default;
- DevSpawnPositionY = default;
- DevSpawnPositionZ = default;
- DevSpawnUnknownHash = default;
- DevSpawnRotationX = default;
- DevSpawnRotationY = default;
- DevSpawnRotationZ = default;
- DevSpawnUnknownFloat = default;
- LandmarkTriggersOffset = default;
- LandmarkTriggersCount = default;
- LandmarkNonFinishLineCount = default;
- BlackspotTriggersOffset = default;
- BlackspotTriggersCount = default;
- GenericRegionTriggersOffset = default;
- GenericRegionTriggersCount = default;
- Section4Offset = default;
- Section4Count = default;
- VFXBoxRegionOffset = default;
- VFXBoxRegionCount = default;
- StartPositionsOffset = default;
- StartPositionsCount = default;
- RoamingLocationsOffset = default;
- RoamingLocationsCount = default;
- SpawnLocationsOffset = default;
- SpawnLocationsCount = default;
- TriggerOffsetListOffset = default;
- TriggerOffsetListCount = default;
-
- LandmarkTriggers.Clear();
- GenericRegionTriggers.Clear();
- Section4Entries.Clear();
- RoamingLocationEntries.Clear();
- SpawnLocationEntries.Clear();
- TriggerOffsets.Clear();
+ public List mpaStartingGrids { get; set; } = new List();
+
+ private long startingGridOffsetPosition = 0;
+ public byte muDesignIndex { get; set; } = 0;
+ public byte muDistrict { get; set; } = 0;
+ public byte mu8Flags { get; set; } = 0;
+
+ public void Read(BinaryReader reader)
+ {
+ base.Read(reader);
+ long startingGridOffset = reader.ReadUInt32();
+ int miStartingGridCount = reader.ReadByte();
+ muDesignIndex = reader.ReadByte();
+ muDistrict = reader.ReadByte();
+ mu8Flags = reader.ReadByte();
+
+ long currentPosition = reader.BaseStream.Position;
+ reader.BaseStream.Position = startingGridOffset;
+
+ for (int i = 0; i < miStartingGridCount; i++)
+ {
+ StartingGrid startingGrid = new StartingGrid();
+ startingGrid.Read(reader);
+ mpaStartingGrids.Add(startingGrid);
+ }
+ reader.BaseStream.Position = currentPosition;
+
}
- public bool Read(BundleEntry entry, ILoader loader = null)
+ public void Write(BinaryWriter writer)
{
- Clear();
+ base.Write(writer);
+ startingGridOffsetPosition = writer.BaseStream.Position;
+ writer.WriteUniquePadding(4);
+ writer.Write((byte)mpaStartingGrids.Count);
+ writer.Write(muDesignIndex);
+ writer.Write(muDistrict);
+ writer.Write(mu8Flags);
+ }
- MemoryStream ms = entry.MakeStream();
- BinaryReader2 br = new BinaryReader2(ms);
- br.BigEndian = entry.Console;
-
- FormatRevision = br.ReadInt32();
- FileSize = br.ReadUInt32();
- Unknown0C = br.ReadInt32();
- Unknown10 = br.ReadInt32();
- DevSpawnPositionX = br.ReadSingle();
- DevSpawnPositionY = br.ReadSingle();
- DevSpawnPositionZ = br.ReadSingle();
- DevSpawnUnknownHash = br.ReadUInt32();
- DevSpawnRotationX = br.ReadSingle();
- DevSpawnRotationY = br.ReadSingle();
- DevSpawnRotationZ = br.ReadSingle();
- DevSpawnUnknownFloat = br.ReadSingle();
- LandmarkTriggersOffset = br.ReadUInt32();
- LandmarkTriggersCount = br.ReadInt32();
- LandmarkNonFinishLineCount = br.ReadInt32();
- BlackspotTriggersOffset = br.ReadUInt32();
- BlackspotTriggersCount = br.ReadInt32();
- GenericRegionTriggersOffset = br.ReadUInt32();
- GenericRegionTriggersCount = br.ReadInt32();
- Section4Offset = br.ReadUInt32();
- Section4Count = br.ReadInt32();
- VFXBoxRegionOffset = br.ReadUInt32();
- VFXBoxRegionCount = br.ReadInt32();
- StartPositionsOffset = br.ReadUInt32();
- StartPositionsCount = br.ReadInt32();
- RoamingLocationsOffset = br.ReadUInt32();
- RoamingLocationsCount = br.ReadInt32();
- SpawnLocationsOffset = br.ReadUInt32();
- SpawnLocationsCount = br.ReadInt32();
- TriggerOffsetListOffset = br.ReadUInt32();
- TriggerOffsetListCount = br.ReadInt32();
-
- br.BaseStream.Position = LandmarkTriggersOffset;
-
- for (int i = 0; i < LandmarkTriggersCount; i++)
- {
- LandmarkTrigger landmarkTrigger = new LandmarkTrigger();
-
- landmarkTrigger.PositionX = br.ReadSingle();
- landmarkTrigger.PositionY = br.ReadSingle();
- landmarkTrigger.PositionZ = br.ReadSingle();
- landmarkTrigger.RotationX = br.ReadSingle();
- landmarkTrigger.RotationY = br.ReadSingle();
- landmarkTrigger.RotationZ = br.ReadSingle();
- landmarkTrigger.SizeX = br.ReadSingle();
- landmarkTrigger.SizeY = br.ReadSingle();
- landmarkTrigger.SizeZ = br.ReadSingle();
- landmarkTrigger.GameDBID = br.ReadInt32();
- landmarkTrigger.GlobalIndex = br.ReadInt16();
- landmarkTrigger.Type = br.ReadByte();
- landmarkTrigger.UnknownByte2B = br.ReadByte();
- landmarkTrigger.UnknownOffset = br.ReadUInt32();
- landmarkTrigger.UnknownByte30 = br.ReadByte();
- landmarkTrigger.LocalIndex = br.ReadByte();
- landmarkTrigger.Subtype = br.ReadByte();
- landmarkTrigger.UnknownByte33 = br.ReadByte();
-
- LandmarkTriggers.Add(landmarkTrigger);
- }
-
- br.BaseStream.Position = GenericRegionTriggersOffset;
-
- for (int i = 0; i < GenericRegionTriggersCount; i++)
- {
- long startPosition = br.BaseStream.Position;
-
- GenericRegionTrigger genericRegionTrigger = new GenericRegionTrigger();
-
- genericRegionTrigger.PositionX = br.ReadSingle();
- genericRegionTrigger.PositionY = br.ReadSingle();
- genericRegionTrigger.PositionZ = br.ReadSingle();
- genericRegionTrigger.RotationX = br.ReadSingle();
- genericRegionTrigger.RotationY = br.ReadSingle();
- genericRegionTrigger.RotationZ = br.ReadSingle();
- genericRegionTrigger.SizeX = br.ReadSingle();
- genericRegionTrigger.SizeY = br.ReadSingle();
- genericRegionTrigger.SizeZ = br.ReadSingle();
- genericRegionTrigger.GameDBID = br.ReadInt32();
- genericRegionTrigger.Index = br.ReadInt16();
- genericRegionTrigger.Type = br.ReadByte();
- genericRegionTrigger.UnknownByte2B = br.ReadByte();
- genericRegionTrigger.GameDBID2 = br.ReadInt32();
- genericRegionTrigger.UnknownShort30 = br.ReadInt16();
- genericRegionTrigger.UnknownShort32 = br.ReadInt16();
- genericRegionTrigger.UnknownByte34 = br.ReadByte();
- genericRegionTrigger.UnknownByte35 = br.ReadByte();
- genericRegionTrigger.Subtype = br.ReadByte();
- genericRegionTrigger.UnknownByte37 = br.ReadByte();
-
- GenericRegionTriggers.Add((uint)startPosition, genericRegionTrigger);
- }
-
- br.BaseStream.Position = Section4Offset;
-
- for (int i = 0; i < Section4Count; i++)
- {
- TriggerSection4Entry section4Entry = new TriggerSection4Entry();
-
- section4Entry.TriggerOffsetListOffset = br.ReadUInt32();
- section4Entry.TriggerOffsetListCount = br.ReadInt32();
- section4Entry.GameDBIDListOffset = br.ReadUInt32();
- section4Entry.GameDBIDListCount = br.ReadInt32();
-
- long oldPosition = br.BaseStream.Position;
-
- br.BaseStream.Position = section4Entry.TriggerOffsetListOffset;
- section4Entry.Triggers = new List();
- for (int j = 0; j < section4Entry.TriggerOffsetListCount; j++)
- {
- uint offset = br.ReadUInt32();
- section4Entry.Triggers.Add(GenericRegionTriggers[offset]);
- }
-
- br.BaseStream.Position = section4Entry.GameDBIDListOffset;
- section4Entry.GameDBIDs = new List();
- for (int j = 0; j < section4Entry.GameDBIDListCount; j++)
- {
- section4Entry.GameDBIDs.Add(br.ReadInt64());
- }
-
- br.BaseStream.Position = oldPosition;
-
- Section4Entries.Add(section4Entry);
- }
-
- br.BaseStream.Position = RoamingLocationsOffset;
+ public void WriteStartingGrid(BinaryWriter writer){
+
+ long currentPosition = writer.BaseStream.Position;
+ writer.BaseStream.Position = startingGridOffsetPosition;
+ writer.Write((uint)currentPosition);
+ writer.BaseStream.Position = currentPosition;
+ foreach (StartingGrid grid in mpaStartingGrids) {
+ grid.Write(writer);
+ }
+ }
+ }
+
+ public enum GenericRegionStuntCameraType
+ {
+ E_STUNT_CAMERA_TYPE_NO_CUTS = 0,
+ E_STUNT_CAMERA_TYPE_CUSTOM = 1,
+ E_STUNT_CAMERA_TYPE_NORMAL = 2
+ }
+
+ public enum GenericRegionType
+ {
+ E_TYPE_JUNK_YARD = 0,
+ E_TYPE_BIKE_SHOP = 1,
+ E_TYPE_GAS_STATION = 2,
+ E_TYPE_BODY_SHOP = 3,
+ E_TYPE_PAINT_SHOP = 4,
+ E_TYPE_CAR_PARK = 5,
+ E_TYPE_SIGNATURE_TAKEDOWN = 6,
+ E_TYPE_KILLZONE = 7,
+ E_TYPE_JUMP = 8,
+ E_TYPE_SMASH = 9,
+ E_TYPE_SIGNATURE_CRASH = 10,
+ E_TYPE_SIGNATURE_CRASH_CAMERA = 11,
+ E_TYPE_ROAD_LIMIT = 12,
+ E_TYPE_OVERDRIVE_BOOST = 13,
+ E_TYPE_OVERDRIVE_STRENGTH = 14,
+ E_TYPE_OVERDRIVE_SPEED = 15,
+ E_TYPE_OVERDRIVE_CONTROL = 16,
+ E_TYPE_TIRE_SHOP = 17,
+ E_TYPE_TUNING_SHOP = 18,
+ E_TYPE_PICTURE_PARADISE = 19,
+ E_TYPE_TUNNEL = 20,
+ E_TYPE_OVERPASS = 21,
+ E_TYPE_BRIDGE = 22,
+ E_TYPE_WAREHOUSE = 23,
+ E_TYPE_LARGE_OVERHEAD_OBJECT = 24,
+ E_TYPE_NARROW_ALLEY = 25,
+ E_TYPE_PASS_TUNNEL = 26,
+ E_TYPE_PASS_OVERPASS = 27,
+ E_TYPE_PASS_BRIDGE = 28,
+ E_TYPE_PASS_WAREHOUSE = 29,
+ E_TYPE_PASS_LARGEOVERHEADOBJECT = 30,
+ E_TYPE_PASS_NARROWALLEY = 31,
+ E_TYPE_RAMP = 32,
+ E_TYPE_GOLD = 33,
+ E_TYPE_ISLAND_ENTITLEMENT = 34
+ }
- for (int i = 0; i < RoamingLocationsCount; i++)
+ public class GenericRegion : TriggerRegion
+ {
+ public GenericRegion() : base()
+ {
+ // Set meType to E_TYPE_GENERIC_REGION
+ meType = RegionType.E_TYPE_GENERIC_REGION;
+ }
+
+ public int GroupID { get; set; } = 0;
+ public short CameraCut1 { get; set; } = 0;
+ public short CameraCut2 { get; set; } = 0;
+ public GenericRegionStuntCameraType CameraType1 { get; set; } = 0;
+ public GenericRegionStuntCameraType CameraType2 { get; set; } = 0;
+ public GenericRegionType Type { get; set; } = GenericRegionType.E_TYPE_JUNK_YARD;
+ public sbyte IsOneWay { get; set; } = 0;
+
+ public void Read(BinaryReader reader)
+ {
+ base.Read(reader);
+ GroupID = reader.ReadInt32();
+ CameraCut1 = reader.ReadInt16();
+ CameraCut2 = reader.ReadInt16();
+ CameraType1 = (GenericRegionStuntCameraType)reader.ReadSByte();
+ CameraType2 = (GenericRegionStuntCameraType)reader.ReadSByte();
+ Type = (GenericRegionType)reader.ReadByte();
+ IsOneWay = reader.ReadSByte();
+ }
+
+ public void Write(BinaryWriter writer)
+ {
+ base.Write(writer);
+ writer.Write(GroupID);
+ writer.Write(CameraCut1);
+ writer.Write(CameraCut2);
+ writer.Write((sbyte)CameraType1);
+ writer.Write((sbyte)CameraType2);
+ writer.Write((byte)Type);
+ writer.Write(IsOneWay);
+ }
+ }
+
+ public enum BlackspotScoreType
+ {
+ E_SCORE_TYPE_DISTANCE = 0,
+ E_SCORE_TYPE_CAR_COUNT = 1
+ }
+
+ public class Blackspot : TriggerRegion
+ {
+ public Blackspot() : base()
+ {
+ // Set meType to E_TYPE_BLACKSPOT
+ meType = RegionType.E_TYPE_BLACKSPOT;
+ }
+
+ public BlackspotScoreType muScoreType { get; set; } = BlackspotScoreType.E_SCORE_TYPE_DISTANCE;
+ public int miScoreAmount { get; set; } = 0;
+
+ public override void Read(BinaryReader reader)
+ {
+ base.Read(reader);
+
+ muScoreType = (BlackspotScoreType) reader.ReadByte();
+ reader.ReadBytes(3); // Padding
+ miScoreAmount = reader.ReadInt32();
+ }
+
+ public override void Write(BinaryWriter writer)
+ {
+ base.Write(writer);
+
+ writer.Write((byte)muScoreType);
+ writer.Write(new byte[3]); // Padding
+ writer.Write(miScoreAmount);
+ }
+ }
+
+ public class Killzone
+ {
+ [Description("Triggers as GenericRegions. Uses region.mId")]
+ public List TriggerIds { get; set; } = new List();
+ public List RegionIds { get; set; } = new List();
+
+ private long TriggerOffsetPosition = 0;
+
+ private long CGSIDOffsetPosition = 0;
+ public void Read(BinaryReader reader)
+ {
+ // Read the trigger pointer array
+ long genericRegionOffset = reader.ReadUInt32();
+ int TriggerCount = reader.ReadInt32();
+
+ // Read the region ID array
+ long cgsOffset = reader.ReadUInt32();
+ int RegionIdCount = reader.ReadInt32();
+ long currentPosition = reader.BaseStream.Position;
+
+ reader.BaseStream.Position = genericRegionOffset;
+ uint[] Triggers = new uint[TriggerCount];
+ for (int i = 0; i < TriggerCount; i++)
{
- RoamingLocation roamingLocation = new RoamingLocation();
+ Triggers[i] = reader.ReadUInt32();
+ }
- roamingLocation.PositionX = br.ReadSingle();
- roamingLocation.PositionY = br.ReadSingle();
- roamingLocation.PositionZ = br.ReadSingle();
- roamingLocation.UnknownHash = br.ReadUInt32();
- roamingLocation.Subdistrict = br.ReadByte();
- roamingLocation.UnknownByte11 = br.ReadByte();
- roamingLocation.UnknownByte12 = br.ReadByte();
- roamingLocation.UnknownByte13 = br.ReadByte();
- roamingLocation.UnknownInt14 = br.ReadInt32();
- roamingLocation.UnknownInt18 = br.ReadInt32();
- roamingLocation.UnknownInt1C = br.ReadInt32();
+ TriggerIds = new List();
+ foreach (uint trigger in Triggers)
+ {
+ reader.BaseStream.Position = trigger;
+ GenericRegion region = new GenericRegion();
+ region.Read(reader);
+ TriggerIds.Add(region.mId);
+ }
- RoamingLocationEntries.Add(roamingLocation);
+ reader.BaseStream.Position = cgsOffset;
+ RegionIds = new List();
+ for (int i = 0; i < RegionIdCount; i++)
+ {
+ CgsID id = new CgsID();
+ id.Read(reader);
+ RegionIds.Add(id);
}
- br.BaseStream.Position = SpawnLocationsOffset;
+ reader.BaseStream.Position = currentPosition;
+ }
+
+ public void Write(BinaryWriter writer)
+ {
+ TriggerOffsetPosition = writer.BaseStream.Position;
+ writer.WriteUniquePadding(4);
+ writer.Write(TriggerIds.Count);
+ CGSIDOffsetPosition = writer.BaseStream.Position;
+ writer.WriteUniquePadding(4);
+ writer.Write(RegionIds.Count);
+ }
- for (int i = 0; i < SpawnLocationsCount; i++)
+ public void WritePointerStuff(BinaryWriter writer, Dictionary genericRegionOffsets) {
+
+ long currentPosition = writer.BaseStream.Position;
+ writer.BaseStream.Position = TriggerOffsetPosition;
+ writer.Write((uint)currentPosition);
+ writer.BaseStream.Position = currentPosition;
+ foreach (int trigger in TriggerIds)
+ {
+ writer.Write(genericRegionOffsets[trigger]);
+ }
+ long paddingCount = 16 - (writer.BaseStream.Position % 16);
+ if (paddingCount < 16)
+ {
+ for (int i = 0; i < paddingCount; i++)
+ writer.Write((byte)0);
+ }
+ currentPosition = writer.BaseStream.Position;
+ writer.BaseStream.Position = CGSIDOffsetPosition;
+ writer.Write((uint)currentPosition);
+ writer.BaseStream.Position = currentPosition;
+ foreach (CgsID ids in RegionIds)
+ {
+ ids.Write(writer);
+ }
+ paddingCount = 16 - (writer.BaseStream.Position % 16);
+ if (paddingCount < 16)
{
- SpawnLocation spawnLocation = new SpawnLocation();
+ for (int i = 0; i < paddingCount; i++)
+ writer.Write((byte)0);
+ }
+
+ }
+
+
+ }
+
+ public class SignatureStunt
+ {
+ [TypeConverter(typeof(ExpandableObjectConverter))]
+ public CgsID mId { get; set; } = new CgsID();
+ public long miCamera { get; set; } = 0;
+ public List stuntElementRegions { get; set; } = new List();
- spawnLocation.PositionX = br.ReadSingle();
- spawnLocation.PositionY = br.ReadSingle();
- spawnLocation.PositionZ = br.ReadSingle();
- spawnLocation.UnknownHash = br.ReadUInt32();
- spawnLocation.RotationX = br.ReadSingle();
- spawnLocation.RotationY = br.ReadSingle();
- spawnLocation.RotationZ = br.ReadSingle();
- spawnLocation.UnknownFloat1C = br.ReadSingle();
- spawnLocation.JunkyardGameDBID = br.ReadInt64();
- spawnLocation.UnknownByte28 = br.ReadByte();
- spawnLocation.UnknownByte29 = br.ReadByte();
- spawnLocation.UnknownByte30 = br.ReadByte();
- spawnLocation.UnknownByte31 = br.ReadByte();
- spawnLocation.UnknownInt32 = br.ReadInt32();
+ private long StuntElementOffsetPosition = 0;
- foreach (GenericRegionTrigger trigger in GenericRegionTriggers.Values)
- {
- if (trigger.GameDBID == spawnLocation.JunkyardGameDBID)
- {
- spawnLocation.JunkyardTrigger = trigger;
- break;
- }
- }
+ public void Read(BinaryReader reader)
+ {
+ mId = new CgsID();
+ mId.Read(reader);
+ miCamera = reader.ReadInt64();
+
+ uint mppStuntElementsOffset = reader.ReadUInt32();
+ int miStuntElementCount = reader.ReadInt32();
- SpawnLocationEntries.Add(spawnLocation);
+ long currentPosition = reader.BaseStream.Position;
+ reader.BaseStream.Position = mppStuntElementsOffset;
+ uint[] Triggers = new uint[miStuntElementCount];
+ for (int i = 0; i < miStuntElementCount; i++)
+ {
+ Triggers[i] = reader.ReadUInt32();
}
- br.BaseStream.Position = TriggerOffsetListOffset;
+ stuntElementRegions = new List();
+ foreach (uint trigger in Triggers)
+ {
+ reader.BaseStream.Position = trigger;
+ GenericRegion region = new GenericRegion();
+ region.Read(reader);
+ stuntElementRegions.Add(region.mId);
+ }
+ reader.BaseStream.Position = currentPosition;
+ }
- for (int i = 0; i < TriggerOffsetListCount; i++)
+ // Write something in triggerIds, because we dont have the actual positions yet
+ public void Write(BinaryWriter writer)
+ {
+ mId.Write(writer);
+ writer.Write(miCamera);
+ StuntElementOffsetPosition = writer.BaseStream.Position;
+ writer.WriteUniquePadding(4);
+ writer.Write(stuntElementRegions.Count);
+ }
+
+ public void WriteStuntElements(BinaryWriter writer, Dictionary genericRegionOffsets) {
+ long currentPosition = writer.BaseStream.Position;
+ writer.BaseStream.Position = StuntElementOffsetPosition;
+ writer.Write(currentPosition);
+ writer.BaseStream.Position = currentPosition;
+ foreach (int trigger in stuntElementRegions)
{
- uint section6Entry = br.ReadUInt32();
- TriggerOffsets.Add(section6Entry);
+ writer.Write(genericRegionOffsets[trigger]);
}
+ }
- br.Close();
- ms.Close();
+ }
+
+ public class RoamingLocation
+ {
+ [TypeConverter(typeof(ExpandableObjectConverter))]
+ public Vector3I Position { get; set; } = new Vector3I(0,0,0,0);
+ public byte DistrictIndex { get; set; } = 0;
+
+ public void Read(BinaryReader reader) {
+
+ Position = new Vector3I(
+ reader.ReadSingle(),
+ reader.ReadSingle(),
+ reader.ReadSingle(), reader.ReadSingle());
+ DistrictIndex = reader.ReadByte();
+ // Read and discard padding
+ reader.ReadBytes(15);
+ }
+
+ public void Write(BinaryWriter writer)
+ {
+ writer.Write(Position.X);
+ writer.Write(Position.Y);
+ writer.Write(Position.Z);
+ writer.Write(Position.S);
+ writer.Write(DistrictIndex);
+
+ // Write padding
+ writer.Write(new byte[15]);
+ }
+ }
+
+ public class VFXBoxRegion : TriggerRegion
+ {
+ public VFXBoxRegion() : base()
+ {
+ // Set meType to E_TYPE_VFXBOX_REGION
+ meType = RegionType.E_TYPE_VFXBOX_REGION;
+ }
+
+ public override void Read(BinaryReader reader)
+ {
+ base.Read(reader);
+ }
+
+ public override void Write(BinaryWriter writer)
+ {
+ base.Write(writer);
+ }
+ }
+
+ public enum SpawnLocationType
+ {
+ E_TYPE_PLAYER_SPAWN = 0,
+ E_TYPE_CAR_SELECT_LEFT = 1,
+ E_TYPE_CAR_SELECT_RIGHT = 2,
+ E_TYPE_CAR_UNLOCK = 3
+ }
+
+ public class SpawnLocation
+ {
+ [TypeConverter(typeof(ExpandableObjectConverter))]
+ public Vector3I mPosition { get; set; } = new Vector3I(0, 0, 0, 0);
+ [TypeConverter(typeof(ExpandableObjectConverter))]
+ public Vector3I mDirection { get; set; } = new Vector3I(0, 0, 0, 0);
+ [TypeConverter(typeof(ExpandableObjectConverter))]
+ public CgsID mJunkyardId { get; set; } = new CgsID();
+ public SpawnLocationType muType { get; set; } = 0;
+ private byte[] padding = new byte[7];
+
+ public void Read(BinaryReader reader)
+ {
+ mPosition = new Vector3I(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
+ mDirection = new Vector3I(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
+ mJunkyardId = new CgsID();
+ mJunkyardId.Read(reader);
+ muType = (SpawnLocationType)reader.ReadByte();
+ padding = reader.ReadBytes(7);
+ }
+
+ public void Write(BinaryWriter writer)
+ {
+ writer.Write(mPosition.X);
+ writer.Write(mPosition.Y);
+ writer.Write(mPosition.Z);
+ writer.Write(mPosition.S);
+ writer.Write(mDirection.X);
+ writer.Write(mDirection.Y);
+ writer.Write(mDirection.Z);
+ writer.Write(mDirection.S);
+ mJunkyardId.Write(writer);
+ writer.Write((byte)muType);
+ writer.Write(padding);
+ }
+
+ }
+
+
+public class TriggerData : IEntryData
+ {
+ public int miVersionNumber { get; set; }
+ public uint muSize { get; set; }
+ public Vector3I mPlayerStartPosition { get; set; }
+ public Vector3I mPlayerStartDirection { get; set; }
+ public List mpLandmarks { get; set; }
+ public int miOnlineLandmarkCount { get; set; }
+ public List mpSignatureStunts { get; set; }
+ public List mpGenericRegions { get; set; }
+
+ [Editor(typeof(DescriptiveCollectionEditor), typeof(UITypeEditor))]
+ public List mpKillzones { get; set; }
+ public List mpBlackspots { get; set; }
+ public List mpVFXBoxRegions { get; set; }
+ public List mpRoamingLocations { get; set; }
+ public List mpSpawnLocations { get; set; }
+ private List TriggerOffsets { get; set; }
+
+
+ public bool Read(BundleEntry entry, ILoader loader = null)
+ {
+ MemoryStream ms = entry.MakeStream();
+ BinaryReader2 reader = new BinaryReader2(ms);
+ reader.BigEndian = entry.Console;
+
+ miVersionNumber = reader.ReadInt32();
+ muSize = reader.ReadUInt32();
+ reader.ReadBytes(8);// skip 8 bytes of padding
+ mPlayerStartPosition = new Vector3I(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
+ mPlayerStartDirection = new Vector3I(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
+ // read landmarks
+ long LandmarkTriggersOffset = reader.ReadUInt32();
+ int miLandmarkCount = reader.ReadInt32();
+ miOnlineLandmarkCount = reader.ReadInt32();
+
+ long SignatureStuntsOffset = reader.ReadUInt32();
+ int miSignatureStuntCount = reader.ReadInt32();
+
+ long GenericRegionsOffset = reader.ReadUInt32();
+ int miGenericRegionCount = reader.ReadInt32();
+
+ long KillzoneOffset = reader.ReadUInt32();
+ int miKillzoneCount = reader.ReadInt32();
+
+ long BlackspotOffset = reader.ReadUInt32();
+ int miBlackspotCount = reader.ReadInt32();
+
+ long VFXBoxRegionOffset = reader.ReadUInt32();
+ int miVFXBoxRegionCount = reader.ReadInt32();
+
+ long RoamingLocationOffset = reader.ReadUInt32();
+ int miRoamingLocationCount = reader.ReadInt32();
+
+ long SpawnLocationOffset = reader.ReadUInt32();
+ int miSpawnLocationCount = reader.ReadInt32();
+
+ long TriggerRegionOffset = reader.ReadUInt32();
+ int miRegionCount = reader.ReadInt32();
+
+ reader.BaseStream.Position = LandmarkTriggersOffset;
+ mpLandmarks = new List();
+ for (int i = 0; i < miLandmarkCount; i++)
+ {
+ Landmark landmark = new Landmark();
+ landmark.Read(reader);
+ mpLandmarks.Add(landmark);
+ }
+
+ reader.BaseStream.Position = SignatureStuntsOffset;
+ // read signature stunts
+ mpSignatureStunts = new List();
+ for (int i = 0; i < miSignatureStuntCount; i++)
+ {
+ SignatureStunt stunt = new SignatureStunt();
+ stunt.Read(reader);
+ mpSignatureStunts.Add(stunt);
+ }
+
+ reader.BaseStream.Position = GenericRegionsOffset;
+ // read generic regions
+ mpGenericRegions = new List();
+ for (int i = 0; i < miGenericRegionCount; i++)
+ {
+ GenericRegion region = new GenericRegion();
+ region.Read(reader);
+ mpGenericRegions.Add(region);
+ }
+
+
+ reader.BaseStream.Position = KillzoneOffset;
+ // read killzones
+ mpKillzones = new List();
+ for (int i = 0; i < miKillzoneCount; i++)
+ {
+ Killzone killzone = new Killzone();
+ killzone.Read(reader);
+ mpKillzones.Add(killzone);
+ }
+
+ // read blackspots
+ reader.BaseStream.Position = BlackspotOffset;
+ mpBlackspots = new List();
+ for (int i = 0; i < miBlackspotCount; i++)
+ {
+ Blackspot spot = new Blackspot();
+ spot.Read(reader);
+ mpBlackspots.Add(spot);
+ }
+
+ reader.BaseStream.Position = VFXBoxRegionOffset;
+
+ // read VFX box regions
+ mpVFXBoxRegions = new List();
+ for (int i = 0; i < miVFXBoxRegionCount; i++)
+ {
+ VFXBoxRegion box = new VFXBoxRegion();
+ box.Read(reader);
+ mpVFXBoxRegions.Add(box);
+ }
+
+ reader.BaseStream.Position = RoamingLocationOffset;
+
+ // read roaming locations
+ mpRoamingLocations = new List();
+ for (int i = 0; i < miRoamingLocationCount; i++)
+ {
+ RoamingLocation location = new RoamingLocation();
+ location.Read(reader);
+ mpRoamingLocations.Add(location);
+ }
+
+ reader.BaseStream.Position = SpawnLocationOffset;
+
+ mpSpawnLocations = new List();
+ for (int i = 0; i < miSpawnLocationCount; i++)
+ {
+ SpawnLocation location = new SpawnLocation();
+ location.Read(reader);
+ mpSpawnLocations.Add(location);
+ }
+
+ reader.BaseStream.Position = TriggerRegionOffset;
+
+ // read TriggerRegion (miGenericCount + miLandmarkCount)
+ TriggerOffsets = new List();
+ for (int i = 0; i < miRegionCount; i++)
+ {
+ uint section6Entry = reader.ReadUInt32();
+ TriggerOffsets.Add(section6Entry);
+ }
return true;
}
public IEntryEditor GetEditor(BundleEntry entry)
{
- return null;
+ TriggerDataEditor triggerDataEditor = new TriggerDataEditor();
+ triggerDataEditor.trigger = this;
+
+ triggerDataEditor.EditEvent += () =>
+ {
+ Write(entry);
+ };
+ return triggerDataEditor;
}
public EntryType GetEntryType(BundleEntry entry)
@@ -410,169 +803,172 @@ public EntryType GetEntryType(BundleEntry entry)
public bool Write(BundleEntry entry)
{
MemoryStream ms = new MemoryStream();
- BinaryWriter bw = new BinaryWriter(ms);
-
- bw.Write(FormatRevision);
- long fileSizeOffset = bw.BaseStream.Position;
- bw.Write((int)0);
- bw.Write(Unknown0C);
- bw.Write(Unknown10);
- bw.Write(DevSpawnPositionX);
- bw.Write(DevSpawnPositionY);
- bw.Write(DevSpawnPositionZ);
- bw.Write(DevSpawnUnknownHash);
- bw.Write(DevSpawnRotationX);
- bw.Write(DevSpawnRotationY);
- bw.Write(DevSpawnRotationZ);
- bw.Write(DevSpawnUnknownFloat);
- bw.Write(LandmarkTriggersOffset);
- bw.Write(LandmarkTriggersCount);
- bw.Write(LandmarkNonFinishLineCount);
- bw.Write(BlackspotTriggersOffset);
- bw.Write(BlackspotTriggersCount);
- bw.Write(GenericRegionTriggersOffset);
- bw.Write(GenericRegionTriggersCount);
- bw.Write(Section4Offset);
- bw.Write(Section4Count);
- bw.Write(VFXBoxRegionOffset);
- bw.Write(VFXBoxRegionCount);
- bw.Write(StartPositionsOffset);
- bw.Write(StartPositionsCount);
- bw.Write(RoamingLocationsOffset);
- bw.Write(RoamingLocationsCount);
- bw.Write(SpawnLocationsOffset);
- bw.Write(SpawnLocationsCount);
- bw.Write(TriggerOffsetListOffset);
- bw.Write(TriggerOffsetListCount);
-
- bw.BaseStream.Position = LandmarkTriggersOffset;
-
- for (int i = 0; i < LandmarkTriggers.Count; i++)
- {
- LandmarkTrigger landmarkTrigger = LandmarkTriggers[i];
-
- bw.Write(landmarkTrigger.PositionX);
- bw.Write(landmarkTrigger.PositionY);
- bw.Write(landmarkTrigger.PositionZ);
- bw.Write(landmarkTrigger.RotationX);
- bw.Write(landmarkTrigger.RotationY);
- bw.Write(landmarkTrigger.RotationZ);
- bw.Write(landmarkTrigger.SizeX);
- bw.Write(landmarkTrigger.SizeY);
- bw.Write(landmarkTrigger.SizeZ);
- bw.Write(landmarkTrigger.GameDBID);
- bw.Write(landmarkTrigger.GlobalIndex);
- bw.Write(landmarkTrigger.Type);
- bw.Write(landmarkTrigger.UnknownByte2B);
- bw.Write(landmarkTrigger.UnknownOffset);
- bw.Write(landmarkTrigger.UnknownByte30);
- bw.Write(landmarkTrigger.LocalIndex);
- bw.Write(landmarkTrigger.Subtype);
- bw.Write(landmarkTrigger.UnknownByte33);
- }
-
- bw.BaseStream.Position = GenericRegionTriggersOffset;
-
- foreach (GenericRegionTrigger genericRegionTrigger in GenericRegionTriggers.Values)
- {
- bw.Write(genericRegionTrigger.PositionX);
- bw.Write(genericRegionTrigger.PositionY);
- bw.Write(genericRegionTrigger.PositionZ);
- bw.Write(genericRegionTrigger.RotationX);
- bw.Write(genericRegionTrigger.RotationY);
- bw.Write(genericRegionTrigger.RotationZ);
- bw.Write(genericRegionTrigger.SizeX);
- bw.Write(genericRegionTrigger.SizeY);
- bw.Write(genericRegionTrigger.SizeZ);
- bw.Write(genericRegionTrigger.GameDBID);
- bw.Write(genericRegionTrigger.Index);
- bw.Write(genericRegionTrigger.Type);
- bw.Write(genericRegionTrigger.UnknownByte2B);
- bw.Write(genericRegionTrigger.GameDBID2);
- bw.Write(genericRegionTrigger.UnknownShort30);
- bw.Write(genericRegionTrigger.UnknownShort32);
- bw.Write(genericRegionTrigger.UnknownByte34);
- bw.Write(genericRegionTrigger.UnknownByte35);
- bw.Write(genericRegionTrigger.Subtype);
- bw.Write(genericRegionTrigger.UnknownByte37);
- }
-
- bw.BaseStream.Position = Section4Offset;
-
- foreach (TriggerSection4Entry section4Entry in Section4Entries)
- {
- bw.Write(section4Entry.TriggerOffsetListOffset);
- bw.Write(section4Entry.TriggerOffsetListCount);
- bw.Write(section4Entry.GameDBIDListOffset);
- bw.Write(section4Entry.GameDBIDListCount);
-
- // TODO: write list
- }
-
- bw.BaseStream.Position = RoamingLocationsOffset;
-
- for (int i = 0; i < RoamingLocationEntries.Count; i++)
- {
- RoamingLocation roamingLocation = RoamingLocationEntries[i];
-
- bw.Write(roamingLocation.PositionX);
- bw.Write(roamingLocation.PositionY);
- bw.Write(roamingLocation.PositionZ);
- bw.Write(roamingLocation.UnknownHash);
- bw.Write(roamingLocation.Subdistrict);
- bw.Write(roamingLocation.UnknownByte11);
- bw.Write(roamingLocation.UnknownByte12);
- bw.Write(roamingLocation.UnknownByte13);
- bw.Write(roamingLocation.UnknownInt14);
- bw.Write(roamingLocation.UnknownInt18);
- bw.Write(roamingLocation.UnknownInt1C);
- }
-
- bw.BaseStream.Position = SpawnLocationsOffset;
-
- for (int i = 0; i < SpawnLocationEntries.Count; i++)
- {
- SpawnLocation spawnLocation = SpawnLocationEntries[i];
-
- bw.Write(spawnLocation.PositionX);
- bw.Write(spawnLocation.PositionY);
- bw.Write(spawnLocation.PositionZ);
- bw.Write(spawnLocation.UnknownHash);
- bw.Write(spawnLocation.RotationX);
- bw.Write(spawnLocation.RotationY);
- bw.Write(spawnLocation.RotationZ);
- bw.Write(spawnLocation.UnknownFloat1C);
- bw.Write(spawnLocation.JunkyardGameDBID);
- bw.Write(spawnLocation.UnknownByte28);
- bw.Write(spawnLocation.UnknownByte29);
- bw.Write(spawnLocation.UnknownByte30);
- bw.Write(spawnLocation.UnknownByte31);
- bw.Write(spawnLocation.UnknownInt32);
+ BinaryWriter writer = new BinaryWriter(ms);
+ writer.Write(miVersionNumber);
+ long SizePosition = writer.BaseStream.Position;
+ writer.WriteUniquePadding(4);
+ writer.WriteUniquePadding(8); //padding
+ writer.Write(mPlayerStartPosition.X);
+ writer.Write(mPlayerStartPosition.Y);
+ writer.Write(mPlayerStartPosition.Z);
+ writer.Write(mPlayerStartPosition.S);
+ writer.Write(mPlayerStartDirection.X);
+ writer.Write(mPlayerStartDirection.Y);
+ writer.Write(mPlayerStartDirection.Z);
+ writer.Write(mPlayerStartDirection.S);
+
+ long LandmarkOffsetPosition = writer.BaseStream.Position;
+ writer.WriteUniquePadding(4);
+ writer.Write(mpLandmarks.Count);
+ writer.Write(miOnlineLandmarkCount);
+ long SignatureStuntskOffsetPosition = writer.BaseStream.Position;
+ writer.WriteUniquePadding(4);
+ writer.Write(mpSignatureStunts.Count);
+ long GenericRegionsOffsetPosition = writer.BaseStream.Position;
+ writer.WriteUniquePadding(4);
+ writer.Write(mpGenericRegions.Count);
+ long KillzoneOffsetPosition = writer.BaseStream.Position;
+ writer.WriteUniquePadding(4);
+ writer.Write(mpKillzones.Count);
+ long BlackspotOffsetPosition = writer.BaseStream.Position;
+ writer.WriteUniquePadding(4);
+ writer.Write(mpBlackspots.Count);
+ long VFXBoxRegionsOffsetPosition = writer.BaseStream.Position;
+ writer.WriteUniquePadding(4);
+ writer.Write(mpVFXBoxRegions.Count);
+ long RoamingLocationsOffsetPosition = writer.BaseStream.Position;
+ writer.WriteUniquePadding(4);
+ writer.Write(mpRoamingLocations.Count);
+ long SpawnLocationsOffsetPosition = writer.BaseStream.Position;
+ writer.WriteUniquePadding(4);
+ writer.Write(mpSpawnLocations.Count);
+ long TriggerOffsetPosition = writer.BaseStream.Position;
+ writer.WriteUniquePadding(4);
+ writer.Write(mpLandmarks.Count + mpGenericRegions.Count + mpBlackspots.Count + mpVFXBoxRegions.Count);
+ writer.WriteUniquePadding(4); // padding
+
+ List TriggerRegionOffsets = new List();
+
+ long currentPosition = writer.BaseStream.Position;
+ writer.BaseStream.Position = LandmarkOffsetPosition;
+ writer.Write((uint)currentPosition);
+ writer.BaseStream.Position = currentPosition;
+ foreach (Landmark landmark in mpLandmarks)
+ {
+ TriggerRegionOffsets.Add((uint)writer.BaseStream.Position);
+ landmark.Write(writer);
+ }
+ writer.WritePadding();
+
+ currentPosition = writer.BaseStream.Position;
+ writer.BaseStream.Position = SignatureStuntskOffsetPosition;
+ writer.Write((uint)currentPosition);
+ writer.BaseStream.Position = currentPosition;
+ foreach (SignatureStunt stunt in mpSignatureStunts)
+ {
+ stunt.Write(writer);
+ }
+ writer.WritePadding();
+
+ currentPosition = writer.BaseStream.Position;
+ writer.BaseStream.Position = GenericRegionsOffsetPosition;
+ writer.Write((uint)currentPosition);
+ writer.BaseStream.Position = currentPosition;
+ Dictionary genericRegionOffsets = new Dictionary();
+ foreach (GenericRegion region in mpGenericRegions)
+ {
+ genericRegionOffsets.Add(region.mId, (uint)writer.BaseStream.Position);
+ TriggerRegionOffsets.Add((uint)writer.BaseStream.Position);
+ region.Write(writer);
+ }
+ writer.WritePadding();
+
+ currentPosition = writer.BaseStream.Position;
+ writer.BaseStream.Position = KillzoneOffsetPosition;
+ writer.Write((uint)currentPosition);
+ writer.BaseStream.Position = currentPosition;
+ foreach (Killzone killzone in mpKillzones)
+ {
+ killzone.Write(writer);
+ };
+ writer.WritePadding();
+
+ currentPosition = writer.BaseStream.Position;
+ writer.BaseStream.Position = BlackspotOffsetPosition;
+ writer.Write((uint)currentPosition);
+ writer.BaseStream.Position = currentPosition;
+ foreach (Blackspot blackspot in mpBlackspots)
+ {
+ TriggerRegionOffsets.Add((uint)writer.BaseStream.Position);
+ blackspot.Write(writer);
}
+ writer.WritePadding();
- bw.BaseStream.Position = TriggerOffsetListOffset;
+ currentPosition = writer.BaseStream.Position;
+ writer.BaseStream.Position = VFXBoxRegionsOffsetPosition;
+ writer.Write((uint)currentPosition);
+ writer.BaseStream.Position = currentPosition;
+ foreach (VFXBoxRegion region in mpVFXBoxRegions)
+ {
+ TriggerRegionOffsets.Add((uint)writer.BaseStream.Position);
+ region.Write(writer);
+ }
+ writer.WritePadding();
- for (int i = 0; i < TriggerOffsets.Count; i++)
+ currentPosition = writer.BaseStream.Position;
+ writer.BaseStream.Position = RoamingLocationsOffsetPosition;
+ writer.Write((uint)currentPosition);
+ writer.BaseStream.Position = currentPosition;
+ foreach (RoamingLocation location in mpRoamingLocations)
{
- uint section6Entry = TriggerOffsets[i];
- bw.Write(section6Entry);
+ location.Write(writer);
}
+ writer.WritePadding();
- long fileSize = bw.BaseStream.Position;
- bw.BaseStream.Position = fileSizeOffset;
- bw.Write((int)fileSize);
+ currentPosition = writer.BaseStream.Position;
+ writer.BaseStream.Position = SpawnLocationsOffsetPosition;
+ writer.Write((uint)currentPosition);
+ writer.BaseStream.Position = currentPosition;
+ foreach (SpawnLocation location in mpSpawnLocations)
+ {
+ location.Write(writer);
+ }
+ writer.WritePadding();
- bw.BaseStream.Position = fileSize;
+ foreach (Landmark land in mpLandmarks) {
+ land.WriteStartingGrid(writer);
+ }
+
+ foreach (SignatureStunt stunt in mpSignatureStunts)
+ {
+ stunt.WriteStuntElements(writer, genericRegionOffsets);
+ }
+
+ foreach (Killzone killzone in mpKillzones)
+ {
+ killzone.WritePointerStuff(writer, genericRegionOffsets);
+ };
+
+ currentPosition = writer.BaseStream.Position;
+ writer.BaseStream.Position = TriggerOffsetPosition;
+ writer.Write((uint)currentPosition);
+ writer.BaseStream.Position = currentPosition;
+ foreach (uint region in TriggerOffsets)
+ {
+ writer.Write(region);
+ }
- long paddingCount = 16 - (bw.BaseStream.Position % 16);
- for (int i = 0; i < paddingCount; i++)
- bw.Write((byte) 0);
+ currentPosition = writer.BaseStream.Position;
+ writer.BaseStream.Position = SizePosition;
+ writer.Write((uint)currentPosition);
+ writer.BaseStream.Position = currentPosition;
+ writer.WritePadding();
- bw.Flush();
+ writer.Flush();
byte[] data = ms.ToArray();
- bw.Close();
+ writer.Close();
ms.Close();
entry.EntryBlocks[0].Data = data;
diff --git a/BaseHandlers/TriggerDataEditor.Designer.cs b/BaseHandlers/TriggerDataEditor.Designer.cs
new file mode 100644
index 0000000..a9a2275
--- /dev/null
+++ b/BaseHandlers/TriggerDataEditor.Designer.cs
@@ -0,0 +1,52 @@
+
+namespace BaseHandlers
+{
+ partial class TriggerDataEditor
+ {
+ private System.ComponentModel.IContainer components = null;
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Vom Windows Form-Designer generierter Code
+
+ ///
+ /// Erforderliche Methode für die Designerunterstützung.
+ /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
+ ///
+ private void InitializeComponent()
+ {
+ this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
+ this.SuspendLayout();
+ //
+ // propertyGrid1
+ //
+ this.propertyGrid1.Location = new System.Drawing.Point(-2, -4);
+ this.propertyGrid1.Name = "propertyGrid1";
+ this.propertyGrid1.Size = new System.Drawing.Size(802, 456);
+ this.propertyGrid1.TabIndex = 0;
+ this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.propertyGrid1_PropertyValueChanged);
+ //
+ // TriggerDataEditor
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(800, 450);
+ this.Controls.Add(this.propertyGrid1);
+ this.Name = "TriggerDataEditor";
+ this.Text = "Trigger Data Editor";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.PropertyGrid propertyGrid1;
+ }
+}
diff --git a/BaseHandlers/TriggerDataEditor.cs b/BaseHandlers/TriggerDataEditor.cs
new file mode 100644
index 0000000..b70299f
--- /dev/null
+++ b/BaseHandlers/TriggerDataEditor.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using PluginAPI;
+
+namespace BaseHandlers
+{
+
+ public delegate void Notify(); // delegate
+ public partial class TriggerDataEditor : Form, IEntryEditor
+ {
+ public event Notify EditEvent;
+
+ private TriggerData _trigger;
+ public TriggerData trigger
+ {
+ get => _trigger;
+ set
+ {
+ _trigger = value;
+ Console.WriteLine(value.muSize);
+ Console.WriteLine(_trigger.muSize);
+ Console.WriteLine(trigger.muSize);
+
+ UpdateComponent();
+ }
+ }
+
+ public void UpdateComponent()
+ {
+ propertyGrid1.SelectedObject = trigger;
+ }
+
+ public TriggerDataEditor()
+ {
+ InitializeComponent();
+ UpdateComponent();
+ }
+
+ private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
+ {
+ EditEvent?.Invoke();
+ }
+
+ private void propertyChanged() {
+ EditEvent?.Invoke();
+ }
+
+ }
+}
diff --git a/BaseHandlers/TriggerDataEditor.resx b/BaseHandlers/TriggerDataEditor.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/BaseHandlers/TriggerDataEditor.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/BundleUtilities/BinaryReader2.cs b/BundleUtilities/BinaryReader2.cs
index bf05259..8be95de 100644
--- a/BundleUtilities/BinaryReader2.cs
+++ b/BundleUtilities/BinaryReader2.cs
@@ -15,6 +15,13 @@ public class Vector3I
public float Y { get; set; }
public float Z { get; set; }
public float S { get; set; }
+
+ public Vector3I() {
+ X = 0;
+ Y = 0;
+ Z = 0;
+ S = 0;
+ }
public Vector3I(float x, float y, float z, float s)
{
X = x;