From 60708fb70eee42bf8a09a3aad7f1446eb3e9d6ce Mon Sep 17 00:00:00 2001 From: lahm86 <33758420+lahm86@users.noreply.github.com> Date: Sun, 29 Sep 2024 13:55:05 +0100 Subject: [PATCH] Exclude TRR monkey item drops (#769) Resolves #768. --- CHANGELOG.md | 1 + .../TR3/Classic/TR3EnvironmentRandomizer.cs | 32 ++---------------- .../Remastered/TR3REnvironmentRandomizer.cs | 3 ++ .../Utilities/TR3EnemyUtilities.cs | 33 +++++++++++++++++++ 4 files changed, 39 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84d149bc..6340558c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - fixed dark pickup sprites in TR2R OG graphics (#760) - fixed gun pickup sprites not showing properly in TR2R Floating Islands and Dragon's Lair OG graphics (#760) - fixed all placement issues with underwater corner secrets in TR1-3 (#763) +- fixed monkey item drops causing crashes in TR3R (#768) - removed support for 32-bit (#759) ## [V1.9.2](https://github.com/LostArtefacts/TR-Rando/compare/V1.9.1...V1.9.2) - 2024-08-20 diff --git a/TRRandomizerCore/Randomizers/TR3/Classic/TR3EnvironmentRandomizer.cs b/TRRandomizerCore/Randomizers/TR3/Classic/TR3EnvironmentRandomizer.cs index e9001ec3..e88e01a2 100644 --- a/TRRandomizerCore/Randomizers/TR3/Classic/TR3EnvironmentRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR3/Classic/TR3EnvironmentRandomizer.cs @@ -5,6 +5,7 @@ using TRRandomizerCore.Helpers; using TRRandomizerCore.Levels; using TRRandomizerCore.Textures; +using TRRandomizerCore.Utilities; namespace TRRandomizerCore.Randomizers; @@ -192,35 +193,6 @@ private void FinalizeEnvironment(TR3CombinedLevel level) monitor.UseMirroring = true; } - CheckMonkeyPickups(level); - } - - private static void CheckMonkeyPickups(TR3CombinedLevel level) - { - // Do a global check for monkeys that may be sitting on more than one pickup. - // This has to happen after item, enemy and environment rando to account for - // any shifted, converted and added items. - List monkeys = level.Data.Entities.FindAll(e => e.TypeID == TR3Type.Monkey); - foreach (TR3Entity monkey in monkeys) - { - List pickups = level.Data.Entities.FindAll(e => - e.X == monkey.X && - e.Y == monkey.Y && - e.Z == monkey.Z && - TR3TypeUtilities.IsAnyPickupType(e.TypeID)).ToList(); - - if (pickups.Count == 1) - { - continue; - } - - // Leave one item to drop, favouring key items. The others will be shifted - // slightly so the monkey doesn't pick them up. - pickups.Sort((e1, e2) => TR3TypeUtilities.IsKeyItemType(e1.TypeID) ? 1 : -1); - for (int i = 0; i < pickups.Count - 1; i++) - { - ++pickups[i].X; - } - } + TR3EnemyUtilities.CheckMonkeyPickups(level.Data, false); } } diff --git a/TRRandomizerCore/Randomizers/TR3/Remastered/TR3REnvironmentRandomizer.cs b/TRRandomizerCore/Randomizers/TR3/Remastered/TR3REnvironmentRandomizer.cs index 69c9e93b..53eed5e2 100644 --- a/TRRandomizerCore/Randomizers/TR3/Remastered/TR3REnvironmentRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR3/Remastered/TR3REnvironmentRandomizer.cs @@ -1,6 +1,7 @@ using TRDataControl.Environment; using TRGE.Core; using TRRandomizerCore.Levels; +using TRRandomizerCore.Utilities; namespace TRRandomizerCore.Randomizers; @@ -75,5 +76,7 @@ private void FinalizeEnvironment(TR3RCombinedLevel level) mod.ApplyToLevel(level.Data, picker.Options); } } + + TR3EnemyUtilities.CheckMonkeyPickups(level.Data, true); } } diff --git a/TRRandomizerCore/Utilities/TR3EnemyUtilities.cs b/TRRandomizerCore/Utilities/TR3EnemyUtilities.cs index cc2e3d20..96b3ddf1 100644 --- a/TRRandomizerCore/Utilities/TR3EnemyUtilities.cs +++ b/TRRandomizerCore/Utilities/TR3EnemyUtilities.cs @@ -416,4 +416,37 @@ static TR3EnemyUtilities() File.ReadAllText(@"Resources\TR3\Restrictions\enemy_restrictions_pathing.json") ); } + + public static void CheckMonkeyPickups(TR3Level level, bool remastered) + { + // Do a global check for monkeys that may be sitting on more than one pickup. + // This has to happen after item, enemy and environment rando to account for + // any shifted, converted and added items. + foreach (TR3Entity monkey in level.Entities.Where(e => e.TypeID == TR3Type.Monkey)) + { + List pickups = level.Entities.FindAll(e => + e.X == monkey.X && + e.Y == monkey.Y && + e.Z == monkey.Z && + TR3TypeUtilities.IsAnyPickupType(e.TypeID)); + + if (remastered) + { + // For TRR, we exclude all monkey pickups because the behaviour can lead to crashes. + pickups.ForEach(e => ++e.X); + } + else if (pickups.Count <= 1) + { + continue; + } + + // Leave one item to drop, favouring key items. The others will be shifted + // slightly so the monkey doesn't pick them up. + pickups.Sort((e1, e2) => TR3TypeUtilities.IsKeyItemType(e1.TypeID) ? 1 : -1); + for (int i = 0; i < pickups.Count - 1; i++) + { + ++pickups[i].X; + } + } + } }