From 61003d68fb8149b9d56a00a130d0630d72044603 Mon Sep 17 00:00:00 2001 From: ben_singer Date: Fri, 25 Oct 2024 20:26:09 +0100 Subject: [PATCH] Added canConverse property to PlayableCharacter --- .../assets/characters/PlayableCharacter.kt | 9 +++++++-- .../benpollarduk/ktaf/commands/game/Talk.kt | 4 ++++ .../CharacterCommandInterpreter.kt | 2 +- .../characters/PlayableCharacterTest.kt | 12 ++++++------ .../ktaf/command/game/TalkTest.kt | 17 +++++++++++++++++ ktaf/src/test/resources/test.jar | Bin 60724 -> 60810 bytes 6 files changed, 35 insertions(+), 9 deletions(-) diff --git a/ktaf/src/main/kotlin/com/github/benpollarduk/ktaf/assets/characters/PlayableCharacter.kt b/ktaf/src/main/kotlin/com/github/benpollarduk/ktaf/assets/characters/PlayableCharacter.kt index 9754993..327828b 100644 --- a/ktaf/src/main/kotlin/com/github/benpollarduk/ktaf/assets/characters/PlayableCharacter.kt +++ b/ktaf/src/main/kotlin/com/github/benpollarduk/ktaf/assets/characters/PlayableCharacter.kt @@ -6,13 +6,16 @@ import com.github.benpollarduk.ktaf.assets.Item import com.github.benpollarduk.ktaf.assets.interaction.InteractWithItem import com.github.benpollarduk.ktaf.assets.interaction.InteractionEffect import com.github.benpollarduk.ktaf.assets.interaction.InteractionResult +import com.github.benpollarduk.ktaf.conversations.Converser /** * A playable character with the specified [identifier] and [description] and [items]. + * If the playable character can converse with a [Converser] [canConverse] should be set to true, else false. */ public class PlayableCharacter( override var identifier: Identifier, override var description: Description, + public val canConverse: Boolean = true, items: List = emptyList() ) : Character() { @@ -21,7 +24,7 @@ public class PlayableCharacter( } /** - * Trigger this [Player] to use the specified [item] on the specified [target]. + * Trigger this [PlayableCharacter] to use the specified [item] on the specified [target]. */ public fun useItem(item: Item, target: InteractWithItem): InteractionResult { val result = target.interact(item) @@ -42,10 +45,12 @@ public class PlayableCharacter( /** * A playable character with the specified [identifier] and [description] and [items]. + * If the playable character can converse with a [Converser] [canConverse] should be set to true, else false. */ public constructor( identifier: String, description: String, + canConverse: Boolean = true, items: List = emptyList() - ) : this(Identifier(identifier), Description(description), items) + ) : this(Identifier(identifier), Description(description), canConverse, items) } diff --git a/ktaf/src/main/kotlin/com/github/benpollarduk/ktaf/commands/game/Talk.kt b/ktaf/src/main/kotlin/com/github/benpollarduk/ktaf/commands/game/Talk.kt index 3059f3c..d5a635a 100644 --- a/ktaf/src/main/kotlin/com/github/benpollarduk/ktaf/commands/game/Talk.kt +++ b/ktaf/src/main/kotlin/com/github/benpollarduk/ktaf/commands/game/Talk.kt @@ -12,6 +12,10 @@ import com.github.benpollarduk.ktaf.logic.Game */ internal class Talk(private val converser: Converser?) : Command { override fun invoke(game: Game): Reaction { + if (!game.player.canConverse) { + return Reaction(ReactionResult.ERROR, "Can't converse.") + } + if (converser == null) { return Reaction(ReactionResult.ERROR, "Can't converse.") } diff --git a/ktaf/src/main/kotlin/com/github/benpollarduk/ktaf/interpretation/CharacterCommandInterpreter.kt b/ktaf/src/main/kotlin/com/github/benpollarduk/ktaf/interpretation/CharacterCommandInterpreter.kt index d849315..ad0646f 100644 --- a/ktaf/src/main/kotlin/com/github/benpollarduk/ktaf/interpretation/CharacterCommandInterpreter.kt +++ b/ktaf/src/main/kotlin/com/github/benpollarduk/ktaf/interpretation/CharacterCommandInterpreter.kt @@ -51,7 +51,7 @@ public class CharacterCommandInterpreter : Interpreter { val commands = mutableListOf() - if (game.overworld.currentRegion?.currentRoom?.characters?.any() == true) { + if (game.player.canConverse && game.overworld.currentRegion?.currentRoom?.characters?.any() == true) { commands.add(talkCommandHelp) } diff --git a/ktaf/src/test/kotlin/com/github/benpollarduk/ktaf/assets/characters/PlayableCharacterTest.kt b/ktaf/src/test/kotlin/com/github/benpollarduk/ktaf/assets/characters/PlayableCharacterTest.kt index 83cdbbe..c077c67 100644 --- a/ktaf/src/test/kotlin/com/github/benpollarduk/ktaf/assets/characters/PlayableCharacterTest.kt +++ b/ktaf/src/test/kotlin/com/github/benpollarduk/ktaf/assets/characters/PlayableCharacterTest.kt @@ -87,7 +87,7 @@ class PlayableCharacterTest { @Test fun `given a default instance when finding a visible item it has then instance is returned`() { // Given - val character = PlayableCharacter("", "", listOf(Item("Test", ""))) + val character = PlayableCharacter("", "", true, listOf(Item("Test", ""))) // When val result = character.findItem("Test") @@ -102,7 +102,7 @@ class PlayableCharacterTest { val item = Item("Test", "").apply { isPlayerVisible = false } - val character = PlayableCharacter("", "", listOf(item)) + val character = PlayableCharacter("", "", true, listOf(item)) // When val result = character.findItem("Test") @@ -117,7 +117,7 @@ class PlayableCharacterTest { val item = Item("Test", "").apply { isPlayerVisible = false } - val character = PlayableCharacter("", "", listOf(item)) + val character = PlayableCharacter("", "", true, listOf(item)) // When val result = character.findItem("Test", true) @@ -144,7 +144,7 @@ class PlayableCharacterTest { fun `given a default instance when giving an item it has then true is returned`() { // Given val item = Item("", "") - val character = PlayableCharacter("", "", listOf(item)) + val character = PlayableCharacter("", "", true, listOf(item)) val otherCharacter = NonPlayableCharacter("", "") // When @@ -158,7 +158,7 @@ class PlayableCharacterTest { fun `given a default instance when giving an item it has then item is dequired`() { // Given val item = Item("Test", "") - val character = PlayableCharacter("", "", listOf(item)) + val character = PlayableCharacter("", "", true, listOf(item)) val otherCharacter = NonPlayableCharacter("", "") // When @@ -173,7 +173,7 @@ class PlayableCharacterTest { fun `given a default instance when giving an item it has then other character has item`() { // Given val item = Item("Test", "") - val character = PlayableCharacter("", "", listOf(item)) + val character = PlayableCharacter("", "", true, listOf(item)) val otherCharacter = NonPlayableCharacter("", "") // When diff --git a/ktaf/src/test/kotlin/com/github/benpollarduk/ktaf/command/game/TalkTest.kt b/ktaf/src/test/kotlin/com/github/benpollarduk/ktaf/command/game/TalkTest.kt index 85883bd..a91b41d 100644 --- a/ktaf/src/test/kotlin/com/github/benpollarduk/ktaf/command/game/TalkTest.kt +++ b/ktaf/src/test/kotlin/com/github/benpollarduk/ktaf/command/game/TalkTest.kt @@ -1,6 +1,7 @@ package com.github.benpollarduk.ktaf.command.game import com.github.benpollarduk.ktaf.assets.characters.NonPlayableCharacter +import com.github.benpollarduk.ktaf.assets.characters.PlayableCharacter import com.github.benpollarduk.ktaf.assets.interaction.ReactionResult import com.github.benpollarduk.ktaf.commands.game.Talk import com.github.benpollarduk.ktaf.conversations.Conversation @@ -22,6 +23,22 @@ class TalkTest { Assertions.assertEquals(ReactionResult.ERROR, result.result) } + @Test + fun `given player that can't converse when invoke then return error`() { + // Given + val converser = NonPlayableCharacter("", "") + val command = Talk(converser) + val game = GameTestHelper.getBlankGame().also { + it.changePlayer(PlayableCharacter("", "", false)) + } + + // When + val result = command.invoke(game) + + // Then + Assertions.assertEquals(ReactionResult.ERROR, result.result) + } + @Test fun `given dead converser when invoke then return error`() { // Given diff --git a/ktaf/src/test/resources/test.jar b/ktaf/src/test/resources/test.jar index a96644f415b82c3e02c4f9f39a1cbe8c5630da15..27353729681fa09f2ac475e3b123b2d0f5f2487a 100644 GIT binary patch delta 4724 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 X#+Lc0cY1-wUI{>Gg`L)%c$n}%agJ#k delta 4726 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