Permalink
Browse files

add per-hero perception; unused

  • Loading branch information...
1 parent ff6b65d commit 41800b48528dac1d5c29d6ff8ae331dec590b75b @Mikolaj Mikolaj committed Mar 21, 2011
Showing with 42 additions and 29 deletions.
  1. +2 −2 src/Action.hs
  2. +9 −9 src/Actions.hs
  3. +3 −3 src/Display2.hs
  4. +3 −4 src/MovableState.hs
  5. +23 −9 src/Perception.hs
  6. +2 −2 src/StrategyState.hs
View
@@ -18,7 +18,7 @@ newtype Action a = Action
forall r .
Session ->
IO r -> -- shutdown cont
- Perception -> -- cached perception
+ Perceptions -> -- cached perception
(State -> Message -> a -> IO r) -> -- continuation
IO r -> -- failure/reset cont
State -> -- current state
@@ -221,7 +221,7 @@ withPerception h = Action (\ s e _ k a st ms ->
runAction h s e (perception_ st) k a st ms)
-- | Get the current perception.
-currentPerception :: Action Perception
+currentPerception :: Action Perceptions
currentPerception = Action (\ s e p k a st ms -> k st ms p)
-- | If in targeting mode, check if the current level is the same
View
@@ -162,7 +162,7 @@ continueRun dir =
let lvl@(Level { lmap = lmap, lheroes = hs }) = slevel state
mslocs = S.fromList (L.map mloc (levelMonsterList state))
t = lmap `at` loc -- tile at current location
- monstersVisible = not (S.null (mslocs `S.intersection` pvisible per))
+ monstersVisible = not (S.null (mslocs `S.intersection` ptvisible per))
newsReported = not (L.null msg)
itemsHere = not (L.null (titems t))
heroThere = L.elem (loc `shift` dir) (L.map mloc (IM.elems hs))
@@ -225,7 +225,7 @@ remember :: Action ()
remember =
do
per <- currentPerception
- let vis = S.toList (pvisible per)
+ let vis = S.toList (ptvisible per)
let rememberLoc = M.update (\ (t,_) -> Just (t,t))
modify (updateLevel (updateLMap (\ lmap -> foldr rememberLoc lmap vis)))
@@ -536,7 +536,7 @@ targetMonster = do
_ -> -1 -- try to target first monster (e.g., number 0)
(lt, gt) = IM.split i ms
gtlt = IM.assocs gt ++ IM.assocs lt
- lf = L.filter (\ (_, m) -> S.member (mloc m) (pvisible per)) gtlt
+ lf = L.filter (\ (_, m) -> S.member (mloc m) (ptvisible per)) gtlt
tgt = case lf of
[] -> target -- no monsters in sight, stick to last target
(ni, _) : _ -> TEnemy (AMonster ni) -- pick the next monster
@@ -551,7 +551,7 @@ setCursor tgt = do
ploc <- gets (mloc . getPlayerBody)
ln <- gets (lname . slevel)
let upd cursor =
- let cloc = case targetToLoc state per of
+ let cloc = case targetToLoc state (ptvisible per) of
Nothing -> ploc
Just l -> l
in cursor { ctargeting = True, clocation = cloc, clocLn = ln }
@@ -569,7 +569,7 @@ doLook =
per <- currentPerception
target <- gets (mtarget . getPlayerBody)
let monsterMsg =
- if S.member loc (pvisible per)
+ if S.member loc (ptvisible per)
then case L.find (\ m -> mloc m == loc) (levelMonsterList state) of
Just m -> subjectMovable (mtype m) ++ " is here. "
Nothing -> ""
@@ -650,7 +650,7 @@ fireItem = do
Just (dart, _) -> do
let fired = dart { icount = 1 }
removeFromInventory fired
- case targetToLoc state per of
+ case targetToLoc state (ptvisible per) of
Nothing -> abortWith "target invalid"
Just loc ->
case locToActor state loc of
@@ -667,7 +667,7 @@ applyItem = do
case findItem (\ i -> itype i == Wand) pitems of
Just (wand, _) -> do
let applied = wand { icount = 1 }
- case targetToLoc state per of
+ case targetToLoc state (ptvisible per) of
Nothing -> abortWith "target invalid"
Just loc ->
case locToActor state loc of
@@ -735,7 +735,7 @@ actorPickupItem actor =
let movable = getActor state actor
let loc = mloc movable
let t = lmap `at` loc -- the map tile in question
- let perceived = loc `S.member` pvisible per
+ let perceived = loc `S.member` ptvisible per
let isPlayer = actor == pl
-- check if something is here to pick up
case titems t of
@@ -913,7 +913,7 @@ actorDamageActor source target damage weaponMsg =
combatMsg = subjectVerbMObject state sm combatVerb tm weaponMsg
updateAnyActor target $ \ m -> m { mhp = newHp }
per <- currentPerception
- let perceived = mloc sm `S.member` pvisible per
+ let perceived = mloc sm `S.member` ptvisible per
messageAdd $
if perceived
then combatMsg
View
@@ -143,7 +143,7 @@ stringByLocation sy xs =
in
(k, \ (y,x) -> M.lookup y m >>= \ n -> M.lookup x n)
-displayLevel :: Session -> Perception -> State -> Message -> Maybe String -> IO Bool
+displayLevel :: Session -> Perceptions -> State -> Message -> Maybe String -> IO Bool
displayLevel session per
(state@(State { splayer = pl,
stime = time,
@@ -154,8 +154,8 @@ displayLevel session per
mloc = ploc, mitems = pitems } =
getPlayerBody state
overlay = maybe "" id moverlay
- reachable = preachable per
- visible = pvisible per
+ reachable = ptreachable per
+ visible = ptvisible per
sSml = ssensory state == Smell
sVis = case ssensory state of Vision _ -> True; _ -> False
sOmn = sdisplay state == Omniscient
View
@@ -11,7 +11,6 @@ import Geometry
import Movable
import Level
import State
-import Perception
-- The operations with "Any", and those that use them, consider all the dungeon.
-- All the other actor and level operations only consider the current level.
@@ -56,8 +55,8 @@ updateAnyLevel f ln state@(State { slevel = level,
| otherwise = updateDungeon (const $ Dungeon $ M.adjust f ln dng) state
-- | Calculate the location of player's target.
-targetToLoc :: State -> Perception -> Maybe Loc
-targetToLoc state per =
+targetToLoc :: State -> S.Set Loc -> Maybe Loc
+targetToLoc state visible =
case mtarget (getPlayerBody state) of
TLoc loc -> Just loc
TCursor ->
@@ -68,7 +67,7 @@ targetToLoc state per =
(ln, m) <- findActorAnyLevel a state -- is target alive?
guard $ ln == lname (slevel state) -- is target on current level?
let loc = mloc m
- guard $ S.member loc (pvisible per) -- is target visible?
+ guard $ S.member loc visible -- is target visible?
return loc
-- The operations below disregard levels other than the current.
View
@@ -14,7 +14,21 @@ import qualified Config
data Perception =
Perception { preachable :: S.Set Loc, pvisible :: S.Set Loc }
-perception_ :: State -> Perception
+-- The pplayer field is void if player not on the current level,
+-- or if the player controls a blind monster (TODO. But perhaps only non-blind
+-- monsters should be controllable?).
+data Perceptions =
+ Perceptions { pplayer :: Maybe Perception,
+ pheroes :: IM.IntMap Perception,
+ ptotal :: Perception }
+
+ptreachable :: Perceptions -> S.Set Loc
+ptreachable = preachable . ptotal
+
+ptvisible :: Perceptions -> S.Set Loc
+ptvisible = pvisible . ptotal
+
+perception_ :: State -> Perceptions
perception_ state@(State { slevel = Level { lmap = lmap, lheroes = hs },
sconfig = config,
ssensory = sensory }) =
@@ -34,14 +48,14 @@ perception_ state@(State { slevel = Level { lmap = lmap, lheroes = hs },
"shadow" -> Shadow
_ -> error $ "perception_: unknown mode: " ++ show mode
-
- lhs = IM.elems hs
- pers = L.map (\ pl -> perception fovMode (mloc pl) lmap) lhs
- reachable = S.unions (L.map preachable pers)
- visible = S.unions (L.map pvisible pers)
- -- TODO: update individual hero perceptions here; see https://github.com/Mikolaj/LambdaHack/issues/issue/31
- -- TODO: do perception also for a monster under player control
- in Perception reachable visible
+ pers = IM.map (\ pl -> perception fovMode (mloc pl) lmap) hs
+ lpers = IM.elems pers
+ pper = Nothing -- TODO, and add it to ptotal, in case it's monster
+ reachable = S.unions (L.map preachable lpers)
+ visible = S.unions (L.map pvisible lpers)
+ in Perceptions { pplayer = pper,
+ pheroes = pers,
+ ptotal = Perception reachable visible }
perception :: FovMode -> Loc -> LMap -> Perception
perception fovMode ploc lmap =
View
@@ -15,7 +15,7 @@ import Perception
import Strategy
import State
-strategy :: Actor -> State -> Perception -> Strategy Dir
+strategy :: Actor -> State -> Perceptions -> Strategy Dir
strategy actor
state@(State { stime = time,
slevel = Level { lsmell = nsmap,
@@ -51,7 +51,7 @@ strategy actor
-- TODO: currently even invisible heroes are targeted if _any_ hero
-- is visible; each hero should carry his own perception to check
-- if he's visible by a given monster
- playerVisible = me `S.member` pvisible per -- monster sees any hero
+ playerVisible = me `S.member` ptvisible per -- monster sees any hero
playerAdjacent = maybe False (adjacent me) ploc
towardsPlayer = maybe (0, 0) (\ ploc -> towards (me, ploc)) ploc
onlyTowardsPlayer = only (\ x -> distance (towardsPlayer, x) <= 1)

0 comments on commit 41800b4

Please sign in to comment.