2022-01-02 17:50:33 +00:00
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Optional, TYPE_CHECKING
|
2022-01-02 15:23:25 +00:00
|
|
|
|
|
|
|
import tcod.event
|
|
|
|
|
2022-01-02 21:43:44 +00:00
|
|
|
from actions import Action, EscapeAction, BumpAction, WaitAction
|
|
|
|
|
2022-01-02 17:50:33 +00:00
|
|
|
if TYPE_CHECKING:
|
|
|
|
from engine import Engine
|
2022-01-02 15:23:25 +00:00
|
|
|
|
2022-01-02 21:43:44 +00:00
|
|
|
MOVE_KEYS = {
|
|
|
|
# Arrow keys.
|
|
|
|
tcod.event.K_UP: (0, -1),
|
|
|
|
tcod.event.K_DOWN: (0, 1),
|
|
|
|
tcod.event.K_LEFT: (-1, 0),
|
|
|
|
tcod.event.K_RIGHT: (1, 0),
|
|
|
|
tcod.event.K_HOME: (-1, -1),
|
|
|
|
tcod.event.K_END: (-1, 1),
|
|
|
|
tcod.event.K_PAGEUP: (1, -1),
|
|
|
|
tcod.event.K_PAGEDOWN: (1, 1),
|
|
|
|
# Numpad keys.
|
|
|
|
tcod.event.K_KP_1: (-1, 1),
|
|
|
|
tcod.event.K_KP_2: (0, 1),
|
|
|
|
tcod.event.K_KP_3: (1, 1),
|
|
|
|
tcod.event.K_KP_4: (-1, 0),
|
|
|
|
tcod.event.K_KP_6: (1, 0),
|
|
|
|
tcod.event.K_KP_7: (-1, -1),
|
|
|
|
tcod.event.K_KP_8: (0, -1),
|
|
|
|
tcod.event.K_KP_9: (1, -1),
|
|
|
|
# Vi keys.
|
|
|
|
tcod.event.K_h: (-1, 0),
|
|
|
|
tcod.event.K_j: (0, 1),
|
|
|
|
tcod.event.K_k: (0, -1),
|
|
|
|
tcod.event.K_l: (1, 0),
|
|
|
|
tcod.event.K_y: (-1, -1),
|
|
|
|
tcod.event.K_u: (1, -1),
|
|
|
|
tcod.event.K_b: (-1, 1),
|
|
|
|
tcod.event.K_n: (1, 1),
|
|
|
|
}
|
|
|
|
|
|
|
|
WAIT_KEYS = {
|
|
|
|
tcod.event.K_PERIOD,
|
|
|
|
tcod.event.K_KP_5,
|
|
|
|
tcod.event.K_CLEAR,
|
|
|
|
}
|
|
|
|
|
2022-01-02 15:23:25 +00:00
|
|
|
|
|
|
|
class EventHandler(tcod.event.EventDispatch[Action]):
|
2022-01-02 17:50:33 +00:00
|
|
|
def __init__(self, engine: Engine):
|
|
|
|
self.engine = engine
|
|
|
|
|
2022-01-02 21:43:44 +00:00
|
|
|
def handle_events(self) -> None:
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
def ev_quit(self, event: tcod.event.Quit) -> Optional[Action]:
|
|
|
|
raise SystemExit()
|
|
|
|
|
|
|
|
|
|
|
|
class MainGameEventHandler(EventHandler):
|
2022-01-02 17:50:33 +00:00
|
|
|
def handle_events(self) -> None:
|
|
|
|
for event in tcod.event.wait():
|
|
|
|
action = self.dispatch(event)
|
|
|
|
|
|
|
|
if action is None:
|
|
|
|
continue
|
|
|
|
|
|
|
|
action.perform()
|
|
|
|
self.engine.handle_enemy_turns()
|
|
|
|
self.engine.update_fov()
|
|
|
|
|
2022-01-02 15:23:25 +00:00
|
|
|
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]:
|
|
|
|
action: Optional[Action] = None
|
|
|
|
|
|
|
|
key = event.sym
|
2022-01-02 17:50:33 +00:00
|
|
|
player = self.engine.player
|
2022-01-02 15:23:25 +00:00
|
|
|
|
2022-01-02 21:43:44 +00:00
|
|
|
if key in MOVE_KEYS:
|
|
|
|
dx, dy = MOVE_KEYS[key]
|
|
|
|
action = BumpAction(player, dx, dy)
|
|
|
|
elif key == WAIT_KEYS:
|
|
|
|
action = WaitAction(player)
|
|
|
|
|
|
|
|
return action
|
|
|
|
|
|
|
|
class GameOverEventHandler(EventHandler):
|
|
|
|
def handle_events(self) -> None:
|
|
|
|
for event in tcod.event.wait():
|
|
|
|
action = self.dispatch(event)
|
|
|
|
|
|
|
|
if action is None:
|
|
|
|
continue
|
|
|
|
|
|
|
|
action.perform()
|
|
|
|
|
|
|
|
def ev_keydown(self, event: tcode.event.KeyDown) -> Optional[Action]:
|
|
|
|
action: Optional[Action] = None
|
|
|
|
|
|
|
|
key = event.sym
|
|
|
|
|
|
|
|
if key == tcod.event.K_ESCAPE:
|
|
|
|
action = EscapeAction(self.engine.player)
|
2022-01-02 15:23:25 +00:00
|
|
|
|
|
|
|
return action
|