Module botroyale.api.gui
A collection of classes used by the GUI.
All classes in this module are the object types that the GUI will request when
calling certain methods of GameAPI
and
BattleAPI
.
Expand source code Browse git
"""A collection of classes used by the GUI.
All classes in this module are the object types that the GUI will request when
calling certain methods of `botroyale.api.gui.GameAPI` and
`botroyale.api.gui.BattleAPI`.
"""
from typing import (
Optional,
Union,
Literal,
Sequence,
NamedTuple,
Any,
Callable,
)
from collections import deque
from itertools import chain
from dataclasses import dataclass, asdict as dataclass_asdict
from botroyale.util.hexagon import Hexagon, ORIGIN
from botroyale.api.logging import logger as glogger
PALETTE = (
(0.73, 0.97, 0.92), # bright cyan
(0.68, 0.85, 0.88), # dark cyan
(0.62, 0.63, 0.76), # purple blue
(0.24, 0.32, 0.48), # dark blue
(0.86, 0.60, 0.35), # orange
)
PALETTE_BG = tuple(tuple(_ / 2 for _ in c) for c in PALETTE)
class Control(NamedTuple):
"""Represents a control the user may use to invoke a callback.
Used for buttons and hotkeys.
"""
label: str
"""Name of the control function (e.g. 'Start new battle')."""
callback: Callable[[], None]
"""Callback when the control is invoked."""
hotkey: Optional[str] = None
"""
Optionally specify to allow invoking this control with the hotkey.
The hotkey is a string with a simple format:
`f'{key}'` or `f'{mods} {key}'`
Where *key* is the keyboard character and *mods* is a string with a
combination of `'^'` for control, `'+'` for shift, `'!'` for alt, and
`'#'` for super (winkey).
E.g.
`g` - The "g" key
`spacebar` - The spacebar
`f1` - The "F1" key
`^+ a` - Control + Shift + a
"""
# The ControlMenu type is a dictionary of menu names and Control lists
ControlMenu = dict[str, list[Control]]
class ControlMenu_:
"""A type alias for `dict[str, list[Control]]`.
Represents a dictionary mapping a menu name to a list of `Control` objects
for that menu.
See also: `combine_control_menus`.
```python
def get_control_menu() -> ControlMenu:
return {
'Actions': [
Control('Idle', _do_idle, hotkey='^ i'),
Control('Move', _do_move, hotkey='^ m'),
],
'Cheats': [
Control('God mode', _cheat_god_mode, hotkey='^+ g'),
Control('Inifinte AP', _cheat_inf_ap),
],
}
```
.. admonition:: Note
Documented under `ControlMenu_` instead of `ControlMenu` because assigning
docstrings to nested type aliases will break the docs.
"""
def combine_control_menus(
control_menu1: ControlMenu,
control_menu2: ControlMenu,
) -> ControlMenu:
"""Return a `ControlMenu_` with items from *control_menu1* and *control_menu2*."""
new_control_menu = {}
for menu_name, controls in chain(control_menu1.items(), control_menu2.items()):
if menu_name in new_control_menu:
new_control_menu[menu_name].extend(controls)
else:
new_control_menu[menu_name] = [*controls]
return new_control_menu
@dataclass
class InputWidget:
"""Represents an input widget in the GUI.
Widget types include:
* `spacer` - has a label but no value
* `toggle` - toggle button (boolean value)
* `text` - arbitrary text input (string value)
* `select` - select from list (string value, must supply *options*)
* `slider` - a slider (float value)
* `divider` - like `spacer` but creates a new section
"""
label: str
"""Text to place near the widget."""
type: Literal["spacer", "toggle", "text", "select", "slider", "divider"]
"""Type of widget."""
default: Any = None
"""Starting value of the widget (default: None)."""
sendto: Optional[str] = None
"""
Name of value (default is to use the same value of *label*).
This is used by the GUI to map the value of the widget to a key in a
dictionary. See `GameAPI.get_new_battle`.
"""
options: Optional[Sequence[str]] = None
"""List of strings, required only by `select` widgets."""
def __post_init__(self):
"""Initialize the dataclass."""
if self.type == "select":
assert self.options
if self.sendto is None:
self.sendto = self.label
if self.default is None:
if self.type == "toggle":
self.default = False
elif self.type == "text":
self.default = ""
elif self.type == "select":
self.default = self.options[0]
elif self.type == "slider":
self.default = 0.0
@dataclass
class Tile:
"""Represents how a hex on the tilemap should be drawn."""
tile: Optional[str] = None
"""Sprite name of the tile itself."""
bg: tuple[float, float, float] = 0, 0, 0
"""Tile (background) color."""
sprite: Optional[str] = None
"""Sprite name to draw on top of the tile."""
color: tuple[float, float, float] = 0.5, 0.5, 0.5
"""Sprite color."""
text: Optional[str] = None
"""Text to draw on the tile."""
@dataclass
class VFX:
"""Represents a visual effect to be drawn on the tilemap."""
name: str
"""Name of vfx image (with .png extension)."""
hex: Hexagon
"""Hex of image center."""
direction: Hexagon
"""Hex to indicate direction for image rotation."""
start_step: Union[int, float]
"""In-game time before which the vfx expires."""
expire_step: Union[int, float]
"""In-game time after which the vfx expires."""
expire_seconds: float
"""Real-time seconds after which the vfx expires."""
def asdict(self):
"""Equivalent to passing *self* to `dataclasses.dataclass_asdict`."""
return dataclass_asdict(self)
class BattleAPI:
"""Base class for the API between the GUI's main menu and the logic.
Used to draw and control the battle. Battles are created using the
`GameAPI.get_new_battle` method, which returns a `BattleAPI` object.
"""
def __init__(self):
"""Initialize the class."""
self.__vfx_queue = deque()
self.__clear_vfx_flag = False
# GUI API
def update(self):
"""Called continuously (every frame) by the GUI."""
pass
def get_time(self) -> Union[int, float]:
"""In-game time. Used by the GUI to determine when vfx need to expire."""
return 0
def get_controls(self) -> ControlMenu:
"""Returns a `ControlMenu_` for buttons and hotkeys in GUI."""
return {
"Battle": [
Control("Foo", lambda: glogger("foo"), "f"),
Control("Bar", lambda: glogger("bar"), "b"),
]
}
# Info panel
def get_info_panel_text(self) -> str:
"""Multiline string to display in the info panel.
Used for displaying a summary of the current game state.
"""
return "Panel text placeholder"
def get_info_panel_color(self) -> tuple[float, float, float]:
"""Color of the info panel in GUI."""
return (0.1, 0.1, 0.1)
# Tile map
def get_gui_tile_info(self, hex: Hexagon) -> Tile:
"""Returns a `Tile` representing how to display *hex* in the GUI.
Called by the GUI for every hex currently visible on the map.
"""
return Tile(
bg=(0.1, 0.1, 0.1),
color=(0.25, 0.25, 0.25),
sprite="hex",
text="" if hex != ORIGIN else "Origin",
)
def get_map_size_hint(self) -> Union[int, float]:
"""The radius of the map size for the GUI to display."""
return 5
def handle_hex_click(self, hex: Hexagon, button: str, mods: str):
"""Called when a tile is clicked on in the GUI.
Args:
hex: The hex that was clicked.
button: One of "left", "right", "middle", "mouse1", "mouse2", etc.
mods: A string of keyboard modifiers that were pressed when the
mouse was clicked.
- `^` control
- `+` shift
- `!` alt
- `#` meta ("win" key)
- `^+` control + shift
"""
glogger(f"Clicked {button} on: {hex}")
if button == "left":
vfx = "mark-green"
elif button == "right":
vfx = "mark-red"
else:
vfx = "mark-blue"
self.add_vfx(vfx, hex)
# VFX
def add_vfx(
self,
name: str,
hex: Hexagon,
direction: Optional[Hexagon] = None,
steps: int = 1,
expire_seconds: Optional[float] = None,
):
"""Add a single vfx to the queue.
See `VFX` for details on the arguments.
"""
assert isinstance(name, str)
assert isinstance(hex, Hexagon)
if direction is not None:
assert isinstance(direction, Hexagon)
start_step = self.get_time()
expire_step = start_step + steps
self.__vfx_queue.append(
VFX(
name,
hex,
direction,
start_step,
expire_step,
expire_seconds,
)
)
def clear_vfx_flag(self) -> bool:
"""Called by the GUI to check if existing VFX need to be cleared.
Returns:
False, unless the flag has been raised (by calling
`BattleAPI.clear_vfx` with `clear_existing=True`) -- in which
case this method will drop the flag and return True.
"""
if self.__clear_vfx_flag:
self.__clear_vfx_flag = False
return True
return False
def clear_vfx(self, flush_queued: bool = True, clear_existing: bool = True):
"""Clears vfx that are queued or already drawn.
Args:
flush_queued: Clears VFX that have been queued but not yet drawn.
clear_existing: Clears VFX that have already been drawn.
"""
if flush_queued:
self.flush_vfx()
if clear_existing:
self.__clear_vfx_flag = True
def flush_vfx(self) -> Sequence[VFX]:
"""Clears and returns the vfx from queue."""
r = self.__vfx_queue
self.__vfx_queue = deque()
return r
class GameAPI:
"""Base class for the API between the GUI's main menu and the logic.
Used to populate the main menu and start battles. Battles are created using
the `GameAPI.get_new_battle` method, which returns a `BattleAPI` object.
"""
def get_new_battle(self, menu_values: dict[str, Any]) -> Union[BattleAPI, None]:
"""Called by the GUI when the user requests to start a new battle.
Args:
menu_values: Dictionary that maps each InputWidget's `sendto` name
to the widget's value. See `GameAPI.get_menu_widgets` and
`InputWidget`.
Returns:
`BattleAPI` (or None if we decide not to start a new battle).
"""
return BattleAPI()
def get_info_panel_text(self) -> str:
"""Returns the string to be displayed in the menu info panel."""
return "Main Menu"
def get_menu_widgets(self) -> list[InputWidget]:
"""Returns a list of InputWidgets to populate the main menu.
The values of these widgets are passed to get_new_battle.
"""
return []
def get_controls(self) -> ControlMenu:
"""Returns a `ControlMenu_` for buttons and hotkeys in GUI."""
return {}
def handle_menu_widget(
self,
widgets: list[str],
menu_values: dict[str, Any],
) -> bool:
"""Called by the GUI when the user interacts with `InputWidget`s.
This will be called without arguments if the user refreshes the menu.
Args:
widgets: The `sendto` names of the widgets that were interacted with.
menu_values: Dictionary that maps each InputWidget's `sendto` name
to the widget's value. See `GameAPI.get_menu_widgets` and
`InputWidget`.
Returns:
True if we wish the GUI to reset the main menu, by calling
`GameAPI.get_info_panel_text` and `GameAPI.get_menu_widgets`.
"""
return False
Functions
-
Return a
ControlMenu_
with items from control_menu1 and control_menu2.Expand source code Browse git
def combine_control_menus( control_menu1: ControlMenu, control_menu2: ControlMenu, ) -> ControlMenu: """Return a `ControlMenu_` with items from *control_menu1* and *control_menu2*.""" new_control_menu = {} for menu_name, controls in chain(control_menu1.items(), control_menu2.items()): if menu_name in new_control_menu: new_control_menu[menu_name].extend(controls) else: new_control_menu[menu_name] = [*controls] return new_control_menu
Classes
class BattleAPI
-
Base class for the API between the GUI's main menu and the logic.
Used to draw and control the battle. Battles are created using the
GameAPI.get_new_battle()
method, which returns aBattleAPI
object.Initialize the class.
Expand source code Browse git
class BattleAPI: """Base class for the API between the GUI's main menu and the logic. Used to draw and control the battle. Battles are created using the `GameAPI.get_new_battle` method, which returns a `BattleAPI` object. """ def __init__(self): """Initialize the class.""" self.__vfx_queue = deque() self.__clear_vfx_flag = False # GUI API def update(self): """Called continuously (every frame) by the GUI.""" pass def get_time(self) -> Union[int, float]: """In-game time. Used by the GUI to determine when vfx need to expire.""" return 0 def get_controls(self) -> ControlMenu: """Returns a `ControlMenu_` for buttons and hotkeys in GUI.""" return { "Battle": [ Control("Foo", lambda: glogger("foo"), "f"), Control("Bar", lambda: glogger("bar"), "b"), ] } # Info panel def get_info_panel_text(self) -> str: """Multiline string to display in the info panel. Used for displaying a summary of the current game state. """ return "Panel text placeholder" def get_info_panel_color(self) -> tuple[float, float, float]: """Color of the info panel in GUI.""" return (0.1, 0.1, 0.1) # Tile map def get_gui_tile_info(self, hex: Hexagon) -> Tile: """Returns a `Tile` representing how to display *hex* in the GUI. Called by the GUI for every hex currently visible on the map. """ return Tile( bg=(0.1, 0.1, 0.1), color=(0.25, 0.25, 0.25), sprite="hex", text="" if hex != ORIGIN else "Origin", ) def get_map_size_hint(self) -> Union[int, float]: """The radius of the map size for the GUI to display.""" return 5 def handle_hex_click(self, hex: Hexagon, button: str, mods: str): """Called when a tile is clicked on in the GUI. Args: hex: The hex that was clicked. button: One of "left", "right", "middle", "mouse1", "mouse2", etc. mods: A string of keyboard modifiers that were pressed when the mouse was clicked. - `^` control - `+` shift - `!` alt - `#` meta ("win" key) - `^+` control + shift """ glogger(f"Clicked {button} on: {hex}") if button == "left": vfx = "mark-green" elif button == "right": vfx = "mark-red" else: vfx = "mark-blue" self.add_vfx(vfx, hex) # VFX def add_vfx( self, name: str, hex: Hexagon, direction: Optional[Hexagon] = None, steps: int = 1, expire_seconds: Optional[float] = None, ): """Add a single vfx to the queue. See `VFX` for details on the arguments. """ assert isinstance(name, str) assert isinstance(hex, Hexagon) if direction is not None: assert isinstance(direction, Hexagon) start_step = self.get_time() expire_step = start_step + steps self.__vfx_queue.append( VFX( name, hex, direction, start_step, expire_step, expire_seconds, ) ) def clear_vfx_flag(self) -> bool: """Called by the GUI to check if existing VFX need to be cleared. Returns: False, unless the flag has been raised (by calling `BattleAPI.clear_vfx` with `clear_existing=True`) -- in which case this method will drop the flag and return True. """ if self.__clear_vfx_flag: self.__clear_vfx_flag = False return True return False def clear_vfx(self, flush_queued: bool = True, clear_existing: bool = True): """Clears vfx that are queued or already drawn. Args: flush_queued: Clears VFX that have been queued but not yet drawn. clear_existing: Clears VFX that have already been drawn. """ if flush_queued: self.flush_vfx() if clear_existing: self.__clear_vfx_flag = True def flush_vfx(self) -> Sequence[VFX]: """Clears and returns the vfx from queue.""" r = self.__vfx_queue self.__vfx_queue = deque() return r
Subclasses
Methods
def add_vfx(self, name: str, hex: Hexagon, direction: Optional[Hexagon] = None, steps: int = 1, expire_seconds: Optional[float] = None)
-
Add a single vfx to the queue.
See
VFX
for details on the arguments.Expand source code Browse git
def add_vfx( self, name: str, hex: Hexagon, direction: Optional[Hexagon] = None, steps: int = 1, expire_seconds: Optional[float] = None, ): """Add a single vfx to the queue. See `VFX` for details on the arguments. """ assert isinstance(name, str) assert isinstance(hex, Hexagon) if direction is not None: assert isinstance(direction, Hexagon) start_step = self.get_time() expire_step = start_step + steps self.__vfx_queue.append( VFX( name, hex, direction, start_step, expire_step, expire_seconds, ) )
def clear_vfx(self, flush_queued: bool = True, clear_existing: bool = True)
-
Clears vfx that are queued or already drawn.
Args
flush_queued
- Clears VFX that have been queued but not yet drawn.
clear_existing
- Clears VFX that have already been drawn.
Expand source code Browse git
def clear_vfx(self, flush_queued: bool = True, clear_existing: bool = True): """Clears vfx that are queued or already drawn. Args: flush_queued: Clears VFX that have been queued but not yet drawn. clear_existing: Clears VFX that have already been drawn. """ if flush_queued: self.flush_vfx() if clear_existing: self.__clear_vfx_flag = True
def clear_vfx_flag(self) ‑> bool
-
Called by the GUI to check if existing VFX need to be cleared.
Returns
False, unless the flag has been raised (by calling
BattleAPI.clear_vfx()
withclear_existing=True
) – in which case this method will drop the flag and return True.Expand source code Browse git
def clear_vfx_flag(self) -> bool: """Called by the GUI to check if existing VFX need to be cleared. Returns: False, unless the flag has been raised (by calling `BattleAPI.clear_vfx` with `clear_existing=True`) -- in which case this method will drop the flag and return True. """ if self.__clear_vfx_flag: self.__clear_vfx_flag = False return True return False
def flush_vfx(self) ‑> Sequence[VFX]
-
Clears and returns the vfx from queue.
Expand source code Browse git
def flush_vfx(self) -> Sequence[VFX]: """Clears and returns the vfx from queue.""" r = self.__vfx_queue self.__vfx_queue = deque() return r
def get_controls(self) ‑> dict[str, list[Control]]
-
Returns a
ControlMenu_
for buttons and hotkeys in GUI.Expand source code Browse git
def get_controls(self) -> ControlMenu: """Returns a `ControlMenu_` for buttons and hotkeys in GUI.""" return { "Battle": [ Control("Foo", lambda: glogger("foo"), "f"), Control("Bar", lambda: glogger("bar"), "b"), ] }
def get_gui_tile_info(self, hex: Hexagon) ‑> Tile
-
Returns a
Tile
representing how to display hex in the GUI.Called by the GUI for every hex currently visible on the map.
Expand source code Browse git
def get_gui_tile_info(self, hex: Hexagon) -> Tile: """Returns a `Tile` representing how to display *hex* in the GUI. Called by the GUI for every hex currently visible on the map. """ return Tile( bg=(0.1, 0.1, 0.1), color=(0.25, 0.25, 0.25), sprite="hex", text="" if hex != ORIGIN else "Origin", )
def get_info_panel_color(self) ‑> tuple[float, float, float]
-
Color of the info panel in GUI.
Expand source code Browse git
def get_info_panel_color(self) -> tuple[float, float, float]: """Color of the info panel in GUI.""" return (0.1, 0.1, 0.1)
def get_info_panel_text(self) ‑> str
-
Multiline string to display in the info panel.
Used for displaying a summary of the current game state.
Expand source code Browse git
def get_info_panel_text(self) -> str: """Multiline string to display in the info panel. Used for displaying a summary of the current game state. """ return "Panel text placeholder"
def get_map_size_hint(self) ‑> Union[int, float]
-
The radius of the map size for the GUI to display.
Expand source code Browse git
def get_map_size_hint(self) -> Union[int, float]: """The radius of the map size for the GUI to display.""" return 5
def get_time(self) ‑> Union[int, float]
-
In-game time. Used by the GUI to determine when vfx need to expire.
Expand source code Browse git
def get_time(self) -> Union[int, float]: """In-game time. Used by the GUI to determine when vfx need to expire.""" return 0
def handle_hex_click(self, hex: Hexagon, button: str, mods: str)
-
Called when a tile is clicked on in the GUI.
Args
hex
- The hex that was clicked.
button
- One of "left", "right", "middle", "mouse1", "mouse2", etc.
mods
-
A string of keyboard modifiers that were pressed when the mouse was clicked.
^
control+
shift!
alt#
meta ("win" key)^+
control + shift
Expand source code Browse git
def handle_hex_click(self, hex: Hexagon, button: str, mods: str): """Called when a tile is clicked on in the GUI. Args: hex: The hex that was clicked. button: One of "left", "right", "middle", "mouse1", "mouse2", etc. mods: A string of keyboard modifiers that were pressed when the mouse was clicked. - `^` control - `+` shift - `!` alt - `#` meta ("win" key) - `^+` control + shift """ glogger(f"Clicked {button} on: {hex}") if button == "left": vfx = "mark-green" elif button == "right": vfx = "mark-red" else: vfx = "mark-blue" self.add_vfx(vfx, hex)
def update(self)
-
Called continuously (every frame) by the GUI.
Expand source code Browse git
def update(self): """Called continuously (every frame) by the GUI.""" pass
class Control (label: str, callback: Callable[[], None], hotkey: Optional[str] = None)
-
Represents a control the user may use to invoke a callback.
Used for buttons and hotkeys.
Expand source code Browse git
class Control(NamedTuple): """Represents a control the user may use to invoke a callback. Used for buttons and hotkeys. """ label: str """Name of the control function (e.g. 'Start new battle').""" callback: Callable[[], None] """Callback when the control is invoked.""" hotkey: Optional[str] = None """ Optionally specify to allow invoking this control with the hotkey. The hotkey is a string with a simple format: `f'{key}'` or `f'{mods} {key}'` Where *key* is the keyboard character and *mods* is a string with a combination of `'^'` for control, `'+'` for shift, `'!'` for alt, and `'#'` for super (winkey). E.g. `g` - The "g" key `spacebar` - The spacebar `f1` - The "F1" key `^+ a` - Control + Shift + a """
Ancestors
- builtins.tuple
Instance variables
var callback : Callable[[], None]
-
Callback when the control is invoked.
var hotkey : Optional[str]
-
Optionally specify to allow invoking this control with the hotkey.
The hotkey is a string with a simple format:
f'{key}'
orf'{mods} {key}'
Where key is the keyboard character and mods is a string with a combination of
'^'
for control,'+'
for shift,'!'
for alt, and'#'
for super (winkey).E.g.
g
- The "g" keyspacebar
- The spacebarf1
- The "F1" key^+ a
- Control + Shift + a var label : str
-
Name of the control function (e.g. 'Start new battle').
class ControlMenu_
-
A type alias for
dict[str, list[Control]]
.Represents a dictionary mapping a menu name to a list of
Control
objects for that menu.See also:
combine_control_menus()
.def get_control_menu() -> ControlMenu: return { 'Actions': [ Control('Idle', _do_idle, hotkey='^ i'), Control('Move', _do_move, hotkey='^ m'), ], 'Cheats': [ Control('God mode', _cheat_god_mode, hotkey='^+ g'), Control('Inifinte AP', _cheat_inf_ap), ], }
Note
Documented under
ControlMenu_
instead ofControlMenu
because assigning docstrings to nested type aliases will break the docs.Expand source code Browse git
class ControlMenu_: """A type alias for `dict[str, list[Control]]`. Represents a dictionary mapping a menu name to a list of `Control` objects for that menu. See also: `combine_control_menus`. ```python def get_control_menu() -> ControlMenu: return { 'Actions': [ Control('Idle', _do_idle, hotkey='^ i'), Control('Move', _do_move, hotkey='^ m'), ], 'Cheats': [ Control('God mode', _cheat_god_mode, hotkey='^+ g'), Control('Inifinte AP', _cheat_inf_ap), ], } ``` .. admonition:: Note Documented under `ControlMenu_` instead of `ControlMenu` because assigning docstrings to nested type aliases will break the docs. """
class GameAPI
-
Base class for the API between the GUI's main menu and the logic.
Used to populate the main menu and start battles. Battles are created using the
GameAPI.get_new_battle()
method, which returns aBattleAPI
object.Expand source code Browse git
class GameAPI: """Base class for the API between the GUI's main menu and the logic. Used to populate the main menu and start battles. Battles are created using the `GameAPI.get_new_battle` method, which returns a `BattleAPI` object. """ def get_new_battle(self, menu_values: dict[str, Any]) -> Union[BattleAPI, None]: """Called by the GUI when the user requests to start a new battle. Args: menu_values: Dictionary that maps each InputWidget's `sendto` name to the widget's value. See `GameAPI.get_menu_widgets` and `InputWidget`. Returns: `BattleAPI` (or None if we decide not to start a new battle). """ return BattleAPI() def get_info_panel_text(self) -> str: """Returns the string to be displayed in the menu info panel.""" return "Main Menu" def get_menu_widgets(self) -> list[InputWidget]: """Returns a list of InputWidgets to populate the main menu. The values of these widgets are passed to get_new_battle. """ return [] def get_controls(self) -> ControlMenu: """Returns a `ControlMenu_` for buttons and hotkeys in GUI.""" return {} def handle_menu_widget( self, widgets: list[str], menu_values: dict[str, Any], ) -> bool: """Called by the GUI when the user interacts with `InputWidget`s. This will be called without arguments if the user refreshes the menu. Args: widgets: The `sendto` names of the widgets that were interacted with. menu_values: Dictionary that maps each InputWidget's `sendto` name to the widget's value. See `GameAPI.get_menu_widgets` and `InputWidget`. Returns: True if we wish the GUI to reset the main menu, by calling `GameAPI.get_info_panel_text` and `GameAPI.get_menu_widgets`. """ return False
Subclasses
Methods
def get_controls(self) ‑> dict[str, list[Control]]
-
Returns a
ControlMenu_
for buttons and hotkeys in GUI.Expand source code Browse git
def get_controls(self) -> ControlMenu: """Returns a `ControlMenu_` for buttons and hotkeys in GUI.""" return {}
def get_info_panel_text(self) ‑> str
-
Returns the string to be displayed in the menu info panel.
Expand source code Browse git
def get_info_panel_text(self) -> str: """Returns the string to be displayed in the menu info panel.""" return "Main Menu"
-
Returns a list of InputWidgets to populate the main menu.
The values of these widgets are passed to get_new_battle.
Expand source code Browse git
def get_menu_widgets(self) -> list[InputWidget]: """Returns a list of InputWidgets to populate the main menu. The values of these widgets are passed to get_new_battle. """ return []
def get_new_battle(self, menu_values: dict[str, typing.Any]) ‑> Optional[BattleAPI]
-
Called by the GUI when the user requests to start a new battle.
Args
menu_values
- Dictionary that maps each InputWidget's
sendto
name to the widget's value. SeeGameAPI.get_menu_widgets()
andInputWidget
.
Returns
BattleAPI
(or None if we decide not to start a new battle).Expand source code Browse git
def get_new_battle(self, menu_values: dict[str, Any]) -> Union[BattleAPI, None]: """Called by the GUI when the user requests to start a new battle. Args: menu_values: Dictionary that maps each InputWidget's `sendto` name to the widget's value. See `GameAPI.get_menu_widgets` and `InputWidget`. Returns: `BattleAPI` (or None if we decide not to start a new battle). """ return BattleAPI()
-
Called by the GUI when the user interacts with
InputWidget
s.This will be called without arguments if the user refreshes the menu.
Args
widgets
- The
sendto
names of the widgets that were interacted with. menu_values
- Dictionary that maps each InputWidget's
sendto
name to the widget's value. SeeGameAPI.get_menu_widgets()
andInputWidget
.
Returns
True if we wish the GUI to reset the main menu, by calling
GameAPI.get_info_panel_text()
andGameAPI.get_menu_widgets()
.Expand source code Browse git
def handle_menu_widget( self, widgets: list[str], menu_values: dict[str, Any], ) -> bool: """Called by the GUI when the user interacts with `InputWidget`s. This will be called without arguments if the user refreshes the menu. Args: widgets: The `sendto` names of the widgets that were interacted with. menu_values: Dictionary that maps each InputWidget's `sendto` name to the widget's value. See `GameAPI.get_menu_widgets` and `InputWidget`. Returns: True if we wish the GUI to reset the main menu, by calling `GameAPI.get_info_panel_text` and `GameAPI.get_menu_widgets`. """ return False
class InputWidget (label: str, type: Literal['spacer', 'toggle', 'text', 'select', 'slider', 'divider'], default: Any = None, sendto: Optional[str] = None, options: Optional[Sequence[str]] = None)
-
Represents an input widget in the GUI.
Widget types include:
spacer
- has a label but no valuetoggle
- toggle button (boolean value)text
- arbitrary text input (string value)select
- select from list (string value, must supply options)slider
- a slider (float value)divider
- likespacer
but creates a new section
Expand source code Browse git
@dataclass class InputWidget: """Represents an input widget in the GUI. Widget types include: * `spacer` - has a label but no value * `toggle` - toggle button (boolean value) * `text` - arbitrary text input (string value) * `select` - select from list (string value, must supply *options*) * `slider` - a slider (float value) * `divider` - like `spacer` but creates a new section """ label: str """Text to place near the widget.""" type: Literal["spacer", "toggle", "text", "select", "slider", "divider"] """Type of widget.""" default: Any = None """Starting value of the widget (default: None).""" sendto: Optional[str] = None """ Name of value (default is to use the same value of *label*). This is used by the GUI to map the value of the widget to a key in a dictionary. See `GameAPI.get_new_battle`. """ options: Optional[Sequence[str]] = None """List of strings, required only by `select` widgets.""" def __post_init__(self): """Initialize the dataclass.""" if self.type == "select": assert self.options if self.sendto is None: self.sendto = self.label if self.default is None: if self.type == "toggle": self.default = False elif self.type == "text": self.default = "" elif self.type == "select": self.default = self.options[0] elif self.type == "slider": self.default = 0.0
Class variables
var default : Any
-
Starting value of the widget (default: None).
var label : str
-
Text to place near the widget.
var options : Optional[Sequence[str]]
-
List of strings, required only by
select
widgets. var sendto : Optional[str]
-
Name of value (default is to use the same value of label).
This is used by the GUI to map the value of the widget to a key in a dictionary. See
GameAPI.get_new_battle()
. var type : Literal['spacer', 'toggle', 'text', 'select', 'slider', 'divider']
-
Type of widget.
class Tile (tile: Optional[str] = None, bg: tuple[float, float, float] = (0, 0, 0), sprite: Optional[str] = None, color: tuple[float, float, float] = (0.5, 0.5, 0.5), text: Optional[str] = None)
-
Represents how a hex on the tilemap should be drawn.
Expand source code Browse git
@dataclass class Tile: """Represents how a hex on the tilemap should be drawn.""" tile: Optional[str] = None """Sprite name of the tile itself.""" bg: tuple[float, float, float] = 0, 0, 0 """Tile (background) color.""" sprite: Optional[str] = None """Sprite name to draw on top of the tile.""" color: tuple[float, float, float] = 0.5, 0.5, 0.5 """Sprite color.""" text: Optional[str] = None """Text to draw on the tile."""
Class variables
var bg : tuple[float, float, float]
-
Tile (background) color.
var color : tuple[float, float, float]
-
Sprite color.
var sprite : Optional[str]
-
Sprite name to draw on top of the tile.
var text : Optional[str]
-
Text to draw on the tile.
var tile : Optional[str]
-
Sprite name of the tile itself.
class VFX (name: str, hex: Hexagon, direction: Hexagon, start_step: Union[int, float], expire_step: Union[int, float], expire_seconds: float)
-
Represents a visual effect to be drawn on the tilemap.
Expand source code Browse git
@dataclass class VFX: """Represents a visual effect to be drawn on the tilemap.""" name: str """Name of vfx image (with .png extension).""" hex: Hexagon """Hex of image center.""" direction: Hexagon """Hex to indicate direction for image rotation.""" start_step: Union[int, float] """In-game time before which the vfx expires.""" expire_step: Union[int, float] """In-game time after which the vfx expires.""" expire_seconds: float """Real-time seconds after which the vfx expires.""" def asdict(self): """Equivalent to passing *self* to `dataclasses.dataclass_asdict`.""" return dataclass_asdict(self)
Class variables
var direction : Hexagon
-
Hex to indicate direction for image rotation.
var expire_seconds : float
-
Real-time seconds after which the vfx expires.
var expire_step : Union[int, float]
-
In-game time after which the vfx expires.
var hex : Hexagon
-
Hex of image center.
var name : str
-
Name of vfx image (with .png extension).
var start_step : Union[int, float]
-
In-game time before which the vfx expires.
Methods
def asdict(self)
-
Equivalent to passing self to
dataclasses.dataclass_asdict
.Expand source code Browse git
def asdict(self): """Equivalent to passing *self* to `dataclasses.dataclass_asdict`.""" return dataclass_asdict(self)