{-# LANGUAGE TupleSections #-}
module Game.LambdaHack.Client.AI.PickTargetM
( refreshTarget
#ifdef EXPOSE_INTERNAL
, computeTarget
#endif
) where
import Prelude ()
import Game.LambdaHack.Core.Prelude
import qualified Data.EnumMap.Strict as EM
import qualified Data.EnumSet as ES
import Game.LambdaHack.Client.AI.ConditionM
import Game.LambdaHack.Client.Bfs
import Game.LambdaHack.Client.BfsM
import Game.LambdaHack.Client.CommonM
import Game.LambdaHack.Client.MonadClient
import Game.LambdaHack.Client.State
import Game.LambdaHack.Common.Actor
import Game.LambdaHack.Common.ActorState
import Game.LambdaHack.Common.Faction
import Game.LambdaHack.Common.Item
import Game.LambdaHack.Common.Kind
import Game.LambdaHack.Common.Level
import Game.LambdaHack.Common.MonadStateRead
import Game.LambdaHack.Common.Point
import qualified Game.LambdaHack.Common.PointArray as PointArray
import Game.LambdaHack.Common.State
import qualified Game.LambdaHack.Common.Tile as Tile
import Game.LambdaHack.Common.Time
import Game.LambdaHack.Common.Types
import Game.LambdaHack.Common.Vector
import qualified Game.LambdaHack.Content.CaveKind as CK
import Game.LambdaHack.Content.ModeKind
import Game.LambdaHack.Content.RuleKind
import Game.LambdaHack.Content.TileKind (isUknownSpace)
import Game.LambdaHack.Core.Frequency
import Game.LambdaHack.Core.Random
import qualified Game.LambdaHack.Definition.Ability as Ability
refreshTarget :: MonadClient m
=> [(ActorId, Actor)] -> [(ActorId, Actor)] -> (ActorId, Actor)
-> m (Maybe TgtAndPath)
refreshTarget :: [(ActorId, Actor)]
-> [(ActorId, Actor)] -> (ActorId, Actor) -> m (Maybe TgtAndPath)
refreshTarget foeAssocs :: [(ActorId, Actor)]
foeAssocs friendAssocs :: [(ActorId, Actor)]
friendAssocs (aid :: ActorId
aid, body :: Actor
body) = do
FactionId
side <- (StateClient -> FactionId) -> m FactionId
forall (m :: * -> *) a.
MonadClientRead m =>
(StateClient -> a) -> m a
getsClient StateClient -> FactionId
sside
let !_A :: ()
_A = Bool -> () -> ()
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Actor -> FactionId
bfid Actor
body FactionId -> FactionId -> Bool
forall a. Eq a => a -> a -> Bool
== FactionId
side
Bool -> (String, (ActorId, Actor, FactionId)) -> Bool
forall a. Show a => Bool -> a -> Bool
`blame` "AI tries to move an enemy actor"
String
-> (ActorId, Actor, FactionId)
-> (String, (ActorId, Actor, FactionId))
forall v. String -> v -> (String, v)
`swith` (ActorId
aid, Actor
body, FactionId
side)) ()
let !_A :: ()
_A = Bool -> () -> ()
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Bool -> Bool
not (Actor -> Bool
bproj Actor
body)
Bool -> (String, (ActorId, Actor, FactionId)) -> Bool
forall a. Show a => Bool -> a -> Bool
`blame` "AI gets to manually move its projectiles"
String
-> (ActorId, Actor, FactionId)
-> (String, (ActorId, Actor, FactionId))
forall v. String -> v -> (String, v)
`swith` (ActorId
aid, Actor
body, FactionId
side)) ()
Maybe TgtAndPath
mtarget <- [(ActorId, Actor)]
-> [(ActorId, Actor)] -> ActorId -> m (Maybe TgtAndPath)
forall (m :: * -> *).
MonadClient m =>
[(ActorId, Actor)]
-> [(ActorId, Actor)] -> ActorId -> m (Maybe TgtAndPath)
computeTarget [(ActorId, Actor)]
foeAssocs [(ActorId, Actor)]
friendAssocs ActorId
aid
case Maybe TgtAndPath
mtarget of
Nothing -> 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 {stargetD :: EnumMap ActorId TgtAndPath
stargetD = ActorId -> EnumMap ActorId TgtAndPath -> EnumMap ActorId TgtAndPath
forall k a. Enum k => k -> EnumMap k a -> EnumMap k a
EM.delete ActorId
aid (StateClient -> EnumMap ActorId TgtAndPath
stargetD StateClient
cli)}
Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe TgtAndPath
forall a. Maybe a
Nothing
Just tgtMPath :: TgtAndPath
tgtMPath -> 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 {stargetD :: EnumMap ActorId TgtAndPath
stargetD = ActorId
-> TgtAndPath
-> EnumMap ActorId TgtAndPath
-> EnumMap ActorId TgtAndPath
forall k a. Enum k => k -> a -> EnumMap k a -> EnumMap k a
EM.insert ActorId
aid TgtAndPath
tgtMPath (StateClient -> EnumMap ActorId TgtAndPath
stargetD StateClient
cli)}
Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe TgtAndPath
mtarget
computeTarget :: forall m. MonadClient m
=> [(ActorId, Actor)] -> [(ActorId, Actor)] -> ActorId
-> m (Maybe TgtAndPath)
computeTarget :: [(ActorId, Actor)]
-> [(ActorId, Actor)] -> ActorId -> m (Maybe TgtAndPath)
computeTarget foeAssocs :: [(ActorId, Actor)]
foeAssocs friendAssocs :: [(ActorId, Actor)]
friendAssocs aid :: ActorId
aid = do
cops :: COps
cops@COps{ContentData CaveKind
cocave :: COps -> ContentData CaveKind
cocave :: ContentData CaveKind
cocave, corule :: COps -> RuleContent
corule=RuleContent{X
rXmax :: RuleContent -> X
rXmax :: X
rXmax, X
rYmax :: RuleContent -> X
rYmax :: X
rYmax, X
rnearby :: RuleContent -> X
rnearby :: X
rnearby}, TileSpeedup
coTileSpeedup :: COps -> TileSpeedup
coTileSpeedup :: TileSpeedup
coTileSpeedup}
<- (State -> COps) -> m COps
forall (m :: * -> *) a. MonadStateRead m => (State -> a) -> m a
getsState State -> COps
scops
Actor
b <- (State -> Actor) -> m Actor
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
Maybe ActorId
mleader <- (StateClient -> Maybe ActorId) -> m (Maybe ActorId)
forall (m :: * -> *) a.
MonadClientRead m =>
(StateClient -> a) -> m a
getsClient StateClient -> Maybe ActorId
sleader
AlterLid
salter <- (StateClient -> AlterLid) -> m AlterLid
forall (m :: * -> *) a.
MonadClientRead m =>
(StateClient -> a) -> m a
getsClient StateClient -> AlterLid
salter
ActorMaxSkills
actorMaxSkills <- (State -> ActorMaxSkills) -> m ActorMaxSkills
forall (m :: * -> *) a. MonadStateRead m => (State -> a) -> m a
getsState State -> ActorMaxSkills
sactorMaxSkills
Bool
condInMelee <- LevelId -> m Bool
forall (m :: * -> *). MonadClient m => LevelId -> m Bool
condInMeleeM (LevelId -> m Bool) -> LevelId -> m Bool
forall a b. (a -> b) -> a -> b
$ Actor -> LevelId
blid Actor
b
let lalter :: Array Word8
lalter = AlterLid
salter AlterLid -> LevelId -> Array Word8
forall k a. Enum k => EnumMap k a -> k -> a
EM.! Actor -> LevelId
blid Actor
b
actorMaxSk :: Skills
actorMaxSk = ActorMaxSkills
actorMaxSkills ActorMaxSkills -> ActorId -> Skills
forall k a. Enum k => EnumMap k a -> k -> a
EM.! ActorId
aid
alterSkill :: X
alterSkill = Skill -> Skills -> X
Ability.getSk Skill
Ability.SkAlter Skills
actorMaxSk
Level
lvl <- LevelId -> m Level
forall (m :: * -> *). MonadStateRead m => LevelId -> m Level
getLevel (LevelId -> m Level) -> LevelId -> m Level
forall a b. (a -> b) -> a -> b
$ Actor -> LevelId
blid Actor
b
Time
localTime <- (State -> Time) -> m Time
forall (m :: * -> *) a. MonadStateRead m => (State -> a) -> m a
getsState ((State -> Time) -> m Time) -> (State -> Time) -> m Time
forall a b. (a -> b) -> a -> b
$ LevelId -> State -> Time
getLocalTime (Actor -> LevelId
blid Actor
b)
let stepAccesible :: [Point] -> Bool
stepAccesible :: [Point] -> Bool
stepAccesible (q :: Point
q : _) =
X
alterSkill X -> X -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8 -> X
forall a. Enum a => a -> X
fromEnum (Array Word8
lalter Array Word8 -> Point -> Word8
forall c. UnboxRepClass c => Array c -> Point -> c
PointArray.! Point
q)
stepAccesible [] = Bool
False
Maybe TgtAndPath
mtgtMPath <- (StateClient -> Maybe TgtAndPath) -> m (Maybe TgtAndPath)
forall (m :: * -> *) a.
MonadClientRead m =>
(StateClient -> a) -> m a
getsClient ((StateClient -> Maybe TgtAndPath) -> m (Maybe TgtAndPath))
-> (StateClient -> Maybe TgtAndPath) -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ ActorId -> EnumMap ActorId TgtAndPath -> Maybe TgtAndPath
forall k a. Enum k => k -> EnumMap k a -> Maybe a
EM.lookup ActorId
aid (EnumMap ActorId TgtAndPath -> Maybe TgtAndPath)
-> (StateClient -> EnumMap ActorId TgtAndPath)
-> StateClient
-> Maybe TgtAndPath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StateClient -> EnumMap ActorId TgtAndPath
stargetD
Maybe TgtAndPath
oldTgtUpdatedPath <- case Maybe TgtAndPath
mtgtMPath of
Just TgtAndPath{Target
tapTgt :: TgtAndPath -> Target
tapTgt :: Target
tapTgt,tapPath :: TgtAndPath -> Maybe AndPath
tapPath=Maybe AndPath
Nothing} ->
TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just (TgtAndPath -> Maybe TgtAndPath)
-> m TgtAndPath -> m (Maybe TgtAndPath)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ActorId -> Target -> m TgtAndPath
forall (m :: * -> *).
MonadClient m =>
ActorId -> Target -> m TgtAndPath
createPath ActorId
aid Target
tapTgt
Just tap :: TgtAndPath
tap@TgtAndPath{Target
tapTgt :: Target
tapTgt :: TgtAndPath -> Target
tapTgt,tapPath :: TgtAndPath -> Maybe AndPath
tapPath=Just AndPath{..}} -> do
Maybe Point
mvalidPos <- (State -> Maybe Point) -> m (Maybe Point)
forall (m :: * -> *) a. MonadStateRead m => (State -> a) -> m a
getsState ((State -> Maybe Point) -> m (Maybe Point))
-> (State -> Maybe Point) -> m (Maybe Point)
forall a b. (a -> b) -> a -> b
$ ActorId -> LevelId -> Maybe Target -> State -> Maybe Point
aidTgtToPos ActorId
aid (Actor -> LevelId
blid Actor
b) (Target -> Maybe Target
forall a. a -> Maybe a
Just Target
tapTgt)
Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$!
if | Maybe Point -> Bool
forall a. Maybe a -> Bool
isNothing Maybe Point
mvalidPos -> Maybe TgtAndPath
forall a. Maybe a
Nothing
| Actor -> Point
bpos Actor
b Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== Point
pathGoal ->
Maybe TgtAndPath
mtgtMPath
| Point
pathSource Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== Actor -> Point
bpos Actor
b ->
if [Point] -> Bool
stepAccesible [Point]
pathList then Maybe TgtAndPath
mtgtMPath else Maybe TgtAndPath
forall a. Maybe a
Nothing
| Bool
otherwise -> case (Point -> Bool) -> [Point] -> ([Point], [Point])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== Actor -> Point
bpos Actor
b) [Point]
pathList of
(crossed :: [Point]
crossed, _ : rest :: [Point]
rest) ->
if [Point] -> Bool
forall a. [a] -> Bool
null [Point]
rest
then Maybe TgtAndPath
forall a. Maybe a
Nothing
else let newPath :: AndPath
newPath =
$WAndPath :: Point -> [Point] -> Point -> X -> AndPath
AndPath{ pathSource :: Point
pathSource = Actor -> Point
bpos Actor
b
, pathList :: [Point]
pathList = [Point]
rest
, Point
pathGoal :: Point
pathGoal :: Point
pathGoal
, pathLen :: X
pathLen = X
pathLen X -> X -> X
forall a. Num a => a -> a -> a
- [Point] -> X
forall a. [a] -> X
length [Point]
crossed X -> X -> X
forall a. Num a => a -> a -> a
- 1 }
in if [Point] -> Bool
stepAccesible [Point]
rest
then TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just TgtAndPath
tap{tapPath :: Maybe AndPath
tapPath=AndPath -> Maybe AndPath
forall a. a -> Maybe a
Just AndPath
newPath}
else Maybe TgtAndPath
forall a. Maybe a
Nothing
(_, []) -> Maybe TgtAndPath
forall a. Maybe a
Nothing
Nothing -> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe TgtAndPath
forall a. Maybe a
Nothing
FactionDict
factionD <- (State -> FactionDict) -> m FactionDict
forall (m :: * -> *) a. MonadStateRead m => (State -> a) -> m a
getsState State -> FactionDict
sfactionD
X
seps <- (StateClient -> X) -> m X
forall (m :: * -> *) a.
MonadClientRead m =>
(StateClient -> a) -> m a
getsClient StateClient -> X
seps
let fact :: Faction
fact = FactionDict
factionD FactionDict -> FactionId -> Faction
forall k a. Enum k => EnumMap k a -> k -> a
EM.! Actor -> FactionId
bfid Actor
b
slackDoctrine :: Bool
slackDoctrine =
Player -> Doctrine
fdoctrine (Faction -> Player
gplayer Faction
fact)
Doctrine -> [Doctrine] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ Doctrine
Ability.TMeleeAndRanged, Doctrine
Ability.TMeleeAdjacent
, Doctrine
Ability.TBlock, Doctrine
Ability.TRoam, Doctrine
Ability.TPatrol ]
canMove :: Bool
canMove = Skill -> Skills -> X
Ability.getSk Skill
Ability.SkMove Skills
actorMaxSk X -> X -> Bool
forall a. Ord a => a -> a -> Bool
> 0
canReach :: Bool
canReach = Bool
canMove
Bool -> Bool -> Bool
|| Skill -> Skills -> X
Ability.getSk Skill
Ability.SkDisplace Skills
actorMaxSk X -> X -> Bool
forall a. Ord a => a -> a -> Bool
> 0
Bool -> Bool -> Bool
|| Skill -> Skills -> X
Ability.getSk Skill
Ability.SkProject Skills
actorMaxSk X -> X -> Bool
forall a. Ord a => a -> a -> Bool
> 0
canAlter :: Bool
canAlter = Skill -> Skills -> X
Ability.getSk Skill
Ability.SkAlter Skills
actorMaxSk
X -> X -> Bool
forall a. Ord a => a -> a -> Bool
>= if Bool
slackDoctrine then 2 else 4
canMoveItem :: Bool
canMoveItem = Skill -> Skills -> X
Ability.getSk Skill
Ability.SkMoveItem Skills
actorMaxSk X -> X -> Bool
forall a. Ord a => a -> a -> Bool
> 0
calmE :: Bool
calmE = Actor -> Skills -> Bool
calmEnough Actor
b Skills
actorMaxSk
heavilyDistressed :: Bool
heavilyDistressed =
ResDelta -> Bool
deltasSerious (Actor -> ResDelta
bcalmDelta Actor
b)
Skills
actorMinSk <- (State -> Skills) -> m Skills
forall (m :: * -> *) a. MonadStateRead m => (State -> a) -> m a
getsState ((State -> Skills) -> m Skills) -> (State -> Skills) -> m Skills
forall a b. (a -> b) -> a -> b
$ Maybe ActorId -> ActorId -> State -> Skills
actorCurrentSkills Maybe ActorId
forall a. Maybe a
Nothing ActorId
aid
Bool
condCanProject <-
X -> ActorId -> m Bool
forall (m :: * -> *). MonadClient m => X -> ActorId -> m Bool
condCanProjectM (Skill -> Skills -> X
Ability.getSk Skill
Ability.SkProject Skills
actorMaxSk) ActorId
aid
EnumMap ActorId (Point, Time)
fleeD <- (StateClient -> EnumMap ActorId (Point, Time))
-> m (EnumMap ActorId (Point, Time))
forall (m :: * -> *) a.
MonadClientRead m =>
(StateClient -> a) -> m a
getsClient StateClient -> EnumMap ActorId (Point, Time)
sfleeD
let condCanMelee :: Bool
condCanMelee = ActorMaxSkills -> ActorId -> Actor -> Bool
actorCanMelee ActorMaxSkills
actorMaxSkills ActorId
aid Actor
b
condHpTooLow :: Bool
condHpTooLow = Actor -> Skills -> Bool
hpTooLow Actor
b Skills
actorMaxSk
mfled :: Maybe (Point, Time)
mfled = ActorId
aid ActorId -> EnumMap ActorId (Point, Time) -> Maybe (Point, Time)
forall k a. Enum k => k -> EnumMap k a -> Maybe a
`EM.lookup` EnumMap ActorId (Point, Time)
fleeD
recentlyFled :: Bool
recentlyFled =
Bool -> ((Point, Time) -> Bool) -> Maybe (Point, Time) -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False (\(_, time :: Time
time) -> Time -> Time -> Bool
timeRecent5 Time
localTime Time
time) Maybe (Point, Time)
mfled
recentlyFled20 :: Bool
recentlyFled20 =
Bool -> ((Point, Time) -> Bool) -> Maybe (Point, Time) -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False (\(_, time :: Time
time) -> Time -> Time -> Bool
timeRecent5 Time
localTime Time
time) Maybe (Point, Time)
mfled
actorTurn :: Delta Time
actorTurn = Speed -> Delta Time
ticksPerMeter (Speed -> Delta Time) -> Speed -> Delta Time
forall a b. (a -> b) -> a -> b
$ Skills -> Speed
gearSpeed Skills
actorMaxSk
let canEscape :: Bool
canEscape = Player -> Bool
fcanEscape (Faction -> Player
gplayer Faction
fact)
canSmell :: Bool
canSmell = Skill -> Skills -> X
Ability.getSk Skill
Ability.SkSmell Skills
actorMaxSk X -> X -> Bool
forall a. Ord a => a -> a -> Bool
> 0
meleeNearby :: X
meleeNearby | Bool
canEscape = X
rnearby X -> X -> X
forall a. Integral a => a -> a -> a
`div` 2
| Bool
otherwise = X
rnearby
rangedNearby :: X
rangedNearby = 2 X -> X -> X
forall a. Num a => a -> a -> a
* X
meleeNearby
worthTargeting :: ActorId -> Actor -> Bool
worthTargeting aidE :: ActorId
aidE body :: Actor
body =
let attacksFriends :: Bool
attacksFriends =
((ActorId, Actor) -> Bool) -> [(ActorId, Actor)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Point -> Point -> Bool
adjacent (Actor -> Point
bpos Actor
body) (Point -> Bool)
-> ((ActorId, Actor) -> Point) -> (ActorId, Actor) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Actor -> Point
bpos (Actor -> Point)
-> ((ActorId, Actor) -> Actor) -> (ActorId, Actor) -> Point
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ActorId, Actor) -> Actor
forall a b. (a, b) -> b
snd) [(ActorId, Actor)]
friendAssocs
Bool -> Bool -> Bool
&& ActorMaxSkills -> ActorId -> Actor -> Bool
actorCanMeleeToHarm ActorMaxSkills
actorMaxSkills ActorId
aidE Actor
body
in Bool
attacksFriends
Bool -> Bool -> Bool
|| Actor -> X
bweapBenign Actor
body X -> X -> Bool
forall a. Ord a => a -> a -> Bool
> 0
Bool -> Bool -> Bool
|| ActorMaxSkills -> ActorId -> Actor -> Bool
actorWorthChasing ActorMaxSkills
actorMaxSkills ActorId
aidE Actor
body
targetableMelee :: Actor -> Bool
targetableMelee body :: Actor
body =
let attacksFriends :: Bool
attacksFriends =
((ActorId, Actor) -> Bool) -> [(ActorId, Actor)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Point -> Point -> Bool
adjacent (Actor -> Point
bpos Actor
body) (Point -> Bool)
-> ((ActorId, Actor) -> Point) -> (ActorId, Actor) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Actor -> Point
bpos (Actor -> Point)
-> ((ActorId, Actor) -> Actor) -> (ActorId, Actor) -> Point
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ActorId, Actor) -> Actor
forall a b. (a, b) -> b
snd) [(ActorId, Actor)]
friendAssocs
n :: X
n | Skill -> Skills -> X
Ability.getSk Skill
Ability.SkAggression Skills
actorMaxSk X -> X -> Bool
forall a. Ord a => a -> a -> Bool
>= 2
= X
rangedNearby
| Bool
condInMelee = if Bool
attacksFriends then 8 else 4
| Bool
otherwise = X
meleeNearby
in Bool
canMove
Bool -> Bool -> Bool
&& Bool
condCanMelee
Bool -> Bool -> Bool
&& Point -> Point -> X
chessDist (Actor -> Point
bpos Actor
body) (Actor -> Point
bpos Actor
b) X -> X -> Bool
forall a. Ord a => a -> a -> Bool
<= X
n
targetableRanged :: Actor -> Bool
targetableRanged body :: Actor
body =
(Bool -> Bool
not Bool
condInMelee Bool -> Bool -> Bool
|| Skill -> Skills -> X
Ability.getSk Skill
Ability.SkAggression Skills
actorMaxSk X -> X -> Bool
forall a. Ord a => a -> a -> Bool
>= 2)
Bool -> Bool -> Bool
&& Point -> Point -> X
chessDist (Actor -> Point
bpos Actor
body) (Actor -> Point
bpos Actor
b) X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< X
rangedNearby
Bool -> Bool -> Bool
&& Bool
condCanProject
Bool -> Bool -> Bool
&& (Bool
canMove Bool -> Bool -> Bool
|| Actor -> Bool
targetableLine Actor
body)
targetableLine :: Actor -> Bool
targetableLine body :: Actor
body = Maybe X -> Bool
forall a. Maybe a -> Bool
isJust (Maybe X -> Bool) -> Maybe X -> Bool
forall a b. (a -> b) -> a -> b
$ Bool -> Actor -> Point -> X -> COps -> Level -> Maybe X
makeLine Bool
False Actor
b (Actor -> Point
bpos Actor
body) X
seps COps
cops Level
lvl
targetableEnemy :: (ActorId, Actor) -> Bool
targetableEnemy (aidE :: ActorId
aidE, body :: Actor
body) = ActorId -> Actor -> Bool
worthTargeting ActorId
aidE Actor
body
Bool -> Bool -> Bool
&& (Point -> Point -> Bool
adjacent (Actor -> Point
bpos Actor
body) (Actor -> Point
bpos Actor
b)
Bool -> Bool -> Bool
|| Actor -> Bool
targetableMelee Actor
body
Bool -> Bool -> Bool
|| Actor -> Bool
targetableRanged Actor
body)
targetableFoes :: [(ActorId, Actor)]
targetableFoes = ((ActorId, Actor) -> Bool)
-> [(ActorId, Actor)] -> [(ActorId, Actor)]
forall a. (a -> Bool) -> [a] -> [a]
filter (ActorId, Actor) -> Bool
targetableEnemy [(ActorId, Actor)]
foeAssocs
canMeleeEnemy :: (ActorId, Actor) -> Bool
canMeleeEnemy (aidE :: ActorId
aidE, body :: Actor
body) = ActorMaxSkills -> ActorId -> Actor -> Bool
actorCanMeleeToHarm ActorMaxSkills
actorMaxSkills ActorId
aidE Actor
body
nearbyFoes :: [(ActorId, Actor)]
nearbyFoes = if Bool
recentlyFled Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
condInMelee
then ((ActorId, Actor) -> Bool)
-> [(ActorId, Actor)] -> [(ActorId, Actor)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> ((ActorId, Actor) -> Bool) -> (ActorId, Actor) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ActorId, Actor) -> Bool
canMeleeEnemy) [(ActorId, Actor)]
targetableFoes
else [(ActorId, Actor)]
targetableFoes
DiscoveryBenefit
discoBenefit <- (StateClient -> DiscoveryBenefit) -> m DiscoveryBenefit
forall (m :: * -> *) a.
MonadClientRead m =>
(StateClient -> a) -> m a
getsClient StateClient -> DiscoveryBenefit
sdiscoBenefit
ItemId -> ItemKind
getKind <- (State -> ItemId -> ItemKind) -> m (ItemId -> ItemKind)
forall (m :: * -> *) a. MonadStateRead m => (State -> a) -> m a
getsState ((State -> ItemId -> ItemKind) -> m (ItemId -> ItemKind))
-> (State -> ItemId -> ItemKind) -> m (ItemId -> ItemKind)
forall a b. (a -> b) -> a -> b
$ (ItemId -> State -> ItemKind) -> State -> ItemId -> ItemKind
forall a b c. (a -> b -> c) -> b -> a -> c
flip ItemId -> State -> ItemKind
getIidKind
ItemId -> AspectRecord
getArItem <- (State -> ItemId -> AspectRecord) -> m (ItemId -> AspectRecord)
forall (m :: * -> *) a. MonadStateRead m => (State -> a) -> m a
getsState ((State -> ItemId -> AspectRecord) -> m (ItemId -> AspectRecord))
-> (State -> ItemId -> AspectRecord) -> m (ItemId -> AspectRecord)
forall a b. (a -> b) -> a -> b
$ (ItemId -> State -> AspectRecord)
-> State -> ItemId -> AspectRecord
forall a b c. (a -> b -> c) -> b -> a -> c
flip ItemId -> State -> AspectRecord
aspectRecordFromIid
[(X, (FactionId, Point))]
cstashes <- if Bool
canMove
Bool -> Bool -> Bool
&& (Bool
calmE Bool -> Bool -> Bool
|| [(ActorId, Actor)] -> Bool
forall a. [a] -> Bool
null [(ActorId, Actor)]
nearbyFoes)
Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
heavilyDistressed
Bool -> Bool -> Bool
&& Faction -> Bool
isAIFact Faction
fact
then ActorId -> m [(X, (FactionId, Point))]
forall (m :: * -> *).
MonadClient m =>
ActorId -> m [(X, (FactionId, Point))]
closestStashes ActorId
aid
else [(X, (FactionId, Point))] -> m [(X, (FactionId, Point))]
forall (m :: * -> *) a. Monad m => a -> m a
return []
let desirableIid :: (ItemId, (X, ItemTimers)) -> Bool
desirableIid (iid :: ItemId
iid, (k :: X
k, _)) =
let Benefit{Double
benPickup :: Benefit -> Double
benPickup :: Double
benPickup} = DiscoveryBenefit
discoBenefit DiscoveryBenefit -> ItemId -> Benefit
forall k a. Enum k => EnumMap k a -> k -> a
EM.! ItemId
iid
in COps -> Bool -> Double -> AspectRecord -> ItemKind -> X -> Bool
desirableItem COps
cops Bool
canEscape Double
benPickup
(ItemId -> AspectRecord
getArItem ItemId
iid) (ItemId -> ItemKind
getKind ItemId
iid) X
k
desirableBagFloor :: EnumMap ItemId (X, ItemTimers) -> Bool
desirableBagFloor bag :: EnumMap ItemId (X, ItemTimers)
bag = ((ItemId, (X, ItemTimers)) -> Bool)
-> [(ItemId, (X, ItemTimers))] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (ItemId, (X, ItemTimers)) -> Bool
desirableIid ([(ItemId, (X, ItemTimers))] -> Bool)
-> [(ItemId, (X, ItemTimers))] -> Bool
forall a b. (a -> b) -> a -> b
$ EnumMap ItemId (X, ItemTimers) -> [(ItemId, (X, ItemTimers))]
forall k a. Enum k => EnumMap k a -> [(k, a)]
EM.assocs EnumMap ItemId (X, ItemTimers)
bag
desirableFloor :: (X, (Point, EnumMap ItemId (X, ItemTimers))) -> Bool
desirableFloor (_, (_, bag :: EnumMap ItemId (X, ItemTimers)
bag)) = EnumMap ItemId (X, ItemTimers) -> Bool
desirableBagFloor EnumMap ItemId (X, ItemTimers)
bag
focused :: Bool
focused = Skills -> Speed
gearSpeed Skills
actorMaxSk Speed -> Speed -> Bool
forall a. Ord a => a -> a -> Bool
< Speed
speedWalk Bool -> Bool -> Bool
|| Bool
condHpTooLow
couldMoveLastTurn :: Bool
couldMoveLastTurn =
let actorSk :: Skills
actorSk = 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 Skills
actorMaxSk else Skills
actorMinSk
in Skill -> Skills -> X
Ability.getSk Skill
Ability.SkMove Skills
actorSk X -> X -> Bool
forall a. Ord a => a -> a -> Bool
> 0
isStuck :: Bool
isStuck = Actor -> Bool
actorWaits Actor
b Bool -> Bool -> Bool
&& Bool
couldMoveLastTurn
setPath :: Target -> m (Maybe TgtAndPath)
setPath :: Target -> m (Maybe TgtAndPath)
setPath tgt :: Target
tgt = do
let take6 :: TgtAndPath -> TgtAndPath
take6 tap :: TgtAndPath
tap@TgtAndPath{tapTgt :: TgtAndPath -> Target
tapTgt=TEnemy{}} = TgtAndPath
tap
take6 TgtAndPath{tapPath :: TgtAndPath -> Maybe AndPath
tapPath=Just AndPath{..}} =
let path6 :: [Point]
path6 = X -> [Point] -> [Point]
forall a. X -> [a] -> [a]
take 6 [Point]
pathList
vOld :: Vector
vOld = if Actor -> Point
bpos Actor
b Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
/= Point
pathGoal
then Point -> Point -> Vector
towards (Actor -> Point
bpos Actor
b) Point
pathGoal
else X -> X -> Vector
Vector 0 0
tapTgt :: Target
tapTgt = Vector -> Target
TVector Vector
vOld
tapPath :: Maybe AndPath
tapPath = AndPath -> Maybe AndPath
forall a. a -> Maybe a
Just $WAndPath :: Point -> [Point] -> Point -> X -> AndPath
AndPath{pathList :: [Point]
pathList=[Point]
path6, ..}
in $WTgtAndPath :: Target -> Maybe AndPath -> TgtAndPath
TgtAndPath{..}
take6 tap :: TgtAndPath
tap = TgtAndPath
tap
TgtAndPath
tgtpath <- ActorId -> Target -> m TgtAndPath
forall (m :: * -> *).
MonadClient m =>
ActorId -> Target -> m TgtAndPath
createPath ActorId
aid Target
tgt
Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just (TgtAndPath -> Maybe TgtAndPath) -> TgtAndPath -> Maybe TgtAndPath
forall a b. (a -> b) -> a -> b
$ if Bool
slackDoctrine then TgtAndPath -> TgtAndPath
take6 TgtAndPath
tgtpath else TgtAndPath
tgtpath
pickNewTarget :: m (Maybe TgtAndPath)
pickNewTarget = Maybe ActorId -> m (Maybe TgtAndPath)
pickNewTargetIgnore Maybe ActorId
forall a. Maybe a
Nothing
pickNewTargetIgnore :: Maybe ActorId -> m (Maybe TgtAndPath)
pickNewTargetIgnore :: Maybe ActorId -> m (Maybe TgtAndPath)
pickNewTargetIgnore maidToIgnore :: Maybe ActorId
maidToIgnore =
case [(X, (FactionId, Point))]
cstashes of
(_, (fid2 :: FactionId
fid2, pos2 :: Point
pos2)) : _ -> Target -> m (Maybe TgtAndPath)
setPath (Target -> m (Maybe TgtAndPath)) -> Target -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TGoal -> LevelId -> Point -> Target
TPoint (FactionId -> TGoal
TStash FactionId
fid2) (Actor -> LevelId
blid Actor
b) Point
pos2
[] -> do
let f :: ActorId -> [(ActorId, Actor)]
f aidToIgnore :: ActorId
aidToIgnore = ((ActorId, Actor) -> Bool)
-> [(ActorId, Actor)] -> [(ActorId, Actor)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((ActorId -> ActorId -> Bool
forall a. Eq a => a -> a -> Bool
/= ActorId
aidToIgnore) (ActorId -> Bool)
-> ((ActorId, Actor) -> ActorId) -> (ActorId, Actor) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ActorId, Actor) -> ActorId
forall a b. (a, b) -> a
fst) [(ActorId, Actor)]
nearbyFoes
notIgnoredFoes :: [(ActorId, Actor)]
notIgnoredFoes = [(ActorId, Actor)]
-> (ActorId -> [(ActorId, Actor)])
-> Maybe ActorId
-> [(ActorId, Actor)]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [(ActorId, Actor)]
nearbyFoes ActorId -> [(ActorId, Actor)]
f Maybe ActorId
maidToIgnore
[(X, (ActorId, Actor))]
cfoes <- [(ActorId, Actor)] -> ActorId -> m [(X, (ActorId, Actor))]
forall (m :: * -> *).
MonadClient m =>
[(ActorId, Actor)] -> ActorId -> m [(X, (ActorId, Actor))]
closestFoes [(ActorId, Actor)]
notIgnoredFoes ActorId
aid
case [(X, (ActorId, Actor))]
cfoes of
(_, (aid2 :: ActorId
aid2, _)) : _ -> Target -> m (Maybe TgtAndPath)
setPath (Target -> m (Maybe TgtAndPath)) -> Target -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ ActorId -> Target
TEnemy ActorId
aid2
[] | Bool
condInMelee -> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe TgtAndPath
forall a. Maybe a
Nothing
[] -> do
Maybe (Point, X)
mhideout <- if Bool
recentlyFled20
then ActorId -> m (Maybe (Point, X))
forall (m :: * -> *).
MonadClient m =>
ActorId -> m (Maybe (Point, X))
closestHideout ActorId
aid
else Maybe (Point, X) -> m (Maybe (Point, X))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Point, X)
forall a. Maybe a
Nothing
case (Maybe (Point, X)
mhideout, Maybe (Point, Time)
mfled) of
(Just (p :: Point
p, dist :: X
dist), Just (_, time :: Time
time))
| Time -> Time -> Delta Time
timeDeltaToFrom Time
localTime Time
time
Delta Time -> Delta Time -> Bool
forall a. Ord a => a -> a -> Bool
<= Delta Time -> X -> Delta Time
timeDeltaScale Delta Time
actorTurn (20 X -> X -> X
forall a. Num a => a -> a -> a
- X
dist) ->
Target -> m (Maybe TgtAndPath)
setPath (Target -> m (Maybe TgtAndPath)) -> Target -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TGoal -> LevelId -> Point -> Target
TPoint TGoal
THideout (Actor -> LevelId
blid Actor
b) Point
p
_ -> do
[(X, (Point, EnumMap ItemId (X, ItemTimers)))]
citemsRaw <- if Bool
canMoveItem Bool -> Bool -> Bool
&& Bool
canMove
then ActorId -> m [(X, (Point, EnumMap ItemId (X, ItemTimers)))]
forall (m :: * -> *).
MonadClient m =>
ActorId -> m [(X, (Point, EnumMap ItemId (X, ItemTimers)))]
closestItems ActorId
aid
else [(X, (Point, EnumMap ItemId (X, ItemTimers)))]
-> m [(X, (Point, EnumMap ItemId (X, ItemTimers)))]
forall (m :: * -> *) a. Monad m => a -> m a
return []
let citems :: Frequency (Point, EnumMap ItemId (X, ItemTimers))
citems = Text
-> [(X, (Point, EnumMap ItemId (X, ItemTimers)))]
-> Frequency (Point, EnumMap ItemId (X, ItemTimers))
forall a. Text -> [(X, a)] -> Frequency a
toFreq "closestItems"
([(X, (Point, EnumMap ItemId (X, ItemTimers)))]
-> Frequency (Point, EnumMap ItemId (X, ItemTimers)))
-> [(X, (Point, EnumMap ItemId (X, ItemTimers)))]
-> Frequency (Point, EnumMap ItemId (X, ItemTimers))
forall a b. (a -> b) -> a -> b
$ ((X, (Point, EnumMap ItemId (X, ItemTimers))) -> Bool)
-> [(X, (Point, EnumMap ItemId (X, ItemTimers)))]
-> [(X, (Point, EnumMap ItemId (X, ItemTimers)))]
forall a. (a -> Bool) -> [a] -> [a]
filter (X, (Point, EnumMap ItemId (X, ItemTimers))) -> Bool
desirableFloor [(X, (Point, EnumMap ItemId (X, ItemTimers)))]
citemsRaw
if Frequency (Point, EnumMap ItemId (X, ItemTimers)) -> Bool
forall a. Frequency a -> Bool
nullFreq Frequency (Point, EnumMap ItemId (X, ItemTimers))
citems then do
[(X, (Point, Time))]
smpos <- if Bool
canSmell
then ActorId -> m [(X, (Point, Time))]
forall (m :: * -> *).
MonadClient m =>
ActorId -> m [(X, (Point, Time))]
closestSmell ActorId
aid
else [(X, (Point, Time))] -> m [(X, (Point, Time))]
forall (m :: * -> *) a. Monad m => a -> m a
return []
case [(X, (Point, Time))]
smpos of
[] -> do
[(X, (Point, (Point, EnumMap ItemId (X, ItemTimers))))]
ctriggersRaw <- FleeViaStairsOrEscape
-> ActorId
-> m [(X, (Point, (Point, EnumMap ItemId (X, ItemTimers))))]
forall (m :: * -> *).
MonadClient m =>
FleeViaStairsOrEscape
-> ActorId
-> m [(X, (Point, (Point, EnumMap ItemId (X, ItemTimers))))]
closestTriggers FleeViaStairsOrEscape
ViaAnything ActorId
aid
let ctriggers :: Frequency (Point, (Point, EnumMap ItemId (X, ItemTimers)))
ctriggers = Text
-> [(X, (Point, (Point, EnumMap ItemId (X, ItemTimers))))]
-> Frequency (Point, (Point, EnumMap ItemId (X, ItemTimers)))
forall a. Text -> [(X, a)] -> Frequency a
toFreq "ctriggers" [(X, (Point, (Point, EnumMap ItemId (X, ItemTimers))))]
ctriggersRaw
if Frequency (Point, (Point, EnumMap ItemId (X, ItemTimers))) -> Bool
forall a. Frequency a -> Bool
nullFreq Frequency (Point, (Point, EnumMap ItemId (X, ItemTimers)))
ctriggers then do
let oldpos :: Point
oldpos = Point -> Maybe Point -> Point
forall a. a -> Maybe a -> a
fromMaybe (Actor -> Point
bpos Actor
b) (Actor -> Maybe Point
boldpos Actor
b)
vOld :: Vector
vOld = Actor -> Point
bpos Actor
b Point -> Point -> Vector
`vectorToFrom` Point
oldpos
pNew :: Point
pNew = X -> X -> Point -> Vector -> Point
shiftBounded X
rXmax X
rYmax (Actor -> Point
bpos Actor
b) Vector
vOld
if Bool
slackDoctrine Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
isStuck Bool -> Bool -> Bool
&& Bool
calmE Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
focused
Bool -> Bool -> Bool
&& Vector -> Bool
isUnit Vector
vOld Bool -> Bool -> Bool
&& Actor -> Point
bpos Actor
b Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
/= Point
pNew
then do
let vFreq :: Frequency Vector
vFreq = Text -> [(X, Vector)] -> Frequency Vector
forall a. Text -> [(X, a)] -> Frequency a
toFreq "vFreq"
([(X, Vector)] -> Frequency Vector)
-> [(X, Vector)] -> Frequency Vector
forall a b. (a -> b) -> a -> b
$ (20, Vector
vOld) (X, Vector) -> [(X, Vector)] -> [(X, Vector)]
forall a. a -> [a] -> [a]
: (Vector -> (X, Vector)) -> [Vector] -> [(X, Vector)]
forall a b. (a -> b) -> [a] -> [b]
map (1,) [Vector]
moves
Vector
v <- Rnd Vector -> m Vector
forall (m :: * -> *) a. MonadClient m => Rnd a -> m a
rndToAction (Rnd Vector -> m Vector) -> Rnd Vector -> m Vector
forall a b. (a -> b) -> a -> b
$ Frequency Vector -> Rnd Vector
forall a. Show a => Frequency a -> Rnd a
frequency Frequency Vector
vFreq
let pathSource :: Point
pathSource = Actor -> Point
bpos Actor
b
traSlack7 :: [Point]
traSlack7 = X -> X -> Point -> [Vector] -> [Point]
trajectoryToPathBounded
X
rXmax X
rYmax Point
pathSource
(X -> Vector -> [Vector]
forall a. X -> a -> [a]
replicate 7 Vector
v)
pathList :: [Point]
pathList = ([Point] -> Point) -> [[Point]] -> [Point]
forall a b. (a -> b) -> [a] -> [b]
map [Point] -> Point
forall a. [a] -> a
head ([[Point]] -> [Point]) -> [[Point]] -> [Point]
forall a b. (a -> b) -> a -> b
$ [Point] -> [[Point]]
forall a. Eq a => [a] -> [[a]]
group [Point]
traSlack7
pathGoal :: Point
pathGoal = [Point] -> Point
forall a. [a] -> a
last [Point]
pathList
pathLen :: X
pathLen = [Point] -> X
forall a. [a] -> X
length [Point]
pathList
tapTgt :: Target
tapTgt = Vector -> Target
TVector Vector
v
tapPath :: Maybe AndPath
tapPath = AndPath -> Maybe AndPath
forall a. a -> Maybe a
Just $WAndPath :: Point -> [Point] -> Point -> X -> AndPath
AndPath{..}
Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just $WTgtAndPath :: Target -> Maybe AndPath -> TgtAndPath
TgtAndPath {..}
else do
Maybe Point
upos <- if Bool
canMove
then ActorId -> m (Maybe Point)
forall (m :: * -> *). MonadClient m => ActorId -> m (Maybe Point)
closestUnknown ActorId
aid
else Maybe Point -> m (Maybe Point)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Point
forall a. Maybe a
Nothing
case Maybe Point
upos of
Nothing -> do
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
canMove Bool -> Bool -> Bool
&& Bool
canAlter) (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 {sexplored :: EnumSet LevelId
sexplored =
LevelId -> EnumSet LevelId -> EnumSet LevelId
forall k. Enum k => k -> EnumSet k -> EnumSet k
ES.insert (Actor -> LevelId
blid Actor
b) (StateClient -> EnumSet LevelId
sexplored StateClient
cli)}
[(X, (Point, (Point, EnumMap ItemId (X, ItemTimers))))]
ctriggersRaw2 <- FleeViaStairsOrEscape
-> ActorId
-> m [(X, (Point, (Point, EnumMap ItemId (X, ItemTimers))))]
forall (m :: * -> *).
MonadClient m =>
FleeViaStairsOrEscape
-> ActorId
-> m [(X, (Point, (Point, EnumMap ItemId (X, ItemTimers))))]
closestTriggers FleeViaStairsOrEscape
ViaExit ActorId
aid
let ctriggers2 :: Frequency (Point, (Point, EnumMap ItemId (X, ItemTimers)))
ctriggers2 = Text
-> [(X, (Point, (Point, EnumMap ItemId (X, ItemTimers))))]
-> Frequency (Point, (Point, EnumMap ItemId (X, ItemTimers)))
forall a. Text -> [(X, a)] -> Frequency a
toFreq "ctriggers2" [(X, (Point, (Point, EnumMap ItemId (X, ItemTimers))))]
ctriggersRaw2
if Frequency (Point, (Point, EnumMap ItemId (X, ItemTimers))) -> Bool
forall a. Frequency a -> Bool
nullFreq Frequency (Point, (Point, EnumMap ItemId (X, ItemTimers)))
ctriggers2 then do
let toKill :: ActorId -> Actor -> Bool
toKill = ActorMaxSkills -> ActorId -> Actor -> Bool
actorWorthKilling ActorMaxSkills
actorMaxSkills
worthyFoes :: [(ActorId, Actor)]
worthyFoes = ((ActorId, Actor) -> Bool)
-> [(ActorId, Actor)] -> [(ActorId, Actor)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((ActorId -> Actor -> Bool) -> (ActorId, Actor) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ActorId -> Actor -> Bool
toKill)
[(ActorId, Actor)]
foeAssocs
[(X, (ActorId, Actor))]
afoes <- [(ActorId, Actor)] -> ActorId -> m [(X, (ActorId, Actor))]
forall (m :: * -> *).
MonadClient m =>
[(ActorId, Actor)] -> ActorId -> m [(X, (ActorId, Actor))]
closestFoes [(ActorId, Actor)]
worthyFoes ActorId
aid
case [(X, (ActorId, Actor))]
afoes of
(_, (aid2 :: ActorId
aid2, _)) : _ ->
Target -> m (Maybe TgtAndPath)
setPath (Target -> m (Maybe TgtAndPath)) -> Target -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ ActorId -> Target
TEnemy ActorId
aid2
[] -> do
Point
furthest <- ActorId -> m Point
forall (m :: * -> *). MonadClient m => ActorId -> m Point
furthestKnown ActorId
aid
Target -> m (Maybe TgtAndPath)
setPath (Target -> m (Maybe TgtAndPath)) -> Target -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TGoal -> LevelId -> Point -> Target
TPoint TGoal
TKnown (Actor -> LevelId
blid Actor
b) Point
furthest
else do
(p :: Point
p, (p0 :: Point
p0, bag :: EnumMap ItemId (X, ItemTimers)
bag)) <-
Rnd (Point, (Point, EnumMap ItemId (X, ItemTimers)))
-> m (Point, (Point, EnumMap ItemId (X, ItemTimers)))
forall (m :: * -> *) a. MonadClient m => Rnd a -> m a
rndToAction (Rnd (Point, (Point, EnumMap ItemId (X, ItemTimers)))
-> m (Point, (Point, EnumMap ItemId (X, ItemTimers))))
-> Rnd (Point, (Point, EnumMap ItemId (X, ItemTimers)))
-> m (Point, (Point, EnumMap ItemId (X, ItemTimers)))
forall a b. (a -> b) -> a -> b
$ Frequency (Point, (Point, EnumMap ItemId (X, ItemTimers)))
-> Rnd (Point, (Point, EnumMap ItemId (X, ItemTimers)))
forall a. Show a => Frequency a -> Rnd a
frequency Frequency (Point, (Point, EnumMap ItemId (X, ItemTimers)))
ctriggers2
Target -> m (Maybe TgtAndPath)
setPath (Target -> m (Maybe TgtAndPath)) -> Target -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TGoal -> LevelId -> Point -> Target
TPoint (EnumMap ItemId (X, ItemTimers) -> Point -> TGoal
TEmbed EnumMap ItemId (X, ItemTimers)
bag Point
p0) (Actor -> LevelId
blid Actor
b) Point
p
Just p :: Point
p -> Target -> m (Maybe TgtAndPath)
setPath (Target -> m (Maybe TgtAndPath)) -> Target -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TGoal -> LevelId -> Point -> Target
TPoint TGoal
TUnknown (Actor -> LevelId
blid Actor
b) Point
p
else do
(p :: Point
p, (p0 :: Point
p0, bag :: EnumMap ItemId (X, ItemTimers)
bag)) <- Rnd (Point, (Point, EnumMap ItemId (X, ItemTimers)))
-> m (Point, (Point, EnumMap ItemId (X, ItemTimers)))
forall (m :: * -> *) a. MonadClient m => Rnd a -> m a
rndToAction (Rnd (Point, (Point, EnumMap ItemId (X, ItemTimers)))
-> m (Point, (Point, EnumMap ItemId (X, ItemTimers))))
-> Rnd (Point, (Point, EnumMap ItemId (X, ItemTimers)))
-> m (Point, (Point, EnumMap ItemId (X, ItemTimers)))
forall a b. (a -> b) -> a -> b
$ Frequency (Point, (Point, EnumMap ItemId (X, ItemTimers)))
-> Rnd (Point, (Point, EnumMap ItemId (X, ItemTimers)))
forall a. Show a => Frequency a -> Rnd a
frequency Frequency (Point, (Point, EnumMap ItemId (X, ItemTimers)))
ctriggers
Target -> m (Maybe TgtAndPath)
setPath (Target -> m (Maybe TgtAndPath)) -> Target -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TGoal -> LevelId -> Point -> Target
TPoint (EnumMap ItemId (X, ItemTimers) -> Point -> TGoal
TEmbed EnumMap ItemId (X, ItemTimers)
bag Point
p0) (Actor -> LevelId
blid Actor
b) Point
p
(_, (p :: Point
p, _)) : _ -> Target -> m (Maybe TgtAndPath)
setPath (Target -> m (Maybe TgtAndPath)) -> Target -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TGoal -> LevelId -> Point -> Target
TPoint TGoal
TSmell (Actor -> LevelId
blid Actor
b) Point
p
else do
(p :: Point
p, bag :: EnumMap ItemId (X, ItemTimers)
bag) <- Rnd (Point, EnumMap ItemId (X, ItemTimers))
-> m (Point, EnumMap ItemId (X, ItemTimers))
forall (m :: * -> *) a. MonadClient m => Rnd a -> m a
rndToAction (Rnd (Point, EnumMap ItemId (X, ItemTimers))
-> m (Point, EnumMap ItemId (X, ItemTimers)))
-> Rnd (Point, EnumMap ItemId (X, ItemTimers))
-> m (Point, EnumMap ItemId (X, ItemTimers))
forall a b. (a -> b) -> a -> b
$ Frequency (Point, EnumMap ItemId (X, ItemTimers))
-> Rnd (Point, EnumMap ItemId (X, ItemTimers))
forall a. Show a => Frequency a -> Rnd a
frequency Frequency (Point, EnumMap ItemId (X, ItemTimers))
citems
Target -> m (Maybe TgtAndPath)
setPath (Target -> m (Maybe TgtAndPath)) -> Target -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TGoal -> LevelId -> Point -> Target
TPoint (EnumMap ItemId (X, ItemTimers) -> TGoal
TItem EnumMap ItemId (X, ItemTimers)
bag) (Actor -> LevelId
blid Actor
b) Point
p
tellOthersNothingHere :: m (Maybe TgtAndPath)
tellOthersNothingHere = do
let f :: TgtAndPath -> Bool
f TgtAndPath{Target
tapTgt :: Target
tapTgt :: TgtAndPath -> Target
tapTgt} = case Target
tapTgt of
TPoint _ lid :: LevelId
lid p :: Point
p -> Point
p Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
/= Actor -> Point
bpos Actor
b Bool -> Bool -> Bool
|| LevelId
lid LevelId -> LevelId -> Bool
forall a. Eq a => a -> a -> Bool
/= Actor -> LevelId
blid Actor
b
_ -> Bool
True
(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 {stargetD :: EnumMap ActorId TgtAndPath
stargetD = (TgtAndPath -> Bool)
-> EnumMap ActorId TgtAndPath -> EnumMap ActorId TgtAndPath
forall a k. (a -> Bool) -> EnumMap k a -> EnumMap k a
EM.filter TgtAndPath -> Bool
f (StateClient -> EnumMap ActorId TgtAndPath
stargetD StateClient
cli)}
m (Maybe TgtAndPath)
pickNewTarget
updateTgt :: TgtAndPath -> m (Maybe TgtAndPath)
updateTgt :: TgtAndPath -> m (Maybe TgtAndPath)
updateTgt TgtAndPath{tapPath :: TgtAndPath -> Maybe AndPath
tapPath=Maybe AndPath
Nothing} = m (Maybe TgtAndPath)
pickNewTarget
updateTgt tap :: TgtAndPath
tap@TgtAndPath{tapPath :: TgtAndPath -> Maybe AndPath
tapPath=Just AndPath{..},Target
tapTgt :: Target
tapTgt :: TgtAndPath -> Target
tapTgt} = case Target
tapTgt of
TEnemy a :: ActorId
a -> do
Actor
body <- (State -> Actor) -> m Actor
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
a
if | (Bool
condInMelee
Bool -> Bool -> Bool
|| Actor -> X
bweapon Actor
body X -> X -> Bool
forall a. Ord a => a -> a -> Bool
<= 0
Bool -> Bool -> Bool
|| Bool -> Bool
not Bool
focused Bool -> Bool -> Bool
&& Bool -> Bool
not ([(ActorId, Actor)] -> Bool
forall a. [a] -> Bool
null [(ActorId, Actor)]
nearbyFoes))
Bool -> Bool -> Bool
&& ActorId
a ActorId -> [ActorId] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` ((ActorId, Actor) -> ActorId) -> [(ActorId, Actor)] -> [ActorId]
forall a b. (a -> b) -> [a] -> [b]
map (ActorId, Actor) -> ActorId
forall a b. (a, b) -> a
fst [(ActorId, Actor)]
nearbyFoes
Bool -> Bool -> Bool
|| Actor -> LevelId
blid Actor
body LevelId -> LevelId -> Bool
forall a. Eq a => a -> a -> Bool
/= Actor -> LevelId
blid Actor
b
Bool -> Bool -> Bool
|| Actor -> Bool
actorDying Actor
body
Bool -> Bool -> Bool
|| Bool -> Bool
not (ActorId -> Actor -> Bool
worthTargeting ActorId
a Actor
body)
Bool -> Bool -> Bool
|| Bool
recentlyFled ->
m (Maybe TgtAndPath)
pickNewTarget
| Bool
otherwise -> do
Maybe AndPath
mpath <- ActorId -> Point -> m (Maybe AndPath)
forall (m :: * -> *).
MonadClient m =>
ActorId -> Point -> m (Maybe AndPath)
getCachePath ActorId
aid (Point -> m (Maybe AndPath)) -> Point -> m (Maybe AndPath)
forall a b. (a -> b) -> a -> b
$ Actor -> Point
bpos Actor
body
case Maybe AndPath
mpath of
Nothing -> Maybe ActorId -> m (Maybe TgtAndPath)
pickNewTargetIgnore (ActorId -> Maybe ActorId
forall a. a -> Maybe a
Just ActorId
a)
Just AndPath{pathList :: AndPath -> [Point]
pathList=[]} -> m (Maybe TgtAndPath)
pickNewTarget
Just AndPath{pathList :: AndPath -> [Point]
pathList= q :: Point
q : _} ->
if Bool -> Bool
not Bool
condInMelee
Bool -> Bool -> Bool
|| Point
q Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== Actor -> Point
bpos Actor
body
Bool -> Bool -> Bool
|| Bool -> Bool
not (Point -> Level -> Bool
occupiedBigLvl Point
q Level
lvl)
Bool -> Bool -> Bool
&& Bool -> Bool
not (Point -> Level -> Bool
occupiedProjLvl Point
q Level
lvl)
then Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just TgtAndPath
tap{tapPath :: Maybe AndPath
tapPath=Maybe AndPath
mpath}
else Maybe ActorId -> m (Maybe TgtAndPath)
pickNewTargetIgnore (ActorId -> Maybe ActorId
forall a. a -> Maybe a
Just ActorId
a)
TPoint _ lid :: LevelId
lid _ | LevelId
lid LevelId -> LevelId -> Bool
forall a. Eq a => a -> a -> Bool
/= Actor -> LevelId
blid Actor
b -> m (Maybe TgtAndPath)
pickNewTarget
TPoint tgoal :: TGoal
tgoal lid :: LevelId
lid pos :: Point
pos -> case TGoal
tgoal of
TStash fid2 :: FactionId
fid2 -> do
[(ActorId, Actor)]
oursExploring <- (State -> [(ActorId, Actor)]) -> m [(ActorId, Actor)]
forall (m :: * -> *) a. MonadStateRead m => (State -> a) -> m a
getsState ((State -> [(ActorId, Actor)]) -> m [(ActorId, Actor)])
-> (State -> [(ActorId, Actor)]) -> m [(ActorId, Actor)]
forall a b. (a -> b) -> a -> b
$ FactionId -> State -> [(ActorId, Actor)]
oursExploringAssocs (Actor -> FactionId
bfid Actor
b)
let oursExploringLid :: [(ActorId, Actor)]
oursExploringLid =
((ActorId, Actor) -> Bool)
-> [(ActorId, Actor)] -> [(ActorId, Actor)]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(_, body :: Actor
body) -> Actor -> LevelId
blid Actor
body LevelId -> LevelId -> Bool
forall a. Eq a => a -> a -> Bool
== LevelId
lid) [(ActorId, Actor)]
oursExploring
spawnFreqs :: Freqs ItemKind
spawnFreqs = CaveKind -> Freqs ItemKind
CK.cactorFreq (CaveKind -> Freqs ItemKind) -> CaveKind -> Freqs ItemKind
forall a b. (a -> b) -> a -> b
$ ContentData CaveKind -> ContentId CaveKind -> CaveKind
forall a. ContentData a -> ContentId a -> a
okind ContentData CaveKind
cocave (ContentId CaveKind -> CaveKind) -> ContentId CaveKind -> CaveKind
forall a b. (a -> b) -> a -> b
$ Level -> ContentId CaveKind
lkind Level
lvl
hasGroup :: GroupName ItemKind -> Bool
hasGroup grp :: GroupName ItemKind
grp = X -> Maybe X -> X
forall a. a -> Maybe a -> a
fromMaybe 0 (GroupName ItemKind -> Freqs ItemKind -> Maybe X
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup GroupName ItemKind
grp Freqs ItemKind
spawnFreqs) X -> X -> Bool
forall a. Ord a => a -> a -> Bool
> 0
lvlSpawnsUs :: Bool
lvlSpawnsUs = (GroupName ItemKind -> Bool) -> [GroupName ItemKind] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any GroupName ItemKind -> Bool
hasGroup ([GroupName ItemKind] -> Bool) -> [GroupName ItemKind] -> Bool
forall a b. (a -> b) -> a -> b
$ Player -> [GroupName ItemKind]
fgroups (Faction -> Player
gplayer Faction
fact)
if (Bool
calmE Bool -> Bool -> Bool
|| [(ActorId, Actor)] -> Bool
forall a. [a] -> Bool
null [(ActorId, Actor)]
nearbyFoes)
Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
heavilyDistressed
Bool -> Bool -> Bool
&& Faction -> Maybe (LevelId, Point)
gstash (FactionDict
factionD FactionDict -> FactionId -> Faction
forall k a. Enum k => EnumMap k a -> k -> a
EM.! FactionId
fid2) Maybe (LevelId, Point) -> Maybe (LevelId, Point) -> Bool
forall a. Eq a => a -> a -> Bool
== (LevelId, Point) -> Maybe (LevelId, Point)
forall a. a -> Maybe a
Just (LevelId
lid, Point
pos)
Bool -> Bool -> Bool
&& (FactionId
fid2 FactionId -> FactionId -> Bool
forall a. Eq a => a -> a -> Bool
== Actor -> FactionId
bfid Actor
b
Bool -> Bool -> Bool
&& (Point
pos Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== Actor -> Point
bpos Actor
b
Bool -> Bool -> Bool
&& ([(ActorId, Actor)] -> Bool
forall a. [a] -> Bool
null [(ActorId, Actor)]
nearbyFoes
Bool -> Bool -> Bool
|| [(ActorId, Actor)] -> X
forall a. [a] -> X
length [(ActorId, Actor)]
oursExploringLid X -> X -> Bool
forall a. Ord a => a -> a -> Bool
> 1)
Bool -> Bool -> Bool
|| Maybe ActorId -> Bool
forall a. Maybe a -> Bool
isNothing (Point -> Level -> Maybe ActorId
posToBigLvl Point
pos Level
lvl))
Bool -> Bool -> Bool
&& ([(ActorId, Actor)] -> X
forall a. [a] -> X
length [(ActorId, Actor)]
oursExploring X -> X -> Bool
forall a. Ord a => a -> a -> Bool
> 1
Bool -> Bool -> Bool
|| Bool
lvlSpawnsUs)
Bool -> Bool -> Bool
|| FactionId -> Faction -> FactionId -> Bool
isFoe (Actor -> FactionId
bfid Actor
b) Faction
fact FactionId
fid2)
then Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just TgtAndPath
tap
else m (Maybe TgtAndPath)
pickNewTarget
_ | Bool
condInMelee Bool -> Bool -> Bool
|| Bool -> Bool
not ([(X, (FactionId, Point))] -> Bool
forall a. [a] -> Bool
null [(X, (FactionId, Point))]
cstashes) -> m (Maybe TgtAndPath)
pickNewTarget
TEnemyPos _
| Actor -> Point
bpos Actor
b Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== Point
pos -> m (Maybe TgtAndPath)
tellOthersNothingHere
| Bool
recentlyFled -> m (Maybe TgtAndPath)
pickNewTarget
| Bool
otherwise -> do
let remainingDist :: X
remainingDist = Point -> Point -> X
chessDist (Actor -> Point
bpos Actor
b) Point
pos
if ((ActorId, Actor) -> Bool) -> [(ActorId, Actor)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\(_, b3 :: Actor
b3) -> Point -> Point -> X
chessDist (Actor -> Point
bpos Actor
b) (Actor -> Point
bpos Actor
b3) X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< X
remainingDist)
[(ActorId, Actor)]
nearbyFoes
then m (Maybe TgtAndPath)
pickNewTarget
else Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just TgtAndPath
tap
THideout ->
if Bool -> Bool
not Bool
recentlyFled20
then m (Maybe TgtAndPath)
pickNewTarget
else Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just TgtAndPath
tap
_ | Bool -> Bool
not ([(ActorId, Actor)] -> Bool
forall a. [a] -> Bool
null [(ActorId, Actor)]
nearbyFoes) -> m (Maybe TgtAndPath)
pickNewTarget
TEmbed bag :: EnumMap ItemId (X, ItemTimers)
bag p :: Point
p -> Bool -> m (Maybe TgtAndPath) -> m (Maybe TgtAndPath)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Point -> Point -> Bool
adjacent Point
pos Point
p) (m (Maybe TgtAndPath) -> m (Maybe TgtAndPath))
-> m (Maybe TgtAndPath) -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ do
EnumMap ItemId (X, ItemTimers)
bag2 <- (State -> EnumMap ItemId (X, ItemTimers))
-> m (EnumMap ItemId (X, ItemTimers))
forall (m :: * -> *) a. MonadStateRead m => (State -> a) -> m a
getsState ((State -> EnumMap ItemId (X, ItemTimers))
-> m (EnumMap ItemId (X, ItemTimers)))
-> (State -> EnumMap ItemId (X, ItemTimers))
-> m (EnumMap ItemId (X, ItemTimers))
forall a b. (a -> b) -> a -> b
$ LevelId -> Point -> State -> EnumMap ItemId (X, ItemTimers)
getEmbedBag LevelId
lid Point
p
if | EnumMap ItemId (X, ItemTimers)
bag EnumMap ItemId (X, ItemTimers)
-> EnumMap ItemId (X, ItemTimers) -> Bool
forall a. Eq a => a -> a -> Bool
/= EnumMap ItemId (X, ItemTimers)
bag2 -> m (Maybe TgtAndPath)
pickNewTarget
| Point -> Point -> Bool
adjacent (Actor -> Point
bpos Actor
b) Point
p ->
Target -> m (Maybe TgtAndPath)
setPath (Target -> m (Maybe TgtAndPath)) -> Target -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TGoal -> LevelId -> Point -> Target
TPoint TGoal
TKnown LevelId
lid (Actor -> Point
bpos Actor
b)
| Bool
otherwise -> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just TgtAndPath
tap
TItem bag :: EnumMap ItemId (X, ItemTimers)
bag -> do
EnumMap ItemId (X, ItemTimers)
bag2 <- (State -> EnumMap ItemId (X, ItemTimers))
-> m (EnumMap ItemId (X, ItemTimers))
forall (m :: * -> *) a. MonadStateRead m => (State -> a) -> m a
getsState ((State -> EnumMap ItemId (X, ItemTimers))
-> m (EnumMap ItemId (X, ItemTimers)))
-> (State -> EnumMap ItemId (X, ItemTimers))
-> m (EnumMap ItemId (X, ItemTimers))
forall a b. (a -> b) -> a -> b
$ LevelId -> Point -> State -> EnumMap ItemId (X, ItemTimers)
getFloorBag LevelId
lid Point
pos
if | EnumMap ItemId (X, ItemTimers)
bag EnumMap ItemId (X, ItemTimers)
-> EnumMap ItemId (X, ItemTimers) -> Bool
forall a. Eq a => a -> a -> Bool
/= EnumMap ItemId (X, ItemTimers)
bag2 -> m (Maybe TgtAndPath)
pickNewTarget
| Actor -> Point
bpos Actor
b Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== Point
pos ->
Target -> m (Maybe TgtAndPath)
setPath (Target -> m (Maybe TgtAndPath)) -> Target -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TGoal -> LevelId -> Point -> Target
TPoint TGoal
TKnown LevelId
lid (Actor -> Point
bpos Actor
b)
| Bool
otherwise -> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just TgtAndPath
tap
TSmell ->
if Bool -> Bool
not Bool
canSmell
Bool -> Bool -> Bool
|| let sml :: Time
sml = Time -> Point -> EnumMap Point Time -> Time
forall k a. Enum k => a -> k -> EnumMap k a -> a
EM.findWithDefault Time
timeZero Point
pos (Level -> EnumMap Point Time
lsmell Level
lvl)
in Time
sml Time -> Time -> Bool
forall a. Ord a => a -> a -> Bool
<= Level -> Time
ltime Level
lvl
then m (Maybe TgtAndPath)
pickNewTarget
else Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just TgtAndPath
tap
TBlock -> do
let t :: ContentId TileKind
t = Level
lvl Level -> Point -> ContentId TileKind
`at` Point
pos
if Bool
isStuck
Bool -> Bool -> Bool
|| X
alterSkill X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< Word8 -> X
forall a. Enum a => a -> X
fromEnum (Array Word8
lalter Array Word8 -> Point -> Word8
forall c. UnboxRepClass c => Array c -> Point -> c
PointArray.! Point
pos)
Bool -> Bool -> Bool
|| TileSpeedup -> ContentId TileKind -> Bool
Tile.isWalkable TileSpeedup
coTileSpeedup ContentId TileKind
t
then m (Maybe TgtAndPath)
pickNewTarget
else Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just TgtAndPath
tap
TUnknown ->
let t :: ContentId TileKind
t = Level
lvl Level -> Point -> ContentId TileKind
`at` Point
pos
in if Level -> X
lexpl Level
lvl X -> X -> Bool
forall a. Ord a => a -> a -> Bool
<= Level -> X
lseen Level
lvl
Bool -> Bool -> Bool
|| Bool -> Bool
not (ContentId TileKind -> Bool
isUknownSpace ContentId TileKind
t)
then m (Maybe TgtAndPath)
pickNewTarget
else Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just TgtAndPath
tap
TKnown ->
if Actor -> Point
bpos Actor
b Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
== Point
pos
Bool -> Bool -> Bool
|| Bool
isStuck
Bool -> Bool -> Bool
|| X
alterSkill X -> X -> Bool
forall a. Ord a => a -> a -> Bool
< Word8 -> X
forall a. Enum a => a -> X
fromEnum (Array Word8
lalter Array Word8 -> Point -> Word8
forall c. UnboxRepClass c => Array c -> Point -> c
PointArray.! Point
pos)
then m (Maybe TgtAndPath)
pickNewTarget
else Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just TgtAndPath
tap
_ | Bool
condInMelee Bool -> Bool -> Bool
|| Bool -> Bool
not ([(ActorId, Actor)] -> Bool
forall a. [a] -> Bool
null [(ActorId, Actor)]
nearbyFoes Bool -> Bool -> Bool
&& [(X, (FactionId, Point))] -> Bool
forall a. [a] -> Bool
null [(X, (FactionId, Point))]
cstashes) ->
m (Maybe TgtAndPath)
pickNewTarget
TNonEnemy _ | 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 ->
m (Maybe TgtAndPath)
pickNewTarget
TNonEnemy a :: ActorId
a -> do
Actor
body <- (State -> Actor) -> m Actor
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
a
if Actor -> LevelId
blid Actor
body LevelId -> LevelId -> Bool
forall a. Eq a => a -> a -> Bool
/= Actor -> LevelId
blid Actor
b
then m (Maybe TgtAndPath)
pickNewTarget
else do
Maybe AndPath
mpath <- ActorId -> Point -> m (Maybe AndPath)
forall (m :: * -> *).
MonadClient m =>
ActorId -> Point -> m (Maybe AndPath)
getCachePath ActorId
aid (Point -> m (Maybe AndPath)) -> Point -> m (Maybe AndPath)
forall a b. (a -> b) -> a -> b
$ Actor -> Point
bpos Actor
body
case Maybe AndPath
mpath of
Nothing -> m (Maybe TgtAndPath)
pickNewTarget
Just AndPath{pathList :: AndPath -> [Point]
pathList=[]} -> m (Maybe TgtAndPath)
pickNewTarget
_ -> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just TgtAndPath
tap{tapPath :: Maybe AndPath
tapPath=Maybe AndPath
mpath}
TVector{} -> if Actor -> Point
bpos Actor
b Point -> Point -> Bool
forall a. Eq a => a -> a -> Bool
/= Point
pathGoal
then Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall a b. (a -> b) -> a -> b
$ TgtAndPath -> Maybe TgtAndPath
forall a. a -> Maybe a
Just TgtAndPath
tap
else m (Maybe TgtAndPath)
pickNewTarget
if Bool
canReach
then m (Maybe TgtAndPath)
-> (TgtAndPath -> m (Maybe TgtAndPath))
-> Maybe TgtAndPath
-> m (Maybe TgtAndPath)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe m (Maybe TgtAndPath)
pickNewTarget TgtAndPath -> m (Maybe TgtAndPath)
updateTgt Maybe TgtAndPath
oldTgtUpdatedPath
else Maybe TgtAndPath -> m (Maybe TgtAndPath)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe TgtAndPath
forall a. Maybe a
Nothing