From 89035ef2797e1a3516833f6f6b8298611195960f Mon Sep 17 00:00:00 2001 From: dexy Date: Sat, 23 Nov 2019 03:57:00 +1100 Subject: [PATCH] Cutscenes classes loading from XML --- .../GameFiles/FileTypes/CutFile.cs | 625 +++++++++++++++++- .../GameFiles/MetaTypes/XmlMeta.cs | 18 + CodeWalker.Core/Utils/Xml.cs | 24 + 3 files changed, 636 insertions(+), 31 deletions(-) diff --git a/CodeWalker.Core/GameFiles/FileTypes/CutFile.cs b/CodeWalker.Core/GameFiles/FileTypes/CutFile.cs index 0761324..0064e6f 100644 --- a/CodeWalker.Core/GameFiles/FileTypes/CutFile.cs +++ b/CodeWalker.Core/GameFiles/FileTypes/CutFile.cs @@ -4,10 +4,11 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using SharpDX; +using System.Xml; using TC = System.ComponentModel.TypeConverterAttribute; using EXP = System.ComponentModel.ExpandableObjectConverter; -using SharpDX; namespace CodeWalker.GameFiles { @@ -17,6 +18,9 @@ namespace CodeWalker.GameFiles public PsoFile Pso { get; set; } + public CutsceneFile2 CutsceneFile2 { get; set; } + + public CutFile() { } public CutFile(RpfFileEntry entry) @@ -27,8 +31,6 @@ namespace CodeWalker.GameFiles public void Load(byte[] data, RpfFileEntry entry) { - //MemoryStream ms = new MemoryStream(data); - FileEntry = entry; MemoryStream ms = new MemoryStream(data); @@ -38,8 +40,13 @@ namespace CodeWalker.GameFiles Pso = new PsoFile(); Pso.Load(ms); - //var xml = PsoXml.GetXml(Pso); + var xml = PsoXml.GetXml(Pso); + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); + var node = doc.DocumentElement; + CutsceneFile2 = new CutsceneFile2(); + CutsceneFile2.ReadXml(node); } else @@ -51,9 +58,16 @@ namespace CodeWalker.GameFiles } + [TC(typeof(EXP))] public abstract class CutBase : IMetaXmlItem + { + public virtual void ReadXml(XmlNode node) + { } + public virtual void WriteXml(StringBuilder sb, int indent) + { } + } - [TC(typeof(EXP))] public class CutsceneFile2 // rage__cutfCutsceneFile2 + [TC(typeof(EXP))] public class CutsceneFile2 : CutBase // rage__cutfCutsceneFile2 { public float fTotalDuration { get; set; } // PsoDataType.Float, 268, 0, 0), public string cFaceDir { get; set; } // PsoDataType.String, 272, 0, (MetaName)16777216), @@ -87,47 +101,210 @@ namespace CodeWalker.GameFiles public CutConcatData[] concatDataList { get; set; } // PsoDataType.Array, 784, 1, (MetaName)2621475),//ARRAYINFO, PsoDataType.Structure, 0, 0, MetaName.rage__cutfCutsceneFile2__SConcatData), public CutHaltFrequency[] discardFrameList { get; set; } // PsoDataType.Array, 5280, 0, (MetaName)37)//ARRAYINFO, PsoDataType.Structure, 0, 0, MetaName.vHaltFrequency), + public override void ReadXml(XmlNode node) + { + fTotalDuration = Xml.GetChildFloatAttribute(node, "fTotalDuration", "value"); + cFaceDir = Xml.GetChildInnerText(node, "cFaceDir"); + iCutsceneFlags = Xml.GetChildRawUintArray(node, "iCutsceneFlags"); + vOffset = Xml.GetChildVector3Attributes(node, "vOffset", "x", "y", "z"); + fRotation = Xml.GetChildFloatAttribute(node, "fRotation", "value"); + cExtraRoom = Xml.GetChildInnerText(node, "cExtraRoom"); + vExtraRoomPos = Xml.GetChildVector3Attributes(node, "vExtraRoomPos", "x", "y", "z"); + vTriggerOffset = Xml.GetChildVector3Attributes(node, "vTriggerOffset", "x", "y", "z"); + pCutsceneObjects = ReadObjectArray(node, "pCutsceneObjects"); + pCutsceneLoadEventList = ReadObjectArray(node, "pCutsceneLoadEventList"); + pCutsceneEventList = ReadObjectArray(node, "pCutsceneEventList"); + pCutsceneEventArgsList = ReadObjectArray(node, "pCutsceneEventArgsList"); + attributes = ReadObject(node, "attributes"); + cutfAttributes = ReadObject(node, "cutfAttributes"); + iRangeStart = Xml.GetChildIntAttribute(node, "iRangeStart", "value"); + iRangeEnd = Xml.GetChildIntAttribute(node, "iRangeEnd", "value"); + iAltRangeEnd = Xml.GetChildIntAttribute(node, "iAltRangeEnd", "value"); + fSectionByTimeSliceDuration = Xml.GetChildFloatAttribute(node, "fSectionByTimeSliceDuration", "value"); + fFadeOutCutsceneDuration = Xml.GetChildFloatAttribute(node, "fFadeOutCutsceneDuration", "value"); + fFadeInGameDuration = Xml.GetChildFloatAttribute(node, "fFadeInGameDuration", "value"); + fadeInColor = Xml.GetChildUIntAttribute(node, "fadeInColor", "value"); + iBlendOutCutsceneDuration = Xml.GetChildIntAttribute(node, "iBlendOutCutsceneDuration", "value"); + iBlendOutCutsceneOffset = Xml.GetChildIntAttribute(node, "iBlendOutCutsceneOffset", "value"); + fFadeOutGameDuration = Xml.GetChildFloatAttribute(node, "fFadeOutGameDuration", "value"); + fFadeInCutsceneDuration = Xml.GetChildFloatAttribute(node, "fFadeInCutsceneDuration", "value"); + fadeOutColor = Xml.GetChildUIntAttribute(node, "fadeOutColor", "value"); + Unk_619896503 = Xml.GetChildUIntAttribute(node, "hash_24F2DEB7", "value"); + cameraCutList = Xml.GetChildRawFloatArray(node, "cameraCutList"); + sectionSplitList = Xml.GetChildRawFloatArray(node, "sectionSplitList"); + concatDataList = XmlMeta.ReadItemArrayNullable(node, "concatDataList"); + discardFrameList = XmlMeta.ReadItemArrayNullable(node, "discardFrameList"); + } + public static CutBase ConstructObject(string type) + { + switch (type) + { + case "rage__cutfAssetManagerObject": return new CutAssetManagerObject(); + case "rage__cutfAnimationManagerObject": return new CutAnimationManagerObject(); + case "rage__cutfCameraObject": return new CutCameraObject(); + case "rage__cutfPedModelObject": return new CutPedModelObject(); + case "rage__cutfPropModelObject": return new CutPropModelObject(); + case "rage__cutfBlockingBoundsObject": return new CutBlockingBoundsObject(); + case "rage__cutfAudioObject": return new CutAudioObject(); + case "rage__cutfHiddenModelObject": return new CutHiddenModelObject(); + case "rage__cutfOverlayObject": return new CutOverlayObject(); + case "rage__cutfSubtitleObject": return new CutSubtitleObject(); + case "rage__cutfLightObject": return new CutLightObject(); + case "rage__cutfAnimatedLightObject": return new CutAnimatedLightObject(); + case "rage__cutfObjectIdEvent": return new CutObjectIdEvent(); + case "rage__cutfObjectVariationEventArgs": return new CutObjectVariationEventArgs(); + case "rage__cutfEventArgs": return new CutEventArgs(); + case "rage__cutfLoadSceneEventArgs": return new CutLoadSceneEventArgs(); + case "rage__cutfObjectIdEventArgs": return new CutObjectIdEventArgs(); + case "rage__cutfObjectIdListEventArgs": return new CutObjectIdListEventArgs(); + case "rage__cutfNameEventArgs": return new CutNameEventArgs(); + case "rage__cutfCameraCutEventArgs": return new CutCameraCutEventArgs(); + case "rage__cutfSubtitleEventArgs": return new CutSubtitleEventArgs(); + case "rage__cutfFinalNameEventArgs": return new CutFinalNameEventArgs(); + case "rage__cutfObjectIdNameEventArgs": return new CutObjectIdNameEventArgs(); + case "rage__cutfVehicleModelObject": return new CutVehicleModelObject(); + case "rage__cutfEvent": return new CutEvent(); + case "rage__cutfCascadeShadowEventArgs": return new CutCascadeShadowEventArgs(); + case "rage__cutfFloatValueEventArgs": return new CutFloatValueEventArgs(); + case "rage__cutfAnimatedParticleEffectObject": return new CutAnimatedParticleEffectObject(); + case "rage__cutfWeaponModelObject": return new CutWeaponModelObject(); + case "rage__cutfPlayParticleEffectEventArgs": return new CutPlayParticleEffectEventArgs(); + case "rage__cutfBoolValueEventArgs": return new CutBoolValueEventArgs(); + case "rage__cutfRayfireObject": return new CutRayfireObject(); + case "rage__cutfParticleEffectObject": return new CutParticleEffectObject(); + case "rage__cutfDecalObject": return new CutDecalObject(); + case "rage__cutfDecalEventArgs": return new CutDecalEventArgs(); + case "rage__cutfScreenFadeObject": return new CutScreenFadeObject(); + case "rage__cutfVehicleVariationEventArgs": return new CutVehicleVariationEventArgs(); + case "rage__cutfScreenFadeEventArgs": return new CutScreenFadeEventArgs(); + case "rage__cutfTriggerLightEffectEventArgs": return new CutTriggerLightEffectEventArgs(); + case "rage__cutfVehicleExtraEventArgs": return new CutVehicleExtraEventArgs(); + case "rage__cutfFixupModelObject": return new CutFixupModelObject(); + case "hash_63D1D732": return new Cut_1674696498(); + case "hash_60F51ABE": return new Cut_1626675902(); + case "hash_2139D1CA": return new Cut_557437386(); + default: return null; + } + } + public static T ReadObject(XmlNode node, string name) where T : IMetaXmlItem, new() + { + var onode = node.SelectSingleNode(name); + if (onode != null) + { + var o = new T(); + o.ReadXml(onode); + return o; + } + return default(T); + } + public static object[] ReadObjectArray(XmlNode node, string name) + { + var aNode = node.SelectSingleNode(name); + if (aNode != null) + { + var inodes = aNode.SelectNodes("Item"); + if (inodes?.Count > 0) + { + var oList = new List(); + foreach (XmlNode inode in inodes) + { + var type = Xml.GetStringAttribute(inode, "type"); + var o = ConstructObject(type); + o.ReadXml(inode); + oList.Add(o); + } + return oList.ToArray(); + } + } + return null; + } } - [TC(typeof(EXP))] public class CutParAttributeList // rage__parAttributeList + [TC(typeof(EXP))] public class CutParAttributeList : CutBase // rage__parAttributeList { public byte UserData1 { get; set; } // PsoDataType.UByte, 8, 0, 0), public byte UserData2 { get; set; } // PsoDataType.UByte, 9, 0, 0) + public override void ReadXml(XmlNode node) + { + UserData1 = (byte)Xml.GetChildUIntAttribute(node, "UserData1", "value"); + UserData2 = (byte)Xml.GetChildUIntAttribute(node, "UserData2", "value"); + } + + public override string ToString() + { + return UserData1.ToString() + ", " + UserData2.ToString(); + } } - [TC(typeof(EXP))] public class CutFAttributeList // rage__cutfAttributeList + [TC(typeof(EXP))] public class CutFAttributeList : CutBase // rage__cutfAttributeList { public object[] Items { get; set; } // PsoDataType.Array, 0, 0, 0)//ARRAYINFO, PsoDataType.Structure, 0, 3, 0), - //Cut_1626675902 (int attribute) - //Cut_1674696498 (float attribute) - //Cut_557437386 (string attribute) + public override void ReadXml(XmlNode node) + { + Items = CutsceneFile2.ReadObjectArray(node, "Items"); + } + + public override string ToString() + { + return (Items?.Length ?? 0).ToString() + " items"; + } } - [TC(typeof(EXP))] public class Cut_1626675902 + [TC(typeof(EXP))] public class Cut_1626675902 : CutBase { public MetaHash Name { get; set; } // PsoDataType.String, 8, 8, 0), public int Value { get; set; } // PsoDataType.SInt, 16, 0, 0) + public override void ReadXml(XmlNode node) + { + Name = XmlMeta.GetHash(Xml.GetChildInnerText(node, "Name")); + Value = Xml.GetChildIntAttribute(node, "Value", "value"); + } + + public override string ToString() + { + return Name.ToString() + ": " + Value.ToString(); + } } - [TC(typeof(EXP))] public class Cut_1674696498 + [TC(typeof(EXP))] public class Cut_1674696498 : CutBase { public MetaHash Name { get; set; } // PsoDataType.String, 8, 8, 0), public float Value { get; set; } // PsoDataType.Float, 16, 0, 0) + public override void ReadXml(XmlNode node) + { + Name = XmlMeta.GetHash(Xml.GetChildInnerText(node, "Name")); + Value = Xml.GetChildFloatAttribute(node, "Value", "value"); + } + + public override string ToString() + { + return Name.ToString() + ": " + Value.ToString(); + } } - [TC(typeof(EXP))] public class Cut_557437386 + [TC(typeof(EXP))] public class Cut_557437386 : CutBase { public MetaHash Name { get; set; } // PsoDataType.String, 8, 8, 0), public string Value { get; set; } // PsoDataType.String, 16, 3, 0) + public override void ReadXml(XmlNode node) + { + Name = XmlMeta.GetHash(Xml.GetChildInnerText(node, "Name")); + Value = Xml.GetChildInnerText(node, "Value"); + } + + public override string ToString() + { + return Name.ToString() + ": " + Value.ToString(); + } } - [TC(typeof(EXP))] public class CutConcatData // rage__cutfCutsceneFile2__SConcatData + [TC(typeof(EXP))] public class CutConcatData : CutBase // rage__cutfCutsceneFile2__SConcatData { public MetaHash cSceneName { get; set; } // PsoDataType.String, 0, 7, 0), public Vector3 vOffset { get; set; } // PsoDataType.Float3, 16, 0, 0), @@ -139,37 +316,66 @@ namespace CodeWalker.GameFiles public int iRangeEnd { get; set; } // PsoDataType.SInt, 52, 0, 0), public bool bValidForPlayBack { get; set; } // PsoDataType.Bool, 56, 0, 0) - - - + public override void ReadXml(XmlNode node) + { + cSceneName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cSceneName")); + vOffset = Xml.GetChildVector3Attributes(node, "vOffset", "x", "y", "z"); + fStartTime = Xml.GetChildFloatAttribute(node, "fStartTime", "value"); + fRotation = Xml.GetChildFloatAttribute(node, "fRotation", "value"); + fPitch = Xml.GetChildFloatAttribute(node, "fPitch", "value"); + fRoll = Xml.GetChildFloatAttribute(node, "fRoll", "value"); + iRangeStart = Xml.GetChildIntAttribute(node, "iRangeStart", "value"); + iRangeEnd = Xml.GetChildIntAttribute(node, "iRangeEnd", "value"); + bValidForPlayBack = Xml.GetChildBoolAttribute(node, "bValidForPlayBack", "value"); + } } - [TC(typeof(EXP))] public class CutHaltFrequency // vHaltFrequency + [TC(typeof(EXP))] public class CutHaltFrequency : CutBase // vHaltFrequency { public MetaHash cSceneName { get; set; } // PsoDataType.String, 0, 7, 0), public int[] frames { get; set; } // PsoDataType.Array, 8, 0, (MetaName)1)//ARRAYINFO, PsoDataType.SInt, 0, 0, 0), + public override void ReadXml(XmlNode node) + { + cSceneName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cSceneName")); + frames = Xml.GetChildRawIntArray(node, "frames"); + } } - [TC(typeof(EXP))] public class CutAssetManagerObject // rage__cutfAssetManagerObject - { - public int iObjectId { get; set; } // PsoDataType.SInt, 8, 0, 0), - public CutParAttributeList attributes { get; set; } // PsoDataType.Structure, 20, 0, MetaName.rage__parAttributeList), - public CutFAttributeList cutfAttributes { get; set; } // PsoDataType.Structure, 32, 4, 0) - - } - [TC(typeof(EXP))] public class CutAnimationManagerObject // rage__cutfAnimationManagerObject + [TC(typeof(EXP))] public abstract class CutObject : CutBase { public int iObjectId { get; set; } // PsoDataType.SInt, 8, 0, 0), public CutParAttributeList attributeList { get; set; } // PsoDataType.Structure, 20, 0, MetaName.rage__parAttributeList), public CutFAttributeList cutfAttributes { get; set; } // PsoDataType.Structure, 32, 4, 0) + public override void ReadXml(XmlNode node) + { + iObjectId = Xml.GetChildIntAttribute(node, "iObjectId", "value"); + attributeList = CutsceneFile2.ReadObject(node, "attributeList"); //might also be called "attributes" ? + cutfAttributes = CutsceneFile2.ReadObject(node, "cutfAttributes"); + } + + public override string ToString() + { + return iObjectId.ToString() + ": " + base.ToString(); + } } - [TC(typeof(EXP))] public abstract class CutNamedObject : CutAnimationManagerObject + [TC(typeof(EXP))] public class CutAssetManagerObject : CutObject // rage__cutfAssetManagerObject + { + } + [TC(typeof(EXP))] public class CutAnimationManagerObject : CutObject // rage__cutfAnimationManagerObject + { + } + [TC(typeof(EXP))] public abstract class CutNamedObject : CutObject { public MetaHash cName { get; set; } // PsoDataType.String, 40, 7, 0), + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + cName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cName")); + } } [TC(typeof(EXP))] public class CutCameraObject : CutNamedObject // rage__cutfCameraObject { @@ -177,6 +383,13 @@ namespace CodeWalker.GameFiles public float fNearDrawDistance { get; set; } // PsoDataType.Float, 56, 0, 0), public float fFarDrawDistance { get; set; } // PsoDataType.Float, 60, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + AnimStreamingBase = Xml.GetChildUIntAttribute(node, "AnimStreamingBase", "value"); + fNearDrawDistance = Xml.GetChildFloatAttribute(node, "fNearDrawDistance", "value"); + fFarDrawDistance = Xml.GetChildFloatAttribute(node, "fFarDrawDistance", "value"); + } } [TC(typeof(EXP))] public class CutPedModelObject : CutNamedObject // rage__cutfPedModelObject { @@ -196,6 +409,24 @@ namespace CodeWalker.GameFiles public MetaHash faceAttributesFilename { get; set; } // PsoDataType.String, 112, 7, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + StreamingName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "StreamingName")); + AnimStreamingBase = Xml.GetChildUIntAttribute(node, "AnimStreamingBase", "value"); + cAnimExportCtrlSpecFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cAnimExportCtrlSpecFile")); + cFaceExportCtrlSpecFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cFaceExportCtrlSpecFile")); + cAnimCompressionFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cAnimCompressionFile")); + cHandle = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cHandle")); + Unk_673165049 = Xml.GetChildUIntAttribute(node, "hash_281FAEF9", "value"); + typeFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "typeFile")); + overrideFaceAnimationFilename = XmlMeta.GetHash(Xml.GetChildInnerText(node, "overrideFaceAnimationFilename")); + bFoundFaceAnimation = Xml.GetChildBoolAttribute(node, "bFoundFaceAnimation", "value"); + bFaceAndBodyAreMerged = Xml.GetChildBoolAttribute(node, "bFaceAndBodyAreMerged", "value"); + bOverrideFaceAnimation = Xml.GetChildBoolAttribute(node, "bOverrideFaceAnimation", "value"); + faceAnimationNodeName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "faceAnimationNodeName")); + faceAttributesFilename = XmlMeta.GetHash(Xml.GetChildInnerText(node, "faceAttributesFilename")); + } } [TC(typeof(EXP))] public class CutPropModelObject : CutNamedObject // rage__cutfPropModelObject { @@ -207,23 +438,51 @@ namespace CodeWalker.GameFiles public MetaHash cHandle { get; set; } // PsoDataType.String, 84, 7, 0), public MetaHash typeFile { get; set; } // PsoDataType.String, 88, 7, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + StreamingName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "StreamingName")); + AnimStreamingBase = Xml.GetChildUIntAttribute(node, "AnimStreamingBase", "value"); + cAnimExportCtrlSpecFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cAnimExportCtrlSpecFile")); + cFaceExportCtrlSpecFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cFaceExportCtrlSpecFile")); + cAnimCompressionFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cAnimCompressionFile")); + cHandle = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cHandle")); + typeFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "typeFile")); + } } [TC(typeof(EXP))] public class CutBlockingBoundsObject : CutNamedObject // rage__cutfBlockingBoundsObject { public Vector3[] vCorners { get; set; } // PsoDataType.Array, 48, 4, (MetaName)262148),//ARRAYINFO, PsoDataType.Float3, 0, 0, 0), public float fHeight { get; set; } // PsoDataType.Float, 112, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + vCorners = Xml.GetChildRawVector3Array(node, "vCorners"); + fHeight = Xml.GetChildFloatAttribute(node, "fHeight", "value"); + } } [TC(typeof(EXP))] public class CutAudioObject : CutNamedObject // rage__cutfAudioObject { public float fOffset { get; set; } // PsoDataType.Float, 56, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + fOffset = Xml.GetChildFloatAttribute(node, "fOffset", "value"); + } } [TC(typeof(EXP))] public class CutHiddenModelObject : CutNamedObject // rage__cutfHiddenModelObject { public Vector3 vPosition { get; set; } // PsoDataType.Float3, 48, 0, 0), public float fRadius { get; set; } // PsoDataType.Float, 64, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + vPosition = Xml.GetChildVector3Attributes(node, "vPosition", "x", "y", "z"); + fRadius = Xml.GetChildFloatAttribute(node, "fRadius", "value"); + } } [TC(typeof(EXP))] public class CutOverlayObject : CutNamedObject // rage__cutfOverlayObject { @@ -231,6 +490,13 @@ namespace CodeWalker.GameFiles public uint iOverlayType { get; set; } // PsoDataType.UInt, 72, 0, 0), public MetaHash modelHashName { get; set; } // PsoDataType.String, 76, 7, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + cRenderTargetName = Xml.GetChildInnerText(node, "cRenderTargetName"); + iOverlayType = Xml.GetChildUIntAttribute(node, "iOverlayType", "value"); + modelHashName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "modelHashName")); + } } [TC(typeof(EXP))] public class CutSubtitleObject : CutNamedObject // rage__cutfSubtitleObject { @@ -260,6 +526,32 @@ namespace CodeWalker.GameFiles public ushort Unk_1437992521 { get; set; } // PsoDataType.UShort, 228, 0, 0), public bool bStatic { get; set; } // PsoDataType.Bool, 230, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + vDirection = Xml.GetChildVector3Attributes(node, "vDirection", "x", "y", "z"); + vColour = Xml.GetChildVector3Attributes(node, "vColour", "x", "y", "z"); + vPosition = Xml.GetChildVector3Attributes(node, "vPosition", "x", "y", "z"); + fIntensity = Xml.GetChildFloatAttribute(node, "fIntensity", "value"); + fFallOff = Xml.GetChildFloatAttribute(node, "fFallOff", "value"); + fConeAngle = Xml.GetChildFloatAttribute(node, "fConeAngle", "value"); + fVolumeIntensity = Xml.GetChildFloatAttribute(node, "fVolumeIntensity", "value"); + fVolumeSizeScale = Xml.GetChildFloatAttribute(node, "fVolumeSizeScale", "value"); + fCoronaSize = Xml.GetChildFloatAttribute(node, "fCoronaSize", "value"); + fCoronaIntensity = Xml.GetChildFloatAttribute(node, "fCoronaIntensity", "value"); + fCoronaZBias = Xml.GetChildFloatAttribute(node, "fCoronaZBias", "value"); + fInnerConeAngle = Xml.GetChildFloatAttribute(node, "fInnerConeAngle", "value"); + fExponentialFallOff = Xml.GetChildFloatAttribute(node, "fExponentialFallOff", "value"); + iLightType = Xml.GetChildIntAttribute(node, "iLightType", "value"); + iLightProperty = Xml.GetChildIntAttribute(node, "iLightProperty", "value"); + TextureDictID = Xml.GetChildIntAttribute(node, "TextureDictID", "value"); + TextureKey = Xml.GetChildIntAttribute(node, "TextureKey", "value"); + Unk_34975788 = Xml.GetChildIntAttribute(node, "hash_0215B02C", "value"); + uLightFlags = Xml.GetChildUIntAttribute(node, "uLightFlags", "value"); + uHourFlags = Xml.GetChildUIntAttribute(node, "uHourFlags", "value"); + Unk_1437992521 = (ushort)Xml.GetChildUIntAttribute(node, "hash_55B60649", "value"); + bStatic = Xml.GetChildBoolAttribute(node, "bStatic", "value"); + } } [TC(typeof(EXP))] public class CutAnimatedLightObject : CutNamedObject // rage__cutfAnimatedLightObject { @@ -281,11 +573,41 @@ namespace CodeWalker.GameFiles public int iLightProperty { get; set; } // PsoDataType.SInt, 160, 0, 0), public int TextureDictID { get; set; } // PsoDataType.SInt, 164, 0, 0), public int TextureKey { get; set; } // PsoDataType.SInt, 168, 0, 0), + //public int Unk_34975788 { get; set; } // PsoDataType.SInt, 216, 0, 0), public uint uLightFlags { get; set; } // PsoDataType.UInt, 176, 0, 0), public uint uHourFlags { get; set; } // PsoDataType.UInt, 180, 0, 0), + //public ushort Unk_1437992521 { get; set; } // PsoDataType.UShort, 228, 0, 0), public bool bStatic { get; set; } // PsoDataType.Bool, 186, 0, 0), public uint AnimStreamingBase { get; set; } // PsoDataType.UInt, 192, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + vDirection = Xml.GetChildVector3Attributes(node, "vDirection", "x", "y", "z"); + vColour = Xml.GetChildVector3Attributes(node, "vColour", "x", "y", "z"); + vPosition = Xml.GetChildVector3Attributes(node, "vPosition", "x", "y", "z"); + fIntensity = Xml.GetChildFloatAttribute(node, "fIntensity", "value"); + fFallOff = Xml.GetChildFloatAttribute(node, "fFallOff", "value"); + fConeAngle = Xml.GetChildFloatAttribute(node, "fConeAngle", "value"); + fVolumeIntensity = Xml.GetChildFloatAttribute(node, "fVolumeIntensity", "value"); + fVolumeSizeScale = Xml.GetChildFloatAttribute(node, "fVolumeSizeScale", "value"); + fCoronaSize = Xml.GetChildFloatAttribute(node, "fCoronaSize", "value"); + fCoronaIntensity = Xml.GetChildFloatAttribute(node, "fCoronaIntensity", "value"); + fCoronaZBias = Xml.GetChildFloatAttribute(node, "fCoronaZBias", "value"); + fInnerConeAngle = Xml.GetChildFloatAttribute(node, "fInnerConeAngle", "value"); + fExponentialFallOff = Xml.GetChildFloatAttribute(node, "fExponentialFallOff", "value"); + fShadowBlur = Xml.GetChildFloatAttribute(node, "fShadowBlur", "value"); + iLightType = Xml.GetChildIntAttribute(node, "iLightType", "value"); + iLightProperty = Xml.GetChildIntAttribute(node, "iLightProperty", "value"); + TextureDictID = Xml.GetChildIntAttribute(node, "TextureDictID", "value"); + TextureKey = Xml.GetChildIntAttribute(node, "TextureKey", "value"); + //Unk_34975788 = Xml.GetChildIntAttribute(node, "hash_0215B02C", "value"); + uLightFlags = Xml.GetChildUIntAttribute(node, "uLightFlags", "value"); + uHourFlags = Xml.GetChildUIntAttribute(node, "uHourFlags", "value"); + //Unk_1437992521 = (ushort)Xml.GetChildUIntAttribute(node, "hash_55B60649", "value"); + bStatic = Xml.GetChildBoolAttribute(node, "bStatic", "value"); + AnimStreamingBase = Xml.GetChildUIntAttribute(node, "AnimStreamingBase", "value"); + } } [TC(typeof(EXP))] public class CutVehicleModelObject : CutNamedObject // rage__cutfVehicleModelObject { @@ -299,6 +621,19 @@ namespace CodeWalker.GameFiles public string[] cRemoveBoneNameList { get; set; } // PsoDataType.Array, 96, 0, (MetaName)11),//ARRAYINFO, PsoDataType.String, 0, 3, 0), public bool bCanApplyRealDamage { get; set; } // PsoDataType.Bool, 112, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + StreamingName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "StreamingName")); + AnimStreamingBase = Xml.GetChildUIntAttribute(node, "AnimStreamingBase", "value"); + cAnimExportCtrlSpecFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cAnimExportCtrlSpecFile")); + cFaceExportCtrlSpecFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cFaceExportCtrlSpecFile")); + cAnimCompressionFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cAnimCompressionFile")); + cHandle = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cHandle")); + typeFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "typeFile")); + cRemoveBoneNameList = XmlMeta.ReadStringItemArray(node, "cRemoveBoneNameList"); + bCanApplyRealDamage = Xml.GetChildBoolAttribute(node, "bCanApplyRealDamage", "value"); + } } [TC(typeof(EXP))] public class CutWeaponModelObject : CutNamedObject // rage__cutfWeaponModelObject { @@ -311,18 +646,42 @@ namespace CodeWalker.GameFiles public MetaHash typeFile { get; set; } // PsoDataType.String, 88, 7, 0), public uint GenericWeaponType { get; set; } // PsoDataType.UInt, 96, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + StreamingName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "StreamingName")); + AnimStreamingBase = Xml.GetChildUIntAttribute(node, "AnimStreamingBase", "value"); + cAnimExportCtrlSpecFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cAnimExportCtrlSpecFile")); + cFaceExportCtrlSpecFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cFaceExportCtrlSpecFile")); + cAnimCompressionFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cAnimCompressionFile")); + cHandle = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cHandle")); + typeFile = XmlMeta.GetHash(Xml.GetChildInnerText(node, "typeFile")); + GenericWeaponType = Xml.GetChildUIntAttribute(node, "GenericWeaponType", "value"); + } } [TC(typeof(EXP))] public class CutRayfireObject : CutNamedObject // rage__cutfRayfireObject { public MetaHash StreamingName { get; set; } // PsoDataType.String, 48, 7, 0), public Vector3 vStartPosition { get; set; } // PsoDataType.Float3, 64, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + StreamingName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "StreamingName")); + vStartPosition = Xml.GetChildVector3Attributes(node, "vStartPosition", "x", "y", "z"); + } } [TC(typeof(EXP))] public class CutParticleEffectObject : CutNamedObject // rage__cutfParticleEffectObject { public MetaHash StreamingName { get; set; } // PsoDataType.String, 48, 7, 0), public MetaHash athFxListHash { get; set; } // PsoDataType.String, 56, 7, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + StreamingName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "StreamingName")); + athFxListHash = XmlMeta.GetHash(Xml.GetChildInnerText(node, "athFxListHash")); + } } [TC(typeof(EXP))] public class CutAnimatedParticleEffectObject : CutNamedObject // rage__cutfAnimatedParticleEffectObject { @@ -330,12 +689,25 @@ namespace CodeWalker.GameFiles public uint AnimStreamingBase { get; set; } // PsoDataType.UInt, 56, 0, 0), public MetaHash athFxListHash { get; set; } // PsoDataType.String, 64, 7, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + StreamingName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "StreamingName")); + AnimStreamingBase = Xml.GetChildUIntAttribute(node, "AnimStreamingBase", "value"); + athFxListHash = XmlMeta.GetHash(Xml.GetChildInnerText(node, "athFxListHash")); + } } [TC(typeof(EXP))] public class CutDecalObject : CutNamedObject // rage__cutfDecalObject { public MetaHash StreamingName { get; set; } // PsoDataType.String, 48, 7, 0), public uint RenderId { get; set; } // PsoDataType.UInt, 56, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + StreamingName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "StreamingName")); + RenderId = Xml.GetChildUIntAttribute(node, "RenderId", "value"); + } } [TC(typeof(EXP))] public class CutScreenFadeObject : CutNamedObject // rage__cutfScreenFadeObject { @@ -345,10 +717,16 @@ namespace CodeWalker.GameFiles public Vector3 vPosition { get; set; } // PsoDataType.Float3, 48, 0, 0), public float fRadius { get; set; } // PsoDataType.Float, 64, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + vPosition = Xml.GetChildVector3Attributes(node, "vPosition", "x", "y", "z"); + fRadius = Xml.GetChildFloatAttribute(node, "fRadius", "value"); + } } - [TC(typeof(EXP))] public class CutEvent // rage__cutfEvent + [TC(typeof(EXP))] public class CutEvent : CutBase // rage__cutfEvent { public float fTime { get; set; } // PsoDataType.Float, 16, 0, 0), public int iEventId { get; set; } // PsoDataType.SInt, 20, 0, 0), @@ -357,48 +735,101 @@ namespace CodeWalker.GameFiles public uint StickyId { get; set; } // PsoDataType.UInt, 40, 0, 0), public bool IsChild { get; set; } // PsoDataType.Bool, 44, 0, 0) + public override void ReadXml(XmlNode node) + { + fTime = Xml.GetChildFloatAttribute(node, "fTime", "value"); + iEventId = Xml.GetChildIntAttribute(node, "iEventId", "value"); + iEventArgsIndex = Xml.GetChildIntAttribute(node, "iEventArgsIndex", "value"); + //pChildEvents = CutsceneFile2.ReadObject(node, "pChildEvents"); //seems never used + StickyId = Xml.GetChildUIntAttribute(node, "StickyId", "value"); + IsChild = Xml.GetChildBoolAttribute(node, "IsChild", "value"); + + var cNode = node.SelectSingleNode("pChildEvents"); + if ((cNode?.ChildNodes?.Count > 0) || (cNode?.Attributes?.Count > 0)) + { } + } } [TC(typeof(EXP))] public class CutObjectIdEvent : CutEvent // rage__cutfObjectIdEvent { public int iObjectId { get; set; } // PsoDataType.SInt, 48, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + iObjectId = Xml.GetChildIntAttribute(node, "iObjectId", "value"); + } } - [TC(typeof(EXP))] public class CutEventArgs // rage__cutfEventArgs + [TC(typeof(EXP))] public class CutEventArgs : CutBase // rage__cutfEventArgs { public CutParAttributeList attributeList { get; set; } // PsoDataType.Structure, 12, 0, MetaName.rage__parAttributeList), public CutFAttributeList cutfAttributes { get; set; } // PsoDataType.Structure, 24, 4, 0) + public override void ReadXml(XmlNode node) + { + attributeList = CutsceneFile2.ReadObject(node, "attributeList"); + cutfAttributes = CutsceneFile2.ReadObject(node, "cutfAttributes"); + } } [TC(typeof(EXP))] public class CutNameEventArgs : CutEventArgs // rage__cutfNameEventArgs { public MetaHash cName { get; set; } // PsoDataType.String, 32, 7, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + cName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cName")); + } } [TC(typeof(EXP))] public class CutFinalNameEventArgs : CutEventArgs // rage__cutfFinalNameEventArgs { public string cName { get; set; } // PsoDataType.String, 32, 3, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + cName = Xml.GetChildInnerText(node, "cName"); + } } [TC(typeof(EXP))] public class CutObjectIdEventArgs : CutEventArgs // rage__cutfObjectIdEventArgs { public int iObjectId { get; set; } // PsoDataType.SInt, 32, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + iObjectId = Xml.GetChildIntAttribute(node, "iObjectId", "value"); + } } [TC(typeof(EXP))] public class CutObjectIdListEventArgs : CutEventArgs // rage__cutfObjectIdListEventArgs { public int[] iObjectIdList { get; set; } // PsoDataType.Array, 32, 0, (MetaName)2)//ARRAYINFO, PsoDataType.SInt, 0, 0, 0), + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + iObjectIdList = Xml.GetChildRawIntArray(node, "iObjectIdList"); + } } [TC(typeof(EXP))] public class CutFloatValueEventArgs : CutEventArgs // rage__cutfFloatValueEventArgs { public float fValue { get; set; } // PsoDataType.Float, 32, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + fValue = Xml.GetChildFloatAttribute(node, "fValue", "value"); + } } [TC(typeof(EXP))] public class CutBoolValueEventArgs : CutEventArgs // rage__cutfBoolValueEventArgs { public bool bValue { get; set; } // PsoDataType.Bool, 32, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + bValue = Xml.GetChildBoolAttribute(node, "bValue", "value"); + } } [TC(typeof(EXP))] public class CutLoadSceneEventArgs : CutNameEventArgs // rage__cutfLoadSceneEventArgs @@ -408,6 +839,14 @@ namespace CodeWalker.GameFiles public float fPitch { get; set; } // PsoDataType.Float, 68, 0, 0), public float fRoll { get; set; } // PsoDataType.Float, 72, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + vOffset = Xml.GetChildVector3Attributes(node, "vOffset", "x", "y", "z"); + fRotation = Xml.GetChildFloatAttribute(node, "fRotation", "value"); + fPitch = Xml.GetChildFloatAttribute(node, "fPitch", "value"); + fRoll = Xml.GetChildFloatAttribute(node, "fRoll", "value"); + } } [TC(typeof(EXP))] public class CutSubtitleEventArgs : CutNameEventArgs // rage__cutfSubtitleEventArgs { @@ -418,6 +857,16 @@ namespace CodeWalker.GameFiles public float fTransitionOutDuration { get; set; } // PsoDataType.Float, 56, 0, 0), public float fSubtitleDuration { get; set; } // PsoDataType.Float, 60, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + iLanguageID = Xml.GetChildIntAttribute(node, "iLanguageID", "value"); + iTransitionIn = Xml.GetChildIntAttribute(node, "iTransitionIn", "value"); + fTransitionInDuration = Xml.GetChildFloatAttribute(node, "fTransitionInDuration", "value"); + iTransitionOut = Xml.GetChildIntAttribute(node, "iTransitionOut", "value"); + fTransitionOutDuration = Xml.GetChildFloatAttribute(node, "fTransitionOutDuration", "value"); + fSubtitleDuration = Xml.GetChildFloatAttribute(node, "fSubtitleDuration", "value"); + } } [TC(typeof(EXP))] public class CutCameraCutEventArgs : CutNameEventArgs // rage__cutfCameraCutEventArgs { @@ -454,16 +903,59 @@ namespace CodeWalker.GameFiles public CutCameraCutCharacterLightParams CharacterLight { get; set; } // PsoDataType.Structure, 192, 0, MetaName.rage__cutfCameraCutCharacterLightParams), public CutCameraCutTimeOfDayDofModifier[] TimeOfDayDofModifers { get; set; } // PsoDataType.Array, 256, 0, (MetaName)34)//ARRAYINFO, PsoDataType.Structure, 0, 0, MetaName.rage__cutfCameraCutTimeOfDayDofModifier), + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + vPosition = Xml.GetChildVector3Attributes(node, "vPosition", "x", "y", "z"); + vRotationQuaternion = Xml.GetChildVector4Attributes(node, "vRotationQuaternion", "x", "y", "z", "w").ToQuaternion(); + fNearDrawDistance = Xml.GetChildFloatAttribute(node, "fNearDrawDistance", "value"); + fFarDrawDistance = Xml.GetChildFloatAttribute(node, "fFarDrawDistance", "value"); + fMapLodScale = Xml.GetChildFloatAttribute(node, "fMapLodScale", "value"); + ReflectionLodRangeStart = Xml.GetChildFloatAttribute(node, "ReflectionLodRangeStart", "value"); + ReflectionLodRangeEnd = Xml.GetChildFloatAttribute(node, "ReflectionLodRangeEnd", "value"); + ReflectionSLodRangeStart = Xml.GetChildFloatAttribute(node, "ReflectionSLodRangeStart", "value"); + ReflectionSLodRangeEnd = Xml.GetChildFloatAttribute(node, "ReflectionSLodRangeEnd", "value"); + LodMultHD = Xml.GetChildFloatAttribute(node, "LodMultHD", "value"); + LodMultOrphanedHD = Xml.GetChildFloatAttribute(node, "LodMultOrphanedHD", "value"); + LodMultLod = Xml.GetChildFloatAttribute(node, "LodMultLod", "value"); + LodMultSLod1 = Xml.GetChildFloatAttribute(node, "LodMultSLod1", "value"); + LodMultSLod2 = Xml.GetChildFloatAttribute(node, "LodMultSLod2", "value"); + LodMultSLod3 = Xml.GetChildFloatAttribute(node, "LodMultSLod3", "value"); + LodMultSLod4 = Xml.GetChildFloatAttribute(node, "LodMultSLod4", "value"); + WaterReflectionFarClip = Xml.GetChildFloatAttribute(node, "WaterReflectionFarClip", "value"); + SSAOLightInten = Xml.GetChildFloatAttribute(node, "SSAOLightInten", "value"); + ExposurePush = Xml.GetChildFloatAttribute(node, "ExposurePush", "value"); + LightFadeDistanceMult = Xml.GetChildFloatAttribute(node, "LightFadeDistanceMult", "value"); + LightShadowFadeDistanceMult = Xml.GetChildFloatAttribute(node, "LightShadowFadeDistanceMult", "value"); + LightSpecularFadeDistMult = Xml.GetChildFloatAttribute(node, "LightSpecularFadeDistMult", "value"); + LightVolumetricFadeDistanceMult = Xml.GetChildFloatAttribute(node, "LightVolumetricFadeDistanceMult", "value"); + DirectionalLightMultiplier = Xml.GetChildFloatAttribute(node, "DirectionalLightMultiplier", "value"); + LensArtefactMultiplier = Xml.GetChildFloatAttribute(node, "LensArtefactMultiplier", "value"); + BloomMax = Xml.GetChildFloatAttribute(node, "BloomMax", "value"); + DisableHighQualityDof = Xml.GetChildBoolAttribute(node, "DisableHighQualityDof", "value"); + FreezeReflectionMap = Xml.GetChildBoolAttribute(node, "FreezeReflectionMap", "value"); + DisableDirectionalLighting = Xml.GetChildBoolAttribute(node, "DisableDirectionalLighting", "value"); + AbsoluteIntensityEnabled = Xml.GetChildBoolAttribute(node, "AbsoluteIntensityEnabled", "value"); + CharacterLight = CutsceneFile2.ReadObject(node, "CharacterLight"); + TimeOfDayDofModifers = XmlMeta.ReadItemArrayNullable(node, "TimeOfDayDofModifers"); + } } - [TC(typeof(EXP))] public class CutCameraCutCharacterLightParams // rage__cutfCameraCutCharacterLightParams + [TC(typeof(EXP))] public class CutCameraCutCharacterLightParams : CutBase // rage__cutfCameraCutCharacterLightParams { public bool bUseTimeCycleValues { get; set; } // PsoDataType.Bool, 8, 0, 0), public Vector3 vDirection { get; set; } // PsoDataType.Float3, 16, 0, 0), public Vector3 vColour { get; set; } // PsoDataType.Float3, 32, 0, 0), public float fIntensity { get; set; } // PsoDataType.Float, 48, 0, 0) + public override void ReadXml(XmlNode node) + { + bUseTimeCycleValues = Xml.GetChildBoolAttribute(node, "bUseTimeCycleValues", "value"); + vDirection = Xml.GetChildVector3Attributes(node, "vDirection", "x", "y", "z"); + vColour = Xml.GetChildVector3Attributes(node, "vColour", "x", "y", "z"); + fIntensity = Xml.GetChildFloatAttribute(node, "fIntensity", "value"); + } } - [TC(typeof(EXP))] public class CutCameraCutTimeOfDayDofModifier // rage__cutfCameraCutTimeOfDayDofModifier + [TC(typeof(EXP))] public class CutCameraCutTimeOfDayDofModifier : CutBase // rage__cutfCameraCutTimeOfDayDofModifier { //no definition available for this?? } @@ -472,6 +964,11 @@ namespace CodeWalker.GameFiles { public MetaHash cName { get; set; } // PsoDataType.String, 40, 7, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + cName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cName")); + } } [TC(typeof(EXP))] public class CutObjectVariationEventArgs : CutObjectIdEventArgs // rage__cutfObjectVariationEventArgs { @@ -479,6 +976,13 @@ namespace CodeWalker.GameFiles public int iDrawable { get; set; } // PsoDataType.SInt, 44, 0, 0), public int iTexture { get; set; } // PsoDataType.SInt, 48, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + iComponent = Xml.GetChildIntAttribute(node, "iComponent", "value"); + iDrawable = Xml.GetChildIntAttribute(node, "iDrawable", "value"); + iTexture = Xml.GetChildIntAttribute(node, "iTexture", "value"); + } } [TC(typeof(EXP))] public class CutVehicleVariationEventArgs : CutObjectIdEventArgs // rage__cutfVehicleVariationEventArgs { @@ -491,11 +995,28 @@ namespace CodeWalker.GameFiles public int iLivery2 { get; set; } // PsoDataType.SInt, 64, 0, 0), public float fDirtLevel { get; set; } // PsoDataType.Float, 68, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + iMainBodyColour = Xml.GetChildIntAttribute(node, "iMainBodyColour", "value"); + iSecondBodyColour = Xml.GetChildIntAttribute(node, "iSecondBodyColour", "value"); + iSpecularColour = Xml.GetChildIntAttribute(node, "iSpecularColour", "value"); + iWheelTrimColour = Xml.GetChildIntAttribute(node, "iWheelTrimColour", "value"); + Unk_2747538743 = Xml.GetChildIntAttribute(node, "hash_A3C41D37", "value"); + iLivery = Xml.GetChildIntAttribute(node, "iLivery", "value"); + iLivery2 = Xml.GetChildIntAttribute(node, "iLivery2", "value"); + fDirtLevel = Xml.GetChildFloatAttribute(node, "fDirtLevel", "value"); + } } [TC(typeof(EXP))] public class CutVehicleExtraEventArgs : CutObjectIdEventArgs // rage__cutfVehicleExtraEventArgs { public int[] pExtraBoneIds { get; set; } // PsoDataType.Array, 40, 0, (MetaName)3)//ARRAYINFO, PsoDataType.SInt, 0, 0, 0), + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + pExtraBoneIds = Xml.GetChildRawIntArray(node, "pExtraBoneIds"); + } } [TC(typeof(EXP))] public class CutDecalEventArgs : CutEventArgs // rage__cutfDecalEventArgs @@ -507,12 +1028,28 @@ namespace CodeWalker.GameFiles public uint Colour { get; set; } // PsoDataType.UInt, 72, 1, 0), public float fLifeTime { get; set; } // PsoDataType.Float, 76, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + vPosition = Xml.GetChildVector3Attributes(node, "vPosition", "x", "y", "z"); + vRotation = Xml.GetChildVector4Attributes(node, "vRotation", "x", "y", "z", "w").ToQuaternion(); + fWidth = Xml.GetChildFloatAttribute(node, "fWidth", "value"); + fHeight = Xml.GetChildFloatAttribute(node, "fHeight", "value"); + Colour = Xml.GetChildUIntAttribute(node, "Colour", "value"); + fLifeTime = Xml.GetChildFloatAttribute(node, "fLifeTime", "value"); + } } [TC(typeof(EXP))] public class CutScreenFadeEventArgs : CutEventArgs // rage__cutfScreenFadeEventArgs { public float fValue { get; set; } // PsoDataType.Float, 32, 0, 0), public uint color { get; set; } // PsoDataType.UInt, 40, 1, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + fValue = Xml.GetChildFloatAttribute(node, "fValue", "value"); + color = Xml.GetChildUIntAttribute(node, "color", "value"); + } } [TC(typeof(EXP))] public class CutCascadeShadowEventArgs : CutEventArgs // rage__cutfCascadeShadowEventArgs { @@ -524,6 +1061,17 @@ namespace CodeWalker.GameFiles public bool enabled { get; set; } // PsoDataType.Bool, 76, 0, 0), public bool interpolateToDisabled { get; set; } // PsoDataType.Bool, 77, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + cameraCutHashName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cameraCutHashName")); + position = Xml.GetChildVector3Attributes(node, "position", "x", "y", "z"); + radius = Xml.GetChildFloatAttribute(node, "radius", "value"); + interpTime = Xml.GetChildFloatAttribute(node, "interpTime", "value"); + cascadeIndex = Xml.GetChildIntAttribute(node, "cascadeIndex", "value"); + enabled = Xml.GetChildBoolAttribute(node, "enabled", "value"); + interpolateToDisabled = Xml.GetChildBoolAttribute(node, "interpolateToDisabled", "value"); + } } [TC(typeof(EXP))] public class CutTriggerLightEffectEventArgs : CutEventArgs // rage__cutfTriggerLightEffectEventArgs { @@ -531,6 +1079,13 @@ namespace CodeWalker.GameFiles public ushort iAttachBoneHash { get; set; } // PsoDataType.UShort, 36, 0, 0), public MetaHash AttachedParentName { get; set; } // PsoDataType.String, 40, 7, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + iAttachParentId = Xml.GetChildIntAttribute(node, "iAttachParentId", "value"); + iAttachBoneHash = (ushort)Xml.GetChildUIntAttribute(node, "iAttachBoneHash", "value"); + AttachedParentName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "AttachedParentName")); + } } [TC(typeof(EXP))] public class CutPlayParticleEffectEventArgs : CutEventArgs // rage__cutfPlayParticleEffectEventArgs { @@ -539,6 +1094,14 @@ namespace CodeWalker.GameFiles public int iAttachParentId { get; set; } // PsoDataType.SInt, 64, 0, 0), public ushort iAttachBoneHash { get; set; } // PsoDataType.UShort, 68, 0, 0) + public override void ReadXml(XmlNode node) + { + base.ReadXml(node); + vInitialBoneRotation = Xml.GetChildVector4Attributes(node, "vInitialBoneRotation", "x", "y", "z", "w").ToQuaternion(); + vInitialBoneOffset = Xml.GetChildVector3Attributes(node, "vInitialBoneOffset", "x", "y", "z"); + iAttachParentId = Xml.GetChildIntAttribute(node, "iAttachParentId", "value"); + iAttachBoneHash = (ushort)Xml.GetChildUIntAttribute(node, "iAttachBoneHash", "value"); + } } diff --git a/CodeWalker.Core/GameFiles/MetaTypes/XmlMeta.cs b/CodeWalker.Core/GameFiles/MetaTypes/XmlMeta.cs index 91f6b2f..ddd6ed0 100644 --- a/CodeWalker.Core/GameFiles/MetaTypes/XmlMeta.cs +++ b/CodeWalker.Core/GameFiles/MetaTypes/XmlMeta.cs @@ -884,6 +884,24 @@ namespace CodeWalker.GameFiles } return null; } + public static string[] ReadStringItemArray(XmlNode node, string name) + { + var vnode = node.SelectSingleNode(name); + if (vnode != null) + { + var inodes = vnode.SelectNodes("Item"); + if (inodes?.Count > 0) + { + var vlist = new List(); + foreach (XmlNode inode in inodes) + { + vlist.Add(inode.InnerText); + } + return vlist.ToArray(); + } + } + return null; + } } diff --git a/CodeWalker.Core/Utils/Xml.cs b/CodeWalker.Core/Utils/Xml.cs index 2c7b912..71e0be9 100644 --- a/CodeWalker.Core/Utils/Xml.cs +++ b/CodeWalker.Core/Utils/Xml.cs @@ -242,6 +242,30 @@ namespace CodeWalker return GetRawUintArray(cnode); } + public static int[] GetRawIntArray(XmlNode node) + { + if (node == null) return new int[0]; + var data = new List(); + var split = Regex.Split(node.InnerText, @"[\s\r\n\t]"); + for (int i = 0; i < split.Length; i++) + { + if (!string.IsNullOrEmpty(split[i])) + { + var str = split[i]; + if (string.IsNullOrEmpty(str)) continue; + var val = 0; + int.TryParse(str, out val); + data.Add(val); + } + } + return data.ToArray(); + } + public static int[] GetChildRawIntArray(XmlNode node, string name) + { + var cnode = node.SelectSingleNode(name); + return GetRawIntArray(cnode); + } + public static float[] GetRawFloatArray(XmlNode node) { if (node == null) return new float[0];