73 lines
No EOL
3 KiB
Haskell
73 lines
No EOL
3 KiB
Haskell
module RPGEngine.Data.Level
|
|
-- Everything is exported
|
|
where
|
|
|
|
import GHC.IO (unsafePerformIO)
|
|
import System.Directory (getDirectoryContents)
|
|
import RPGEngine.Input.Core (ListSelector(..))
|
|
import RPGEngine.Data (Action(..), Level (..), Physical (..), Direction (..), Entity (..), Game (..), Item (..), Player (..), State (..), X, Y, Layout, Condition (InventoryFull, InventoryContains, Not, AlwaysFalse))
|
|
import RPGEngine.Config (levelFolder)
|
|
import Data.Foldable (find)
|
|
|
|
------------------------------ Exported ------------------------------
|
|
|
|
-- Find first position of a Physical
|
|
-- Graceful exit by giving Nothing if there is nothing found.
|
|
findFirstOf :: Level -> Physical -> Maybe (X, Y)
|
|
findFirstOf l@Level{ index = index } physical = try
|
|
where matches = filter (\(x, y, v) -> v == physical) index
|
|
try | not (null matches) = Just $ (\(x, y, _) -> (x, y)) $ head matches
|
|
| otherwise = Nothing
|
|
|
|
-- What is located at a given position in the level?
|
|
findAt :: (X, Y) -> Level -> Physical
|
|
findAt pos lvl@Level{ index = index } = try
|
|
where matches = map (\(_, _, v) -> v) $ filter (\(x, y, v) -> (x, y) == pos) index
|
|
try | not (null matches) = head matches
|
|
| otherwise = Void
|
|
|
|
hasAt :: (X, Y) -> Level -> Maybe (Either Item Entity)
|
|
hasAt pos level = match firstItem firstEntity
|
|
where match :: Maybe Item -> Maybe Entity -> Maybe (Either Item Entity)
|
|
match (Just a) _ = Just $ Left a
|
|
match _ (Just a) = Just $ Right a
|
|
match _ _ = Nothing
|
|
firstEntity = find ((== pos) . getECoord) $ entities level
|
|
getECoord e = (entityX e, entityY e)
|
|
firstItem = find ((== pos) . getICoord) $ items level
|
|
getICoord i = (itemX i, itemY i)
|
|
|
|
directionOffsets :: Direction -> (X, Y)
|
|
directionOffsets North = ( 0, 1)
|
|
directionOffsets East = ( 1, 0)
|
|
directionOffsets South = ( 0, -1)
|
|
directionOffsets West = (-1, 0)
|
|
directionOffsets Stay = ( 0, 0)
|
|
|
|
getLevelList :: [FilePath]
|
|
getLevelList = drop 2 $ unsafePerformIO $ getDirectoryContents levelFolder
|
|
|
|
-- Get the actions of either an entity or an item
|
|
getActions :: Either Item Entity -> [([Condition], Action)]
|
|
getActions (Left item) = itemActions item
|
|
getActions (Right entity) = entityActions entity
|
|
|
|
getActionText :: Action -> String
|
|
getActionText Leave = "Leave"
|
|
getActionText (RetrieveItem _) = "Pick up"
|
|
getActionText (UseItem _) = "Use item"
|
|
getActionText _ = "ERROR"
|
|
|
|
-- TODO Check conditions
|
|
-- Filter based on the conditions, keep only the actions of which the
|
|
-- conditions are met.
|
|
filterActions :: [([Condition], Action)] -> [Action]
|
|
filterActions [] = []
|
|
filterActions ((conditions, action):others) = action:filterActions others
|
|
|
|
-- Check if a condition is met or not.
|
|
meetsCondition :: Condition -> Bool
|
|
meetsCondition InventoryFull = False -- TODO
|
|
meetsCondition (InventoryContains id) = True -- TODO
|
|
meetsCondition (Not condition) = not $ meetsCondition condition
|
|
meetsCondition AlwaysFalse = False |