packages feed

LambdaHack-0.1.20080413: Item.hs

module Item where

import Data.Binary
import Data.Set as S
import Data.List as L
import Data.Maybe
import Control.Monad

import Display
import Geometry
import Random

data Item = Item
             { itype   :: ItemType,   
               iletter :: Maybe Char }  -- inventory identifier
  deriving Show

data ItemType =
   Ring
 | Scroll
 | Potion
 | Wand
 | Amulet
 | Gem
 | Gold
 deriving Show

instance Binary Item where
  put (Item itype iletter) = put itype >> put iletter
  get = liftM2 Item get get

instance Binary ItemType where
  put Ring   = putWord8 0
  put Scroll = putWord8 1
  put Potion = putWord8 2
  put Wand   = putWord8 3
  put Amulet = putWord8 4
  put Gem    = putWord8 5
  put Gold   = putWord8 6
  get = do
          tag <- getWord8
          case tag of
            0 -> return Ring
            1 -> return Scroll
            2 -> return Potion
            3 -> return Wand
            4 -> return Amulet
            5 -> return Gem
            6 -> return Gold

itemFrequency :: Frequency ItemType
itemFrequency =
  Frequency
  [
    (10, Gold),
    (3, Gem),
    (2, Ring),
    (4, Scroll),
    (2, Wand),
    (1, Amulet),
    (4, Potion)
  ]

-- | Generate an item.
newItem :: Frequency ItemType -> Rnd Item
newItem ftp =
  do
    tp <- frequency ftp
    return (Item tp Nothing)

-- | Assigns a letter to an item, for inclusion
-- in the inventory of the player. Takes a starting
-- letter.
assignLetter :: Char -> [Item] -> Maybe Char
assignLetter c is =
    listToMaybe (L.filter (\x -> not (x `member` current)) candidates)
  where
    current    = S.fromList (concatMap (maybeToList . iletter) is)
    allLetters = ['a'..'z'] ++ ['A'..'Z']
    candidates = take (length allLetters) (drop (fromJust (findIndex (==c) allLetters)) (cycle allLetters))

viewItem :: ItemType -> (Char, Attr -> Attr)
viewItem Ring   = ('=', id)
viewItem Scroll = ('?', id)
viewItem Potion = ('!', id)
viewItem Wand   = ('/', id)
viewItem Gold   = ('$', setFG yellow)
viewItem Gem    = ('*', setFG red)
viewItem _      = ('~', id)

objectItem :: ItemType -> String
objectItem Ring   = "a ring"
objectItem Scroll = "a scroll"
objectItem Potion = "a potion"
objectItem Wand   = "a wand"
objectItem Amulet = "an amulet"
objectItem Gem    = "a gem"
objectItem Gold   = "some gold"