From bbe3842a2f0a11bf5bd639da3b6bec66465e3897 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Wed, 30 Sep 2020 20:20:29 +0200 Subject: [PATCH] ui: allow loading characters directly from cli (#16) --- pqcli/__main__.py | 34 +++++++++++++++++++++++++++++++++- pqcli/ui/base.py | 10 +++++++++- pqcli/ui/basic/__init__.py | 14 +++++++++++--- pqcli/ui/curses/__init__.py | 17 ++++++++++++----- 4 files changed, 65 insertions(+), 10 deletions(-) diff --git a/pqcli/__main__.py b/pqcli/__main__.py index 3ccf910..e9e93bd 100644 --- a/pqcli/__main__.py +++ b/pqcli/__main__.py @@ -1,8 +1,11 @@ import argparse +import sys +import typing as T from pathlib import Path import xdg +from pqcli.mechanic import Player from pqcli.roster import Roster from pqcli.ui.basic import BasicUserInterface from pqcli.ui.curses import CursesUserInterface @@ -44,15 +47,44 @@ def parse_args() -> argparse.Namespace: help=argparse.SUPPRESS, ) parser.add_argument("--cheats", action="store_true", help="???") + parser.add_argument( + "--list-saves", + action="store_true", + help="list saved characters and exit", + ) + parser.add_argument( + "--load-save", + type=int, + metavar="NUM", + help="play chosen character", + ) return parser.parse_args() +def list_players(roster: Roster, file: T.Optional[T.Any] = None) -> None: + for i, player in enumerate(roster.players, start=1): + print(f"{i}. {player.name}", file=file) + + def main() -> None: args = parse_args() roster = Roster.load(SAVE_PATH) + if args.list_saves: + list_players(roster) + exit(0) + + player: T.Optional[Player] = None + if args.load_save: + try: + player = list(roster.players)[args.load_save - 1] + except IndexError: + print(f"Invalid player. Available players:", file=sys.stderr) + list_players(roster, file=sys.stderr) + exit(1) + try: - ui = args.ui(roster, args) + ui = args.ui(roster, player, args) ui.run() finally: if args.use_saves: diff --git a/pqcli/ui/base.py b/pqcli/ui/base.py index 94816e7..6f06f18 100644 --- a/pqcli/ui/base.py +++ b/pqcli/ui/base.py @@ -1,13 +1,21 @@ import abc import argparse +import typing as T +from pqcli.mechanic import Player from pqcli.roster import Roster class BaseUserInterface(abc.ABC): - def __init__(self, roster: Roster, args: argparse.Namespace) -> None: + def __init__( + self, + roster: Roster, + player: T.Optional[Player], + args: argparse.Namespace, + ) -> None: self.roster = roster self.args = args + self.player = player @abc.abstractmethod def run(self) -> None: diff --git a/pqcli/ui/basic/__init__.py b/pqcli/ui/basic/__init__.py index c83879d..4b5adcf 100644 --- a/pqcli/ui/basic/__init__.py +++ b/pqcli/ui/basic/__init__.py @@ -32,8 +32,13 @@ class MainMenu(enum.IntEnum): class BasicUserInterface(BaseUserInterface): - def __init__(self, roster: Roster, args: argparse.Namespace) -> None: - super().__init__(roster, args) + def __init__( + self, + roster: Roster, + player: T.Optional[Player], + args: argparse.Namespace, + ) -> None: + super().__init__(roster, player, args) def signal_handler(sig: T.Any, frame: T.Any) -> None: logging.info("Quitting") @@ -51,7 +56,10 @@ class BasicUserInterface(BaseUserInterface): ) self.logo() - self.main_menu() + if self.player: + self.play(self.player) + else: + self.main_menu() def logo(self) -> None: print(LOGO) diff --git a/pqcli/ui/curses/__init__.py b/pqcli/ui/curses/__init__.py index 386d632..1ed79e7 100644 --- a/pqcli/ui/curses/__init__.py +++ b/pqcli/ui/curses/__init__.py @@ -39,8 +39,10 @@ class StopMainLoop(Exception): class CursesUserInterface(BaseUserInterface): - def __init__(self, roster: Roster, args: argparse.Namespace) -> None: - super().__init__(roster, args) + def __init__( + self, roster: Roster, player: Player, args: argparse.Namespace + ) -> None: + super().__init__(roster, player, args) os.environ.setdefault("ESCDELAY", "25") self._screen = curses.initscr() self._screen.nodelay(True) @@ -77,7 +79,10 @@ class CursesUserInterface(BaseUserInterface): def run(self) -> None: try: - self._switch_to_roster_view() + if self.player: + self._switch_to_game_view(self.player) + else: + self._switch_to_roster_view() while True: key = T.cast(int, self._screen.getch()) @@ -130,8 +135,10 @@ class CursesUserInterface(BaseUserInterface): view.on_cancel += lambda: self._switch_to_create_char_race_view( player_name, race ) - view.on_confirm += lambda class_: self._switch_to_create_char_stats_view( - player_name, race, class_ + view.on_confirm += ( + lambda class_: self._switch_to_create_char_stats_view( + player_name, race, class_ + ) ) self._switch_view(view)