From b7074dc17f2f37c07d2a87fe2f83637f98dc5fd3 Mon Sep 17 00:00:00 2001 From: lahm86 <33758420+lahm86@users.noreply.github.com> Date: Mon, 15 Apr 2024 07:23:14 +0100 Subject: [PATCH] Refactor animation collections (#616) Converts all animation and model arrays to lists. Part of #468. --- .../Models/EMModelExistsCondition.cs | 6 +- .../Models/EMUnconditionalBirdCheck.cs | 2 +- .../Model/Types/Mirroring/EMMirrorFunction.cs | 2 +- .../Types/Models/EMConvertModelFunction.cs | 6 +- .../EMImportNonGraphicsModelFunction.cs | 4 +- TRLevelControl/Control/TR1LevelControl.cs | 72 ++++++++-------- TRLevelControl/Control/TR2LevelControl.cs | 72 ++++++++-------- TRLevelControl/Control/TR3LevelControl.cs | 72 ++++++++-------- TRLevelControl/Helpers/TRMeshUtilities.cs | 34 +++----- TRLevelControl/Model/Base/TR1Level.cs | 76 ++--------------- TRLevelControl/Model/TR2/TR2Level.cs | 76 ++--------------- TRLevelControl/Model/TR3/TR3Level.cs | 76 ++--------------- TRLevelControl/Model/TR4/TR4LevelDataChunk.cs | 55 ++++--------- TRLevelControl/Model/TR5/TR5LevelDataChunk.cs | 55 ++++--------- TRLevelControl/TR4FileReadUtilities.cs | 58 +++++++------ TRLevelControl/TR5FileReadUtilities.cs | 58 +++++++------ .../DataControls/TR/TRAnimationControl.cs | 12 +-- .../DataControls/TR/TRModelControl.cs | 2 +- .../Animations/AnimationTransportHandler.cs | 51 ++---------- .../Handlers/Animations/AnimationUtilities.cs | 80 +++++++----------- .../Handlers/ModelTransportHandler.cs | 33 +++----- .../Textures/TR2/TR2TextureImportHandler.cs | 2 +- .../Transport/TR1/TR1ModelExporter.cs | 82 +++++++------------ .../Transport/TR1/TR1ModelImporter.cs | 4 +- .../Transport/TR2/TR2ModelImporter.cs | 4 +- .../Transport/TR3/TR3ModelImporter.cs | 4 +- TRRandomizerCore/Levels/TR1CombinedLevel.cs | 8 +- TRRandomizerCore/Levels/TR3CombinedLevel.cs | 8 +- .../Processors/TR3/TR3SequenceProcessor.cs | 9 +- .../Randomizers/TR1/TR1EnemyRandomizer.cs | 24 ++---- .../Randomizers/TR1/TR1OutfitRandomizer.cs | 11 +-- .../Randomizers/TR1/TR1SecretRandomizer.cs | 10 +-- .../Randomizers/TR2/TR2EnemyRandomizer.cs | 14 ++-- .../Randomizers/TR3/TR3SecretRandomizer.cs | 22 ++--- .../Textures/DynamicTextureBuilder.cs | 6 +- .../Wireframing/AbstractTRWireframer.cs | 2 +- .../Textures/Wireframing/TR1Wireframer.cs | 2 +- .../Textures/Wireframing/TR2Wireframer.cs | 4 +- .../Textures/Wireframing/TR3Wireframer.cs | 4 +- .../Utilities/TR1EnemyUtilities.cs | 2 +- 40 files changed, 358 insertions(+), 766 deletions(-) diff --git a/TREnvironmentEditor/Model/Conditions/Models/EMModelExistsCondition.cs b/TREnvironmentEditor/Model/Conditions/Models/EMModelExistsCondition.cs index 30dab7824..a5169fc8a 100644 --- a/TREnvironmentEditor/Model/Conditions/Models/EMModelExistsCondition.cs +++ b/TREnvironmentEditor/Model/Conditions/Models/EMModelExistsCondition.cs @@ -8,19 +8,19 @@ public class EMModelExistsCondition : BaseEMCondition protected override bool Evaluate(TR1Level level) { - TRModel model = level.Models.ToList().Find(m => m.ID == ModelID); + TRModel model = level.Models.Find(m => m.ID == ModelID); return model != null; } protected override bool Evaluate(TR2Level level) { - TRModel model = level.Models.ToList().Find(m => m.ID == ModelID); + TRModel model = level.Models.Find(m => m.ID == ModelID); return model != null; } protected override bool Evaluate(TR3Level level) { - TRModel model = level.Models.ToList().Find(m => m.ID == ModelID); + TRModel model = level.Models.Find(m => m.ID == ModelID); return model != null; } } diff --git a/TREnvironmentEditor/Model/Conditions/Models/EMUnconditionalBirdCheck.cs b/TREnvironmentEditor/Model/Conditions/Models/EMUnconditionalBirdCheck.cs index 57892a94a..f8f7ac2de 100644 --- a/TREnvironmentEditor/Model/Conditions/Models/EMUnconditionalBirdCheck.cs +++ b/TREnvironmentEditor/Model/Conditions/Models/EMUnconditionalBirdCheck.cs @@ -11,7 +11,7 @@ protected override bool Evaluate(TR1Level level) protected override bool Evaluate(TR2Level level) { - TRModel model = Array.Find(level.Models, m => m.ID == (uint)TR2Type.BirdMonster); + TRModel model = level.Models.Find(m => m.ID == (uint)TR2Type.BirdMonster); if (model != null) { return level.Animations[model.Animation + 20].FrameEnd == level.Animations[model.Animation + 19].FrameEnd; diff --git a/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorFunction.cs b/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorFunction.cs index 40ef36495..36d3c72dd 100644 --- a/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorFunction.cs +++ b/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorFunction.cs @@ -1263,7 +1263,7 @@ private static void MirrorObjectTextures(ISet textureReferences, TRObjec } } - private static void MirrorDependentFaces(TRModel[] models, ISet textureReferences, Func meshAction) + private static void MirrorDependentFaces(IEnumerable models, ISet textureReferences, Func meshAction) { foreach (TRModel model in models) { diff --git a/TREnvironmentEditor/Model/Types/Models/EMConvertModelFunction.cs b/TREnvironmentEditor/Model/Types/Models/EMConvertModelFunction.cs index a234a2912..ab1556580 100644 --- a/TREnvironmentEditor/Model/Types/Models/EMConvertModelFunction.cs +++ b/TREnvironmentEditor/Model/Types/Models/EMConvertModelFunction.cs @@ -25,11 +25,11 @@ public override void ApplyToLevel(TR3Level level) UpdateModelEntities(level.Entities); } - private void ConvertModel(TRModel[] models) + private void ConvertModel(List models) { - if (Array.Find(models, m => m.ID == NewModelID) == null) + if (models.Find(m => m.ID == NewModelID) == null) { - TRModel oldModel = Array.Find(models, m => m.ID == OldModelID); + TRModel oldModel = models.Find(m => m.ID == OldModelID); if (oldModel != null) { oldModel.ID = NewModelID; diff --git a/TREnvironmentEditor/Model/Types/Models/EMImportNonGraphicsModelFunction.cs b/TREnvironmentEditor/Model/Types/Models/EMImportNonGraphicsModelFunction.cs index 5a2930285..a802ad41a 100644 --- a/TREnvironmentEditor/Model/Types/Models/EMImportNonGraphicsModelFunction.cs +++ b/TREnvironmentEditor/Model/Types/Models/EMImportNonGraphicsModelFunction.cs @@ -72,12 +72,12 @@ public override void ApplyToLevel(TR3Level level) RemapFaces(data, level.NumObjectTextures - 1, modelID => TRMeshUtilities.GetModelMeshes(level, (TR3Type)modelID)); } - private List PrepareImportData(TRModel[] existingModels) + private List PrepareImportData(List existingModels) { List importData = new(); foreach (EMMeshTextureData data in Data) { - if (Array.Find(existingModels, m => m.ID == data.ModelID) == null) + if (existingModels.Find(m => m.ID == data.ModelID) == null) { importData.Add(data); } diff --git a/TRLevelControl/Control/TR1LevelControl.cs b/TRLevelControl/Control/TR1LevelControl.cs index e0e26fb8f..b1d977180 100644 --- a/TRLevelControl/Control/TR1LevelControl.cs +++ b/TRLevelControl/Control/TR1LevelControl.cs @@ -130,61 +130,59 @@ protected override void Read(TRLevelReader reader) _level.Meshes = ConstructMeshData(_level.MeshPointers, _level.RawMeshData); //Animations - _level.NumAnimations = reader.ReadUInt32(); - _level.Animations = new TRAnimation[_level.NumAnimations]; - for (int i = 0; i < _level.NumAnimations; i++) + uint numAnimations = reader.ReadUInt32(); + _level.Animations = new(); + for (int i = 0; i < numAnimations; i++) { - _level.Animations[i] = TR2FileReadUtilities.ReadAnimation(reader); + _level.Animations.Add(TR2FileReadUtilities.ReadAnimation(reader)); } //State Changes - _level.NumStateChanges = reader.ReadUInt32(); - _level.StateChanges = new TRStateChange[_level.NumStateChanges]; - for (int i = 0; i < _level.NumStateChanges; i++) + uint numStateChanges = reader.ReadUInt32(); + _level.StateChanges = new(); + for (int i = 0; i < numStateChanges; i++) { - _level.StateChanges[i] = TR2FileReadUtilities.ReadStateChange(reader); + _level.StateChanges.Add(TR2FileReadUtilities.ReadStateChange(reader)); } //Animation Dispatches - _level.NumAnimDispatches = reader.ReadUInt32(); - _level.AnimDispatches = new TRAnimDispatch[_level.NumAnimDispatches]; - for (int i = 0; i < _level.NumAnimDispatches; i++) + uint numAnimDispatches = reader.ReadUInt32(); + _level.AnimDispatches = new(); + for (int i = 0; i < numAnimDispatches; i++) { - _level.AnimDispatches[i] = TR2FileReadUtilities.ReadAnimDispatch(reader); + _level.AnimDispatches.Add(TR2FileReadUtilities.ReadAnimDispatch(reader)); } //Animation Commands - _level.NumAnimCommands = reader.ReadUInt32(); - _level.AnimCommands = new TRAnimCommand[_level.NumAnimCommands]; - for (int i = 0; i < _level.NumAnimCommands; i++) + uint numAnimCommands = reader.ReadUInt32(); + _level.AnimCommands = new(); + for (int i = 0; i < numAnimCommands; i++) { - _level.AnimCommands[i] = TR2FileReadUtilities.ReadAnimCommand(reader); + _level.AnimCommands.Add(TR2FileReadUtilities.ReadAnimCommand(reader)); } //Mesh Trees - _level.NumMeshTrees = reader.ReadUInt32(); - _level.NumMeshTrees /= 4; - _level.MeshTrees = new TRMeshTreeNode[_level.NumMeshTrees]; - for (int i = 0; i < _level.NumMeshTrees; i++) + uint numMeshTrees = reader.ReadUInt32() / 4; + _level.MeshTrees = new(); + for (int i = 0; i < numMeshTrees; i++) { - _level.MeshTrees[i] = TR2FileReadUtilities.ReadMeshTreeNode(reader); + _level.MeshTrees.Add(TR2FileReadUtilities.ReadMeshTreeNode(reader)); } //Frames - _level.NumFrames = reader.ReadUInt32(); - _level.Frames = new ushort[_level.NumFrames]; - for (int i = 0; i < _level.NumFrames; i++) + uint numFrames = reader.ReadUInt32(); + _level.Frames = new(); + for (int i = 0; i < numFrames; i++) { - _level.Frames[i] = reader.ReadUInt16(); + _level.Frames.Add(reader.ReadUInt16()); } //Models - _level.NumModels = reader.ReadUInt32(); - _level.Models = new TRModel[_level.NumModels]; - - for (int i = 0; i < _level.NumModels; i++) + uint numModels = reader.ReadUInt32(); + _level.Models = new(); + for (int i = 0; i < numModels; i++) { - _level.Models[i] = TR2FileReadUtilities.ReadModel(reader); + _level.Models.Add(TR2FileReadUtilities.ReadModel(reader)); } //Static Meshes @@ -352,20 +350,20 @@ protected override void Write(TRLevelWriter writer) writer.Write(_level.NumMeshPointers); foreach (uint ptr in _level.MeshPointers) { writer.Write(ptr); } - writer.Write(_level.NumAnimations); + writer.Write((uint)_level.Animations.Count); foreach (TRAnimation anim in _level.Animations) { writer.Write(anim.Serialize()); } - writer.Write(_level.NumStateChanges); + writer.Write((uint)_level.StateChanges.Count); foreach (TRStateChange statec in _level.StateChanges) { writer.Write(statec.Serialize()); } - writer.Write(_level.NumAnimDispatches); + writer.Write((uint)_level.AnimDispatches.Count); foreach (TRAnimDispatch dispatch in _level.AnimDispatches) { writer.Write(dispatch.Serialize()); } - writer.Write(_level.NumAnimCommands); + writer.Write((uint)_level.AnimCommands.Count); foreach (TRAnimCommand cmd in _level.AnimCommands) { writer.Write(cmd.Serialize()); } - writer.Write(_level.NumMeshTrees * 4); //To get the correct number /= 4 is done during read, make sure to reverse it here. + writer.Write((uint)(_level.MeshTrees.Count * 4)); //To get the correct number /= 4 is done during read, make sure to reverse it here. foreach (TRMeshTreeNode node in _level.MeshTrees) { writer.Write(node.Serialize()); } - writer.Write(_level.NumFrames); + writer.Write((uint)_level.Frames.Count); foreach (ushort frame in _level.Frames) { writer.Write(frame); } - writer.Write(_level.NumModels); + writer.Write((uint)_level.Models.Count); foreach (TRModel model in _level.Models) { writer.Write(model.Serialize()); } writer.Write(_level.NumStaticMeshes); foreach (TRStaticMesh mesh in _level.StaticMeshes) { writer.Write(mesh.Serialize()); } diff --git a/TRLevelControl/Control/TR2LevelControl.cs b/TRLevelControl/Control/TR2LevelControl.cs index c40fcb0f9..f64766ee2 100644 --- a/TRLevelControl/Control/TR2LevelControl.cs +++ b/TRLevelControl/Control/TR2LevelControl.cs @@ -137,61 +137,59 @@ protected override void Read(TRLevelReader reader) _level.Meshes = ConstructMeshData(_level.MeshPointers, _level.RawMeshData); //Animations - _level.NumAnimations = reader.ReadUInt32(); - _level.Animations = new TRAnimation[_level.NumAnimations]; - for (int i = 0; i < _level.NumAnimations; i++) + uint numAnimations = reader.ReadUInt32(); + _level.Animations = new(); + for (int i = 0; i < numAnimations; i++) { - _level.Animations[i] = TR2FileReadUtilities.ReadAnimation(reader); + _level.Animations.Add(TR2FileReadUtilities.ReadAnimation(reader)); } //State Changes - _level.NumStateChanges = reader.ReadUInt32(); - _level.StateChanges = new TRStateChange[_level.NumStateChanges]; - for (int i = 0; i < _level.NumStateChanges; i++) + uint numStateChanges = reader.ReadUInt32(); + _level.StateChanges = new(); + for (int i = 0; i < numStateChanges; i++) { - _level.StateChanges[i] = TR2FileReadUtilities.ReadStateChange(reader); + _level.StateChanges.Add(TR2FileReadUtilities.ReadStateChange(reader)); } //Animation Dispatches - _level.NumAnimDispatches = reader.ReadUInt32(); - _level.AnimDispatches = new TRAnimDispatch[_level.NumAnimDispatches]; - for (int i = 0; i < _level.NumAnimDispatches; i++) + uint numAnimDispatches = reader.ReadUInt32(); + _level.AnimDispatches = new(); + for (int i = 0; i < numAnimDispatches; i++) { - _level.AnimDispatches[i] = TR2FileReadUtilities.ReadAnimDispatch(reader); + _level.AnimDispatches.Add(TR2FileReadUtilities.ReadAnimDispatch(reader)); } //Animation Commands - _level.NumAnimCommands = reader.ReadUInt32(); - _level.AnimCommands = new TRAnimCommand[_level.NumAnimCommands]; - for (int i = 0; i < _level.NumAnimCommands; i++) + uint numAnimCommands = reader.ReadUInt32(); + _level.AnimCommands = new(); + for (int i = 0; i < numAnimCommands; i++) { - _level.AnimCommands[i] = TR2FileReadUtilities.ReadAnimCommand(reader); + _level.AnimCommands.Add(TR2FileReadUtilities.ReadAnimCommand(reader)); } //Mesh Trees - _level.NumMeshTrees = reader.ReadUInt32(); - _level.NumMeshTrees /= 4; - _level.MeshTrees = new TRMeshTreeNode[_level.NumMeshTrees]; - for (int i = 0; i < _level.NumMeshTrees; i++) + uint numMeshTrees = reader.ReadUInt32() / 4; + _level.MeshTrees = new(); + for (int i = 0; i < numMeshTrees; i++) { - _level.MeshTrees[i] = TR2FileReadUtilities.ReadMeshTreeNode(reader); + _level.MeshTrees.Add(TR2FileReadUtilities.ReadMeshTreeNode(reader)); } //Frames - _level.NumFrames = reader.ReadUInt32(); - _level.Frames = new ushort[_level.NumFrames]; - for (int i = 0; i < _level.NumFrames; i++) + uint numFrames = reader.ReadUInt32(); + _level.Frames = new(); + for (int i = 0; i < numFrames; i++) { - _level.Frames[i] = reader.ReadUInt16(); + _level.Frames.Add(reader.ReadUInt16()); } //Models - _level.NumModels = reader.ReadUInt32(); - _level.Models = new TRModel[_level.NumModels]; - - for (int i = 0; i < _level.NumModels; i++) + uint numModels = reader.ReadUInt32(); + _level.Models = new(); + for (int i = 0; i < numModels; i++) { - _level.Models[i] = TR2FileReadUtilities.ReadModel(reader); + _level.Models.Add(TR2FileReadUtilities.ReadModel(reader)); } //Static Meshes @@ -360,20 +358,20 @@ protected override void Write(TRLevelWriter writer) writer.Write(_level.NumMeshPointers); foreach (uint ptr in _level.MeshPointers) { writer.Write(ptr); } - writer.Write(_level.NumAnimations); + writer.Write((uint)_level.Animations.Count); foreach (TRAnimation anim in _level.Animations) { writer.Write(anim.Serialize()); } - writer.Write(_level.NumStateChanges); + writer.Write((uint)_level.StateChanges.Count); foreach (TRStateChange statec in _level.StateChanges) { writer.Write(statec.Serialize()); } - writer.Write(_level.NumAnimDispatches); + writer.Write((uint)_level.AnimDispatches.Count); foreach (TRAnimDispatch dispatch in _level.AnimDispatches) { writer.Write(dispatch.Serialize()); } - writer.Write(_level.NumAnimCommands); + writer.Write((uint)_level.AnimCommands.Count); foreach (TRAnimCommand cmd in _level.AnimCommands) { writer.Write(cmd.Serialize()); } - writer.Write(_level.NumMeshTrees * 4); //To get the correct number /= 4 is done during read, make sure to reverse it here. + writer.Write((uint)_level.MeshTrees.Count * 4); //To get the correct number /= 4 is done during read, make sure to reverse it here. foreach (TRMeshTreeNode node in _level.MeshTrees) { writer.Write(node.Serialize()); } - writer.Write(_level.NumFrames); + writer.Write((uint)_level.Frames.Count); foreach (ushort frame in _level.Frames) { writer.Write(frame); } - writer.Write(_level.NumModels); + writer.Write((uint)_level.Models.Count); foreach (TRModel model in _level.Models) { writer.Write(model.Serialize()); } writer.Write(_level.NumStaticMeshes); foreach (TRStaticMesh mesh in _level.StaticMeshes) { writer.Write(mesh.Serialize()); } diff --git a/TRLevelControl/Control/TR3LevelControl.cs b/TRLevelControl/Control/TR3LevelControl.cs index 4b8c0f696..51f8c1984 100644 --- a/TRLevelControl/Control/TR3LevelControl.cs +++ b/TRLevelControl/Control/TR3LevelControl.cs @@ -141,61 +141,59 @@ protected override void Read(TRLevelReader reader) _level.Meshes = ConstructMeshData(_level.MeshPointers, _level.RawMeshData); //Animations - _level.NumAnimations = reader.ReadUInt32(); - _level.Animations = new TRAnimation[_level.NumAnimations]; - for (int i = 0; i < _level.NumAnimations; i++) + uint numAnimations = reader.ReadUInt32(); + _level.Animations = new(); + for (int i = 0; i < numAnimations; i++) { - _level.Animations[i] = TR2FileReadUtilities.ReadAnimation(reader); + _level.Animations.Add(TR2FileReadUtilities.ReadAnimation(reader)); } //State Changes - _level.NumStateChanges = reader.ReadUInt32(); - _level.StateChanges = new TRStateChange[_level.NumStateChanges]; - for (int i = 0; i < _level.NumStateChanges; i++) + uint numStateChanges = reader.ReadUInt32(); + _level.StateChanges = new(); + for (int i = 0; i < numStateChanges; i++) { - _level.StateChanges[i] = TR2FileReadUtilities.ReadStateChange(reader); + _level.StateChanges.Add(TR2FileReadUtilities.ReadStateChange(reader)); } //Animation Dispatches - _level.NumAnimDispatches = reader.ReadUInt32(); - _level.AnimDispatches = new TRAnimDispatch[_level.NumAnimDispatches]; - for (int i = 0; i < _level.NumAnimDispatches; i++) + uint numAnimDispatches = reader.ReadUInt32(); + _level.AnimDispatches = new(); + for (int i = 0; i < numAnimDispatches; i++) { - _level.AnimDispatches[i] = TR2FileReadUtilities.ReadAnimDispatch(reader); + _level.AnimDispatches.Add(TR2FileReadUtilities.ReadAnimDispatch(reader)); } //Animation Commands - _level.NumAnimCommands = reader.ReadUInt32(); - _level.AnimCommands = new TRAnimCommand[_level.NumAnimCommands]; - for (int i = 0; i < _level.NumAnimCommands; i++) + uint numAnimCommands = reader.ReadUInt32(); + _level.AnimCommands = new(); + for (int i = 0; i < numAnimCommands; i++) { - _level.AnimCommands[i] = TR2FileReadUtilities.ReadAnimCommand(reader); + _level.AnimCommands.Add(TR2FileReadUtilities.ReadAnimCommand(reader)); } //Mesh Trees - _level.NumMeshTrees = reader.ReadUInt32(); - _level.NumMeshTrees /= 4; - _level.MeshTrees = new TRMeshTreeNode[_level.NumMeshTrees]; - for (int i = 0; i < _level.NumMeshTrees; i++) + uint numMeshTrees = reader.ReadUInt32() / 4; + _level.MeshTrees = new(); + for (int i = 0; i < numMeshTrees; i++) { - _level.MeshTrees[i] = TR2FileReadUtilities.ReadMeshTreeNode(reader); + _level.MeshTrees.Add(TR2FileReadUtilities.ReadMeshTreeNode(reader)); } //Frames - _level.NumFrames = reader.ReadUInt32(); - _level.Frames = new ushort[_level.NumFrames]; - for (int i = 0; i < _level.NumFrames; i++) + uint numFrames = reader.ReadUInt32(); + _level.Frames = new(); + for (int i = 0; i < numFrames; i++) { - _level.Frames[i] = reader.ReadUInt16(); + _level.Frames.Add(reader.ReadUInt16()); } //Models - _level.NumModels = reader.ReadUInt32(); - _level.Models = new TRModel[_level.NumModels]; - - for (int i = 0; i < _level.NumModels; i++) + uint numModels = reader.ReadUInt32(); + _level.Models = new(); + for (int i = 0; i < numModels; i++) { - _level.Models[i] = TR2FileReadUtilities.ReadModel(reader); + _level.Models.Add(TR2FileReadUtilities.ReadModel(reader)); } //Static Meshes @@ -362,20 +360,20 @@ protected override void Write(TRLevelWriter writer) writer.Write(_level.NumMeshPointers); foreach (uint ptr in _level.MeshPointers) { writer.Write(ptr); } - writer.Write(_level.NumAnimations); + writer.Write((uint)_level.Animations.Count); foreach (TRAnimation anim in _level.Animations) { writer.Write(anim.Serialize()); } - writer.Write(_level.NumStateChanges); + writer.Write((uint)_level.StateChanges.Count); foreach (TRStateChange statec in _level.StateChanges) { writer.Write(statec.Serialize()); } - writer.Write(_level.NumAnimDispatches); + writer.Write((uint)_level.AnimDispatches.Count); foreach (TRAnimDispatch dispatch in _level.AnimDispatches) { writer.Write(dispatch.Serialize()); } - writer.Write(_level.NumAnimCommands); + writer.Write((uint)_level.AnimCommands.Count); foreach (TRAnimCommand cmd in _level.AnimCommands) { writer.Write(cmd.Serialize()); } - writer.Write(_level.NumMeshTrees * 4); //To get the correct number /= 4 is done during read, make sure to reverse it here. + writer.Write((uint)_level.MeshTrees.Count * 4); //To get the correct number /= 4 is done during read, make sure to reverse it here. foreach (TRMeshTreeNode node in _level.MeshTrees) { writer.Write(node.Serialize()); } - writer.Write(_level.NumFrames); + writer.Write((uint)_level.Frames.Count); foreach (ushort frame in _level.Frames) { writer.Write(frame); } - writer.Write(_level.NumModels); + writer.Write((uint)_level.Models.Count); foreach (TRModel model in _level.Models) { writer.Write(model.Serialize()); } writer.Write(_level.NumStaticMeshes); foreach (TRStaticMesh mesh in _level.StaticMeshes) { writer.Write(mesh.Serialize()); } diff --git a/TRLevelControl/Helpers/TRMeshUtilities.cs b/TRLevelControl/Helpers/TRMeshUtilities.cs index 73d9ec86e..3c24a6a9b 100644 --- a/TRLevelControl/Helpers/TRMeshUtilities.cs +++ b/TRLevelControl/Helpers/TRMeshUtilities.cs @@ -6,7 +6,7 @@ public static class TRMeshUtilities { public static TRMesh GetModelFirstMesh(TR1Level level, TR1Type entity) { - TRModel model = level.Models.ToList().Find(e => e.ID == (uint)entity); + TRModel model = level.Models.Find(e => e.ID == (uint)entity); if (model != null) { return GetModelFirstMesh(level, model); @@ -16,7 +16,7 @@ public static TRMesh GetModelFirstMesh(TR1Level level, TR1Type entity) public static TRMesh GetModelFirstMesh(TR2Level level, TR2Type entity) { - TRModel model = level.Models.ToList().Find(e => e.ID == (uint)entity); + TRModel model = level.Models.Find(e => e.ID == (uint)entity); if (model != null) { return GetModelFirstMesh(level, model); @@ -26,7 +26,7 @@ public static TRMesh GetModelFirstMesh(TR2Level level, TR2Type entity) public static TRMesh GetModelFirstMesh(TR3Level level, TR3Type entity) { - TRModel model = level.Models.ToList().Find(e => e.ID == (uint)entity); + TRModel model = level.Models.Find(e => e.ID == (uint)entity); if (model != null) { return GetModelFirstMesh(level, model); @@ -149,14 +149,14 @@ public static TRMeshTreeNode[] GetModelMeshTrees(TR3Level level, TRModel model) return GetModelMeshTrees(level.MeshTrees, model); } - public static TRMeshTreeNode[] GetModelMeshTrees(TRMeshTreeNode[] meshTrees, TRModel model) + public static TRMeshTreeNode[] GetModelMeshTrees(List meshTrees, TRModel model) { List nodes = new(); int index = (int)model.MeshTree / 4; for (int i = 0; i < model.NumMeshes; i++) { int offset = index + i; - if (offset < meshTrees.Length) + if (offset < meshTrees.Count) { nodes.Add(meshTrees[offset]); } @@ -412,31 +412,19 @@ public static void UpdateMeshPointers(TR3Level level, TRMesh modifiedMesh, int p /// public static int InsertMeshTreeNode(TR1Level level, TRMeshTreeNode newNode) { - List nodes = level.MeshTrees.ToList(); - nodes.Add(newNode); - level.MeshTrees = nodes.ToArray(); - level.NumMeshTrees++; - - return level.MeshTrees.Length - 1; + level.MeshTrees.Add(newNode); + return level.MeshTrees.Count - 1; } public static int InsertMeshTreeNode(TR2Level level, TRMeshTreeNode newNode) { - List nodes = level.MeshTrees.ToList(); - nodes.Add(newNode); - level.MeshTrees = nodes.ToArray(); - level.NumMeshTrees++; - - return level.MeshTrees.Length - 1; + level.MeshTrees.Add(newNode); + return level.MeshTrees.Count - 1; } public static int InsertMeshTreeNode(TR3Level level, TRMeshTreeNode newNode) { - List nodes = level.MeshTrees.ToList(); - nodes.Add(newNode); - level.MeshTrees = nodes.ToArray(); - level.NumMeshTrees++; - - return level.MeshTrees.Length - 1; + level.MeshTrees.Add(newNode); + return level.MeshTrees.Count - 1; } } diff --git a/TRLevelControl/Model/Base/TR1Level.cs b/TRLevelControl/Model/Base/TR1Level.cs index 980b3f45f..42fb8000f 100644 --- a/TRLevelControl/Model/Base/TR1Level.cs +++ b/TRLevelControl/Model/Base/TR1Level.cs @@ -54,75 +54,13 @@ public class TR1Level : TRLevelBase /// public uint[] MeshPointers { get; set; } - /// - /// 4 bytes - /// - public uint NumAnimations { get; set; } - - /// - /// NumAnimations * 32 bytes - /// - public TRAnimation[] Animations { get; set; } - - /// - /// 4 bytes - /// - public uint NumStateChanges { get; set; } - - /// - /// NumStateChanges * 6 bytes - /// - public TRStateChange[] StateChanges { get; set; } - - /// - /// 4 bytes - /// - public uint NumAnimDispatches { get; set; } - - /// - /// NumAnimDispatches * 8 bytes - /// - public TRAnimDispatch[] AnimDispatches { get; set; } - - /// - /// 4 bytes - /// - public uint NumAnimCommands { get; set; } - - /// - /// NumAnimCommands * 2 bytes - /// - public TRAnimCommand[] AnimCommands { get; set; } - - /// - /// 4 bytes - /// - public uint NumMeshTrees { get; set; } - - /// - /// NumMeshTrees * 4 bytes - /// - public TRMeshTreeNode[] MeshTrees { get; set; } - - /// - /// 4 bytes - /// - public uint NumFrames { get; set; } - - /// - /// NumFrames * 2 bytes - /// - public ushort[] Frames { get; set; } - - /// - /// 4 bytes - /// - public uint NumModels { get; set; } - - /// - /// NumModels * 18 bytes - /// - public TRModel[] Models { get; set; } + public List Animations { get; set; } + public List StateChanges { get; set; } + public List AnimDispatches { get; set; } + public List AnimCommands { get; set; } + public List MeshTrees { get; set; } + public List Frames { get; set; } + public List Models { get; set; } /// /// 4 bytes diff --git a/TRLevelControl/Model/TR2/TR2Level.cs b/TRLevelControl/Model/TR2/TR2Level.cs index 28a9b4f4b..db547ea3c 100644 --- a/TRLevelControl/Model/TR2/TR2Level.cs +++ b/TRLevelControl/Model/TR2/TR2Level.cs @@ -57,75 +57,13 @@ public class TR2Level : TRLevelBase /// public uint[] MeshPointers { get; set; } - /// - /// 4 bytes - /// - public uint NumAnimations { get; set; } - - /// - /// NumAnimations * 32 bytes - /// - public TRAnimation[] Animations { get; set; } - - /// - /// 4 bytes - /// - public uint NumStateChanges { get; set; } - - /// - /// NumStateChanges * 6 bytes - /// - public TRStateChange[] StateChanges { get; set; } - - /// - /// 4 bytes - /// - public uint NumAnimDispatches { get; set; } - - /// - /// NumAnimDispatches * 8 bytes - /// - public TRAnimDispatch[] AnimDispatches { get; set; } - - /// - /// 4 bytes - /// - public uint NumAnimCommands { get; set; } - - /// - /// NumAnimCommands * 2 bytes - /// - public TRAnimCommand[] AnimCommands { get; set; } - - /// - /// 4 bytes - /// - public uint NumMeshTrees { get; set; } - - /// - /// NumMeshTrees * 4 bytes - /// - public TRMeshTreeNode[] MeshTrees { get; set; } - - /// - /// 4 bytes - /// - public uint NumFrames { get; set; } - - /// - /// NumFrames * 2 bytes - /// - public ushort[] Frames { get; set; } - - /// - /// 4 bytes - /// - public uint NumModels { get; set; } - - /// - /// NumModels * 18 bytes - /// - public TRModel[] Models { get; set; } + public List Animations { get; set; } + public List StateChanges { get; set; } + public List AnimDispatches { get; set; } + public List AnimCommands { get; set; } + public List MeshTrees { get; set; } + public List Frames { get; set; } + public List Models { get; set; } /// /// 4 bytes diff --git a/TRLevelControl/Model/TR3/TR3Level.cs b/TRLevelControl/Model/TR3/TR3Level.cs index 71239b388..74d751357 100644 --- a/TRLevelControl/Model/TR3/TR3Level.cs +++ b/TRLevelControl/Model/TR3/TR3Level.cs @@ -57,75 +57,13 @@ public class TR3Level : TRLevelBase /// public uint[] MeshPointers { get; set; } - /// - /// 4 bytes - /// - public uint NumAnimations { get; set; } - - /// - /// NumAnimations * 32 bytes - /// - public TRAnimation[] Animations { get; set; } - - /// - /// 4 bytes - /// - public uint NumStateChanges { get; set; } - - /// - /// NumStateChanges * 6 bytes - /// - public TRStateChange[] StateChanges { get; set; } - - /// - /// 4 bytes - /// - public uint NumAnimDispatches { get; set; } - - /// - /// NumAnimDispatches * 8 bytes - /// - public TRAnimDispatch[] AnimDispatches { get; set; } - - /// - /// 4 bytes - /// - public uint NumAnimCommands { get; set; } - - /// - /// NumAnimCommands * 2 bytes - /// - public TRAnimCommand[] AnimCommands { get; set; } - - /// - /// 4 bytes - /// - public uint NumMeshTrees { get; set; } - - /// - /// NumMeshTrees * 4 bytes - /// - public TRMeshTreeNode[] MeshTrees { get; set; } - - /// - /// 4 bytes - /// - public uint NumFrames { get; set; } - - /// - /// NumFrames * 2 bytes - /// - public ushort[] Frames { get; set; } - - /// - /// 4 bytes - /// - public uint NumModels { get; set; } - - /// - /// NumModels * 18 bytes - /// - public TRModel[] Models { get; set; } + public List Animations { get; set; } + public List StateChanges { get; set; } + public List AnimDispatches { get; set; } + public List AnimCommands { get; set; } + public List MeshTrees { get; set; } + public List Frames { get; set; } + public List Models { get; set; } /// /// 4 bytes diff --git a/TRLevelControl/Model/TR4/TR4LevelDataChunk.cs b/TRLevelControl/Model/TR4/TR4LevelDataChunk.cs index c557ad6ef..a60a13730 100644 --- a/TRLevelControl/Model/TR4/TR4LevelDataChunk.cs +++ b/TRLevelControl/Model/TR4/TR4LevelDataChunk.cs @@ -29,33 +29,13 @@ public class TR4LevelDataChunk : ISerializableCompact public uint[] MeshPointers { get; set; } - public uint NumAnimations { get; set; } - - public TR4Animation[] Animations { get; set; } - - public uint NumStateChanges { get; set; } - - public TRStateChange[] StateChanges { get; set; } - - public uint NumAnimDispatches { get; set; } - - public TRAnimDispatch[] AnimDispatches { get; set; } - - public uint NumAnimCommands { get; set; } - - public TRAnimCommand[] AnimCommands { get; set; } - - public uint NumMeshTrees { get; set; } - - public TRMeshTreeNode[] MeshTrees { get; set; } - - public uint NumFrames { get; set; } - - public ushort[] Frames { get; set; } - - public uint NumModels { get; set; } - - public TRModel[] Models { get; set; } + public List Animations { get; set; } + public List StateChanges { get; set; } + public List AnimDispatches { get; set; } + public List AnimCommands { get; set; } + public List MeshTrees { get; set; } + public List Frames { get; set; } + public List Models { get; set; } public uint NumStaticMeshes { get; set; } @@ -160,50 +140,43 @@ public byte[] Serialize() writer.Write(data); } - writer.Write(NumAnimations); - + writer.Write((uint)Animations.Count); foreach (TR4Animation anim in Animations) { writer.Write(anim.Serialize()); } - writer.Write(NumStateChanges); - + writer.Write((uint)StateChanges.Count); foreach (TRStateChange sc in StateChanges) { writer.Write(sc.Serialize()); } - writer.Write(NumAnimDispatches); - + writer.Write((uint)AnimDispatches.Count); foreach (TRAnimDispatch ad in AnimDispatches) { writer.Write(ad.Serialize()); } - writer.Write(NumAnimCommands); - + writer.Write((uint)AnimCommands.Count); foreach (TRAnimCommand ac in AnimCommands) { writer.Write(ac.Serialize()); } - writer.Write(NumMeshTrees * 4); //To get the correct number /= 4 is done during read, make sure to reverse it here. - + writer.Write((uint)MeshTrees.Count * 4); //To get the correct number /= 4 is done during read, make sure to reverse it here. foreach (TRMeshTreeNode node in MeshTrees) { writer.Write(node.Serialize()); } - writer.Write(NumFrames); - + writer.Write((uint)Frames.Count); foreach (ushort frame in Frames) { writer.Write(frame); } - writer.Write(NumModels); - + writer.Write((uint)Models.Count); foreach (TRModel model in Models) { writer.Write(model.Serialize()); diff --git a/TRLevelControl/Model/TR5/TR5LevelDataChunk.cs b/TRLevelControl/Model/TR5/TR5LevelDataChunk.cs index 16ea02968..8e6ea1a36 100644 --- a/TRLevelControl/Model/TR5/TR5LevelDataChunk.cs +++ b/TRLevelControl/Model/TR5/TR5LevelDataChunk.cs @@ -28,33 +28,13 @@ public class TR5LevelDataChunk public uint[] MeshPointers { get; set; } - public uint NumAnimations { get; set; } - - public TR4Animation[] Animations { get; set; } - - public uint NumStateChanges { get; set; } - - public TRStateChange[] StateChanges { get; set; } - - public uint NumAnimDispatches { get; set; } - - public TRAnimDispatch[] AnimDispatches { get; set; } - - public uint NumAnimCommands { get; set; } - - public TRAnimCommand[] AnimCommands { get; set; } - - public uint NumMeshTrees { get; set; } - - public TRMeshTreeNode[] MeshTrees { get; set; } - - public uint NumFrames { get; set; } - - public ushort[] Frames { get; set; } - - public uint NumModels { get; set; } - - public TR5Model[] Models { get; set; } + public List Animations { get; set; } + public List StateChanges { get; set; } + public List AnimDispatches { get; set; } + public List AnimCommands { get; set; } + public List MeshTrees { get; set; } + public List Frames { get; set; } + public List Models { get; set; } public uint NumStaticMeshes { get; set; } @@ -159,50 +139,43 @@ public byte[] Serialize() writer.Write(data); } - writer.Write(NumAnimations); - + writer.Write((uint)Animations.Count); foreach (TR4Animation anim in Animations) { writer.Write(anim.Serialize()); } - writer.Write(NumStateChanges); - + writer.Write((uint)StateChanges.Count); foreach (TRStateChange sc in StateChanges) { writer.Write(sc.Serialize()); } - writer.Write(NumAnimDispatches); - + writer.Write((uint)AnimDispatches.Count); foreach (TRAnimDispatch ad in AnimDispatches) { writer.Write(ad.Serialize()); } - writer.Write(NumAnimCommands); - + writer.Write((uint)AnimCommands.Count); foreach (TRAnimCommand ac in AnimCommands) { writer.Write(ac.Serialize()); } - writer.Write(NumMeshTrees * 4); //To get the correct number /= 4 is done during read, make sure to reverse it here. - + writer.Write((uint)MeshTrees.Count * 4); //To get the correct number /= 4 is done during read, make sure to reverse it here. foreach (TRMeshTreeNode node in MeshTrees) { writer.Write(node.Serialize()); } - writer.Write(NumFrames); - + writer.Write((uint)Frames.Count); foreach (ushort frame in Frames) { writer.Write(frame); } - writer.Write(NumModels); - + writer.Write((uint)Models.Count); foreach (TR5Model model in Models) { writer.Write(model.Serialize()); diff --git a/TRLevelControl/TR4FileReadUtilities.cs b/TRLevelControl/TR4FileReadUtilities.cs index 21ecb20f8..e42222716 100644 --- a/TRLevelControl/TR4FileReadUtilities.cs +++ b/TRLevelControl/TR4FileReadUtilities.cs @@ -123,64 +123,62 @@ public static void PopulateMeshes(BinaryReader reader, TR4Level lvl) public static void PopulateAnimations(BinaryReader reader, TR4Level lvl) { //Animations - lvl.LevelDataChunk.NumAnimations = reader.ReadUInt32(); - lvl.LevelDataChunk.Animations = new TR4Animation[lvl.LevelDataChunk.NumAnimations]; - for (int i = 0; i < lvl.LevelDataChunk.NumAnimations; i++) + uint numAnimations = reader.ReadUInt32(); + lvl.LevelDataChunk.Animations = new(); + for (int i = 0; i < numAnimations; i++) { - lvl.LevelDataChunk.Animations[i] = TR4FileReadUtilities.ReadAnimation(reader); + lvl.LevelDataChunk.Animations.Add(ReadAnimation(reader)); } //State Changes - lvl.LevelDataChunk.NumStateChanges = reader.ReadUInt32(); - lvl.LevelDataChunk.StateChanges = new TRStateChange[lvl.LevelDataChunk.NumStateChanges]; - for (int i = 0; i < lvl.LevelDataChunk.NumStateChanges; i++) + uint numStateChanges = reader.ReadUInt32(); + lvl.LevelDataChunk.StateChanges = new(); + for (int i = 0; i < numStateChanges; i++) { - lvl.LevelDataChunk.StateChanges[i] = TR2FileReadUtilities.ReadStateChange(reader); + lvl.LevelDataChunk.StateChanges.Add(TR2FileReadUtilities.ReadStateChange(reader)); } //Animation Dispatches - lvl.LevelDataChunk.NumAnimDispatches = reader.ReadUInt32(); - lvl.LevelDataChunk.AnimDispatches = new TRAnimDispatch[lvl.LevelDataChunk.NumAnimDispatches]; - for (int i = 0; i < lvl.LevelDataChunk.NumAnimDispatches; i++) + uint numAnimDispatches = reader.ReadUInt32(); + lvl.LevelDataChunk.AnimDispatches = new(); + for (int i = 0; i < numAnimDispatches; i++) { - lvl.LevelDataChunk.AnimDispatches[i] = TR2FileReadUtilities.ReadAnimDispatch(reader); + lvl.LevelDataChunk.AnimDispatches.Add(TR2FileReadUtilities.ReadAnimDispatch(reader)); } //Animation Commands - lvl.LevelDataChunk.NumAnimCommands = reader.ReadUInt32(); - lvl.LevelDataChunk.AnimCommands = new TRAnimCommand[lvl.LevelDataChunk.NumAnimCommands]; - for (int i = 0; i < lvl.LevelDataChunk.NumAnimCommands; i++) + uint numAnimCommands = reader.ReadUInt32(); + lvl.LevelDataChunk.AnimCommands = new(); + for (int i = 0; i < numAnimCommands; i++) { - lvl.LevelDataChunk.AnimCommands[i] = TR2FileReadUtilities.ReadAnimCommand(reader); + lvl.LevelDataChunk.AnimCommands.Add(TR2FileReadUtilities.ReadAnimCommand(reader)); } } public static void PopulateMeshTreesFramesModels(BinaryReader reader, TR4Level lvl) { //Mesh Trees - lvl.LevelDataChunk.NumMeshTrees = reader.ReadUInt32(); - lvl.LevelDataChunk.NumMeshTrees /= 4; - lvl.LevelDataChunk.MeshTrees = new TRMeshTreeNode[lvl.LevelDataChunk.NumMeshTrees]; - for (int i = 0; i < lvl.LevelDataChunk.NumMeshTrees; i++) + uint numMeshTrees = reader.ReadUInt32() / 4; + lvl.LevelDataChunk.MeshTrees = new(); + for (int i = 0; i < numMeshTrees; i++) { - lvl.LevelDataChunk.MeshTrees[i] = TR2FileReadUtilities.ReadMeshTreeNode(reader); + lvl.LevelDataChunk.MeshTrees.Add(TR2FileReadUtilities.ReadMeshTreeNode(reader)); } //Frames - lvl.LevelDataChunk.NumFrames = reader.ReadUInt32(); - lvl.LevelDataChunk.Frames = new ushort[lvl.LevelDataChunk.NumFrames]; - for (int i = 0; i < lvl.LevelDataChunk.NumFrames; i++) + uint numFrames = reader.ReadUInt32(); + lvl.LevelDataChunk.Frames = new(); + for (int i = 0; i < numFrames; i++) { - lvl.LevelDataChunk.Frames[i] = reader.ReadUInt16(); + lvl.LevelDataChunk.Frames.Add(reader.ReadUInt16()); } //Models - lvl.LevelDataChunk.NumModels = reader.ReadUInt32(); - lvl.LevelDataChunk.Models = new TRModel[lvl.LevelDataChunk.NumModels]; - - for (int i = 0; i < lvl.LevelDataChunk.NumModels; i++) + uint numModels = reader.ReadUInt32(); + lvl.LevelDataChunk.Models = new(); + for (int i = 0; i < numModels; i++) { - lvl.LevelDataChunk.Models[i] = TR2FileReadUtilities.ReadModel(reader); + lvl.LevelDataChunk.Models.Add(TR2FileReadUtilities.ReadModel(reader)); } } diff --git a/TRLevelControl/TR5FileReadUtilities.cs b/TRLevelControl/TR5FileReadUtilities.cs index e044c1376..14822eb84 100644 --- a/TRLevelControl/TR5FileReadUtilities.cs +++ b/TRLevelControl/TR5FileReadUtilities.cs @@ -240,64 +240,62 @@ public static void PopulateMeshes(BinaryReader reader, TR5Level lvl) public static void PopulateAnimations(BinaryReader reader, TR5Level lvl) { //Animations - lvl.LevelDataChunk.NumAnimations = reader.ReadUInt32(); - lvl.LevelDataChunk.Animations = new TR4Animation[lvl.LevelDataChunk.NumAnimations]; - for (int i = 0; i < lvl.LevelDataChunk.NumAnimations; i++) + uint numAnimations = reader.ReadUInt32(); + lvl.LevelDataChunk.Animations = new(); + for (int i = 0; i < numAnimations; i++) { - lvl.LevelDataChunk.Animations[i] = TR4FileReadUtilities.ReadAnimation(reader); + lvl.LevelDataChunk.Animations.Add(TR4FileReadUtilities.ReadAnimation(reader)); } //State Changes - lvl.LevelDataChunk.NumStateChanges = reader.ReadUInt32(); - lvl.LevelDataChunk.StateChanges = new TRStateChange[lvl.LevelDataChunk.NumStateChanges]; - for (int i = 0; i < lvl.LevelDataChunk.NumStateChanges; i++) + uint numStateChanges = reader.ReadUInt32(); + lvl.LevelDataChunk.StateChanges = new(); + for (int i = 0; i < numStateChanges; i++) { - lvl.LevelDataChunk.StateChanges[i] = TR2FileReadUtilities.ReadStateChange(reader); + lvl.LevelDataChunk.StateChanges.Add(TR2FileReadUtilities.ReadStateChange(reader)); } //Animation Dispatches - lvl.LevelDataChunk.NumAnimDispatches = reader.ReadUInt32(); - lvl.LevelDataChunk.AnimDispatches = new TRAnimDispatch[lvl.LevelDataChunk.NumAnimDispatches]; - for (int i = 0; i < lvl.LevelDataChunk.NumAnimDispatches; i++) + uint numAnimDispatches = reader.ReadUInt32(); + lvl.LevelDataChunk.AnimDispatches = new(); + for (int i = 0; i < numAnimDispatches; i++) { - lvl.LevelDataChunk.AnimDispatches[i] = TR2FileReadUtilities.ReadAnimDispatch(reader); + lvl.LevelDataChunk.AnimDispatches.Add(TR2FileReadUtilities.ReadAnimDispatch(reader)); } //Animation Commands - lvl.LevelDataChunk.NumAnimCommands = reader.ReadUInt32(); - lvl.LevelDataChunk.AnimCommands = new TRAnimCommand[lvl.LevelDataChunk.NumAnimCommands]; - for (int i = 0; i < lvl.LevelDataChunk.NumAnimCommands; i++) + uint numAnimCommands = reader.ReadUInt32(); + lvl.LevelDataChunk.AnimCommands = new(); + for (int i = 0; i < numAnimCommands; i++) { - lvl.LevelDataChunk.AnimCommands[i] = TR2FileReadUtilities.ReadAnimCommand(reader); + lvl.LevelDataChunk.AnimCommands.Add(TR2FileReadUtilities.ReadAnimCommand(reader)); } } public static void PopulateMeshTreesFramesModels(BinaryReader reader, TR5Level lvl) { //Mesh Trees - lvl.LevelDataChunk.NumMeshTrees = reader.ReadUInt32(); - lvl.LevelDataChunk.NumMeshTrees /= 4; - lvl.LevelDataChunk.MeshTrees = new TRMeshTreeNode[lvl.LevelDataChunk.NumMeshTrees]; - for (int i = 0; i < lvl.LevelDataChunk.NumMeshTrees; i++) + uint numMeshTrees = reader.ReadUInt32() / 4; + lvl.LevelDataChunk.MeshTrees = new(); + for (int i = 0; i < numMeshTrees; i++) { - lvl.LevelDataChunk.MeshTrees[i] = TR2FileReadUtilities.ReadMeshTreeNode(reader); + lvl.LevelDataChunk.MeshTrees.Add(TR2FileReadUtilities.ReadMeshTreeNode(reader)); } //Frames - lvl.LevelDataChunk.NumFrames = reader.ReadUInt32(); - lvl.LevelDataChunk.Frames = new ushort[lvl.LevelDataChunk.NumFrames]; - for (int i = 0; i < lvl.LevelDataChunk.NumFrames; i++) + uint numFrames = reader.ReadUInt32(); + lvl.LevelDataChunk.Frames = new(); + for (int i = 0; i < numFrames; i++) { - lvl.LevelDataChunk.Frames[i] = reader.ReadUInt16(); + lvl.LevelDataChunk.Frames.Add(reader.ReadUInt16()); } //Models - lvl.LevelDataChunk.NumModels = reader.ReadUInt32(); - lvl.LevelDataChunk.Models = new TR5Model[lvl.LevelDataChunk.NumModels]; - - for (int i = 0; i < lvl.LevelDataChunk.NumModels; i++) + uint numModels = reader.ReadUInt32(); + lvl.LevelDataChunk.Models = new(); + for (int i = 0; i < numModels; i++) { - lvl.LevelDataChunk.Models[i] = ReadTR5Model(reader); + lvl.LevelDataChunk.Models.Add(ReadTR5Model(reader)); } } diff --git a/TRLevelToolset/Controls/DataControls/TR/TRAnimationControl.cs b/TRLevelToolset/Controls/DataControls/TR/TRAnimationControl.cs index 4f32271d5..199dfb1a8 100644 --- a/TRLevelToolset/Controls/DataControls/TR/TRAnimationControl.cs +++ b/TRLevelToolset/Controls/DataControls/TR/TRAnimationControl.cs @@ -10,12 +10,12 @@ public void Draw() { if (ImGui.TreeNodeEx("Animations Data", ImGuiTreeNodeFlags.OpenOnArrow)) { - ImGui.Text("Animations count: " + IOManager.CurrentLevelAsTR1?.NumAnimations); - ImGui.Text("State change count: " + IOManager.CurrentLevelAsTR1?.NumStateChanges); - ImGui.Text("Animation dispatch count: " + IOManager.CurrentLevelAsTR1?.NumAnimations); - ImGui.Text("Animation command count: " + IOManager.CurrentLevelAsTR1?.NumAnimCommands); - ImGui.Text("Mesh tree count: " + IOManager.CurrentLevelAsTR1?.NumMeshTrees); - ImGui.Text("Total frames count: " + IOManager.CurrentLevelAsTR1?.NumFrames); + ImGui.Text("Animations count: " + IOManager.CurrentLevelAsTR1?.Animations.Count); + ImGui.Text("State change count: " + IOManager.CurrentLevelAsTR1?.StateChanges.Count); + ImGui.Text("Animation dispatch count: " + IOManager.CurrentLevelAsTR1?.Animations.Count); + ImGui.Text("Animation command count: " + IOManager.CurrentLevelAsTR1?.AnimCommands.Count); + ImGui.Text("Mesh tree count: " + IOManager.CurrentLevelAsTR1?.MeshTrees.Count); + ImGui.Text("Total frames count: " + IOManager.CurrentLevelAsTR1?.Frames.Count); ImGui.TreePop(); } diff --git a/TRLevelToolset/Controls/DataControls/TR/TRModelControl.cs b/TRLevelToolset/Controls/DataControls/TR/TRModelControl.cs index 0c8a23f45..74eb6588e 100644 --- a/TRLevelToolset/Controls/DataControls/TR/TRModelControl.cs +++ b/TRLevelToolset/Controls/DataControls/TR/TRModelControl.cs @@ -10,7 +10,7 @@ public void Draw() { if (ImGui.TreeNodeEx("Model Data", ImGuiTreeNodeFlags.OpenOnArrow)) { - ImGui.Text("Model count: " + IOManager.CurrentLevelAsTR1?.NumModels); + ImGui.Text("Model count: " + IOManager.CurrentLevelAsTR1?.Models.Count); ImGui.TreePop(); } diff --git a/TRModelTransporter/Handlers/Animations/AnimationTransportHandler.cs b/TRModelTransporter/Handlers/Animations/AnimationTransportHandler.cs index f53c57bd9..9978ba767 100644 --- a/TRModelTransporter/Handlers/Animations/AnimationTransportHandler.cs +++ b/TRModelTransporter/Handlers/Animations/AnimationTransportHandler.cs @@ -90,16 +90,12 @@ public static void Import(TR1Level level, TR1ModelDefinition definition) bool firstAnimationConfigured = false; Dictionary indexMap = new(); - List animDispatches = level.AnimDispatches.ToList(); - List stateChanges = level.StateChanges.ToList(); - List animCommands = level.AnimCommands.ToList(); - foreach (int oldAnimationIndex in animations.Keys) { TR1PackedAnimation packedAnimation = animations[oldAnimationIndex]; - AnimationUtilities.UnpackStateChanges(animDispatches, stateChanges, packedAnimation); + AnimationUtilities.UnpackStateChanges(level.AnimDispatches, level.StateChanges, packedAnimation); AnimationUtilities.UnpackAnimSounds(level, packedAnimation); - AnimationUtilities.UnpackAnimCommands(animCommands, packedAnimation); + AnimationUtilities.UnpackAnimCommands(level.AnimCommands, packedAnimation); int newAnimationIndex = AnimationUtilities.UnpackAnimation(level, packedAnimation); indexMap[oldAnimationIndex] = newAnimationIndex; @@ -111,15 +107,6 @@ public static void Import(TR1Level level, TR1ModelDefinition definition) } } - level.AnimDispatches = animDispatches.ToArray(); - level.NumAnimDispatches = (uint)animDispatches.Count; - - level.StateChanges = stateChanges.ToArray(); - level.NumStateChanges = (uint)stateChanges.Count; - - level.AnimCommands = animCommands.ToArray(); - level.NumAnimCommands = (uint)animCommands.Count; - // Re-map the NextAnimations of each of the animation and dispatches // now we know the indices of each of the newly inserted animations. foreach (TR1PackedAnimation packedAnimation in animations.Values) @@ -145,16 +132,12 @@ public static void Import(TR2Level level, TR2ModelDefinition definition) bool firstAnimationConfigured = false; Dictionary indexMap = new(); - List animDispatches = level.AnimDispatches.ToList(); - List stateChanges = level.StateChanges.ToList(); - List animCommands = level.AnimCommands.ToList(); - foreach (int oldAnimationIndex in animations.Keys) { TR2PackedAnimation packedAnimation = animations[oldAnimationIndex]; - AnimationUtilities.UnpackStateChanges(animDispatches, stateChanges, packedAnimation); + AnimationUtilities.UnpackStateChanges(level.AnimDispatches, level.StateChanges, packedAnimation); AnimationUtilities.UnpackAnimSounds(level, packedAnimation); - AnimationUtilities.UnpackAnimCommands(animCommands, packedAnimation); + AnimationUtilities.UnpackAnimCommands(level.AnimCommands, packedAnimation); int newAnimationIndex = AnimationUtilities.UnpackAnimation(level, packedAnimation); indexMap[oldAnimationIndex] = newAnimationIndex; @@ -166,15 +149,6 @@ public static void Import(TR2Level level, TR2ModelDefinition definition) } } - level.AnimDispatches = animDispatches.ToArray(); - level.NumAnimDispatches = (uint)animDispatches.Count; - - level.StateChanges = stateChanges.ToArray(); - level.NumStateChanges = (uint)stateChanges.Count; - - level.AnimCommands = animCommands.ToArray(); - level.NumAnimCommands = (uint)animCommands.Count; - foreach (TR2PackedAnimation packedAnimation in animations.Values) { packedAnimation.Animation.NextAnimation = (ushort)indexMap[packedAnimation.Animation.NextAnimation]; @@ -200,16 +174,12 @@ public static void Import(TR3Level level, TR3ModelDefinition definition) bool firstAnimationConfigured = false; Dictionary indexMap = new(); - List animDispatches = level.AnimDispatches.ToList(); - List stateChanges = level.StateChanges.ToList(); - List animCommands = level.AnimCommands.ToList(); - foreach (int oldAnimationIndex in animations.Keys) { TR3PackedAnimation packedAnimation = animations[oldAnimationIndex]; - AnimationUtilities.UnpackStateChanges(animDispatches, stateChanges, packedAnimation); + AnimationUtilities.UnpackStateChanges(level.AnimDispatches, level.StateChanges, packedAnimation); AnimationUtilities.UnpackAnimSounds(level, packedAnimation); - AnimationUtilities.UnpackAnimCommands(animCommands, packedAnimation); + AnimationUtilities.UnpackAnimCommands(level.AnimCommands, packedAnimation); int newAnimationIndex = AnimationUtilities.UnpackAnimation(level, packedAnimation); indexMap[oldAnimationIndex] = newAnimationIndex; @@ -221,15 +191,6 @@ public static void Import(TR3Level level, TR3ModelDefinition definition) } } - level.AnimDispatches = animDispatches.ToArray(); - level.NumAnimDispatches = (uint)animDispatches.Count; - - level.StateChanges = stateChanges.ToArray(); - level.NumStateChanges = (uint)stateChanges.Count; - - level.AnimCommands = animCommands.ToArray(); - level.NumAnimCommands = (uint)animCommands.Count; - foreach (TR3PackedAnimation packedAnimation in animations.Values) { if (indexMap.ContainsKey(packedAnimation.Animation.NextAnimation)) diff --git a/TRModelTransporter/Handlers/Animations/AnimationUtilities.cs b/TRModelTransporter/Handlers/Animations/AnimationUtilities.cs index 5c23ebc99..50645367f 100644 --- a/TRModelTransporter/Handlers/Animations/AnimationUtilities.cs +++ b/TRModelTransporter/Handlers/Animations/AnimationUtilities.cs @@ -9,24 +9,24 @@ public static class AnimationUtilities { public static int GetModelAnimationCount(TR1Level level, TRModel model) { - return GetModelAnimationCount(level.Models, model, level.NumAnimations); + return GetModelAnimationCount(level.Models, model, level.Animations.Count); } public static int GetModelAnimationCount(TR2Level level, TRModel model) { - return GetModelAnimationCount(level.Models, model, level.NumAnimations); + return GetModelAnimationCount(level.Models, model, level.Animations.Count); } public static int GetModelAnimationCount(TR3Level level, TRModel model) { - return GetModelAnimationCount(level.Models, model, level.NumAnimations); + return GetModelAnimationCount(level.Models, model, level.Animations.Count); } - public static int GetModelAnimationCount(TRModel[] models, TRModel model, uint totalAnimations) + public static int GetModelAnimationCount(List models, TRModel model, int totalAnimations) { TRModel nextModel = model; int modelIndex = models.ToList().IndexOf(model) + 1; - while (modelIndex < models.Length) + while (modelIndex < models.Count) { nextModel = models[modelIndex++]; if (nextModel.Animation != ushort.MaxValue) @@ -108,15 +108,15 @@ public static void PackAnimCommands(TR1Level level, TRAnimation animation, TR1Pa public static void PackAnimCommands(TR2Level level, TRAnimation animation, TR2PackedAnimation packedAnimation) { - packedAnimation.Commands = PackAnimCommands(level.AnimCommands, animation); + packedAnimation.Commands = PackAnimCommands(level.AnimCommands.ToList(), animation); } public static void PackAnimCommands(TR3Level level, TRAnimation animation, TR3PackedAnimation packedAnimation) { - packedAnimation.Commands = PackAnimCommands(level.AnimCommands, animation); + packedAnimation.Commands = PackAnimCommands(level.AnimCommands.ToList(), animation); } - private static Dictionary PackAnimCommands(TRAnimCommand[] animCommands, TRAnimation animation) + private static Dictionary PackAnimCommands(List animCommands, TRAnimation animation) { Dictionary cmds = new(); @@ -266,32 +266,32 @@ public static ushort[] GetAnimationFrames(TR1Level level, TRModel model) public static ushort[] GetAnimationFrames(TR2Level level, TRModel model) { - return GetAnimationFrames(model, level.Models, level.Frames); + return GetAnimationFrames(model, level.Models, level.Frames.ToList()); } public static ushort[] GetAnimationFrames(TR3Level level, TRModel model) { - return GetAnimationFrames(model, level.Models, level.Frames); + return GetAnimationFrames(model, level.Models, level.Frames.ToList()); } - public static ushort[] GetAnimationFrames(TRModel model, TRModel[] allModels, ushort[] allFrames) + public static ushort[] GetAnimationFrames(TRModel model, List allModels, List allFrames) { - int modelIndex = allModels.ToList().IndexOf(model); + int modelIndex = allModels.IndexOf(model); uint endFrame = 0; - if (modelIndex == allModels.Length - 1) + if (modelIndex == allModels.Count - 1) { - endFrame = (uint)allFrames.Length; + endFrame = (uint)allFrames.Count; } else { - while (endFrame == 0 && modelIndex < allModels.Length) + while (endFrame == 0 && modelIndex < allModels.Count) { endFrame = allModels[++modelIndex].FrameOffset / 2; } } List frames = new(); - for (uint i = model.FrameOffset / 2; i < endFrame; i++) + for (int i = (int)model.FrameOffset / 2; i < endFrame; i++) { frames.Add(allFrames[i]); } @@ -479,42 +479,26 @@ private static void RemapSoundIndices(IEnumerable com public static int UnpackAnimation(TR1Level level, TR1PackedAnimation animation) { - List levelAnimations = level.Animations.ToList(); - levelAnimations.Add(animation.Animation); - level.Animations = levelAnimations.ToArray(); - level.NumAnimations++; - - return levelAnimations.Count - 1; + level.Animations.Add(animation.Animation); + return level.Animations.Count - 1; } public static int UnpackAnimation(TR2Level level, TR2PackedAnimation animation) { - List levelAnimations = level.Animations.ToList(); - levelAnimations.Add(animation.Animation); - level.Animations = levelAnimations.ToArray(); - level.NumAnimations++; - - return levelAnimations.Count - 1; + level.Animations.Add(animation.Animation); + return level.Animations.Count - 1; } public static int UnpackAnimation(TR3Level level, TR3PackedAnimation animation) { - List levelAnimations = level.Animations.ToList(); - levelAnimations.Add(animation.Animation); - level.Animations = levelAnimations.ToArray(); - level.NumAnimations++; - - return levelAnimations.Count - 1; + level.Animations.Add(animation.Animation); + return level.Animations.Count - 1; } public static void ImportAnimationFrames(TR1Level level, TR1ModelDefinition definition) { - List levelFrames = level.Frames.ToList(); - definition.Model.FrameOffset = (uint)levelFrames.Count * 2; - - levelFrames.AddRange(definition.AnimationFrames); - level.Frames = levelFrames.ToArray(); - level.NumFrames = (uint)levelFrames.Count; + definition.Model.FrameOffset = (uint)level.Frames.Count * 2; + level.Frames.AddRange(definition.AnimationFrames); foreach (TR1PackedAnimation packedAnimation in definition.Animations.Values) { @@ -524,12 +508,8 @@ public static void ImportAnimationFrames(TR1Level level, TR1ModelDefinition defi public static void ImportAnimationFrames(TR2Level level, TR2ModelDefinition definition) { - List levelFrames = level.Frames.ToList(); - definition.Model.FrameOffset = (uint)levelFrames.Count * 2; - - levelFrames.AddRange(definition.AnimationFrames); - level.Frames = levelFrames.ToArray(); - level.NumFrames = (uint)levelFrames.Count; + definition.Model.FrameOffset = (uint)level.Frames.Count * 2; + level.Frames.AddRange(definition.AnimationFrames); foreach (TR2PackedAnimation packedAnimation in definition.Animations.Values) { @@ -539,12 +519,8 @@ public static void ImportAnimationFrames(TR2Level level, TR2ModelDefinition defi public static void ImportAnimationFrames(TR3Level level, TR3ModelDefinition definition) { - List levelFrames = level.Frames.ToList(); - definition.Model.FrameOffset = (uint)levelFrames.Count * 2; - - levelFrames.AddRange(definition.AnimationFrames); - level.Frames = levelFrames.ToArray(); - level.NumFrames = (uint)levelFrames.Count; + definition.Model.FrameOffset = (uint)level.Frames.Count * 2; + level.Frames.AddRange(definition.AnimationFrames); foreach (TR3PackedAnimation packedAnimation in definition.Animations.Values) { diff --git a/TRModelTransporter/Handlers/ModelTransportHandler.cs b/TRModelTransporter/Handlers/ModelTransportHandler.cs index f35afb424..be31cda63 100644 --- a/TRModelTransporter/Handlers/ModelTransportHandler.cs +++ b/TRModelTransporter/Handlers/ModelTransportHandler.cs @@ -20,21 +20,18 @@ public static void Export(TR3Level level, TR3ModelDefinition definition, TR3Type definition.Model = GetTRModel(level.Models, (short)entity); } - private static TRModel GetTRModel(IEnumerable models, short entityID) + private static TRModel GetTRModel(List models, short entityID) { - TRModel model = models.ToList().Find(m => m.ID == entityID); + TRModel model = models.Find(m => m.ID == entityID); return model ?? throw new ArgumentException($"The model for {entityID} could not be found."); } public static void Import(TR1Level level, TR1ModelDefinition definition, Dictionary aliasPriority, IEnumerable laraDependants) { - List levelModels = level.Models.ToList(); - int i = levelModels.FindIndex(m => m.ID == (short)definition.Entity); + int i = level.Models.FindIndex(m => m.ID == (short)definition.Entity); if (i == -1) { - levelModels.Add(definition.Model); - level.Models = levelModels.ToArray(); - level.NumModels++; + level.Models.Add(definition.Model); } else if (!aliasPriority.ContainsKey(definition.Entity) || aliasPriority[definition.Entity] == definition.Alias) { @@ -52,24 +49,21 @@ public static void Import(TR1Level level, TR1ModelDefinition definition, Diction { if (definition.Entity == TR1Type.Lara) { - ReplaceLaraDependants(levelModels, definition.Model, laraDependants.Select(e => (short)e)); + ReplaceLaraDependants(level.Models, definition.Model, laraDependants.Select(e => (short)e)); } else if (laraDependants.Contains((TR1Type)definition.Model.ID)) { - ReplaceLaraDependants(levelModels, levelModels.Find(m => m.ID == (uint)TR1Type.Lara), new short[] { (short)definition.Model.ID }); + ReplaceLaraDependants(level.Models, level.Models.Find(m => m.ID == (uint)TR1Type.Lara), new short[] { (short)definition.Model.ID }); } } } public static void Import(TR2Level level, TR2ModelDefinition definition, Dictionary aliasPriority, IEnumerable laraDependants) { - List levelModels = level.Models.ToList(); - int i = levelModels.FindIndex(m => m.ID == (short)definition.Entity); + int i = level.Models.FindIndex(m => m.ID == (short)definition.Entity); if (i == -1) { - levelModels.Add(definition.Model); - level.Models = levelModels.ToArray(); - level.NumModels++; + level.Models.Add(definition.Model); } else if (!aliasPriority.ContainsKey(definition.Entity) || aliasPriority[definition.Entity] == definition.Alias) { @@ -85,19 +79,16 @@ public static void Import(TR2Level level, TR2ModelDefinition definition, Diction // their starting mesh and mesh tree indices are just remapped to Lara's. if (definition.Entity == TR2Type.Lara && laraDependants != null) { - ReplaceLaraDependants(levelModels, definition.Model, laraDependants.Select(e => (short)e)); + ReplaceLaraDependants(level.Models, definition.Model, laraDependants.Select(e => (short)e)); } } public static void Import(TR3Level level, TR3ModelDefinition definition, Dictionary aliasPriority, IEnumerable laraDependants, IEnumerable unsafeReplacements) { - List levelModels = level.Models.ToList(); - int i = levelModels.FindIndex(m => m.ID == (short)definition.Entity); + int i = level.Models.FindIndex(m => m.ID == (short)definition.Entity); if (i == -1) { - levelModels.Add(definition.Model); - level.Models = levelModels.ToArray(); - level.NumModels++; + level.Models.Add(definition.Model); } else if (!aliasPriority.ContainsKey(definition.Entity) || aliasPriority[definition.Entity] == definition.Alias) { @@ -119,7 +110,7 @@ public static void Import(TR3Level level, TR3ModelDefinition definition, Diction if (definition.Entity == TR3Type.Lara && laraDependants != null) { - ReplaceLaraDependants(levelModels, definition.Model, laraDependants.Select(e => (short)e)); + ReplaceLaraDependants(level.Models, definition.Model, laraDependants.Select(e => (short)e)); } } diff --git a/TRModelTransporter/Handlers/Textures/TR2/TR2TextureImportHandler.cs b/TRModelTransporter/Handlers/Textures/TR2/TR2TextureImportHandler.cs index e877a0c7e..d71dcbd3a 100644 --- a/TRModelTransporter/Handlers/Textures/TR2/TR2TextureImportHandler.cs +++ b/TRModelTransporter/Handlers/Textures/TR2/TR2TextureImportHandler.cs @@ -78,7 +78,7 @@ private void ApplyFlamePatch() if ( _definitions.ToList().FindIndex(d => flameEnemies.Contains(d.Entity)) != -1 || - _level.Models.ToList().FindIndex(m => flameEnemies.Contains((TR2Type)m.ID)) != -1 + _level.Models.FindIndex(m => flameEnemies.Contains((TR2Type)m.ID)) != -1 ) { List sequences = _level.SpriteSequences.ToList(); diff --git a/TRModelTransporter/Transport/TR1/TR1ModelExporter.cs b/TRModelTransporter/Transport/TR1/TR1ModelExporter.cs index 2c45cac60..b4f8deb25 100644 --- a/TRModelTransporter/Transport/TR1/TR1ModelExporter.cs +++ b/TRModelTransporter/Transport/TR1/TR1ModelExporter.cs @@ -98,65 +98,53 @@ protected override void ModelExportReady(TR1ModelDefinition definition) public static void AmendPierreGunshot(TR1Level level) { - TRModel model = Array.Find(level.Models, m => m.ID == (uint)TR1Type.Pierre); + TRModel model = level.Models.Find(m => m.ID == (uint)TR1Type.Pierre); // Get his shooting animation TRAnimation anim = level.Animations[model.Animation + 10]; - List cmds = level.AnimCommands.ToList(); - anim.AnimCommand = (ushort)cmds.Count; + anim.AnimCommand = (ushort)level.AnimCommands.Count; anim.NumAnimCommands = 1; // On the 2nd frame, play SFX 44 (magnums) - cmds.Add(new TRAnimCommand { Value = 5 }); - cmds.Add(new TRAnimCommand { Value = (short)(anim.FrameStart + 1) }); - cmds.Add(new TRAnimCommand { Value = 44 }); - - level.AnimCommands = cmds.ToArray(); - level.NumAnimCommands = (uint)cmds.Count; + level.AnimCommands.Add(new() { Value = 5 }); + level.AnimCommands.Add(new() { Value = (short)(anim.FrameStart + 1) }); + level.AnimCommands.Add(new() { Value = 44 }); } public static void AmendPierreDeath(TR1Level level) { - TRModel model = Array.Find(level.Models, m => m.ID == (uint)TR1Type.Pierre); + TRModel model = level.Models.Find(m => m.ID == (uint)TR1Type.Pierre); // Get his death animation TRAnimation anim = level.Animations[model.Animation + 12]; anim.NumAnimCommands++; - List cmds = level.AnimCommands.ToList(); - anim.AnimCommand = (ushort)cmds.Count; - cmds.Add(new TRAnimCommand { Value = 4 }); // Death + anim.AnimCommand = (ushort)level.AnimCommands.Count; + level.AnimCommands.Add(new() { Value = 4 }); // Death // On the 61st frame, play SFX 159 (death) - cmds.Add(new TRAnimCommand { Value = 5 }); - cmds.Add(new TRAnimCommand { Value = (short)(anim.FrameStart + 60) }); - cmds.Add(new TRAnimCommand { Value = 159 }); - - level.AnimCommands = cmds.ToArray(); - level.NumAnimCommands = (uint)cmds.Count; + level.AnimCommands.Add(new() { Value = 5 }); + level.AnimCommands.Add(new() { Value = (short)(anim.FrameStart + 60) }); + level.AnimCommands.Add(new() { Value = 159 }); } public static void AmendLarsonDeath(TR1Level level) { - TRModel model = Array.Find(level.Models, m => m.ID == (uint)TR1Type.Larson); + TRModel model = level.Models.Find(m => m.ID == (uint)TR1Type.Larson); // Get his death animation TRAnimation anim = level.Animations[model.Animation + 15]; anim.NumAnimCommands++; - List cmds = level.AnimCommands.ToList(); - anim.AnimCommand = (ushort)cmds.Count; - cmds.Add(new TRAnimCommand { Value = 4 }); // Death + anim.AnimCommand = (ushort)level.AnimCommands.Count; + level.AnimCommands.Add(new() { Value = 4 }); // Death // On the 2nd frame, play SFX 158 (death) - cmds.Add(new TRAnimCommand { Value = 5 }); - cmds.Add(new TRAnimCommand { Value = (short)(anim.FrameStart + 1) }); - cmds.Add(new TRAnimCommand { Value = 158 }); - - level.AnimCommands = cmds.ToArray(); - level.NumAnimCommands = (uint)cmds.Count; + level.AnimCommands.Add(new() { Value = 5 }); + level.AnimCommands.Add(new() { Value = (short)(anim.FrameStart + 1) }); + level.AnimCommands.Add(new() { Value = 158 }); } public static void AmendSkaterBoyDeath(TR1Level level) { - TRModel model = Array.Find(level.Models, m => m.ID == (uint)TR1Type.SkateboardKid); + TRModel model = level.Models.Find(m => m.ID == (uint)TR1Type.SkateboardKid); // Get his death animation TRAnimation anim = level.Animations[model.Animation + 13]; // Play the death sound on the 2nd frame (doesn't work on the 1st, which is OG). @@ -165,22 +153,18 @@ public static void AmendSkaterBoyDeath(TR1Level level) public static void AmendNatlaDeath(TR1Level level) { - TRModel model = Array.Find(level.Models, m => m.ID == (uint)TR1Type.Natla); + TRModel model = level.Models.Find(m => m.ID == (uint)TR1Type.Natla); // Get her death animation TRAnimation anim = level.Animations[model.Animation + 13]; anim.NumAnimCommands++; - List cmds = level.AnimCommands.ToList(); - anim.AnimCommand = (ushort)cmds.Count; - cmds.Add(new TRAnimCommand { Value = 4 }); // Death + anim.AnimCommand = (ushort)level.AnimCommands.Count; + level.AnimCommands.Add(new() { Value = 4 }); // Death // On the 5th frame, play SFX 160 (death) - cmds.Add(new TRAnimCommand { Value = 5 }); - cmds.Add(new TRAnimCommand { Value = (short)(anim.FrameStart + 4) }); - cmds.Add(new TRAnimCommand { Value = 160 }); - - level.AnimCommands = cmds.ToArray(); - level.NumAnimCommands = (uint)cmds.Count; + level.AnimCommands.Add(new() { Value = 5 }); + level.AnimCommands.Add(new() { Value = (short)(anim.FrameStart + 4) }); + level.AnimCommands.Add(new() { Value = 160 }); } public static void AddMovingBlockSFX(TR1Level level) @@ -194,23 +178,19 @@ public static void AddMovingBlockSFX(TR1Level level) SoundUtilities.ImportLevelSound(level, vilcabamba, new short[] { 162 }); } - TRModel model = Array.Find(level.Models, m => m.ID == (uint)TR1Type.MovingBlock); - List cmds = level.AnimCommands.ToList(); + TRModel model = level.Models.Find(m => m.ID == (uint)TR1Type.MovingBlock); for (int i = 2; i < 4; i++) { TRAnimation anim = level.Animations[model.Animation + i]; anim.NumAnimCommands++; - anim.AnimCommand = (ushort)cmds.Count; - cmds.Add(new TRAnimCommand { Value = 4 }); // KillItem + anim.AnimCommand = (ushort)level.AnimCommands.Count; + level.AnimCommands.Add(new() { Value = 4 }); // KillItem // On the 1st frame, play SFX 162 - cmds.Add(new TRAnimCommand { Value = 5 }); - cmds.Add(new TRAnimCommand { Value = (short)(anim.FrameStart) }); - cmds.Add(new TRAnimCommand { Value = 162 }); - } - - level.AnimCommands = cmds.ToArray(); - level.NumAnimCommands = (uint)cmds.Count; + level.AnimCommands.Add(new() { Value = 5 }); + level.AnimCommands.Add(new() { Value = (short)anim.FrameStart }); + level.AnimCommands.Add(new() { Value = 162 }); + } } } diff --git a/TRModelTransporter/Transport/TR1/TR1ModelImporter.cs b/TRModelTransporter/Transport/TR1/TR1ModelImporter.cs index 3728747c7..5488251e5 100644 --- a/TRModelTransporter/Transport/TR1/TR1ModelImporter.cs +++ b/TRModelTransporter/Transport/TR1/TR1ModelImporter.cs @@ -33,9 +33,7 @@ protected override AbstractTextureImportHandler GetExistingModelTypes() { - List existingEntities = new(); - Level.Models.ToList().ForEach(m => existingEntities.Add((TR1Type)m.ID)); - return existingEntities; + return Level.Models.Select(m => (TR1Type)m.ID).ToList(); } protected override void Import(IEnumerable standardDefinitions, IEnumerable soundOnlyDefinitions) diff --git a/TRModelTransporter/Transport/TR2/TR2ModelImporter.cs b/TRModelTransporter/Transport/TR2/TR2ModelImporter.cs index daae6fd49..587080cb7 100644 --- a/TRModelTransporter/Transport/TR2/TR2ModelImporter.cs +++ b/TRModelTransporter/Transport/TR2/TR2ModelImporter.cs @@ -21,9 +21,7 @@ protected override AbstractTextureImportHandler GetExistingModelTypes() { - List existingEntities = new(); - Level.Models.ToList().ForEach(m => existingEntities.Add((TR2Type)m.ID)); - return existingEntities; + return Level.Models.Select(m => (TR2Type)m.ID).ToList(); } protected override void Import(IEnumerable standardDefinitions, IEnumerable soundOnlyDefinitions) diff --git a/TRModelTransporter/Transport/TR3/TR3ModelImporter.cs b/TRModelTransporter/Transport/TR3/TR3ModelImporter.cs index c60b817c1..ceec70485 100644 --- a/TRModelTransporter/Transport/TR3/TR3ModelImporter.cs +++ b/TRModelTransporter/Transport/TR3/TR3ModelImporter.cs @@ -22,9 +22,7 @@ protected override AbstractTextureImportHandler GetExistingModelTypes() { - List existingEntities = new(); - Level.Models.ToList().ForEach(m => existingEntities.Add((TR3Type)m.ID)); - return existingEntities; + return Level.Models.Select(m => (TR3Type)m.ID).ToList(); } protected override void Import(IEnumerable standardDefinitions, IEnumerable soundOnlyDefinitions) diff --git a/TRRandomizerCore/Levels/TR1CombinedLevel.cs b/TRRandomizerCore/Levels/TR1CombinedLevel.cs index 1a81f7f84..267c0d502 100644 --- a/TRRandomizerCore/Levels/TR1CombinedLevel.cs +++ b/TRRandomizerCore/Levels/TR1CombinedLevel.cs @@ -76,12 +76,6 @@ public class TR1CombinedLevel public void RemoveModel(TR1Type type) { - List models = Data.Models.ToList(); - if (models.Find(m => m.ID == (uint)type) is TRModel model) - { - models.Remove(model); - Data.Models = models.ToArray(); - Data.NumModels--; - } + Data.Models.RemoveAll(m => m.ID == (uint)type); } } diff --git a/TRRandomizerCore/Levels/TR3CombinedLevel.cs b/TRRandomizerCore/Levels/TR3CombinedLevel.cs index a83ad537c..581114946 100644 --- a/TRRandomizerCore/Levels/TR3CombinedLevel.cs +++ b/TRRandomizerCore/Levels/TR3CombinedLevel.cs @@ -129,12 +129,6 @@ public TR3Adventure Adventure public void RemoveModel(TR3Type type) { - List models = Data.Models.ToList(); - if (models.Find(m => m.ID == (uint)type) is TRModel model) - { - models.Remove(model); - Data.Models = models.ToArray(); - Data.NumModels--; - } + Data.Models.RemoveAll(m => m.ID == (uint)type); } } diff --git a/TRRandomizerCore/Processors/TR3/TR3SequenceProcessor.cs b/TRRandomizerCore/Processors/TR3/TR3SequenceProcessor.cs index 00d6f02bd..f4d855f77 100644 --- a/TRRandomizerCore/Processors/TR3/TR3SequenceProcessor.cs +++ b/TRRandomizerCore/Processors/TR3/TR3SequenceProcessor.cs @@ -272,14 +272,12 @@ private void ImportArtefactMenuModels(TR3CombinedLevel level) private void AmendWillardBoss(TR3CombinedLevel level) { - List models = level.Data.Models.ToList(); - // Add new duplicate models for keys, so secret rando doesn't replace the originals. foreach (TR3Type artefact in _artefactAssignment.Keys) { TR3Type replacement = _artefactAssignment[artefact]; - TRModel artefactModel = models.Find(m => m.ID == (uint)artefact); - models.Add(new TRModel + TRModel artefactModel = level.Data.Models.Find(m => m.ID == (uint)artefact); + level.Data.Models.Add(new() { Animation = artefactModel.Animation, FrameOffset = artefactModel.FrameOffset, @@ -300,9 +298,6 @@ private void AmendWillardBoss(TR3CombinedLevel level) level.Script.Keys[i] = ScriptEditor.Script.GameStrings1[80 + i]; } - level.Data.Models = models.ToArray(); - level.Data.NumModels = (uint)models.Count; - // Apply any changes needed for the boss fight AmendBossFight(level); diff --git a/TRRandomizerCore/Randomizers/TR1/TR1EnemyRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/TR1EnemyRandomizer.cs index 5e8fa25e1..22fb9fa7f 100644 --- a/TRRandomizerCore/Randomizers/TR1/TR1EnemyRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/TR1EnemyRandomizer.cs @@ -691,11 +691,7 @@ private void RandomizeEnemies(TR1CombinedLevel level, EnemyRandomizationCollecti if (Settings.AllowEmptyEggs) { // Add 1/4 chance of an empty egg, provided at least one spawn model is not available - List allModels = new(); - foreach (TRModel model in level.Data.Models) - { - allModels.Add((TR1Type)model.ID); - } + IEnumerable allModels = level.Data.Models.Select(m => (TR1Type)m.ID); // We can add Adam to make it possible for a dud spawn - he's not normally available for eggs because // of his own restrictions. @@ -840,7 +836,7 @@ private static int GetEntityCount(TR1CombinedLevel level, TR1Type entityType) else if (type == TR1Type.AdamEgg || type == TR1Type.AtlanteanEgg) { TR1Type eggType = TR1EnemyUtilities.CodeBitsToAtlantean(entity.CodeBits); - if (eggType == translatedType && Array.Find(level.Data.Models, m => m.ID == (uint)eggType) != null) + if (eggType == translatedType && level.Data.Models.Find(m => m.ID == (uint)eggType) != null) { count++; } @@ -871,7 +867,7 @@ private static bool IsEnemyInOrAboveWater(TR1Entity entity, TR1Level level, FDCo private static void AmendToQLarson(TR1CombinedLevel level) { - TRModel larsonModel = Array.Find(level.Data.Models, m => m.ID == (uint)TR1Type.Larson); + TRModel larsonModel = level.Data.Models.Find(m => m.ID == (uint)TR1Type.Larson); if (larsonModel != null) { // Convert the Larson model into the Great Pyramid scion to allow ending the level. Larson will @@ -944,12 +940,11 @@ private void AmendAtlanteanModels(TR1CombinedLevel level, EnemyRandomizationColl // If non-shooting grounded Atlanteans are present, we can just duplicate the model to make shooting Atlanteans if (enemies.Available.Any(TR1TypeUtilities.GetFamily(TR1Type.ShootingAtlantean_N).Contains)) { - List models = level.Data.Models.ToList(); - TRModel shooter = models.Find(m => m.ID == (uint)TR1Type.ShootingAtlantean_N); - TRModel nonShooter = models.Find(m => m.ID == (uint)TR1Type.NonShootingAtlantean_N); + TRModel shooter = level.Data.Models.Find(m => m.ID == (uint)TR1Type.ShootingAtlantean_N); + TRModel nonShooter = level.Data.Models.Find(m => m.ID == (uint)TR1Type.NonShootingAtlantean_N); if (shooter == null && nonShooter != null) { - models.Add(new TRModel + level.Data.Models.Add(new() { ID = (uint)TR1Type.ShootingAtlantean_N, Animation = nonShooter.Animation, @@ -959,9 +954,6 @@ private void AmendAtlanteanModels(TR1CombinedLevel level, EnemyRandomizationColl StartingMesh = nonShooter.StartingMesh }); - level.Data.Models = models.ToArray(); - level.Data.NumModels++; - enemies.Available.Add(TR1Type.ShootingAtlantean_N); } } @@ -1071,7 +1063,7 @@ private void AddUnarmedLevelAmmo(TR1CombinedLevel level) }; // Only include it if the model is present i.e. it's not an empty egg. - if (Array.Find(level.Data.Models, m => (TR1Type)m.ID == resultantEnemy.TypeID) != null) + if (level.Data.Models.Find(m => (TR1Type)m.ID == resultantEnemy.TypeID) != null) { levelEnemies.Add(resultantEnemy); } @@ -1329,7 +1321,7 @@ private void CloneEnemies(TR1CombinedLevel level) TR1Entity adamEgg = level.Data.Entities.Find(e => e.TypeID == TR1Type.AdamEgg); if (adamEgg != null && TR1EnemyUtilities.CodeBitsToAtlantean(adamEgg.CodeBits) == TR1Type.Adam - && Array.Find(level.Data.Models, m => m.ID == (uint)TR1Type.Adam) != null) + && level.Data.Models.Find(m => m.ID == (uint)TR1Type.Adam) != null) { enemies.Add(adamEgg); } diff --git a/TRRandomizerCore/Randomizers/TR1/TR1OutfitRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/TR1OutfitRandomizer.cs index 40374f572..dd4db415f 100644 --- a/TRRandomizerCore/Randomizers/TR1/TR1OutfitRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/TR1OutfitRandomizer.cs @@ -379,7 +379,7 @@ private static void CreateGoldenBraid(TR1CombinedLevel level) TRMesh goldenHips = TRMeshUtilities.GetModelFirstMesh(level.Data, TR1Type.LaraMiscAnim_H); ushort goldPalette = goldenHips.ColouredRectangles[0].Texture; - TRModel ponytail = Array.Find(level.Data.Models, m => m.ID == (uint)TR1Type.LaraPonytail_H_U); + TRModel ponytail = level.Data.Models.Find(m => m.ID == (uint)TR1Type.LaraPonytail_H_U); TRMesh[] ponytailMeshes = TRMeshUtilities.GetModelMeshes(level.Data, ponytail); MeshEditor editor = new(); foreach (TRMesh mesh in ponytailMeshes) @@ -388,10 +388,7 @@ private static void CreateGoldenBraid(TR1CombinedLevel level) TRMeshUtilities.InsertMesh(level.Data, clonedMesh); } - List nodes = level.Data.MeshTrees.ToList(); - nodes.AddRange(TRMeshUtilities.GetModelMeshTrees(level.Data, ponytail)); - level.Data.MeshTrees = nodes.ToArray(); - level.Data.NumMeshTrees += ponytail.NumMeshes; + level.Data.MeshTrees.AddRange(TRMeshUtilities.GetModelMeshTrees(level.Data, ponytail)); ponytail.NumMeshes *= 2; } @@ -720,7 +717,7 @@ private bool ImportGymOutfit(TR1CombinedLevel level) return false; } - TRModel existingModel = Array.Find(level.Data.Models, m => m.ID == (uint)TR1Type.LaraMiscAnim_H); + TRModel existingModel = level.Data.Models.Find(m => m.ID == (uint)TR1Type.LaraMiscAnim_H); if (existingModel != null) { // If we already have the gym outfit available, we're done. @@ -753,7 +750,7 @@ private bool ImportGymOutfit(TR1CombinedLevel level) // e.g. for Adam death animation and scion pickups. if (existingModel != null) { - TRModel newModel = Array.Find(level.Data.Models, m => m.ID == (uint)TR1Type.LaraMiscAnim_H); + TRModel newModel = level.Data.Models.Find(m => m.ID == (uint)TR1Type.LaraMiscAnim_H); newModel.Animation = existingModel.Animation; newModel.FrameOffset = existingModel.FrameOffset; } diff --git a/TRRandomizerCore/Randomizers/TR1/TR1SecretRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/TR1SecretRandomizer.cs index 7964a5ff5..ca59326bf 100644 --- a/TRRandomizerCore/Randomizers/TR1/TR1SecretRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/TR1SecretRandomizer.cs @@ -837,11 +837,9 @@ protected override void StartImpl() // Work out which models are available to replace as secret pickups. // We exclude current puzzle/key items from the available switching pool. - List models = level.Data.Models.ToList(); - foreach (TR1Type puzzleType in _modelReplacements.Keys) { - if (models.Find(m => m.ID == (uint)puzzleType) == null) + if (level.Data.Models.Find(m => m.ID == (uint)puzzleType) == null) { allocation.AvailablePickupModels.Add(puzzleType); } @@ -873,7 +871,6 @@ protected override void ProcessImpl() importer.Import(); - List models = level.Data.Models.ToList(); List sequences = level.Data.SpriteSequences.ToList(); // Redefine the artefacts as puzzle models @@ -884,7 +881,7 @@ protected override void ProcessImpl() TR1Type puzzleModelType = allocation.AvailablePickupModels.First(); TR1Type puzzlePickupType = _modelReplacements[puzzleModelType]; - models.Find(m => m.ID == (uint)secretModelType).ID = (uint)puzzleModelType; + level.Data.Models.Find(m => m.ID == (uint)secretModelType).ID = (uint)puzzleModelType; sequences.Find(s => s.SpriteID == (int)secretPickupType).SpriteID = (int)puzzlePickupType; if (secretModelType == TR1Type.SecretScion_M_H && _outer.Are3DPickupsEnabled()) @@ -907,9 +904,6 @@ protected override void ProcessImpl() // Assign a name for the script SetPuzzleTypeName(level, puzzlePickupType, _pickupNames[secretModelType]); } - - level.Data.Models = models.ToArray(); - level.Data.NumModels = (uint)models.Count; } if (!_outer.TriggerProgress()) diff --git a/TRRandomizerCore/Randomizers/TR2/TR2EnemyRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2EnemyRandomizer.cs index 9d9707690..b1ffc4a1d 100644 --- a/TRRandomizerCore/Randomizers/TR2/TR2EnemyRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2EnemyRandomizer.cs @@ -489,19 +489,18 @@ private void RandomizeEnemiesNatively(TR2CombinedLevel level) private static void DisguiseEntity(TR2CombinedLevel level, TR2Type guiser, TR2Type targetEntity) { - List models = level.Data.Models.ToList(); - int existingIndex = models.FindIndex(m => m.ID == (short)guiser); + int existingIndex = level.Data.Models.FindIndex(m => m.ID == (short)guiser); if (existingIndex != -1) { - models.RemoveAt(existingIndex); + level.Data.Models.RemoveAt(existingIndex); } - TRModel disguiseAsModel = models[models.FindIndex(m => m.ID == (short)targetEntity)]; + TRModel disguiseAsModel = level.Data.Models.Find(m => m.ID == (short)targetEntity); if (targetEntity == TR2Type.BirdMonster && level.Is(TR2LevelNames.CHICKEN)) { // We have to keep the original model for the boss, so in // this instance we just clone the model for the guiser - models.Add(new TRModel + level.Data.Models.Add(new() { Animation = disguiseAsModel.Animation, FrameOffset = disguiseAsModel.FrameOffset, @@ -515,9 +514,6 @@ private static void DisguiseEntity(TR2CombinedLevel level, TR2Type guiser, TR2Ty { disguiseAsModel.ID = (uint)guiser; } - - level.Data.Models = models.ToArray(); - level.Data.NumModels = (uint)models.Count; } private void RandomizeEnemies(TR2CombinedLevel level, EnemyRandomizationCollection enemies) @@ -978,7 +974,7 @@ private static void MakeChickensUnconditional(TR2CombinedLevel level) // #327 Trick the game into never reaching the final frame of the death animation. // This results in a very abrupt death but avoids the level ending. For Ice Palace, // environment modifications will be made to enforce an alternative ending. - TRModel model = Array.Find(level.Data.Models, m => m.ID == (uint)TR2Type.BirdMonster); + TRModel model = level.Data.Models.Find(m => m.ID == (uint)TR2Type.BirdMonster); if (model != null) { level.Data.Animations[model.Animation + 20].FrameEnd = level.Data.Animations[model.Animation + 19].FrameEnd; diff --git a/TRRandomizerCore/Randomizers/TR3/TR3SecretRandomizer.cs b/TRRandomizerCore/Randomizers/TR3/TR3SecretRandomizer.cs index d75a6e5aa..612745340 100644 --- a/TRRandomizerCore/Randomizers/TR3/TR3SecretRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR3/TR3SecretRandomizer.cs @@ -449,7 +449,6 @@ private void AddDamageControl(TR3CombinedLevel level, List pickupTypes, { // If we have a spare model slot, duplicate one of the artefacts into this so that // we can add a hint with the item name. Otherwise, just re-use a puzzle item. - List models = level.Data.Models.ToList(); Dictionary artefacts = TR3TypeUtilities.GetArtefactReplacements(); TR3Type availablePickupType = default; @@ -457,7 +456,7 @@ private void AddDamageControl(TR3CombinedLevel level, List pickupTypes, foreach (TR3Type pickupType in artefacts.Keys) { TR3Type menuType = artefacts[pickupType]; - if (models.Find(m => m.ID == (uint)menuType) == null) + if (level.Data.Models.Find(m => m.ID == (uint)menuType) == null) { availablePickupType = pickupType; availableMenuType = menuType; @@ -469,8 +468,8 @@ private void AddDamageControl(TR3CombinedLevel level, List pickupTypes, { // We have a free slot, so duplicate a model TR3Type baseArtefact = pickupTypes[_generator.Next(0, pickupTypes.Count)]; - TRModel artefactMenuModel = models.Find(m => m.ID == (uint)artefacts[baseArtefact]); - models.Add(new TRModel + TRModel artefactMenuModel = level.Data.Models.Find(m => m.ID == (uint)artefacts[baseArtefact]); + level.Data.Models.Add(new() { Animation = artefactMenuModel.Animation, FrameOffset = artefactMenuModel.FrameOffset, @@ -480,9 +479,6 @@ private void AddDamageControl(TR3CombinedLevel level, List pickupTypes, StartingMesh = artefactMenuModel.StartingMesh }); - level.Data.Models = models.ToArray(); - level.Data.NumModels++; - // Add a script name - pull from GamestringRando once translations completed SetPuzzleTypeName(level, availablePickupType, "Infinite Medi Packs"); } @@ -833,11 +829,8 @@ protected override void ProcessImpl() DataFolder = _outer.GetResourcePath(@"TR3\Models"), TexturePositionMonitor = monitor }; - importer.Import(); - List models = level.Data.Models.ToList(); - // Redefine the artefacts as puzzle models otherwise the level ends on pickup foreach (TR3Type artefactPickupType in allocation.ImportModels) { @@ -846,13 +839,13 @@ protected override void ProcessImpl() TR3Type puzzlePickupType = allocation.AvailablePickupModels.First(); TR3Type puzzleMenuType = _artefactReplacements[puzzlePickupType]; - models.Find(m => m.ID == (uint)artefactPickupType).ID = (uint)puzzlePickupType; + level.Data.Models.Find(m => m.ID == (uint)artefactPickupType).ID = (uint)puzzlePickupType; // #277 Most levels (beyond India) have the artefacts as menu models so we need // to duplicate the models instead of replacing them, otherwise the carried-over // artefacts from previous levels are invisible. - TRModel menuModel = models.Find(m => m.ID == (uint)artefactMenuType); - models.Add(new TRModel + TRModel menuModel = level.Data.Models.Find(m => m.ID == (uint)artefactMenuType); + level.Data.Models.Add(new() { Animation = menuModel.Animation, FrameOffset = menuModel.FrameOffset, @@ -875,9 +868,6 @@ protected override void ProcessImpl() monitor.EntityMap[artefactPickupType] = puzzlePickupType; monitor.EntityMap[artefactMenuType] = puzzleMenuType; } - - level.Data.Models = models.ToArray(); - level.Data.NumModels = (uint)models.Count; } if (!_outer.TriggerProgress()) diff --git a/TRRandomizerCore/Textures/DynamicTextureBuilder.cs b/TRRandomizerCore/Textures/DynamicTextureBuilder.cs index ac875767f..708076fa2 100644 --- a/TRRandomizerCore/Textures/DynamicTextureBuilder.cs +++ b/TRRandomizerCore/Textures/DynamicTextureBuilder.cs @@ -136,7 +136,7 @@ public DynamicTextureTarget Build(TR1CombinedLevel level) // Lara will be partially re-textured. foreach (TR1Type modelID in modelIDs) { - TRModel model = Array.Find(level.Data.Models, m => m.ID == (uint)modelID); + TRModel model = level.Data.Models.Find(m => m.ID == (uint)modelID); if (model != null) { AddModelTextures(level.Data, model, hips, defaultObjectTextures, modelMeshes); @@ -145,7 +145,7 @@ public DynamicTextureTarget Build(TR1CombinedLevel level) foreach (TR1Type modelID in _enemyIDs) { - TRModel model = Array.Find(level.Data.Models, m => m.ID == (uint)modelID); + TRModel model = level.Data.Models.Find(m => m.ID == (uint)modelID); if (model != null) { AddModelTextures(level.Data, model, hips, enemyObjectTextures, modelMeshes); @@ -173,7 +173,7 @@ public DynamicTextureTarget Build(TR1CombinedLevel level) Dictionary keyItems = TR1TypeUtilities.GetKeyItemMap(); foreach (TR1Type pickupType in keyItems.Keys) { - TRModel model = Array.Find(level.Data.Models, m => m.ID == (uint)keyItems[pickupType]); + TRModel model = level.Data.Models.Find(m => m.ID == (uint)keyItems[pickupType]); if (model == null) { continue; diff --git a/TRRandomizerCore/Textures/Wireframing/AbstractTRWireframer.cs b/TRRandomizerCore/Textures/Wireframing/AbstractTRWireframer.cs index 79e30d147..8c03175e8 100644 --- a/TRRandomizerCore/Textures/Wireframing/AbstractTRWireframer.cs +++ b/TRRandomizerCore/Textures/Wireframing/AbstractTRWireframer.cs @@ -727,7 +727,7 @@ private void DeleteAnimatedTextures(L level) protected abstract Dictionary GetModelMeshes(L level); protected abstract int GetBlackPaletteIndex(L level); protected abstract int ImportColour(L level, Color c); - protected abstract TRModel[] GetModels(L level); + protected abstract List GetModels(L level); protected abstract TRMesh[] GetModelMeshes(L level, TRModel model); protected abstract TRMesh[] GetLevelMeshes(L level); protected abstract TRStaticMesh[] GetStaticMeshes(L level); diff --git a/TRRandomizerCore/Textures/Wireframing/TR1Wireframer.cs b/TRRandomizerCore/Textures/Wireframing/TR1Wireframer.cs index e8c05d460..04c0a0f58 100644 --- a/TRRandomizerCore/Textures/Wireframing/TR1Wireframer.cs +++ b/TRRandomizerCore/Textures/Wireframing/TR1Wireframer.cs @@ -110,7 +110,7 @@ protected override TRMesh[] GetModelMeshes(TR1Level level, TRModel model) return TRMeshUtilities.GetModelMeshes(level, model); } - protected override TRModel[] GetModels(TR1Level level) + protected override List GetModels(TR1Level level) { return level.Models; } diff --git a/TRRandomizerCore/Textures/Wireframing/TR2Wireframer.cs b/TRRandomizerCore/Textures/Wireframing/TR2Wireframer.cs index 050b18fca..f0e5070f8 100644 --- a/TRRandomizerCore/Textures/Wireframing/TR2Wireframer.cs +++ b/TRRandomizerCore/Textures/Wireframing/TR2Wireframer.cs @@ -82,9 +82,9 @@ protected override TRMesh[] GetModelMeshes(TR2Level level, TRModel model) return TRMeshUtilities.GetModelMeshes(level, model); } - protected override TRModel[] GetModels(TR2Level level) + protected override List GetModels(TR2Level level) { - return level.Models; + return level.Models.ToList(); } protected override TRObjectTexture[] GetObjectTextures(TR2Level level) diff --git a/TRRandomizerCore/Textures/Wireframing/TR3Wireframer.cs b/TRRandomizerCore/Textures/Wireframing/TR3Wireframer.cs index e8ff549d4..2d6540bf9 100644 --- a/TRRandomizerCore/Textures/Wireframing/TR3Wireframer.cs +++ b/TRRandomizerCore/Textures/Wireframing/TR3Wireframer.cs @@ -77,9 +77,9 @@ protected override TRMesh[] GetModelMeshes(TR3Level level, TRModel model) return TRMeshUtilities.GetModelMeshes(level, model); } - protected override TRModel[] GetModels(TR3Level level) + protected override List GetModels(TR3Level level) { - return level.Models; + return level.Models.ToList(); } protected override TRObjectTexture[] GetObjectTextures(TR3Level level) diff --git a/TRRandomizerCore/Utilities/TR1EnemyUtilities.cs b/TRRandomizerCore/Utilities/TR1EnemyUtilities.cs index df230c859..b5a217ed8 100644 --- a/TRRandomizerCore/Utilities/TR1EnemyUtilities.cs +++ b/TRRandomizerCore/Utilities/TR1EnemyUtilities.cs @@ -583,7 +583,7 @@ public static bool IsEmptyEgg(TR1Entity entity, TR1CombinedLevel level) } TR1Type type = CodeBitsToAtlantean(entity.CodeBits); - return Array.Find(level.Data.Models, m => m.ID == (uint)type) == null; + return level.Data.Models.Find(m => m.ID == (uint)type) == null; } public static bool CanDropItems(TR1Entity entity, TR1CombinedLevel level, FDControl floorData)