From 362ca6b0759a525a6840578f5c34e43091524b5e Mon Sep 17 00:00:00 2001 From: lahm86 <33758420+lahm86@users.noreply.github.com> Date: Sun, 23 Jun 2024 10:53:42 +0100 Subject: [PATCH] Miscellaneous TRR fixes (#715) Resolves #712. Resolves #713. Resolves #714. Resolves #716. Resolves #717. Resolves #718. --- CHANGELOG.md | 10 +- .../Data/Remastered/TR3RDataCache.cs | 1 + .../Editors/TR1RemasteredEditor.cs | 1 - .../TR1/Classic/TR1EnemyRandomizer.cs | 2 +- .../TR1/Remastered/TR1REnemyRandomizer.cs | 17 +- .../TR1/Shared/TR1EnemyAllocator.cs | 6 +- .../TR3/Remastered/TR3RItemRandomizer.cs | 10 + .../Environment/LEVEL10C.PHD-Environment.json | 183 ++++++++++++++++++ .../Environment/LEVEL3B.PHD-Environment.json | 12 ++ TRRandomizerCore/TRVersionSupport.cs | 1 + TRRandomizerView/App.xaml | 40 ++++ TRRandomizerView/Model/ControllerOptions.cs | 8 + TRRandomizerView/TRRandomizerView.csproj | 2 +- TRRandomizerView/Windows/AdvancedWindow.xaml | 3 +- TRRandomizerView/Windows/MessageWindow.xaml | 14 +- .../Windows/MessageWindow.xaml.cs | 3 +- 16 files changed, 292 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20579e51c..24ee8ef13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,12 @@ -## [Unreleased](https://github.com/LostArtefacts/TR-Rando/compare/V1.9.0...master) - xxxx-xx-xx +## [Unreleased](https://github.com/LostArtefacts/TR-Rando/compare/V1.9.1...master) - xxxx-xx-xx + +## [V1.9.1](https://github.com/LostArtefacts/TR-Rando/compare/V1.9.0...V1.9.1) - 2024-06-23 +- fixed a missing reference related to Willard, which would cause enemy randomization to fail if he was selected (#712) +- fixed the "show error folder" link in popup message windows not working (#713) +- fixed being unable to randomize enemies natively in TR1R (#716) +- fixed the key in Jungle appearing mid-air or inside walls (#717) +- fixed a pickup issue in Natla's Mines that could cause a crash (#718) +- restored the option to replace required enemies in TR1R (#714) ## [V1.9.0](https://github.com/LostArtefacts/TR-Rando/compare/V1.8.4...V1.9.0) - 2024-06-22 - added support for TR1X V4 (#626) diff --git a/TRDataControl/Data/Remastered/TR3RDataCache.cs b/TRDataControl/Data/Remastered/TR3RDataCache.cs index 247e0c16f..73d301cc5 100644 --- a/TRDataControl/Data/Remastered/TR3RDataCache.cs +++ b/TRDataControl/Data/Remastered/TR3RDataCache.cs @@ -116,6 +116,7 @@ public override TR3RAlias GetAlias(TR3Type key) [TR3Type.TinnosWasp] = TR3LevelNames.TINNOS, [TR3Type.Willie] = TR3LevelNames.WILLIE, + [TR3Type.AIPath_N] = TR3LevelNames.WILLIE, [TR3Type.RXGunLad] = TR3LevelNames.WILLIE, [TR3Type.Winston] = TR3LevelNames.ASSAULT, diff --git a/TRRandomizerCore/Editors/TR1RemasteredEditor.cs b/TRRandomizerCore/Editors/TR1RemasteredEditor.cs index da9588a0a..d47cbccae 100644 --- a/TRRandomizerCore/Editors/TR1RemasteredEditor.cs +++ b/TRRandomizerCore/Editors/TR1RemasteredEditor.cs @@ -18,7 +18,6 @@ protected override void ApplyConfig(Config config) Settings.AllowReturnPathLocations = false; Settings.AddReturnPaths = false; Settings.FixOGBugs = false; - Settings.ReplaceRequiredEnemies = false; Settings.SwapEnemyAppearance = false; Settings.SecretRewardMode = TRSecretRewardMode.Stack; } diff --git a/TRRandomizerCore/Randomizers/TR1/Classic/TR1EnemyRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/Classic/TR1EnemyRandomizer.cs index 913236b6a..65229b7c5 100644 --- a/TRRandomizerCore/Randomizers/TR1/Classic/TR1EnemyRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/Classic/TR1EnemyRandomizer.cs @@ -287,7 +287,7 @@ private void AddUnarmedLevelAmmo(TR1CombinedLevel level) return; } - _allocator.AddUnarmedLevelAmmo(level.Name, level.Data, (loc, type) => + _allocator.AddUnarmedLevelAmmo(level.Name, level.Data, true, (loc, type) => { level.Script.AddStartInventoryItem(ItemUtilities.ConvertToScriptItem(type)); }); diff --git a/TRRandomizerCore/Randomizers/TR1/Remastered/TR1REnemyRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/Remastered/TR1REnemyRandomizer.cs index cc8ad1e6d..e83d7921c 100644 --- a/TRRandomizerCore/Randomizers/TR1/Remastered/TR1REnemyRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/Remastered/TR1REnemyRandomizer.cs @@ -120,7 +120,7 @@ private void ApplyPostRandomization(TR1RCombinedLevel level, EnemyRandomizationC private void UpdateAtlanteanPDP(TR1RCombinedLevel level, EnemyRandomizationCollection enemies) { - if (!enemies.Available.Contains(TR1Type.ShootingAtlantean_N) || level.PDPData.ContainsKey(TR1Type.ShootingAtlantean_N)) + if (enemies == null || !enemies.Available.Contains(TR1Type.ShootingAtlantean_N) || level.PDPData.ContainsKey(TR1Type.ShootingAtlantean_N)) { return; } @@ -167,7 +167,7 @@ private void AdjustTihocanEnding(TR1RCombinedLevel level) level.Data.Entities.AddRange(TR1ItemAllocator.TihocanEndItems); } - private static void AdjustScionEnding(TR1RCombinedLevel level) + private void AdjustScionEnding(TR1RCombinedLevel level) { if (level.Data.Models.ContainsKey(TR1Type.ScionPiece4_S_P) && (level.Data.Models.ContainsKey(TR1Type.TRex) || level.Data.Models.ContainsKey(TR1Type.Adam))) @@ -176,6 +176,17 @@ private static void AdjustScionEnding(TR1RCombinedLevel level) // but support for PDP isn't there yet. level.PDPData.ChangeKey(TR1Type.ScionPiece4_S_P, TR1Type.ScionPiece3_S_P); } + else if (level.Is(TR1LevelNames.QUALOPEC) && Settings.ReplaceRequiredEnemies) + { + // The scion must be shot to end the level - in OG, it's hidden and a Qualopec skeleton is the target; + // we can't add remastered meshes yet so we just add the actual scion so it's obvious, and make the sound + // effect from Pyramid available too. + TRDictionary pyramidPDP = _pdpControl.Read(Path.Combine(BackupPath, Path.ChangeExtension(TR1LevelNames.PYRAMID, ".PDP"))); + level.PDPData[TR1Type.ScionPiece3_S_P] = pyramidPDP[TR1Type.ScionPiece3_S_P]; + + TR1Level pyramidLevel = _levelControl.Read(Path.Combine(BackupPath, TR1LevelNames.PYRAMID)); + level.Data.SoundEffects[TR1SFX.ScionLoop] = pyramidLevel.SoundEffects[TR1SFX.ScionLoop]; + } } private void AddUnarmedLevelAmmo(TR1RCombinedLevel level) @@ -185,7 +196,7 @@ private void AddUnarmedLevelAmmo(TR1RCombinedLevel level) return; } - _allocator.AddUnarmedLevelAmmo(level.Name, level.Data, (loc, type) => + _allocator.AddUnarmedLevelAmmo(level.Name, level.Data, false, (loc, type) => { if (ItemFactory.CanCreateItem(level.Name, level.Data.Entities)) { diff --git a/TRRandomizerCore/Randomizers/TR1/Shared/TR1EnemyAllocator.cs b/TRRandomizerCore/Randomizers/TR1/Shared/TR1EnemyAllocator.cs index b34127018..0b659b409 100644 --- a/TRRandomizerCore/Randomizers/TR1/Shared/TR1EnemyAllocator.cs +++ b/TRRandomizerCore/Randomizers/TR1/Shared/TR1EnemyAllocator.cs @@ -734,7 +734,7 @@ private void AmendAtlanteanModels(TR1Level level, EnemyRandomizationCollection createItemCallback) + public void AddUnarmedLevelAmmo(string levelName, TR1Level level, bool changeWeapon, Action createItemCallback) { if (!Settings.CrossLevelEnemies || !Settings.GiveUnarmedItems) { @@ -783,7 +783,7 @@ public void AddUnarmedLevelAmmo(string levelName, TR1Level level, Action EnemyDifficulty.Easy) + if (changeWeapon && difficulty > EnemyDifficulty.Easy) { while (weaponEntity.TypeID == TR1Type.Pistols_S_P) { @@ -793,7 +793,7 @@ public void AddUnarmedLevelAmmo(string levelName, TR1Level level, Action 0) + if (changeWeapon && ammoAllocation > 0) { ammoAllocation *= (int)difficulty; TR1Type ammoType = TR1TypeUtilities.GetWeaponAmmo(weaponType); diff --git a/TRRandomizerCore/Randomizers/TR3/Remastered/TR3RItemRandomizer.cs b/TRRandomizerCore/Randomizers/TR3/Remastered/TR3RItemRandomizer.cs index 83602e5f7..0c1faea9b 100644 --- a/TRRandomizerCore/Randomizers/TR3/Remastered/TR3RItemRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR3/Remastered/TR3RItemRandomizer.cs @@ -1,4 +1,5 @@ using TRGE.Core; +using TRLevelControl; using TRLevelControl.Helpers; using TRLevelControl.Model; using TRRandomizerCore.Helpers; @@ -61,6 +62,15 @@ public void FinalizeRandomization() _levelInstance.Script.OriginalSequence, _levelInstance.HasExposureMeter); } + if (_levelInstance.Is(TR3LevelNames.JUNGLE) + && _levelInstance.Data.Entities.Find(e => e.TypeID == TR3Type.Key4_P) is TR3Entity key) + { + // Counteract the shift done by the game in patch 3. Nudge it slightly further in case + // we land on an enemy. + key.X += TRConsts.Step2 * 3 + 1; + key.Z += TRConsts.Step2; + } + SaveLevelInstance(); } diff --git a/TRRandomizerCore/Resources/TR1/Environment/LEVEL10C.PHD-Environment.json b/TRRandomizerCore/Resources/TR1/Environment/LEVEL10C.PHD-Environment.json index e588356d0..885ddf0e9 100644 --- a/TRRandomizerCore/Resources/TR1/Environment/LEVEL10C.PHD-Environment.json +++ b/TRRandomizerCore/Resources/TR1/Environment/LEVEL10C.PHD-Environment.json @@ -3193,6 +3193,9 @@ { "Comments": "Make a room to house a switch.", "EMType": 126, + "Tags": [ + 14 + ], "Location": { "X": 57344, "Y": -14592, @@ -3254,6 +3257,9 @@ { "Comments": "Collisional portals.", "EMType": 82, + "Tags": [ + 14 + ], "Portals": { "36": { "-1": [ @@ -3278,6 +3284,9 @@ { "Comments": "Visibility portals.", "EMType": 81, + "Tags": [ + 14 + ], "Portals": [ { "BaseRoom": 36, @@ -3342,6 +3351,9 @@ { "Comments": "Add a lever texture.", "EMType": 21, + "Tags": [ + 14 + ], "TextureMap": { "42": { "-1": { @@ -3355,6 +3367,9 @@ { "Comments": "Remove faces for portals.", "EMType": 22, + "Tags": [ + 14 + ], "GeometryMap": { "-1": { "Rectangles": [ @@ -3365,6 +3380,9 @@ }, { "EMType": 23, + "Tags": [ + 14 + ], "Modifications": [ { "RoomNumber": 36, @@ -3383,6 +3401,9 @@ { "Comments": "Let there be light.", "EMType": 128, + "Tags": [ + 14 + ], "RoomIndices": [ -1 ] @@ -3390,6 +3411,9 @@ { "Comments": "Add a switch.", "EMType": 51, + "Tags": [ + 14 + ], "TypeID": 55, "Intensity": -1, "Location": { @@ -3403,6 +3427,9 @@ { "Comments": "Duplicate one of the heavy triggers to capture everything Adam would trigger.", "EMType": 63, + "Tags": [ + 14 + ], "Locations": [ { "X": 59904, @@ -3421,6 +3448,9 @@ { "Comments": "Convert the duplicated trigger into a switch type.", "EMType": 69, + "Tags": [ + 14 + ], "Location": { "X": 59904, "Y": -14592, @@ -3433,6 +3463,9 @@ { "Comments": "Clear the heavy triggers from the platform.", "EMType": 62, + "Tags": [ + 14 + ], "Rooms": [ 36 ], @@ -3443,6 +3476,9 @@ { "Comments": "Add a door.", "EMType": 51, + "Tags": [ + 14 + ], "TypeID": 57, "Intensity": 4096, "Location": { @@ -3455,6 +3491,9 @@ { "Comments": "Add another switch.", "EMType": 51, + "Tags": [ + 14 + ], "TypeID": 55, "Intensity": -1, "Location": { @@ -3468,6 +3507,9 @@ { "Comments": "Trigger the new door.", "EMType": 61, + "Tags": [ + 14 + ], "EntityLocation": -1, "Trigger": { "TrigType": 2, @@ -3479,6 +3521,147 @@ } ] } + }, + { + "Comments": "Clear the heavy triggers from the platform (TR1R).", + "EMType": 62, + "Tags": [ + 13 + ], + "Rooms": [ + 36 + ], + "TrigTypes": [ + 5 + ] + }, + { + "Comments": "Add 4 switches (TR1R).", + "EMType": 51, + "Tags": [ + 13 + ], + "TypeID": 55, + "Intensity": -1, + "Location": { + "X": 64000, + "Y": -15616, + "Z": 14848, + "Room": 36 + } + }, + { + "EMType": 51, + "Tags": [ + 13 + ], + "TypeID": 55, + "Intensity": -1, + "Location": { + "X": 65024, + "Y": -15616, + "Z": 14848, + "Room": 36 + } + }, + { + "EMType": 51, + "Tags": [ + 13 + ], + "TypeID": 55, + "Intensity": -1, + "Location": { + "X": 64000, + "Y": -15616, + "Z": 8704, + "Room": 36, + "Angle": -32768 + } + }, + { + "EMType": 51, + "Tags": [ + 13 + ], + "TypeID": 55, + "Intensity": -1, + "Location": { + "X": 65024, + "Y": -15616, + "Z": 8704, + "Room": 36, + "Angle": -32768 + } + }, + { + "Comments": "Switches open the door (TR1R).", + "EMType": 61, + "Tags": [ + 13 + ], + "EntityLocation": -1, + "Trigger": { + "TrigType": 2, + "Mask": 3, + "SwitchOrKeyRef": -1, + "Actions": [ + { + "Parameter": 86 + } + ] + } + }, + { + "EMType": 61, + "Tags": [ + 13 + ], + "EntityLocation": -2, + "Trigger": { + "TrigType": 2, + "Mask": 4, + "SwitchOrKeyRef": -2, + "Actions": [ + { + "Parameter": 86 + } + ] + } + }, + { + "EMType": 61, + "Tags": [ + 13 + ], + "EntityLocation": -3, + "Trigger": { + "TrigType": 2, + "Mask": 8, + "SwitchOrKeyRef": -3, + "Actions": [ + { + "Parameter": 86 + } + ] + } + }, + { + "EMType": 61, + "Tags": [ + 13 + ], + "EntityLocation": -4, + "Trigger": { + "TrigType": 2, + "Mask": 16, + "SwitchOrKeyRef": -4, + "Actions": [ + { + "Parameter": 86 + } + ] + } } ] } diff --git a/TRRandomizerCore/Resources/TR1/Environment/LEVEL3B.PHD-Environment.json b/TRRandomizerCore/Resources/TR1/Environment/LEVEL3B.PHD-Environment.json index 00ff351ec..e0812a814 100644 --- a/TRRandomizerCore/Resources/TR1/Environment/LEVEL3B.PHD-Environment.json +++ b/TRRandomizerCore/Resources/TR1/Environment/LEVEL3B.PHD-Environment.json @@ -5932,6 +5932,18 @@ "Angle": 16384 } }, + { + "Comments": "Add a sound effect for it (TR1R only).", + "EMType": 101, + "Tags": [ + 13 + ], + "ID": 154, + "Mode": 192, + "X": 39424, + "Y": 4864, + "Z": 55808 + }, { "Comments": "Trigger the scion.", "EMType": 68, diff --git a/TRRandomizerCore/TRVersionSupport.cs b/TRRandomizerCore/TRVersionSupport.cs index aee760500..641f16ee1 100644 --- a/TRRandomizerCore/TRVersionSupport.cs +++ b/TRRandomizerCore/TRVersionSupport.cs @@ -71,6 +71,7 @@ internal class TRVersionSupport TRRandomizerType.HideDeadTrexes, TRRandomizerType.Item, TRRandomizerType.KeyItems, + TRRandomizerType.LarsonBehaviour, TRRandomizerType.Secret, TRRandomizerType.SecretAudio, TRRandomizerType.SecretReward, diff --git a/TRRandomizerView/App.xaml b/TRRandomizerView/App.xaml index 4803b2e59..ee29e04b3 100644 --- a/TRRandomizerView/App.xaml +++ b/TRRandomizerView/App.xaml @@ -206,5 +206,45 @@ + + diff --git a/TRRandomizerView/Model/ControllerOptions.cs b/TRRandomizerView/Model/ControllerOptions.cs index d73b886c0..369e6fde0 100644 --- a/TRRandomizerView/Model/ControllerOptions.cs +++ b/TRRandomizerView/Model/ControllerOptions.cs @@ -2854,9 +2854,15 @@ public bool UseEnemyExclusions { _useEnemyExclusions = value; FirePropertyChanged(); + FirePropertyChanged(nameof(CanSelectEnemyExclusions)); } } + public bool CanSelectEnemyExclusions + { + get => _crossLevelEnemies.Value && _useEnemyExclusions; + } + public bool ShowExclusionWarnings { get => _showExclusionWarnings; @@ -3159,6 +3165,8 @@ public ControllerOptions() Description = "Allow enemy types to appear in any level." }; BindingOperations.SetBinding(CrossLevelEnemies, BoolItemControlClass.IsActiveProperty, randomizeEnemiesBinding); + CrossLevelEnemies.PropertyChanged += (e, s) => FirePropertyChanged(nameof(CanSelectEnemyExclusions)); + DocileWillard = new BoolItemControlClass() { Title = "Enable docile Willard", diff --git a/TRRandomizerView/TRRandomizerView.csproj b/TRRandomizerView/TRRandomizerView.csproj index c85fe9801..7825ae7f9 100644 --- a/TRRandomizerView/TRRandomizerView.csproj +++ b/TRRandomizerView/TRRandomizerView.csproj @@ -20,7 +20,7 @@ false Resources\rando.ico - 1.9.0 + 1.9.1 Tomb Raider Randomizer Copyright © Tomb Raider Community 2024 diff --git a/TRRandomizerView/Windows/AdvancedWindow.xaml b/TRRandomizerView/Windows/AdvancedWindow.xaml index ec6834835..91a743210 100644 --- a/TRRandomizerView/Windows/AdvancedWindow.xaml +++ b/TRRandomizerView/Windows/AdvancedWindow.xaml @@ -525,6 +525,7 @@ diff --git a/TRRandomizerView/Windows/MessageWindow.xaml b/TRRandomizerView/Windows/MessageWindow.xaml index ac8ef0a69..f628c07f6 100644 --- a/TRRandomizerView/Windows/MessageWindow.xaml +++ b/TRRandomizerView/Windows/MessageWindow.xaml @@ -50,14 +50,12 @@ - - Show Error Folder - +