244 lines
7.8 KiB
Haskell
244 lines
7.8 KiB
Haskell
{-# LANGUAGE LambdaCase #-}
|
|
|
|
module Dodge.Inventory.SelectionList (
|
|
invSelectionItem,
|
|
closeItemToSelectionItem,
|
|
closeButtonToSelectionItem,
|
|
getInventoryPath,
|
|
getItemValue,
|
|
) where
|
|
|
|
import Dodge.Creature.MaxHP
|
|
import Dodge.Data.Equipment.Misc
|
|
import Numeric
|
|
import Dodge.Inventory.Path
|
|
import Control.Applicative
|
|
import ShortShow
|
|
import Data.Maybe
|
|
import Dodge.Data.DoubleTree
|
|
import Dodge.Item.InvSize
|
|
import Dodge.Data.ComposedItem
|
|
import Dodge.Data.SelectionList
|
|
import Dodge.Data.World
|
|
import Dodge.Equipment.Text
|
|
import Dodge.Item.Display
|
|
import Dodge.Item.Grammar
|
|
import Dodge.Item.InventoryColor
|
|
import LensHelp
|
|
import NewInt
|
|
import Padding
|
|
import Picture.Base
|
|
|
|
invSelectionItem :: World -> Int -> LocationDT OItem -> SelectionItem ()
|
|
invSelectionItem w indent loc =
|
|
SelectionItem
|
|
{ _siPictures = itemDisplay w cr ci
|
|
, _siHeight = itInvHeight $ ci ^. _1
|
|
, _siWidth = 15
|
|
, _siIsSelectable = True
|
|
, _siColor = itemInvColor ci
|
|
, _siOffX = indent
|
|
, _siPayload = ()
|
|
}
|
|
where
|
|
ci = (a,b)
|
|
(a,b,_) = loc ^. locDT . dtValue
|
|
cr = w ^?! cWorld . lWorld . creatures . ix 0
|
|
|
|
-- note the convoluted display of the hotkey/equipment, this was done to avoid a
|
|
-- space leak
|
|
itemDisplay :: World -> Creature -> CItem -> [String]
|
|
itemDisplay w cr ci = -- f
|
|
basicItemDisplay itm
|
|
-- (itemNumberDisplay w cr ci)
|
|
`g` anyextra
|
|
where
|
|
itm = ci ^. _1
|
|
NInt itid = itm ^. itID
|
|
--f (x:xs) (y:_) = itemDisplayPad x y : xs
|
|
--f xs _ = xs
|
|
--g (x:xs) (y:_) = (rightPad 15 ' ' x ++ y) : xs
|
|
g (x:xs) (y:_) = (x ++ y) : xs
|
|
g xs _ = xs
|
|
anyextra = maybeToList (anyscroll <> anyexternal <> anyhotkey <> anyequippos)
|
|
anyhotkey = fmap hotkeyToString
|
|
(w ^? cWorld . lWorld . imHotkeys . unNIntMap . ix itid)
|
|
anyequippos = do
|
|
_ <- ci ^? _1 . itType . ibtEquip
|
|
epText <$> ci ^? _1 . itLocation . ilEquipSite
|
|
anyscroll = fmap absurround $ itemScrollDisplay =<< (ci ^? _1)
|
|
absurround str = " <" ++ str ++ ">"
|
|
anyexternal = fae <$> itemExternalValue itm w cr
|
|
-- will probably want to remote the !
|
|
fae (Left i) = " !"++shortShow i
|
|
fae (Right s) = " !" ++ s
|
|
|
|
epText :: Maybe EquipSite -> [Char]
|
|
epText (Just ep) = ' ' : rightPad 8 ' ' ('@' : eqPosText ep)
|
|
epText Nothing = " @NOT.EQP"
|
|
|
|
introScanValue :: Creature -> IntroScanType -> Either Int String
|
|
introScanValue cr = \case
|
|
HEALTH -> Left $ cr ^. crHP
|
|
MAXHEALTH -> Left $ crMaxHP $ cr ^. crType
|
|
|
|
itemExternalValue :: Item -> World -> Creature -> Maybe (Either Int String)
|
|
itemExternalValue itm w cr
|
|
| EQUIP WRIST_ECG <- itm ^. itType = Just . Right .
|
|
displayPulse $ cr ^?! crType . avatarPulse . pulseProgress
|
|
| Just t <- itm ^? itType . ibtIntroScanType = Just $ introScanValue cr t
|
|
| ITEMSCAN <- itm ^. itType
|
|
, Just ExamineInventory <- w ^? hud . hudElement . subInventory
|
|
= Just (Right "ON")
|
|
| BINGATE <- itm ^. itType = do
|
|
invid <- itm ^? itLocation . ilInvID
|
|
litm <- cr ^? crInv . ix (invid -2)
|
|
ritm <- cr ^? crInv . ix (invid -1)
|
|
x <- itm ^? itScroll . itsRangeInt
|
|
l <- getItemValue litm w cr ^? _Just . _Left
|
|
r <- getItemValue ritm w cr ^? _Just . _Left
|
|
Just . Left $ bgateCalc x l r
|
|
| UNIGATE <- itm ^. itType = do
|
|
invid <- itm ^? itLocation . ilInvID
|
|
itm' <- cr ^? crInv . ix (invid -1)
|
|
x <- itm ^? itScroll . itsRangeInt
|
|
y <- getItemValue itm' w cr ^? _Just . _Left
|
|
Just . Left $ ugateCalc x y
|
|
| otherwise = mempty
|
|
|
|
ugateCalc :: Int -> Int -> Int
|
|
ugateCalc x y = (x `div` ((2::Int) ^ (f y ::Int))::Int) `mod` 2
|
|
where
|
|
f i | i > 0 = 1
|
|
| otherwise = 0
|
|
|
|
bgateCalc :: Int -> Int -> Int -> Int
|
|
bgateCalc x l r = (x `div` ((2::Int) ^ ((2::Int)*f l + f r))) `mod` 2
|
|
where
|
|
f i | i > 0 = 1
|
|
| otherwise = 0
|
|
|
|
itemScrollDisplay :: Item -> Maybe String
|
|
itemScrollDisplay itm
|
|
| HELD ALTERIFLE <- itm ^. itType = Just $
|
|
case itm ^? itParams . alteRifleSwitch of
|
|
Just 0 -> "L"
|
|
_ -> "R"
|
|
| UseScope OpticScope{_opticZoom = x} <- itm ^. itUse = Just $ shortShow x
|
|
| UNIGATE <- itm ^. itType = do
|
|
i <- itm ^? itScroll . itsRangeInt
|
|
return $ toBinary 2 i
|
|
| BINGATE <- itm ^. itType = do
|
|
i <- itm ^? itScroll . itsRangeInt
|
|
return $ toBinary 4 i
|
|
| ItemScrollInt i <- itm ^. itScroll = Just $ show i
|
|
| ItemScrollIntRange _ i <- itm ^. itScroll = Just $ show i
|
|
| otherwise = Nothing
|
|
|
|
toBinary :: Int -> Int -> String
|
|
toBinary x = leftPad x '0' . ($ []) . showIntAtBase 2 f
|
|
where
|
|
f 0 = '0'
|
|
f _ = '1'
|
|
|
|
getItemValue :: Item -> World -> Creature -> Maybe (Either Int String)
|
|
getItemValue itm w cr = itemInternalValue itm <|> itemExternalValue itm w cr
|
|
<|> itemScrollValue itm
|
|
|
|
itemScrollValue :: Item -> Maybe (Either Int b)
|
|
itemScrollValue itm = Left <$> itm ^? itScroll . failing itsInt itsRangeInt
|
|
|
|
--itemDisplayPad :: [Char] -> String -> [Char]
|
|
--itemDisplayPad ls rs
|
|
-- | rs == "" = ls
|
|
-- | otherwise = midPadL 15 ' ' ls (' ' : rs)
|
|
|
|
--itemNumberDisplay :: World -> Creature -> CItem -> [String]
|
|
--itemNumberDisplay w cr ci
|
|
-- | Just x <- ci ^? _1 . itUse . uInt = [show x]
|
|
-- | Just x <- ci ^? _1 . itUse . useToggle = [show x]
|
|
-- | ITEMSCAN <- ci ^. _1 . itType
|
|
-- , Just ExamineInventory <- w ^? hud . hudElement . subInventory = ["ACTIVE"]
|
|
-- | EQUIP WRIST_ECG <- ci ^. _1 . itType =
|
|
-- [displayPulse $ cr ^?! crType . avatarPulse . pulseProgress]
|
|
-- | isJust $ ci ^? _1 . itTargeting . itTgPos . _Just = ["!TARG!"]
|
|
-- | Just x <- ci ^? _1 . itConsumables . magLoadStatus . iaLoaded = [shortShow x]
|
|
-- | Just i <- ci ^? _1 . itUse . uaParams . apInt = [show i]
|
|
-- | Just x <- ci ^? _1 . itUse . uaParams . apProjectiles = [show x]
|
|
-- | Just t <- ci ^? _1 . itType . ibtIntroScanType = [introScanDisplay cr t]
|
|
-- | otherwise = mempty
|
|
|
|
--introScanDisplay :: Creature -> IntroScanType -> String
|
|
--introScanDisplay cr = \case
|
|
-- HEALTH -> shortShow (cr ^. crHP)
|
|
-- MAXHEALTH -> shortShow (cr ^. crMaxHP)
|
|
|
|
displayPulse :: Int -> String
|
|
displayPulse 0 = "*****"
|
|
displayPulse x = take 5 $ drop y "----^-----"
|
|
where
|
|
y = min 5 $ x `div` 3
|
|
|
|
hotkeyToString :: Hotkey -> String
|
|
hotkeyToString x = " [" ++ hotkeyToChar x : "]"
|
|
|
|
hotkeyToChar :: Hotkey -> Char
|
|
hotkeyToChar = \case
|
|
HotkeyQ -> 'Q'
|
|
HotkeyE -> 'E'
|
|
HotkeyR -> 'R'
|
|
HotkeyZ -> 'Z'
|
|
HotkeyX -> 'X'
|
|
HotkeyC -> 'C'
|
|
HotkeyV -> 'V'
|
|
Hotkey1 -> '1'
|
|
Hotkey2 -> '2'
|
|
Hotkey3 -> '3'
|
|
Hotkey4 -> '4'
|
|
Hotkey5 -> '5'
|
|
Hotkey6 -> '6'
|
|
Hotkey7 -> '7'
|
|
Hotkey8 -> '8'
|
|
Hotkey9 -> '9'
|
|
Hotkey0 -> '0'
|
|
|
|
closeItemToSelectionItem :: World -> NewInt FloorInt -> Maybe (SelectionItem ())
|
|
closeItemToSelectionItem w (NInt i) = do
|
|
e <- w ^? cWorld . lWorld . floorItems . unNIntMap . ix i
|
|
let (pics, col) = closeItemToTextPictures e
|
|
return
|
|
SelectionItem
|
|
{ _siPictures = pics
|
|
, _siHeight = length pics
|
|
, _siWidth = 15
|
|
, _siIsSelectable = True
|
|
, _siColor = col
|
|
, _siOffX = 0
|
|
, _siPayload = ()
|
|
}
|
|
|
|
closeButtonToSelectionItem :: World -> Int -> Maybe (SelectionItem ())
|
|
closeButtonToSelectionItem w i = do
|
|
bt <- w ^? cWorld . lWorld . buttons . ix i
|
|
return
|
|
SelectionItem
|
|
{ _siPictures = [btText bt]
|
|
, _siHeight = 1
|
|
, _siWidth = 15
|
|
, _siIsSelectable = True
|
|
, _siColor = yellow
|
|
, _siOffX = 0
|
|
, _siPayload = ()
|
|
}
|
|
|
|
btText :: Button -> String
|
|
btText bt = case _btEvent bt of
|
|
ButtonPress {} -> "BUTTON"
|
|
ButtonSwitch {_btOn = t} -> if t then "SWITCH\\" else "SWITCH/"
|
|
ButtonAccessTerminal {} -> "TERMINAL"
|
|
|
|
closeItemToTextPictures :: FloorItem -> ([String], Color)
|
|
closeItemToTextPictures flit = (basicItemDisplay it, itemInvColor $ baseCI it)
|
|
where
|
|
it = _flIt flit
|