Allow using inventory items, and dropping items
This commit is contained in:
parent
2b708b3b7f
commit
c54ae75f08
@ -87,6 +87,11 @@ class EscapeAction(Action):
|
|||||||
raise SystemExit()
|
raise SystemExit()
|
||||||
|
|
||||||
|
|
||||||
|
class DropItem(ItemAction):
|
||||||
|
def perform(self) -> None:
|
||||||
|
self.entity.inventory.drop(self.item)
|
||||||
|
|
||||||
|
|
||||||
class WaitAction(Action):
|
class WaitAction(Action):
|
||||||
def perform(self) -> None:
|
def perform(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
@ -4,6 +4,7 @@ from typing import overload, Optional, TYPE_CHECKING
|
|||||||
|
|
||||||
import tcod.event
|
import tcod.event
|
||||||
|
|
||||||
|
import actions
|
||||||
from actions import (
|
from actions import (
|
||||||
Action,
|
Action,
|
||||||
BumpAction,
|
BumpAction,
|
||||||
@ -16,6 +17,7 @@ import exceptions
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from engine import Engine
|
from engine import Engine
|
||||||
|
from entity import Item
|
||||||
|
|
||||||
MOVE_KEYS = {
|
MOVE_KEYS = {
|
||||||
# Arrow keys
|
# Arrow keys
|
||||||
@ -94,6 +96,136 @@ class EventHandler(tcod.event.EventDispatch[Action]):
|
|||||||
self.engine.render(console)
|
self.engine.render(console)
|
||||||
|
|
||||||
|
|
||||||
|
class AskUserEventHandler(EventHandler):
|
||||||
|
"""Handles user input for actions which require special input."""
|
||||||
|
|
||||||
|
def handle_action(self, action: Optional[Action]) -> bool:
|
||||||
|
"""Return to the main event handler when a valid action was performed."""
|
||||||
|
if super().handle_action(action):
|
||||||
|
self.engine.event_handler = MainGameEventHandler(self.engine)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]:
|
||||||
|
"""By default any key exits this input handler."""
|
||||||
|
# Ignore modifier keys.
|
||||||
|
if event.sym in {
|
||||||
|
tcod.event.K_LSHIFT,
|
||||||
|
tcod.event.K_RSHIFT,
|
||||||
|
tcod.event.K_LCTRL,
|
||||||
|
tcod.event.K_RCTRL,
|
||||||
|
tcod.event.K_LALT,
|
||||||
|
tcod.event.K_RALT,
|
||||||
|
}:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return self.on_exit()
|
||||||
|
|
||||||
|
def ev_mousebuttondown(self, event: tcod.event.MouseButtonDown) -> Optional[Action]:
|
||||||
|
"""By default any mouse click exits this input handler."""
|
||||||
|
return self.on_exit()
|
||||||
|
|
||||||
|
def on_exit(self) -> Optional[Action]:
|
||||||
|
"""Called when the user is trying to exit or cancel an action.
|
||||||
|
|
||||||
|
By default this returns to the main event handler.
|
||||||
|
"""
|
||||||
|
self.engine.event_handler = MainGameEventHandler(self.engine)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class InventoryEventHandler(AskUserEventHandler):
|
||||||
|
"""This handler lets the user select an item.
|
||||||
|
|
||||||
|
What happens then depends on the subclass.
|
||||||
|
"""
|
||||||
|
|
||||||
|
TITLE = "<missing title>"
|
||||||
|
|
||||||
|
def on_render(self, console: tcod.Console) -> None:
|
||||||
|
"""Render an inventory menu, which displays the items in the inventory, and the letter
|
||||||
|
to select them. Will move to a different position based on where the player is located, so
|
||||||
|
the player can always see where they are.
|
||||||
|
"""
|
||||||
|
super().on_render(console)
|
||||||
|
number_of_items_in_inventory = len(self.engine.player.inventory.items)
|
||||||
|
|
||||||
|
height = number_of_items_in_inventory + 2
|
||||||
|
|
||||||
|
if height <= 3:
|
||||||
|
height = 3
|
||||||
|
|
||||||
|
if self.engine.player.x <= 30:
|
||||||
|
x = 40
|
||||||
|
else:
|
||||||
|
x = 0
|
||||||
|
|
||||||
|
y = 0
|
||||||
|
|
||||||
|
width = len(self.TITLE) + 4
|
||||||
|
|
||||||
|
console.draw_frame(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
title=self.TITLE,
|
||||||
|
clear=True,
|
||||||
|
fg=(255, 255, 255),
|
||||||
|
bg=(0, 0, 0),
|
||||||
|
)
|
||||||
|
|
||||||
|
if number_of_items_in_inventory > 0:
|
||||||
|
for i, item in enumerate(self.engine.player.inventory.items):
|
||||||
|
item_key = chr(ord("a") + i)
|
||||||
|
console.print(x + 1, y + i + 1, f"({item_key}) {item.name}")
|
||||||
|
else:
|
||||||
|
console.print(x + 1, y + 1, "(Empty)")
|
||||||
|
|
||||||
|
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]:
|
||||||
|
player = self.engine.player
|
||||||
|
key = event.sym
|
||||||
|
index = key - tcod.event.K_a
|
||||||
|
|
||||||
|
if 0 <= index <= 26:
|
||||||
|
try:
|
||||||
|
selected_item = player.inventory.items[index]
|
||||||
|
except IndexError:
|
||||||
|
self.engine.message_log.add_message("Invalid entry.", color.invalid)
|
||||||
|
return None
|
||||||
|
|
||||||
|
return self.on_item_selected(selected_item)
|
||||||
|
|
||||||
|
return super().ev_keydown(event)
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def on_item_selected(self, item: Item) -> Optional[Action]:
|
||||||
|
"""Called when the user selects a valid item."""
|
||||||
|
|
||||||
|
|
||||||
|
class InventoryActivateHandler(InventoryEventHandler):
|
||||||
|
"""Handle using an inventory item."""
|
||||||
|
|
||||||
|
TITLE = "Select an item to use"
|
||||||
|
|
||||||
|
def on_item_selected(self, item: Item) -> Optional[Action]:
|
||||||
|
"""Return the action for the selected item."""
|
||||||
|
return item.consumable.get_action(self.engine.player)
|
||||||
|
|
||||||
|
|
||||||
|
class InventoryDropHandler(InventoryEventHandler):
|
||||||
|
"""Handle dropping an inventory item."""
|
||||||
|
|
||||||
|
TITLE = "Select an item to drop"
|
||||||
|
|
||||||
|
def on_item_selected(self, item: Item) -> Optional[Action]:
|
||||||
|
"""Drop this item."""
|
||||||
|
return actions.DropItem(self.engine.player, item)
|
||||||
|
|
||||||
|
|
||||||
class MainGameEventHandler(EventHandler):
|
class MainGameEventHandler(EventHandler):
|
||||||
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]:
|
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]:
|
||||||
action: Optional[Action] = None
|
action: Optional[Action] = None
|
||||||
@ -117,6 +249,11 @@ class MainGameEventHandler(EventHandler):
|
|||||||
elif key == tcod.event.K_g:
|
elif key == tcod.event.K_g:
|
||||||
action = PickupAction(player)
|
action = PickupAction(player)
|
||||||
|
|
||||||
|
elif key == tcod.event.K_i:
|
||||||
|
self.engine.event_handler = InventoryActivateHandler(self.engine)
|
||||||
|
elif key == tcod.event.K_d:
|
||||||
|
self.engine.event_handler = InventoryDropHandler(self.engine)
|
||||||
|
|
||||||
# No valid key was pressed
|
# No valid key was pressed
|
||||||
return action
|
return action
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user