diff options
author | Griffin Smith <root@gws.fyi> | 2019-11-30T03·59-0500 |
---|---|---|
committer | Griffin Smith <root@gws.fyi> | 2019-11-30T03·59-0500 |
commit | 8a1235c3dcf7fe69b2e2ea3eea326858d26d38b9 (patch) | |
tree | 398c6dce549602c9890fbded64e3bdf2646b2a1f /src/Xanthous/App.hs | |
parent | 7d8ce026a2acc5a4d208110750be188f0ce5591c (diff) |
Use menus for combat and picking up items
Refactor a bunch of stuff around to allow for polymorphically surfacing an EntityChar for all entities, and use this to write a generic `entityMenu` function, which generates a menu from the chars of a list of entities - and use that to fully implement (removing `undefined`) menus for both attacking and picking things up when there are multiple entities on the relevant tile.
Diffstat (limited to 'src/Xanthous/App.hs')
-rw-r--r-- | src/Xanthous/App.hs | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/src/Xanthous/App.hs b/src/Xanthous/App.hs index 13c4af1246d5..76e03e860999 100644 --- a/src/Xanthous/App.hs +++ b/src/Xanthous/App.hs @@ -30,6 +30,7 @@ import Xanthous.Data import Xanthous.Data.EntityMap (EntityMap) import qualified Xanthous.Data.EntityMap as EntityMap import Xanthous.Game +import Xanthous.Game.State import Xanthous.Game.Draw (drawGame) import Xanthous.Game.Prompt import Xanthous.Monad @@ -38,8 +39,7 @@ import qualified Xanthous.Messages as Messages import Xanthous.Util.Inflection (toSentence) -------------------------------------------------------------------------------- import qualified Xanthous.Entities.Character as Character -import Xanthous.Entities.Character -import Xanthous.Entities +import Xanthous.Entities.Character hiding (pickUpItem) import Xanthous.Entities.Item (Item) import qualified Xanthous.Entities.Item as Item import Xanthous.Entities.Creature (Creature) @@ -138,16 +138,19 @@ handleCommand (Move dir) = do handleCommand PickUp = do pos <- use characterPosition - items <- uses entities $ entitiesAtPositionWithType @Item pos - case items of - [] -> say_ ["items", "nothingToPickUp"] - [(itemID, item)] -> do + uses entities (entitiesAtPositionWithType @Item pos) >>= \case + [] -> say_ ["pickUp", "nothingToPickUp"] + [item] -> pickUpItem item + items -> + menu_ ["pickUp", "menu"] Cancellable (entityMenu_ items) + $ \(MenuResult item) -> pickUpItem item + continue + where + pickUpItem (itemID, item) = do character %= Character.pickUpItem item entities . at itemID .= Nothing - say ["items", "pickUp"] $ object [ "item" A..= item ] + say ["pickUp", "pickUp"] $ object [ "item" A..= item ] stepGameBy 100 -- TODO - _ -> undefined - continue handleCommand PreviousMessage = do messageHistory %= previousMessage @@ -188,6 +191,7 @@ handleCommand Eat = do let foodMenuItem idx (item, edibleItem) = ( item ^. Item.itemType . char . char , MenuOption (description item) (idx, item, edibleItem)) + -- TODO refactor to use entityMenu_ menuItems = mkMenuItems $ imap foodMenuItem food in menu_ ["eat", "menuPrompt"] Cancellable menuItems $ \(MenuResult (idx, item, edibleItem)) -> do @@ -265,6 +269,8 @@ handlePromptEvent >> continue handlePromptEvent _ (Prompt _ SPointOnMap _ _ _) _ = continue +handlePromptEvent _ _ _ = continue + clearPrompt :: AppM (Next GameState) clearPrompt = promptState .= NoPrompt >> continue @@ -330,7 +336,6 @@ menu_ :: forall (a :: Type). -> AppM () menu_ msgPath = menu msgPath $ object [] - -------------------------------------------------------------------------------- entitiesAtPositionWithType @@ -374,7 +379,9 @@ attackAt pos = uses entities (entitiesAtPositionWithType @Creature pos) >>= \case Empty -> say_ ["combat", "nothingToAttack"] (creature :< Empty) -> attackCreature creature - creatures -> undefined + creatures -> + menu_ ["combat", "menu"] Cancellable (entityMenu_ creatures) + $ \(MenuResult creature) -> attackCreature creature where attackCreature (creatureID, creature) = do charDamage <- use $ character . characterDamage @@ -388,3 +395,21 @@ attackAt pos = say ["combat", "hit"] msgParams entities . ix creatureID . positioned .= SomeEntity creature' stepGame -- TODO + +entityMenu_ + :: (Comonad w, Entity entity) + => [w entity] + -> Map Char (MenuOption (w entity)) +entityMenu_ = mkMenuItems @[_] . map entityMenuItem + where + entityMenuItem wentity + = let entity = extract wentity + in (entityMenuChar entity, MenuOption (description entity) wentity) + entityMenuChar entity + = let ec = entityChar entity ^. char + in if ec `elem` (['a'..'z'] ++ ['A'..'Z']) + then ec + else 'a' + +entityMenu :: Entity entity => [entity] -> Map Char (MenuOption entity) +entityMenu = map (map runIdentity) . entityMenu_ . fmap Identity |