{- | 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)