From 5c5aa14a3dcb5c172eaf8d2236b41020c8e92051 Mon Sep 17 00:00:00 2001 From: Griffin Smith Date: Fri, 3 Jan 2020 12:04:08 -0500 Subject: Don't render moving entities that aren't visible When the character walks away from or around the corner from entities that move such that they're no longer visible, stop rendering them. Still render static entities like walls, doors, and items though. This prevents entities walking into a "revealed position" after the character's left being visible despite not being in a line of sight any more. --- src/Xanthous/Game/Draw.hs | 53 ++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 21 deletions(-) (limited to 'src/Xanthous/Game/Draw.hs') diff --git a/src/Xanthous/Game/Draw.hs b/src/Xanthous/Game/Draw.hs index d98b48c02742..8a86101d9915 100644 --- a/src/Xanthous/Game/Draw.hs +++ b/src/Xanthous/Game/Draw.hs @@ -20,6 +20,7 @@ import Xanthous.Game , entities , revealedPositions , characterPosition + , characterVisiblePositions , character , MessageHistory(..) , messageHistory @@ -62,10 +63,12 @@ drawPromptState (WaitingPrompt msg (Prompt _ pt ps pri _)) = drawEntities :: (Position -> Bool) - -- ^ Can we render a given position? + -- ^ Is a given position directly visible to the character? + -> (Position -> Bool) + -- ^ Has a given position *ever* been seen by the character? -> EntityMap SomeEntity -- ^ all entities -> Widget Name -drawEntities canRenderPos allEnts +drawEntities isVisible isRevealed allEnts = vBox rows where entityPositions = EntityMap.positions allEnts @@ -74,23 +77,27 @@ drawEntities canRenderPos allEnts rows = mkRow <$> [0..maxY] mkRow rowY = hBox $ renderEntityAt . flip Position rowY <$> [0..maxX] renderEntityAt pos - | canRenderPos pos + = let entitiesAtPosition = allEnts ^. atPosition pos + immobileEntitiesAtPosition = + filter (not . entityCanMove) entitiesAtPosition + in renderTopEntity pos + $ if | isVisible pos -> entitiesAtPosition + | isRevealed pos -> immobileEntitiesAtPosition + | otherwise -> mempty + renderTopEntity pos ents = let neighbors = EntityMap.neighbors pos allEnts in maybe (str " ") (drawWithNeighbors neighbors) - $ maximumByOf - (atPosition pos . folded) - (compare `on` drawPriority) - allEnts - | otherwise = str " " + $ maximumBy (compare `on` drawPriority) + <$> fromNullable ents drawMap :: GameState -> Widget Name drawMap game = viewport Resource.MapViewport Both . cursorPosition game $ drawEntities - (\pos -> - (game ^. debugState . allRevealed) - || (pos `member` (game ^. revealedPositions))) + (\pos -> (game ^. debugState . allRevealed) + || (pos `member` (game ^. revealedPositions))) + (`member` characterVisiblePositions game) -- FIXME: this will break down as soon as creatures can walk around on their -- own, since we don't want to render things walking around when the -- character can't see them @@ -99,17 +106,11 @@ drawMap game bullet :: Char bullet = '•' -drawPanel :: GameState -> Panel -> Widget Name -drawPanel game panel - = border - . hLimit 35 - . viewport (Resource.Panel panel) Vertical - $ case panel of - InventoryPanel -> - drawWielded (game ^. character . inventory . wielded) - <=> drawBackpack (game ^. character . inventory . backpack) +drawInventoryPanel :: GameState -> Widget Name +drawInventoryPanel game + = drawWielded (game ^. character . inventory . wielded) + <=> drawBackpack (game ^. character . inventory . backpack) where - drawWielded :: Wielded -> Widget Name drawWielded (Hands Nothing Nothing) = emptyWidget drawWielded (DoubleHanded i) = txtWrap $ "You are holding " <> description i <> " in both hands" @@ -132,6 +133,16 @@ drawPanel game panel (txtWrap . ((bullet <| " ") <>) . description) backpackItems) + +drawPanel :: GameState -> Panel -> Widget Name +drawPanel game panel + = border + . hLimit 35 + . viewport (Resource.Panel panel) Vertical + . case panel of + InventoryPanel -> drawInventoryPanel + $ game + drawCharacterInfo :: Character -> Widget Name drawCharacterInfo ch = txt " " <+> charName <+> charHitpoints where -- cgit 1.4.1