From d2a8a78f8551ceca55fe0fee02a0dc0fb13debd8 Mon Sep 17 00:00:00 2001 From: Ammar Askar Date: Wed, 2 Aug 2023 00:28:55 -0400 Subject: [PATCH] Parse camera, model and screen effects --- .../Content/DBPF/Effects/CameraEffect.cs | 11 ++- .../Content/DBPF/Effects/ModelEffect.cs | 20 +++++ .../Content/DBPF/Effects/ModelEffect.cs.meta | 3 + .../Content/DBPF/Effects/ScreenEffect.cs | 25 ++++++ .../Content/DBPF/Effects/ScreenEffect.cs.meta | 3 + .../Content/DBPF/Effects/WaterEffect.cs | 7 ++ .../Content/DBPF/Effects/WaterEffect.cs.meta | 3 + .../OpenTS2/Content/DBPF/EffectsAsset.cs | 9 +- .../Files/Formats/DBPF/EffectsCodec.cs | 83 ++++++++++++++++++- .../Files/Formats/DBPF/EffectsCodecTest.cs | 77 +++++++++++------ 10 files changed, 211 insertions(+), 30 deletions(-) create mode 100644 Assets/Scripts/OpenTS2/Content/DBPF/Effects/ModelEffect.cs create mode 100644 Assets/Scripts/OpenTS2/Content/DBPF/Effects/ModelEffect.cs.meta create mode 100644 Assets/Scripts/OpenTS2/Content/DBPF/Effects/ScreenEffect.cs create mode 100644 Assets/Scripts/OpenTS2/Content/DBPF/Effects/ScreenEffect.cs.meta create mode 100644 Assets/Scripts/OpenTS2/Content/DBPF/Effects/WaterEffect.cs create mode 100644 Assets/Scripts/OpenTS2/Content/DBPF/Effects/WaterEffect.cs.meta diff --git a/Assets/Scripts/OpenTS2/Content/DBPF/Effects/CameraEffect.cs b/Assets/Scripts/OpenTS2/Content/DBPF/Effects/CameraEffect.cs index b4f53e2..c82d6b2 100644 --- a/Assets/Scripts/OpenTS2/Content/DBPF/Effects/CameraEffect.cs +++ b/Assets/Scripts/OpenTS2/Content/DBPF/Effects/CameraEffect.cs @@ -2,6 +2,15 @@ { public readonly struct CameraEffect : IBaseEffect { - + public readonly float Life; + public readonly float ShakeAspect; + public readonly string CameraSelectName; + + public CameraEffect(float life, float shakeAspect, string cameraSelectName) + { + Life = life; + ShakeAspect = shakeAspect; + CameraSelectName = cameraSelectName; + } } } \ No newline at end of file diff --git a/Assets/Scripts/OpenTS2/Content/DBPF/Effects/ModelEffect.cs b/Assets/Scripts/OpenTS2/Content/DBPF/Effects/ModelEffect.cs new file mode 100644 index 0000000..9f54ac7 --- /dev/null +++ b/Assets/Scripts/OpenTS2/Content/DBPF/Effects/ModelEffect.cs @@ -0,0 +1,20 @@ +using UnityEngine; + +namespace OpenTS2.Content.DBPF.Effects +{ + public readonly struct ModelEffect : IBaseEffect + { + public readonly string ModelName; + public readonly float Size; + public readonly Vector3 Color; + public readonly float Alpha; + + public ModelEffect(string modelName, float size, Vector3 color, float alpha) + { + ModelName = modelName; + Size = size; + Color = color; + Alpha = alpha; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/OpenTS2/Content/DBPF/Effects/ModelEffect.cs.meta b/Assets/Scripts/OpenTS2/Content/DBPF/Effects/ModelEffect.cs.meta new file mode 100644 index 0000000..af04109 --- /dev/null +++ b/Assets/Scripts/OpenTS2/Content/DBPF/Effects/ModelEffect.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c1c744d947d84c39847bdf44d41d20b9 +timeCreated: 1690949107 \ No newline at end of file diff --git a/Assets/Scripts/OpenTS2/Content/DBPF/Effects/ScreenEffect.cs b/Assets/Scripts/OpenTS2/Content/DBPF/Effects/ScreenEffect.cs new file mode 100644 index 0000000..2c7b010 --- /dev/null +++ b/Assets/Scripts/OpenTS2/Content/DBPF/Effects/ScreenEffect.cs @@ -0,0 +1,25 @@ +using UnityEngine; + +namespace OpenTS2.Content.DBPF.Effects +{ + /// + /// Applies a texture across the whole screen. + /// + public readonly struct ScreenEffect : IBaseEffect + { + public readonly Vector3[] Colors; + public readonly FloatCurve Strength; + public readonly float Length; + public readonly float Delay; + public readonly string Texture; + + public ScreenEffect(Vector3[] colors, FloatCurve strength, float length, float delay, string texture) + { + Colors = colors; + Strength = strength; + Length = length; + Delay = delay; + Texture = texture; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/OpenTS2/Content/DBPF/Effects/ScreenEffect.cs.meta b/Assets/Scripts/OpenTS2/Content/DBPF/Effects/ScreenEffect.cs.meta new file mode 100644 index 0000000..a115832 --- /dev/null +++ b/Assets/Scripts/OpenTS2/Content/DBPF/Effects/ScreenEffect.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 587e1275af1244429c88255c36177d93 +timeCreated: 1690949796 \ No newline at end of file diff --git a/Assets/Scripts/OpenTS2/Content/DBPF/Effects/WaterEffect.cs b/Assets/Scripts/OpenTS2/Content/DBPF/Effects/WaterEffect.cs new file mode 100644 index 0000000..044de9e --- /dev/null +++ b/Assets/Scripts/OpenTS2/Content/DBPF/Effects/WaterEffect.cs @@ -0,0 +1,7 @@ +namespace OpenTS2.Content.DBPF.Effects +{ + public readonly struct WaterEffect : IBaseEffect + { + + } +} \ No newline at end of file diff --git a/Assets/Scripts/OpenTS2/Content/DBPF/Effects/WaterEffect.cs.meta b/Assets/Scripts/OpenTS2/Content/DBPF/Effects/WaterEffect.cs.meta new file mode 100644 index 0000000..510aed5 --- /dev/null +++ b/Assets/Scripts/OpenTS2/Content/DBPF/Effects/WaterEffect.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 522d917d07bb4397bab90c351a3771eb +timeCreated: 1690950298 \ No newline at end of file diff --git a/Assets/Scripts/OpenTS2/Content/DBPF/EffectsAsset.cs b/Assets/Scripts/OpenTS2/Content/DBPF/EffectsAsset.cs index cc7cbd4..ad14e09 100644 --- a/Assets/Scripts/OpenTS2/Content/DBPF/EffectsAsset.cs +++ b/Assets/Scripts/OpenTS2/Content/DBPF/EffectsAsset.cs @@ -38,9 +38,13 @@ namespace OpenTS2.Content.DBPF public SequenceEffect[] SequenceEffects { get; } public SoundEffect[] SoundEffects { get; } public CameraEffect[] CameraEffects { get; } + public ModelEffect[] ModelEffects { get; } + public ScreenEffect[] ScreenEffects { get; } + public WaterEffect[] WaterEffects { get; } public EffectsAsset(ParticleEffect[] particles, MetaParticle[] metaParticles, DecalEffect[] decalEffects, - SequenceEffect[] sequenceEffects, SoundEffect[] soundEffects, CameraEffect[] cameraEffects) + SequenceEffect[] sequenceEffects, SoundEffect[] soundEffects, CameraEffect[] cameraEffects, + ModelEffect[] modelEffects, ScreenEffect[] screenEffects, WaterEffect[] waterEffects) { Particles = particles; MetaParticles = metaParticles; @@ -48,6 +52,9 @@ namespace OpenTS2.Content.DBPF SequenceEffects = sequenceEffects; SoundEffects = soundEffects; CameraEffects = cameraEffects; + ModelEffects = modelEffects; + ScreenEffects = screenEffects; + WaterEffects = waterEffects; } } } \ No newline at end of file diff --git a/Assets/Scripts/OpenTS2/Files/Formats/DBPF/EffectsCodec.cs b/Assets/Scripts/OpenTS2/Files/Formats/DBPF/EffectsCodec.cs index 374af8c..7babf5e 100644 --- a/Assets/Scripts/OpenTS2/Files/Formats/DBPF/EffectsCodec.cs +++ b/Assets/Scripts/OpenTS2/Files/Formats/DBPF/EffectsCodec.cs @@ -44,7 +44,7 @@ namespace OpenTS2.Files.Formats.DBPF Debug.Assert(numBrushes == 0, "There shouldn't be any brush effects in Sims2"); var numScrubbers = reader.ReadUInt32(); - Debug.Assert(numScrubbers == 0, "There shouldn't be any brush effects in Sims2"); + Debug.Assert(numScrubbers == 0, "There shouldn't be any scrubber effects in Sims2"); var sequences = new SequenceEffect[reader.ReadUInt32()]; for (var i = 0; i < sequences.Length; i++) @@ -59,8 +59,29 @@ namespace OpenTS2.Files.Formats.DBPF } var cameras = new CameraEffect[reader.ReadUInt32()]; + for (var i = 0; i < cameras.Length; i++) + { + cameras[i] = ReadCameraEffect(reader); + } - return new EffectsAsset(particleEffects, metaParticles, decals, sequences, sounds, cameras); + var numGameEffects = reader.ReadUInt32(); + Debug.Assert(numGameEffects == 0, "There shouldn't be any game effects in Sims2"); + + var models = new ModelEffect[reader.ReadUInt32()]; + for (var i = 0; i < models.Length; i++) + { + models[i] = ReadModelEffect(reader); + } + + var screens = new ScreenEffect[reader.ReadUInt32()]; + for (var i = 0; i < screens.Length; i++) + { + screens[i] = ReadScreenEffect(reader); + } + + var waters = new WaterEffect[reader.ReadUInt32()]; + + return new EffectsAsset(particleEffects, metaParticles, decals, sequences, sounds, cameras, models, screens, waters); } private static Vector3[] ReadMultipleVectors(IoBuffer reader) @@ -296,5 +317,63 @@ namespace OpenTS2.Files.Formats.DBPF return new SoundEffect(audioId, volume); } + + private static CameraEffect ReadCameraEffect(IoBuffer reader) + { + var version = reader.ReadUInt16(); + Debug.Assert(version == 1); + + var flags = reader.ReadUInt32(); + var life = reader.ReadFloat(); + var shakeFadeLength = reader.ReadFloat(); + var shakeAmplitude = FloatCurve.Deserialize(reader); + var shakeFrequency = FloatCurve.Deserialize(reader); + var shakeAspect = reader.ReadFloat(); + var shakeType = reader.ReadByte(); + + var heading = FloatCurve.Deserialize(reader); + var pitch = FloatCurve.Deserialize(reader); + var roll = FloatCurve.Deserialize(reader); + var orbit = FloatCurve.Deserialize(reader); + var fieldOfView = FloatCurve.Deserialize(reader); + var nearClip = FloatCurve.Deserialize(reader); + var farClip = FloatCurve.Deserialize(reader); + + var zoom = reader.ReadSByte(); + var rotate = reader.ReadSByte(); + var attachRadius = reader.ReadFloat(); + var cameraSelectName = reader.ReadUint32PrefixedString(); + + return new CameraEffect(life, shakeAspect, cameraSelectName); + } + + private static ModelEffect ReadModelEffect(IoBuffer reader) + { + var version = reader.ReadUInt16(); + Debug.Assert(version == 1); + + var modelName = reader.ReadUint32PrefixedString(); + var size = reader.ReadFloat(); + var color = Vector3Serializer.Deserialize(reader); + var alpha = reader.ReadFloat(); + + return new ModelEffect(modelName, size, color, alpha); + } + + private static ScreenEffect ReadScreenEffect(IoBuffer reader) + { + var version = reader.ReadUInt16(); + Debug.Assert(version == 1); + + var mode = reader.ReadByte(); + var flags = reader.ReadUInt32(); + var colors = ReadMultipleVectors(reader); + var strength = FloatCurve.Deserialize(reader); + var length = reader.ReadFloat(); + var delay = reader.ReadFloat(); + var texture = reader.ReadUint32PrefixedString(); + + return new ScreenEffect(colors, strength, length, delay, texture); + } } } \ No newline at end of file diff --git a/Assets/Tests/OpenTS2/Files/Formats/DBPF/EffectsCodecTest.cs b/Assets/Tests/OpenTS2/Files/Formats/DBPF/EffectsCodecTest.cs index a1d2999..1eea7b8 100644 --- a/Assets/Tests/OpenTS2/Files/Formats/DBPF/EffectsCodecTest.cs +++ b/Assets/Tests/OpenTS2/Files/Formats/DBPF/EffectsCodecTest.cs @@ -7,34 +7,35 @@ using UnityEngine; public class EffectsCodecTest { - [SetUp] + private EffectsAsset _effectsAsset; + + [OneTimeSetUp] public void SetUp() { TestMain.Initialize(); ContentProvider.Get().AddPackage("TestAssets/Codecs/Effects.package"); + _effectsAsset = ContentProvider.Get() + .GetAsset(new ResourceKey(instanceID: 1, groupID: GroupIDs.Effects, typeID: TypeIDs.EFFECTS)); } [Test] public void TestSuccessfullyLoadsAndHasCorrectNumberOfEffects() { - var effectsAsset = ContentProvider.Get() - .GetAsset(new ResourceKey(instanceID: 1, groupID: GroupIDs.Effects, typeID: TypeIDs.EFFECTS)); - - Assert.IsNotNull(effectsAsset); - Assert.That(effectsAsset.Particles.Length, Is.EqualTo(1792)); - Assert.That(effectsAsset.MetaParticles.Length, Is.EqualTo(302)); - Assert.That(effectsAsset.DecalEffects.Length, Is.EqualTo(23)); - Assert.That(effectsAsset.SequenceEffects.Length, Is.EqualTo(82)); - Assert.That(effectsAsset.SoundEffects.Length, Is.EqualTo(109)); - Assert.That(effectsAsset.CameraEffects.Length, Is.EqualTo(43)); + Assert.IsNotNull(_effectsAsset); + Assert.That(_effectsAsset.Particles.Length, Is.EqualTo(1792)); + Assert.That(_effectsAsset.MetaParticles.Length, Is.EqualTo(302)); + Assert.That(_effectsAsset.DecalEffects.Length, Is.EqualTo(23)); + Assert.That(_effectsAsset.SequenceEffects.Length, Is.EqualTo(82)); + Assert.That(_effectsAsset.SoundEffects.Length, Is.EqualTo(109)); + Assert.That(_effectsAsset.CameraEffects.Length, Is.EqualTo(43)); + Assert.That(_effectsAsset.ModelEffects.Length, Is.EqualTo(40)); + Assert.That(_effectsAsset.WaterEffects.Length, Is.EqualTo(3)); } [Test] public void TestFirstParticleEffectIsCorrect() { - var effectsAsset = ContentProvider.Get() - .GetAsset(new ResourceKey(instanceID: 1, groupID: GroupIDs.Effects, typeID: TypeIDs.EFFECTS)); - var particle = effectsAsset.Particles[0]; + var particle = _effectsAsset.Particles[0]; Assert.That(particle.Life.Life, Is.EqualTo(new Vector2(1, 1))); @@ -59,9 +60,7 @@ public class EffectsCodecTest [Test] public void TestFirstMetaParticleIsCorrect() { - var effectsAsset = ContentProvider.Get() - .GetAsset(new ResourceKey(instanceID: 1, groupID: GroupIDs.Effects, typeID: TypeIDs.EFFECTS)); - var meta = effectsAsset.MetaParticles[0]; + var meta = _effectsAsset.MetaParticles[0]; Assert.That(meta.Life.Life.x, Is.EqualTo(0.1).Within(0.05)); Assert.That(meta.Life.Life.y, Is.EqualTo(0.1).Within(0.05)); @@ -84,9 +83,7 @@ public class EffectsCodecTest [Test] public void TestFirstDecalIsCorrect() { - var effectsAsset = ContentProvider.Get() - .GetAsset(new ResourceKey(instanceID: 1, groupID: GroupIDs.Effects, typeID: TypeIDs.EFFECTS)); - var decal = effectsAsset.DecalEffects[0]; + var decal = _effectsAsset.DecalEffects[0]; Assert.That(decal.Life, Is.EqualTo(0.1).Within(0.05)); Assert.That(decal.TextureName, Is.EqualTo("terrain_edit_ring")); @@ -96,9 +93,7 @@ public class EffectsCodecTest [Test] public void TestFirstSequenceIsCorrect() { - var effectsAsset = ContentProvider.Get() - .GetAsset(new ResourceKey(instanceID: 1, groupID: GroupIDs.Effects, typeID: TypeIDs.EFFECTS)); - var sequence = effectsAsset.SequenceEffects[0]; + var sequence = _effectsAsset.SequenceEffects[0]; Assert.That(sequence.Flags, Is.EqualTo(0x1)); Assert.That(sequence.Components.Length, Is.EqualTo(1)); @@ -111,11 +106,41 @@ public class EffectsCodecTest [Test] public void TestFirstSoundIsCorrect() { - var effectsAsset = ContentProvider.Get() - .GetAsset(new ResourceKey(instanceID: 1, groupID: GroupIDs.Effects, typeID: TypeIDs.EFFECTS)); - var sound = effectsAsset.SoundEffects[0]; + var sound = _effectsAsset.SoundEffects[0]; Assert.That(sound.AudioId, Is.EqualTo(0xFF108046)); Assert.That(sound.Volume, Is.EqualTo(0.0)); } + + [Test] + public void TestSixthCameraIsCorrect() + { + var camera = _effectsAsset.CameraEffects[6]; + + Assert.That(camera.Life, Is.EqualTo(1.0)); + Assert.That(camera.ShakeAspect, Is.EqualTo(1.0)); + Assert.That(camera.CameraSelectName, Is.EqualTo("CAS_ZoomDisabled")); + } + + [Test] + public void TestFirstModelIsCorrect() + { + var model = _effectsAsset.ModelEffects[0]; + + Assert.That(model.ModelName, Is.EqualTo("destruction_post_mouseup_cres")); + Assert.That(model.Size, Is.EqualTo(1.0f)); + Assert.That(model.Color, Is.EqualTo(new Vector3(1, 1, 1))); + Assert.That(model.Alpha, Is.EqualTo(1.0f)); + } + + [Test] + public void TestThirdScreenIsCorrect() + { + var screen = _effectsAsset.ScreenEffects[3]; + + Assert.That(screen.Strength.Curve, Is.EquivalentTo(new[] { 1.0f })); + Assert.That(screen.Length, Is.EqualTo(0)); + Assert.That(screen.Delay, Is.EqualTo(0)); + Assert.That(screen.Texture, Is.EqualTo("letterbox")); + } } \ No newline at end of file