From 15b4f0e6a73987f9afbc46f46862b5120029e715 Mon Sep 17 00:00:00 2001 From: Griffin Smith Date: Sat, 16 May 2020 18:57:07 -0400 Subject: [PATCH] Stop auto-moving if there's an enemy nearby If at any point during an auto-move there's an enemy in the character's line of sight, cancel the autocommand and send a message --- src/Xanthous/App/Autocommands.hs | 37 ++++++++++++++++++++++++------- src/Xanthous/Entities/RawTypes.hs | 5 ++++- src/Xanthous/Game/Lenses.hs | 9 +++++++- src/Xanthous/messages.yaml | 4 +++- 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/Xanthous/App/Autocommands.hs b/src/Xanthous/App/Autocommands.hs index e8d94ce74..35b92bba7 100644 --- a/src/Xanthous/App/Autocommands.hs +++ b/src/Xanthous/App/Autocommands.hs @@ -4,16 +4,24 @@ module Xanthous.App.Autocommands , autoStep ) where -------------------------------------------------------------------------------- -import Xanthous.Prelude +import Xanthous.Prelude -------------------------------------------------------------------------------- -import Control.Concurrent (threadDelay) +import Control.Concurrent (threadDelay) +import qualified Data.Aeson as A +import Data.Aeson (object) +import Data.List.NonEmpty (nonEmpty) +import qualified Data.List.NonEmpty as NE +import Control.Monad.State (gets) -------------------------------------------------------------------------------- -import Xanthous.App.Common -import Xanthous.App.Time -import Xanthous.Data -import Xanthous.Data.App -import Xanthous.Entities.Character (speed) -import Xanthous.Game.State +import Xanthous.App.Common +import Xanthous.App.Time +import Xanthous.Data +import Xanthous.Data.App +import Xanthous.Entities.Character (speed) +import Xanthous.Entities.Creature (Creature, creatureType) +import Xanthous.Entities.RawTypes (hostile) +import Xanthous.Game.State +import Xanthous.Game.Lenses (characterVisibleEntities) -------------------------------------------------------------------------------- autoStep :: Autocommand -> AppM () @@ -24,7 +32,20 @@ autoStep (AutoMove dir) = do characterPosition .= newPos stepGameBy =<< uses (character . speed) (|*| 1) describeEntitiesAt newPos + maybeVisibleEnemies <- nonEmpty <$> enemiesInSight + for_ maybeVisibleEnemies $ \visibleEnemies -> do + say ["autoMove", "enemyInSight"] + $ object [ "firstEntity" A..= NE.head visibleEnemies ] + cancelAutocommand Just _ -> cancelAutocommand + where + enemiesInSight :: AppM [Creature] + enemiesInSight = do + ents <- gets characterVisibleEntities + pure $ ents + ^.. folded + . _SomeEntity @Creature + . filtered (view $ creatureType . hostile) -------------------------------------------------------------------------------- diff --git a/src/Xanthous/Entities/RawTypes.hs b/src/Xanthous/Entities/RawTypes.hs index 4b31524ad..30039662f 100644 --- a/src/Xanthous/Entities/RawTypes.hs +++ b/src/Xanthous/Entities/RawTypes.hs @@ -9,6 +9,7 @@ module Xanthous.Entities.RawTypes -- * Creatures , CreatureType(..) + , hostile -- * Items , ItemType(..) @@ -63,6 +64,9 @@ data CreatureType = CreatureType CreatureType makeFieldsNoPrefix ''CreatureType +hostile :: Lens' CreatureType Bool +hostile = friendly . involuted not + -------------------------------------------------------------------------------- data EdibleItem = EdibleItem @@ -127,4 +131,3 @@ data EntityRaw via WithOptions '[ SumEnc ObjWithSingleField ] EntityRaw makePrisms ''EntityRaw - diff --git a/src/Xanthous/Game/Lenses.hs b/src/Xanthous/Game/Lenses.hs index 48b7235d2..5d5e673c5 100644 --- a/src/Xanthous/Game/Lenses.hs +++ b/src/Xanthous/Game/Lenses.hs @@ -8,6 +8,7 @@ module Xanthous.Game.Lenses , characterPosition , updateCharacterVision , characterVisiblePositions + , characterVisibleEntities , getInitialState , initialStateFromSeed , entitiesAtCharacter @@ -28,7 +29,8 @@ import Xanthous.Game.State import Xanthous.Data import Xanthous.Data.Levels import qualified Xanthous.Data.EntityMap as EntityMap -import Xanthous.Data.EntityMap.Graphics (visiblePositions) +import Xanthous.Data.EntityMap.Graphics + (visiblePositions, visibleEntities) import Xanthous.Data.VectorBag import Xanthous.Entities.Character (Character, mkCharacter) import {-# SOURCE #-} Xanthous.Entities.Entities () @@ -101,6 +103,11 @@ characterVisiblePositions game = let charPos = game ^. characterPosition in visiblePositions charPos visionRadius $ game ^. entities +characterVisibleEntities :: GameState -> EntityMap.EntityMap SomeEntity +characterVisibleEntities game = + let charPos = game ^. characterPosition + in visibleEntities charPos visionRadius $ game ^. entities + entitiesCollision :: ( Functor f , forall xx. MonoFoldable (f xx) diff --git a/src/Xanthous/messages.yaml b/src/Xanthous/messages.yaml index 404264237..c1835ef23 100644 --- a/src/Xanthous/messages.yaml +++ b/src/Xanthous/messages.yaml @@ -111,7 +111,9 @@ drop: - You take the {{item.itemType.name}} out of your backpack and put it on the ground. - You take the {{item.itemType.name}} out of your backpack and drop it on the ground. - +autoMove: + enemyInSight: + - There's a {{firstEntity.creatureType.name}} nearby! ### tutorial: