Parse camera, model and screen effects

This commit is contained in:
Ammar Askar 2023-08-02 00:28:55 -04:00
parent 7c26ee3774
commit d2a8a78f85
10 changed files with 211 additions and 30 deletions

View file

@ -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;
}
}
}

View file

@ -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;
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c1c744d947d84c39847bdf44d41d20b9
timeCreated: 1690949107

View file

@ -0,0 +1,25 @@
using UnityEngine;
namespace OpenTS2.Content.DBPF.Effects
{
/// <summary>
/// Applies a texture across the whole screen.
/// </summary>
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;
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 587e1275af1244429c88255c36177d93
timeCreated: 1690949796

View file

@ -0,0 +1,7 @@
namespace OpenTS2.Content.DBPF.Effects
{
public readonly struct WaterEffect : IBaseEffect
{
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 522d917d07bb4397bab90c351a3771eb
timeCreated: 1690950298

View file

@ -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;
}
}
}

View file

@ -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);
}
}
}

View file

@ -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<EffectsAsset>(new ResourceKey(instanceID: 1, groupID: GroupIDs.Effects, typeID: TypeIDs.EFFECTS));
}
[Test]
public void TestSuccessfullyLoadsAndHasCorrectNumberOfEffects()
{
var effectsAsset = ContentProvider.Get()
.GetAsset<EffectsAsset>(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<EffectsAsset>(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<EffectsAsset>(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<EffectsAsset>(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<EffectsAsset>(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<EffectsAsset>(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"));
}
}