From 0f7f35d28b3d3d0d266159c521c5daca3b6a62fa Mon Sep 17 00:00:00 2001 From: dexy Date: Fri, 22 Nov 2019 00:34:27 +1100 Subject: [PATCH] Added RPF Explorer .yed, .yfd, .yld generic support --- CodeWalker.Core/CodeWalker.Core.csproj | 6 + .../GameFiles/FileTypes/YedFile.cs | 53 + .../GameFiles/FileTypes/YfdFile.cs | 53 + .../GameFiles/FileTypes/YldFile.cs | 53 + CodeWalker.Core/GameFiles/GameFile.cs | 3 + .../GameFiles/Resources/Clothes.cs | 1825 +++++++++++++++++ .../GameFiles/Resources/Expression.cs | 427 ++++ CodeWalker.Core/GameFiles/Resources/Filter.cs | 153 ++ CodeWalker.csproj | 9 + ExploreForm.cs | 40 +- Forms/GenericForm.Designer.cs | 61 + Forms/GenericForm.cs | 58 + Forms/GenericForm.resx | 409 ++++ 13 files changed, 3149 insertions(+), 1 deletion(-) create mode 100644 CodeWalker.Core/GameFiles/FileTypes/YedFile.cs create mode 100644 CodeWalker.Core/GameFiles/FileTypes/YfdFile.cs create mode 100644 CodeWalker.Core/GameFiles/FileTypes/YldFile.cs create mode 100644 CodeWalker.Core/GameFiles/Resources/Clothes.cs create mode 100644 CodeWalker.Core/GameFiles/Resources/Expression.cs create mode 100644 CodeWalker.Core/GameFiles/Resources/Filter.cs create mode 100644 Forms/GenericForm.Designer.cs create mode 100644 Forms/GenericForm.cs create mode 100644 Forms/GenericForm.resx diff --git a/CodeWalker.Core/CodeWalker.Core.csproj b/CodeWalker.Core/CodeWalker.Core.csproj index 1061806..ebe3724 100644 --- a/CodeWalker.Core/CodeWalker.Core.csproj +++ b/CodeWalker.Core/CodeWalker.Core.csproj @@ -71,7 +71,10 @@ + + + @@ -98,7 +101,10 @@ + + + diff --git a/CodeWalker.Core/GameFiles/FileTypes/YedFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YedFile.cs new file mode 100644 index 0000000..5caf37e --- /dev/null +++ b/CodeWalker.Core/GameFiles/FileTypes/YedFile.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CodeWalker.GameFiles +{ + [TypeConverter(typeof(ExpandableObjectConverter))] + public class YedFile : GameFile, PackedFile + { + public ExpressionDictionary ExpressionDictionary { get; set; } + + public string LoadException { get; set; } + + + public YedFile() : base(null, GameFileType.Yed) + { + } + public YedFile(RpfFileEntry entry) : base(entry, GameFileType.Yed) + { + } + + public void Load(byte[] data, RpfFileEntry entry) + { + Name = entry.Name; + RpfFileEntry = entry; + //Hash = entry.ShortNameHash; + + + RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; + if (resentry == null) + { + throw new Exception("File entry wasn't a resource! (is it binary data?)"); + } + + ResourceDataReader rd = null; + try + { + rd = new ResourceDataReader(resentry, data); + } + catch (Exception ex) + { + //data = entry.File.DecompressBytes(data); //?? + LoadException = ex.ToString(); + } + + ExpressionDictionary = rd?.ReadBlock(); + + } + } +} diff --git a/CodeWalker.Core/GameFiles/FileTypes/YfdFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YfdFile.cs new file mode 100644 index 0000000..7c7c8b3 --- /dev/null +++ b/CodeWalker.Core/GameFiles/FileTypes/YfdFile.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CodeWalker.GameFiles +{ + [TypeConverter(typeof(ExpandableObjectConverter))] + public class YfdFile : GameFile, PackedFile + { + public FrameFilterDictionary FrameFilterDictionary { get; set; } + + public string LoadException { get; set; } + + + public YfdFile() : base(null, GameFileType.Yfd) + { + } + public YfdFile(RpfFileEntry entry) : base(entry, GameFileType.Yfd) + { + } + + public void Load(byte[] data, RpfFileEntry entry) + { + Name = entry.Name; + RpfFileEntry = entry; + //Hash = entry.ShortNameHash; + + + RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; + if (resentry == null) + { + throw new Exception("File entry wasn't a resource! (is it binary data?)"); + } + + ResourceDataReader rd = null; + try + { + rd = new ResourceDataReader(resentry, data); + } + catch (Exception ex) + { + //data = entry.File.DecompressBytes(data); //?? + LoadException = ex.ToString(); + } + + FrameFilterDictionary = rd?.ReadBlock(); + + } + } +} diff --git a/CodeWalker.Core/GameFiles/FileTypes/YldFile.cs b/CodeWalker.Core/GameFiles/FileTypes/YldFile.cs new file mode 100644 index 0000000..a7bd9d6 --- /dev/null +++ b/CodeWalker.Core/GameFiles/FileTypes/YldFile.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CodeWalker.GameFiles +{ + [TypeConverter(typeof(ExpandableObjectConverter))] + public class YldFile : GameFile, PackedFile + { + public ClothDictionary ClothDictionary { get; set; } + + public string LoadException { get; set; } + + + public YldFile() : base(null, GameFileType.Yld) + { + } + public YldFile(RpfFileEntry entry) : base(entry, GameFileType.Yld) + { + } + + public void Load(byte[] data, RpfFileEntry entry) + { + Name = entry.Name; + RpfFileEntry = entry; + //Hash = entry.ShortNameHash; + + + RpfResourceFileEntry resentry = entry as RpfResourceFileEntry; + if (resentry == null) + { + throw new Exception("File entry wasn't a resource! (is it binary data?)"); + } + + ResourceDataReader rd = null; + try + { + rd = new ResourceDataReader(resentry, data); + } + catch (Exception ex) + { + //data = entry.File.DecompressBytes(data); //?? + LoadException = ex.ToString(); + } + + ClothDictionary = rd?.ReadBlock(); + + } + } +} diff --git a/CodeWalker.Core/GameFiles/GameFile.cs b/CodeWalker.Core/GameFiles/GameFile.cs index 631cc83..fa8442d 100644 --- a/CodeWalker.Core/GameFiles/GameFile.cs +++ b/CodeWalker.Core/GameFiles/GameFile.cs @@ -77,6 +77,9 @@ namespace CodeWalker.GameFiles VehicleLayouts = 21, Peds = 22, Ped = 23, + Yed = 24, + Yld = 25, + Yfd = 26, } diff --git a/CodeWalker.Core/GameFiles/Resources/Clothes.cs b/CodeWalker.Core/GameFiles/Resources/Clothes.cs new file mode 100644 index 0000000..f6f9c97 --- /dev/null +++ b/CodeWalker.Core/GameFiles/Resources/Clothes.cs @@ -0,0 +1,1825 @@ +using SharpDX; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +/* + Copyright(c) 2017 Neodymium + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + + +//ruthlessly stolen + + +namespace CodeWalker.GameFiles +{ + + [TypeConverter(typeof(ExpandableObjectConverter))] public class ClothDictionary : ResourceFileBase + { + // pgBase + // pgDictionaryBase + // pgDictionary + public override long BlockLength => 0x40; + + // structure data + public uint Unknown_10h { get; set; } // 0x00000000 + public uint Unknown_14h { get; set; } // 0x00000000 + public uint Unknown_18h { get; set; } // 0x00000001 + public uint Unknown_1Ch { get; set; } // 0x00000000 + public ResourceSimpleList64_uint ClothNameHashes { get; set; } + public ResourcePointerList64 Clothes { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + base.Read(reader, parameters); + + // read structure data + this.Unknown_10h = reader.ReadUInt32(); + this.Unknown_14h = reader.ReadUInt32(); + this.Unknown_18h = reader.ReadUInt32(); + this.Unknown_1Ch = reader.ReadUInt32(); + this.ClothNameHashes = reader.ReadBlock(); + this.Clothes = reader.ReadBlock>(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + base.Write(writer, parameters); + + // write structure data + writer.Write(this.Unknown_10h); + writer.Write(this.Unknown_14h); + writer.Write(this.Unknown_18h); + writer.Write(this.Unknown_1Ch); + writer.WriteBlock(this.ClothNameHashes); + writer.WriteBlock(this.Clothes); + } + + public override Tuple[] GetParts() + { + return new Tuple[] { + new Tuple(0x20, ClothNameHashes), + new Tuple(0x30, Clothes) + }; + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class ClothController : ResourceSystemBlock + { + // clothController + public override long BlockLength => 0x80; + + // structure data + public uint VFT { get; set; } + public uint Unknown_4h { get; set; } // 0x00000001 + public uint Unknown_8h { get; set; } // 0x00000000 + public uint Unknown_Ch { get; set; } // 0x00000000 + public ulong BridgeSimGfxPointer { get; set; } + public ulong MorphControllerPointer { get; set; } + public ulong VerletCloth1Pointer { get; set; } + public ulong VerletCloth2Pointer { get; set; } + public ulong VerletCloth3Pointer { get; set; } + public uint Unknown_38h { get; set; } // 0x00000000 + public uint Unknown_3Ch { get; set; } // 0x00000000 + public uint Unknown_40h { get; set; } // 0x00000000 + public uint Unknown_44h { get; set; } // 0x00000000 + public uint Unknown_48h { get; set; } // 0x00000000 + public uint Unknown_4Ch { get; set; } // 0x00000000 + public uint Type { get; set; } + public uint Unknown_54h { get; set; } // 0x00000000 + public uint Unknown_58h { get; set; } // no float + public uint Unknown_5Ch { get; set; } // no float + public uint Unknown_60h { get; set; } // no float + public uint Unknown_64h { get; set; } // no float + public uint Unknown_68h { get; set; } // no float + public uint Unknown_6Ch { get; set; } // no float + public uint Unknown_70h { get; set; } // no float + public uint Unknown_74h { get; set; } // 0x00000000 + public uint Unknown_78h { get; set; } // 0x00000000 + public uint Unknown_7Ch { get; set; } // 0x00000000 + + // reference data + public ClothBridgeSimGfx BridgeSimGfx { get; set; } + public MorphController MorphController { get; set; } + public VerletCloth VerletCloth1 { get; set; } + public VerletCloth VerletCloth2 { get; set; } + public VerletCloth VerletCloth3 { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.VFT = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + this.BridgeSimGfxPointer = reader.ReadUInt64(); + this.MorphControllerPointer = reader.ReadUInt64(); + this.VerletCloth1Pointer = reader.ReadUInt64(); + this.VerletCloth2Pointer = reader.ReadUInt64(); + this.VerletCloth3Pointer = reader.ReadUInt64(); + this.Unknown_38h = reader.ReadUInt32(); + this.Unknown_3Ch = reader.ReadUInt32(); + this.Unknown_40h = reader.ReadUInt32(); + this.Unknown_44h = reader.ReadUInt32(); + this.Unknown_48h = reader.ReadUInt32(); + this.Unknown_4Ch = reader.ReadUInt32(); + this.Type = reader.ReadUInt32(); + this.Unknown_54h = reader.ReadUInt32(); + this.Unknown_58h = reader.ReadUInt32(); + this.Unknown_5Ch = reader.ReadUInt32(); + this.Unknown_60h = reader.ReadUInt32(); + this.Unknown_64h = reader.ReadUInt32(); + this.Unknown_68h = reader.ReadUInt32(); + this.Unknown_6Ch = reader.ReadUInt32(); + this.Unknown_70h = reader.ReadUInt32(); + this.Unknown_74h = reader.ReadUInt32(); + this.Unknown_78h = reader.ReadUInt32(); + this.Unknown_7Ch = reader.ReadUInt32(); + + // read reference data + this.BridgeSimGfx = reader.ReadBlockAt( + this.BridgeSimGfxPointer // offset + ); + this.MorphController = reader.ReadBlockAt( + this.MorphControllerPointer // offset + ); + this.VerletCloth1 = reader.ReadBlockAt( + this.VerletCloth1Pointer // offset + ); + this.VerletCloth2 = reader.ReadBlockAt( + this.VerletCloth2Pointer // offset + ); + this.VerletCloth3 = reader.ReadBlockAt( + this.VerletCloth3Pointer // offset + ); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // update structure data + this.BridgeSimGfxPointer = (ulong)(this.BridgeSimGfx != null ? this.BridgeSimGfx.FilePosition : 0); + this.MorphControllerPointer = (ulong)(this.MorphController != null ? this.MorphController.FilePosition : 0); + this.VerletCloth1Pointer = (ulong)(this.VerletCloth1 != null ? this.VerletCloth1.FilePosition : 0); + this.VerletCloth2Pointer = (ulong)(this.VerletCloth2 != null ? this.VerletCloth2.FilePosition : 0); + this.VerletCloth3Pointer = (ulong)(this.VerletCloth3 != null ? this.VerletCloth3.FilePosition : 0); + + // write structure data + writer.Write(this.VFT); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + writer.Write(this.BridgeSimGfxPointer); + writer.Write(this.MorphControllerPointer); + writer.Write(this.VerletCloth1Pointer); + writer.Write(this.VerletCloth2Pointer); + writer.Write(this.VerletCloth3Pointer); + writer.Write(this.Unknown_38h); + writer.Write(this.Unknown_3Ch); + writer.Write(this.Unknown_40h); + writer.Write(this.Unknown_44h); + writer.Write(this.Unknown_48h); + writer.Write(this.Unknown_4Ch); + writer.Write(this.Type); + writer.Write(this.Unknown_54h); + writer.Write(this.Unknown_58h); + writer.Write(this.Unknown_5Ch); + writer.Write(this.Unknown_60h); + writer.Write(this.Unknown_64h); + writer.Write(this.Unknown_68h); + writer.Write(this.Unknown_6Ch); + writer.Write(this.Unknown_70h); + writer.Write(this.Unknown_74h); + writer.Write(this.Unknown_78h); + writer.Write(this.Unknown_7Ch); + } + + /// + /// Returns a list of data blocks which are referenced by this block. + /// + public override IResourceBlock[] GetReferences() + { + var list = new List(); + if (BridgeSimGfx != null) list.Add(BridgeSimGfx); + if (MorphController != null) list.Add(MorphController); + if (VerletCloth1 != null) list.Add(VerletCloth1); + if (VerletCloth2 != null) list.Add(VerletCloth2); + if (VerletCloth3 != null) list.Add(VerletCloth3); + return list.ToArray(); + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class ClothBridgeSimGfx : ResourceSystemBlock + { + // pgBase + // clothBridgeSimGfx + public override long BlockLength => 0x140; + + // structure data + public uint VFT { get; set; } + public uint Unknown_4h { get; set; } // 0x00000001 + public uint Unknown_8h { get; set; } // 0x00000000 + public uint Unknown_Ch { get; set; } // 0x00000000 + public uint Unknown_10h { get; set; } + public uint Unknown_14h { get; set; } + public uint Unknown_18h { get; set; } + public uint Unknown_1Ch { get; set; } // 0x00000000 + public ResourceSimpleList64_float Unknown_20h { get; set; } + public ResourceSimpleList64_float Unknown_30h { get; set; } + public ResourceSimpleList64_float Unknown_40h { get; set; } + public uint Unknown_50h { get; set; } // 0x00000000 + public uint Unknown_54h { get; set; } // 0x00000000 + public uint Unknown_58h { get; set; } // 0x00000000 + public uint Unknown_5Ch { get; set; } // 0x00000000 + public ResourceSimpleList64_float Unknown_60h { get; set; } + public ResourceSimpleList64_uint Unknown_70h { get; set; } + public ResourceSimpleList64_uint Unknown_80h { get; set; } + public uint Unknown_90h { get; set; } // 0x00000000 + public uint Unknown_94h { get; set; } // 0x00000000 + public uint Unknown_98h { get; set; } // 0x00000000 + public uint Unknown_9Ch { get; set; } // 0x00000000 + public ResourceSimpleList64_float Unknown_A0h { get; set; } + public ResourceSimpleList64_uint Unknown_B0h { get; set; } + public ResourceSimpleList64_uint Unknown_C0h { get; set; } + public uint Unknown_D0h { get; set; } // 0x00000000 + public uint Unknown_D4h { get; set; } // 0x00000000 + public uint Unknown_D8h { get; set; } // 0x00000000 + public uint Unknown_DCh { get; set; } // 0x00000000 + public ResourceSimpleList64_ushort Unknown_E0h { get; set; } + public ResourceSimpleList64_ushort Unknown_F0h { get; set; } + public ResourceSimpleList64_ushort Unknown_100h { get; set; } + public uint Unknown_110h { get; set; } // 0x00000000 + public uint Unknown_114h { get; set; } // 0x00000000 + public uint Unknown_118h { get; set; } // 0x00000000 + public uint Unknown_11Ch { get; set; } // 0x00000000 + public uint Unknown_120h { get; set; } // 0x00000000 + public uint Unknown_124h { get; set; } // 0x00000000 + public ResourceSimpleList64_uint Unknown_128h { get; set; } + public uint Unknown_138h { get; set; } // 0x00000000 + public uint Unknown_13Ch { get; set; } // 0x00000000 + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.VFT = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + this.Unknown_10h = reader.ReadUInt32(); + this.Unknown_14h = reader.ReadUInt32(); + this.Unknown_18h = reader.ReadUInt32(); + this.Unknown_1Ch = reader.ReadUInt32(); + this.Unknown_20h = reader.ReadBlock(); + this.Unknown_30h = reader.ReadBlock(); + this.Unknown_40h = reader.ReadBlock(); + this.Unknown_50h = reader.ReadUInt32(); + this.Unknown_54h = reader.ReadUInt32(); + this.Unknown_58h = reader.ReadUInt32(); + this.Unknown_5Ch = reader.ReadUInt32(); + this.Unknown_60h = reader.ReadBlock(); + this.Unknown_70h = reader.ReadBlock(); + this.Unknown_80h = reader.ReadBlock(); + this.Unknown_90h = reader.ReadUInt32(); + this.Unknown_94h = reader.ReadUInt32(); + this.Unknown_98h = reader.ReadUInt32(); + this.Unknown_9Ch = reader.ReadUInt32(); + this.Unknown_A0h = reader.ReadBlock(); + this.Unknown_B0h = reader.ReadBlock(); + this.Unknown_C0h = reader.ReadBlock(); + this.Unknown_D0h = reader.ReadUInt32(); + this.Unknown_D4h = reader.ReadUInt32(); + this.Unknown_D8h = reader.ReadUInt32(); + this.Unknown_DCh = reader.ReadUInt32(); + this.Unknown_E0h = reader.ReadBlock(); + this.Unknown_F0h = reader.ReadBlock(); + this.Unknown_100h = reader.ReadBlock(); + this.Unknown_110h = reader.ReadUInt32(); + this.Unknown_114h = reader.ReadUInt32(); + this.Unknown_118h = reader.ReadUInt32(); + this.Unknown_11Ch = reader.ReadUInt32(); + this.Unknown_120h = reader.ReadUInt32(); + this.Unknown_124h = reader.ReadUInt32(); + this.Unknown_128h = reader.ReadBlock(); + this.Unknown_138h = reader.ReadUInt32(); + this.Unknown_13Ch = reader.ReadUInt32(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // write structure data + writer.Write(this.VFT); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + writer.Write(this.Unknown_10h); + writer.Write(this.Unknown_14h); + writer.Write(this.Unknown_18h); + writer.Write(this.Unknown_1Ch); + writer.WriteBlock(this.Unknown_20h); + writer.WriteBlock(this.Unknown_30h); + writer.WriteBlock(this.Unknown_40h); + writer.Write(this.Unknown_50h); + writer.Write(this.Unknown_54h); + writer.Write(this.Unknown_58h); + writer.Write(this.Unknown_5Ch); + writer.WriteBlock(this.Unknown_60h); + writer.WriteBlock(this.Unknown_70h); + writer.WriteBlock(this.Unknown_80h); + writer.Write(this.Unknown_90h); + writer.Write(this.Unknown_94h); + writer.Write(this.Unknown_98h); + writer.Write(this.Unknown_9Ch); + writer.WriteBlock(this.Unknown_A0h); + writer.WriteBlock(this.Unknown_B0h); + writer.WriteBlock(this.Unknown_C0h); + writer.Write(this.Unknown_D0h); + writer.Write(this.Unknown_D4h); + writer.Write(this.Unknown_D8h); + writer.Write(this.Unknown_DCh); + writer.WriteBlock(this.Unknown_E0h); + writer.WriteBlock(this.Unknown_F0h); + writer.WriteBlock(this.Unknown_100h); + writer.Write(this.Unknown_110h); + writer.Write(this.Unknown_114h); + writer.Write(this.Unknown_118h); + writer.Write(this.Unknown_11Ch); + writer.Write(this.Unknown_120h); + writer.Write(this.Unknown_124h); + writer.WriteBlock(this.Unknown_128h); + writer.Write(this.Unknown_138h); + writer.Write(this.Unknown_13Ch); + } + + public override Tuple[] GetParts() + { + return new Tuple[] { + new Tuple(0x20, Unknown_20h), + new Tuple(0x30, Unknown_30h), + new Tuple(0x40, Unknown_40h), + new Tuple(0x60, Unknown_60h), + new Tuple(0x70, Unknown_70h), + new Tuple(0x80, Unknown_80h), + new Tuple(0xA0, Unknown_A0h), + new Tuple(0xB0, Unknown_B0h), + new Tuple(0xC0, Unknown_C0h), + new Tuple(0xE0, Unknown_E0h), + new Tuple(0xF0, Unknown_F0h), + new Tuple(0x100, Unknown_100h), + new Tuple(0x128, Unknown_128h) + }; + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class ClothInstanceTuning : ResourceSystemBlock + { + // pgBase + // clothInstanceTuning + public override long BlockLength => 0x40; + + // structure data + public uint VFT { get; set; } + public uint Unknown_4h { get; set; } // 0x00000001 + public uint Unknown_8h { get; set; } // 0x00000000 + public uint Unknown_Ch { get; set; } // 0x00000000 + public uint Unknown_10h { get; set; } // float + public uint Unknown_14h { get; set; } + public uint Unknown_18h { get; set; } // 0x00000000 + public uint Unknown_1Ch { get; set; } // 0x00000000 + public uint Unknown_20h { get; set; } + public uint Unknown_24h { get; set; } + public uint Unknown_28h { get; set; } // float + public uint Unknown_2Ch { get; set; } + public uint Unknown_30h { get; set; } // no float + public uint Unknown_34h { get; set; } // float + public uint Unknown_38h { get; set; } + public uint Unknown_3Ch { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.VFT = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + this.Unknown_10h = reader.ReadUInt32(); + this.Unknown_14h = reader.ReadUInt32(); + this.Unknown_18h = reader.ReadUInt32(); + this.Unknown_1Ch = reader.ReadUInt32(); + this.Unknown_20h = reader.ReadUInt32(); + this.Unknown_24h = reader.ReadUInt32(); + this.Unknown_28h = reader.ReadUInt32(); + this.Unknown_2Ch = reader.ReadUInt32(); + this.Unknown_30h = reader.ReadUInt32(); + this.Unknown_34h = reader.ReadUInt32(); + this.Unknown_38h = reader.ReadUInt32(); + this.Unknown_3Ch = reader.ReadUInt32(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // write structure data + writer.Write(this.VFT); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + writer.Write(this.Unknown_10h); + writer.Write(this.Unknown_14h); + writer.Write(this.Unknown_18h); + writer.Write(this.Unknown_1Ch); + writer.Write(this.Unknown_20h); + writer.Write(this.Unknown_24h); + writer.Write(this.Unknown_28h); + writer.Write(this.Unknown_2Ch); + writer.Write(this.Unknown_30h); + writer.Write(this.Unknown_34h); + writer.Write(this.Unknown_38h); + writer.Write(this.Unknown_3Ch); + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class VerletCloth : ResourceSystemBlock + { + // pgBase + // phVerletCloth + public override long BlockLength => 0x180; + + // structure data + public uint VFT { get; set; } + public uint Unknown_4h { get; set; } // 0x00000001 + public uint Unknown_8h { get; set; } // 0x00000000 + public uint Unknown_Ch { get; set; } // 0x00000000 + public uint Unknown_10h { get; set; } // 0x00000000 + public uint Unknown_14h { get; set; } // 0x00000000 + public ulong BoundPointer { get; set; } + public uint Unknown_20h { get; set; } // 0x00000000 + public uint Unknown_24h { get; set; } // 0x00000000 + public uint Unknown_28h { get; set; } // 0x00000000 + public uint Unknown_2Ch { get; set; } // 0x00000000 + public uint Unknown_30h { get; set; } + public uint Unknown_34h { get; set; } + public uint Unknown_38h { get; set; } + public uint Unknown_3Ch { get; set; } + public uint Unknown_40h { get; set; } + public uint Unknown_44h { get; set; } + public uint Unknown_48h { get; set; } + public uint Unknown_4Ch { get; set; } + public uint Unknown_50h { get; set; } + public uint Unknown_54h { get; set; } // 0x00000001 + public uint Unknown_58h { get; set; } // 0x00000000 + public uint Unknown_5Ch { get; set; } // 0x00000000 + public uint Unknown_60h { get; set; } // 0x00000000 + public uint Unknown_64h { get; set; } // 0x00000000 + public uint Unknown_68h { get; set; } // 0x00000000 + public uint Unknown_6Ch { get; set; } // 0x00000000 + public ResourceSimpleList64_s Unknown_70h { get; set; } + public ResourceSimpleList64_s Unknown_80h { get; set; } + public uint Unknown_90h { get; set; } // 0x00000000 + public uint Unknown_94h { get; set; } // 0x00000000 + public uint Unknown_98h { get; set; } // 0x00000000 + public uint Unknown_9Ch { get; set; } // 0x00000000 + public uint Unknown_A0h { get; set; } // 0x00000000 + public uint Unknown_A4h { get; set; } // 0x00000000 + public uint Unknown_A8h { get; set; } + public uint Unknown_ACh { get; set; } + public uint Unknown_B0h { get; set; } // 0x00000000 + public uint Unknown_B4h { get; set; } // 0x00000000 + public uint Unknown_B8h { get; set; } // 0x00000000 + public uint Unknown_BCh { get; set; } // 0x00000000 + public uint Unknown_C0h { get; set; } // 0x00000000 + public uint Unknown_C4h { get; set; } // 0x00000000 + public uint Unknown_C8h { get; set; } // 0x00000000 + public uint Unknown_CCh { get; set; } // 0x00000000 + public uint Unknown_D0h { get; set; } // 0x00000000 + public uint Unknown_D4h { get; set; } // 0x00000000 + public uint Unknown_D8h { get; set; } // 0x00000000 + public uint Unknown_DCh { get; set; } // 0x00000000 + public uint Unknown_E0h { get; set; } // 0x00000000 + public uint Unknown_E4h { get; set; } // 0x00000000 + public uint Unknown_E8h { get; set; } + public uint Unknown_ECh { get; set; } + public uint Unknown_F0h { get; set; } + public uint Unknown_F4h { get; set; } // 0x00000000 + public uint Unknown_F8h { get; set; } + public uint Unknown_FCh { get; set; } // 0x00000000 + public ResourceSimpleList64 Unknown_100h { get; set; } + public ResourceSimpleList64 Unknown_110h { get; set; } + public uint Unknown_120h { get; set; } // 0x00000000 + public uint Unknown_124h { get; set; } // 0x00000000 + public uint Unknown_128h { get; set; } // 0x00000000 + public uint Unknown_12Ch { get; set; } // 0x00000000 + public ulong BehaviorPointer { get; set; } + public uint Unknown_138h { get; set; } // 0x00100000 + public uint Unknown_13Ch { get; set; } // 0x00000000 + public ulong Unknown_140h_Pointer { get; set; } + public uint Unknown_148h { get; set; } + public uint Unknown_14Ch { get; set; } // 0x00000000 + public uint Unknown_150h { get; set; } // 0x00000000 + public uint Unknown_154h { get; set; } // 0x00000000 + public uint Unknown_158h { get; set; } + public uint Unknown_15Ch { get; set; } // 0x00000000 + public uint Unknown_160h { get; set; } // 0x00000000 + public uint Unknown_164h { get; set; } // 0x00000000 + public uint Unknown_168h { get; set; } // 0x00000000 + public uint Unknown_16Ch { get; set; } // 0x00000000 + public uint Unknown_170h { get; set; } // 0x00000000 + public uint Unknown_174h { get; set; } // 0x00000000 + public uint Unknown_178h { get; set; } // 0x00000000 + public uint Unknown_17Ch { get; set; } // 0x00000000 + + // reference data + public Bounds Bound { get; set; } + public EnvClothVerletBehavior Behavior { get; set; } + public Unknown_C_007 Unknown_140h_Data { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.VFT = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + this.Unknown_10h = reader.ReadUInt32(); + this.Unknown_14h = reader.ReadUInt32(); + this.BoundPointer = reader.ReadUInt64(); + this.Unknown_20h = reader.ReadUInt32(); + this.Unknown_24h = reader.ReadUInt32(); + this.Unknown_28h = reader.ReadUInt32(); + this.Unknown_2Ch = reader.ReadUInt32(); + this.Unknown_30h = reader.ReadUInt32(); + this.Unknown_34h = reader.ReadUInt32(); + this.Unknown_38h = reader.ReadUInt32(); + this.Unknown_3Ch = reader.ReadUInt32(); + this.Unknown_40h = reader.ReadUInt32(); + this.Unknown_44h = reader.ReadUInt32(); + this.Unknown_48h = reader.ReadUInt32(); + this.Unknown_4Ch = reader.ReadUInt32(); + this.Unknown_50h = reader.ReadUInt32(); + this.Unknown_54h = reader.ReadUInt32(); + this.Unknown_58h = reader.ReadUInt32(); + this.Unknown_5Ch = reader.ReadUInt32(); + this.Unknown_60h = reader.ReadUInt32(); + this.Unknown_64h = reader.ReadUInt32(); + this.Unknown_68h = reader.ReadUInt32(); + this.Unknown_6Ch = reader.ReadUInt32(); + this.Unknown_70h = reader.ReadBlock>(); + this.Unknown_80h = reader.ReadBlock>(); + this.Unknown_90h = reader.ReadUInt32(); + this.Unknown_94h = reader.ReadUInt32(); + this.Unknown_98h = reader.ReadUInt32(); + this.Unknown_9Ch = reader.ReadUInt32(); + this.Unknown_A0h = reader.ReadUInt32(); + this.Unknown_A4h = reader.ReadUInt32(); + this.Unknown_A8h = reader.ReadUInt32(); + this.Unknown_ACh = reader.ReadUInt32(); + this.Unknown_B0h = reader.ReadUInt32(); + this.Unknown_B4h = reader.ReadUInt32(); + this.Unknown_B8h = reader.ReadUInt32(); + this.Unknown_BCh = reader.ReadUInt32(); + this.Unknown_C0h = reader.ReadUInt32(); + this.Unknown_C4h = reader.ReadUInt32(); + this.Unknown_C8h = reader.ReadUInt32(); + this.Unknown_CCh = reader.ReadUInt32(); + this.Unknown_D0h = reader.ReadUInt32(); + this.Unknown_D4h = reader.ReadUInt32(); + this.Unknown_D8h = reader.ReadUInt32(); + this.Unknown_DCh = reader.ReadUInt32(); + this.Unknown_E0h = reader.ReadUInt32(); + this.Unknown_E4h = reader.ReadUInt32(); + this.Unknown_E8h = reader.ReadUInt32(); + this.Unknown_ECh = reader.ReadUInt32(); + this.Unknown_F0h = reader.ReadUInt32(); + this.Unknown_F4h = reader.ReadUInt32(); + this.Unknown_F8h = reader.ReadUInt32(); + this.Unknown_FCh = reader.ReadUInt32(); + this.Unknown_100h = reader.ReadBlock>(); + this.Unknown_110h = reader.ReadBlock>(); + this.Unknown_120h = reader.ReadUInt32(); + this.Unknown_124h = reader.ReadUInt32(); + this.Unknown_128h = reader.ReadUInt32(); + this.Unknown_12Ch = reader.ReadUInt32(); + this.BehaviorPointer = reader.ReadUInt64(); + this.Unknown_138h = reader.ReadUInt32(); + this.Unknown_13Ch = reader.ReadUInt32(); + this.Unknown_140h_Pointer = reader.ReadUInt64(); + this.Unknown_148h = reader.ReadUInt32(); + this.Unknown_14Ch = reader.ReadUInt32(); + this.Unknown_150h = reader.ReadUInt32(); + this.Unknown_154h = reader.ReadUInt32(); + this.Unknown_158h = reader.ReadUInt32(); + this.Unknown_15Ch = reader.ReadUInt32(); + this.Unknown_160h = reader.ReadUInt32(); + this.Unknown_164h = reader.ReadUInt32(); + this.Unknown_168h = reader.ReadUInt32(); + this.Unknown_16Ch = reader.ReadUInt32(); + this.Unknown_170h = reader.ReadUInt32(); + this.Unknown_174h = reader.ReadUInt32(); + this.Unknown_178h = reader.ReadUInt32(); + this.Unknown_17Ch = reader.ReadUInt32(); + + // read reference data + this.Bound = reader.ReadBlockAt( + this.BoundPointer // offset + ); + this.Behavior = reader.ReadBlockAt( + this.BehaviorPointer // offset + ); + this.Unknown_140h_Data = reader.ReadBlockAt( + this.Unknown_140h_Pointer // offset + ); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // update structure data + this.BoundPointer = (ulong)(this.Bound != null ? this.Bound.FilePosition : 0); + this.BehaviorPointer = (ulong)(this.Behavior != null ? this.Behavior.FilePosition : 0); + this.Unknown_140h_Pointer = (ulong)(this.Unknown_140h_Data != null ? this.Unknown_140h_Data.FilePosition : 0); + + // write structure data + writer.Write(this.VFT); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + writer.Write(this.Unknown_10h); + writer.Write(this.Unknown_14h); + writer.Write(this.BoundPointer); + writer.Write(this.Unknown_20h); + writer.Write(this.Unknown_24h); + writer.Write(this.Unknown_28h); + writer.Write(this.Unknown_2Ch); + writer.Write(this.Unknown_30h); + writer.Write(this.Unknown_34h); + writer.Write(this.Unknown_38h); + writer.Write(this.Unknown_3Ch); + writer.Write(this.Unknown_40h); + writer.Write(this.Unknown_44h); + writer.Write(this.Unknown_48h); + writer.Write(this.Unknown_4Ch); + writer.Write(this.Unknown_50h); + writer.Write(this.Unknown_54h); + writer.Write(this.Unknown_58h); + writer.Write(this.Unknown_5Ch); + writer.Write(this.Unknown_60h); + writer.Write(this.Unknown_64h); + writer.Write(this.Unknown_68h); + writer.Write(this.Unknown_6Ch); + writer.WriteBlock(this.Unknown_70h); + writer.WriteBlock(this.Unknown_80h); + writer.Write(this.Unknown_90h); + writer.Write(this.Unknown_94h); + writer.Write(this.Unknown_98h); + writer.Write(this.Unknown_9Ch); + writer.Write(this.Unknown_A0h); + writer.Write(this.Unknown_A4h); + writer.Write(this.Unknown_A8h); + writer.Write(this.Unknown_ACh); + writer.Write(this.Unknown_B0h); + writer.Write(this.Unknown_B4h); + writer.Write(this.Unknown_B8h); + writer.Write(this.Unknown_BCh); + writer.Write(this.Unknown_C0h); + writer.Write(this.Unknown_C4h); + writer.Write(this.Unknown_C8h); + writer.Write(this.Unknown_CCh); + writer.Write(this.Unknown_D0h); + writer.Write(this.Unknown_D4h); + writer.Write(this.Unknown_D8h); + writer.Write(this.Unknown_DCh); + writer.Write(this.Unknown_E0h); + writer.Write(this.Unknown_E4h); + writer.Write(this.Unknown_E8h); + writer.Write(this.Unknown_ECh); + writer.Write(this.Unknown_F0h); + writer.Write(this.Unknown_F4h); + writer.Write(this.Unknown_F8h); + writer.Write(this.Unknown_FCh); + writer.WriteBlock(this.Unknown_100h); + writer.WriteBlock(this.Unknown_110h); + writer.Write(this.Unknown_120h); + writer.Write(this.Unknown_124h); + writer.Write(this.Unknown_128h); + writer.Write(this.Unknown_12Ch); + writer.Write(this.BehaviorPointer); + writer.Write(this.Unknown_138h); + writer.Write(this.Unknown_13Ch); + writer.Write(this.Unknown_140h_Pointer); + writer.Write(this.Unknown_148h); + writer.Write(this.Unknown_14Ch); + writer.Write(this.Unknown_150h); + writer.Write(this.Unknown_154h); + writer.Write(this.Unknown_158h); + writer.Write(this.Unknown_15Ch); + writer.Write(this.Unknown_160h); + writer.Write(this.Unknown_164h); + writer.Write(this.Unknown_168h); + writer.Write(this.Unknown_16Ch); + writer.Write(this.Unknown_170h); + writer.Write(this.Unknown_174h); + writer.Write(this.Unknown_178h); + writer.Write(this.Unknown_17Ch); + } + + /// + /// Returns a list of data blocks which are referenced by this block. + /// + public override IResourceBlock[] GetReferences() + { + var list = new List(); + if (Bound != null) list.Add(Bound); + if (Behavior != null) list.Add(Behavior); + if (Unknown_140h_Data != null) list.Add(Unknown_140h_Data); + return list.ToArray(); + } + + public override Tuple[] GetParts() + { + return new Tuple[] { + new Tuple(0x70, Unknown_70h), + new Tuple(0x80, Unknown_80h), + new Tuple(0x100, Unknown_100h), + new Tuple(0x110, Unknown_110h) + }; + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class EnvClothVerletBehavior : ResourceSystemBlock + { + // datBase + // phInstBehavior + // phClothVerletBehavior + // phEnvClothVerletBehavior + public override long BlockLength => 0x40; + + // structure data + public uint Unknown_0h { get; set; } // 0x00000000 + public uint Unknown_4h { get; set; } // 0x00000000 + public uint Unknown_8h { get; set; } // 0x00000000 + public uint Unknown_Ch { get; set; } // 0x00000000 + public uint Unknown_10h { get; set; } // 0x00000000 + public uint Unknown_14h { get; set; } // 0x00000000 + public uint Unknown_18h { get; set; } // 0x00000000 + public uint Unknown_1Ch { get; set; } // 0x00000000 + public uint Unknown_20h { get; set; } // 0x00000000 + public uint Unknown_24h { get; set; } // 0x00000000 + public uint Unknown_28h { get; set; } // 0x00000000 + public uint Unknown_2Ch { get; set; } // 0x00000000 + public uint Unknown_30h { get; set; } // 0x00000000 + public uint Unknown_34h { get; set; } // 0x00000000 + public uint Unknown_38h { get; set; } // 0x00000000 + public uint Unknown_3Ch { get; set; } // 0x00000000 + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.Unknown_0h = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + this.Unknown_10h = reader.ReadUInt32(); + this.Unknown_14h = reader.ReadUInt32(); + this.Unknown_18h = reader.ReadUInt32(); + this.Unknown_1Ch = reader.ReadUInt32(); + this.Unknown_20h = reader.ReadUInt32(); + this.Unknown_24h = reader.ReadUInt32(); + this.Unknown_28h = reader.ReadUInt32(); + this.Unknown_2Ch = reader.ReadUInt32(); + this.Unknown_30h = reader.ReadUInt32(); + this.Unknown_34h = reader.ReadUInt32(); + this.Unknown_38h = reader.ReadUInt32(); + this.Unknown_3Ch = reader.ReadUInt32(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // write structure data + writer.Write(this.Unknown_0h); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + writer.Write(this.Unknown_10h); + writer.Write(this.Unknown_14h); + writer.Write(this.Unknown_18h); + writer.Write(this.Unknown_1Ch); + writer.Write(this.Unknown_20h); + writer.Write(this.Unknown_24h); + writer.Write(this.Unknown_28h); + writer.Write(this.Unknown_2Ch); + writer.Write(this.Unknown_30h); + writer.Write(this.Unknown_34h); + writer.Write(this.Unknown_38h); + writer.Write(this.Unknown_3Ch); + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class EnvironmentCloth : ResourceSystemBlock + { + // pgBase + // clothBase (TODO) + // environmentCloth + public override long BlockLength => 0x80; + + // structure data + public uint VFT { get; set; } + public uint Unknown_4h { get; set; } // 0x00000001 + public uint Unknown_8h { get; set; } // 0x00000000 + public uint Unknown_Ch { get; set; } // 0x00000000 + public ulong InstanceTuningPointer { get; set; } + public ulong DrawablePointer { get; set; } + public uint Unknown_20h { get; set; } // 0x00000000 + public uint Unknown_24h { get; set; } // 0x00000000 + public ulong ControllerPointer { get; set; } + public uint Unknown_30h { get; set; } // 0x00000000 + public uint Unknown_34h { get; set; } // 0x00000000 + public uint Unknown_38h { get; set; } // 0x00000000 + public uint Unknown_3Ch { get; set; } // 0x00000000 + public uint Unknown_40h { get; set; } // 0x00000000 + public uint Unknown_44h { get; set; } // 0x00000000 + public uint Unknown_48h { get; set; } // 0x00000000 + public uint Unknown_4Ch { get; set; } // 0x00000000 + public uint Unknown_50h { get; set; } // 0x00000000 + public uint Unknown_54h { get; set; } // 0x00000000 + public uint Unknown_58h { get; set; } // 0x00000000 + public uint Unknown_5Ch { get; set; } // 0x00000000 + public ulong pxxxxx_2 { get; set; } + public ushort cntxx51a { get; set; } + public ushort cntxx51b { get; set; } + public uint Unknown_6Ch { get; set; } // 0x00000000 + public uint Unknown_70h { get; set; } // 0x00000000 + public uint Unknown_74h { get; set; } // 0x00000000 + public uint Unknown_78h { get; set; } + public uint Unknown_7Ch { get; set; } // 0x00000000 + + // reference data + public ClothInstanceTuning InstanceTuning { get; set; } + public FragDrawable Drawable { get; set; } + public ClothController Controller { get; set; } + public ResourceSimpleArray pxxxxx_2data { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.VFT = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + this.InstanceTuningPointer = reader.ReadUInt64(); + this.DrawablePointer = reader.ReadUInt64(); + this.Unknown_20h = reader.ReadUInt32(); + this.Unknown_24h = reader.ReadUInt32(); + this.ControllerPointer = reader.ReadUInt64(); + this.Unknown_30h = reader.ReadUInt32(); + this.Unknown_34h = reader.ReadUInt32(); + this.Unknown_38h = reader.ReadUInt32(); + this.Unknown_3Ch = reader.ReadUInt32(); + this.Unknown_40h = reader.ReadUInt32(); + this.Unknown_44h = reader.ReadUInt32(); + this.Unknown_48h = reader.ReadUInt32(); + this.Unknown_4Ch = reader.ReadUInt32(); + this.Unknown_50h = reader.ReadUInt32(); + this.Unknown_54h = reader.ReadUInt32(); + this.Unknown_58h = reader.ReadUInt32(); + this.Unknown_5Ch = reader.ReadUInt32(); + this.pxxxxx_2 = reader.ReadUInt64(); + this.cntxx51a = reader.ReadUInt16(); + this.cntxx51b = reader.ReadUInt16(); + this.Unknown_6Ch = reader.ReadUInt32(); + this.Unknown_70h = reader.ReadUInt32(); + this.Unknown_74h = reader.ReadUInt32(); + this.Unknown_78h = reader.ReadUInt32(); + this.Unknown_7Ch = reader.ReadUInt32(); + + // read reference data + this.InstanceTuning = reader.ReadBlockAt( + this.InstanceTuningPointer // offset + ); + this.Drawable = reader.ReadBlockAt( + this.DrawablePointer // offset + ); + this.Controller = reader.ReadBlockAt( + this.ControllerPointer // offset + ); + this.pxxxxx_2data = reader.ReadBlockAt>( + this.pxxxxx_2, // offset + this.cntxx51a + ); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // update structure data + this.InstanceTuningPointer = (ulong)(this.InstanceTuning != null ? this.InstanceTuning.FilePosition : 0); + this.DrawablePointer = (ulong)(this.Drawable != null ? this.Drawable.FilePosition : 0); + this.ControllerPointer = (ulong)(this.Controller != null ? this.Controller.FilePosition : 0); + this.pxxxxx_2 = (ulong)(this.pxxxxx_2data != null ? this.pxxxxx_2data.FilePosition : 0); + this.cntxx51a = (ushort)(this.pxxxxx_2data != null ? this.pxxxxx_2data.Count : 0); + this.cntxx51b = (ushort)(this.pxxxxx_2data != null ? this.pxxxxx_2data.Count : 0); + + // write structure data + writer.Write(this.VFT); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + writer.Write(this.InstanceTuningPointer); + writer.Write(this.DrawablePointer); + writer.Write(this.Unknown_20h); + writer.Write(this.Unknown_24h); + writer.Write(this.ControllerPointer); + writer.Write(this.Unknown_30h); + writer.Write(this.Unknown_34h); + writer.Write(this.Unknown_38h); + writer.Write(this.Unknown_3Ch); + writer.Write(this.Unknown_40h); + writer.Write(this.Unknown_44h); + writer.Write(this.Unknown_48h); + writer.Write(this.Unknown_4Ch); + writer.Write(this.Unknown_50h); + writer.Write(this.Unknown_54h); + writer.Write(this.Unknown_58h); + writer.Write(this.Unknown_5Ch); + writer.Write(this.pxxxxx_2); + writer.Write(this.cntxx51a); + writer.Write(this.cntxx51b); + writer.Write(this.Unknown_6Ch); + writer.Write(this.Unknown_70h); + writer.Write(this.Unknown_74h); + writer.Write(this.Unknown_78h); + writer.Write(this.Unknown_7Ch); + } + + /// + /// Returns a list of data blocks which are referenced by this block. + /// + public override IResourceBlock[] GetReferences() + { + var list = new List(); + if (InstanceTuning != null) list.Add(InstanceTuning); + if (Drawable != null) list.Add(Drawable); + if (Controller != null) list.Add(Controller); + if (pxxxxx_2data != null) list.Add(pxxxxx_2data); + return list.ToArray(); + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class CharacterCloth : ResourceSystemBlock + { + // pgBase + // clothBase (TODO) + // characterCloth + public override long BlockLength => 0xD0; + + // structure data + public uint VFT { get; set; } + public uint Unknown_4h { get; set; } // 0x00000001 + public uint Unknown_8h { get; set; } // 0x00000000 + public uint Unknown_Ch { get; set; } // 0x00000000 + public ResourceSimpleList64 Unknown_10h { get; set; } + public ulong ControllerPointer { get; set; } + public ulong BoundPointer { get; set; } + public ResourceSimpleList64_uint Unknown_30h { get; set; } + public uint Unknown_40h { get; set; } // 0x00000000 + public uint Unknown_44h { get; set; } // 0x00000000 + public uint Unknown_48h { get; set; } // 0x00000000 + public uint Unknown_4Ch { get; set; } // 0x00000000 + public uint Unknown_50h { get; set; } // 0x3F800000 + public uint Unknown_54h { get; set; } // 0x00000000 + public uint Unknown_58h { get; set; } // 0x00000000 + public uint Unknown_5Ch { get; set; } // 0x00000000 + public uint Unknown_60h { get; set; } // 0x00000000 + public uint Unknown_64h { get; set; } // 0x3F800000 + public uint Unknown_68h { get; set; } // 0x00000000 + public uint Unknown_6Ch { get; set; } // 0x00000000 + public uint Unknown_70h { get; set; } // 0x00000000 + public uint Unknown_74h { get; set; } // 0x00000000 + public uint Unknown_78h { get; set; } // 0x3F800000 + public uint Unknown_7Ch { get; set; } // 0x00000000 + public uint Unknown_80h { get; set; } // 0x00000000 + public uint Unknown_84h { get; set; } // 0x00000000 + public uint Unknown_88h { get; set; } // 0x00000000 + public uint Unknown_8Ch { get; set; } // 0x00000000 + public ResourceSimpleList64_uint Unknown_90h { get; set; } + public uint Unknown_A0h { get; set; } // 0x00000000 + public uint Unknown_A4h { get; set; } // 0x00000000 + public uint Unknown_A8h { get; set; } // 0x00000000 + public uint Unknown_ACh { get; set; } // 0x00000000 + public uint Unknown_B0h { get; set; } // 0x00000000 + public uint Unknown_B4h { get; set; } // 0x00000000 + public uint Unknown_B8h { get; set; } // 0x00000000 + public uint Unknown_BCh { get; set; } // 0x00000000 + public uint Unknown_C0h { get; set; } // 0x00000001 + public uint Unknown_C4h { get; set; } // 0x00000000 + public uint Unknown_C8h { get; set; } // 0x00000000 + public uint Unknown_CCh { get; set; } // 0x00000000 + + // reference data + public CharacterClothController Controller { get; set; } + public Bounds Bound { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.VFT = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + this.Unknown_10h = reader.ReadBlock>(); + this.ControllerPointer = reader.ReadUInt64(); + this.BoundPointer = reader.ReadUInt64(); + this.Unknown_30h = reader.ReadBlock(); + this.Unknown_40h = reader.ReadUInt32(); + this.Unknown_44h = reader.ReadUInt32(); + this.Unknown_48h = reader.ReadUInt32(); + this.Unknown_4Ch = reader.ReadUInt32(); + this.Unknown_50h = reader.ReadUInt32(); + this.Unknown_54h = reader.ReadUInt32(); + this.Unknown_58h = reader.ReadUInt32(); + this.Unknown_5Ch = reader.ReadUInt32(); + this.Unknown_60h = reader.ReadUInt32(); + this.Unknown_64h = reader.ReadUInt32(); + this.Unknown_68h = reader.ReadUInt32(); + this.Unknown_6Ch = reader.ReadUInt32(); + this.Unknown_70h = reader.ReadUInt32(); + this.Unknown_74h = reader.ReadUInt32(); + this.Unknown_78h = reader.ReadUInt32(); + this.Unknown_7Ch = reader.ReadUInt32(); + this.Unknown_80h = reader.ReadUInt32(); + this.Unknown_84h = reader.ReadUInt32(); + this.Unknown_88h = reader.ReadUInt32(); + this.Unknown_8Ch = reader.ReadUInt32(); + this.Unknown_90h = reader.ReadBlock(); + this.Unknown_A0h = reader.ReadUInt32(); + this.Unknown_A4h = reader.ReadUInt32(); + this.Unknown_A8h = reader.ReadUInt32(); + this.Unknown_ACh = reader.ReadUInt32(); + this.Unknown_B0h = reader.ReadUInt32(); + this.Unknown_B4h = reader.ReadUInt32(); + this.Unknown_B8h = reader.ReadUInt32(); + this.Unknown_BCh = reader.ReadUInt32(); + this.Unknown_C0h = reader.ReadUInt32(); + this.Unknown_C4h = reader.ReadUInt32(); + this.Unknown_C8h = reader.ReadUInt32(); + this.Unknown_CCh = reader.ReadUInt32(); + + // read reference data + this.Controller = reader.ReadBlockAt( + this.ControllerPointer // offset + ); + this.Bound = reader.ReadBlockAt( + this.BoundPointer // offset + ); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // update structure data + this.ControllerPointer = (ulong)(this.Controller != null ? this.Controller.FilePosition : 0); + this.BoundPointer = (ulong)(this.Bound != null ? this.Bound.FilePosition : 0); + + // write structure data + writer.Write(this.VFT); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + writer.WriteBlock(this.Unknown_10h); + writer.Write(this.ControllerPointer); + writer.Write(this.BoundPointer); + writer.WriteBlock(this.Unknown_30h); + writer.Write(this.Unknown_40h); + writer.Write(this.Unknown_44h); + writer.Write(this.Unknown_48h); + writer.Write(this.Unknown_4Ch); + writer.Write(this.Unknown_50h); + writer.Write(this.Unknown_54h); + writer.Write(this.Unknown_58h); + writer.Write(this.Unknown_5Ch); + writer.Write(this.Unknown_60h); + writer.Write(this.Unknown_64h); + writer.Write(this.Unknown_68h); + writer.Write(this.Unknown_6Ch); + writer.Write(this.Unknown_70h); + writer.Write(this.Unknown_74h); + writer.Write(this.Unknown_78h); + writer.Write(this.Unknown_7Ch); + writer.Write(this.Unknown_80h); + writer.Write(this.Unknown_84h); + writer.Write(this.Unknown_88h); + writer.Write(this.Unknown_8Ch); + writer.WriteBlock(this.Unknown_90h); + writer.Write(this.Unknown_A0h); + writer.Write(this.Unknown_A4h); + writer.Write(this.Unknown_A8h); + writer.Write(this.Unknown_ACh); + writer.Write(this.Unknown_B0h); + writer.Write(this.Unknown_B4h); + writer.Write(this.Unknown_B8h); + writer.Write(this.Unknown_BCh); + writer.Write(this.Unknown_C0h); + writer.Write(this.Unknown_C4h); + writer.Write(this.Unknown_C8h); + writer.Write(this.Unknown_CCh); + } + + /// + /// Returns a list of data blocks which are referenced by this block. + /// + public override IResourceBlock[] GetReferences() + { + var list = new List(); + if (Controller != null) list.Add(Controller); + if (Bound != null) list.Add(Bound); + return list.ToArray(); + } + + public override Tuple[] GetParts() + { + return new Tuple[] { + new Tuple(0x10, Unknown_10h), + new Tuple(0x30, Unknown_30h), + new Tuple(0x90, Unknown_90h) + }; + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class CharacterClothController : ClothController + { + // characterClothController + public override long BlockLength => 0xF0; + + // structure data + public ResourceSimpleList64_ushort Unknown_80h { get; set; } + public ResourceSimpleList64 Unknown_90h { get; set; } + public uint Unknown_A0h { get; set; } // 0x3D23D70A + public uint Unknown_A4h { get; set; } // 0x00000000 + public uint Unknown_A8h { get; set; } // 0x00000000 + public uint Unknown_ACh { get; set; } // 0x00000000 + public ResourceSimpleList64_uint Unknown_B0h { get; set; } + public ResourceSimpleList64 Unknown_C0h { get; set; } + public uint Unknown_D0h { get; set; } // 0x00000000 + public uint Unknown_D4h { get; set; } // 0x00000000 + public uint Unknown_D8h { get; set; } // 0x00000000 + public uint Unknown_DCh { get; set; } // 0x3F800000 + public ResourceSimpleList64_uint Unknown_E0h { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + base.Read(reader, parameters); + + // read structure data + this.Unknown_80h = reader.ReadBlock(); + this.Unknown_90h = reader.ReadBlock>(); + this.Unknown_A0h = reader.ReadUInt32(); + this.Unknown_A4h = reader.ReadUInt32(); + this.Unknown_A8h = reader.ReadUInt32(); + this.Unknown_ACh = reader.ReadUInt32(); + this.Unknown_B0h = reader.ReadBlock(); + this.Unknown_C0h = reader.ReadBlock>(); + this.Unknown_D0h = reader.ReadUInt32(); + this.Unknown_D4h = reader.ReadUInt32(); + this.Unknown_D8h = reader.ReadUInt32(); + this.Unknown_DCh = reader.ReadUInt32(); + this.Unknown_E0h = reader.ReadBlock(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + base.Write(writer, parameters); + + // write structure data + writer.WriteBlock(this.Unknown_80h); + writer.WriteBlock(this.Unknown_90h); + writer.Write(this.Unknown_A0h); + writer.Write(this.Unknown_A4h); + writer.Write(this.Unknown_A8h); + writer.Write(this.Unknown_ACh); + writer.WriteBlock(this.Unknown_B0h); + writer.WriteBlock(this.Unknown_C0h); + writer.Write(this.Unknown_D0h); + writer.Write(this.Unknown_D4h); + writer.Write(this.Unknown_D8h); + writer.Write(this.Unknown_DCh); + writer.WriteBlock(this.Unknown_E0h); + } + + public override Tuple[] GetParts() + { + return new Tuple[] { + new Tuple(0x80, Unknown_80h), + new Tuple(0x90, Unknown_90h), + new Tuple(0xB0, Unknown_B0h), + new Tuple(0xC0, Unknown_C0h), + new Tuple(0xE0, Unknown_E0h) + }; + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class MorphController : ResourceSystemBlock + { + // pgBase + // phMorphController + public override long BlockLength => 0x40; + + // structure data + public uint VFT { get; set; } + public uint Unknown_4h { get; set; } // 0x00000001 + public uint Unknown_8h { get; set; } // 0x00000000 + public uint Unknown_Ch { get; set; } // 0x00000000 + public uint Unknown_10h { get; set; } // 0x00000000 + public uint Unknown_14h { get; set; } // 0x00000000 + public ulong Unknown_18h_Pointer { get; set; } + public ulong Unknown_20h_Pointer { get; set; } + public ulong Unknown_28h_Pointer { get; set; } + public uint Unknown_30h { get; set; } // 0x00000000 + public uint Unknown_34h { get; set; } // 0x00000000 + public uint Unknown_38h { get; set; } // 0x00000000 + public uint Unknown_3Ch { get; set; } // 0x00000000 + + // reference data + public Unknown_C_006 Unknown_18h_Data { get; set; } + public Unknown_C_006 Unknown_20h_Data { get; set; } + public Unknown_C_006 Unknown_28h_Data { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.VFT = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + this.Unknown_10h = reader.ReadUInt32(); + this.Unknown_14h = reader.ReadUInt32(); + this.Unknown_18h_Pointer = reader.ReadUInt64(); + this.Unknown_20h_Pointer = reader.ReadUInt64(); + this.Unknown_28h_Pointer = reader.ReadUInt64(); + this.Unknown_30h = reader.ReadUInt32(); + this.Unknown_34h = reader.ReadUInt32(); + this.Unknown_38h = reader.ReadUInt32(); + this.Unknown_3Ch = reader.ReadUInt32(); + + // read reference data + this.Unknown_18h_Data = reader.ReadBlockAt( + this.Unknown_18h_Pointer // offset + ); + this.Unknown_20h_Data = reader.ReadBlockAt( + this.Unknown_20h_Pointer // offset + ); + this.Unknown_28h_Data = reader.ReadBlockAt( + this.Unknown_28h_Pointer // offset + ); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // update structure data + this.Unknown_18h_Pointer = (ulong)(this.Unknown_18h_Data != null ? this.Unknown_18h_Data.FilePosition : 0); + this.Unknown_20h_Pointer = (ulong)(this.Unknown_20h_Data != null ? this.Unknown_20h_Data.FilePosition : 0); + this.Unknown_28h_Pointer = (ulong)(this.Unknown_28h_Data != null ? this.Unknown_28h_Data.FilePosition : 0); + + // write structure data + writer.Write(this.VFT); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + writer.Write(this.Unknown_10h); + writer.Write(this.Unknown_14h); + writer.Write(this.Unknown_18h_Pointer); + writer.Write(this.Unknown_20h_Pointer); + writer.Write(this.Unknown_28h_Pointer); + writer.Write(this.Unknown_30h); + writer.Write(this.Unknown_34h); + writer.Write(this.Unknown_38h); + writer.Write(this.Unknown_3Ch); + } + + /// + /// Returns a list of data blocks which are referenced by this block. + /// + public override IResourceBlock[] GetReferences() + { + var list = new List(); + if (Unknown_18h_Data != null) list.Add(Unknown_18h_Data); + if (Unknown_20h_Data != null) list.Add(Unknown_20h_Data); + if (Unknown_28h_Data != null) list.Add(Unknown_28h_Data); + return list.ToArray(); + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class Unknown_C_001 : ResourceSystemBlock + { + public override long BlockLength => 0x10; + + // structure data + public uint Unknown_0h { get; set; } + public uint Unknown_4h { get; set; } + public uint Unknown_8h { get; set; } + public uint Unknown_Ch { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.Unknown_0h = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // write structure data + writer.Write(this.Unknown_0h); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class Unknown_C_002 : ResourceSystemBlock + { + public override long BlockLength => 0x10; + + // structure data + public uint Unknown_0h { get; set; } + public uint Unknown_4h { get; set; } + public uint Unknown_8h { get; set; } + public uint Unknown_Ch { get; set; } // 0x7F800001 + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.Unknown_0h = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // write structure data + writer.Write(this.Unknown_0h); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class Unknown_C_003 : ResourceSystemBlock + { + public override long BlockLength => 0x20; + + // structure data + public uint Unknown_0h { get; set; } + public uint Unknown_4h { get; set; } + public uint Unknown_8h { get; set; } + public uint Unknown_Ch { get; set; } + public uint Unknown_10h { get; set; } + public uint Unknown_14h { get; set; } + public uint Unknown_18h { get; set; } + public uint Unknown_1Ch { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.Unknown_0h = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + this.Unknown_10h = reader.ReadUInt32(); + this.Unknown_14h = reader.ReadUInt32(); + this.Unknown_18h = reader.ReadUInt32(); + this.Unknown_1Ch = reader.ReadUInt32(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // write structure data + writer.Write(this.Unknown_0h); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + writer.Write(this.Unknown_10h); + writer.Write(this.Unknown_14h); + writer.Write(this.Unknown_18h); + writer.Write(this.Unknown_1Ch); + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class Unknown_C_004 : ResourceSystemBlock + { + public override long BlockLength => 0x10; + + // structure data + public ushort Unknown_0h { get; set; } + public ushort Unknown_2h { get; set; } + public float Unknown_4h { get; set; } + public float Unknown_8h { get; set; } + public float Unknown_Ch { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.Unknown_0h = reader.ReadUInt16(); + this.Unknown_2h = reader.ReadUInt16(); + this.Unknown_4h = reader.ReadSingle(); + this.Unknown_8h = reader.ReadSingle(); + this.Unknown_Ch = reader.ReadSingle(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // write structure data + writer.Write(this.Unknown_0h); + writer.Write(this.Unknown_2h); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class Unknown_C_006 : ResourceSystemBlock + { + public override long BlockLength => 0x190; + + // structure data + public uint Unknown_0h { get; set; } // 0x00000000 + public uint Unknown_4h { get; set; } // 0x00000000 + public uint Unknown_8h { get; set; } // 0x00000000 + public uint Unknown_Ch { get; set; } // 0x00000000 + public uint Unknown_10h { get; set; } // 0x00000000 + public uint Unknown_14h { get; set; } // 0x00000000 + public uint Unknown_18h { get; set; } // 0x00000000 + public uint Unknown_1Ch { get; set; } // 0x00000000 + public uint Unknown_20h { get; set; } // 0x00000000 + public uint Unknown_24h { get; set; } // 0x00000000 + public uint Unknown_28h { get; set; } // 0x00000000 + public uint Unknown_2Ch { get; set; } // 0x00000000 + public uint Unknown_30h { get; set; } // 0x00000000 + public uint Unknown_34h { get; set; } // 0x00000000 + public uint Unknown_38h { get; set; } // 0x00000000 + public uint Unknown_3Ch { get; set; } // 0x00000000 + public uint Unknown_40h { get; set; } // 0x00000000 + public uint Unknown_44h { get; set; } // 0x00000000 + public uint Unknown_48h { get; set; } // 0x00000000 + public uint Unknown_4Ch { get; set; } // 0x00000000 + public ResourceSimpleList64_s Unknown_50h { get; set; } + public ResourceSimpleList64_ushort Unknown_60h { get; set; } + public ResourceSimpleList64_ushort Unknown_70h { get; set; } + public ResourceSimpleList64_ushort Unknown_80h { get; set; } + public ResourceSimpleList64_ushort Unknown_90h { get; set; } + public ResourceSimpleList64_s Unknown_A0h { get; set; } + public ResourceSimpleList64_ushort Unknown_B0h { get; set; } + public ResourceSimpleList64_ushort Unknown_C0h { get; set; } + public ResourceSimpleList64_ushort Unknown_D0h { get; set; } + public ResourceSimpleList64_ushort Unknown_E0h { get; set; } + public uint Unknown_F0h { get; set; } // 0x00000000 + public uint Unknown_F4h { get; set; } // 0x00000000 + public uint Unknown_F8h { get; set; } // 0x00000000 + public uint Unknown_FCh { get; set; } // 0x00000000 + public uint Unknown_100h { get; set; } // 0x00000000 + public uint Unknown_104h { get; set; } // 0x00000000 + public uint Unknown_108h { get; set; } // 0x00000000 + public uint Unknown_10Ch { get; set; } // 0x00000000 + public uint Unknown_110h { get; set; } // 0x00000000 + public uint Unknown_114h { get; set; } // 0x00000000 + public uint Unknown_118h { get; set; } // 0x00000000 + public uint Unknown_11Ch { get; set; } // 0x00000000 + public uint Unknown_120h { get; set; } // 0x00000000 + public uint Unknown_124h { get; set; } // 0x00000000 + public uint Unknown_128h { get; set; } // 0x00000000 + public uint Unknown_12Ch { get; set; } // 0x00000000 + public uint Unknown_130h { get; set; } // 0x00000000 + public uint Unknown_134h { get; set; } // 0x00000000 + public uint Unknown_138h { get; set; } // 0x00000000 + public uint Unknown_13Ch { get; set; } // 0x00000000 + public uint Unknown_140h { get; set; } // 0x00000000 + public uint Unknown_144h { get; set; } // 0x00000000 + public uint Unknown_148h { get; set; } // 0x00000000 + public uint Unknown_14Ch { get; set; } // 0x00000000 + public ResourceSimpleList64_ushort Unknown_150h { get; set; } + public ResourceSimpleList64_ushort Unknown_160h { get; set; } + public uint Unknown_170h { get; set; } // 0x00000000 + public uint Unknown_174h { get; set; } // 0x00000000 + public uint Unknown_178h { get; set; } // 0x00000000 + public uint Unknown_17Ch { get; set; } // 0x00000000 + public uint Unknown_180h { get; set; } + public uint Unknown_184h { get; set; } // 0x00000000 + public uint Unknown_188h { get; set; } // 0x00000000 + public uint Unknown_18Ch { get; set; } // 0x00000000 + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.Unknown_0h = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + this.Unknown_10h = reader.ReadUInt32(); + this.Unknown_14h = reader.ReadUInt32(); + this.Unknown_18h = reader.ReadUInt32(); + this.Unknown_1Ch = reader.ReadUInt32(); + this.Unknown_20h = reader.ReadUInt32(); + this.Unknown_24h = reader.ReadUInt32(); + this.Unknown_28h = reader.ReadUInt32(); + this.Unknown_2Ch = reader.ReadUInt32(); + this.Unknown_30h = reader.ReadUInt32(); + this.Unknown_34h = reader.ReadUInt32(); + this.Unknown_38h = reader.ReadUInt32(); + this.Unknown_3Ch = reader.ReadUInt32(); + this.Unknown_40h = reader.ReadUInt32(); + this.Unknown_44h = reader.ReadUInt32(); + this.Unknown_48h = reader.ReadUInt32(); + this.Unknown_4Ch = reader.ReadUInt32(); + this.Unknown_50h = reader.ReadBlock>(); + this.Unknown_60h = reader.ReadBlock(); + this.Unknown_70h = reader.ReadBlock(); + this.Unknown_80h = reader.ReadBlock(); + this.Unknown_90h = reader.ReadBlock(); + this.Unknown_A0h = reader.ReadBlock>(); + this.Unknown_B0h = reader.ReadBlock(); + this.Unknown_C0h = reader.ReadBlock(); + this.Unknown_D0h = reader.ReadBlock(); + this.Unknown_E0h = reader.ReadBlock(); + this.Unknown_F0h = reader.ReadUInt32(); + this.Unknown_F4h = reader.ReadUInt32(); + this.Unknown_F8h = reader.ReadUInt32(); + this.Unknown_FCh = reader.ReadUInt32(); + this.Unknown_100h = reader.ReadUInt32(); + this.Unknown_104h = reader.ReadUInt32(); + this.Unknown_108h = reader.ReadUInt32(); + this.Unknown_10Ch = reader.ReadUInt32(); + this.Unknown_110h = reader.ReadUInt32(); + this.Unknown_114h = reader.ReadUInt32(); + this.Unknown_118h = reader.ReadUInt32(); + this.Unknown_11Ch = reader.ReadUInt32(); + this.Unknown_120h = reader.ReadUInt32(); + this.Unknown_124h = reader.ReadUInt32(); + this.Unknown_128h = reader.ReadUInt32(); + this.Unknown_12Ch = reader.ReadUInt32(); + this.Unknown_130h = reader.ReadUInt32(); + this.Unknown_134h = reader.ReadUInt32(); + this.Unknown_138h = reader.ReadUInt32(); + this.Unknown_13Ch = reader.ReadUInt32(); + this.Unknown_140h = reader.ReadUInt32(); + this.Unknown_144h = reader.ReadUInt32(); + this.Unknown_148h = reader.ReadUInt32(); + this.Unknown_14Ch = reader.ReadUInt32(); + this.Unknown_150h = reader.ReadBlock(); + this.Unknown_160h = reader.ReadBlock(); + this.Unknown_170h = reader.ReadUInt32(); + this.Unknown_174h = reader.ReadUInt32(); + this.Unknown_178h = reader.ReadUInt32(); + this.Unknown_17Ch = reader.ReadUInt32(); + this.Unknown_180h = reader.ReadUInt32(); + this.Unknown_184h = reader.ReadUInt32(); + this.Unknown_188h = reader.ReadUInt32(); + this.Unknown_18Ch = reader.ReadUInt32(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // write structure data + writer.Write(this.Unknown_0h); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + writer.Write(this.Unknown_10h); + writer.Write(this.Unknown_14h); + writer.Write(this.Unknown_18h); + writer.Write(this.Unknown_1Ch); + writer.Write(this.Unknown_20h); + writer.Write(this.Unknown_24h); + writer.Write(this.Unknown_28h); + writer.Write(this.Unknown_2Ch); + writer.Write(this.Unknown_30h); + writer.Write(this.Unknown_34h); + writer.Write(this.Unknown_38h); + writer.Write(this.Unknown_3Ch); + writer.Write(this.Unknown_40h); + writer.Write(this.Unknown_44h); + writer.Write(this.Unknown_48h); + writer.Write(this.Unknown_4Ch); + writer.WriteBlock(this.Unknown_50h); + writer.WriteBlock(this.Unknown_60h); + writer.WriteBlock(this.Unknown_70h); + writer.WriteBlock(this.Unknown_80h); + writer.WriteBlock(this.Unknown_90h); + writer.WriteBlock(this.Unknown_A0h); + writer.WriteBlock(this.Unknown_B0h); + writer.WriteBlock(this.Unknown_C0h); + writer.WriteBlock(this.Unknown_D0h); + writer.WriteBlock(this.Unknown_E0h); + writer.Write(this.Unknown_F0h); + writer.Write(this.Unknown_F4h); + writer.Write(this.Unknown_F8h); + writer.Write(this.Unknown_FCh); + writer.Write(this.Unknown_100h); + writer.Write(this.Unknown_104h); + writer.Write(this.Unknown_108h); + writer.Write(this.Unknown_10Ch); + writer.Write(this.Unknown_110h); + writer.Write(this.Unknown_114h); + writer.Write(this.Unknown_118h); + writer.Write(this.Unknown_11Ch); + writer.Write(this.Unknown_120h); + writer.Write(this.Unknown_124h); + writer.Write(this.Unknown_128h); + writer.Write(this.Unknown_12Ch); + writer.Write(this.Unknown_130h); + writer.Write(this.Unknown_134h); + writer.Write(this.Unknown_138h); + writer.Write(this.Unknown_13Ch); + writer.Write(this.Unknown_140h); + writer.Write(this.Unknown_144h); + writer.Write(this.Unknown_148h); + writer.Write(this.Unknown_14Ch); + writer.WriteBlock(this.Unknown_150h); + writer.WriteBlock(this.Unknown_160h); + writer.Write(this.Unknown_170h); + writer.Write(this.Unknown_174h); + writer.Write(this.Unknown_178h); + writer.Write(this.Unknown_17Ch); + writer.Write(this.Unknown_180h); + writer.Write(this.Unknown_184h); + writer.Write(this.Unknown_188h); + writer.Write(this.Unknown_18Ch); + } + + public override Tuple[] GetParts() + { + return new Tuple[] { + new Tuple(0x50, Unknown_50h), + new Tuple(0x60, Unknown_60h), + new Tuple(0x70, Unknown_70h), + new Tuple(0x80, Unknown_80h), + new Tuple(0x90, Unknown_90h), + new Tuple(0xA0, Unknown_A0h), + new Tuple(0xB0, Unknown_B0h), + new Tuple(0xC0, Unknown_C0h), + new Tuple(0xD0, Unknown_D0h), + new Tuple(0xE0, Unknown_E0h), + new Tuple(0x150, Unknown_150h), + new Tuple(0x160, Unknown_160h) + }; + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class Unknown_C_007 : ResourceSystemBlock + { + public override long BlockLength + { + get { return 16; } + } + + // structure data + public uint Unknown_0h { get; set; } // 0x00000000 + public uint Unknown_4h { get; set; } // 0x00000000 + public uint Unknown_8h { get; set; } // 0x00000000 + public uint Unknown_Ch { get; set; } // 0x00000000 + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.Unknown_0h = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // write structure data + writer.Write(this.Unknown_0h); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + } + } + + + +} diff --git a/CodeWalker.Core/GameFiles/Resources/Expression.cs b/CodeWalker.Core/GameFiles/Resources/Expression.cs new file mode 100644 index 0000000..e238668 --- /dev/null +++ b/CodeWalker.Core/GameFiles/Resources/Expression.cs @@ -0,0 +1,427 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +/* + Copyright(c) 2017 Neodymium + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + + +//ruthlessly stolen + + +namespace CodeWalker.GameFiles +{ + + [TypeConverter(typeof(ExpandableObjectConverter))] public class ExpressionDictionary : ResourceFileBase + { + // pgDictionaryBase + // pgDictionary + public override long BlockLength => 0x40; + + // structure data + public uint Unknown_10h { get; set; } + public uint Unknown_14h { get; set; } + public uint Unknown_18h { get; set; } + public uint Unknown_1Ch { get; set; } + public ResourceSimpleList64_uint ExpressionNameHashes { get; set; } + public ResourcePointerList64 Expressions { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + base.Read(reader, parameters); + + // read structure data + this.Unknown_10h = reader.ReadUInt32(); + this.Unknown_14h = reader.ReadUInt32(); + this.Unknown_18h = reader.ReadUInt32(); + this.Unknown_1Ch = reader.ReadUInt32(); + this.ExpressionNameHashes = reader.ReadBlock(); + this.Expressions = reader.ReadBlock>(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + base.Write(writer, parameters); + + // write structure data + writer.Write(this.Unknown_10h); + writer.Write(this.Unknown_14h); + writer.Write(this.Unknown_18h); + writer.Write(this.Unknown_1Ch); + writer.WriteBlock(this.ExpressionNameHashes); + writer.WriteBlock(this.Expressions); + } + + /// + /// Returns a list of data blocks which are referenced by this block. + /// + public override IResourceBlock[] GetReferences() + { + var list = new List(base.GetReferences()); + return list.ToArray(); + } + + public override Tuple[] GetParts() + { + return new Tuple[] { + new Tuple(0x20, ExpressionNameHashes), + new Tuple(0x30, Expressions) + }; + } + } + + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class Expression : ResourceSystemBlock + { + // pgBase + // crExpressions + public override long BlockLength => 0x90; + + // structure data + public uint VFT { get; set; } + public uint Unknown_4h { get; set; } + public uint Unknown_8h { get; set; } + public uint Unknown_Ch { get; set; } + public uint Unknown_10h { get; set; } + public uint Unknown_14h { get; set; } + public uint Unknown_18h { get; set; } + public uint Unknown_1Ch { get; set; } + public ResourcePointerList64 Unknown_20h { get; set; } + public ResourceSimpleList64_uint Unknown_30h { get; set; } + public ResourceSimpleList64 Unknown_40h { get; set; } + public ResourceSimpleList64_uint Unknown_50h { get; set; } + public ulong NamePointer { get; set; } + public uint Unknown_68h { get; set; } // short, short, (name len, name len+1) + public uint Unknown_6Ch { get; set; } + public uint Unknown_70h { get; set; } + public uint Unknown_74h { get; set; } + public ushort len { get; set; } + public ushort Unknown_7Ah { get; set; } + public uint Unknown_7Ch { get; set; } + public uint Unknown_80h { get; set; } + public uint Unknown_84h { get; set; } + public uint Unknown_88h { get; set; } + public uint Unknown_8Ch { get; set; } + + // reference data + public string_r Name; + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.VFT = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + this.Unknown_10h = reader.ReadUInt32(); + this.Unknown_14h = reader.ReadUInt32(); + this.Unknown_18h = reader.ReadUInt32(); + this.Unknown_1Ch = reader.ReadUInt32(); + this.Unknown_20h = reader.ReadBlock>(); + this.Unknown_30h = reader.ReadBlock(); + this.Unknown_40h = reader.ReadBlock>(); + this.Unknown_50h = reader.ReadBlock(); + this.NamePointer = reader.ReadUInt64(); + this.Unknown_68h = reader.ReadUInt32(); + this.Unknown_6Ch = reader.ReadUInt32(); + this.Unknown_70h = reader.ReadUInt32(); + this.Unknown_74h = reader.ReadUInt32(); + this.len = reader.ReadUInt16(); + this.Unknown_7Ah = reader.ReadUInt16(); + this.Unknown_7Ch = reader.ReadUInt32(); + this.Unknown_80h = reader.ReadUInt32(); + this.Unknown_84h = reader.ReadUInt32(); + this.Unknown_88h = reader.ReadUInt32(); + this.Unknown_8Ch = reader.ReadUInt32(); + + // read reference data + this.Name = reader.ReadBlockAt( + this.NamePointer // offset + ); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // update structure data + this.NamePointer = (ulong)(this.Name != null ? this.Name.FilePosition : 0); + + // write structure data + writer.Write(this.VFT); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + writer.Write(this.Unknown_10h); + writer.Write(this.Unknown_14h); + writer.Write(this.Unknown_18h); + writer.Write(this.Unknown_1Ch); + writer.WriteBlock(this.Unknown_20h); + writer.WriteBlock(this.Unknown_30h); + writer.WriteBlock(this.Unknown_40h); + writer.WriteBlock(this.Unknown_50h); + writer.Write(this.NamePointer); + writer.Write(this.Unknown_68h); + writer.Write(this.Unknown_6Ch); + writer.Write(this.Unknown_70h); + writer.Write(this.Unknown_74h); + writer.Write(this.len); + writer.Write(this.Unknown_7Ah); + writer.Write(this.Unknown_7Ch); + writer.Write(this.Unknown_80h); + writer.Write(this.Unknown_84h); + writer.Write(this.Unknown_88h); + writer.Write(this.Unknown_8Ch); + } + + /// + /// Returns a list of data blocks which are referenced by this block. + /// + public override IResourceBlock[] GetReferences() + { + var list = new List(); + if (Name != null) list.Add(Name); + return list.ToArray(); + } + + public override Tuple[] GetParts() + { + return new Tuple[] { + new Tuple(0x20, Unknown_20h), + new Tuple(0x30, Unknown_30h), + new Tuple(0x40, Unknown_40h), + new Tuple(0x50, Unknown_50h) + }; + } + } + + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class ExpressionUnk1 : ResourceSystemBlock + { + public override long BlockLength + { + get { return 16 + Data1.Length + Data2.Length + Data3.Length; } + } + + // structure data + public uint Unknown_0h { get; set; } + public uint len1 { get; set; } + public uint len2 { get; set; } + public ushort len3 { get; set; } + public ushort Unknown_Eh { get; set; } + public byte[] Data1 { get; set; } + public byte[] Data2 { get; set; } + public byte[] Data3 { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.Unknown_0h = reader.ReadUInt32(); + this.len1 = reader.ReadUInt32(); + this.len2 = reader.ReadUInt32(); + this.len3 = reader.ReadUInt16(); + this.Unknown_Eh = reader.ReadUInt16(); + this.Data1 = reader.ReadBytes((int)len1); + this.Data2 = reader.ReadBytes((int)len2); + this.Data3 = reader.ReadBytes((int)len3); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // write structure data + writer.Write(this.Unknown_0h); + writer.Write(this.len1); + writer.Write(this.len2); + writer.Write(this.len3); + writer.Write(this.Unknown_Eh); + writer.Write(this.Data1); + writer.Write(this.Data2); + writer.Write(this.Data3); + } + } + + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class ExpressionUnk2 : ResourceSystemBlock + { + public override long BlockLength => 0xA0; + + // structure data + public float Unknown_0h { get; set; } + public float Unknown_4h { get; set; } + public float Unknown_8h { get; set; } + public uint Unknown_Ch { get; set; } + public float Unknown_10h { get; set; } + public float Unknown_14h { get; set; } + public float Unknown_18h { get; set; } + public uint Unknown_1Ch { get; set; } + public float Unknown_20h { get; set; } + public float Unknown_24h { get; set; } + public float Unknown_28h { get; set; } + public uint Unknown_2Ch { get; set; } + public float Unknown_30h { get; set; } + public float Unknown_34h { get; set; } + public float Unknown_38h { get; set; } + public uint Unknown_3Ch { get; set; } + public float Unknown_40h { get; set; } + public float Unknown_44h { get; set; } + public float Unknown_48h { get; set; } + public uint Unknown_4Ch { get; set; } + public float Unknown_50h { get; set; } + public float Unknown_54h { get; set; } + public float Unknown_58h { get; set; } + public uint Unknown_5Ch { get; set; } + public float Unknown_60h { get; set; } + public float Unknown_64h { get; set; } + public float Unknown_68h { get; set; } + public uint Unknown_6Ch { get; set; } + public float Unknown_70h { get; set; } + public float Unknown_74h { get; set; } + public float Unknown_78h { get; set; } + public uint Unknown_7Ch { get; set; } + public float Unknown_80h { get; set; } + public float Unknown_84h { get; set; } + public float Unknown_88h { get; set; } + public uint Unknown_8Ch { get; set; } + public float Unknown_90h { get; set; } + public float Unknown_94h { get; set; } + public float Unknown_98h { get; set; } + public uint Unknown_9Ch { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.Unknown_0h = reader.ReadSingle(); + this.Unknown_4h = reader.ReadSingle(); + this.Unknown_8h = reader.ReadSingle(); + this.Unknown_Ch = reader.ReadUInt32(); + this.Unknown_10h = reader.ReadSingle(); + this.Unknown_14h = reader.ReadSingle(); + this.Unknown_18h = reader.ReadSingle(); + this.Unknown_1Ch = reader.ReadUInt32(); + this.Unknown_20h = reader.ReadSingle(); + this.Unknown_24h = reader.ReadSingle(); + this.Unknown_28h = reader.ReadSingle(); + this.Unknown_2Ch = reader.ReadUInt32(); + this.Unknown_30h = reader.ReadSingle(); + this.Unknown_34h = reader.ReadSingle(); + this.Unknown_38h = reader.ReadSingle(); + this.Unknown_3Ch = reader.ReadUInt32(); + this.Unknown_40h = reader.ReadSingle(); + this.Unknown_44h = reader.ReadSingle(); + this.Unknown_48h = reader.ReadSingle(); + this.Unknown_4Ch = reader.ReadUInt32(); + this.Unknown_50h = reader.ReadSingle(); + this.Unknown_54h = reader.ReadSingle(); + this.Unknown_58h = reader.ReadSingle(); + this.Unknown_5Ch = reader.ReadUInt32(); + this.Unknown_60h = reader.ReadSingle(); + this.Unknown_64h = reader.ReadSingle(); + this.Unknown_68h = reader.ReadSingle(); + this.Unknown_6Ch = reader.ReadUInt32(); + this.Unknown_70h = reader.ReadSingle(); + this.Unknown_74h = reader.ReadSingle(); + this.Unknown_78h = reader.ReadSingle(); + this.Unknown_7Ch = reader.ReadUInt32(); + this.Unknown_80h = reader.ReadSingle(); + this.Unknown_84h = reader.ReadSingle(); + this.Unknown_88h = reader.ReadSingle(); + this.Unknown_8Ch = reader.ReadUInt32(); + this.Unknown_90h = reader.ReadSingle(); + this.Unknown_94h = reader.ReadSingle(); + this.Unknown_98h = reader.ReadSingle(); + this.Unknown_9Ch = reader.ReadUInt32(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // write structure data + writer.Write(this.Unknown_0h); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + writer.Write(this.Unknown_10h); + writer.Write(this.Unknown_14h); + writer.Write(this.Unknown_18h); + writer.Write(this.Unknown_1Ch); + writer.Write(this.Unknown_20h); + writer.Write(this.Unknown_24h); + writer.Write(this.Unknown_28h); + writer.Write(this.Unknown_2Ch); + writer.Write(this.Unknown_30h); + writer.Write(this.Unknown_34h); + writer.Write(this.Unknown_38h); + writer.Write(this.Unknown_3Ch); + writer.Write(this.Unknown_40h); + writer.Write(this.Unknown_44h); + writer.Write(this.Unknown_48h); + writer.Write(this.Unknown_4Ch); + writer.Write(this.Unknown_50h); + writer.Write(this.Unknown_54h); + writer.Write(this.Unknown_58h); + writer.Write(this.Unknown_5Ch); + writer.Write(this.Unknown_60h); + writer.Write(this.Unknown_64h); + writer.Write(this.Unknown_68h); + writer.Write(this.Unknown_6Ch); + writer.Write(this.Unknown_70h); + writer.Write(this.Unknown_74h); + writer.Write(this.Unknown_78h); + writer.Write(this.Unknown_7Ch); + writer.Write(this.Unknown_80h); + writer.Write(this.Unknown_84h); + writer.Write(this.Unknown_88h); + writer.Write(this.Unknown_8Ch); + writer.Write(this.Unknown_90h); + writer.Write(this.Unknown_94h); + writer.Write(this.Unknown_98h); + writer.Write(this.Unknown_9Ch); + } + } + + + +} diff --git a/CodeWalker.Core/GameFiles/Resources/Filter.cs b/CodeWalker.Core/GameFiles/Resources/Filter.cs new file mode 100644 index 0000000..d21e02b --- /dev/null +++ b/CodeWalker.Core/GameFiles/Resources/Filter.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +/* + Copyright(c) 2017 Neodymium + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + + +//ruthlessly stolen + + +namespace CodeWalker.GameFiles +{ + + [TypeConverter(typeof(ExpandableObjectConverter))] public class FrameFilterDictionary : ResourceFileBase + { + // pgDictionaryBase + // pgDictionary + public override long BlockLength => 0x40; + + // structure data + public uint Unknown_10h { get; set; } // 0x00000000 + public uint Unknown_14h { get; set; } // 0x00000000 + public uint Unknown_18h { get; set; } // 0x00000001 + public uint Unknown_1Ch { get; set; } // 0x00000000 + public ResourceSimpleList64_uint FilterNameHashes { get; set; } + public ResourcePointerList64 Filters { get; set; } + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + base.Read(reader, parameters); + + // read structure data + this.Unknown_10h = reader.ReadUInt32(); + this.Unknown_14h = reader.ReadUInt32(); + this.Unknown_18h = reader.ReadUInt32(); + this.Unknown_1Ch = reader.ReadUInt32(); + this.FilterNameHashes = reader.ReadBlock(); + this.Filters = reader.ReadBlock>(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + base.Write(writer, parameters); + + // write structure data + writer.Write(this.Unknown_10h); + writer.Write(this.Unknown_14h); + writer.Write(this.Unknown_18h); + writer.Write(this.Unknown_1Ch); + writer.WriteBlock(this.FilterNameHashes); + writer.WriteBlock(this.Filters); + } + + public override Tuple[] GetParts() + { + return new Tuple[] { + new Tuple(0x20, FilterNameHashes), + new Tuple(0x30, Filters) + }; + } + } + + + [TypeConverter(typeof(ExpandableObjectConverter))] public class FrameFilter : ResourceSystemBlock + { + // crFrameFilter -> this is polymorphic, there are many filters + public override long BlockLength => 0x40; + + // structure data + public uint VFT { get; set; } + public uint Unknown_4h { get; set; } // 0x00000001 + public uint Unknown_8h { get; set; } // 0x00000001 + public uint Unknown_Ch { get; set; } + public uint Unknown_10h { get; set; } // 0x00000004 + public uint Unknown_14h { get; set; } // 0x00000000 + public ResourceSimpleList64_ulong Unknown_18h { get; set; } + public ResourceSimpleList64_uint Unknown_28h { get; set; } + public uint Unknown_38h { get; set; } // 0x00000000 + public uint Unknown_3Ch { get; set; } // 0x00000000 + + /// + /// Reads the data-block from a stream. + /// + public override void Read(ResourceDataReader reader, params object[] parameters) + { + // read structure data + this.VFT = reader.ReadUInt32(); + this.Unknown_4h = reader.ReadUInt32(); + this.Unknown_8h = reader.ReadUInt32(); + this.Unknown_Ch = reader.ReadUInt32(); + this.Unknown_10h = reader.ReadUInt32(); + this.Unknown_14h = reader.ReadUInt32(); + this.Unknown_18h = reader.ReadBlock(); + this.Unknown_28h = reader.ReadBlock(); + this.Unknown_38h = reader.ReadUInt32(); + this.Unknown_3Ch = reader.ReadUInt32(); + } + + /// + /// Writes the data-block to a stream. + /// + public override void Write(ResourceDataWriter writer, params object[] parameters) + { + // write structure data + writer.Write(this.VFT); + writer.Write(this.Unknown_4h); + writer.Write(this.Unknown_8h); + writer.Write(this.Unknown_Ch); + writer.Write(this.Unknown_10h); + writer.Write(this.Unknown_14h); + writer.WriteBlock(this.Unknown_18h); + writer.WriteBlock(this.Unknown_28h); + writer.Write(this.Unknown_38h); + writer.Write(this.Unknown_3Ch); + } + + public override Tuple[] GetParts() + { + return new Tuple[] { + new Tuple(0x18, Unknown_18h), + new Tuple(0x28, Unknown_28h) + }; + } + } + + +} diff --git a/CodeWalker.csproj b/CodeWalker.csproj index 9758a4c..f39166b 100644 --- a/CodeWalker.csproj +++ b/CodeWalker.csproj @@ -143,6 +143,12 @@ AboutForm.cs + + Form + + + GenericForm.cs + Form @@ -595,6 +601,9 @@ AboutForm.cs + + GenericForm.cs + ModelMatForm.cs diff --git a/ExploreForm.cs b/ExploreForm.cs index b18ea6f..5cd8603 100644 --- a/ExploreForm.cs +++ b/ExploreForm.cs @@ -236,7 +236,9 @@ namespace CodeWalker InitFileType(".yvr", "Vehicle Record", 9, FileTypeAction.ViewYvr); InitFileType(".ywr", "Waypoint Record", 9, FileTypeAction.ViewYwr); InitFileType(".fxc", "Compiled Shaders", 9, FileTypeAction.ViewFxc); - InitFileType(".yed", "Expression Dictionary", 9); + InitFileType(".yed", "Expression Dictionary", 9, FileTypeAction.ViewYed); + InitFileType(".yld", "Cloth Dictionary", 9, FileTypeAction.ViewYld); + InitFileType(".yfd", "Frame Filter Dictionary", 9, FileTypeAction.ViewYfd); InitFileType(".asi", "ASI Plugin", 9); InitFileType(".dll", "Dynamic Link Library", 9); InitFileType(".exe", "Executable", 10); @@ -1304,6 +1306,9 @@ namespace CodeWalker case FileTypeAction.ViewYcd: case FileTypeAction.ViewYnd: case FileTypeAction.ViewCacheDat: + case FileTypeAction.ViewYed: + case FileTypeAction.ViewYld: + case FileTypeAction.ViewYfd: return true; case FileTypeAction.ViewHex: default: @@ -1434,6 +1439,15 @@ namespace CodeWalker case FileTypeAction.ViewCacheDat: ViewCacheDat(name, path, data, fe); break; + case FileTypeAction.ViewYed: + ViewYed(name, path, data, fe); + break; + case FileTypeAction.ViewYld: + ViewYld(name, path, data, fe); + break; + case FileTypeAction.ViewYfd: + ViewYfd(name, path, data, fe); + break; case FileTypeAction.ViewHex: default: ViewHex(name, path, data); @@ -1640,6 +1654,27 @@ namespace CodeWalker f.Show(); f.LoadMeta(ynd); } + private void ViewYed(string name, string path, byte[] data, RpfFileEntry e) + { + var yed = RpfFile.GetFile(e, data); + GenericForm f = new GenericForm(this); + f.Show(); + f.LoadFile(yed, yed.RpfFileEntry); + } + private void ViewYld(string name, string path, byte[] data, RpfFileEntry e) + { + var yld = RpfFile.GetFile(e, data); + GenericForm f = new GenericForm(this); + f.Show(); + f.LoadFile(yld, yld.RpfFileEntry); + } + private void ViewYfd(string name, string path, byte[] data, RpfFileEntry e) + { + var yfd = RpfFile.GetFile(e, data); + GenericForm f = new GenericForm(this); + f.Show(); + f.LoadFile(yfd, yfd.RpfFileEntry); + } private void ViewCacheDat(string name, string path, byte[] data, RpfFileEntry e) { var cachedat = RpfFile.GetFile(e, data); @@ -4176,6 +4211,9 @@ namespace CodeWalker ViewYcd = 17, ViewYnd = 18, ViewCacheDat = 19, + ViewYed = 20, + ViewYld = 21, + ViewYfd = 22, } diff --git a/Forms/GenericForm.Designer.cs b/Forms/GenericForm.Designer.cs new file mode 100644 index 0000000..f2b2bdc --- /dev/null +++ b/Forms/GenericForm.Designer.cs @@ -0,0 +1,61 @@ +namespace CodeWalker.Forms +{ + partial class GenericForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GenericForm)); + this.DetailsPropertyGrid = new CodeWalker.WinForms.PropertyGridFix(); + this.SuspendLayout(); + // + // DetailsPropertyGrid + // + this.DetailsPropertyGrid.Dock = System.Windows.Forms.DockStyle.Fill; + this.DetailsPropertyGrid.HelpVisible = false; + this.DetailsPropertyGrid.Location = new System.Drawing.Point(0, 0); + this.DetailsPropertyGrid.Name = "DetailsPropertyGrid"; + this.DetailsPropertyGrid.Size = new System.Drawing.Size(692, 449); + this.DetailsPropertyGrid.TabIndex = 1; + // + // GenericForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(692, 449); + this.Controls.Add(this.DetailsPropertyGrid); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "GenericForm"; + this.Text = "File Inspector - CodeWalker by dexyfex"; + this.ResumeLayout(false); + + } + + #endregion + + private WinForms.PropertyGridFix DetailsPropertyGrid; + } +} \ No newline at end of file diff --git a/Forms/GenericForm.cs b/Forms/GenericForm.cs new file mode 100644 index 0000000..17d19eb --- /dev/null +++ b/Forms/GenericForm.cs @@ -0,0 +1,58 @@ +using CodeWalker.GameFiles; +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; + +namespace CodeWalker.Forms +{ + public partial class GenericForm : Form + { + + private string fileName; + public string FileName + { + get { return fileName; } + set + { + fileName = value; + UpdateFormTitle(); + } + } + public string FilePath { get; set; } + + ExploreForm ExploreForm; + object CurrentFile; + + + public GenericForm(ExploreForm exploreForm) + { + ExploreForm = exploreForm; + InitializeComponent(); + } + + + public void LoadFile(object file, RpfFileEntry fileEntry) + { + CurrentFile = file; + + DetailsPropertyGrid.SelectedObject = file; + + fileName = fileEntry?.Name; + + UpdateFormTitle(); + } + + + private void UpdateFormTitle() + { + Text = fileName + " - File Inspector - CodeWalker by dexyfex"; + } + + } +} diff --git a/Forms/GenericForm.resx b/Forms/GenericForm.resx new file mode 100644 index 0000000..1431f6b --- /dev/null +++ b/Forms/GenericForm.resx @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + 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 + 6P///ysvjWVqtP///////wAAAAAAAAAAAP////D0/0hPpsDG6////////6y02d7k8////3qAx+/z/f// + /wAAAAAAAAAAAAAAAAAAAP///////////////8zT8V5ns1Rcrdzh9f///////////wAAAAAAAAAAAAAA + AAAAAP////////7+/6ix3nmBxFthtmdwu09WqbC54/v9//r8//j6//39/wAAAAAAAAAAAOjt/H6I0FJc + skpSqHF+wRMahFZhs4iT1AsNc1pgrm52v2RsuO/z/gAAAP////////L2/cLJ7rrD64+V4DY+ozU+mYmU + 0X2Hy1hfss7V8urv/PP2/v///wAAAP///+Pp+d/k9////////+Pp/4uR3ysymW14xYOM0fD0/P///+Xq + +ri/6Pj6/wAAAOrv/j5DnbS75P////////////X4/+/0/ubr+/r7/////////9rh+hgZhKGo2QAAAPDz + /eLn+f////j6/2Nqttrg9////+Hn+P3+//3+/1hescLJ6/////L2/eru/AAAAAAAAAAAAP///8rR70tR + p/3+//v8/zY6jNPY7////09WqWpwu////wAAAAAAAAAAAAAAAAAAAAAAAPb4/vr7//////v8/5Wd1eHm + +P////v8//T3/wAAAAAAAAAAAAAAAP//AAD8PwAA/D8AAPwDAACAAwAAgAMAAIAHAADABwAAwAEAAMAB + AAAAAQAAAAEAAAABAAAAAQAAwAcAAOAPAAAoAAAAQAAAAIAAAAABABgAAAAAAAAwAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//P3//P3//P3/ + /f7//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/ + +fv/+fv/+Pr/+fv/+vv//P3//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/f7/+fr/8/b/7PL/5+3/6e/+9Pf/+vv//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/P3/9/r/6O7/cXe1UVaet7z17fL/+Pr//f3/AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+/z/9Pj/4Oj/NzyCUlOd2dz/6O//9Pf//P3/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/2+P9X2OmREGLnqPd + 4+v/8vb/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/ + 1N35bXK1JSRtbHGz5O7/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA+vv/8PX/3Ob/U1eaDwtXjZLT4+z/8fX/+/z/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA+vv/8fb/2eP+MjR6AAA+c3i34Or/8fX/+/z/AAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+vv/8vb/1d/7MS91AAA1UFSS4On/8vb/+/z/AAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + /v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+vz/+fv/+Pr/+Pr/+vv//f3//v//AAAAAAAAAAAAAAAA + /v//+fv/9Pf/2+L/SVGtAABsLTaZytL58fX/9/n//f7/AAAAAAAAAAAAAAAA/v7/+/z/9/n/9fj/9vn/ + 9fj/9vj/+vz//f7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7//f3//f3//f3//v7//v//AAAA + AAAAAAAAAAAAAAAAAAAA+/z/9vn/6e//mZ7gTVarr7bp6/H/9fj/+vv//v7/AAAAAAAAAAAAAAAAAAAA + /v7//f7/+/z/+/z/+/z//P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/f3/+Pr/9fj/6e7/4+n/8fb/9Pf/+Pr//f3/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//P3/+fv/+fv/+vv/+Pr/+vv/ + /P3//v7/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7//f7/ + /f3//P3//f7//v7//v//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////// + ///////4D/////////AH////////8Af////////wB/////////AH////////8Af////////wB/////// + //AH////////8Af////////wB/////////AH////////8AfwP//////wB8Af//+Af/AHgB///wA/8AcA + H///AB/wBgAf//8AD/AGAB///wAH8AYAH///AAPwBAAf//8AA/AEAD///wAD8AQAP///AAPwBAB///+A + A/AEAP///8AD4AAA////4AcAAAH////wDgAAAf/////8AAAH//////gAAAf/////4AAAAf/////gAAAA + /f//+AAAAAAAD//AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+AAAAAAAAH/4AAAAAAAAf/gAAAAAAAB/+A + AAAAAAAP/4AAAAAAAB//wAAAAABAf/4HwAAAAYAf8APAAAADgA/gA+AAAAMAA8AD8AAABwADgAP8AAAf + AAOAA/4AAB8AA4ADAAAAAQADgAIAcA4AgAOABgBwDgBAA4AMAGAMADADwDwAYAwAOAfg+ABgBAAeH//4 + AEAEAB////gAwAYAH///+ADABgAf///4AcAGAB////gBwAcAH///+APAB4A////8B+AHwH//////4A// + ///////gD/////////Af//////////////8= + + + \ No newline at end of file