From 5aff9c662e5944276e9a6d46470212f75edd26a6 Mon Sep 17 00:00:00 2001 From: ben_pollard Date: Fri, 10 Jan 2025 14:05:27 +0000 Subject: [PATCH] Added functionality to prevent all playable characters being able to take or drop items --- NetAF.Tests/Commands/Scene/Drop_Tests.cs | 19 ++++++++++ NetAF.Tests/Commands/Scene/TakeAll_Tests.cs | 36 +++++++++++++++++++ NetAF.Tests/Commands/Scene/Take_Tests.cs | 19 ++++++++++ NetAF/Assets/Characters/PlayableCharacter.cs | 18 +++++++--- NetAF/Commands/Scene/Drop.cs | 3 ++ NetAF/Commands/Scene/Take.cs | 3 ++ NetAF/Commands/Scene/TakeAll.cs | 3 ++ .../Interpretation/SceneCommandInterpreter.cs | 4 +-- 8 files changed, 98 insertions(+), 7 deletions(-) diff --git a/NetAF.Tests/Commands/Scene/Drop_Tests.cs b/NetAF.Tests/Commands/Scene/Drop_Tests.cs index 89a477c6..8b69f8a4 100644 --- a/NetAF.Tests/Commands/Scene/Drop_Tests.cs +++ b/NetAF.Tests/Commands/Scene/Drop_Tests.cs @@ -22,6 +22,25 @@ public void GivenNoCharacter_WhenInvoke_ThenError() Assert.AreEqual(ReactionResult.Error, result.Result); } + [TestMethod] + public void GivenCannotTakeOrDropItems_WhenInvoke_ThenError() + { + var room = new Room(Identifier.Empty, Description.Empty); + var region = new Region(string.Empty, string.Empty); + region.AddRoom(room, 0, 0, 0); + var overworld = new Overworld(string.Empty, string.Empty); + overworld.AddRegion(region); + var character = new PlayableCharacter(Identifier.Empty, Description.Empty, false, false); + var item = new Item(new Identifier("A"), Description.Empty, true); + var game = Game.Create(new GameInfo(string.Empty, string.Empty, string.Empty), string.Empty, AssetGenerator.Retained(overworld, character), GameEndConditions.NoEnd, TestGameConfiguration.Default).Invoke(); + game.Overworld.CurrentRegion.Enter(); + var command = new Drop(item); + + var result = command.Invoke(game); + + Assert.AreEqual(ReactionResult.Error, result.Result); + } + [TestMethod] public void GivenNoItem_WhenInvoke_ThenError() { diff --git a/NetAF.Tests/Commands/Scene/TakeAll_Tests.cs b/NetAF.Tests/Commands/Scene/TakeAll_Tests.cs index 1092825f..0eff1421 100644 --- a/NetAF.Tests/Commands/Scene/TakeAll_Tests.cs +++ b/NetAF.Tests/Commands/Scene/TakeAll_Tests.cs @@ -11,6 +11,42 @@ namespace NetAF.Tests.Commands.Scene [TestClass] public class TakeAll_Tests { + [TestMethod] + public void GivenNoCharacter_WhenInvoke_ThenError() + { + var room = new Room(Identifier.Empty, Description.Empty); + var region = new Region(string.Empty, string.Empty); + region.AddRoom(room, 0, 0, 0); + var overworld = new Overworld(string.Empty, string.Empty); + overworld.AddRegion(region); + var game = Game.Create(new GameInfo(string.Empty, string.Empty, string.Empty), string.Empty, AssetGenerator.Retained(overworld, null), GameEndConditions.NoEnd, TestGameConfiguration.Default).Invoke(); + game.Overworld.CurrentRegion.Enter(); + var command = new TakeAll(); + + var result = command.Invoke(game); + + Assert.AreEqual(ReactionResult.Error, result.Result); + } + + [TestMethod] + public void GivenCannotTakeOrDropItems_WhenInvoke_ThenError() + { + var room = new Room(Identifier.Empty, Description.Empty); + var region = new Region(string.Empty, string.Empty); + region.AddRoom(room, 0, 0, 0); + var overworld = new Overworld(string.Empty, string.Empty); + overworld.AddRegion(region); + var character = new PlayableCharacter(Identifier.Empty, Description.Empty, false, false); + var item = new Item(new Identifier("A"), Description.Empty, true); + var game = Game.Create(new GameInfo(string.Empty, string.Empty, string.Empty), string.Empty, AssetGenerator.Retained(overworld, character), GameEndConditions.NoEnd, TestGameConfiguration.Default).Invoke(); + game.Overworld.CurrentRegion.Enter(); + var command = new TakeAll(); + + var result = command.Invoke(game); + + Assert.AreEqual(ReactionResult.Error, result.Result); + } + [TestMethod] public void GivenNoItem_WhenInvoke_ThenError() { diff --git a/NetAF.Tests/Commands/Scene/Take_Tests.cs b/NetAF.Tests/Commands/Scene/Take_Tests.cs index 66f24a27..199e70f1 100644 --- a/NetAF.Tests/Commands/Scene/Take_Tests.cs +++ b/NetAF.Tests/Commands/Scene/Take_Tests.cs @@ -28,6 +28,25 @@ public void GivenNoCharacter_WhenInvoke_ThenError() Assert.AreEqual(ReactionResult.Error, result.Result); } + [TestMethod] + public void GivenCannotTakeOrDropItems_WhenInvoke_ThenError() + { + var room = new Room(Identifier.Empty, Description.Empty); + var region = new Region(string.Empty, string.Empty); + region.AddRoom(room, 0, 0, 0); + var overworld = new Overworld(string.Empty, string.Empty); + overworld.AddRegion(region); + var character = new PlayableCharacter(Identifier.Empty, Description.Empty, false, false); + var item = new Item(new Identifier("A"), Description.Empty, true); + var game = Game.Create(new GameInfo(string.Empty, string.Empty, string.Empty), string.Empty, AssetGenerator.Retained(overworld, character), GameEndConditions.NoEnd, TestGameConfiguration.Default).Invoke(); + game.Overworld.CurrentRegion.Enter(); + var command = new Take(item); + + var result = command.Invoke(game); + + Assert.AreEqual(ReactionResult.Error, result.Result); + } + [TestMethod] public void GivenNoItem_WhenInvoke_ThenError() { diff --git a/NetAF/Assets/Characters/PlayableCharacter.cs b/NetAF/Assets/Characters/PlayableCharacter.cs index 3a989660..5a69abb9 100644 --- a/NetAF/Assets/Characters/PlayableCharacter.cs +++ b/NetAF/Assets/Characters/PlayableCharacter.cs @@ -14,6 +14,11 @@ public sealed class PlayableCharacter : Character /// public bool CanConverse { get; private set; } + /// + /// Get if this playable character can take and drop items. + /// + public bool CanTakeAndDropItems { get; private set; } + #endregion #region Constructors @@ -40,7 +45,7 @@ public sealed class PlayableCharacter : Character /// This objects commands. /// The interaction. /// The examination. - public PlayableCharacter(Identifier identifier, IDescription description, Item[] items = null, CustomCommand[] commands = null, InteractionCallback interaction = null, ExaminationCallback examination = null) : this(identifier, description, true, items, commands, interaction, examination) + public PlayableCharacter(Identifier identifier, IDescription description, Item[] items = null, CustomCommand[] commands = null, InteractionCallback interaction = null, ExaminationCallback examination = null) : this(identifier, description, true, true, items, commands, interaction, examination) { } @@ -49,12 +54,13 @@ public PlayableCharacter(Identifier identifier, IDescription description, Item[] /// /// The identifier. /// The description. - /// If this object can converse with an IConverser. + /// If this playable character can converse with an IConverser. + /// If this playable character can take and drop items. /// The items. /// This objects commands. /// The interaction. /// The examination. - public PlayableCharacter(string identifier, string description, bool canConverse, Item[] items = null, CustomCommand[] commands = null, InteractionCallback interaction = null, ExaminationCallback examination = null) : this(new Identifier(identifier), new Description(description), canConverse, items, commands, interaction, examination) + public PlayableCharacter(string identifier, string description, bool canConverse, bool canTakeAndDropItems = true, Item[] items = null, CustomCommand[] commands = null, InteractionCallback interaction = null, ExaminationCallback examination = null) : this(new Identifier(identifier), new Description(description), canConverse, canTakeAndDropItems, items, commands, interaction, examination) { } @@ -63,16 +69,18 @@ public PlayableCharacter(Identifier identifier, IDescription description, Item[] /// /// The identifier. /// The description. - /// If this object can converse with an IConverser. + /// If this playable character can converse with an IConverser. + /// If this playable character can take and drop items. /// The items. /// This objects commands. /// The interaction. /// The examination. - public PlayableCharacter(Identifier identifier, IDescription description, bool canConverse, Item[] items = null, CustomCommand[] commands = null, InteractionCallback interaction = null, ExaminationCallback examination = null) + public PlayableCharacter(Identifier identifier, IDescription description, bool canConverse, bool canTakeAndDropItems = true, Item[] items = null, CustomCommand[] commands = null, InteractionCallback interaction = null, ExaminationCallback examination = null) { Identifier = identifier; Description = description; CanConverse = canConverse; + CanTakeAndDropItems = canTakeAndDropItems; Items = items ?? []; Commands = commands ?? []; Interaction = interaction ?? (i => new(InteractionResult.NoChange, i)); diff --git a/NetAF/Commands/Scene/Drop.cs b/NetAF/Commands/Scene/Drop.cs index db768f17..30717334 100644 --- a/NetAF/Commands/Scene/Drop.cs +++ b/NetAF/Commands/Scene/Drop.cs @@ -32,6 +32,9 @@ public Reaction Invoke(Logic.Game game) if (game.Player == null) return new(ReactionResult.Error, "You must specify a character."); + if (!game.Player.CanTakeAndDropItems) + return new(ReactionResult.Error, "The player cannot drop items."); + if (item == null) return new(ReactionResult.Error, "You must specify what to drop."); diff --git a/NetAF/Commands/Scene/Take.cs b/NetAF/Commands/Scene/Take.cs index fe99411d..ab8aff77 100644 --- a/NetAF/Commands/Scene/Take.cs +++ b/NetAF/Commands/Scene/Take.cs @@ -32,6 +32,9 @@ public Reaction Invoke(Logic.Game game) if (game.Player == null) return new(ReactionResult.Error, "You must specify a character."); + if (!game.Player.CanTakeAndDropItems) + return new(ReactionResult.Error, "The player cannot take items."); + if (item == null) return new(ReactionResult.Error, "You must specify what to take."); diff --git a/NetAF/Commands/Scene/TakeAll.cs b/NetAF/Commands/Scene/TakeAll.cs index 5113c160..8f1c28fc 100644 --- a/NetAF/Commands/Scene/TakeAll.cs +++ b/NetAF/Commands/Scene/TakeAll.cs @@ -32,6 +32,9 @@ public Reaction Invoke(Logic.Game game) if (game.Player == null) return new(ReactionResult.Error, "You must specify a character."); + if (!game.Player.CanTakeAndDropItems) + return new(ReactionResult.Error, "The player cannot take items."); + if (game.Overworld.CurrentRegion.CurrentRoom == null) return new(ReactionResult.Error, "Not in a room."); diff --git a/NetAF/Interpretation/SceneCommandInterpreter.cs b/NetAF/Interpretation/SceneCommandInterpreter.cs index 3a6b3c89..e5a5133b 100644 --- a/NetAF/Interpretation/SceneCommandInterpreter.cs +++ b/NetAF/Interpretation/SceneCommandInterpreter.cs @@ -477,10 +477,10 @@ public CommandHelp[] GetContextualCommandHelp(Game game) commands.Add(Examine.CommandHelp); - if (game.Player.Items.Any()) + if (game.Player.Items.Any() && game.Player.CanTakeAndDropItems) commands.Add(Drop.CommandHelp); - if (game.Overworld.CurrentRegion.CurrentRoom.Items.Any()) + if (game.Overworld.CurrentRegion.CurrentRoom.Items.Any() && game.Player.CanTakeAndDropItems) { commands.Add(Take.CommandHelp); commands.Add(TakeAll.CommandHelp);