diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b236b05..5a55613e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ## [Unreleased](https://github.com/LostArtefacts/TR-Rando/compare/V1.9.1...master) - xxxx-xx-xx +- fixed key item softlocks in TR1R New Game+ (#732) - fixed wireframe mode potentially exceeding texture limits and preventing levels from loading (#722) - fixed docile bird monsters causing multiple Laras to spawn in remastered levels (#723) - fixed the incomplete skidoo model in TR2R when it appears anywhere other than Tibetan Foothills (#721) diff --git a/TRLevelControl/Helpers/TR1TypeUtilities.cs b/TRLevelControl/Helpers/TR1TypeUtilities.cs index c8b6c8d5..a582ca0c 100644 --- a/TRLevelControl/Helpers/TR1TypeUtilities.cs +++ b/TRLevelControl/Helpers/TR1TypeUtilities.cs @@ -254,6 +254,11 @@ public static bool IsStandardPickupType(TR1Type type) return GetStandardPickupTypes().Contains(type); } + public static bool IsMediType(TR1Type type) + { + return type == TR1Type.SmallMed_S_P || type == TR1Type.LargeMed_S_P; + } + public static bool IsWeaponPickup(TR1Type type) { return GetWeaponPickups().Contains(type); diff --git a/TRRandomizerCore/Randomizers/TR1/Remastered/TR1RItemRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/Remastered/TR1RItemRandomizer.cs index b01ca56c..d6b3e010 100644 --- a/TRRandomizerCore/Randomizers/TR1/Remastered/TR1RItemRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/Remastered/TR1RItemRandomizer.cs @@ -3,6 +3,7 @@ using TRLevelControl.Model; using TRRandomizerCore.Helpers; using TRRandomizerCore.Levels; +using TRRandomizerCore.Utilities; namespace TRRandomizerCore.Randomizers; @@ -51,6 +52,7 @@ public void FinalizeRandomization() if (Settings.ItemMode == ItemMode.Shuffled) { _allocator.ApplyItemSwaps(_levelInstance.Name, _levelInstance.Data.Entities); + AdjustNGPlusItems(_levelInstance); } else { @@ -77,4 +79,29 @@ private static void CheckTihocanPierre(TR1RCombinedLevel level) level.Data.Entities.AddRange(TR1ItemAllocator.TihocanEndItems); } + + private void AdjustNGPlusItems(TR1RCombinedLevel level) + { + // If keys have ended up as OG medi-packs, NG+ will convert them to ammo and hence softlock-city. + // Duplicate the items so the game doesn't know their indices, and hide the originals. + List keyItems = level.Data.Entities.FindAll(e => TR1TypeUtilities.IsKeyItemType(e.TypeID)); + TR1Level ogLevel = _levelControl.Read(Path.Combine(BackupPath, level.Name)); + foreach (TR1Entity item in keyItems) + { + int currentIndex = level.Data.Entities.IndexOf(item); + if (currentIndex < ogLevel.Entities.Count + && TR1TypeUtilities.IsMediType(ogLevel.Entities[currentIndex].TypeID)) + { + level.Data.Entities.Add((TR1Entity)item.Clone()); + item.TypeID = TR1Type.CameraTarget_N; + ItemUtilities.HideEntity(item); + + // Any triggers will need to match the new index + short newIndex = (short)(level.Data.Entities.Count - 1); + level.Data.FloorData.GetEntityTriggers(currentIndex) + .SelectMany(t => t.Actions.Where(a => a.Action == FDTrigAction.Object && a.Parameter == currentIndex)) + .ToList().ForEach(a => a.Parameter = newIndex); + } + } + } }