From 55e17c0ff62c2bc387d5d7323824a9777d3c7417 Mon Sep 17 00:00:00 2001 From: rr- Date: Mon, 5 Nov 2018 17:34:26 +0100 Subject: [PATCH] ui: add equipment view --- pqcli/config.py | 152 +++++++++++++++++++++--------------------- pqcli/mechanic.py | 51 ++++++++------ pqcli/ui/game_view.py | 47 ++++++++++++- 3 files changed, 152 insertions(+), 98 deletions(-) diff --git a/pqcli/config.py b/pqcli/config.py index 940b799..f5d9584 100644 --- a/pqcli/config.py +++ b/pqcli/config.py @@ -154,93 +154,93 @@ DEFENSE_BAD = [ @dataclass -class Equipment: +class EquipmentPreset: name: str quality: int SHIELDS = [ - Equipment("Parasol", 0), - Equipment("Pie Plate", 1), - Equipment("Garbage Can Lid", 2), - Equipment("Buckler", 3), - Equipment("Plexiglass", 4), - Equipment("Fender", 4), - Equipment("Round Shield", 5), - Equipment("Carapace", 5), - Equipment("Scutum", 6), - Equipment("Propugner", 6), - Equipment("Kite Shield", 7), - Equipment("Pavise", 8), - Equipment("Tower Shield", 9), - Equipment("Baroque Shield", 11), - Equipment("Aegis", 12), - Equipment("Magnetic Field", 18), + EquipmentPreset("Parasol", 0), + EquipmentPreset("Pie Plate", 1), + EquipmentPreset("Garbage Can Lid", 2), + EquipmentPreset("Buckler", 3), + EquipmentPreset("Plexiglass", 4), + EquipmentPreset("Fender", 4), + EquipmentPreset("Round Shield", 5), + EquipmentPreset("Carapace", 5), + EquipmentPreset("Scutum", 6), + EquipmentPreset("Propugner", 6), + EquipmentPreset("Kite Shield", 7), + EquipmentPreset("Pavise", 8), + EquipmentPreset("Tower Shield", 9), + EquipmentPreset("Baroque Shield", 11), + EquipmentPreset("Aegis", 12), + EquipmentPreset("Magnetic Field", 18), ] ARMORS = [ - Equipment("Lace", 1), - Equipment("Macrame", 2), - Equipment("Burlap", 3), - Equipment("Canvas", 4), - Equipment("Flannel", 5), - Equipment("Chamois", 6), - Equipment("Pleathers", 7), - Equipment("Leathers", 8), - Equipment("Bearskin", 9), - Equipment("Ringmail", 10), - Equipment("Scale Mail", 12), - Equipment("Chainmail", 14), - Equipment("Splint Mail", 15), - Equipment("Platemail", 16), - Equipment("ABS", 17), - Equipment("Kevlar", 18), - Equipment("Titanium", 19), - Equipment("Mithril Mail", 20), - Equipment("Diamond Mail", 25), - Equipment("Plasma", 30), + EquipmentPreset("Lace", 1), + EquipmentPreset("Macrame", 2), + EquipmentPreset("Burlap", 3), + EquipmentPreset("Canvas", 4), + EquipmentPreset("Flannel", 5), + EquipmentPreset("Chamois", 6), + EquipmentPreset("Pleathers", 7), + EquipmentPreset("Leathers", 8), + EquipmentPreset("Bearskin", 9), + EquipmentPreset("Ringmail", 10), + EquipmentPreset("Scale Mail", 12), + EquipmentPreset("Chainmail", 14), + EquipmentPreset("Splint Mail", 15), + EquipmentPreset("Platemail", 16), + EquipmentPreset("ABS", 17), + EquipmentPreset("Kevlar", 18), + EquipmentPreset("Titanium", 19), + EquipmentPreset("Mithril Mail", 20), + EquipmentPreset("Diamond Mail", 25), + EquipmentPreset("Plasma", 30), ] WEAPONS = [ - Equipment("Stick", 0), - Equipment("Broken Bottle", 1), - Equipment("Shiv", 1), - Equipment("Sprig", 1), - Equipment("Oxgoad", 1), - Equipment("Eelspear", 2), - Equipment("Bowie Knife", 2), - Equipment("Claw Hammer", 2), - Equipment("Handpeen", 2), - Equipment("Andiron", 3), - Equipment("Hatchet", 3), - Equipment("Tomahawk", 3), - Equipment("Hackbarm", 3), - Equipment("Crowbar", 4), - Equipment("Mace", 4), - Equipment("Battleadze", 4), - Equipment("Leafmace", 5), - Equipment("Shortsword", 5), - Equipment("Longiron", 5), - Equipment("Poachard", 5), - Equipment("Baselard", 5), - Equipment("Whinyard", 6), - Equipment("Blunderbuss", 6), - Equipment("Longsword", 6), - Equipment("Crankbow", 6), - Equipment("Blibo", 7), - Equipment("Broadsword", 7), - Equipment("Kreen", 7), - Equipment("Warhammer", 7), - Equipment("Morning Star", 8), - Equipment("Pole-adze", 8), - Equipment("Spontoon", 8), - Equipment("Bastard Sword", 9), - Equipment("Peen-arm", 9), - Equipment("Culverin", 10), - Equipment("Lance", 10), - Equipment("Halberd", 11), - Equipment("Poleax", 12), - Equipment("Bandyclef", 15), + EquipmentPreset("Stick", 0), + EquipmentPreset("Broken Bottle", 1), + EquipmentPreset("Shiv", 1), + EquipmentPreset("Sprig", 1), + EquipmentPreset("Oxgoad", 1), + EquipmentPreset("Eelspear", 2), + EquipmentPreset("Bowie Knife", 2), + EquipmentPreset("Claw Hammer", 2), + EquipmentPreset("Handpeen", 2), + EquipmentPreset("Andiron", 3), + EquipmentPreset("Hatchet", 3), + EquipmentPreset("Tomahawk", 3), + EquipmentPreset("Hackbarm", 3), + EquipmentPreset("Crowbar", 4), + EquipmentPreset("Mace", 4), + EquipmentPreset("Battleadze", 4), + EquipmentPreset("Leafmace", 5), + EquipmentPreset("Shortsword", 5), + EquipmentPreset("Longiron", 5), + EquipmentPreset("Poachard", 5), + EquipmentPreset("Baselard", 5), + EquipmentPreset("Whinyard", 6), + EquipmentPreset("Blunderbuss", 6), + EquipmentPreset("Longsword", 6), + EquipmentPreset("Crankbow", 6), + EquipmentPreset("Blibo", 7), + EquipmentPreset("Broadsword", 7), + EquipmentPreset("Kreen", 7), + EquipmentPreset("Warhammer", 7), + EquipmentPreset("Morning Star", 8), + EquipmentPreset("Pole-adze", 8), + EquipmentPreset("Spontoon", 8), + EquipmentPreset("Bastard Sword", 9), + EquipmentPreset("Peen-arm", 9), + EquipmentPreset("Culverin", 10), + EquipmentPreset("Lance", 10), + EquipmentPreset("Halberd", 11), + EquipmentPreset("Poleax", 12), + EquipmentPreset("Bandyclef", 15), ] SPECIALS = [ diff --git a/pqcli/mechanic.py b/pqcli/mechanic.py index 3452c87..9b03944 100644 --- a/pqcli/mechanic.py +++ b/pqcli/mechanic.py @@ -13,23 +13,16 @@ from pqcli.lingo import * logger = logging.getLogger(__name__) -SENTINEL = object() - - class SignalMixin: def __init_subclass__(cls: T.Any, **kwargs: T.Any) -> None: urwid.signals.register_signal(cls, cls.signals) super().__init_subclass__(**kwargs) - def emit(self, signal_name: str, user_data: T.Any = SENTINEL) -> None: - urwid.signals.emit_signal(self, signal_name, user_data) + def emit(self, signal_name: str, *user_data: T.Any) -> None: + urwid.signals.emit_signal(self, signal_name, *user_data) def connect(self, signal_name: str, callback: T.Callable) -> None: - urwid.signals.connect_signal( - self, - signal_name, - lambda arg: callback() if arg is SENTINEL else callback(arg), - ) + urwid.signals.connect_signal(self, signal_name, callback) def level_up_time(level: int) -> int: @@ -161,6 +154,26 @@ class Inventory(SignalMixin): self.encum_bar.reset(capacity, self.encum_bar.position) +class Equipment(SignalMixin): + signals = ["change"] + + def __init__(self) -> None: + self._items: T.Dict[EquipmentType, str] = { + EquipmentType.weapon: "Sharp Rock", + EquipmentType.hauberk: "-3 Burlap", + } + + def __iter__(self) -> T.Iterator[T.Tuple[EquipmentType, str]]: + return iter(self._items.items()) + + def __getitem__(self, equipment_type: EquipmentType) -> T.Optional[str]: + return self._items.get(equipment_type, None) + + def put(self, equipment_type: EquipmentType, item_name: str) -> None: + self._items[equipment_type] = item_name + self.emit("change", equipment_type, item_name) + + @dataclass class Spell: name: str @@ -274,11 +287,7 @@ class Player(SignalMixin): self.quest_book = QuestBook() self.inventory = Inventory(capacity=10 + self.stats[StatType.strength]) - self.equipment: T.Dict[EquipmentType, str] = { - EquipmentType.weapon: "Sharp Rock", - EquipmentType.hauberk: "-3 Burlap", - } - + self.equipment = Equipment() self.spell_book = SpellBook() self.set_task(RegularTask("Loading", 2_000)) @@ -344,7 +353,7 @@ class Player(SignalMixin): def win_equipment(self) -> None: choice = random.choice(list(EquipmentType)) - stuff: T.List[Equipment] + stuff: T.List[EquipmentPreset] better: T.List[Modifier] worse: T.List[Modifier] @@ -381,7 +390,7 @@ class Player(SignalMixin): name = f"+{plus} {name}" logger.info("Gained %s %s", name, choice.value) - self.equipment[choice] = name + self.equipment.put(choice, name) def win_item(self) -> None: self.inventory.add(special_item(), 1) @@ -717,10 +726,12 @@ def named_monster(level: int) -> str: return generate_name() + " the " + monster.name -def pick_equipment(source: T.List[Equipment], goal: int) -> Equipment: - result = T.cast(Equipment, random.choice(source)) +def pick_equipment( + source: T.List[EquipmentPreset], goal: int +) -> EquipmentPreset: + result = T.cast(EquipmentPreset, random.choice(source)) for _ in range(5): - alternative = T.cast(Equipment, random.choice(source)) + alternative = T.cast(EquipmentPreset, random.choice(source)) if abs(goal - alternative.quality) < abs(goal - result.quality): result = alternative return result diff --git a/pqcli/ui/game_view.py b/pqcli/ui/game_view.py index cf0528e..8ace103 100644 --- a/pqcli/ui/game_view.py +++ b/pqcli/ui/game_view.py @@ -3,7 +3,7 @@ import typing as T import urwid -from pqcli.config import StatType +from pqcli.config import EquipmentType, StatType from pqcli.lingo import to_roman from pqcli.mechanic import InventoryItem, Player, Simulation, Spell from pqcli.ui.custom_line_box import CustomLineBox @@ -99,6 +99,42 @@ class SpellBookView(CustomLineBox): widget.contents[1][0].set_text(to_roman(spell.level)) +class EquipmentView(CustomLineBox): + def __init__(self, player: Player) -> None: + self.player = player + + self.value_texts = { + equipment_type: urwid.Text("") for equipment_type in EquipmentType + } + self.list_box = urwid.ListBox( + [ + urwid.Columns( + [ + urwid.Text(equipment_type.value), + self.value_texts[equipment_type], + ] + ) + for equipment_type in EquipmentType + ] + ) + + self.player.equipment.connect("change", self.sync_equipment_change) + self.sync_equipment() + + super().__init__(self.list_box, title="Equipment") + + def sync_equipment(self) -> None: + for equipment_type in EquipmentType: + self.sync_equipment_change( + equipment_type, self.player.equipment[equipment_type] + ) + + def sync_equipment_change( + self, equipment_type: EquipmentType, item_name: str + ) -> None: + self.value_texts[equipment_type].set_text(item_name or "") + + class InventoryView(urwid.Pile): def __init__(self, player: Player) -> None: self.player = player @@ -205,6 +241,7 @@ class GameView(urwid.Pile): self.character_sheet_view = CharacterSheetView(player) self.experience_view = ExperienceView(player) self.spell_book_view = SpellBookView(player) + self.equipment_view = EquipmentView(player) self.inventory_view = InventoryView(player) self.task_view = TaskView(player) @@ -223,7 +260,13 @@ class GameView(urwid.Pile): ] ), ), - ("weight", 2, urwid.Pile([self.inventory_view])), + ( + "weight", + 2, + urwid.Pile( + [self.equipment_view, self.inventory_view] + ), + ), ] ), ("pack", self.task_view),