140 lines
4.7 KiB
Haskell
140 lines
4.7 KiB
Haskell
{- | 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
|