mcpi-0.0.0.1: src/Data/MineCraft/Pi/Types.hs
--------------------------------------------------------------------------------
-- |
-- Module : Types
-- License : Public Domain
--
-- Maintainer : Douglas Burke
-- Stability : experimental
-- Portability : Haskell 98
--
-- Useful data types. The block types should probably move to
-- "Data.MineCraft.Pi.Block".
--
--------------------------------------------------------------------------------
module Data.MineCraft.Pi.Types
(
Pos(..)
, IPos
, FPos
, BlockType(..)
, BlockData(..)
) where
import Data.List (intercalate)
import Data.List.Split (splitOn)
import Data.Word (Word16)
import Network.MineCraft.Pi.Client
-- | Represent the position of an entity. Note that we use
-- @(X,Y,Z)@ order rather than @(X,Z,Y)@ used by the MineCraft API.
--
-- This *should* be replaced by one of the \"standard\" Haskell
-- 3D vector types.
--
data Pos a = Pos { _x :: a, _y :: a, _z :: a }
deriving (Eq, Show)
type IPos = Pos Int
type FPos = Pos Float
instance FromMineCraft a => FromMineCraft (Pos a) where
fromMC s = let toks = map fromMC $ splitOn "," s
in case toks of
(x:z:y:[]) -> Pos x y z
_ -> error $ "*Expected 3 values* " ++ s
instance ToMineCraft a => ToMineCraft (Pos a) where
toMC (Pos x y z) = intercalate "," $ map toMC [x,z,y]
-- | Represent a block.
--
-- We should probably combine `BlockType` and `BlockData`.
-- I have not looked to see whether it is worth using
-- an integer (as I currently do) or just an enumerated
-- type (e.g. if there are large ranges of the range 0 to 1023
-- that do not represent a valid block).
--
-- Use `Data.MineCraft.Pi.Block.showBlock` for a more readable
-- way to convert to a @String@.
newtype BlockType = BlockType Word16
deriving (Eq, Ord, Show)
-- | Data on a block.
newtype BlockData = BlockData Int
deriving (Eq, Ord, Show)
{- Looks like this range includes entities and other items than just
blocks.
instance Bounded BlockType where
minBound = BlockType 0
maxBound = BlockType 1023
-}
instance ToMineCraft BlockType where
toMC (BlockType bt) = show bt
instance FromMineCraft BlockType where
fromMC val = let i = eRead val
in if i >= 0 && i < 1024
then BlockType i
else error $ "*invalid block type: " ++ val
instance ToMineCraft BlockData where
toMC (BlockData bd) = show bd
instance FromMineCraft BlockData where
fromMC = BlockData . eRead