diff --git a/TRLevelControl/Model/Common/FloorData/FDControl.cs b/TRLevelControl/Model/Common/FloorData/FDControl.cs index d5049424..3020ba05 100644 --- a/TRLevelControl/Model/Common/FloorData/FDControl.cs +++ b/TRLevelControl/Model/Common/FloorData/FDControl.cs @@ -172,6 +172,26 @@ public void RemoveEntityTriggers(int entityIndex) } } + public List GetTriggerRooms(int entityIndex, List rooms) + where R : TRRoom + { + List triggers = GetEntityTriggers(entityIndex); + List triggerRooms = new(); + for (short i = 0; i < rooms.Count; i++) + { + foreach (TRRoomSector sector in rooms[i].Sectors.Where(s => s.FDIndex != 0)) + { + if (triggers.Any(_entries[sector.FDIndex].Contains)) + { + triggerRooms.Add(i); + break; + } + } + } + + return triggerRooms; + } + public TRRoomSector GetRoomSector(int x, int y, int z, short roomNumber, List rooms) where R : TRRoom { diff --git a/TRRandomizerCore/Randomizers/Shared/ItemAllocator.cs b/TRRandomizerCore/Randomizers/Shared/ItemAllocator.cs index a8047239..1a083825 100644 --- a/TRRandomizerCore/Randomizers/Shared/ItemAllocator.cs +++ b/TRRandomizerCore/Randomizers/Shared/ItemAllocator.cs @@ -326,10 +326,7 @@ public void ApplyItemSwaps(string levelName, List items) } } - if (!Settings.AllowEnemyKeyDrops) - { - ExcludeEnemyKeyDrops(items); - } + ExcludeEnemyKeyDrops(items); } protected List GetPickups(string levelName, List items, bool isUnarmed) diff --git a/TRRandomizerCore/Randomizers/Shared/LocationPicker.cs b/TRRandomizerCore/Randomizers/Shared/LocationPicker.cs index 4aafaa73..79b79cfb 100644 --- a/TRRandomizerCore/Randomizers/Shared/LocationPicker.cs +++ b/TRRandomizerCore/Randomizers/Shared/LocationPicker.cs @@ -17,7 +17,7 @@ public class LocationPicker : IRouteManager private Random _generator; public Func TriggerTestAction { get; set; } - public Func KeyItemTestAction { get; set; } + public Func, bool> KeyItemTestAction { get; set; } public List RoomInfos { get; set; } public int LevelSize { get; private set; } @@ -138,7 +138,7 @@ public Location GetKeyItemLocation(int keyItemID, TREntity entity, bool ha continue; } - if (KeyItemTestAction != null && !KeyItemTestAction(newLocation, hasPickupTrigger)) + if (KeyItemTestAction != null && !KeyItemTestAction(newLocation, hasPickupTrigger, roomPool)) { continue; } diff --git a/TRRandomizerCore/Randomizers/TR1/Classic/TR1ItemRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/Classic/TR1ItemRandomizer.cs index a77c02ae..0901d6f3 100644 --- a/TRRandomizerCore/Randomizers/TR1/Classic/TR1ItemRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/Classic/TR1ItemRandomizer.cs @@ -80,12 +80,11 @@ public void FinalizeRandomization() else { _allocator.RandomizeKeyItems(_levelInstance.Name, _levelInstance.Data, _levelInstance.Script.OriginalSequence); - } - - if (Settings.AllowEnemyKeyDrops) - { - UpdateEnemyItemDrops(_levelInstance, _levelInstance.Data.Entities - .Where(e => TR1TypeUtilities.IsKeyItemType(e.TypeID))); + if (Settings.AllowEnemyKeyDrops) + { + UpdateEnemyItemDrops(_levelInstance, _levelInstance.Data.Entities + .Where(e => TR1TypeUtilities.IsKeyItemType(e.TypeID))); + } } SaveLevelInstance(); diff --git a/TRRandomizerCore/Randomizers/TR2/Shared/TR2ItemAllocator.cs b/TRRandomizerCore/Randomizers/TR2/Shared/TR2ItemAllocator.cs index 783dafde..f7cbfa1d 100644 --- a/TRRandomizerCore/Randomizers/TR2/Shared/TR2ItemAllocator.cs +++ b/TRRandomizerCore/Randomizers/TR2/Shared/TR2ItemAllocator.cs @@ -84,7 +84,7 @@ private void InitialisePicker(string levelName, TR2Level level, LocationMode loc ? location => LocationUtilities.HasAnyTrigger(location, level) : null; _picker.KeyItemTestAction = locationMode == LocationMode.KeyItems - ? (location, hasPickupTrigger) => TestKeyItemLocation(location, hasPickupTrigger, levelName, level) + ? (location, hasPickupTrigger, roomPool) => TestKeyItemLocation(location, hasPickupTrigger, roomPool, levelName, level) : null; _picker.RoomInfos = new(level.Rooms.Select(r => new ExtRoomInfo(r))); @@ -99,9 +99,10 @@ private void InitialisePicker(string levelName, TR2Level level, LocationMode loc _picker.Initialise(levelName, pool, Settings, Generator); } - private bool TestKeyItemLocation(Location location, bool hasPickupTrigger, string levelName, TR2Level level) + private bool TestKeyItemLocation(Location location, bool hasPickupTrigger, List roomPool, string levelName, TR2Level level) { - // Make sure if we're placing on the same tile as an enemy, that the enemy can drop the item. + // Make sure if we're placing on the same tile as an enemy, that the enemy can drop the item. Ensure too that the enemy + // can be triggered from within the key item's room pool and not beyond. TR2Entity enemy = level.Entities .FindAll(e => TR2TypeUtilities.IsEnemyType(e.TypeID)) .Find(e => e.GetLocation().IsEquivalent(location)); @@ -111,7 +112,8 @@ private bool TestKeyItemLocation(Location location, bool hasPickupTrigger, strin TR2TypeUtilities.GetAliasForLevel(levelName, enemy.TypeID), Settings.RandomizeEnemies && !Settings.ProtectMonks, Settings.RandomizeEnemies && Settings.UnconditionalChickens - )); + ) + && level.FloorData.GetTriggerRooms(level.Entities.IndexOf(enemy), level.Rooms).Any(roomPool.Contains)); } private List GetItemLocationPool(string levelName, TR2Level level, bool keyItemMode) diff --git a/TRRandomizerCore/Randomizers/TR3/Shared/TR3ItemAllocator.cs b/TRRandomizerCore/Randomizers/TR3/Shared/TR3ItemAllocator.cs index d54498a9..ba99b851 100644 --- a/TRRandomizerCore/Randomizers/TR3/Shared/TR3ItemAllocator.cs +++ b/TRRandomizerCore/Randomizers/TR3/Shared/TR3ItemAllocator.cs @@ -79,7 +79,7 @@ private void InitialisePicker(string levelName, TR3Level level, LocationMode loc ? location => LocationUtilities.HasAnyTrigger(location, level) : null; _picker.KeyItemTestAction = locationMode == LocationMode.KeyItems - ? (location, hasPickupTrigger) => TestKeyItemLocation(location, hasPickupTrigger, levelName, level) + ? (location, hasPickupTrigger, roomPool) => TestKeyItemLocation(location, hasPickupTrigger, roomPool, levelName, level) : null; _picker.RoomInfos = new(level.Rooms.Select(r => new ExtRoomInfo(r))); @@ -94,7 +94,7 @@ private void InitialisePicker(string levelName, TR3Level level, LocationMode loc _picker.Initialise(levelName, pool, Settings, Generator); } - private bool TestKeyItemLocation(Location location, bool hasPickupTrigger, string levelName, TR3Level level) + private bool TestKeyItemLocation(Location location, bool hasPickupTrigger, List roomPool, string levelName, TR3Level level) { // Make sure if we're placing on the same tile as an enemy, that the enemy can drop the item. TR3Entity enemy = level.Entities @@ -105,7 +105,8 @@ private bool TestKeyItemLocation(Location location, bool hasPickupTrigger, strin ( TR3TypeUtilities.GetAliasForLevel(levelName, enemy.TypeID), !Settings.RandomizeEnemies || Settings.ProtectMonks - )); + ) + && level.FloorData.GetTriggerRooms(level.Entities.IndexOf(enemy), level.Rooms).Any(roomPool.Contains)); } private List GetItemLocationPool(string levelName, TR3Level level, bool keyItemMode, bool isCold) diff --git a/TRRandomizerView/Model/ControllerOptions.cs b/TRRandomizerView/Model/ControllerOptions.cs index 76d22a60..8afb6179 100644 --- a/TRRandomizerView/Model/ControllerOptions.cs +++ b/TRRandomizerView/Model/ControllerOptions.cs @@ -1037,7 +1037,7 @@ private void UpdateItemMode() MaintainKeyContinuity.IsActive = defaultMode; AllowReturnPathLocations.IsActive = !defaultMode || IncludeKeyItems.Value; - AllowEnemyKeyDrops.IsActive = !defaultMode || IncludeKeyItems.Value; + AllowEnemyKeyDrops.IsActive = defaultMode && IncludeKeyItems.Value; FirePropertyChanged(nameof(WeaponDifficultyAvailable)); FirePropertyChanged(nameof(IncludeKeyItemsImplied)); @@ -3535,7 +3535,7 @@ private void IncludeKeyItems_PropertyChanged(object sender, PropertyChangedEvent { bool defaultMode = ItemMode == ItemMode.Default; AllowReturnPathLocations.IsActive = !defaultMode || IncludeKeyItems.Value; - AllowEnemyKeyDrops.IsActive = !defaultMode || IncludeKeyItems.Value; + AllowEnemyKeyDrops.IsActive = defaultMode && IncludeKeyItems.Value; FirePropertyChanged(nameof(IncludeKeyItemsImplied)); }