From 87d113ab39da695f31bd86d0a8911a070e932f51 Mon Sep 17 00:00:00 2001 From: lahm86 <33758420+lahm86@users.noreply.github.com> Date: Fri, 16 Aug 2024 14:30:52 +0100 Subject: [PATCH] Make vehicle randomization optional (#751) Resolves #750. --- CHANGELOG.md | 1 + .../Editors/RandomizerSettings.cs | 3 ++ .../TR2/Classic/TR2ItemRandomizer.cs | 8 +++- .../TR2/Shared/TR2EnemyAllocator.cs | 47 +++++-------------- TRRandomizerCore/TRRandomizerController.cs | 6 +++ TRRandomizerCore/TRRandomizerType.cs | 1 + TRRandomizerCore/TRVersionSupport.cs | 2 + TRRandomizerView/Model/ControllerOptions.cs | 24 +++++++++- 8 files changed, 54 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a14742e..aa33ed57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## [Unreleased](https://github.com/LostArtefacts/TR-Rando/compare/V1.9.1...master) - xxxx-xx-xx - added options to use textures from specific game areas only in TRR texture randomization (#726) +- changed vehicle randomization in TR2 so that it is now optional within item randomization (#750) - fixed key item softlocks in remastered New Game+ when using shuffled item mode (#732, #734) - 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) diff --git a/TRRandomizerCore/Editors/RandomizerSettings.cs b/TRRandomizerCore/Editors/RandomizerSettings.cs index 54d1f580..f44c70b9 100644 --- a/TRRandomizerCore/Editors/RandomizerSettings.cs +++ b/TRRandomizerCore/Editors/RandomizerSettings.cs @@ -43,6 +43,7 @@ public class RandomizerSettings public ItemMode ItemMode { get; set; } public WeaponDifficulty WeaponDifficulty { get; set; } public bool IncludeKeyItems { get; set; } + public bool RandomizeVehicles { get; set; } public bool AllowReturnPathLocations { get; set; } public ItemRange KeyItemRange { get; set; } public bool AllowEnemyKeyDrops { get; set; } @@ -222,6 +223,7 @@ public void ApplyConfig(Config config) ItemMode = (ItemMode)config.GetEnum(nameof(ItemMode), typeof(ItemMode), ItemMode.Default); WeaponDifficulty = (WeaponDifficulty)config.GetEnum(nameof(WeaponDifficulty), typeof(WeaponDifficulty), WeaponDifficulty.Easy); IncludeKeyItems = config.GetBool(nameof(IncludeKeyItems), true); + RandomizeVehicles = config.GetBool(nameof(RandomizeVehicles), true); KeyItemRange = (ItemRange)config.GetEnum(nameof(KeyItemRange), typeof(ItemRange), ItemRange.Medium); AllowEnemyKeyDrops = config.GetBool(nameof(AllowEnemyKeyDrops), true); MaintainKeyContinuity = config.GetBool(nameof(MaintainKeyContinuity), true); @@ -401,6 +403,7 @@ public void StoreConfig(Config config) config[nameof(ItemMode)] = ItemMode; config[nameof(WeaponDifficulty)] = WeaponDifficulty; config[nameof(IncludeKeyItems)] = IncludeKeyItems; + config[nameof(RandomizeVehicles)] = RandomizeVehicles; config[nameof(KeyItemRange)] = KeyItemRange; config[nameof(AllowEnemyKeyDrops)] = AllowEnemyKeyDrops; config[nameof(MaintainKeyContinuity)] = MaintainKeyContinuity; diff --git a/TRRandomizerCore/Randomizers/TR2/Classic/TR2ItemRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/Classic/TR2ItemRandomizer.cs index 4f308ec3..0adabb0d 100644 --- a/TRRandomizerCore/Randomizers/TR2/Classic/TR2ItemRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/Classic/TR2ItemRandomizer.cs @@ -151,6 +151,11 @@ private void AdjustSeraphContinuity(TR2CombinedLevel level) private void RandomizeVehicles(TR2CombinedLevel level) { + if (!Settings.RandomizeVehicles) + { + return; + } + Dictionary> vehicleLocations = new(); void StoreLocation(TR2Type type) { @@ -176,9 +181,8 @@ void StoreLocation(TR2Type type) } } - if (level.IsAssault) + if (level.IsAssault || level.Data.Entities.Any(e => e.TypeID == TR2Type.RedSnowmobile)) { - // Regular skidoo rando comes with enemy rando currently StoreLocation(TR2Type.RedSnowmobile); } diff --git a/TRRandomizerCore/Randomizers/TR2/Shared/TR2EnemyAllocator.cs b/TRRandomizerCore/Randomizers/TR2/Shared/TR2EnemyAllocator.cs index 79cb52aa..5a1acac1 100644 --- a/TRRandomizerCore/Randomizers/TR2/Shared/TR2EnemyAllocator.cs +++ b/TRRandomizerCore/Randomizers/TR2/Shared/TR2EnemyAllocator.cs @@ -1,5 +1,4 @@ -using TRLevelControl; -using TRLevelControl.Helpers; +using TRLevelControl.Helpers; using TRLevelControl.Model; using TRRandomizerCore.Helpers; using TRRandomizerCore.Utilities; @@ -535,40 +534,20 @@ public void RandomizeEnemies(string levelName, TR2Level level, EnemyRandomizatio } // MercSnowMobDriver relies on RedSnowmobile so it will be available in the model list - if (levelName != TR2LevelNames.TIBET) + if (!level.Entities.Any(e => e.TypeID == TR2Type.RedSnowmobile) + && level.Entities.Find(e => e.TypeID == TR2Type.MercSnowmobDriver) is TR2Entity mercDriver) { - TR2Entity mercDriver = level.Entities.Find(e => e.TypeID == TR2Type.MercSnowmobDriver); - if (mercDriver != null) + TR2Entity skidoo = new() { - TR2Entity skidoo = new() - { - TypeID = TR2Type.RedSnowmobile, - Intensity1 = -1, - Intensity2 = -1 - }; - level.Entities.Add(skidoo); - - Location randomLocation = VehicleUtilities.GetRandomLocation(levelName, level, TR2Type.RedSnowmobile, Generator) - ?? mercDriver.GetLocation(); - skidoo.SetLocation(randomLocation); - } - } - else - { - TR2Entity skidoo = level.Entities.Find(e => e.TypeID == TR2Type.RedSnowmobile); - if (skidoo != null) - { - Location randomLocation = VehicleUtilities.GetRandomLocation(levelName, level, TR2Type.RedSnowmobile, Generator); - if (randomLocation != null) - { - skidoo.SetLocation(randomLocation); - } - else - { - // A secret depends on this skidoo, so just rotate it for variety. - skidoo.Angle = (short)(Generator.Next(0, 8) * -TRConsts.Angle45); - } - } + TypeID = TR2Type.RedSnowmobile, + Intensity1 = -1, + Intensity2 = -1 + }; + level.Entities.Add(skidoo); + + Location randomLocation = VehicleUtilities.GetRandomLocation(levelName, level, TR2Type.RedSnowmobile, Generator) + ?? mercDriver.GetLocation(); + skidoo.SetLocation(randomLocation); } // Check in case there are too many skidoo drivers diff --git a/TRRandomizerCore/TRRandomizerController.cs b/TRRandomizerCore/TRRandomizerController.cs index 4841de8b..e030e3fb 100644 --- a/TRRandomizerCore/TRRandomizerController.cs +++ b/TRRandomizerCore/TRRandomizerController.cs @@ -1167,6 +1167,12 @@ public bool IncludeKeyItems set => LevelRandomizer.IncludeKeyItems = value; } + public bool RandomizeVehicles + { + get => LevelRandomizer.RandomizeVehicles; + set => LevelRandomizer.RandomizeVehicles = value; + } + public bool AllowReturnPathLocations { get => LevelRandomizer.AllowReturnPathLocations; diff --git a/TRRandomizerCore/TRRandomizerType.cs b/TRRandomizerCore/TRRandomizerType.cs index b194db95..a10e0c8f 100644 --- a/TRRandomizerCore/TRRandomizerType.cs +++ b/TRRandomizerCore/TRRandomizerType.cs @@ -70,4 +70,5 @@ public enum TRRandomizerType TextureSwap, Wireframe, HideDeadTrexes, + Vehicles, } diff --git a/TRRandomizerCore/TRVersionSupport.cs b/TRRandomizerCore/TRVersionSupport.cs index 641f16ee..e5066a90 100644 --- a/TRRandomizerCore/TRVersionSupport.cs +++ b/TRRandomizerCore/TRVersionSupport.cs @@ -125,6 +125,7 @@ internal class TRVersionSupport TRRandomizerType.Texture, TRRandomizerType.Unarmed, TRRandomizerType.ItemSprite, + TRRandomizerType.Vehicles, TRRandomizerType.Wireframe, }; @@ -146,6 +147,7 @@ internal class TRVersionSupport TRRandomizerType.Text, TRRandomizerType.Texture, TRRandomizerType.TextureSwap, + TRRandomizerType.Vehicles, }; private static readonly List _tr3Types = new() diff --git a/TRRandomizerView/Model/ControllerOptions.cs b/TRRandomizerView/Model/ControllerOptions.cs index 51d74487..4c18993d 100644 --- a/TRRandomizerView/Model/ControllerOptions.cs +++ b/TRRandomizerView/Model/ControllerOptions.cs @@ -38,7 +38,7 @@ public class ControllerOptions : INotifyPropertyChanged private TRSecretCountMode _secretCountMode; private bool _useRewardRoomCameras; private uint _minSecretCount, _maxSecretCount; - private BoolItemControlClass _includeKeyItems, _allowReturnPathLocations, _includeExtraPickups, _randomizeItemTypes, _randomizeItemLocations, _allowEnemyKeyDrops, _maintainKeyContinuity, _oneItemDifficulty; + private BoolItemControlClass _includeKeyItems, _randomizeVehicles, _allowReturnPathLocations, _includeExtraPickups, _randomizeItemTypes, _randomizeItemLocations, _allowEnemyKeyDrops, _maintainKeyContinuity, _oneItemDifficulty; private BoolItemControlClass _crossLevelEnemies, _protectMonks, _docileWillard, _swapEnemyAppearance, _allowEmptyEggs, _hideEnemies, _removeLevelEndingLarson, _giveUnarmedItems, _relocateAwkwardEnemies, _hideDeadTrexes, _unrestrictedEnemyDifficulty; private BoolItemControlClass _persistTextures, _randomizeWaterColour, _retainLevelTextures, _retainKeySpriteTextures, _retainSecretSpriteTextures, _retainEnemyTextures, _retainLaraTextures; private BoolItemControlClass _changeAmbientTracks, _includeBlankTracks, _changeTriggerTracks, _separateSecretTracks, _changeWeaponSFX, _changeCrashSFX, _changeEnemySFX, _changeDoorSFX, _linkCreatureSFX, _randomizeWibble; @@ -1818,6 +1818,16 @@ public bool IncludeKeyItemsImplied get => ItemMode == ItemMode.Shuffled || IncludeKeyItems.Value; } + public BoolItemControlClass RandomizeVehicles + { + get => _randomizeVehicles; + set + { + _randomizeVehicles = value; + FirePropertyChanged(); + } + } + public BoolItemControlClass AllowReturnPathLocations { get => _allowReturnPathLocations; @@ -3169,6 +3179,12 @@ public ControllerOptions() Description = "The positions of key item pickups will be randomized. Items will be placed before their respective locks/slots." }; BindingOperations.SetBinding(IncludeKeyItems, BoolItemControlClass.IsActiveProperty, randomizeItemsBinding); + RandomizeVehicles = new() + { + Title = "Include vehicles", + Description = "The positions of vehicles may change within a level, and they may appear in different levels." + }; + BindingOperations.SetBinding(RandomizeVehicles, BoolItemControlClass.IsActiveProperty, randomizeItemsBinding); AllowReturnPathLocations = new() { Title = "Allow return path locations", @@ -3532,7 +3548,7 @@ public ControllerOptions() }; ItemBoolItemControls = new() { - _randomizeItemTypes, _randomizeItemLocations, _includeKeyItems, _allowReturnPathLocations, _allowEnemyKeyDrops, _oneItemDifficulty, _maintainKeyContinuity, _includeExtraPickups + _randomizeItemTypes, _randomizeItemLocations, _includeKeyItems, _allowReturnPathLocations, _allowEnemyKeyDrops, _randomizeVehicles, _oneItemDifficulty, _maintainKeyContinuity, _includeExtraPickups }; EnemyBoolItemControls = new() { @@ -3637,6 +3653,7 @@ private void AdjustAvailableOptions() _hideDeadTrexes.IsAvailable = IsHideDeadTrexesTypeSupported; _includeKeyItems.IsAvailable = IsKeyItemTypeSupported; + _randomizeVehicles.IsAvailable = IsVehiclesTypeSupported; _maintainKeyContinuity.IsAvailable = IsKeyContinuityTypeSupported; _includeExtraPickups.IsAvailable = IsExtraPickupsTypeSupported; _allowEnemyKeyDrops.IsAvailable = IsItemDropsTypeSupported; @@ -3748,6 +3765,7 @@ public void Load(TRRandomizerController controller) WeaponDifficulties = Enum.GetValues(); WeaponDifficulty = _controller.WeaponDifficulty; IncludeKeyItems.Value = _controller.IncludeKeyItems; + RandomizeVehicles.Value = _controller.RandomizeVehicles; AllowReturnPathLocations.Value = _controller.AllowReturnPathLocations; IncludeExtraPickups.Value = _controller.IncludeExtraPickups; RandomizeItemTypes.Value = _controller.RandomizeItemTypes; @@ -4077,6 +4095,7 @@ public void Save() _controller.ItemMode = ItemMode; _controller.WeaponDifficulty = WeaponDifficulty; _controller.IncludeKeyItems = IncludeKeyItems.Value; + _controller.RandomizeVehicles = RandomizeVehicles.Value; _controller.AllowReturnPathLocations = AllowReturnPathLocations.Value; _controller.IncludeExtraPickups = IncludeExtraPickups.Value; _controller.RandomizeItemTypes = RandomizeItemTypes.Value; @@ -4308,6 +4327,7 @@ public void Unload() public bool IsItemTypeSupported => IsRandomizationSupported(TRRandomizerType.Item); public bool IsItemDropsTypeSupported => IsRandomizationSupported(TRRandomizerType.ItemDrops); public bool IsKeyItemTypeSupported => IsRandomizationSupported(TRRandomizerType.KeyItems); + public bool IsVehiclesTypeSupported => IsRandomizationSupported(TRRandomizerType.Vehicles); public bool IsKeyContinuityTypeSupported => IsRandomizationSupported(TRRandomizerType.KeyContinuity); public bool IsExtraPickupsTypeSupported => IsRandomizationSupported(TRRandomizerType.ExtraPickups); public bool IsEnemyTypeSupported => IsRandomizationSupported(TRRandomizerType.Enemy);