Files
loop/src/Dodge/Creature/AlertLevel.hs
T
2021-07-25 01:29:43 +02:00

66 lines
2.6 KiB
Haskell

{- | Deals with changes in a creature's awareness of other creatures. -}
module Dodge.Creature.AlertLevel
where
import Dodge.Data
import Dodge.Creature.AlertLevel.Data
import Dodge.Base.Collide
import StrictHelp
import Control.Lens
import Control.Monad.Reader
import qualified Data.IntMap.Strict as IM
{- | Ties together (currently) an awareness and attention update -}
basicPerceptionUpdate
:: [Int] -- ^ List of creature ids that may direct attention and awareness
-> World
-> Creature
-> Creature
basicPerceptionUpdate is w cr
= basicAwarenessUpdate w $ basicAttentionUpdate is w cr
basicPerceptionUpdateR
:: [Int] -- ^ List of creature ids that may direct attention and awareness
-> Creature
-> Reader World Creature
basicPerceptionUpdateR is cr = reader $ \w ->
basicAwarenessUpdate w $ basicAttentionUpdate is w cr
{- | Update a creatures awareness based upon the creatures current direction
of attention -}
basicAwarenessUpdate
:: World -> Creature -> Creature
basicAwarenessUpdate _ cr = case _crAttentionDir cr of
AttentiveTo is -> cr & crAwarenessLevel %~ updateAwareness is
Fixated i -> cr & crAwarenessLevel
%~ ( IM.insert i (Cognizant 100) . IM.mapMaybe decreaseAwareness)
{- | Increase awareness of a given list of ids -}
updateAwareness :: [Int] -> IM.IntMap AwarenessLevel -> IM.IntMap AwarenessLevel
updateAwareness is imawareness
= foldr (\k -> IM.insertWith (\_ x -> increaseAwareness x) k (AwarenessInt 1))
(IM.mapMaybe decreaseAwareness imawareness) is
-- (IM.mapMaybe decreaseAwareness imawareness) is
{- | Increase awareness level -}
increaseAwareness :: AwarenessLevel -> AwarenessLevel
increaseAwareness (AwarenessInt x)
| x < 100 = AwarenessInt $ x + 2
| otherwise = Cognizant 1
increaseAwareness (Cognizant x)
| x < 100 = Cognizant (x + 2)
| otherwise = Cognizant 100
{- | Decrease awareness level. Returns 'Maybe' value for use with 'IM.mapMaybe'
-}
decreaseAwareness :: AwarenessLevel -> Maybe AwarenessLevel
decreaseAwareness (AwarenessInt 0) = Nothing
decreaseAwareness (AwarenessInt x) = Just $ AwarenessInt (x - 1)
decreaseAwareness (Cognizant 0) = Just $ AwarenessInt 100
decreaseAwareness (Cognizant x) = Just $ Cognizant $ x - 1
{- | Given a fixed group of creatures, direct attention to those of them that
- are in view. -}
basicAttentionUpdate
:: [Int] -- ^ Creatures that may attract this creature's attention
-> World
-> Creature
-> Creature
basicAttentionUpdate cids w cr = cr & crAttentionDir .~
AttentiveTo (forceFoldable $ filter (\cid -> canSee (_crID cr) cid w) cids)