LambdaHack-0.1.20110918: src/ItemKind.hs
module ItemKind
(ItemKind(..), ItemKindId, getIK, itemFrequency, itemFlavours, swordKindId)
where
import Data.Binary
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.IntMap as IM
import Control.Monad
import Data.Maybe
import Color
import Effect
import Random
import Flavour
-- TODO: jpower is out of place here. It doesn't make sense for all items,
-- and will mean different things for different items. Perhaps it should
-- be part of the Effect, but then we have to be careful to distinguish
-- parts of the Effect that are rolled on item creation and those rolled
-- at each use (e.g., sword magical +damage vs. sword damage dice).
-- Another thing to keep in minds is that jpower will heavily determine
-- the value of the item for shops, treasure chests, artifact set rebalancing,
-- etc., so if we make jpower complex, the value computation gets complex too.
data ItemKind = ItemKind
{ jsymbol :: !Char -- ^ map symbol
, jflavour :: [Flavour] -- ^ possible flavours
, jname :: String -- ^ item group name
, jeffect :: Effect -- ^ the effect when activated
, jcount :: RollQuad -- ^ created in that quantify
, jfreq :: !Int -- ^ created that often
, jpower :: RollQuad -- ^ created with that power
}
deriving (Show, Eq, Ord)
newtype ItemKindId = ItemKindId Int
deriving (Show, Eq, Ord)
instance Binary ItemKindId where
put (ItemKindId i) = put i
get = liftM ItemKindId get
itemAssocs :: [(Int, ItemKind)]
itemAssocs = L.zip [0..] loot
itemContent :: IM.IntMap ItemKind
itemContent = IM.fromDistinctAscList itemAssocs
getIK :: ItemKindId -> ItemKind
getIK (ItemKindId i) = itemContent IM.! i
itemFrequency :: Frequency ItemKindId
itemFrequency = Frequency [(jfreq ik, ItemKindId i) | (i, ik) <- itemAssocs]
itemFlavours :: M.Map ItemKindId [Flavour]
itemFlavours =
M.fromDistinctAscList [(ItemKindId i, jflavour ik) | (i, ik) <- itemAssocs]
swordKindId :: ItemKindId
swordKindId = ItemKindId $ fromJust $ L.elemIndex sword loot
loot :: [ItemKind]
loot =
[amulet,
dart,
gem1, gem2, gem3, gem4,
gold,
potion1, potion2, potion3,
ring,
scroll1, scroll2,
sword,
wand]
-- rollQuad (a, b, x, y) = a * d b + (lvl * x * d y) / 10
amulet, dart, gem, gem1, gem2, gem3, gem4, gold :: ItemKind
potion, potion1, potion2, potion3 :: ItemKind
ring, scroll, scroll1, scroll2, sword, wand :: ItemKind
amulet = ItemKind
{ jsymbol = '"'
, jflavour = [(BrGreen, True)]
, jname = "amulet"
, jeffect = Regneration
, jcount = intToQuad 1
, jfreq = 10
, jpower = (2, 1, 2, 2)
}
dart = ItemKind
{ jsymbol = ')'
, jflavour = [(Yellow, False)]
, jname = "dart"
, jeffect = Wound (1, 1)
, jcount = (3, 3, 0, 0)
, jfreq = 30
, jpower = intToQuad 0
}
gem = ItemKind
{ jsymbol = '*'
, jflavour = zipPlain brightCol -- natural, so not fancy
, jname = "gem"
, jeffect = NoEffect
, jcount = intToQuad 0
, jfreq = 20 -- x4, but rare on shallow levels
, jpower = intToQuad 0
}
gem1 = gem
{ jcount = (1, 1, 0, 0) -- appears on lvl 1
}
gem2 = gem
{ jcount = (0, 0, 2, 1) -- appears on lvl 5, doubled on lvl 10
}
gem3 = gem
{ jcount = (0, 0, 1, 1) -- appears on lvl 10
}
gem4 = gem
{ jcount = (0, 0, 1, 1) -- appears on lvl 10
}
gold = ItemKind
{ jsymbol = '$'
, jflavour = [(BrYellow, False)]
, jname = "gold piece"
, jeffect = NoEffect
, jcount = (0, 0, 10, 10)
, jfreq = 80
, jpower = intToQuad 0
}
potion = ItemKind
{ jsymbol = '!'
, jflavour = zipFancy stdCol
, jname = "potion"
, jeffect = NoEffect
, jcount = intToQuad 1
, jfreq = 10
, jpower = intToQuad 0
}
potion1 = potion
{ jeffect = ApplyPerfume
}
potion2 = potion
{ jeffect = Heal
, jpower = (10, 1, 0, 0)
}
potion3 = potion
{ jeffect = Wound (0, 0)
, jpower = (10, 1, 0, 0)
}
ring = ItemKind
{ jsymbol = '='
, jflavour = [(White, False)]
, jname = "ring"
, jeffect = Searching
, jcount = intToQuad 1
, jfreq = 10
, jpower = (1, 1, 2, 2)
}
scroll = ItemKind
{ jsymbol = '?'
, jflavour = zipFancy darkCol -- arcane and old
, jname = "scroll"
, jeffect = NoEffect
, jcount = intToQuad 1
, jfreq = 10
, jpower = intToQuad 0
}
scroll1 = scroll
{ jeffect = SummonFriend
, jfreq = 20
}
scroll2 = scroll
{ jeffect = SummonEnemy
}
sword = ItemKind
{ jsymbol = ')'
, jflavour = [(BrCyan, False)]
, jname = "sword"
, jeffect = Wound (3, 1)
, jcount = intToQuad 1
, jfreq = 60
, jpower = (1, 2, 4, 2)
}
wand = ItemKind
{ jsymbol = '/'
, jflavour = [(BrRed, True)]
, jname = "wand"
, jeffect = Dominate
, jcount = intToQuad 1
, jfreq = 10
, jpower = intToQuad 0
}