diff --git a/CodeWalker.Core/GameFiles/FileTypes/RelFile.cs b/CodeWalker.Core/GameFiles/FileTypes/RelFile.cs
index e95bd69f0..dd0895ae0 100644
--- a/CodeWalker.Core/GameFiles/FileTypes/RelFile.cs
+++ b/CodeWalker.Core/GameFiles/FileTypes/RelFile.cs
@@ -1791,7 +1791,7 @@ public class RelSoundHeader
public FlagsUint Flags { get; set; }
public FlagsUint Flags2 { get; set; }
- public ushort MaxHeaderSize { get; set; }
+ public ushort ParentOverrides { get; set; } // bit 0=Volume, 1=Pitch, 2=Pan, 3=PreDelay, 4=StartOffset, 5=AttackTime, 6=ReleaseTime, 7=DopplerFactor, 8=LPFCutoff, 9=HPFCutoff, 10=VolumeCurve, 11=VolumeCurveScale, 12=VolumeCurvePlateau, 13=SpeakerMask
public short Volume { get; set; }
public ushort VolumeVariance { get; set; } //0xD-0xF
public short Pitch { get; set; } //0xF-0x11
@@ -1841,7 +1841,7 @@ public RelSoundHeader(BinaryReader br)
if ((Flags & 0xFF) != 0xAA)
{
if (Bit(0)) Flags2 = br.ReadUInt32();
- if (Bit(1)) MaxHeaderSize = br.ReadUInt16();
+ if (Bit(1)) ParentOverrides = br.ReadUInt16();
if (Bit(2)) Volume = br.ReadInt16();
if (Bit(3)) VolumeVariance = br.ReadUInt16();
if (Bit(4)) Pitch = br.ReadInt16();
@@ -1895,7 +1895,7 @@ public void Write(BinaryWriter bw)
if ((Flags & 0xFF) != 0xAA)
{
if (Bit(0)) bw.Write(Flags2);
- if (Bit(1)) bw.Write(MaxHeaderSize);
+ if (Bit(1)) bw.Write(ParentOverrides);
if (Bit(2)) bw.Write(Volume);
if (Bit(3)) bw.Write(VolumeVariance);
if (Bit(4)) bw.Write(Pitch);
@@ -1946,7 +1946,18 @@ public void WriteXml(StringBuilder sb, int indent)
if ((Flags & 0xFF) != 0xAA)
{
if (Bit(0)) RelXml.ValueTag(sb, indent, "Flags2", "0x" + Flags2.Hex);
- if (Bit(1)) RelXml.ValueTag(sb, indent, "MaxHeaderSize", MaxHeaderSize.ToString());
+ if (Bit(1))
+ {
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (ParentOverrideFlags flag in Enum.GetValues(typeof(ParentOverrideFlags)))
+ {
+ bool set = (ParentOverrides & (1 << (int)flag)) != 0;
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{set.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ }
if (Bit(2)) RelXml.ValueTag(sb, indent, "Volume", Volume.ToString());
if (Bit(3)) RelXml.ValueTag(sb, indent, "VolumeVariance", VolumeVariance.ToString());
if (Bit(4)) RelXml.ValueTag(sb, indent, "Pitch", Pitch.ToString());
@@ -1996,7 +2007,33 @@ public void ReadXml(XmlNode node)
if ((Flags & 0xFF) != 0xAA)
{
if (Bit(0)) Flags2 = Xml.GetChildUIntAttribute(node, "Flags2", "value");
- if (Bit(1)) MaxHeaderSize = (ushort)Xml.GetChildUIntAttribute(node, "MaxHeaderSize", "value");
+ if (Bit(1))
+ {
+ // support old format: or
+ uint legacyValue = Xml.GetChildUIntAttribute(node, "MaxHeaderSize", "value") | Xml.GetChildUIntAttribute(node, "ParentOverrides", "value");
+ // support new format: ...
+ XmlNode poNode = node.SelectSingleNode("ParentOverrides");
+ if (poNode != null && poNode.HasChildNodes)
+ {
+ ushort flags = 0;
+ foreach (XmlNode flagNode in poNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out ParentOverrideFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (string.Equals(valueStr, "true", StringComparison.OrdinalIgnoreCase))
+ {
+ flags |= (ushort)(1 << (int)flag);
+ }
+ }
+ }
+ ParentOverrides = flags;
+ }
+ else
+ {
+ ParentOverrides = (ushort)legacyValue;
+ }
+ }
if (Bit(2)) Volume = (short)Xml.GetChildIntAttribute(node, "Volume", "value");
if (Bit(3)) VolumeVariance = (ushort)Xml.GetChildUIntAttribute(node, "VolumeVariance", "value");
if (Bit(4)) Pitch = (short)Xml.GetChildIntAttribute(node, "Pitch", "value");
@@ -2047,7 +2084,7 @@ public uint CalcHeaderLength()
if ((Flags & 0xFF) != 0xAA)
{
if (Bit(0)) length += 4;// Flags2 = br.ReadUInt32();
- if (Bit(1)) length += 2;// MaxHeaderSize = br.ReadUInt16();
+ if (Bit(1)) length += 2;// ParentOverrides = br.ReadUInt16();
if (Bit(2)) length += 2;// Volume = br.ReadUInt16();
if (Bit(3)) length += 2;// VolumeVariance = br.ReadUInt16();
if (Bit(4)) length += 2;// Pitch = br.ReadUInt16();
@@ -2099,7 +2136,7 @@ private bool Bit(int b)
public override string ToString()
{
- return string.Format("{0}: {1}, {2}, {3}, {4}, {5}, {6}, {7}", Flags.Hex, Flags2.Hex, Category, StartOffset, StartOffsetVariance, VolumeCurve, PreDelayVariable, StartOffsetVariable);
+ return $"{Flags.Hex}: {Flags2.Hex}, {Category}, {StartOffset}, {StartOffsetVariance}, {VolumeCurve}, {PreDelayVariable}, {StartOffsetVariable}";
}
}
@@ -2161,11 +2198,15 @@ public void WriteHeaderXml(StringBuilder sb, int indent)
public void WriteChildSoundsXml(StringBuilder sb, int indent, string nodeName = "ChildSounds")
{
if (ChildSoundsHashes == null) return;
- if (ChildSoundsHashes.Length > 0)
+
+ // Filter out empty hashes
+ var nonEmptyHashes = ChildSoundsHashes.Where(h => h != 0).ToArray();
+
+ if (nonEmptyHashes.Length > 0)
{
RelXml.OpenTag(sb, indent, nodeName);
var cind = indent + 1;
- foreach (var hash in ChildSoundsHashes)
+ foreach (var hash in nonEmptyHashes)
{
RelXml.StringTag(sb, cind, "Item", RelXml.HashString(hash));
}
@@ -2229,6 +2270,24 @@ public override MetaHash[] GetCategoryHashes()
+ public enum ParentOverrideFlags
+ {
+ VolumeOverridesParent,
+ PitchOverridesParent,
+ PanOverridesParent,
+ PreDelayOverridesParent,
+ StartOffsetOverridesParent,
+ AttackTimeOverridesParent,
+ ReleaseTimeOverridesParent,
+ DopplerFactorOverridesParent,
+ LPFCutoffOverridesParent,
+ HPFCutoffOverridesParent,
+ VolumeCurveOverridesParent,
+ VolumeCurveScaleOverridesParent,
+ VolumeCurvePlateauOverridesParent,
+ SpeakerMaskOverridesParent,
+ }
+
public enum Dat54SoundType : byte
{
LoopingSound = 1,
@@ -2542,6 +2601,16 @@ public override void ReadXml(XmlNode node)
MinCrossfadeTimeVariable = XmlRel.GetHash(Xml.GetChildInnerText(node, "MinCrossfadeTimeVariable"));
MaxCrossfadeTimeVariable = XmlRel.GetHash(Xml.GetChildInnerText(node, "MaxCrossfadeTimeVariable"));
ReadChildSoundsXml(node);
+
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[0];
+ ChildSoundsCount = 0;
+ }
+ else
+ {
+ ChildSoundsCount = (byte)ChildSoundsHashes.Length;
+ }
}
public override void WriteXml(StringBuilder sb, int indent)
{
@@ -2570,6 +2639,12 @@ public override void Write(BinaryWriter bw)
bw.Write(MinCrossfadeTimeVariable);
bw.Write(MaxCrossfadeTimeVariable);
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[0];
+ ChildSoundsCount = 0;
+ }
+
WriteChildSoundsHashes(bw);
}
public override uint[] GetHashTableOffsets()
@@ -2581,6 +2656,7 @@ public override MetaHash[] GetCurveHashes()
return new[] { CrossfadeCurve };
}
}
+
[TC(typeof(EXP))]
class Dat54SpeechSound : Dat54Sound
{
@@ -2781,6 +2857,16 @@ public override void ReadXml(XmlNode node)
{
base.ReadXml(node);
ReadChildSoundsXml(node);
+
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[0];
+ ChildSoundsCount = 0;
+ }
+ else
+ {
+ ChildSoundsCount = (byte)ChildSoundsHashes.Length;
+ }
}
public override void WriteXml(StringBuilder sb, int indent)
{
@@ -2790,6 +2876,13 @@ public override void WriteXml(StringBuilder sb, int indent)
public override void Write(BinaryWriter bw)
{
base.Write(bw);
+
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[0];
+ ChildSoundsCount = 0;
+ }
+
WriteChildSoundsHashes(bw);
}
public override uint[] GetHashTableOffsets()
@@ -2816,6 +2909,16 @@ public override void ReadXml(XmlNode node)
base.ReadXml(node);
Duration = Xml.GetChildIntAttribute(node, "Duration", "value");
ReadChildSoundsXml(node);
+
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[0];
+ ChildSoundsCount = 0;
+ }
+ else
+ {
+ ChildSoundsCount = (byte)ChildSoundsHashes.Length;
+ }
}
public override void WriteXml(StringBuilder sb, int indent)
{
@@ -2827,6 +2930,13 @@ public override void Write(BinaryWriter bw)
{
base.Write(bw);
bw.Write(Duration);
+
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[0];
+ ChildSoundsCount = 0;
+ }
+
WriteChildSoundsHashes(bw);
}
public override uint[] GetHashTableOffsets()
@@ -3146,6 +3256,16 @@ public override void ReadXml(XmlNode node)
{
base.ReadXml(node);
ReadChildSoundsXml(node);
+
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[0];
+ ChildSoundsCount = 0;
+ }
+ else
+ {
+ ChildSoundsCount = (byte)ChildSoundsHashes.Length;
+ }
}
public override void WriteXml(StringBuilder sb, int indent)
{
@@ -3155,6 +3275,13 @@ public override void WriteXml(StringBuilder sb, int indent)
public override void Write(BinaryWriter bw)
{
base.Write(bw);
+
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[0];
+ ChildSoundsCount = 0;
+ }
+
WriteChildSoundsHashes(bw);
}
public override uint[] GetHashTableOffsets()
@@ -3312,7 +3439,16 @@ public override void ReadXml(XmlNode node)
{
base.ReadXml(node);
Entities = XmlRel.ReadHashItemArray(node, "Entities");
- EntitiesCount = (byte)(Entities?.Length ?? 0);
+
+ if (Entities == null)
+ {
+ Entities = new MetaHash[0];
+ EntitiesCount = 0;
+ }
+ else
+ {
+ EntitiesCount = (byte)Entities.Length;
+ }
}
public override void WriteXml(StringBuilder sb, int indent)
{
@@ -3322,6 +3458,13 @@ public override void WriteXml(StringBuilder sb, int indent)
public override void Write(BinaryWriter bw)
{
base.Write(bw);
+
+ if (Entities == null)
+ {
+ Entities = new MetaHash[0];
+ EntitiesCount = 0;
+ }
+
bw.Write(EntitiesCount);
for (int i = 0; i < EntitiesCount; i++)
{
@@ -3355,6 +3498,16 @@ public override void ReadXml(XmlNode node)
SequenceDirection = XmlRel.GetHash(Xml.GetChildInnerText(node, "SequenceDirection"));
ReadChildSoundsXml(node);
+
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[0];
+ ChildSoundsCount = 0;
+ }
+ else
+ {
+ ChildSoundsCount = (byte)ChildSoundsHashes.Length;
+ }
}
public override void WriteXml(StringBuilder sb, int indent)
{
@@ -3371,6 +3524,13 @@ public override void Write(BinaryWriter bw)
bw.Write(DelayTime);
bw.Write(DelayTimeVariable);
bw.Write(SequenceDirection);
+
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[0];
+ ChildSoundsCount = 0;
+ }
+
WriteChildSoundsHashes(bw);
}
public override uint[] GetHashTableOffsets()
@@ -3399,16 +3559,25 @@ public Dat54ModularSynthSound(RelData d, BinaryReader br) : base(d, br)
PlaybackTimeLimit = br.ReadSingle(); //0x8-0xC
VirtualisationMode = br.ReadInt32(); //0xC-0x10
TrackCount = br.ReadInt32(); //0x10-0x14
- ChildSoundsHashes = new MetaHash[4];
- for (int i = 0; i < 4; i++)
+
+ long bytesRemaining = br.BaseStream.Length - br.BaseStream.Position;
+ if (bytesRemaining >= 16) // 4 hashes * 4 bytes each
{
- ChildSoundsHashes[i] = br.ReadUInt32();
+ ChildSoundsHashes = new MetaHash[4];
+ for (int i = 0; i < 4; i++)
+ {
+ ChildSoundsHashes[i] = br.ReadUInt32();
+ }
}
- ExposedVariablesCount = br.ReadInt32();
- ExposedVariables = new Dat54ModularSynthSoundVariable[ExposedVariablesCount];
- for (int i = 0; i < ExposedVariablesCount; i++)
+
+ if (br.BaseStream.Position < br.BaseStream.Length)
{
- ExposedVariables[i] = new Dat54ModularSynthSoundVariable(br);
+ ExposedVariablesCount = br.ReadInt32();
+ ExposedVariables = new Dat54ModularSynthSoundVariable[ExposedVariablesCount];
+ for (int i = 0; i < ExposedVariablesCount; i++)
+ {
+ ExposedVariables[i] = new Dat54ModularSynthSoundVariable(br);
+ }
}
}
public override void ReadXml(XmlNode node)
@@ -3420,6 +3589,18 @@ public override void ReadXml(XmlNode node)
VirtualisationMode = Xml.GetChildIntAttribute(node, "VirtualisationMode", "value");
TrackCount = Xml.GetChildIntAttribute(node, "TrackCount", "value");
ReadChildSoundsXml(node, "EnvironmentSounds");
+
+ if (ChildSoundsHashes != null && ChildSoundsHashes.Length < 4)
+ {
+ var paddedHashes = new MetaHash[4];
+ Array.Copy(ChildSoundsHashes, paddedHashes, ChildSoundsHashes.Length);
+ ChildSoundsHashes = paddedHashes;
+ }
+ else if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[4];
+ }
+
ExposedVariables = XmlRel.ReadItemArray(node, "ExposedVariables");
ExposedVariablesCount = (ExposedVariables?.Length ?? 0);
}
@@ -3442,6 +3623,12 @@ public override void Write(BinaryWriter bw)
bw.Write(PlaybackTimeLimit); //0x8-0xC
bw.Write(VirtualisationMode); //0xC-0x10
bw.Write(TrackCount); //0x10-0x14
+
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[4];
+ }
+
for (int i = 0; i < 4; i++)
{
bw.Write(ChildSoundsHashes[i]);
@@ -3904,6 +4091,16 @@ public override void ReadXml(XmlNode node)
base.ReadXml(node);
Variable = XmlRel.GetHash(Xml.GetChildInnerText(node, "Variable"));
ReadChildSoundsXml(node);
+
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[0];
+ ChildSoundsCount = 0;
+ }
+ else
+ {
+ ChildSoundsCount = (byte)ChildSoundsHashes.Length;
+ }
}
public override void WriteXml(StringBuilder sb, int indent)
{
@@ -3915,6 +4112,13 @@ public override void Write(BinaryWriter bw)
{
base.Write(bw);
bw.Write(Variable);
+
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[0];
+ ChildSoundsCount = 0;
+ }
+
WriteChildSoundsHashes(bw);
}
public override uint[] GetHashTableOffsets()
@@ -4504,8 +4708,8 @@ public override uint[] GetHashTableOffsets()
public float BandTwoMaximum { get; set; } //0x1A-0x1E
public float IntraBandFlipProbabilty { get; set; } //0x1E-0x22
public float InterBandFlipProbabilty { get; set; } //0x22-0x26
- public float MinSwitchTime { get; set; } //0x26-0x2A
- public float MaxSwitchTime { get; set; } //0x2A-0x2E
+ public uint MinSwitchTime { get; set; } //0x26-0x2A
+ public uint MaxSwitchTime { get; set; } //0x2A-0x2E
public float InitialValue { get; set; } //0x2E-0x32
public Dat54FluctuatorSoundData()
@@ -4523,8 +4727,8 @@ public Dat54FluctuatorSoundData(BinaryReader br)
BandTwoMaximum = br.ReadSingle();
IntraBandFlipProbabilty = br.ReadSingle();
InterBandFlipProbabilty = br.ReadSingle();
- MinSwitchTime = br.ReadSingle();
- MaxSwitchTime = br.ReadSingle();
+ MinSwitchTime = br.ReadUInt32();
+ MaxSwitchTime = br.ReadUInt32();
InitialValue = br.ReadSingle();
}
public void ReadXml(XmlNode node)
@@ -4540,8 +4744,8 @@ public void ReadXml(XmlNode node)
BandTwoMaximum = Xml.GetChildFloatAttribute(node, "BandTwoMaximum", "value");
IntraBandFlipProbabilty = Xml.GetChildFloatAttribute(node, "IntraBandFlipProbabilty", "value");
InterBandFlipProbabilty = Xml.GetChildFloatAttribute(node, "InterBandFlipProbabilty", "value");
- MinSwitchTime = Xml.GetChildFloatAttribute(node, "MinSwitchTime", "value");
- MaxSwitchTime = Xml.GetChildFloatAttribute(node, "MaxSwitchTime", "value");
+ MinSwitchTime = Xml.GetChildUIntAttribute(node, "MinSwitchTime", "value");
+ MaxSwitchTime = Xml.GetChildUIntAttribute(node, "MaxSwitchTime", "value");
InitialValue = Xml.GetChildFloatAttribute(node, "InitialValue", "value");
}
public void WriteXml(StringBuilder sb, int indent)
@@ -4557,8 +4761,8 @@ public void WriteXml(StringBuilder sb, int indent)
RelXml.ValueTag(sb, indent, "BandTwoMaximum", FloatUtil.ToString(BandTwoMaximum));
RelXml.ValueTag(sb, indent, "IntraBandFlipProbabilty", FloatUtil.ToString(IntraBandFlipProbabilty));
RelXml.ValueTag(sb, indent, "InterBandFlipProbabilty", FloatUtil.ToString(InterBandFlipProbabilty));
- RelXml.ValueTag(sb, indent, "MinSwitchTime", FloatUtil.ToString(MinSwitchTime));
- RelXml.ValueTag(sb, indent, "MaxSwitchTime", FloatUtil.ToString(MaxSwitchTime));
+ RelXml.ValueTag(sb, indent, "MinSwitchTime", MinSwitchTime.ToString());
+ RelXml.ValueTag(sb, indent, "MaxSwitchTime", MaxSwitchTime.ToString());
RelXml.ValueTag(sb, indent, "InitialValue", FloatUtil.ToString(InitialValue));
}
public void Write(BinaryWriter bw)
@@ -4728,6 +4932,16 @@ public override void ReadXml(XmlNode node)
{
base.ReadXml(node);
ReadChildSoundsXml(node, "EnvironmentSounds");
+
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[0];
+ ChildSoundsCount = 0;
+ }
+ else
+ {
+ ChildSoundsCount = (byte)ChildSoundsHashes.Length;
+ }
}
public override void WriteXml(StringBuilder sb, int indent)
{
@@ -4737,6 +4951,13 @@ public override void WriteXml(StringBuilder sb, int indent)
public override void Write(BinaryWriter bw)
{
base.Write(bw);
+
+ if (ChildSoundsHashes == null)
+ {
+ ChildSoundsHashes = new MetaHash[0];
+ ChildSoundsCount = 0;
+ }
+
WriteChildSoundsHashes(bw);
bw.Write(EnvironmentSound1);
@@ -4968,7 +5189,16 @@ public override void ReadXml(XmlNode node)
{
base.ReadXml(node);
SoundSets = XmlRel.ReadHashItemArray(node, "SoundSets");
- SoundSetsCount = (uint)(SoundSets?.Length ?? 0);
+
+ if (SoundSets == null)
+ {
+ SoundSets = new MetaHash[0];
+ SoundSetsCount = 0;
+ }
+ else
+ {
+ SoundSetsCount = (uint)SoundSets.Length;
+ }
}
public override void WriteXml(StringBuilder sb, int indent)
{
@@ -4978,6 +5208,13 @@ public override void WriteXml(StringBuilder sb, int indent)
public override void Write(BinaryWriter bw)
{
base.Write(bw);
+
+ if (SoundSets == null)
+ {
+ SoundSets = new MetaHash[0];
+ SoundSetsCount = 0;
+ }
+
bw.Write(SoundSetsCount);
for (int i = 0; i < SoundSetsCount; i++)
{
@@ -5025,7 +5262,16 @@ public override void ReadXml(XmlNode node)
base.ReadXml(node);
UnkShort = (ushort)Xml.GetChildUIntAttribute(node, "UnkShort", "value");
SoundHashes = XmlRel.ReadHashItemArray(node, "SoundHashes");
- SoundHashesCount = (uint)(SoundHashes?.Length ?? 0);
+
+ if (SoundHashes == null)
+ {
+ SoundHashes = new MetaHash[0];
+ SoundHashesCount = 0;
+ }
+ else
+ {
+ SoundHashesCount = (uint)SoundHashes.Length;
+ }
}
public override void WriteXml(StringBuilder sb, int indent)
{
@@ -5036,6 +5282,13 @@ public override void WriteXml(StringBuilder sb, int indent)
public override void Write(BinaryWriter bw)
{
base.Write(bw);
+
+ if (SoundHashes == null)
+ {
+ SoundHashes = new MetaHash[0];
+ SoundHashesCount = 0;
+ }
+
bw.Write(UnkShort);
bw.Write(SoundHashesCount);
for (int i = 0; i < SoundHashesCount; i++)
@@ -5208,6 +5461,367 @@ public override string ToString()
{
return GetBaseString() + ": " + Type.ToString();
}
+
+ public static void SetTristateValue(ref uint flags, int flagid, TristateValue value)
+ {
+ flags &= (uint)~(0x3 << (flagid << 1));
+ flags |= (uint)((int)value << (flagid << 1));
+ }
+
+ public static TristateValue GetTristateValue(uint flags, int flagid)
+ {
+ return (TristateValue)((flags >> (flagid << 1)) & 0x3);
+ }
+ }
+ public enum TristateValue
+ {
+ False,
+ True,
+ Unspecified,
+ }
+
+ public enum CarAudioSettingsFlags
+ {
+ SportsCarRevsEnabled,
+ ReverseWarning,
+ BigRigBrakes,
+ DoorOpenWarning,
+ DisableAmbientRadio,
+ HeavyRoadNoise,
+ IamNotACar,
+ TyreChirpsEnabled,
+ IsToyCar,
+ HasCBRadio,
+ DisableSkids,
+ CauseControllerRumble,
+ MobileCausesRadioInterference,
+ IsKickStarted,
+ HasAlarm
+ }
+
+ public enum CollisionMaterialSettingsFlags
+ {
+ IsSoftForLightProps,
+ DryMaterial,
+ ShouldPlayRicochet,
+ IsResonant,
+ TreatAsFixed,
+ LooseSurface,
+ ScrapesForPeds,
+ PedsAreSolid,
+ UseCustomCurves,
+ ShellCasingsIgnoreHardness,
+ SurfaceSettleIsLoop,
+ GeneratePostShootoutDebris,
+ TriggerClatterOnTouch
+ }
+
+ public enum StaticEmitterFlags
+ {
+ Enabled,
+ GenerateBeats,
+ LinkedToProp,
+ ConedFront,
+ FillsInteriorSpace,
+ PlayFullRadio,
+ MuteForScore,
+ DisabledByScript,
+ StartStopImmediatelyAtTimeLimits,
+ MuteForFrontendRadio,
+ ForceMaxPathDepth,
+ IgnoreSnipe
+ }
+
+ public enum EntityEmitterFlags
+ {
+ OnlyWhenRaining,
+ MoreLikelyWhenHot,
+ VolumeCone,
+ WindBasedVolume,
+ GeneratesTreeRain,
+ StopWhenRaining,
+ ComputeOcclusion
+ }
+
+ public enum HeliAudioSettingsFlags
+ {
+ DisableAmbientRadio,
+ HasMissileLockSystem,
+ AircraftWarningVoiceIsMale
+ }
+
+ public enum SpeechContextFlags
+ {
+ AllowRepeat,
+ ForcePlay,
+ IsConversation,
+ IsPain,
+ IsCombat,
+ IsOkayOnMission,
+ IsUrgent,
+ IsMuttedDuringSlowMo,
+ IsPitchedDuringSlowMo
+ }
+
+ public enum SpeechContextVirtualFlags
+ {
+ AllowRepeat,
+ ForcePlay,
+ IsConversation,
+ IsPain,
+ IsCombat,
+ IsOkayOnMission,
+ IsUrgent,
+ IsMuttedDuringSlowMo,
+ IsPitchedDuringSlowMo
+ }
+
+ public enum SpeechParamsFlags
+ {
+ AllowRepeat,
+ ForcePlay,
+ SayOverPain,
+ PreloadOnly,
+ IsConversationInterrupt,
+ AddBlip,
+ IsUrgent,
+ InterruptAmbientSpeech,
+ IsMutedDuringSlowMo,
+ IsPitchedDuringSlowMo
+ }
+
+ public enum BoatAudioSettingsFlags
+ {
+ DisableAmbientRadio,
+ IsSubmarine
+ }
+
+ public enum WeaponSettingsFlags
+ {
+ IsPlayerAutoFire,
+ IsNPCAutoFire,
+ IsNonLethal,
+ RecockWhenSniping,
+ DoesMeleeImpacts
+ }
+
+ public enum RadioStationSettingsFlags
+ {
+ NoBack2BackMusic,
+ Back2BackAds,
+ PlayWeather,
+ PlayNews,
+ SequentialMusic,
+ IdentsInsteadOfAds,
+ Locked,
+ Hidden,
+ PlayUsersMusic,
+ HasReverbChannel,
+ IsMixStation
+ }
+
+ public enum RadioStationTrackListFlags
+ {
+ Locked,
+ Shuffle
+ }
+
+ public enum ScriptedScannerLineFlags
+ {
+ DisableScannerSFX,
+ EnableEcho
+ }
+
+ public enum AmbientZoneFlags
+ {
+ InteriorZone,
+ ZoneEnabledStatePersistent,
+ ZoneEnabledStateNonPersistent,
+ UsePlayerPosition,
+ DisableInMultiplayer,
+ ScaleMaxWorldHeightWithZoneInfluence,
+ HasTunnelReflections,
+ HasReverbLinkedReflections,
+ HasRandomStaticRadioEmitters,
+ HasRandomVehicleRadioEmitters,
+ OccludeRain
+ }
+
+ public enum AmbientRuleFlags
+ {
+ IgnoreInitialMinRepeatTime,
+ StopWhenRaining,
+ StopOnLoudSound,
+ FollowListener,
+ UseOcclusion,
+ StreamingSound,
+ StopOnZoneDeactivation,
+ TriggerOnLoudSound,
+ CanTriggerOverWater,
+ CheckConditionsEachFrame,
+ UsePlayerPosition,
+ DisableInMultiplayer
+ }
+
+ public enum EnvironmentRuleFlags
+ {
+ OverrideReverb,
+ OverrideEchos,
+ RandomEchoPositions,
+ HeightRestrictions
+ }
+
+ public enum InteriorSettingsFlags
+ {
+ HasInteriorWalla,
+ InhibitIdleMusic,
+ BuildAllExtendedPaths,
+ BuildInterInteriorPaths,
+ AllowQuietScene,
+ UseBoundingBoxOcclusion
+ }
+
+ public enum InteriorRoomFlags
+ {
+ HasInteriorWalla
+ }
+
+ public enum DoorTuningParamsFlags
+ {
+ IsRailLevelCrossing
+ }
+
+ public enum ModelAudioCollisionSettingsFlags
+ {
+ IsResonant,
+ TurnOffRainVolOnProps,
+ SwingingProp,
+ RainLoopTracksListener,
+ PlaceRainLoopOntopOfBounds,
+ ResonanceLoopTracksListener
+ }
+
+ public enum PlaneAudioSettingsFlags
+ {
+ EnginesAttachedToWings,
+ HasMissileLockSystem,
+ IsJet,
+ DisableAmbientRadio,
+ AircraftWarningVoiceIsMale
+ }
+
+ public enum StartTrackActionFlags
+ {
+ OverrideRadio,
+ RandomStartOffset,
+ MuteRadioOffSound
+ }
+
+ public enum StopTrackActionFlags
+ {
+ UnfreezeRadio
+ }
+
+ public enum StartOneShotActionFlags
+ {
+ UnfreezeRadio,
+ OverrideRadio
+ }
+
+ public enum DirectionalAmbienceFlags
+ {
+ MonoPannedSource,
+ StopWhenRaining
+ }
+
+ public enum ScannerVehicleParamsFlags
+ {
+ BlockColorReporting
+ }
+
+ public enum MicrophoneSettingsFlags
+ {
+ PlayerFrontend,
+ DistantPlayerWeapons,
+ DisableBulletsBy
+ }
+
+ public enum ClothAudioSettingsFlags
+ {
+ HavePockets,
+ FlapsInWind
+ }
+
+ public enum ExplosionAudioSettingsFlags
+ {
+ DisabledDebris,
+ DisableShockwave,
+ IsCarExplosion
+ }
+
+ public enum GranularEngineAudioSettingsFlags
+ {
+ GearChangeWobblesEnabled,
+ Publish,
+ HasRevLimiter,
+ VisualFxOnLimiter,
+ ExhaustProximityMixerSceneEnabled
+ }
+
+ public enum ShoreLinePoolAudioSettingsFlags
+ {
+ IsInterior,
+ TreatAsLake
+ }
+
+ public enum ShoreLineLakeAudioSettingsFlags
+ {
+ IsInterior
+ }
+
+ public enum ShoreLineRiverAudioSettingsFlags
+ {
+ IsInterior
+ }
+
+ public enum ShoreLineOceanAudioSettingsFlags
+ {
+ IsInterior,
+ WaveDetection
+ }
+
+ public enum ReflectionsSettingsFlags
+ {
+ FilterEnabled,
+ StaticReflections,
+ InvertPhaseChannel0,
+ InvertPhaseChannel1,
+ InvertPhaseChannel2,
+ InvertPhaseChannel3,
+ InvertPhaseChannel4,
+ InvertPhaseChannel5
+ }
+
+ public enum ForceRadioTrackActionFlags
+ {
+ UnfreezeStation
+ }
+
+ public enum PedScenarioAudioSettingsFlags
+ {
+ IsStreaming,
+ AllowSharedOwnership
+ }
+
+ public enum RandomisedRadioEmitterSettingsFlags
+ {
+ USeOcclusionOnStaticEmitters,
+ UseOcclusionOnVehicleEmitters
+ }
+
+ public enum ReplayRadioStationTrackListFlags
+ {
+ Locked
}
[TC(typeof(EXP))]
@@ -5306,6 +5920,12 @@ public override void Write(BinaryWriter bw)
{
WriteTypeAndOffset(bw);
+ if (EmitterHashes == null)
+ {
+ EmitterHashes = new MetaHash[0];
+ EmitterCount = 0;
+ }
+
bw.Write(EmitterCount);
for (int i = 0; i < EmitterCount; i++)
{
@@ -5320,7 +5940,16 @@ public override void WriteXml(StringBuilder sb, int indent)
public override void ReadXml(XmlNode node)
{
EmitterHashes = XmlRel.ReadHashItemArray(node, "Emitters");
- EmitterCount = (uint)(EmitterHashes?.Length ?? 0);
+
+ if (EmitterHashes == null)
+ {
+ EmitterHashes = new MetaHash[0];
+ EmitterCount = 0;
+ }
+ else
+ {
+ EmitterCount = (uint)EmitterHashes.Length;
+ }
}
public override MetaHash[] GetGameHashes()
{
@@ -5555,7 +6184,14 @@ public override void Write(BinaryWriter bw)
bw.Write(PedWallaSettings);
bw.Write(RandomisedRadioSettings);
bw.Write(NumRulesToPlay);
- bw.Write(ZoneWaterCalculation);
+ bw.Write(ZoneWaterCalculation);
+
+ if (Rules == null)
+ {
+ Rules = new MetaHash[0];
+ NumRules = 0;
+ }
+
bw.Write(NumRules);
bw.Write(Unused11);
@@ -5578,6 +6214,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (AmbientZoneFlags flag in Enum.GetValues(typeof(AmbientZoneFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.StringTag(sb, indent, "Shape", Shape.ToString());
RelXml.SelfClosingTag(sb, indent, "ActivationZoneCentre " + FloatUtil.GetVector3XmlString(ActivationZoneCentre));
RelXml.SelfClosingTag(sb, indent, "ActivationZoneSize " + FloatUtil.GetVector3XmlString(ActivationZoneSize));
@@ -5609,7 +6255,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("AmbientZoneFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out AmbientZoneFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Shape = Xml.GetEnumValue(Xml.GetChildInnerText(node, "Shape"));
ActivationZoneCentre = Xml.GetChildVector3Attributes(node, "ActivationZoneCentre");
ActivationZoneSize = Xml.GetChildVector3Attributes(node, "ActivationZoneSize");
@@ -5637,7 +6300,17 @@ public override void ReadXml(XmlNode node)
NumRulesToPlay = (byte)Xml.GetChildUIntAttribute(node, "NumRulesToPlay", "value");
ZoneWaterCalculation = (byte)Xml.GetChildUIntAttribute(node, "ZoneWaterCalculation", "value");
Rules = XmlRel.ReadHashItemArray(node, "Rules");
- NumRules = (byte)(Rules?.Length ?? 0);
+
+ if (Rules == null)
+ {
+ Rules = new MetaHash[0];
+ NumRules = 0;
+ }
+ else
+ {
+ NumRules = (byte)Rules.Length;
+ }
+
DirAmbiences = XmlRel.ReadItemArray(node, "DirAmbiences");
NumDirAmbiences = (byte)(DirAmbiences?.Length ?? 0);
}
@@ -5829,6 +6502,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (AmbientRuleFlags flag in Enum.GetValues(typeof(AmbientRuleFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.SelfClosingTag(sb, indent, "Position " + FloatUtil.GetVector3XmlString(Position));
RelXml.StringTag(sb, indent, "ChildSound", RelXml.HashString(ChildSound));
RelXml.StringTag(sb, indent, "Category", RelXml.HashString(Category));
@@ -5852,7 +6535,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("AmbientRuleFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out AmbientRuleFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Position = Xml.GetChildVector3Attributes(node, "Position");
ChildSound = XmlRel.GetHash(Xml.GetChildInnerText(node, "ChildSound"));
Category = XmlRel.GetHash(Xml.GetChildInnerText(node, "Category"));
@@ -5909,6 +6609,12 @@ public override void Write(BinaryWriter bw)
{
WriteTypeAndOffset(bw);
+ if (ZoneHashes == null)
+ {
+ ZoneHashes = new MetaHash[0];
+ ZoneCount = 0;
+ }
+
bw.Write(ZoneCount);
for (int i = 0; i < ZoneCount; i++)
{
@@ -5923,7 +6629,16 @@ public override void WriteXml(StringBuilder sb, int indent)
public override void ReadXml(XmlNode node)
{
ZoneHashes = XmlRel.ReadHashItemArray(node, "Zones");
- ZoneCount = (uint)(ZoneHashes?.Length ?? 0);
+
+ if (ZoneHashes == null)
+ {
+ ZoneHashes = new MetaHash[0];
+ ZoneCount = 0;
+ }
+ else
+ {
+ ZoneCount = (uint)ZoneHashes.Length;
+ }
}
public override MetaHash[] GetGameHashes()
{
@@ -6033,6 +6748,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (StaticEmitterFlags flag in Enum.GetValues(typeof(StaticEmitterFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.StringTag(sb, indent, "ChildSound", RelXml.HashString(ChildSound));
RelXml.StringTag(sb, indent, "RadioStation", RelXml.HashString(RadioStation));
RelXml.SelfClosingTag(sb, indent, "Position " + FloatUtil.GetVector3XmlString(Position));
@@ -6061,7 +6786,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("StaticEmitterFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out StaticEmitterFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
ChildSound = XmlRel.GetHash(Xml.GetChildInnerText(node, "ChildSound"));
RadioStation = XmlRel.GetHash(Xml.GetChildInnerText(node, "RadioStation"));
Position = Xml.GetChildVector3Attributes(node, "Position");
@@ -6129,6 +6871,12 @@ public override void Write(BinaryWriter bw)
{
WriteTypeAndOffset(bw);
+ if (Rooms == null)
+ {
+ Rooms = new MetaHash[0];
+ RoomsCount = 0;
+ }
+
bw.Write(Flags);
bw.Write(InteriorWallaSoundSet);
bw.Write(InteriorReflections);
@@ -6141,17 +6889,53 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (InteriorSettingsFlags flag in Enum.GetValues(typeof(InteriorSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.StringTag(sb, indent, "InteriorWallaSoundSet", RelXml.HashString(InteriorWallaSoundSet));
RelXml.StringTag(sb, indent, "InteriorReflections", RelXml.HashString(InteriorReflections));
RelXml.WriteHashItemArray(sb, Rooms, indent, "Rooms");
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("InteriorSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out InteriorSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
InteriorWallaSoundSet = XmlRel.GetHash(Xml.GetChildInnerText(node, "InteriorWallaSoundSet"));
InteriorReflections = XmlRel.GetHash(Xml.GetChildInnerText(node, "InteriorReflections"));
Rooms = XmlRel.ReadHashItemArray(node, "Rooms");
- RoomsCount = (uint)(Rooms?.Length ?? 0);
+
+ if (Rooms == null)
+ {
+ Rooms = new MetaHash[0];
+ RoomsCount = 0;
+ }
+ else
+ {
+ RoomsCount = (uint)Rooms.Length;
+ }
}
public override uint[] GetHashTableOffsets()
{
@@ -6259,6 +7043,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (InteriorRoomFlags flag in Enum.GetValues(typeof(InteriorRoomFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.StringTag(sb, indent, "RoomName", RelXml.HashString(RoomName));
RelXml.StringTag(sb, indent, "AmbientZone", RelXml.HashString(AmbientZone));
RelXml.ValueTag(sb, indent, "InteriorType", InteriorType.ToString());
@@ -6277,7 +7071,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("InteriorRoomFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out InteriorRoomFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
RoomName = XmlRel.GetHash(Xml.GetChildInnerText(node, "RoomName"));
AmbientZone = XmlRel.GetHash(Xml.GetChildInnerText(node, "AmbientZone"));
InteriorType = (byte)Xml.GetChildUIntAttribute(node, "InteriorType", "value");
@@ -6333,6 +7144,12 @@ public override void Write(BinaryWriter bw)
{
WriteTypeAndOffset(bw);
+ if (Stations == null)
+ {
+ Stations = new MetaHash[0];
+ StationsCount = 0;
+ }
+
bw.Write(StationsCount);
for (int i = 0; i < StationsCount; i++)
{
@@ -6346,7 +7163,16 @@ public override void WriteXml(StringBuilder sb, int indent)
public override void ReadXml(XmlNode node)
{
Stations = XmlRel.ReadHashItemArray(node, "Stations");
- StationsCount = (uint)(Stations?.Length ?? 0);
+
+ if (Stations == null)
+ {
+ Stations = new MetaHash[0];
+ StationsCount = 0;
+ }
+ else
+ {
+ StationsCount = (uint)Stations.Length;
+ }
}
public override uint[] GetHashTableOffsets()
{
@@ -6373,7 +7199,6 @@ public class Dat151RadioStationSettings : Dat151RelData
public byte AmbientRadioVol { get; set; }
public string RadioName { get; set; }
public ushort padding00 { get; set; }
-
public uint NumTrackList { get; set; }
public MetaHash[] TrackList { get; set; }
@@ -6423,6 +7248,12 @@ public override void Write(BinaryWriter bw)
bw.Write(padding00);
+ if (TrackList == null)
+ {
+ TrackList = new MetaHash[0];
+ NumTrackList = 0;
+ }
+
bw.Write(NumTrackList);
for (int i = 0; i < NumTrackList; i++)
{
@@ -6432,6 +7263,17 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (RadioStationSettingsFlags flag in Enum.GetValues(typeof(RadioStationSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
+ RelXml.ValueTag(sb, indent, "NextStationSettingsPtr", NextStationSettingsPtr.ToString());
RelXml.ValueTag(sb, indent, "WheelPosition", WheelPosition.ToString());
RelXml.ValueTag(sb, indent, "Genre", Genre.ToString());
RelXml.ValueTag(sb, indent, "AmbientRadioVol", AmbientRadioVol.ToString());
@@ -6440,13 +7282,40 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("RadioStationSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out RadioStationSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
+ NextStationSettingsPtr = Xml.GetChildUIntAttribute(node, "NextStationSettingsPtr", "value");
WheelPosition = Xml.GetChildUIntAttribute(node, "WheelPosition", "value");
Genre = (byte)Xml.GetChildUIntAttribute(node, "Genre", "value");
AmbientRadioVol = (byte)Xml.GetChildUIntAttribute(node, "AmbientRadioVol", "value");
RadioName = Xml.GetChildInnerText(node, "RadioName");
TrackList = XmlRel.ReadHashItemArray(node, "TrackList");
- NumTrackList = (uint)(TrackList?.Length ?? 0);
+
+ if (TrackList == null)
+ {
+ TrackList = new MetaHash[0];
+ NumTrackList = 0;
+ }
+ else
+ {
+ NumTrackList = (uint)TrackList.Length;
+ }
}
public override uint[] GetHashTableOffsets()
{
@@ -6554,13 +7423,40 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (RadioStationTrackListFlags flag in Enum.GetValues(typeof(RadioStationTrackListFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "Category", Category.ToString());
RelXml.ValueTag(sb, indent, "NumHistorySpaceElems", NumHistorySpaceElems.ToString());
RelXml.WriteItemArray(sb, Tracks, indent, "Tracks");
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("RadioStationTrackListFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out RadioStationTrackListFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Category = (byte)Xml.GetChildUIntAttribute(node, "Category", "value");
NumHistorySpaceElems = (byte)Xml.GetChildUIntAttribute(node, "NumHistorySpaceElems", "value");
Tracks = XmlRel.ReadItemArray(node, "Tracks");
@@ -6617,11 +7513,38 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (ReplayRadioStationTrackListFlags flag in Enum.GetValues(typeof(ReplayRadioStationTrackListFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.WriteItemArray(sb, Tracks, indent, "Tracks");
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("ReplayRadioStationTrackListFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out ReplayRadioStationTrackListFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Tracks = XmlRel.ReadItemArray(node, "Tracks");
TrackCount = (uint)(Tracks?.Length ?? 0);
}
@@ -6839,6 +7762,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (StartTrackActionFlags flag in Enum.GetValues(typeof(StartTrackActionFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "Constrain", Constrain.ToString());
RelXml.ValueTag(sb, indent, "numTimingConstraints", numTimingConstraints.ToString());
RelXml.StringTag(sb, indent, "TimingConstraint1", RelXml.HashString(TimingConstraint1));
@@ -6855,7 +7788,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("StartTrackActionFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out StartTrackActionFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Constrain = (byte)Xml.GetChildIntAttribute(node, "Constrain", "value");
numTimingConstraints = Xml.GetChildIntAttribute(node, "numTimingConstraints", "value");
TimingConstraint1 = XmlRel.GetHash(Xml.GetChildInnerText(node, "TimingConstraint1"));
@@ -6979,6 +7929,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (StopTrackActionFlags flag in Enum.GetValues(typeof(StopTrackActionFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "Constrain", Constrain.ToString());
RelXml.ValueTag(sb, indent, "numTimingConstraints", numTimingConstraints.ToString());
RelXml.StringTag(sb, indent, "TimingConstraint1", RelXml.HashString(TimingConstraint1));
@@ -6988,7 +7948,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("StopTrackActionFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out StopTrackActionFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Constrain = (byte)Xml.GetChildIntAttribute(node, "Constrain", "value");
numTimingConstraints = Xml.GetChildIntAttribute(node, "numTimingConstraints", "value");
TimingConstraint1 = XmlRel.GetHash(Xml.GetChildInnerText(node, "TimingConstraint1"));
@@ -7280,6 +8257,12 @@ public override void Write(BinaryWriter bw)
{
WriteTypeAndOffset(bw);
+ if (Actions == null)
+ {
+ Actions = new MetaHash[0];
+ ActionsCount = 0;
+ }
+
bw.Write(ActionsCount);
for (int i = 0; i < ActionsCount; i++)
{
@@ -7294,7 +8277,16 @@ public override void WriteXml(StringBuilder sb, int indent)
public override void ReadXml(XmlNode node)
{
Actions = XmlRel.ReadHashItemArray(node, "Actions");
- ActionsCount = (uint)(Actions?.Length ?? 0);
+
+ if (Actions == null)
+ {
+ Actions = new MetaHash[0];
+ ActionsCount = 0;
+ }
+ else
+ {
+ ActionsCount = (uint)Actions.Length;
+ }
}
public override uint[] GetHashTableOffsets()
{
@@ -7378,6 +8370,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (StartOneShotActionFlags flag in Enum.GetValues(typeof(StartOneShotActionFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "Constrain", Constrain.ToString());
RelXml.ValueTag(sb, indent, "numTimingConstraints", numTimingConstraints.ToString());
RelXml.StringTag(sb, indent, "TimingConstraint1", RelXml.HashString(TimingConstraint1));
@@ -7391,7 +8393,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("StartOneShotActionFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out StartOneShotActionFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Constrain = (byte)Xml.GetChildIntAttribute(node, "Constrain", "value");
numTimingConstraints = Xml.GetChildIntAttribute(node, "numTimingConstraints", "value");
TimingConstraint1 = XmlRel.GetHash(Xml.GetChildInnerText(node, "TimingConstraint1"));
@@ -7753,6 +8772,12 @@ public override void Write(BinaryWriter bw)
Materials[i].Write(bw);
}
+ if (FragComponentSettings == null)
+ {
+ FragComponentSettings = new MetaHash[0];
+ FragComponentSettingsCount = 0;
+ }
+
bw.Write(FragComponentSettingsCount);
for (int i = 0; i < FragComponentSettingsCount; i++)
{
@@ -7764,6 +8789,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (ModelAudioCollisionSettingsFlags flag in Enum.GetValues(typeof(ModelAudioCollisionSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "LastFragTime", LastFragTime.ToString());
RelXml.ValueTag(sb, indent, "MediumIntensity", MediumIntensity.ToString());
RelXml.ValueTag(sb, indent, "HighIntensity", HighIntensity.ToString());
@@ -7791,7 +8826,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("ModelAudioCollisionSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out ModelAudioCollisionSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
LastFragTime = Xml.GetChildUIntAttribute(node, "LastFragTime", "value");
MediumIntensity = Xml.GetChildUIntAttribute(node, "MediumIntensity", "value");
HighIntensity = Xml.GetChildUIntAttribute(node, "HighIntensity", "value");
@@ -7811,7 +8863,16 @@ public override void ReadXml(XmlNode node)
Materials = XmlRel.ReadItemArray(node, "Materials");
MaterialsCount = (byte)(Materials?.Length ?? 0);
FragComponentSettings = XmlRel.ReadHashItemArray(node, "FragComponentSettings");
- FragComponentSettingsCount = (uint)(FragComponentSettings?.Length ?? 0);
+
+ if (FragComponentSettings == null)
+ {
+ FragComponentSettings = new MetaHash[0];
+ FragComponentSettingsCount = 0;
+ }
+ else
+ {
+ FragComponentSettingsCount = (uint)FragComponentSettings.Length;
+ }
}
public override uint[] GetHashTableOffsets()
{
@@ -8265,6 +9326,17 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (CollisionMaterialSettingsFlags flag in Enum.GetValues(typeof(CollisionMaterialSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
+
RelXml.StringTag(sb, indent, "HardImpact", RelXml.HashString(HardImpact));
RelXml.StringTag(sb, indent, "SolidImpact", RelXml.HashString(SolidImpact));
RelXml.StringTag(sb, indent, "SoftImpact", RelXml.HashString(SoftImpact));
@@ -8364,7 +9436,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("CollisionMaterialSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out CollisionMaterialSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
HardImpact = XmlRel.GetHash(Xml.GetChildInnerText(node, "HardImpact"));
SolidImpact = XmlRel.GetHash(Xml.GetChildInnerText(node, "SolidImpact"));
SoftImpact = XmlRel.GetHash(Xml.GetChildInnerText(node, "SoftImpact"));
@@ -9041,6 +10130,13 @@ public override void Write(BinaryWriter bw)
bw.Write(DelayTime);
bw.Write(Station);
bw.Write(NextIndex);
+
+ if (TrackList == null)
+ {
+ TrackList = new MetaHash[0];
+ NumTrackLists = 0;
+ }
+
bw.Write(NumTrackLists);
bw.Write(padding02);
bw.Write(padding03);
@@ -9052,6 +10148,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (ForceRadioTrackActionFlags flag in Enum.GetValues(typeof(ForceRadioTrackActionFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "Constrain", Constrain.ToString());
RelXml.ValueTag(sb, indent, "numTimingConstraints", numTimingConstraints.ToString());
RelXml.StringTag(sb, indent, "TimingConstraint1", RelXml.HashString(TimingConstraint1));
@@ -9063,7 +10169,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("ForceRadioTrackActionFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out ForceRadioTrackActionFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Constrain = (byte)Xml.GetChildIntAttribute(node, "Constrain", "value");
numTimingConstraints = Xml.GetChildIntAttribute(node, "numTimingConstraints", "value");
TimingConstraint1 = XmlRel.GetHash(Xml.GetChildInnerText(node, "TimingConstraint1"));
@@ -9072,7 +10195,16 @@ public override void ReadXml(XmlNode node)
Station = XmlRel.GetHash(Xml.GetChildInnerText(node, "Station"));
NextIndex = Xml.GetChildIntAttribute(node, "NextIndex", "value");
TrackList = XmlRel.ReadHashItemArray(node, "TrackList");
- NumTrackLists = (byte)(TrackList?.Length ?? 0);
+
+ if (TrackList == null)
+ {
+ TrackList = new MetaHash[0];
+ NumTrackLists = 0;
+ }
+ else
+ {
+ NumTrackLists = (byte)TrackList.Length;
+ }
}
public override uint[] GetHashTableOffsets()
{
@@ -9836,6 +10968,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (ShoreLinePoolAudioSettingsFlags flag in Enum.GetValues(typeof(ShoreLinePoolAudioSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.SelfClosingTag(sb, indent, "ActivationBox " + FloatUtil.GetVector4XmlString(ActivationBox));
RelXml.ValueTag(sb, indent, "RotationAngle", FloatUtil.ToString(RotationAngle));
RelXml.ValueTag(sb, indent, "WaterLappingMinDelay", WaterLappingMinDelay.ToString());
@@ -9851,7 +10993,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("ShoreLinePoolAudioSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out ShoreLinePoolAudioSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
ActivationBox = Xml.GetChildVector4Attributes(node, "ActivationBox");
RotationAngle = Xml.GetChildFloatAttribute(node, "RotationAngle", "value");
WaterLappingMinDelay = Xml.GetChildIntAttribute(node, "WaterLappingMinDelay", "value");
@@ -9926,6 +11085,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (ShoreLineLakeAudioSettingsFlags flag in Enum.GetValues(typeof(ShoreLineLakeAudioSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.SelfClosingTag(sb, indent, "ActivationBox " + FloatUtil.GetVector4XmlString(ActivationBox));
RelXml.ValueTag(sb, indent, "RotationAngle", FloatUtil.ToString(RotationAngle));
RelXml.StringTag(sb, indent, "NextShoreline", RelXml.HashString(NextShoreline));
@@ -9934,7 +11103,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("ShoreLineLakeAudioSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out ShoreLineLakeAudioSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
ActivationBox = Xml.GetChildVector4Attributes(node, "ActivationBox");
RotationAngle = Xml.GetChildFloatAttribute(node, "RotationAngle", "value");
NextShoreline = XmlRel.GetHash(Xml.GetChildInnerText(node, "NextShoreline"));
@@ -10009,6 +11195,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (ShoreLineRiverAudioSettingsFlags flag in Enum.GetValues(typeof(ShoreLineRiverAudioSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.SelfClosingTag(sb, indent, "ActivationBox " + FloatUtil.GetVector4XmlString(ActivationBox));
RelXml.ValueTag(sb, indent, "RotationAngle", FloatUtil.ToString(RotationAngle));
RelXml.StringTag(sb, indent, "NextShoreline", RelXml.HashString(NextShoreline));
@@ -10018,7 +11214,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("ShoreLineRiverAudioSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out ShoreLineRiverAudioSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
ActivationBox = Xml.GetChildVector4Attributes(node, "ActivationBox");
RotationAngle = Xml.GetChildFloatAttribute(node, "RotationAngle", "value");
NextShoreline = XmlRel.GetHash(Xml.GetChildInnerText(node, "NextShoreline"));
@@ -10035,7 +11248,9 @@ public class Dat151ShoreLineOceanAudioSettings : Dat151RelData
public FlagsUint Flags { get; set; }
public Vector4 ActivationBox { get; set; }
public float RotationAngle { get; set; }
- public uint OceanType { get; set; }
+ public byte OceanType { get; set; }
+ public byte OceanDirection { get; set; }
+ public ushort padding00 { get; set; }
public MetaHash NextShoreline { get; set; }
public float WaveStartDPDistance { get; set; }
public float WaveStartHeight { get; set; }
@@ -10057,7 +11272,9 @@ public Dat151ShoreLineOceanAudioSettings(RelData d, BinaryReader br) : base(d, b
Flags = br.ReadUInt32();
ActivationBox = new Vector4(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
RotationAngle = br.ReadSingle();
- OceanType = br.ReadUInt32();
+ OceanType = br.ReadByte();
+ OceanDirection = br.ReadByte();
+ padding00 = br.ReadUInt16();
NextShoreline = br.ReadUInt32();
WaveStartDPDistance = br.ReadSingle();
WaveStartHeight = br.ReadSingle();
@@ -10087,6 +11304,8 @@ public override void Write(BinaryWriter bw)
bw.Write(ActivationBox.W);
bw.Write(RotationAngle);
bw.Write(OceanType);
+ bw.Write(OceanDirection);
+ bw.Write(padding00);
bw.Write(NextShoreline);
bw.Write(WaveStartDPDistance);
bw.Write(WaveStartHeight);
@@ -10107,9 +11326,20 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (ShoreLineOceanAudioSettingsFlags flag in Enum.GetValues(typeof(ShoreLineOceanAudioSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.SelfClosingTag(sb, indent, "ActivationBox " + FloatUtil.GetVector4XmlString(ActivationBox));
RelXml.ValueTag(sb, indent, "RotationAngle", FloatUtil.ToString(RotationAngle));
RelXml.ValueTag(sb, indent, "OceanType", OceanType.ToString());
+ RelXml.ValueTag(sb, indent, "OceanDirection", OceanDirection.ToString());
RelXml.StringTag(sb, indent, "NextShoreline", RelXml.HashString(NextShoreline));
RelXml.ValueTag(sb, indent, "WaveStartDPDistance", FloatUtil.ToString(WaveStartDPDistance));
RelXml.ValueTag(sb, indent, "WaveStartHeight", FloatUtil.ToString(WaveStartHeight));
@@ -10122,10 +11352,28 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("ShoreLineOceanAudioSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out ShoreLineOceanAudioSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
ActivationBox = Xml.GetChildVector4Attributes(node, "ActivationBox");
RotationAngle = Xml.GetChildFloatAttribute(node, "RotationAngle", "value");
- OceanType = Xml.GetChildUIntAttribute(node, "OceanType", "value");
+ OceanType = (byte)Xml.GetChildUIntAttribute(node, "OceanType", "value");
+ OceanDirection = (byte)Xml.GetChildUIntAttribute(node, "OceanDirection", "value");
NextShoreline = XmlRel.GetHash(Xml.GetChildInnerText(node, "NextShoreline"));
WaveStartDPDistance = Xml.GetChildFloatAttribute(node, "WaveStartDPDistance", "value");
WaveStartHeight = Xml.GetChildFloatAttribute(node, "WaveStartHeight", "value");
@@ -10164,6 +11412,12 @@ public override void Write(BinaryWriter bw)
{
WriteTypeAndOffset(bw);
+ if (ShoreLines == null)
+ {
+ ShoreLines = new MetaHash[0];
+ ShoreLineCount = 0;
+ }
+
bw.Write(ShoreLineCount);
for (int i = 0; i < ShoreLineCount; i++)
{
@@ -10177,7 +11431,16 @@ public override void WriteXml(StringBuilder sb, int indent)
public override void ReadXml(XmlNode node)
{
ShoreLines = XmlRel.ReadHashItemArray(node, "ShoreLines");
- ShoreLineCount = (uint)(ShoreLines?.Length ?? 0);
+
+ if (ShoreLines == null)
+ {
+ ShoreLines = new MetaHash[0];
+ ShoreLineCount = 0;
+ }
+ else
+ {
+ ShoreLineCount = (uint)ShoreLines.Length;
+ }
}
public override MetaHash[] GetGameHashes()
{
@@ -10472,6 +11735,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (GranularEngineAudioSettingsFlags flag in Enum.GetValues(typeof(GranularEngineAudioSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "MasterVolume", MasterVolume.ToString());
RelXml.StringTag(sb, indent, "EngineAccel", RelXml.HashString(EngineAccel));
RelXml.StringTag(sb, indent, "ExhaustAccel", RelXml.HashString(ExhaustAccel));
@@ -10534,7 +11807,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("GranularEngineAudioSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out GranularEngineAudioSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
MasterVolume = Xml.GetChildIntAttribute(node, "MasterVolume", "value");
EngineAccel = XmlRel.GetHash(Xml.GetChildInnerText(node, "EngineAccel"));
ExhaustAccel = XmlRel.GetHash(Xml.GetChildInnerText(node, "ExhaustAccel"));
@@ -10887,9 +12177,20 @@ public override void Write(BinaryWriter bw)
}
}
+
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (CarAudioSettingsFlags flag in Enum.GetValues(typeof(CarAudioSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.StringTag(sb, indent, "Engine", RelXml.HashString(Engine));
RelXml.StringTag(sb, indent, "GranularEngine", RelXml.HashString(GranularEngine));
RelXml.StringTag(sb, indent, "HornSounds", RelXml.HashString(HornSounds));
@@ -10973,7 +12274,25 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("CarAudioSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out CarAudioSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Engine = XmlRel.GetHash(Xml.GetChildInnerText(node, "Engine"));
GranularEngine = XmlRel.GetHash(Xml.GetChildInnerText(node, "GranularEngine"));
HornSounds = XmlRel.GetHash(Xml.GetChildInnerText(node, "HornSounds"));
@@ -11466,11 +12785,38 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (ScannerVehicleParamsFlags flag in Enum.GetValues(typeof(ScannerVehicleParamsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.WriteItemArray(sb, Params, indent, "Params");
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("ScannerVehicleParamsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out ScannerVehicleParamsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Params = XmlRel.ReadItemArray(node, "Params");
ParamCount = (Params?.Length ?? 0);
}
@@ -11746,6 +13092,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (WeaponSettingsFlags flag in Enum.GetValues(typeof(WeaponSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "Version", Version.ToString());
RelXml.StringTag(sb, indent, "FireSound", RelXml.HashString(FireSound));
RelXml.StringTag(sb, indent, "SuppressedFireSound", RelXml.HashString(SuppressedFireSound));
@@ -11829,7 +13185,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("WeaponSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out WeaponSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Version = Xml.GetChildIntAttribute(node, "Version", "value");
FireSound = XmlRel.GetHash(Xml.GetChildInnerText(node, "FireSound"));
SuppressedFireSound = XmlRel.GetHash(Xml.GetChildInnerText(node, "SuppressedFireSound"));
@@ -11975,6 +13348,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (ExplosionAudioSettingsFlags flag in Enum.GetValues(typeof(ExplosionAudioSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.StringTag(sb, indent, "ExplosionSound", RelXml.HashString(ExplosionSound));
RelXml.StringTag(sb, indent, "DebrisSound", RelXml.HashString(DebrisSound));
RelXml.ValueTag(sb, indent, "DeafeningVolume", FloatUtil.ToString(DeafeningVolume));
@@ -11989,7 +13372,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("ExplosionAudioSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out ExplosionAudioSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
ExplosionSound = XmlRel.GetHash(Xml.GetChildInnerText(node, "ExplosionSound"));
DebrisSound = XmlRel.GetHash(Xml.GetChildInnerText(node, "DebrisSound"));
DeafeningVolume = Xml.GetChildFloatAttribute(node, "DeafeningVolume", "value");
@@ -12149,6 +13549,13 @@ public override void Write(BinaryWriter bw)
{
GangVoices[i].Write(bw);
}
+
+ if (BackupPVGs == null)
+ {
+ BackupPVGs = new MetaHash[0];
+ BackupPVGCount = 0;
+ }
+
bw.Write(BackupPVGCount);
if (Version >= 1)
{
@@ -12182,7 +13589,17 @@ public override void ReadXml(XmlNode node)
GangVoices = XmlRel.ReadItemArray(node, "GangVoices");
GangVoicesCount = (byte)(GangVoices?.Length ?? 0);
BackupPVGs = XmlRel.ReadHashItemArray(node, "BackupPVGs");
- BackupPVGCount = (byte)(BackupPVGs?.Length ?? 0);
+
+ if (BackupPVGs == null)
+ {
+ BackupPVGs = new MetaHash[0];
+ BackupPVGCount = 0;
+ }
+ else
+ {
+ BackupPVGCount = (byte)BackupPVGs.Length;
+ }
+
Version = (BackupPVGCount == 0) ? 0 : 1;
}
public override MetaHash[] GetSpeechHashes()
@@ -12282,6 +13699,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (EntityEmitterFlags flag in Enum.GetValues(typeof(EntityEmitterFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.StringTag(sb, indent, "Sound", RelXml.HashString(Sound));
RelXml.ValueTag(sb, indent, "MaxDistance", FloatUtil.ToString(MaxDistance));
RelXml.ValueTag(sb, indent, "BusinessHoursProb", FloatUtil.ToString(BusinessHoursProb));
@@ -12296,7 +13723,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("EntityEmitterFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out EntityEmitterFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Sound = XmlRel.GetHash(Xml.GetChildInnerText(node, "Sound"));
MaxDistance = Xml.GetChildFloatAttribute(node, "MaxDistance", "value");
BusinessHoursProb = Xml.GetChildFloatAttribute(node, "BusinessHoursProb", "value");
@@ -12538,6 +13982,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (BoatAudioSettingsFlags flag in Enum.GetValues(typeof(BoatAudioSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.StringTag(sb, indent, "Engine1Loop", RelXml.HashString(Engine1Loop));
RelXml.StringTag(sb, indent, "Engine1Vol", RelXml.HashString(Engine1Vol));
RelXml.StringTag(sb, indent, "Engine1Pitch", RelXml.HashString(Engine1Pitch));
@@ -12607,7 +14061,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("BoatAudioSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out BoatAudioSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Engine1Loop = XmlRel.GetHash(Xml.GetChildInnerText(node, "Engine1Loop"));
Engine1Vol = XmlRel.GetHash(Xml.GetChildInnerText(node, "Engine1Vol"));
Engine1Pitch = XmlRel.GetHash(Xml.GetChildInnerText(node, "Engine1Pitch"));
@@ -13147,6 +14618,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (PlaneAudioSettingsFlags flag in Enum.GetValues(typeof(PlaneAudioSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "Version", Version.ToString());
RelXml.StringTag(sb, indent, "EngineLoop", RelXml.HashString(EngineLoop));
RelXml.StringTag(sb, indent, "ExhaustLoop", RelXml.HashString(ExhaustLoop));
@@ -13251,7 +14732,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("PlaneAudioSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out PlaneAudioSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Version = Xml.GetChildIntAttribute(node, "Version", "value");
EngineLoop = XmlRel.GetHash(Xml.GetChildInnerText(node, "EngineLoop"));
ExhaustLoop = XmlRel.GetHash(Xml.GetChildInnerText(node, "ExhaustLoop"));
@@ -13700,6 +15198,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (HeliAudioSettingsFlags flag in Enum.GetValues(typeof(HeliAudioSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "Version", Version.ToString());
RelXml.StringTag(sb, indent, "RotorLoop", RelXml.HashString(RotorLoop));
RelXml.StringTag(sb, indent, "RearRotorLoop", RelXml.HashString(RearRotorLoop));
@@ -13801,7 +15309,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("HeliAudioSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out HeliAudioSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Version = Xml.GetChildIntAttribute(node, "Version", "value");
RotorLoop = XmlRel.GetHash(Xml.GetChildInnerText(node, "RotorLoop"));
RearRotorLoop = XmlRel.GetHash(Xml.GetChildInnerText(node, "RearRotorLoop"));
@@ -14524,6 +16049,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (SpeechParamsFlags flag in Enum.GetValues(typeof(SpeechParamsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "OverrideContextSettings", OverrideContextSettings.ToString());
RelXml.ValueTag(sb, indent, "PreloadTimeoutInMs", PreloadTimeoutInMs.ToString());
RelXml.ValueTag(sb, indent, "RequestedVolume", RequestedVolume.ToString());
@@ -14533,7 +16068,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("SpeechParamsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out SpeechParamsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
OverrideContextSettings = Xml.GetChildIntAttribute(node, "OverrideContextSettings", "value");
PreloadTimeoutInMs = Xml.GetChildUIntAttribute(node, "PreloadTimeoutInMs", "value");
RequestedVolume = (byte)Xml.GetChildUIntAttribute(node, "RequestedVolume", "value");
@@ -14888,6 +16440,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (SpeechContextFlags flag in Enum.GetValues(typeof(SpeechContextFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.StringTag(sb, indent, "ContextName", RelXml.HashString(ContextName));
RelXml.ValueTag(sb, indent, "RepeatTime", RepeatTime.ToString());
RelXml.ValueTag(sb, indent, "RepeatTimeOnSameVoice", RepeatTimeOnSameVoice.ToString());
@@ -14907,7 +16469,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("SpeechContextFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out SpeechContextFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
ContextName = XmlRel.GetHash(Xml.GetChildInnerText(node, "ContextName"));
RepeatTime = Xml.GetChildIntAttribute(node, "RepeatTime", "value");
RepeatTimeOnSameVoice = Xml.GetChildIntAttribute(node, "RepeatTimeOnSameVoice", "value");
@@ -15011,6 +16590,12 @@ public override void Write(BinaryWriter bw)
bw.Write(ResolvingFunction);
+ if (Items == null)
+ {
+ Items = new MetaHash[0];
+ ItemCount = 0;
+ }
+
bw.Write(ItemCount);
for (int i = 0; i < ItemCount; i++)
{
@@ -15020,6 +16605,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (SpeechContextVirtualFlags flag in Enum.GetValues(typeof(SpeechContextVirtualFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.StringTag(sb, indent, "ContextNameHash", RelXml.HashString(ContextNameHash));
RelXml.ValueTag(sb, indent, "RepeatTime", RepeatTime.ToString());
RelXml.ValueTag(sb, indent, "RepeatTimeOnSameVoice", RepeatTimeOnSameVoice.ToString());
@@ -15043,7 +16638,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("SpeechContextVirtualFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out SpeechContextVirtualFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
ContextNameHash = XmlRel.GetHash(Xml.GetChildInnerText(node, "ContextNameHash"));
RepeatTime = Xml.GetChildIntAttribute(node, "RepeatTime", "value");
RepeatTimeOnSameVoice = Xml.GetChildIntAttribute(node, "RepeatTimeOnSameVoice", "value");
@@ -15064,7 +16676,16 @@ public override void ReadXml(XmlNode node)
ResolvingFunction = (byte)Xml.GetChildUIntAttribute(node, "ResolvingFunction", "value");
Items = XmlRel.ReadHashItemArray(node, "Items");
- ItemCount = (byte)(Items?.Length ?? 0);
+
+ if (Items == null)
+ {
+ Items = new MetaHash[0];
+ ItemCount = 0;
+ }
+ else
+ {
+ ItemCount = (byte)Items.Length;
+ }
}
public override MetaHash[] GetSoundHashes()
@@ -15102,6 +16723,12 @@ public override void Write(BinaryWriter bw)
{
WriteTypeAndOffset(bw);
+ if (TriggeredSpeechContexts == null)
+ {
+ TriggeredSpeechContexts = new MetaHash[0];
+ TriggeredSpeechContextsCount = 0;
+ }
+
bw.Write(TriggeredSpeechContextsCount);
for (int i = 0; i < TriggeredSpeechContextsCount; i++)
{
@@ -15115,7 +16742,16 @@ public override void WriteXml(StringBuilder sb, int indent)
public override void ReadXml(XmlNode node)
{
TriggeredSpeechContexts = XmlRel.ReadHashItemArray(node, "TriggeredSpeechContexts");
- TriggeredSpeechContextsCount = (TriggeredSpeechContexts?.Length ?? 0);
+
+ if (TriggeredSpeechContexts == null)
+ {
+ TriggeredSpeechContexts = new MetaHash[0];
+ TriggeredSpeechContextsCount = 0;
+ }
+ else
+ {
+ TriggeredSpeechContextsCount = TriggeredSpeechContexts.Length;
+ }
}
public override MetaHash[] GetGameHashes()
{
@@ -15726,6 +17362,12 @@ public override void Write(BinaryWriter bw)
bw.Write(Italian);
bw.Write(Pakistani);
+ if (FriendGroups == null)
+ {
+ FriendGroups = new MetaHash[0];
+ FriendGroupsCount = 0;
+ }
+
bw.Write(FriendGroupsCount);
for (int i = 0; i < FriendGroupsCount; i++)
{
@@ -15763,7 +17405,16 @@ public override void ReadXml(XmlNode node)
Italian = XmlRel.GetHash(Xml.GetChildInnerText(node, "Italian"));
Pakistani = XmlRel.GetHash(Xml.GetChildInnerText(node, "Pakistani"));
FriendGroups = XmlRel.ReadHashItemArray(node, "FriendGroups");
- FriendGroupsCount = (FriendGroups?.Length ?? 0);
+
+ if (FriendGroups == null)
+ {
+ FriendGroups = new MetaHash[0];
+ FriendGroupsCount = 0;
+ }
+ else
+ {
+ FriendGroupsCount = FriendGroups.Length;
+ }
}
public override MetaHash[] GetGameHashes()
{
@@ -15840,11 +17491,38 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (ScriptedScannerLineFlags flag in Enum.GetValues(typeof(ScriptedScannerLineFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.WriteItemArray(sb, Phrase, indent, "Phrase");
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("ScriptedScannerLineFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out ScriptedScannerLineFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
Phrase = XmlRel.ReadItemArray(node, "Phrase");
PhrasesCount = (Phrase?.Length ?? 0);
}
@@ -15991,6 +17669,12 @@ public override void Write(BinaryWriter bw)
bw.Write(Radius);
bw.Write(ProbOfPlaying);
+ if (Sound == null)
+ {
+ Sound = new MetaHash[0];
+ NumSounds = 0;
+ }
+
bw.Write(NumSounds);
for (int i = 0; i < NumSounds; i++)
{
@@ -16018,7 +17702,16 @@ public override void ReadXml(XmlNode node)
ProbOfPlaying = Xml.GetChildFloatAttribute(node, "ProbOfPlaying", "value");
Sound = XmlRel.ReadHashItemArray(node, "Sound");
- NumSounds = (Sound?.Length ?? 0);
+
+ if (Sound == null)
+ {
+ Sound = new MetaHash[0];
+ NumSounds = 0;
+ }
+ else
+ {
+ NumSounds = Sound.Length;
+ }
}
public override MetaHash[] GetSoundHashes()
{
@@ -16050,6 +17743,12 @@ public override void Write(BinaryWriter bw)
{
WriteTypeAndOffset(bw);
+ if (Locations == null)
+ {
+ Locations = new MetaHash[0];
+ LocationsCount = 0;
+ }
+
bw.Write(LocationsCount);
for (int i = 0; i < LocationsCount; i++)
{
@@ -16063,7 +17762,16 @@ public override void WriteXml(StringBuilder sb, int indent)
public override void ReadXml(XmlNode node)
{
Locations = XmlRel.ReadHashItemArray(node, "Locations");
- LocationsCount = (Locations?.Length ?? 0);
+
+ if (Locations == null)
+ {
+ Locations = new MetaHash[0];
+ LocationsCount = 0;
+ }
+ else
+ {
+ LocationsCount = Locations.Length;
+ }
}
public override MetaHash[] GetGameHashes()
{
@@ -16277,6 +17985,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (EnvironmentRuleFlags flag in Enum.GetValues(typeof(EnvironmentRuleFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "ReverbSmall", FloatUtil.ToString(ReverbSmall));
RelXml.ValueTag(sb, indent, "ReverbMedium", FloatUtil.ToString(ReverbMedium));
RelXml.ValueTag(sb, indent, "ReverbLarge", FloatUtil.ToString(ReverbLarge));
@@ -16290,7 +18008,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("EnvironmentRuleFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out EnvironmentRuleFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
ReverbSmall = Xml.GetChildFloatAttribute(node, "ReverbSmall", "value");
ReverbMedium = Xml.GetChildFloatAttribute(node, "ReverbMedium", "value");
ReverbLarge = Xml.GetChildFloatAttribute(node, "ReverbLarge", "value");
@@ -16401,6 +18136,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (DoorTuningParamsFlags flag in Enum.GetValues(typeof(DoorTuningParamsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "OpenThresh", FloatUtil.ToString(OpenThresh));
RelXml.ValueTag(sb, indent, "HeadingThresh", FloatUtil.ToString(HeadingThresh));
RelXml.ValueTag(sb, indent, "ClosedThresh", FloatUtil.ToString(ClosedThresh));
@@ -16412,7 +18157,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("DoorTuningParamsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out DoorTuningParamsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
OpenThresh = Xml.GetChildFloatAttribute(node, "OpenThresh", "value");
HeadingThresh = Xml.GetChildFloatAttribute(node, "HeadingThresh", "value");
ClosedThresh = Xml.GetChildFloatAttribute(node, "ClosedThresh", "value");
@@ -16528,6 +18290,12 @@ public override void Write(BinaryWriter bw)
bw.Write(AudioScene);
bw.Write(WindGustEnd);
+ if (WindSounds == null)
+ {
+ WindSounds = new MetaHash[0];
+ WindSoundsCount = 0;
+ }
+
bw.Write(WindSoundsCount);
for (int i = 0; i < WindSoundsCount; i++)
{
@@ -16557,7 +18325,16 @@ public override void ReadXml(XmlNode node)
AudioScene = XmlRel.GetHash(Xml.GetChildInnerText(node, "AudioScene"));
WindGustEnd = XmlRel.GetHash(Xml.GetChildInnerText(node, "WindGustEnd"));
WindSounds = XmlRel.ReadHashItemArray(node, "WindSounds");
- WindSoundsCount = (WindSounds?.Length ?? 0);
+
+ if (WindSounds == null)
+ {
+ WindSounds = new MetaHash[0];
+ WindSoundsCount = 0;
+ }
+ else
+ {
+ WindSoundsCount = WindSounds.Length;
+ }
}
public override MetaHash[] GetMixerHashes()
{
@@ -16783,6 +18560,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (DirectionalAmbienceFlags flag in Enum.GetValues(typeof(DirectionalAmbienceFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.StringTag(sb, indent, "SoundNorth", RelXml.HashString(SoundNorth));
RelXml.StringTag(sb, indent, "SoundEast", RelXml.HashString(SoundEast));
RelXml.StringTag(sb, indent, "SoundSouth", RelXml.HashString(SoundSouth));
@@ -16804,7 +18591,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("DirectionalAmbienceFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out DirectionalAmbienceFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
SoundNorth = XmlRel.GetHash(Xml.GetChildInnerText(node, "SoundNorth"));
SoundEast = XmlRel.GetHash(Xml.GetChildInnerText(node, "SoundEast"));
SoundSouth = XmlRel.GetHash(Xml.GetChildInnerText(node, "SoundSouth"));
@@ -17556,7 +19360,7 @@ public void ReadXml(XmlNode node)
}
public override string ToString()
{
- return string.Format("{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", ListenerContribution, RearAttenuationFrontConeAngle, RearAttenuationRearConeAngle, CloseRearAttenuation, FarRearAttenuation, RollOff, RearAttenuationType, MicLength, MicToPlayerLocalEnvironmentRatio);
+ return $"{ListenerContribution}, {RearAttenuationFrontConeAngle}, {RearAttenuationRearConeAngle}, {CloseRearAttenuation}, {FarRearAttenuation}, {RollOff}, {RearAttenuationType}, {MicLength}, {MicToPlayerLocalEnvironmentRatio}";
}
}
@@ -17607,12 +19411,39 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (MicrophoneSettingsFlags flag in Enum.GetValues(typeof(MicrophoneSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "MicType", MicType.ToString());
RelXml.WriteItemArray(sb, Microphones, indent, "Microphones");
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("MicrophoneSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out MicrophoneSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
MicType = (byte)Xml.GetChildIntAttribute(node, "MicType", "value");
Microphones = XmlRel.ReadItemArray(node, "Microphones");
MicrophonesCount = (byte)(Microphones?.Length ?? 0);
@@ -17957,6 +19788,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (ClothAudioSettingsFlags flag in Enum.GetValues(typeof(ClothAudioSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.StringTag(sb, indent, "ImpactSound", RelXml.HashString(ImpactSound));
RelXml.StringTag(sb, indent, "WalkSound", RelXml.HashString(WalkSound));
RelXml.StringTag(sb, indent, "RunSound", RelXml.HashString(RunSound));
@@ -17974,7 +19815,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("ClothAudioSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out ClothAudioSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
ImpactSound = XmlRel.GetHash(Xml.GetChildInnerText(node, "ImpactSound"));
WalkSound = XmlRel.GetHash(Xml.GetChildInnerText(node, "WalkSound"));
RunSound = XmlRel.GetHash(Xml.GetChildInnerText(node, "RunSound"));
@@ -18373,6 +20231,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (ReflectionsSettingsFlags flag in Enum.GetValues(typeof(ReflectionsSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "MinDelay", FloatUtil.ToString(MinDelay));
RelXml.ValueTag(sb, indent, "MaxDelay", FloatUtil.ToString(MaxDelay));
RelXml.ValueTag(sb, indent, "DelayTimeScalar", FloatUtil.ToString(DelayTimeScalar));
@@ -18394,7 +20262,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("ReflectionsSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out ReflectionsSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
MinDelay = Xml.GetChildFloatAttribute(node, "MinDelay", "value");
MaxDelay = Xml.GetChildFloatAttribute(node, "MaxDelay", "value");
DelayTimeScalar = Xml.GetChildFloatAttribute(node, "DelayTimeScalar", "value");
@@ -18594,6 +20479,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (PedScenarioAudioSettingsFlags flag in Enum.GetValues(typeof(PedScenarioAudioSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "MaxInstances", MaxInstances.ToString());
RelXml.StringTag(sb, indent, "Sound", RelXml.HashString(Sound));
RelXml.ValueTag(sb, indent, "SharedOwnershipRadius", FloatUtil.ToString(SharedOwnershipRadius));
@@ -18601,7 +20496,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("PedScenarioAudioSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out PedScenarioAudioSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
MaxInstances = Xml.GetChildIntAttribute(node, "MaxInstances", "value");
Sound = XmlRel.GetHash(Xml.GetChildInnerText(node, "Sound"));
SharedOwnershipRadius = Xml.GetChildFloatAttribute(node, "SharedOwnershipRadius", "value");
@@ -19771,6 +21683,16 @@ public override void Write(BinaryWriter bw)
public override void WriteXml(StringBuilder sb, int indent)
{
RelXml.ValueTag(sb, indent, "Flags", "0x" + Flags.Hex);
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+ foreach (RandomisedRadioEmitterSettingsFlags flag in Enum.GetValues(typeof(RandomisedRadioEmitterSettingsFlags)))
+ {
+ TristateValue value = GetTristateValue(Flags, (int)flag);
+ RelXml.SelfClosingTag(sb, indent + 1, flag.ToString() + $" value=\"{value.ToString().ToLower()}\"");
+ }
+ RelXml.Indent(sb, indent);
+ sb.AppendLine("");
+
RelXml.ValueTag(sb, indent, "VehicleEmitterBias", FloatUtil.ToString(VehicleEmitterBias));
RelXml.StringTag(sb, indent, "StaticEmitter", RelXml.HashString(StaticEmitter));
RelXml.ValueTag(sb, indent, "StaticEmitterMinTime", FloatUtil.ToString(StaticEmitterMinTime));
@@ -19795,7 +21717,24 @@ public override void WriteXml(StringBuilder sb, int indent)
}
public override void ReadXml(XmlNode node)
{
- Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ uint flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
+ XmlNode flagsNode = node.SelectSingleNode("RandomisedRadioEmitterSettingsFlags");
+ if (flagsNode != null)
+ {
+ foreach (XmlNode flagNode in flagsNode.ChildNodes)
+ {
+ if (Enum.TryParse(flagNode.Name, out RandomisedRadioEmitterSettingsFlags flag))
+ {
+ string valueStr = flagNode.Attributes?["value"]?.Value;
+ if (Enum.TryParse(valueStr, true, out TristateValue value))
+ {
+ SetTristateValue(ref flags, (int)flag, value);
+ }
+ }
+ }
+ }
+ Flags = flags;
+
VehicleEmitterBias = Xml.GetChildFloatAttribute(node, "VehicleEmitterBias", "value");
StaticEmitter = XmlRel.GetHash(Xml.GetChildInnerText(node, "StaticEmitter"));
StaticEmitterMinTime = Xml.GetChildFloatAttribute(node, "StaticEmitterMinTime", "value");
@@ -20199,6 +22138,12 @@ public override void Write(BinaryWriter bw)
{
WriteTypeAndOffset(bw);
+ if (GameObjectHashes == null)
+ {
+ GameObjectHashes = new MetaHash[0];
+ GameObjectHashesCount = 0;
+ }
+
bw.Write(Flags);
bw.Write(GameObjectHashesCount);
for (int i = 0; i < GameObjectHashesCount; i++)
@@ -20216,7 +22161,16 @@ public override void ReadXml(XmlNode node)
{
Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
GameObjectHashes = XmlRel.ReadHashItemArray(node, "GameObjectHashes");
- GameObjectHashesCount = (uint)(GameObjectHashes?.Length ?? 0);
+
+ if (GameObjectHashes == null)
+ {
+ GameObjectHashes = new MetaHash[0];
+ GameObjectHashesCount = 0;
+ }
+ else
+ {
+ GameObjectHashesCount = (uint)GameObjectHashes.Length;
+ }
}
public override MetaHash[] GetGameHashes()
{
@@ -20622,6 +22576,13 @@ public Dat4ConfigWaveSlotsList(RelData d, BinaryReader br) : base(d, br)
public override void Write(BinaryWriter bw)
{
base.Write(bw);
+
+ if (WaveSlots == null)
+ {
+ WaveSlots = new MetaHash[0];
+ WaveSlotsCount = 0;
+ }
+
bw.Write(WaveSlotsCount);
for (int i = 0; i < WaveSlotsCount; i++)
{
@@ -20637,7 +22598,16 @@ public override void ReadXml(XmlNode node)
{
base.ReadXml(node);
WaveSlots = XmlRel.ReadHashItemArray(node, "WaveSlots");
- WaveSlotsCount = (WaveSlots?.Length ?? 0);
+
+ if (WaveSlots == null)
+ {
+ WaveSlots = new MetaHash[0];
+ WaveSlotsCount = 0;
+ }
+ else
+ {
+ WaveSlotsCount = WaveSlots.Length;
+ }
}
public override uint[] GetHashTableOffsets()
{
@@ -21709,7 +23679,16 @@ public static AssembleResult Assemble(string assembly, Dat10SynthVariable[] vari
return null;
}
- var inputs = parts[0].Split(',').Select(s => s.Trim()).Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
+ // Consolidated: split, trim, and filter in single pass
+ var inputParts = parts[0].Split(',');
+ var inputList = new List(inputParts.Length);
+ foreach (var s in inputParts)
+ {
+ var trimmed = s.Trim();
+ if (!string.IsNullOrWhiteSpace(trimmed))
+ inputList.Add(trimmed);
+ }
+ var inputs = inputList.ToArray();
var stateBlockEnd = parts[1].LastIndexOf(']');
var stateBlockStart = parts[1].IndexOf('[');
@@ -21730,8 +23709,17 @@ public static AssembleResult Assemble(string assembly, Dat10SynthVariable[] vari
var hasStateBlock = stateBlockStart != -1;
var stateBlockStr = hasStateBlock ? parts[1].Substring(stateBlockStart + 1, stateBlockEnd - stateBlockStart - 1) : null;
- var outputs = parts[1].Substring(0, hasStateBlock ? stateBlockStart : parts[1].Length)
- .Split(',').Select(s => s.Trim()).Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
+ // Consolidated: split, trim, and filter in single pass
+ var outputStr = parts[1].Substring(0, hasStateBlock ? stateBlockStart : parts[1].Length);
+ var outputParts = outputStr.Split(',');
+ var outputList = new List(outputParts.Length);
+ foreach (var s in outputParts)
+ {
+ var trimmed = s.Trim();
+ if (!string.IsNullOrWhiteSpace(trimmed))
+ outputList.Add(trimmed);
+ }
+ var outputs = outputList.ToArray();
var currInputIndex = 0;
var currOutputIndex = 0;
@@ -23310,6 +25298,12 @@ public override void Write(BinaryWriter bw)
{
WriteTypeAndOffsetAndFlags(bw);
+ if (Groups == null)
+ {
+ Groups = new MetaHash[0];
+ GroupCount = 0;
+ }
+
bw.Write(GroupCount);
for (int i = 0; i < GroupCount; i++)
{
@@ -23325,7 +25319,16 @@ public override void ReadXml(XmlNode node)
{
Flags = Xml.GetChildUIntAttribute(node, "Flags", "value");
Groups = XmlRel.ReadHashItemArray(node, "Groups");
- GroupCount = (byte)(Groups?.Length ?? 0);
+
+ if (Groups == null)
+ {
+ Groups = new MetaHash[0];
+ GroupCount = 0;
+ }
+ else
+ {
+ GroupCount = (byte)Groups.Length;
+ }
}
public override MetaHash[] GetMixerHashes()
{
@@ -24440,6 +26443,13 @@ public override void Write(BinaryWriter bw)
bw.Write(UnderwaterWetLevel);
bw.Write(StonedWetLevel);
bw.Write(Timer);
+
+ if (SubCategories == null)
+ {
+ SubCategories = new MetaHash[0];
+ SubCategoryCount = 0;
+ }
+
bw.Write(SubCategoryCount);
for (int i = 0; i < SubCategoryCount; i++)
{
@@ -24492,7 +26502,16 @@ public override void ReadXml(XmlNode node)
StonedWetLevel = (short)Xml.GetChildIntAttribute(node, "StonedWetLevel", "value");
Timer = (byte)Xml.GetChildUIntAttribute(node, "Timer", "value");
SubCategories = XmlRel.ReadHashItemArray(node, "SubCategories");
- SubCategoryCount = (byte)(SubCategories?.Length ?? 0);
+
+ if (SubCategories == null)
+ {
+ SubCategories = new MetaHash[0];
+ SubCategoryCount = 0;
+ }
+ else
+ {
+ SubCategoryCount = (byte)SubCategories.Length;
+ }
}
public override MetaHash[] GetCurveHashes()
{