{-# LANGUAGE LambdaCase #-} module Dodge.Render.HUD ( drawHUD, selNumPos, -- this shoud probably be pushed back here ) where import Dodge.SelectionSections import Control.Lens import Control.Monad import qualified Data.Map.Strict as M import Data.Maybe import qualified Data.Vector as V import Dodge.Base import Dodge.Clock import Dodge.Creature.Info import Dodge.Data.CardinalPoint import Dodge.Data.Combine import Dodge.Data.Config import Dodge.Data.SelectionList import Dodge.Data.World import Dodge.Default.SelectionList import Dodge.Equipment.Text import Dodge.Inventory import Dodge.Item.Display import Dodge.Item.Grammar import Dodge.Item.Info import Dodge.ListDisplayParams import Dodge.Render.Connectors import Dodge.Render.HUD.Carte import Dodge.Render.List import Dodge.ScreenPos import Dodge.SelectionSections import Dodge.SelectionSections.Draw import Geometry import qualified IntMapHelp as IM import Justify --import ListHelp --import Padding import Picture import SDL (MouseButton (..)) drawHUD :: Configuration -> World -> Picture drawHUD cfig w = case w ^. hud . hudElement of DisplayCarte -> drawCarte cfig w DisplayInventory{_diSections = sections, _subInventory = subinv} -> drawHP cfig w <> drawInventory sections w cfig <> drawSubInventory subinv cfig w drawHP :: Configuration -> World -> Picture drawHP cfig = dShadCol white . translate (halfWidth cfig) (halfHeight cfig - 40) . scale 0.2 0.2 . textRight . show . (^?! cWorld . lWorld . creatures . ix 0 . crHP) drawInventory :: SelectionSections () -> World -> Configuration -> Picture drawInventory sss w cfig = drawSelectionSections sss ldp cfig <> iextra <> translateScreenPos cfig (ldp ^. ldpPos) (drawDIMouseOver w) <> drawDISelections w cfig where ldp = invDisplayParams w iextra = fromMaybe mempty $ do inv <- w ^? cWorld . lWorld . creatures . ix 0 . crInv let x = case invAdj inv of Left str -> error $ "drawInventory: " ++ str Right y -> y return $ inventoryExtra sss cfig w x drawDIMouseOver :: World -> Picture drawDIMouseOver w = fromMaybe mempty $ do (_,i) <- w ^? hud . hudElement . subInventory . nsMouseOver . _Just sss <- w ^? hud . hudElement . diSections let idp = invDisplayParams w return . color (withAlpha 0.5 white) $ selSecDrawCursorAt (0,i) 10 idp sss drawDISelections :: World -> Configuration -> Picture drawDISelections w cfig = fromMaybe mempty $ do (i,j) <- w ^? hud . hudElement . subInventory . nsSelected . _Just sss <- w ^? hud . hudElement . diSections let idp = invDisplayParams w tp <- selNumPos cfig idp sss 0 i bp <- selNumPos cfig idp sss 0 j return . color red $ line [tp,bp] drawSubInventory :: SubInventory -> Configuration -> World -> Picture drawSubInventory subinv cfig w = case subinv of LockedInventory -> mempty -- topInvCursor col cursPos cfig w NoSubInventory{} -> drawRBOptions cfig w ExamineInventory -> drawExamineInventory cfig w DisplayTerminal tid -> displayTerminal tid cfig (w ^. cWorld . lWorld) CombineInventory{_ciSections = sss} -> drawCombineInventory cfig sss w drawCombineInventory :: Configuration -> SelectionSections CombinableItem -> World -> Picture drawCombineInventory cfig sss w = invHead cfig "COMBINE" <> drawSelectionSections sss secondColumnParams cfig <> combineInventoryExtra sss cfig w drawExamineInventory :: Configuration -> World -> Picture drawExamineInventory cfig w = invHead cfig "EXAMINE" <> drawSelectionList secondColumnParams cfig ( defaultSelectionList & slItems .~ map -- tweakItems itm -- ++ f ( makeParagraph 55 $ yourAugmentedItem itemInfo (yourInfo (you w)) (closeObjectInfo (crNumFreeSlots (you w))) w ) ) where -- itm = yourSelectedItem w f str = SelectionItem { _siPictures = [str] , _siHeight = 1 , _siIsSelectable = True , _siColor = white , _siOffX = 0 , _siPayload = () } closeObjectInfo :: Int -> Either FloorItem Button -> String closeObjectInfo n x = case x of Left FlIt{_flIt = itm} -> itemInfo itm ++ " It is on the floor" ++ floorItemPickupInfo n itm Right _ -> "Some sort of switch or button." floorItemPickupInfo :: Int -> Item -> String floorItemPickupInfo n itm | n >= _itInvSize itm = ", but you have space to pick it up." | otherwise = ", and you don't have space to pick it up." -- note the use of ^?! -- it is probably desirable for this to crash hard for now yourAugmentedItem :: (Item -> a) -> a -> (Either FloorItem Button -> a) -> World -> a yourAugmentedItem f x g w = case you w ^? crManipulation . manObject of Just (SelectedItem i _ _) -> f $ yourInv w ^?! ix i Just (SelCloseObject i) -> g $ w ^?! hud . closeObjects . ix i _ -> x drawRBOptions :: Configuration -> World -> Picture drawRBOptions cfig w = fromMaybe mempty $ do guard $ ButtonRight `M.member` _mouseButtons (_input w) invid <- you w ^? crManipulation . manObject . imSelectedItem eslist <- fmap equipSiteToPositions $ you w ^? crInv . ix invid . itUse . uequipEffect . eeSite i <- w ^? rbOptions . opSel let ae = getEquipmentAllocation w sss <- w ^? hud . hudElement . diSections (i', j) <- sss ^? sssExtra . sssSelPos . _Just curpos <- selSecYint i' j sss let ytext = drawListElement 0 1 0 curpos . text midstr = equipAllocString ae extrastr = case ae of SwapEquipment{_allocOldPos = oldp, _allocSwapID = sid} -> "SWAPS " ++ otheritem sid ++ " ONTO " ++ eqPosText oldp ReplaceEquipment{_allocRemoveID = rid} -> "REMOVES " ++ otheritem rid _ -> "" return $ toTopLeft cfig $ translate 290 (-1) (ytext midstr) <> translate 160 (-1) (listCursorChooseBorderScale 0 1 [North, South] curpos 0 white 21 1) <> translate 380 (-1) ( drawListYoff (curpos - i) (map (text . eqPosText) eslist) <> listCursorChooseBorderScale 0 1 [East] (curpos - i) 0 white 7 (length eslist) <> listCursorChooseBorderScale 0 1 [West] (curpos + 1) 0 white 7 (length eslist - (i + 1)) <> listCursorChooseBorderScale 0 1 [West] (curpos - i) 0 white 7 i <> maybetopborder i curpos <> maybebottomborder i (length eslist) curpos ) <> translate 460 (-1) (ytext extrastr) where maybetopborder 0 curpos = listCursorChooseBorderScale 0 1 [North] curpos 0 white 7 1 maybetopborder _ _ = mempty maybebottomborder a b curpos | a == b - 1 = listCursorChooseBorderScale 0 1 [South] curpos 0 white 7 1 | otherwise = mempty otheritem j = fromMaybe "" $ do itm <- you w ^? crInv . ix j return $ itemBaseName itm equipAllocString :: EquipmentAllocation -> String equipAllocString = \case DoNotMoveEquipment -> "" PutOnEquipment{} -> " PUT ON" MoveEquipment{} -> " MOVE TO" SwapEquipment{} -> " MOVE TO" ReplaceEquipment{} -> " PUT ON" RemoveEquipment{} -> "TAKE OFF" inventoryExtra :: SelectionSections () -> Configuration -> World -> IM.IntMap (Maybe (Int, Int), [Int], [Int]) -> Picture inventoryExtra sss cfig w = translate (negate 5) 0 . IM.foldMapWithKey (inventoryExtraH sss cfig w) . fmap (\(_, a, b) -> a <> b) inventoryExtraH :: SelectionSections () -> Configuration -> World -> Int -> [Int] -> Picture inventoryExtraH sss cfig w i is = fromMaybe mempty $ do p <- snum i let ps = mapMaybe snum is return $ color white $ lConnectMulti ps p where snum = selNumPos cfig (invDisplayParams w) sss 0 combineInventoryExtra :: SelectionSections CombinableItem -> Configuration -> World -> Picture combineInventoryExtra sss cfig w = fromMaybe mempty $ do (i, j) <- sss ^? sssExtra . sssSelPos . _Just cpos <- selSecYint i j sss si <- sss ^? sssSections . ix i . ssItems . ix j let col = _siColor si mconcat [ do strs <- si ^? siPayload . ciInfo return . translate 160 0 -- it would be better to get the width of the selection list from elsewhere . translateScreenPos cfig (secondColumnParams ^. ldpPos) $ drawListYoff cpos $ map (color red . text) strs , do lnks <- si ^? siPayload . ciInvIDs return (lnkMidPosInvSelsCol cfig w j col lnks) <> foldMap invcursor lnks ] where invcursor i = do sss' <- w ^? hud . hudElement . diSections let idp = invDisplayParams w & ldpCursorSides .~ [North, South, East, West] return $ translateScreenPos cfig (idp ^. ldpPos) $ selSecDrawCursor 17 idp (sss' & sssExtra . sssSelPos ?~ (0, i)) displayTerminal :: Int -> Configuration -> LWorld -> Picture displayTerminal tid cfig w = fromMaybe mempty $ do tm <- w ^? terminals . ix tid return $ invHead cfig (_tmTitle tm ++ ":T" ++ show tid) <> drawSelectionList secondColumnParams cfig (thesellist tm) where toselitm (str, col) = SelectionItem [str] 1 True col 0 () thesellist tm = defaultSelectionList & slItems .~ thelist tm thelist tm = map toselitm . displayTermInput tm . reverse . take (_tmMaxLines tm) $ _tmDisplayedLines tm displayTermInput tm = case _tmInput tm of TerminalInput{_tiText = s, _tiFocus = hasfoc} -> (++ [(displayInputText tm s ++ displayBlinkCursor hasfoc, white)]) partcommand tm = maybe "" (++ " ") $ tm ^? tmPartialCommand . _Just . tcString displayInputText tm s | _tmStatus tm == TerminalReady = partcommand tm ++ "> " ++ s | otherwise = "" displayBlinkCursor hasfoc | hasfoc = clockCycle 10 (V.fromList ["_", "."]) w | otherwise = [] lnkMidPosInvSelsCol :: Configuration -> World -> Int -> Color -> [Int] -> Picture lnkMidPosInvSelsCol cfig w i col = fromMaybe mempty . foldMap f where f j = do sss <- w ^? hud . hudElement . diSections combinesss <- w ^? hud . hudElement . subInventory . ciSections lp <- selNumPos cfig (invDisplayParams w) sss 0 j rp <- selNumPos cfig secondColumnParams combinesss 0 i invcol <- selSecSelCol 0 j sss return $ zConnectCol (rp - V2 5 0) (lp + V2 175 0) col col col invcol invHead :: Configuration -> String -> Picture invHead cfig = translateScreenPos cfig (fromTopLeft (V2 (subInvX - 5) 80)) . dShadCol white . scale 0.4 0.4 . textJustifyLeft --locPoss = map (cartePosToScreen cfig (w ^. hud) . ($ w) . doWorldPos . fst) . IM.elems . _seenLocations . _lWorld $ _cWorld w --locTexts = map fst locs --displayListEndCoords :: Configuration -> [String] -> [Point2] --displayListEndCoords cfig ss = map (doWindowScale cfig) $ zipWith h ss $ map f [1 ..] -- where -- f :: Int -> Point2 -- f i = V2 (15 - halfWidth cfig) (2.5 + halfHeight cfig - (20 * fromIntegral i)) -- h :: String -> Point2 -> Point2 -- h s (V2 x y) = V2 (x + 9 * fromIntegral (length s)) y --closeObjectTexts :: Configuration -> World -> Picture --closeObjectTexts cfig w = pictures $ -- renderListAt pushout (negate 20 * fromIntegral invPos) cfig (map colAndText $ _closeObjects w) -- : maybeToList maybeLine -- where -- colAndText (Left x) = ( _itName $ _flIt x, _itInvColor $ _flIt x) -- colAndText (Right x) = (_btText x,yellow) -- youSel = _crInvSel $ you w -- freeSlot = mayIt >>= \it -> checkInvSlotsYou (_flIt it) w -- invPos = fromMaybe youSel freeSlot -- mayObj = listToMaybe $ _closeObjects w -- mayIt = mayObj >>= maybeLeft -- maybeLeft (Left x) = Just x -- maybeLeft _ = Nothing -- pushout = 120 -- objPos obj = case obj of -- Left flit -> _flItPos flit -- Right bt -> _btPos bt -- mayScreenPos = fmap (worldPosToScreen w . objPos) mayObj -- maybeLine = do -- itScreenPos <- mayScreenPos -- (theText,col) <- fmap colAndText mayObj -- let textWidth = 9 * fromIntegral (length theText) -- let p = V2 (textWidth + 15 + pushout - halfWidth cfig) -- ( halfHeight cfig - 20* (fromIntegral invPos +1) + 2.5) -- return . winScale cfig . color col $ lConnect p itScreenPos --textSelItems :: [String] -> [SelectionItem ()] --textSelItems = map (picsToSelectable . (: [])) --picsToSelectable :: [String] -> SelectionItem () --picsToSelectable pics = -- SelectionItem -- { _siPictures = pics -- , _siHeight = length pics -- , _siIsSelectable = True -- , _siColor = white -- , _siOffX = 0 -- , _siPayload = () -- } -- would be nice to add parameter to orient this with NSEW, cf cursor selNumPos :: Configuration -> ListDisplayParams -> SelectionSections a -> Int -> Int -> Maybe Point2 selNumPos cfig ldp sss i j = do ipos <- selSecYint i j sss size <- selSecSelSize i j sss indent <- sss ^? sssSections . ix i . ssItems . ix j . siOffX return $ screenPosAbs cfig (ldp ^. ldpPos) + V2 (10 * s * fromIntegral indent) (negate (20 * s + ygap) * (fromIntegral ipos + fromIntegral size * 0.5)) where s = _ldpScale ldp ygap = _ldpVerticalGap ldp selSecSelCol :: Int -> Int -> SelectionSections a -> Maybe Color selSecSelCol i j sss = sss ^? sssSections . ix i . ssItems . ix j . siColor