{-# LANGUAGE GADTs #-}
module Game.LambdaHack.Client.AI
( queryAI
#ifdef EXPOSE_INTERNAL
, pickActorAndAction, udpdateCondInMelee
#endif
) where
import Prelude ()
import Game.LambdaHack.Common.Prelude
import qualified Data.EnumMap.Strict as EM
import Game.LambdaHack.Client.AI.HandleAbilityM
import Game.LambdaHack.Client.AI.PickActorM
import Game.LambdaHack.Client.MonadClient
import Game.LambdaHack.Client.Request
import Game.LambdaHack.Client.State
import Game.LambdaHack.Common.Actor
import Game.LambdaHack.Common.ActorState
import Game.LambdaHack.Common.Faction
import Game.LambdaHack.Common.MonadStateRead
import Game.LambdaHack.Common.State
queryAI :: MonadClient m => ActorId -> m RequestAI
queryAI aid = do
side <- getsClient sside
mleader <- getsState $ gleader . (EM.! side) . sfactionD
mleaderCli <- getsClient sleader
unless (Just aid == mleader || mleader == mleaderCli) $
modifyClient $ \cli -> cli {_sleader = mleader}
udpdateCondInMelee aid
(aidToMove, treq) <- pickActorAndAction Nothing aid
(aidToMove2, treq2) <-
case treq of
RequestAnyAbility ReqWait | mleader == Just aid -> do
modifyClient $ \cli -> cli {_sleader = mleader}
pickActorAndAction (Just (aidToMove, treq)) aid
_ -> return (aidToMove, treq)
return ( ReqAITimed treq2
, if aidToMove2 /= aid then Just aidToMove2 else Nothing )
pickActorAndAction :: MonadClient m
=> Maybe (ActorId, RequestAnyAbility) -> ActorId
-> m (ActorId, RequestAnyAbility)
{-# INLINE pickActorAndAction #-}
pickActorAndAction maid aid = do
mleader <- getsClient sleader
aidToMove <-
if mleader == Just aid
then pickActorToMove (fst <$> maid)
else do
setTargetFromTactics aid
return aid
treq <- case maid of
Just (aidOld, treqOld) | aidToMove == aidOld ->
return treqOld
_ -> pickAction aidToMove (isJust maid)
return (aidToMove, treq)
udpdateCondInMelee :: MonadClient m => ActorId -> m ()
udpdateCondInMelee aid = do
b <- getsState $ getActorBody aid
condInMelee <- getsClient $ (EM.! blid b) . scondInMelee
case condInMelee of
Just{} -> return ()
Nothing -> do
newCond <- getsState $ inMelee b
modifyClient $ \cli ->
cli {scondInMelee =
EM.adjust (const $ Just newCond) (blid b) (scondInMelee cli)}