{- | Module testing for properties of creatures, whether they are reloading, etc. Each function takes the world and a creature and returns a bool. Note that the creature NEED NOT be the same as the creature with that id in the world, in fact in some cases a creature with that id may not even exist. -} module Dodge.Creature.Test -- ( crCanShoot -- , crIsAiming' -- , crIsReloading -- , crIsAiming -- , crHasTargetLOS -- , crAwayFromPost -- , crHasTargetR -- , crStratConMatchesR -- , crHasAmmo -- , crSafeDistFromTarg -- ) where import Dodge.Data import Dodge.Base.Collide import Geometry import SameConstr import Data.List (find) import Data.Maybe import qualified Data.IntMap.Strict as IM import Control.Lens import Control.Monad.Reader andTest :: (a -> Bool) -> (a -> Bool) -> a -> Bool andTest f g a = f a && g a onBoth :: (a -> b -> c) -> (d -> a) -> (d -> b) -> d -> c onBoth f g h x = f (g x) (h x) crIsReloading :: Creature -> Bool crIsReloading cr = case cr ^? crInv . ix (_crInvSel cr) . itConsumption . reloadState . _Just' of Just t -> t > 0 _ -> False crIsReloadingR :: Creature -> Reader World Bool crIsReloadingR cr = return $ case cr ^? crInv . ix (_crInvSel cr) . itConsumption . reloadState . _Just' of Just t -> t > 0 _ -> False crCanSeeCr :: Creature -> (World, Creature) -> Bool crCanSeeCr tcr (w,cr) = hasLOS (_crPos cr) (_crPos tcr) w crCanSeeR :: Creature -> Creature -> Reader World Bool crCanSeeR tcr cr = reader $ \w -> hasLOS (_crPos cr) (_crPos tcr) w crCanSeeCID :: Int -> (World, Creature) -> Bool crCanSeeCID cid (w,cr) = hasLOS (_crPos cr) (_crPos $ _creatures w IM.! cid) w crCanSeeCIDR :: Int -> Creature -> Reader World Bool crCanSeeCIDR cid cr = reader $ \w -> hasLOS (_crPos cr) (_crPos $ _creatures w IM.! cid) w crIsAiming :: Creature -> Bool crIsAiming cr = _posture (_crStance cr) == Aiming crIsAiming' :: Creature -> Bool crIsAiming' cr = _posture (_crStance cr) == Aiming crHasTarget' :: Creature -> Bool crHasTarget' cr = isJust $ cr ^? crIntention . targetCr . _Just crHasTargetLOS :: World -> Creature -> Bool crHasTargetLOS w cr = case cr ^? crIntention . targetCr . _Just of Just i -> crCanSeeCr i (w,cr) Nothing -> False crHasTargetLOS' :: World -> Creature -> Bool crHasTargetLOS' w cr = case cr ^? crIntention . targetCr . _Just of Just i -> crCanSeeCr i (w,cr) Nothing -> False crHasTargetLOSR :: Creature -> Reader World Bool crHasTargetLOSR cr = reader $ \w -> case cr ^? crIntention . targetCr . _Just of Just i -> crCanSeeCr i (w,cr) Nothing -> False crSafeDistFromTarg :: Float -> Creature -> Bool crSafeDistFromTarg d cr = case cr ^? crIntention . targetCr . _Just of Just tcr -> dist (_crPos cr) (_crPos tcr) > d Nothing -> True crSafeDistFromTargR :: Float -> Creature -> Reader World Bool crSafeDistFromTargR d cr = return $ case cr ^? crIntention . targetCr . _Just of Just tcr -> dist (_crPos cr) (_crPos tcr) > d Nothing -> True crStratConMatches :: Strategy -> (World,Creature) -> Bool crStratConMatches strat (_,cr) = eqConstr strat (_crStrategy $ _crActionPlan cr) crStratConMatches' :: Strategy -> Creature -> Bool crStratConMatches' strat cr = eqConstr strat (_crStrategy $ _crActionPlan cr) crStratConMatchesR :: Strategy -> Creature -> Reader World Bool crStratConMatchesR strat cr = return $ eqConstr strat (_crStrategy $ _crActionPlan cr) crAwayFromPost :: Creature -> Bool crAwayFromPost cr = case find sentinelGoal $ _crGoal $ _crActionPlan cr of Just (SentinelAt p _) -> dist p (_crPos cr) > 15 _ -> False where sentinelGoal (SentinelAt _ _) = True sentinelGoal _ = False crAwayFromPostR :: Creature -> Reader World Bool crAwayFromPostR cr = return $ case find sentinelGoal $ _crGoal $ _crActionPlan cr of Just (SentinelAt p _) -> dist p (_crPos cr) > 15 _ -> False where sentinelGoal (SentinelAt _ _) = True sentinelGoal _ = False crHasAmmo :: Creature -> Bool crHasAmmo cr = maybe False (> 0) $ cr ^? crInv . ix (_crInvSel cr) . itConsumption . ammoLoaded crHasAmmo' :: Creature -> Bool crHasAmmo' cr = maybe False (> 0) $ cr ^? crInv . ix (_crInvSel cr) . itConsumption . ammoLoaded crCanShoot :: Creature -> Bool crCanShoot p = crIsAiming p && crHasAmmo p crCanShoot' :: Creature -> Bool crCanShoot' p = crIsAiming' p && crHasAmmo' p