From 94a70a0dbc87efa79f4cc178aff2aa9e218af36a Mon Sep 17 00:00:00 2001 From: ben_pollard Date: Fri, 6 Dec 2024 22:37:34 +0000 Subject: [PATCH] Fixed an issue where exits couldn't be located as interaction targets --- NetAF.Examples/Assets/Regions/Flat/Flat.cs | 2 +- .../Assets/Regions/Flat/Rooms/Lounge.cs | 4 +- .../Assets/Regions/Flat/Rooms/Roof.cs | 2 +- .../Assets/Regions/Flat/Rooms/SpareBedroom.cs | 2 +- .../Assets/Regions/Zelda/Rooms/Stream.cs | 2 +- NetAF.Tests/Assets/Locations/Room_Tests.cs | 24 ------ NetAF/Assets/Locations/Room.cs | 74 ++++++++----------- NetAF/Commands/Scene/UseOn.cs | 2 +- .../Interpretation/SceneCommandInterpreter.cs | 3 +- NetAF/Logic/Game.cs | 3 - 10 files changed, 38 insertions(+), 80 deletions(-) diff --git a/NetAF.Examples/Assets/Regions/Flat/Flat.cs b/NetAF.Examples/Assets/Regions/Flat/Flat.cs index f6eca28f..b73eb002 100644 --- a/NetAF.Examples/Assets/Regions/Flat/Flat.cs +++ b/NetAF.Examples/Assets/Regions/Flat/Flat.cs @@ -41,7 +41,7 @@ public Region Instantiate() if (Guitar.Name.EqualsIdentifier(item.Identifier)) { - if (spareBedroom.ContainsItem(Lead.Name)) + if (spareBedroom.FindItem(Lead.Name, out _)) { easternHallway[Direction.East].Unlock(); diff --git a/NetAF.Examples/Assets/Regions/Flat/Rooms/Lounge.cs b/NetAF.Examples/Assets/Regions/Flat/Rooms/Lounge.cs index 23e6bba9..3fb87de4 100644 --- a/NetAF.Examples/Assets/Regions/Flat/Rooms/Lounge.cs +++ b/NetAF.Examples/Assets/Regions/Flat/Rooms/Lounge.cs @@ -27,7 +27,7 @@ public Room Instantiate() ConditionalDescription description = new("You're in a large sitting room. Theres a huge map hanging on the eastern wall. On the southern wall there is a canvas. Theres a large coffee table in the center of the room. Beth is sat on a green sofa watching the TV. There is what appears to be a lead of some sort poking out from underneath the sofa. The kitchen is to the north.", "You're in a large sitting room. Theres a huge map hanging on the eastern wall. On the southern wall there is a canvas. Theres a large coffee table in the center of the room. Beth is sat on a green sofa watching the TV. The kitchen is to the north.", - () => room.ContainsItem(Lead.Name)); + () => room.FindItem(Lead.Name, out _)); room = new(new Identifier(Name), description, [new Exit(Direction.North)], interaction: item => { @@ -35,7 +35,7 @@ public Room Instantiate() { if (CoffeeMug.Name.EqualsIdentifier(item.Identifier)) { - if (room.ContainsCharacter(Beth.Name)) + if (room.FindCharacter(Beth.Name, out _)) return new(InteractionResult.ItemExpires, item, "Beth takes the cup of coffee and smiles. Brownie points to you!"); return new(InteractionResult.NoChange, item, "As no one is about you decide to drink the coffee yourself. Your nose wasn't lying, it is bitter but delicious."); diff --git a/NetAF.Examples/Assets/Regions/Flat/Rooms/Roof.cs b/NetAF.Examples/Assets/Regions/Flat/Rooms/Roof.cs index 213a04f3..613a5f32 100644 --- a/NetAF.Examples/Assets/Regions/Flat/Rooms/Roof.cs +++ b/NetAF.Examples/Assets/Regions/Flat/Rooms/Roof.cs @@ -24,7 +24,7 @@ public Room Instantiate() Room room = null; ConditionalDescription description = new("The roof is small and gravely, and it hurts your shoe-less feet to stand on it. There is a large skylight in the center of the roof, and a coffee mug sits to the side, indicating someone has been here recently. The window behind you south leads back into the bathroom.", "The roof is small and gravely, and it hurts your shoe-less feet to stand on it. There is a large skylight in the center of the roof. The window behind you south leads back into the bathroom.", - () => room.ContainsItem(CoffeeMug.Name)); + () => room.FindItem(CoffeeMug.Name, out _)); room = new(new Identifier(Name), description, [new Exit(Direction.South)]); diff --git a/NetAF.Examples/Assets/Regions/Flat/Rooms/SpareBedroom.cs b/NetAF.Examples/Assets/Regions/Flat/Rooms/SpareBedroom.cs index 445c79f8..c8299e08 100644 --- a/NetAF.Examples/Assets/Regions/Flat/Rooms/SpareBedroom.cs +++ b/NetAF.Examples/Assets/Regions/Flat/Rooms/SpareBedroom.cs @@ -25,7 +25,7 @@ public Room Instantiate() ConditionalDescription description = new("You are in a very tidy room. The eastern wall is painted in a dark red colour. Against the south wall is a line of guitar amplifiers, all turned on. A very tidy blue guitar rests against the amps just begging to be played. There is a Gamecube against the northern wall. A doorway to the north leads back to the Western Hallway.", "You are in a very tidy room. The eastern wall is painted in a dark red colour. Against the south wall is a line of guitar amplifiers, all turned on. There is a Gamecube against the northern wall. A doorway to the north leads back to the Western Hallway.", - () => room.ContainsItem(Guitar.Name)); + () => room.FindItem(Guitar.Name, out _)); room = new(new Identifier(Name), description, [new Exit(Direction.North)], interaction: Interaction); diff --git a/NetAF.Examples/Assets/Regions/Zelda/Rooms/Stream.cs b/NetAF.Examples/Assets/Regions/Zelda/Rooms/Stream.cs index aa54cdff..afb953c0 100644 --- a/NetAF.Examples/Assets/Regions/Zelda/Rooms/Stream.cs +++ b/NetAF.Examples/Assets/Regions/Zelda/Rooms/Stream.cs @@ -25,7 +25,7 @@ public Room Instantiate() Room room = null; ConditionalDescription description = new ("A small stream flows east to west in front of you. The water is clear, and looks good enough to drink. On the bank is a small bush. To the south is the Kokiri forest", "A small stream flows east to west in front of you. The water is clear, and looks good enough to drink. On the bank is a stump where the bush was. To the south is the Kokiri forest.", - () => room.ContainsItem(Bush.Name)); + () => room.FindItem(Bush.Name, out _)); room = new(new Identifier(Name), description, [new Exit(Direction.South)]); diff --git a/NetAF.Tests/Assets/Locations/Room_Tests.cs b/NetAF.Tests/Assets/Locations/Room_Tests.cs index 73b63115..68820769 100644 --- a/NetAF.Tests/Assets/Locations/Room_Tests.cs +++ b/NetAF.Tests/Assets/Locations/Room_Tests.cs @@ -116,18 +116,6 @@ public void GivenHasItem_WhenContainsItem_ThenTrue() Assert.IsTrue(result); } - [TestMethod] - public void GivenHasItem_WhenContainsItemByName_ThenTrue() - { - var room = new Room(string.Empty, string.Empty); - var item = new Item("A", string.Empty); - room.AddItem(item); - - var result = room.ContainsItem("A"); - - Assert.IsTrue(result); - } - [TestMethod] public void GivenDoesNotHaveCharacter_WhenContainsCharacter_ThenFalse() { @@ -151,18 +139,6 @@ public void GivenHasCharacter_WhenContainsCharacter_ThenTrue() Assert.IsTrue(result); } - [TestMethod] - public void GivenHasCharacter_WhenContainsCharacterByName_ThenTrue() - { - var room = new Room(string.Empty, string.Empty); - var character = new NonPlayableCharacter("A", string.Empty); - room.AddCharacter(character); - - var result = room.ContainsCharacter("A"); - - Assert.IsTrue(result); - } - [TestMethod] public void GivenValidCharacter_WhenRemoveInteractionTarget_ThenCharacterRemoved() { diff --git a/NetAF/Assets/Locations/Room.cs b/NetAF/Assets/Locations/Room.cs index 4fb7cf64..ab09a895 100644 --- a/NetAF/Assets/Locations/Room.cs +++ b/NetAF/Assets/Locations/Room.cs @@ -4,6 +4,7 @@ using NetAF.Assets.Characters; using NetAF.Commands; using NetAF.Extensions; +using NetAF.Interpretation; using NetAF.Serialization; using NetAF.Serialization.Assets; using NetAF.Utilities; @@ -275,35 +276,16 @@ public bool FindExit(Direction direction, bool includeInvisibleExits, out Exit e return false; } - /// - /// Get if this Room contains an item. This will not include items whose ExaminableObject.IsPlayerVisible property is set to false. - /// - /// The item to check for. - /// True if the item is in this room, else false. - public bool ContainsItem(Item item) - { - return Items.Contains(item); - } - /// /// Get if this Room contains an item. /// - /// The item name to check for. - /// Specify if invisible items should be included. + /// The item to check for. + /// Specify if invisible exits should be included. /// True if the item is in this room, else false. - public bool ContainsItem(string itemName, bool includeInvisibleItems = false) + public bool ContainsItem(Item item, bool includeInvisibleItems = false) { - return Array.Exists(Items, item => itemName.EqualsExaminable(item) && (includeInvisibleItems || item.IsPlayerVisible)); - } - - /// - /// Get if this Room contains an interaction target. - /// - /// The name of the target to check for. - /// True if the target is in this room, else false. - public bool ContainsInteractionTarget(string targetName) - { - return Array.Exists(Items, i => targetName.EqualsExaminable(i) || Array.Exists(Characters, targetName.EqualsExaminable)); + + return Array.Exists(Items, i => i == item && (includeInvisibleItems || i.IsPlayerVisible)); } /// @@ -347,25 +329,40 @@ public bool FindItem(string itemName, out Item item, bool includeInvisibleItems) public bool FindInteractionTarget(string targetName, out IInteractWithItem target) { var items = Items.Where(targetName.EqualsExaminable).ToArray(); - var nPCS = Characters.Where(targetName.EqualsExaminable).ToArray(); - var exits = Exits.Where(targetName.EqualsExaminable).ToArray(); - List interactions = []; if (items.Length > 0) - interactions.AddRange(items); + { + target = items[0]; + return true; + } + + var nPCS = Characters.Where(targetName.EqualsExaminable).ToArray(); if (nPCS.Length > 0) - interactions.AddRange(nPCS); + { + target = nPCS[0]; + return true; + } - if (exits.Length > 0) - interactions.AddRange(exits); + var exits = Exits.Where(targetName.EqualsExaminable).ToArray(); - if (interactions.Count > 0) + if (exits.Length > 0) { - target = interactions[0]; + target = exits[0]; return true; } + if (SceneCommandInterpreter.TryParseToDirection(targetName, out var direction)) + { + exits = Exits.Where(x => x.Direction == direction).ToArray(); + + if (exits.Length > 0) + { + target = exits[0]; + return true; + } + } + target = null; return false; } @@ -381,17 +378,6 @@ public bool ContainsCharacter(NonPlayableCharacter character, bool includeInvisi return Characters.Contains(character) && (includeInvisibleCharacters || character.IsPlayerVisible); } - /// - /// Get if this Room contains a character. - /// - /// The character name to check for. - /// Specify if invisible characters should be included. - /// True if the item is in this room, else false. - public bool ContainsCharacter(string characterName, bool includeInvisibleCharacters = false) - { - return Array.Exists(Characters, character => characterName.EqualsExaminable(character) && (includeInvisibleCharacters || character.IsPlayerVisible)); - } - /// /// Find a character. This will not include characters whose ExaminableObject.IsPlayerVisible property is set to false. /// diff --git a/NetAF/Commands/Scene/UseOn.cs b/NetAF/Commands/Scene/UseOn.cs index 4440d7c3..46c8f10f 100644 --- a/NetAF/Commands/Scene/UseOn.cs +++ b/NetAF/Commands/Scene/UseOn.cs @@ -58,7 +58,7 @@ private static void ItemExpires(Game game, Item item, IInteractWithItem target) /// The target that expired. private static void TargetExpires(Game game, IInteractWithItem target) { - if (target is IExaminable examinable && game.Overworld.CurrentRegion.CurrentRoom.ContainsInteractionTarget(examinable.Identifier.Name)) + if (target is IExaminable examinable && game.Overworld.CurrentRegion.CurrentRoom.FindInteractionTarget(examinable.Identifier.Name, out _)) game.Overworld.CurrentRegion.CurrentRoom.RemoveInteractionTarget(target); if (target is Item item) diff --git a/NetAF/Interpretation/SceneCommandInterpreter.cs b/NetAF/Interpretation/SceneCommandInterpreter.cs index f36cbde4..d4949eee 100644 --- a/NetAF/Interpretation/SceneCommandInterpreter.cs +++ b/NetAF/Interpretation/SceneCommandInterpreter.cs @@ -357,7 +357,7 @@ private static bool TryParseUseOnCommand(string text, Game game, out ICommand co /// The string to parse. /// The direction. /// The result of the parse. - private static bool TryParseToDirection(string text, out Direction direction) + public static bool TryParseToDirection(string text, out Direction direction) { if (Move.NorthCommandHelp.Equals(text)) { @@ -399,7 +399,6 @@ private static bool TryParseToDirection(string text, out Direction direction) return false; } - #endregion #region Implementation of IInterpreter diff --git a/NetAF/Logic/Game.cs b/NetAF/Logic/Game.cs index 3cc1ce67..390f4241 100644 --- a/NetAF/Logic/Game.cs +++ b/NetAF/Logic/Game.cs @@ -379,9 +379,6 @@ public IInteractWithItem FindInteractionTarget(string name) if (name.EqualsExaminable(Overworld.CurrentRegion.CurrentRoom)) return Overworld.CurrentRegion.CurrentRoom; - if (!Overworld.CurrentRegion.CurrentRoom.ContainsInteractionTarget(name)) - return null; - Overworld.CurrentRegion.CurrentRoom.FindInteractionTarget(name, out var target); return target; }