diff --git a/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorFunction.cs b/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorFunction.cs index 231954cd0..19c511e4e 100644 --- a/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorFunction.cs +++ b/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorFunction.cs @@ -561,20 +561,20 @@ private void MirrorBoxes(List boxes) private static void MirrorStaticMeshes(TR1Level level) { - MirrorStaticMeshes(level.StaticMeshes); + MirrorStaticMeshes(level.StaticMeshes.Values); } private static void MirrorStaticMeshes(TR2Level level) { - MirrorStaticMeshes(level.StaticMeshes); + MirrorStaticMeshes(level.StaticMeshes.Values); } private static void MirrorStaticMeshes(TR3Level level) { - MirrorStaticMeshes(level.StaticMeshes); + MirrorStaticMeshes(level.StaticMeshes.Values); } - private static void MirrorStaticMeshes(List staticMeshes) + private static void MirrorStaticMeshes(IEnumerable staticMeshes) { foreach (TRStaticMesh staticMesh in staticMeshes) { @@ -1010,7 +1010,6 @@ private static void MirrorTextures(TR1Level level) // Keep track of static meshes so they are only processed once, // and so we only target those actually in use in rooms. - List staticMeshes = level.StaticMeshes.ToList(); ISet processedMeshes = new HashSet(); foreach (TR1Room room in level.Rooms) @@ -1031,7 +1030,8 @@ private static void MirrorTextures(TR1Level level) foreach (TR1RoomStaticMesh roomStaticMesh in room.StaticMeshes) { - TRStaticMesh staticMesh = staticMeshes.Find(m => m.ID == roomStaticMesh.MeshID); + TR1Type id = roomStaticMesh.MeshID + TR1Type.SceneryBase; + TRStaticMesh staticMesh = level.StaticMeshes[id]; if (!processedMeshes.Add(staticMesh)) { continue; @@ -1088,7 +1088,6 @@ private static void MirrorTextures(TR2Level level) // Keep track of static meshes so they are only processed once, // and so we only target those actually in use in rooms. - List staticMeshes = level.StaticMeshes.ToList(); ISet processedMeshes = new HashSet(); foreach (TR2Room room in level.Rooms) @@ -1109,7 +1108,8 @@ private static void MirrorTextures(TR2Level level) foreach (TR2RoomStaticMesh roomStaticMesh in room.StaticMeshes) { - TRStaticMesh staticMesh = staticMeshes.Find(m => m.ID == roomStaticMesh.MeshID); + TR2Type id = roomStaticMesh.MeshID + TR2Type.SceneryBase; + TRStaticMesh staticMesh = level.StaticMeshes[id]; if (!processedMeshes.Add(staticMesh)) { continue; @@ -1158,7 +1158,6 @@ private static void MirrorTextures(TR3Level level) { ISet textureReferences = new HashSet(); - List staticMeshes = level.StaticMeshes.ToList(); ISet processedMeshes = new HashSet(); foreach (TR3Room room in level.Rooms) @@ -1179,7 +1178,8 @@ private static void MirrorTextures(TR3Level level) foreach (TR3RoomStaticMesh roomStaticMesh in room.StaticMeshes) { - TRStaticMesh staticMesh = staticMeshes.Find(m => m.ID == roomStaticMesh.MeshID); + TR3Type id = roomStaticMesh.MeshID + TR3Type.SceneryBase; + TRStaticMesh staticMesh = level.StaticMeshes[id]; if (!processedMeshes.Add(staticMesh)) { continue; diff --git a/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorStaticMeshFunction.cs b/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorStaticMeshFunction.cs index d0372ee57..a0c3a0343 100644 --- a/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorStaticMeshFunction.cs +++ b/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorStaticMeshFunction.cs @@ -8,27 +8,27 @@ public class EMMirrorStaticMeshFunction : BaseEMFunction public override void ApplyToLevel(TR1Level level) { - IEnumerable meshes = level.StaticMeshes.ToList() - .FindAll(s => MeshIDs.Contains(s.ID)) - .Select(s => s.Mesh); + IEnumerable meshes = level.StaticMeshes + .Where(kvp => MeshIDs.Contains(kvp.Key - TR1Type.SceneryBase)) + .Select(kvp => kvp.Value.Mesh); MirrorMeshes(meshes); } public override void ApplyToLevel(TR2Level level) { - IEnumerable meshes = level.StaticMeshes.ToList() - .FindAll(s => MeshIDs.Contains(s.ID)) - .Select(s => s.Mesh); + IEnumerable meshes = level.StaticMeshes + .Where(kvp => MeshIDs.Contains(kvp.Key - TR2Type.SceneryBase)) + .Select(kvp => kvp.Value.Mesh); MirrorMeshes(meshes); } public override void ApplyToLevel(TR3Level level) { - IEnumerable meshes = level.StaticMeshes.ToList() - .FindAll(s => MeshIDs.Contains(s.ID)) - .Select(s => s.Mesh); + IEnumerable meshes = level.StaticMeshes + .Where(kvp => MeshIDs.Contains(kvp.Key - TR3Type.SceneryBase)) + .Select(kvp => kvp.Value.Mesh); MirrorMeshes(meshes); } diff --git a/TREnvironmentEditor/Model/Types/Textures/EMCreateStaticMeshFunction.cs b/TREnvironmentEditor/Model/Types/Textures/EMCreateStaticMeshFunction.cs index 624a8f6e9..8b5b67a95 100644 --- a/TREnvironmentEditor/Model/Types/Textures/EMCreateStaticMeshFunction.cs +++ b/TREnvironmentEditor/Model/Types/Textures/EMCreateStaticMeshFunction.cs @@ -4,6 +4,7 @@ namespace TREnvironmentEditor.Model; public class EMCreateStaticMeshFunction : BaseEMFunction { + public uint ID { get; set; } public TRMesh Mesh { get; set; } public TRStaticMesh Info { get; set; } @@ -11,20 +12,20 @@ public override void ApplyToLevel(TR1Level level) { TRStaticMesh newMesh = Info.Clone(); newMesh.Mesh = Mesh; - level.StaticMeshes.Add(newMesh); + level.StaticMeshes[(TR1Type)ID] = newMesh; } public override void ApplyToLevel(TR2Level level) { TRStaticMesh newMesh = Info.Clone(); newMesh.Mesh = Mesh; - level.StaticMeshes.Add(newMesh); + level.StaticMeshes[(TR2Type)ID] = newMesh; } public override void ApplyToLevel(TR3Level level) { TRStaticMesh newMesh = Info.Clone(); newMesh.Mesh = Mesh; - level.StaticMeshes.Add(newMesh); + level.StaticMeshes[(TR3Type)ID] = newMesh; } } diff --git a/TRLevelControl/Build/TRObjectMeshBuilder.cs b/TRLevelControl/Build/TRObjectMeshBuilder.cs index 9699c6057..f62c1fabb 100644 --- a/TRLevelControl/Build/TRObjectMeshBuilder.cs +++ b/TRLevelControl/Build/TRObjectMeshBuilder.cs @@ -3,14 +3,15 @@ namespace TRLevelControl.Build; -public class TRObjectMeshBuilder : IMeshProvider +public class TRObjectMeshBuilder : IMeshProvider + where T : Enum { private readonly TRGameVersion _version; private readonly ITRLevelObserver _observer; private uint[] _meshPointers; private Dictionary _objectMeshes; - private Dictionary _staticMeshPointers; + private Dictionary _staticMeshPointers; public TRMesh GetObjectMesh(long pointer) => _objectMeshes[_meshPointers[pointer]]; @@ -95,7 +96,7 @@ public void BuildObjectMeshes(TRLevelReader reader) } } - public void WriteObjectMeshes(TRLevelWriter writer, IEnumerable objectMeshes, List staticMeshes) + public void WriteObjectMeshes(TRLevelWriter writer, IEnumerable objectMeshes, TRDictionary staticMeshes) { List cachedMeshes = new(); List meshPointers = new(); @@ -123,9 +124,9 @@ void StoreMesh(TRMesh m) StoreMesh(mesh); } - foreach (TRStaticMesh staticMesh in staticMeshes) + foreach (var (type, staticMesh) in staticMeshes) { - _staticMeshPointers[staticMesh.ID] = (ushort)meshPointers.Count; + _staticMeshPointers[type] = (ushort)meshPointers.Count; StoreMesh(staticMesh.Mesh); } @@ -136,33 +137,36 @@ void StoreMesh(TRMesh m) writer.Write(meshPointers); } - public List ReadStaticMeshes(TRLevelReader reader) + public TRDictionary ReadStaticMeshes(TRLevelReader reader, T sceneryBase) { + uint sceneryID = (uint)(object)sceneryBase; uint numMeshes = reader.ReadUInt32(); - List meshes = new(); + TRDictionary meshes = new(); for (int i = 0; i < numMeshes; i++) { - meshes.Add(new() + T type = (T)(object)(reader.ReadUInt32() + sceneryID); + meshes[type] = new() { - ID = reader.ReadUInt32(), Mesh = GetObjectMesh(reader.ReadUInt16()), VisibilityBox = reader.ReadBoundingBox(), CollisionBox = reader.ReadBoundingBox(), Flags = reader.ReadUInt16() - }); + }; } return meshes; } - public void WriteStaticMeshes(TRLevelWriter writer, List staticMeshes) + public void WriteStaticMeshes(TRLevelWriter writer, TRDictionary staticMeshes, T sceneryBase) { + uint sceneryID = (uint)(object)sceneryBase; writer.Write((uint)staticMeshes.Count); - foreach (TRStaticMesh staticMesh in staticMeshes) + foreach (T staticType in staticMeshes.Keys) { - writer.Write(staticMesh.ID); - writer.Write(_staticMeshPointers[staticMesh.ID]); + TRStaticMesh staticMesh = staticMeshes[staticType]; + writer.Write((uint)(object)staticType - sceneryID); + writer.Write(_staticMeshPointers[staticType]); writer.Write(staticMesh.VisibilityBox); writer.Write(staticMesh.CollisionBox); writer.Write(staticMesh.Flags); diff --git a/TRLevelControl/Control/TR1LevelControl.cs b/TRLevelControl/Control/TR1LevelControl.cs index 0350d7cc7..611bbf0bc 100644 --- a/TRLevelControl/Control/TR1LevelControl.cs +++ b/TRLevelControl/Control/TR1LevelControl.cs @@ -7,7 +7,7 @@ namespace TRLevelControl; public class TR1LevelControl : TRLevelControlBase { - private readonly TRObjectMeshBuilder _meshBuilder; + private readonly TRObjectMeshBuilder _meshBuilder; private readonly TRSpriteBuilder _spriteBuilder; public TR1LevelControl(ITRLevelObserver observer = null) @@ -264,12 +264,12 @@ private void WriteModelData(TRLevelWriter writer) private void ReadStaticMeshes(TRLevelReader reader) { - _level.StaticMeshes = _meshBuilder.ReadStaticMeshes(reader); + _level.StaticMeshes = _meshBuilder.ReadStaticMeshes(reader, TR1Type.SceneryBase); } private void WriteStaticMeshes(TRLevelWriter writer) { - _meshBuilder.WriteStaticMeshes(writer, _level.StaticMeshes); + _meshBuilder.WriteStaticMeshes(writer, _level.StaticMeshes, TR1Type.SceneryBase); } private void ReadSprites(TRLevelReader reader) diff --git a/TRLevelControl/Control/TR2LevelControl.cs b/TRLevelControl/Control/TR2LevelControl.cs index d06733b2f..ef55158b5 100644 --- a/TRLevelControl/Control/TR2LevelControl.cs +++ b/TRLevelControl/Control/TR2LevelControl.cs @@ -7,7 +7,7 @@ namespace TRLevelControl; public class TR2LevelControl : TRLevelControlBase { - private readonly TRObjectMeshBuilder _meshBuilder; + private readonly TRObjectMeshBuilder _meshBuilder; private readonly TRSpriteBuilder _spriteBuilder; public TR2LevelControl(ITRLevelObserver observer = null) @@ -275,12 +275,12 @@ private void WriteModelData(TRLevelWriter writer) private void ReadStaticMeshes(TRLevelReader reader) { - _level.StaticMeshes = _meshBuilder.ReadStaticMeshes(reader); + _level.StaticMeshes = _meshBuilder.ReadStaticMeshes(reader, TR2Type.SceneryBase); } private void WriteStaticMeshes(TRLevelWriter writer) { - _meshBuilder.WriteStaticMeshes(writer, _level.StaticMeshes); + _meshBuilder.WriteStaticMeshes(writer, _level.StaticMeshes, TR2Type.SceneryBase); } private void ReadSprites(TRLevelReader reader) diff --git a/TRLevelControl/Control/TR3LevelControl.cs b/TRLevelControl/Control/TR3LevelControl.cs index 39e8edb70..a9cd64052 100644 --- a/TRLevelControl/Control/TR3LevelControl.cs +++ b/TRLevelControl/Control/TR3LevelControl.cs @@ -7,7 +7,7 @@ namespace TRLevelControl; public class TR3LevelControl : TRLevelControlBase { - private readonly TRObjectMeshBuilder _meshBuilder; + private readonly TRObjectMeshBuilder _meshBuilder; private readonly TRSpriteBuilder _spriteBuilder; public TR3LevelControl(ITRLevelObserver observer = null) @@ -281,12 +281,12 @@ private void WriteModelData(TRLevelWriter writer) private void ReadStaticMeshes(TRLevelReader reader) { - _level.StaticMeshes = _meshBuilder.ReadStaticMeshes(reader); + _level.StaticMeshes = _meshBuilder.ReadStaticMeshes(reader, TR3Type.SceneryBase); } private void WriteStaticMeshes(TRLevelWriter writer) { - _meshBuilder.WriteStaticMeshes(writer, _level.StaticMeshes); + _meshBuilder.WriteStaticMeshes(writer, _level.StaticMeshes, TR3Type.SceneryBase); } private void ReadSprites(TRLevelReader reader) diff --git a/TRLevelControl/Control/TR4LevelControl.cs b/TRLevelControl/Control/TR4LevelControl.cs index 097d3d028..ecd64d8d4 100644 --- a/TRLevelControl/Control/TR4LevelControl.cs +++ b/TRLevelControl/Control/TR4LevelControl.cs @@ -6,7 +6,7 @@ namespace TRLevelControl; public class TR4LevelControl : TRLevelControlBase { - private readonly TRObjectMeshBuilder _meshBuilder; + private readonly TRObjectMeshBuilder _meshBuilder; private readonly TRSpriteBuilder _spriteBuilder; public TR4LevelControl(ITRLevelObserver observer = null) @@ -206,12 +206,12 @@ private void WriteModelData(TRLevelWriter writer) private void ReadStaticMeshes(TRLevelReader reader) { - _level.StaticMeshes = _meshBuilder.ReadStaticMeshes(reader); + _level.StaticMeshes = _meshBuilder.ReadStaticMeshes(reader, TR4Type.SceneryBase); } private void WriteStaticMeshes(TRLevelWriter writer) { - _meshBuilder.WriteStaticMeshes(writer, _level.StaticMeshes); + _meshBuilder.WriteStaticMeshes(writer, _level.StaticMeshes, TR4Type.SceneryBase); } private void ReadSprites(TRLevelReader reader) diff --git a/TRLevelControl/Control/TR5LevelControl.cs b/TRLevelControl/Control/TR5LevelControl.cs index 359280f07..41a1492ec 100644 --- a/TRLevelControl/Control/TR5LevelControl.cs +++ b/TRLevelControl/Control/TR5LevelControl.cs @@ -6,7 +6,7 @@ namespace TRLevelControl; public class TR5LevelControl : TRLevelControlBase { - private readonly TRObjectMeshBuilder _meshBuilder; + private readonly TRObjectMeshBuilder _meshBuilder; private readonly TRSpriteBuilder _spriteBuilder; public TR5LevelControl(ITRLevelObserver observer = null) @@ -223,12 +223,12 @@ private void WriteModelData(TRLevelWriter writer) private void ReadStaticMeshes(TRLevelReader reader) { - _level.StaticMeshes = _meshBuilder.ReadStaticMeshes(reader); + _level.StaticMeshes = _meshBuilder.ReadStaticMeshes(reader, TR5Type.SceneryBase); } private void WriteStaticMeshes(TRLevelWriter writer) { - _meshBuilder.WriteStaticMeshes(writer, _level.StaticMeshes); + _meshBuilder.WriteStaticMeshes(writer, _level.StaticMeshes, TR5Type.SceneryBase); } private void ReadSprites(TRLevelReader reader) diff --git a/TRLevelControl/Model/Common/TRStaticMesh.cs b/TRLevelControl/Model/Common/TRStaticMesh.cs index ace455d80..5f42150de 100644 --- a/TRLevelControl/Model/Common/TRStaticMesh.cs +++ b/TRLevelControl/Model/Common/TRStaticMesh.cs @@ -2,7 +2,6 @@ public class TRStaticMesh : ICloneable { - public uint ID { get; set; } public TRMesh Mesh { get; set; } public TRBoundingBox VisibilityBox { get; set; } public TRBoundingBox CollisionBox { get; set; } @@ -44,7 +43,6 @@ public TRStaticMesh Clone() { return new() { - ID = ID, Mesh = Mesh.Clone(), VisibilityBox = VisibilityBox.Clone(), CollisionBox = CollisionBox.Clone(), diff --git a/TRLevelControl/Model/TR1/TR1Level.cs b/TRLevelControl/Model/TR1/TR1Level.cs index 3a52d931e..1a50a0791 100644 --- a/TRLevelControl/Model/TR1/TR1Level.cs +++ b/TRLevelControl/Model/TR1/TR1Level.cs @@ -6,7 +6,7 @@ public class TR1Level : TRLevelBase public List Rooms { get; set; } public List FloorData { get; set; } public TRDictionary Models { get; set; } - public List StaticMeshes { get; set; } + public TRDictionary StaticMeshes { get; set; } public List ObjectTextures { get; set; } public TRDictionary Sprites { get; set; } public List Cameras { get; set; } @@ -23,6 +23,6 @@ public class TR1Level : TRLevelBase public SortedDictionary SoundEffects { get; set; } public override IEnumerable DistinctMeshes => Models.Values.SelectMany(m => m.Meshes) - .Concat(StaticMeshes.Select(s => s.Mesh)) + .Concat(StaticMeshes.Values.Select(s => s.Mesh)) .Distinct(); } diff --git a/TRLevelControl/Model/TR2/TR2Level.cs b/TRLevelControl/Model/TR2/TR2Level.cs index df12a497b..e29aee993 100644 --- a/TRLevelControl/Model/TR2/TR2Level.cs +++ b/TRLevelControl/Model/TR2/TR2Level.cs @@ -9,7 +9,7 @@ public class TR2Level : TRLevelBase public List Rooms { get; set; } public List FloorData { get; set; } public TRDictionary Models { get; set; } - public List StaticMeshes { get; set; } + public TRDictionary StaticMeshes { get; set; } public List ObjectTextures { get; set; } public TRDictionary Sprites { get; set; } public List Cameras { get; set; } @@ -25,6 +25,6 @@ public class TR2Level : TRLevelBase public SortedDictionary SoundEffects { get; set; } public override IEnumerable DistinctMeshes => Models.Values.SelectMany(m => m.Meshes) - .Concat(StaticMeshes.Select(s => s.Mesh)) + .Concat(StaticMeshes.Values.Select(s => s.Mesh)) .Distinct(); } diff --git a/TRLevelControl/Model/TR3/TR3Level.cs b/TRLevelControl/Model/TR3/TR3Level.cs index 28aaa8b21..d14c3d1c1 100644 --- a/TRLevelControl/Model/TR3/TR3Level.cs +++ b/TRLevelControl/Model/TR3/TR3Level.cs @@ -9,7 +9,7 @@ public class TR3Level : TRLevelBase public List Rooms { get; set; } public List FloorData { get; set; } public TRDictionary Models { get; set; } - public List StaticMeshes { get; set; } + public TRDictionary StaticMeshes { get; set; } public TRDictionary Sprites { get; set; } public List Cameras { get; set; } public List SoundSources { get; set; } @@ -25,6 +25,6 @@ public class TR3Level : TRLevelBase public SortedDictionary SoundEffects { get; set; } public override IEnumerable DistinctMeshes => Models.Values.SelectMany(m => m.Meshes) - .Concat(StaticMeshes.Select(s => s.Mesh)) + .Concat(StaticMeshes.Values.Select(s => s.Mesh)) .Distinct(); } diff --git a/TRLevelControl/Model/TR4/TR4Level.cs b/TRLevelControl/Model/TR4/TR4Level.cs index 4c0208659..51ff92046 100644 --- a/TRLevelControl/Model/TR4/TR4Level.cs +++ b/TRLevelControl/Model/TR4/TR4Level.cs @@ -6,7 +6,7 @@ public class TR4Level : TRLevelBase public List Rooms { get; set; } public List FloorData { get; set; } public TRDictionary Models { get; set; } - public List StaticMeshes { get; set; } + public TRDictionary StaticMeshes { get; set; } public TRDictionary Sprites { get; set; } public List Cameras { get; set; } public List FlybyCameras { get; set; } @@ -23,6 +23,6 @@ public class TR4Level : TRLevelBase public SortedDictionary SoundEffects { get; set; } public override IEnumerable DistinctMeshes => Models.Values.SelectMany(m => m.Meshes) - .Concat(StaticMeshes.Select(s => s.Mesh)) + .Concat(StaticMeshes.Values.Select(s => s.Mesh)) .Distinct(); } diff --git a/TRLevelControl/Model/TR5/TR5Level.cs b/TRLevelControl/Model/TR5/TR5Level.cs index b2067afa0..39325ddfc 100644 --- a/TRLevelControl/Model/TR5/TR5Level.cs +++ b/TRLevelControl/Model/TR5/TR5Level.cs @@ -8,7 +8,7 @@ public class TR5Level : TRLevelBase public List Rooms { get; set; } public List FloorData { get; set; } public TRDictionary Models { get; set; } - public List StaticMeshes { get; set; } + public TRDictionary StaticMeshes { get; set; } public TRDictionary Sprites { get; set; } public List Cameras { get; set; } public List FlybyCameras { get; set; } @@ -25,6 +25,6 @@ public class TR5Level : TRLevelBase public SortedDictionary SoundEffects { get; set; } public override IEnumerable DistinctMeshes => Models.Values.SelectMany(m => m.Meshes) - .Concat(StaticMeshes.Select(s => s.Mesh)) + .Concat(StaticMeshes.Values.Select(s => s.Mesh)) .Distinct(); } diff --git a/TRModelTransporter/Helpers/TRModelExtensions.cs b/TRModelTransporter/Helpers/TRModelExtensions.cs index f9bc85af4..575ce13f7 100644 --- a/TRModelTransporter/Helpers/TRModelExtensions.cs +++ b/TRModelTransporter/Helpers/TRModelExtensions.cs @@ -247,7 +247,7 @@ private static ushort ConvertTextureReference(ushort textureReference, Dictionar return defaultToOriginal ? textureReference : (ushort)0; } - public static string ComputeSkeletonHash(this IEnumerable meshes, TRGameVersion version) + public static string ComputeSkeletonHash(this IEnumerable meshes) { using MemoryStream ms = new(); using BinaryWriter writer = new(ms); @@ -255,17 +255,14 @@ public static string ComputeSkeletonHash(this IEnumerable meshes, TRGame // We only care about the structure, so reset all texture references // as there is no guarantee these will match across levels. - TRObjectMeshBuilder builder = new(version); + TRObjectMeshBuilder builder = new(TRGameVersion.TR1); foreach (TRMesh mesh in meshes) { TRMesh clone = mesh.Clone(); clone.TexturedRectangles.ForEach(t => t.Texture = 0); clone.TexturedTriangles.ForEach(t => t.Texture = 0); - if (version >= TRGameVersion.TR4) - { - clone.ColouredRectangles.ForEach(t => t.Texture = 0); - clone.ColouredTriangles.ForEach(t => t.Texture = 0); - } + clone.ColouredRectangles?.ForEach(t => t.Texture = 0); + clone.ColouredTriangles?.ForEach(t => t.Texture = 0); writer.Write(builder.Serialize(clone)); } diff --git a/TRRandomizerCore/Randomizers/TR1/TR1OutfitRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/TR1OutfitRandomizer.cs index 9e9379f98..7c9fa8e02 100644 --- a/TRRandomizerCore/Randomizers/TR1/TR1OutfitRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/TR1OutfitRandomizer.cs @@ -690,7 +690,7 @@ private bool ImportGymOutfit(TR1CombinedLevel level) if (existingModel != null) { // If we already have the gym outfit available, we're done. - if (existingModel.Meshes.ComputeSkeletonHash(TRGameVersion.TR1) == _gymOutfitHash) + if (existingModel.Meshes.ComputeSkeletonHash() == _gymOutfitHash) { return true; } diff --git a/TRRandomizerCore/Randomizers/TR2/TR2NightModeRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2NightModeRandomizer.cs index 14b0d89ec..36d3faf1e 100644 --- a/TRRandomizerCore/Randomizers/TR2/TR2NightModeRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2NightModeRandomizer.cs @@ -118,10 +118,9 @@ private void HideDaytimeEntities(TR2Level level, string levelName) // Hide any static meshes if (_staticMeshesToHide.ContainsKey(levelName)) { - List staticMeshes = level.StaticMeshes.ToList(); - foreach (uint meshID in _staticMeshesToHide[levelName]) + foreach (TR2Type type in _staticMeshesToHide[levelName]) { - TRStaticMesh mesh = staticMeshes.Find(m => m.ID == meshID); + TRStaticMesh mesh = level.StaticMeshes[type]; if (mesh != null) { mesh.NonCollidable = true; @@ -136,13 +135,13 @@ private void HideDaytimeEntities(TR2Level level, string levelName) [TR2Type.SingingBirds_N] = TR2Type.Flares_S_P // Birds don't sing at night }; - private static readonly Dictionary _staticMeshesToHide = new() + private static readonly Dictionary _staticMeshesToHide = new() { // The washing lines come in at night [TR2LevelNames.VENICE] = - new uint[] { 32, 33 }, + new TR2Type[] { TR2Type.Architecture2, TR2Type.Architecture3 }, // The monks are washing their prayer flags [TR2LevelNames.MONASTERY] = - new uint[] { 36 } + new TR2Type[] { TR2Type.Architecture6 } }; } diff --git a/TRRandomizerCore/Resources/TR1/Environment/EGYPT.PHD-Environment.json b/TRRandomizerCore/Resources/TR1/Environment/EGYPT.PHD-Environment.json index 0e8322533..83366378c 100644 --- a/TRRandomizerCore/Resources/TR1/Environment/EGYPT.PHD-Environment.json +++ b/TRRandomizerCore/Resources/TR1/Environment/EGYPT.PHD-Environment.json @@ -4064,6 +4064,7 @@ }, { "EMType": 34, + "ID": 206, "Mesh": { "Pointer": 87280, "Centre": {}, @@ -4267,7 +4268,6 @@ "ColouredTriangles": [] }, "Info": { - "ID": 15, "Mesh": 260, "VisibilityBox": { "MinX": -166, diff --git a/TRRandomizerCore/Resources/TR2/Environment/EMPRTOMB.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/EMPRTOMB.TR2-Environment.json index f4cddc370..6c1d28ba7 100644 --- a/TRRandomizerCore/Resources/TR2/Environment/EMPRTOMB.TR2-Environment.json +++ b/TRRandomizerCore/Resources/TR2/Environment/EMPRTOMB.TR2-Environment.json @@ -1931,6 +1931,7 @@ { "Comments": "Create a dummy static mesh.", "EMType": 34, + "ID": 292, "Mesh": { "Centre": {}, "Vertices": [], @@ -1942,7 +1943,6 @@ "ColouredTriangles": [] }, "Info": { - "ID": 27, "VisibilityBox": { "MinX": -3584, "MaxX": 512, diff --git a/TRRandomizerCore/Resources/TR2/Environment/OPERA.TR2-Environment.json b/TRRandomizerCore/Resources/TR2/Environment/OPERA.TR2-Environment.json index cc21553e4..61de7d5a9 100644 --- a/TRRandomizerCore/Resources/TR2/Environment/OPERA.TR2-Environment.json +++ b/TRRandomizerCore/Resources/TR2/Environment/OPERA.TR2-Environment.json @@ -1244,6 +1244,7 @@ "Tags": [ 11 ], + "ID": 292, "Mesh": { "Centre": {}, "Vertices": [], @@ -1255,7 +1256,6 @@ "ColouredTriangles": [] }, "Info": { - "ID": 27, "VisibilityBox": { "MinX": -512, "MaxX": 2560, diff --git a/TRRandomizerCore/Textures/DynamicTextureBuilder.cs b/TRRandomizerCore/Textures/DynamicTextureBuilder.cs index e043c2f00..18d39d0d8 100644 --- a/TRRandomizerCore/Textures/DynamicTextureBuilder.cs +++ b/TRRandomizerCore/Textures/DynamicTextureBuilder.cs @@ -101,7 +101,7 @@ public DynamicTextureTarget Build(TR1CombinedLevel level) } // Include all static mesh textures - foreach (TRStaticMesh staticMesh in level.Data.StaticMeshes) + foreach (TRStaticMesh staticMesh in level.Data.StaticMeshes.Values) { AddMeshTextures(staticMesh.Mesh, defaultObjectTextures); if (!RetainMainTextures) diff --git a/TRRandomizerCore/Utilities/Locations/AbstractLocationGenerator.cs b/TRRandomizerCore/Utilities/Locations/AbstractLocationGenerator.cs index f10846198..cb996eb20 100644 --- a/TRRandomizerCore/Utilities/Locations/AbstractLocationGenerator.cs +++ b/TRRandomizerCore/Utilities/Locations/AbstractLocationGenerator.cs @@ -7,7 +7,9 @@ namespace TRRandomizerCore.Utilities; -public abstract class AbstractLocationGenerator where L : class +public abstract class AbstractLocationGenerator + where L : TRLevelBase + where T : Enum { protected static readonly int _standardHeight = TRConsts.Step3; protected static readonly int _crawlspaceHeight = TRConsts.Step2; @@ -60,7 +62,10 @@ protected void DetermineBaseExcludedSectors(L level, List exclusions, } } - List collidableMeshes = GetCollidableStaticMeshes(level); + List collidableMeshes = GetStaticMeshes(level) + .Where(kvp => !IsPermittableMesh(kvp.Value)) + .Select(kvp => kvp.Key) + .ToList(); for (short r = 0; r < GetRoomCount(level); r++) { @@ -87,12 +92,12 @@ protected void DetermineBaseExcludedSectors(L level, List exclusions, } // If there are any collidable static meshes in this room, exclude the sectors they're on - Dictionary> meshLocations = GetRoomStaticMeshLocations(level, r); - foreach (ushort meshID in meshLocations.Keys) + Dictionary> meshLocations = GetRoomStaticMeshLocations(level, r); + foreach (var (type, locations) in meshLocations) { - if (collidableMeshes.Find(m => m.ID == meshID) != null) + if (collidableMeshes.Contains(type)) { - foreach (Location location in meshLocations[meshID]) + foreach (Location location in locations) { _excludedSectors.Add(GetSector(location, level)); } @@ -101,13 +106,6 @@ protected void DetermineBaseExcludedSectors(L level, List exclusions, } } - protected List GetCollidableStaticMeshes(L level) - { - return GetStaticMeshes(level) - .Where(m => !IsPermittableMesh(m)) - .ToList(); - } - private static bool IsPermittableMesh(TRStaticMesh mesh) { // TR1/2 use a hitbox flag @@ -709,11 +707,11 @@ private static Location CreateLocation(short roomIndex, TRRoomSector sector, int protected abstract TRRoomSector GetSector(Location location, L level); protected abstract TRRoomSector GetSector(int x, int z, int roomIndex, L level); protected abstract List GetRoomSectors(L level, int room); - protected abstract List GetStaticMeshes(L level); + protected abstract TRDictionary GetStaticMeshes(L level); protected abstract int GetRoomCount(L level); protected abstract short GetFlipMapRoom(L level, short room); protected abstract bool IsRoomValid(L level, short room); - protected abstract Dictionary> GetRoomStaticMeshLocations(L level, short room); + protected abstract Dictionary> GetRoomStaticMeshLocations(L level, short room); protected abstract ushort GetRoomDepth(L level, short room); protected abstract int GetRoomYTop(L level, short room); protected abstract Vector2 GetRoomPosition(L level, short room); diff --git a/TRRandomizerCore/Utilities/Locations/TR1LocationGenerator.cs b/TRRandomizerCore/Utilities/Locations/TR1LocationGenerator.cs index 5180f0ad5..8298a960b 100644 --- a/TRRandomizerCore/Utilities/Locations/TR1LocationGenerator.cs +++ b/TRRandomizerCore/Utilities/Locations/TR1LocationGenerator.cs @@ -7,7 +7,7 @@ namespace TRRandomizerCore.Utilities; -public class TR1LocationGenerator : AbstractLocationGenerator +public class TR1LocationGenerator : AbstractLocationGenerator { public override bool CrawlspacesAllowed => false; public override bool WadingAllowed => false; @@ -33,9 +33,9 @@ protected override List GetRoomSectors(TR1Level level, int room) return level.Rooms[room].Sectors.ToList(); } - protected override List GetStaticMeshes(TR1Level level) + protected override TRDictionary GetStaticMeshes(TR1Level level) { - return level.StaticMeshes.ToList(); + return level.StaticMeshes; } protected override int GetRoomCount(TR1Level level) @@ -60,17 +60,14 @@ protected override bool TriggerSupportsItems(TR1Level level, FDTriggerEntry trig && level.Entities[a.Parameter].TypeID == TR1Type.ThorHammerHandle); } - protected override Dictionary> GetRoomStaticMeshLocations(TR1Level level, short room) + protected override Dictionary> GetRoomStaticMeshLocations(TR1Level level, short room) { - Dictionary> locations = new(); + Dictionary> locations = new(); foreach (TR1RoomStaticMesh staticMesh in level.Rooms[room].StaticMeshes) { - if (!locations.ContainsKey(staticMesh.MeshID)) - { - locations[staticMesh.MeshID] = new List(); - } - - locations[staticMesh.MeshID].Add(new Location + TR1Type id = staticMesh.MeshID + TR1Type.SceneryBase; + locations[id] ??= new(); + locations[id].Add(new() { X = (int)staticMesh.X, Y = (int)staticMesh.Y, diff --git a/TRRandomizerCore/Utilities/Locations/TR2LocationGenerator.cs b/TRRandomizerCore/Utilities/Locations/TR2LocationGenerator.cs index 3595fa7e4..14371858d 100644 --- a/TRRandomizerCore/Utilities/Locations/TR2LocationGenerator.cs +++ b/TRRandomizerCore/Utilities/Locations/TR2LocationGenerator.cs @@ -5,7 +5,7 @@ namespace TRRandomizerCore.Utilities; -public class TR2LocationGenerator : AbstractLocationGenerator +public class TR2LocationGenerator : AbstractLocationGenerator { public override bool CrawlspacesAllowed => false; public override bool WadingAllowed => true; @@ -31,9 +31,9 @@ protected override List GetRoomSectors(TR2Level level, int room) return level.Rooms[room].SectorList.ToList(); } - protected override List GetStaticMeshes(TR2Level level) + protected override TRDictionary GetStaticMeshes(TR2Level level) { - return level.StaticMeshes.ToList(); + return level.StaticMeshes; } protected override int GetRoomCount(TR2Level level) @@ -51,17 +51,14 @@ protected override bool IsRoomValid(TR2Level level, short room) return true; } - protected override Dictionary> GetRoomStaticMeshLocations(TR2Level level, short room) + protected override Dictionary> GetRoomStaticMeshLocations(TR2Level level, short room) { - Dictionary> locations = new(); + Dictionary> locations = new(); foreach (TR2RoomStaticMesh staticMesh in level.Rooms[room].StaticMeshes) { - if (!locations.ContainsKey(staticMesh.MeshID)) - { - locations[staticMesh.MeshID] = new List(); - } - - locations[staticMesh.MeshID].Add(new Location + TR2Type id = staticMesh.MeshID + TR2Type.SceneryBase; + locations[id] ??= new(); + locations[id].Add(new() { X = (int)staticMesh.X, Y = (int)staticMesh.Y, diff --git a/TRRandomizerCore/Utilities/Locations/TR3LocationGenerator.cs b/TRRandomizerCore/Utilities/Locations/TR3LocationGenerator.cs index 11fb52e1e..f0b9d0f08 100644 --- a/TRRandomizerCore/Utilities/Locations/TR3LocationGenerator.cs +++ b/TRRandomizerCore/Utilities/Locations/TR3LocationGenerator.cs @@ -5,7 +5,7 @@ namespace TRRandomizerCore.Utilities; -public class TR3LocationGenerator : AbstractLocationGenerator +public class TR3LocationGenerator : AbstractLocationGenerator { public override bool CrawlspacesAllowed => true; public override bool WadingAllowed => true; @@ -31,9 +31,9 @@ protected override List GetRoomSectors(TR3Level level, int room) return level.Rooms[room].Sectors.ToList(); } - protected override List GetStaticMeshes(TR3Level level) + protected override TRDictionary GetStaticMeshes(TR3Level level) { - return level.StaticMeshes.ToList(); + return level.StaticMeshes; } protected override int GetRoomCount(TR3Level level) @@ -51,17 +51,14 @@ protected override bool IsRoomValid(TR3Level level, short room) return !level.Rooms[room].IsSwamp; } - protected override Dictionary> GetRoomStaticMeshLocations(TR3Level level, short room) + protected override Dictionary> GetRoomStaticMeshLocations(TR3Level level, short room) { - Dictionary> locations = new(); + Dictionary> locations = new(); foreach (TR3RoomStaticMesh staticMesh in level.Rooms[room].StaticMeshes) { - if (!locations.ContainsKey(staticMesh.MeshID)) - { - locations[staticMesh.MeshID] = new List(); - } - - locations[staticMesh.MeshID].Add(new Location + TR3Type id = staticMesh.MeshID + TR3Type.SceneryBase; + locations[id] ??= new(); + locations[id].Add(new() { X = (int)staticMesh.X, Y = (int)staticMesh.Y,