about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGriffin Smith <root@gws.fyi>2020-05-16T22·57-0400
committerGriffin Smith <root@gws.fyi>2020-05-16T22·57-0400
commit15b4f0e6a73987f9afbc46f46862b5120029e715 (patch)
tree780f05b979e2d01f473ea6a75cb7fc9242cc0b68
parent34cabba896507f2b6523d6aec344ec1c88e453be (diff)
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
-rw-r--r--src/Xanthous/App/Autocommands.hs37
-rw-r--r--src/Xanthous/Entities/RawTypes.hs5
-rw-r--r--src/Xanthous/Game/Lenses.hs9
-rw-r--r--src/Xanthous/messages.yaml4
4 files changed, 44 insertions, 11 deletions
diff --git a/src/Xanthous/App/Autocommands.hs b/src/Xanthous/App/Autocommands.hs
index e8d94ce741fd..35b92bba7289 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 4b31524ad7f1..30039662f071 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 48b7235d2263..5d5e673c5b88 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 40426423783c..c1835ef2327b 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: