module Game.LambdaHack.Client.AI
( queryAI
#ifdef EXPOSE_INTERNAL
, pickActorAndAction
#endif
) where
import Prelude ()
import Game.LambdaHack.Core.Prelude
import qualified Data.EnumMap.Strict as EM
import Game.LambdaHack.Client.AI.PickActionM
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.Point
import Game.LambdaHack.Common.State
import Game.LambdaHack.Common.Time
import Game.LambdaHack.Common.Types
queryAI :: MonadClient m => ActorId -> m RequestAI
queryAI :: forall (m :: * -> *). MonadClient m => ActorId -> m RequestAI
queryAI ActorId
aid = do
body <- (State -> Actor) -> m Actor
forall a. (State -> a) -> m a
forall (m :: * -> *) a. MonadStateRead m => (State -> a) -> m a
getsState ((State -> Actor) -> m Actor) -> (State -> Actor) -> m Actor
forall a b. (a -> b) -> a -> b
$ ActorId -> State -> Actor
getActorBody ActorId
aid
foeAssocs <- getsState $ foeRegularAssocs (bfid body) (blid body)
friendAssocs <- getsState $ friendRegularAssocs (bfid body) (blid body)
mleader <- getsState $ gleader . (EM.! bfid body) . sfactionD
mleaderCli <- getsClient sleader
unless (Just aid == mleader || mleader == mleaderCli) $
modifyClient $ \StateClient
cli -> StateClient
cli {_sleader = mleader}
(aidToMove, treq, oldFlee) <- pickActorAndAction foeAssocs friendAssocs
Nothing aid
let tryAgain = do
(StateClient -> StateClient) -> m ()
forall (m :: * -> *).
MonadClient m =>
(StateClient -> StateClient) -> m ()
modifyClient ((StateClient -> StateClient) -> m ())
-> (StateClient -> StateClient) -> m ()
forall a b. (a -> b) -> a -> b
$ \StateClient
cli -> StateClient
cli
{ _sleader = mleader
, sfleeD = EM.alter (const oldFlee) aidToMove $ sfleeD cli }
(a, t, _) <- [(ActorId, Actor)]
-> [(ActorId, Actor)]
-> Maybe ActorId
-> ActorId
-> m (ActorId, RequestTimed, Maybe (Point, Time))
forall (m :: * -> *).
MonadClient m =>
[(ActorId, Actor)]
-> [(ActorId, Actor)]
-> Maybe ActorId
-> ActorId
-> m (ActorId, RequestTimed, Maybe (Point, Time))
pickActorAndAction [(ActorId, Actor)]
foeAssocs [(ActorId, Actor)]
friendAssocs
(ActorId -> Maybe ActorId
forall a. a -> Maybe a
Just ActorId
aidToMove) ActorId
aid
return (a, t)
(aidToMove2, treq2) <-
if mleader /= Just aid
then return (aidToMove, treq)
else case treq of
RequestTimed
ReqWait -> m (ActorId, RequestTimed)
tryAgain
RequestTimed
ReqYell -> m (ActorId, RequestTimed)
tryAgain
RequestTimed
_ -> (ActorId, RequestTimed) -> m (ActorId, RequestTimed)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (ActorId
aidToMove, RequestTimed
treq)
return ( ReqAITimed treq2
, if aidToMove2 /= aid then Just aidToMove2 else Nothing )
pickActorAndAction :: MonadClient m
=> [(ActorId, Actor)] -> [(ActorId, Actor)]
-> Maybe ActorId -> ActorId
-> m (ActorId, RequestTimed, Maybe (Point, Time))
pickActorAndAction :: forall (m :: * -> *).
MonadClient m =>
[(ActorId, Actor)]
-> [(ActorId, Actor)]
-> Maybe ActorId
-> ActorId
-> m (ActorId, RequestTimed, Maybe (Point, Time))
pickActorAndAction [(ActorId, Actor)]
foeAssocs [(ActorId, Actor)]
friendAssocs Maybe ActorId
maid ActorId
aid = do
mleader <- (StateClient -> Maybe ActorId) -> m (Maybe ActorId)
forall a. (StateClient -> a) -> m a
forall (m :: * -> *) a.
MonadClientRead m =>
(StateClient -> a) -> m a
getsClient StateClient -> Maybe ActorId
sleader
aidToMove <-
if mleader == Just aid
then pickActorToMove foeAssocs friendAssocs maid
else do
setTargetFromDoctrines foeAssocs friendAssocs aid
return aid
oldFlee <- getsClient $ EM.lookup aidToMove . sfleeD
let retry = ActorId -> Maybe ActorId
forall a. a -> Maybe a
Just ActorId
aidToMove Maybe ActorId -> Maybe ActorId -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe ActorId
maid
treq <- pickAction foeAssocs friendAssocs aidToMove retry
return (aidToMove, treq, oldFlee)