module RPGEngine.Input.ActionSelection ( handleInputActionSelection ) where import RPGEngine.Input.Core (InputHandler, handleKey, composeInputHandlers, ListSelector (selection)) import RPGEngine.Data (Game (..), State (..), Direction (..), Action (..), ItemId, EntityId, Level (..), Player (inventory, playerHp, Player), Item (..), HP) import Graphics.Gloss.Interface.IO.Game (Key(SpecialKey), SpecialKey (KeyUp, KeyDown)) import Graphics.Gloss.Interface.IO.Interact ( SpecialKey(..), KeyState(..) ) import RPGEngine.Data.Level (getWithId) import Data.Foldable (find) ------------------------------ Exported ------------------------------ handleInputActionSelection :: InputHandler Game handleInputActionSelection = composeInputHandlers [ handleKey (SpecialKey KeySpace) Down selectAction, handleKey (SpecialKey KeyUp) Down $ moveSelector North, handleKey (SpecialKey KeyDown) Down $ moveSelector South ] ---------------------------------------------------------------------- selectAction :: Game -> Game selectAction game@Game{ state = ActionSelection list selector continue } = newGame where newGame = game{ state = execute selectedAction continue } selectedAction = list !! index index = selection selector selectAction g = g -- TODO Lift this code from LevelSelection -- Move the selector either up or down moveSelector :: Direction -> Game -> Game moveSelector dir game@Game{ state = state@(ActionSelection list selector _) } = newGame where newGame = game{ state = newState } newState = state{ selector = newSelector } newSelector | constraint = selector{ selection = newSelection } | otherwise = selector constraint = 0 <= newSelection && newSelection < length list newSelection = selection selector + diff diff | dir == North = -1 | dir == South = 1 | otherwise = 0 moveSelector _ g = g{ state = Error "Something went wrong while moving the selector up or down"} ------------------------------ Actions ------------------------------- execute :: Action -> State -> State execute (RetrieveItem id ) s = pickUpItem id s execute (UseItem id ) s = useItem id s execute (DecreaseHp eid iid) s = decreaseHp eid iid s execute (IncreasePlayerHp iid) s = healedPlayer where healedPlayer = s{ player = increasePlayerHp iid (player s)} execute _ s = s -- Pick up the item with itemId and put it in the players inventory -- Should receive a Playing state pickUpItem :: ItemId -> State -> State pickUpItem id s@Playing{ level = level, player = player } = newState where (Just (Left pickedUpItem)) = getWithId id level newState = s{ level = newLevel, player = newPlayer } newLevel = level{ items = filteredItems } filteredItems = filter (/= pickedUpItem) $ items level newPlayer = player{ inventory = newInventory } newInventory = pickedUpItem:inventory player pickUpItem _ _ = Error "Something went wrong while picking up an item" -- Use an item useItem :: ItemId -> State -> State -- TODO useItem _ s = s -- TODO -- Attack an entity using an item decreaseHp :: EntityId -> ItemId -> State -> State decreaseHp _ _ s = s -- TODO DecreaseHp of monster -- TODO Check if monster is dead -- TODO Entity attack player -- TODO Decrease durability of item -- TODO Break item if durability below zero -- Heal a bit -- Should receive a Player increasePlayerHp :: ItemId -> Player -> Player increasePlayerHp id p@Player{ playerHp = hp, inventory = inventory} = newPlayer where newPlayer = p{ playerHp = newHp, inventory = newInventory newItem } (Just usedItem) = find ((== id) . itemId) inventory newItem = decreaseDurability usedItem newInventory (Just item) = item:filteredInventory newInventory _ = filteredInventory filteredInventory =filter (/= usedItem) inventory newHp = changeHealth hp (itemValue usedItem) decreaseDurability :: Item -> Maybe Item decreaseDurability item@Item{ useTimes = Nothing } = Just item -- Infinite uses, never breaks decreaseDurability item@Item{ useTimes = Just val } | 0 < val - 1 = Just item{ useTimes = Just (val - 1) } | otherwise = Nothing -- Broken -- Change given health by a given amount changeHealth :: HP -> HP -> HP changeHealth (Just health) (Just difference) = Just (health + difference) changeHealth health _ = health