{- | Function updating a creature in a Reader World environment -} module Dodge.Creature.ReaderUpdate where import Dodge.Data import Dodge.Creature.Stance.Data import Dodge.Creature.Test import Dodge.Creature.Volition import Dodge.Creature.AlertLevel.Data import Geometry import qualified Data.IntMap.Strict as IM import Control.Monad.Reader import Control.Lens overrideMeleeCloseTargetR :: Creature -> Reader World Creature overrideMeleeCloseTargetR cr = return $ maybe cr (tryMeleeAttack cr) (_crTarget cr) tryMeleeAttack :: Creature -> Creature -> Creature tryMeleeAttack cr tcr | _crMeleeCooldown cr == 0 && dist (_crPos tcr) cpos < _crRad cr + _crRad tcr + 5 && abs (_crDir cr - argV (_crPos tcr -.- cpos)) < pi/4 -- = cr & crActionPlan . crStrategy .~ StrategyActions MeleeStrike meleeActions = cr & crActionPlan . crImpulse .~ [Melee $ _crID tcr] | otherwise = cr where cpos = _crPos cr --meleeActions = -- [DoImpulses [Melee (_crID tcr)] -- `DoActionThen` DoImpulses [ChangeStrategy WatchAndWait] -- ] chaseTargetR :: (Creature -> World -> Maybe Creature) -- ^ Function for determining target -> Creature -> Reader World Creature chaseTargetR targFunc cr = reader $ \w -> case targFunc cr w of Nothing -> cr Just crTarg -> cr & crActionPlan . crImpulse .~ chaseTarg cr crTarg chaseTarg :: Creature -> Creature -> [Impulse] chaseTarg cr crT | dist tpos cpos < combinedRad + 5 && abs (_crDir cr - argV (tpos -.- cpos)) < pi/4 = [ TurnToward tpos 0.05 ] | abs (_crDir cr - argV (tpos -.- cpos)) < pi/4 = [MoveForward 2.5 , TurnToward tpos 0.2, RandomTurn 0.2 ] | otherwise = [MoveForward 2.5 , TurnToward tpos 0.05, RandomTurn 0.2 ] where cpos = _crPos cr tpos = _crPos crT combinedRad = _crRad cr + _crRad crT doStrategyActionsR :: Creature -> Reader World Creature doStrategyActionsR cr = return $ case cr ^? crActionPlan . crStrategy of Just (StrategyActions strat acs) -> cr & crActionPlan . crAction .~ acs & crActionPlan . crStrategy .~ strat _ -> cr reloadOverrideR :: Creature -> Reader World Creature reloadOverrideR cr | cr ^? crInv . ix (_crInvSel cr) . wpLoadedAmmo == Just 0 && cr ^. crStance . posture == Aiming = return $ cr & crActionPlan . crStrategy .~ StrategyActions Reload reloadActions | otherwise = return cr where reloadActions = [ holsterWeapon , WaitThen 1 $ DoActionWhileInterrupt NoAction crIsReloading (DoImpulses [ChangeStrategy WatchAndWait]) ] overrideInternalR :: ((World , Creature) -> Bool) -> (World -> Creature -> Creature) -> Creature -> Reader World Creature overrideInternalR test update cr = reader $ \w -> if test (w,cr) then update w cr else cr overrideInternalRR :: ((World , Creature) -> Bool) -> (Creature -> Reader World Creature) -> Creature -> Reader World Creature overrideInternalRR test update cr = reader $ \w -> if test (w,cr) then runReader (update cr) w else cr watchUpdateStratR :: [ ((World, Creature) -> Bool, World -> Creature -> Strategy) ] -> Creature -> Reader World Creature watchUpdateStratR fs cr = reader $ \w -> case cr ^? crActionPlan . crStrategy of Just WatchAndWait -> cr & crActionPlan . crStrategy .~ listGuard (fs, \_ _ -> WatchAndWait) (w, cr) w cr _ -> cr watchUpdateStratRRR :: [ (Creature -> Reader World Bool, Creature -> Reader World Strategy) ] -> Creature -> Reader World Creature watchUpdateStratRRR fs cr = do return undefined fs cr -- reader $ \w -> case cr ^? crActionPlan . crStrategy of -- Just WatchAndWait -> cr -- & crActionPlan . crStrategy .~ listGuard (fs, \_ _ -> WatchAndWait) (w, cr) w cr -- _ -> cr listGuard :: ([(a -> Bool, b)] , b) -> a -> b listGuard ( (test,y):ps, z ) x | test x = y | otherwise = listGuard (ps, z) x listGuard (_,z) _ = z targetYouWhenCognizantR :: Creature -> Reader World Creature targetYouWhenCognizantR cr = reader $ \w -> case cr ^? crAwarenessLevel . ix 0 of -- Just (Cognizant _) -> cr & crTarget ?~ _creatures w IM.! 0 Just (Cognizant _) -> cr {_crTarget = Just $! _creatures w IM.! 0} _ -> cr & crTarget .~ Nothing shootTargetWithStratR :: (Creature -> World -> Maybe Creature) -- ^ Function for determining target -> (World -> Creature -> Creature -> [Action] -> [Action]) -- ^ Function for determining shooting strategy given target -> Creature -> Reader World Creature shootTargetWithStratR targFunc strat cr = reader $ \w -> case targFunc cr w of Nothing -> cr Just crTarg -> cr & crActionPlan . crAction %~ strat w cr crTarg