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)) import Graphics.Gloss.Interface.IO.Game (Key(SpecialKey), SpecialKey (KeyUp, KeyDown)) import Graphics.Gloss.Interface.IO.Interact ( SpecialKey(..), KeyState(..) ) import RPGEngine.Data.Level (getWithId) ------------------------------ 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 = increasePlayerHp iid 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 on the player 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 increasePlayerHp :: ItemId -> State -> State increasePlayerHp _ s = s -- TODO Increase playerHp -- TODO Decrease durability of item -- TODO Remove item if durability below zero