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.Faction
import Game.LambdaHack.Common.MonadStateRead
import Game.LambdaHack.Common.State
import Game.LambdaHack.Common.Types
import Game.LambdaHack.Common.Point
queryAI :: MonadClient m => ActorId -> m RequestAI
queryAI :: ActorId -> m RequestAI
queryAI aid :: ActorId
aid = do
FactionId
side <- (StateClient -> FactionId) -> m FactionId
forall (m :: * -> *) a.
MonadClientRead m =>
(StateClient -> a) -> m a
getsClient StateClient -> FactionId
sside
Maybe ActorId
mleader <- (State -> Maybe ActorId) -> m (Maybe ActorId)
forall (m :: * -> *) a. MonadStateRead m => (State -> a) -> m a
getsState ((State -> Maybe ActorId) -> m (Maybe ActorId))
-> (State -> Maybe ActorId) -> m (Maybe ActorId)
forall a b. (a -> b) -> a -> b
$ Faction -> Maybe ActorId
gleader (Faction -> Maybe ActorId)
-> (State -> Faction) -> State -> Maybe ActorId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (EnumMap FactionId Faction -> FactionId -> Faction
forall k a. Enum k => EnumMap k a -> k -> a
EM.! FactionId
side) (EnumMap FactionId Faction -> Faction)
-> (State -> EnumMap FactionId Faction) -> State -> Faction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. State -> EnumMap FactionId Faction
sfactionD
Maybe ActorId
mleaderCli <- (StateClient -> Maybe ActorId) -> m (Maybe ActorId)
forall (m :: * -> *) a.
MonadClientRead m =>
(StateClient -> a) -> m a
getsClient StateClient -> Maybe ActorId
sleader
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (ActorId -> Maybe ActorId
forall a. a -> Maybe a
Just ActorId
aid Maybe ActorId -> Maybe ActorId -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe ActorId
mleader Bool -> Bool -> Bool
|| Maybe ActorId
mleader Maybe ActorId -> Maybe ActorId -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe ActorId
mleaderCli) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
(StateClient -> StateClient) -> m ()
forall (m :: * -> *).
MonadClient m =>
(StateClient -> StateClient) -> m ()
modifyClient ((StateClient -> StateClient) -> m ())
-> (StateClient -> StateClient) -> m ()
forall a b. (a -> b) -> a -> b
$ \cli :: StateClient
cli -> StateClient
cli {_sleader :: Maybe ActorId
_sleader = Maybe ActorId
mleader}
(aidToMove :: ActorId
aidToMove, treq :: RequestTimed
treq, oldFlee :: Maybe Point
oldFlee) <- Maybe ActorId -> ActorId -> m (ActorId, RequestTimed, Maybe Point)
forall (m :: * -> *).
MonadClient m =>
Maybe ActorId -> ActorId -> m (ActorId, RequestTimed, Maybe Point)
pickActorAndAction Maybe ActorId
forall a. Maybe a
Nothing ActorId
aid
(aidToMove2 :: ActorId
aidToMove2, treq2 :: RequestTimed
treq2) <-
case RequestTimed
treq of
ReqWait | Maybe ActorId
mleader Maybe ActorId -> Maybe ActorId -> Bool
forall a. Eq a => a -> a -> Bool
== ActorId -> Maybe ActorId
forall a. a -> Maybe a
Just ActorId
aid -> 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
$ \cli :: StateClient
cli -> StateClient
cli
{ _sleader :: Maybe ActorId
_sleader = Maybe ActorId
mleader
, sfleeD :: EnumMap ActorId Point
sfleeD = case Maybe Point
oldFlee of
Just p :: Point
p -> ActorId -> Point -> EnumMap ActorId Point -> EnumMap ActorId Point
forall k a. Enum k => k -> a -> EnumMap k a -> EnumMap k a
EM.insert ActorId
aidToMove Point
p (EnumMap ActorId Point -> EnumMap ActorId Point)
-> EnumMap ActorId Point -> EnumMap ActorId Point
forall a b. (a -> b) -> a -> b
$ StateClient -> EnumMap ActorId Point
sfleeD StateClient
cli
Nothing -> ActorId -> EnumMap ActorId Point -> EnumMap ActorId Point
forall k a. Enum k => k -> EnumMap k a -> EnumMap k a
EM.delete ActorId
aidToMove (EnumMap ActorId Point -> EnumMap ActorId Point)
-> EnumMap ActorId Point -> EnumMap ActorId Point
forall a b. (a -> b) -> a -> b
$ StateClient -> EnumMap ActorId Point
sfleeD StateClient
cli }
(a :: ActorId
a, t :: RequestTimed
t, _) <- Maybe ActorId -> ActorId -> m (ActorId, RequestTimed, Maybe Point)
forall (m :: * -> *).
MonadClient m =>
Maybe ActorId -> ActorId -> m (ActorId, RequestTimed, Maybe Point)
pickActorAndAction (ActorId -> Maybe ActorId
forall a. a -> Maybe a
Just ActorId
aidToMove) ActorId
aid
(ActorId, RequestTimed) -> m (ActorId, RequestTimed)
forall (m :: * -> *) a. Monad m => a -> m a
return (ActorId
a, RequestTimed
t)
_ -> (ActorId, RequestTimed) -> m (ActorId, RequestTimed)
forall (m :: * -> *) a. Monad m => a -> m a
return (ActorId
aidToMove, RequestTimed
treq)
RequestAI -> m RequestAI
forall (m :: * -> *) a. Monad m => a -> m a
return ( RequestTimed -> ReqAI
ReqAITimed RequestTimed
treq2
, if ActorId
aidToMove2 ActorId -> ActorId -> Bool
forall a. Eq a => a -> a -> Bool
/= ActorId
aid then ActorId -> Maybe ActorId
forall a. a -> Maybe a
Just ActorId
aidToMove2 else Maybe ActorId
forall a. Maybe a
Nothing )
pickActorAndAction :: MonadClient m
=> Maybe ActorId -> ActorId
-> m (ActorId, RequestTimed, Maybe Point)
pickActorAndAction :: Maybe ActorId -> ActorId -> m (ActorId, RequestTimed, Maybe Point)
pickActorAndAction maid :: Maybe ActorId
maid aid :: ActorId
aid = do
Maybe ActorId
mleader <- (StateClient -> Maybe ActorId) -> m (Maybe ActorId)
forall (m :: * -> *) a.
MonadClientRead m =>
(StateClient -> a) -> m a
getsClient StateClient -> Maybe ActorId
sleader
ActorId
aidToMove <-
if Maybe ActorId
mleader Maybe ActorId -> Maybe ActorId -> Bool
forall a. Eq a => a -> a -> Bool
== ActorId -> Maybe ActorId
forall a. a -> Maybe a
Just ActorId
aid
then Maybe ActorId -> m ActorId
forall (m :: * -> *). MonadClient m => Maybe ActorId -> m ActorId
pickActorToMove Maybe ActorId
maid
else do
ActorId -> m ()
forall (m :: * -> *). MonadClient m => ActorId -> m ()
setTargetFromTactics ActorId
aid
ActorId -> m ActorId
forall (m :: * -> *) a. Monad m => a -> m a
return ActorId
aid
Maybe Point
oldFlee <- (StateClient -> Maybe Point) -> m (Maybe Point)
forall (m :: * -> *) a.
MonadClientRead m =>
(StateClient -> a) -> m a
getsClient ((StateClient -> Maybe Point) -> m (Maybe Point))
-> (StateClient -> Maybe Point) -> m (Maybe Point)
forall a b. (a -> b) -> a -> b
$ ActorId -> EnumMap ActorId Point -> Maybe Point
forall k a. Enum k => k -> EnumMap k a -> Maybe a
EM.lookup ActorId
aidToMove (EnumMap ActorId Point -> Maybe Point)
-> (StateClient -> EnumMap ActorId Point)
-> StateClient
-> Maybe Point
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StateClient -> EnumMap ActorId Point
sfleeD
let retry :: Bool
retry = Bool -> (ActorId -> Bool) -> Maybe ActorId -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False (ActorId
aidToMove ActorId -> ActorId -> Bool
forall a. Eq a => a -> a -> Bool
==) Maybe ActorId
maid
RequestTimed
treq <- ActorId -> Bool -> m RequestTimed
forall (m :: * -> *).
MonadClient m =>
ActorId -> Bool -> m RequestTimed
pickAction ActorId
aidToMove Bool
retry
(ActorId, RequestTimed, Maybe Point)
-> m (ActorId, RequestTimed, Maybe Point)
forall (m :: * -> *) a. Monad m => a -> m a
return (ActorId
aidToMove, RequestTimed
treq, Maybe Point
oldFlee)