{-# LANGUAGE GADTs #-}
module Game.LambdaHack.Client.AI
( queryAI
#ifdef EXPOSE_INTERNAL
, pickActorAndAction
#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.Faction
import Game.LambdaHack.Common.MonadStateRead
import Game.LambdaHack.Common.Point
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}
(aidToMove, treq, oldFlee) <- pickActorAndAction Nothing aid
(aidToMove2, treq2) <-
case treq of
RequestAnyAbility ReqWait | mleader == Just aid -> do
modifyClient $ \cli -> cli
{ _sleader = mleader
, sfleeD = case oldFlee of
Just p -> EM.insert aidToMove p $ sfleeD cli
Nothing -> EM.delete aidToMove $ sfleeD cli }
(a, t, _) <- pickActorAndAction (Just (aidToMove, treq)) aid
return (a, t)
_ -> return (aidToMove, treq)
return ( ReqAITimed treq2
, if aidToMove2 /= aid then Just aidToMove2 else Nothing )
pickActorAndAction :: MonadClient m
=> Maybe (ActorId, RequestAnyAbility) -> ActorId
-> m (ActorId, RequestAnyAbility, Maybe Point)
{-# INLINE pickActorAndAction #-}
pickActorAndAction maid aid = do
mleader <- getsClient sleader
aidToMove <-
if mleader == Just aid
then pickActorToMove (fst <$> maid)
else do
setTargetFromTactics aid
return aid
oldFlee <- getsClient $ EM.lookup aidToMove . sfleeD
treq <- case maid of
Just (aidOld, treqOld) | aidToMove == aidOld ->
return treqOld
_ -> pickAction aidToMove (isJust maid)
return (aidToMove, treq, oldFlee)