mirror of
https://github.com/rr-/pq-cli.git
synced 2026-09-29 06:44:00 -06:00
ui: add equipment view
This commit is contained in:
+76
-76
@@ -154,93 +154,93 @@ DEFENSE_BAD = [
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Equipment:
|
class EquipmentPreset:
|
||||||
name: str
|
name: str
|
||||||
quality: int
|
quality: int
|
||||||
|
|
||||||
|
|
||||||
SHIELDS = [
|
SHIELDS = [
|
||||||
Equipment("Parasol", 0),
|
EquipmentPreset("Parasol", 0),
|
||||||
Equipment("Pie Plate", 1),
|
EquipmentPreset("Pie Plate", 1),
|
||||||
Equipment("Garbage Can Lid", 2),
|
EquipmentPreset("Garbage Can Lid", 2),
|
||||||
Equipment("Buckler", 3),
|
EquipmentPreset("Buckler", 3),
|
||||||
Equipment("Plexiglass", 4),
|
EquipmentPreset("Plexiglass", 4),
|
||||||
Equipment("Fender", 4),
|
EquipmentPreset("Fender", 4),
|
||||||
Equipment("Round Shield", 5),
|
EquipmentPreset("Round Shield", 5),
|
||||||
Equipment("Carapace", 5),
|
EquipmentPreset("Carapace", 5),
|
||||||
Equipment("Scutum", 6),
|
EquipmentPreset("Scutum", 6),
|
||||||
Equipment("Propugner", 6),
|
EquipmentPreset("Propugner", 6),
|
||||||
Equipment("Kite Shield", 7),
|
EquipmentPreset("Kite Shield", 7),
|
||||||
Equipment("Pavise", 8),
|
EquipmentPreset("Pavise", 8),
|
||||||
Equipment("Tower Shield", 9),
|
EquipmentPreset("Tower Shield", 9),
|
||||||
Equipment("Baroque Shield", 11),
|
EquipmentPreset("Baroque Shield", 11),
|
||||||
Equipment("Aegis", 12),
|
EquipmentPreset("Aegis", 12),
|
||||||
Equipment("Magnetic Field", 18),
|
EquipmentPreset("Magnetic Field", 18),
|
||||||
]
|
]
|
||||||
|
|
||||||
ARMORS = [
|
ARMORS = [
|
||||||
Equipment("Lace", 1),
|
EquipmentPreset("Lace", 1),
|
||||||
Equipment("Macrame", 2),
|
EquipmentPreset("Macrame", 2),
|
||||||
Equipment("Burlap", 3),
|
EquipmentPreset("Burlap", 3),
|
||||||
Equipment("Canvas", 4),
|
EquipmentPreset("Canvas", 4),
|
||||||
Equipment("Flannel", 5),
|
EquipmentPreset("Flannel", 5),
|
||||||
Equipment("Chamois", 6),
|
EquipmentPreset("Chamois", 6),
|
||||||
Equipment("Pleathers", 7),
|
EquipmentPreset("Pleathers", 7),
|
||||||
Equipment("Leathers", 8),
|
EquipmentPreset("Leathers", 8),
|
||||||
Equipment("Bearskin", 9),
|
EquipmentPreset("Bearskin", 9),
|
||||||
Equipment("Ringmail", 10),
|
EquipmentPreset("Ringmail", 10),
|
||||||
Equipment("Scale Mail", 12),
|
EquipmentPreset("Scale Mail", 12),
|
||||||
Equipment("Chainmail", 14),
|
EquipmentPreset("Chainmail", 14),
|
||||||
Equipment("Splint Mail", 15),
|
EquipmentPreset("Splint Mail", 15),
|
||||||
Equipment("Platemail", 16),
|
EquipmentPreset("Platemail", 16),
|
||||||
Equipment("ABS", 17),
|
EquipmentPreset("ABS", 17),
|
||||||
Equipment("Kevlar", 18),
|
EquipmentPreset("Kevlar", 18),
|
||||||
Equipment("Titanium", 19),
|
EquipmentPreset("Titanium", 19),
|
||||||
Equipment("Mithril Mail", 20),
|
EquipmentPreset("Mithril Mail", 20),
|
||||||
Equipment("Diamond Mail", 25),
|
EquipmentPreset("Diamond Mail", 25),
|
||||||
Equipment("Plasma", 30),
|
EquipmentPreset("Plasma", 30),
|
||||||
]
|
]
|
||||||
|
|
||||||
WEAPONS = [
|
WEAPONS = [
|
||||||
Equipment("Stick", 0),
|
EquipmentPreset("Stick", 0),
|
||||||
Equipment("Broken Bottle", 1),
|
EquipmentPreset("Broken Bottle", 1),
|
||||||
Equipment("Shiv", 1),
|
EquipmentPreset("Shiv", 1),
|
||||||
Equipment("Sprig", 1),
|
EquipmentPreset("Sprig", 1),
|
||||||
Equipment("Oxgoad", 1),
|
EquipmentPreset("Oxgoad", 1),
|
||||||
Equipment("Eelspear", 2),
|
EquipmentPreset("Eelspear", 2),
|
||||||
Equipment("Bowie Knife", 2),
|
EquipmentPreset("Bowie Knife", 2),
|
||||||
Equipment("Claw Hammer", 2),
|
EquipmentPreset("Claw Hammer", 2),
|
||||||
Equipment("Handpeen", 2),
|
EquipmentPreset("Handpeen", 2),
|
||||||
Equipment("Andiron", 3),
|
EquipmentPreset("Andiron", 3),
|
||||||
Equipment("Hatchet", 3),
|
EquipmentPreset("Hatchet", 3),
|
||||||
Equipment("Tomahawk", 3),
|
EquipmentPreset("Tomahawk", 3),
|
||||||
Equipment("Hackbarm", 3),
|
EquipmentPreset("Hackbarm", 3),
|
||||||
Equipment("Crowbar", 4),
|
EquipmentPreset("Crowbar", 4),
|
||||||
Equipment("Mace", 4),
|
EquipmentPreset("Mace", 4),
|
||||||
Equipment("Battleadze", 4),
|
EquipmentPreset("Battleadze", 4),
|
||||||
Equipment("Leafmace", 5),
|
EquipmentPreset("Leafmace", 5),
|
||||||
Equipment("Shortsword", 5),
|
EquipmentPreset("Shortsword", 5),
|
||||||
Equipment("Longiron", 5),
|
EquipmentPreset("Longiron", 5),
|
||||||
Equipment("Poachard", 5),
|
EquipmentPreset("Poachard", 5),
|
||||||
Equipment("Baselard", 5),
|
EquipmentPreset("Baselard", 5),
|
||||||
Equipment("Whinyard", 6),
|
EquipmentPreset("Whinyard", 6),
|
||||||
Equipment("Blunderbuss", 6),
|
EquipmentPreset("Blunderbuss", 6),
|
||||||
Equipment("Longsword", 6),
|
EquipmentPreset("Longsword", 6),
|
||||||
Equipment("Crankbow", 6),
|
EquipmentPreset("Crankbow", 6),
|
||||||
Equipment("Blibo", 7),
|
EquipmentPreset("Blibo", 7),
|
||||||
Equipment("Broadsword", 7),
|
EquipmentPreset("Broadsword", 7),
|
||||||
Equipment("Kreen", 7),
|
EquipmentPreset("Kreen", 7),
|
||||||
Equipment("Warhammer", 7),
|
EquipmentPreset("Warhammer", 7),
|
||||||
Equipment("Morning Star", 8),
|
EquipmentPreset("Morning Star", 8),
|
||||||
Equipment("Pole-adze", 8),
|
EquipmentPreset("Pole-adze", 8),
|
||||||
Equipment("Spontoon", 8),
|
EquipmentPreset("Spontoon", 8),
|
||||||
Equipment("Bastard Sword", 9),
|
EquipmentPreset("Bastard Sword", 9),
|
||||||
Equipment("Peen-arm", 9),
|
EquipmentPreset("Peen-arm", 9),
|
||||||
Equipment("Culverin", 10),
|
EquipmentPreset("Culverin", 10),
|
||||||
Equipment("Lance", 10),
|
EquipmentPreset("Lance", 10),
|
||||||
Equipment("Halberd", 11),
|
EquipmentPreset("Halberd", 11),
|
||||||
Equipment("Poleax", 12),
|
EquipmentPreset("Poleax", 12),
|
||||||
Equipment("Bandyclef", 15),
|
EquipmentPreset("Bandyclef", 15),
|
||||||
]
|
]
|
||||||
|
|
||||||
SPECIALS = [
|
SPECIALS = [
|
||||||
|
|||||||
+31
-20
@@ -13,23 +13,16 @@ from pqcli.lingo import *
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
SENTINEL = object()
|
|
||||||
|
|
||||||
|
|
||||||
class SignalMixin:
|
class SignalMixin:
|
||||||
def __init_subclass__(cls: T.Any, **kwargs: T.Any) -> None:
|
def __init_subclass__(cls: T.Any, **kwargs: T.Any) -> None:
|
||||||
urwid.signals.register_signal(cls, cls.signals)
|
urwid.signals.register_signal(cls, cls.signals)
|
||||||
super().__init_subclass__(**kwargs)
|
super().__init_subclass__(**kwargs)
|
||||||
|
|
||||||
def emit(self, signal_name: str, user_data: T.Any = SENTINEL) -> None:
|
def emit(self, signal_name: str, *user_data: T.Any) -> None:
|
||||||
urwid.signals.emit_signal(self, signal_name, user_data)
|
urwid.signals.emit_signal(self, signal_name, *user_data)
|
||||||
|
|
||||||
def connect(self, signal_name: str, callback: T.Callable) -> None:
|
def connect(self, signal_name: str, callback: T.Callable) -> None:
|
||||||
urwid.signals.connect_signal(
|
urwid.signals.connect_signal(self, signal_name, callback)
|
||||||
self,
|
|
||||||
signal_name,
|
|
||||||
lambda arg: callback() if arg is SENTINEL else callback(arg),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def level_up_time(level: int) -> int:
|
def level_up_time(level: int) -> int:
|
||||||
@@ -161,6 +154,26 @@ class Inventory(SignalMixin):
|
|||||||
self.encum_bar.reset(capacity, self.encum_bar.position)
|
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
|
@dataclass
|
||||||
class Spell:
|
class Spell:
|
||||||
name: str
|
name: str
|
||||||
@@ -274,11 +287,7 @@ class Player(SignalMixin):
|
|||||||
self.quest_book = QuestBook()
|
self.quest_book = QuestBook()
|
||||||
|
|
||||||
self.inventory = Inventory(capacity=10 + self.stats[StatType.strength])
|
self.inventory = Inventory(capacity=10 + self.stats[StatType.strength])
|
||||||
self.equipment: T.Dict[EquipmentType, str] = {
|
self.equipment = Equipment()
|
||||||
EquipmentType.weapon: "Sharp Rock",
|
|
||||||
EquipmentType.hauberk: "-3 Burlap",
|
|
||||||
}
|
|
||||||
|
|
||||||
self.spell_book = SpellBook()
|
self.spell_book = SpellBook()
|
||||||
|
|
||||||
self.set_task(RegularTask("Loading", 2_000))
|
self.set_task(RegularTask("Loading", 2_000))
|
||||||
@@ -344,7 +353,7 @@ class Player(SignalMixin):
|
|||||||
def win_equipment(self) -> None:
|
def win_equipment(self) -> None:
|
||||||
choice = random.choice(list(EquipmentType))
|
choice = random.choice(list(EquipmentType))
|
||||||
|
|
||||||
stuff: T.List[Equipment]
|
stuff: T.List[EquipmentPreset]
|
||||||
better: T.List[Modifier]
|
better: T.List[Modifier]
|
||||||
worse: T.List[Modifier]
|
worse: T.List[Modifier]
|
||||||
|
|
||||||
@@ -381,7 +390,7 @@ class Player(SignalMixin):
|
|||||||
name = f"+{plus} {name}"
|
name = f"+{plus} {name}"
|
||||||
|
|
||||||
logger.info("Gained %s %s", name, choice.value)
|
logger.info("Gained %s %s", name, choice.value)
|
||||||
self.equipment[choice] = name
|
self.equipment.put(choice, name)
|
||||||
|
|
||||||
def win_item(self) -> None:
|
def win_item(self) -> None:
|
||||||
self.inventory.add(special_item(), 1)
|
self.inventory.add(special_item(), 1)
|
||||||
@@ -717,10 +726,12 @@ def named_monster(level: int) -> str:
|
|||||||
return generate_name() + " the " + monster.name
|
return generate_name() + " the " + monster.name
|
||||||
|
|
||||||
|
|
||||||
def pick_equipment(source: T.List[Equipment], goal: int) -> Equipment:
|
def pick_equipment(
|
||||||
result = T.cast(Equipment, random.choice(source))
|
source: T.List[EquipmentPreset], goal: int
|
||||||
|
) -> EquipmentPreset:
|
||||||
|
result = T.cast(EquipmentPreset, random.choice(source))
|
||||||
for _ in range(5):
|
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):
|
if abs(goal - alternative.quality) < abs(goal - result.quality):
|
||||||
result = alternative
|
result = alternative
|
||||||
return result
|
return result
|
||||||
|
|||||||
+45
-2
@@ -3,7 +3,7 @@ import typing as T
|
|||||||
|
|
||||||
import urwid
|
import urwid
|
||||||
|
|
||||||
from pqcli.config import StatType
|
from pqcli.config import EquipmentType, StatType
|
||||||
from pqcli.lingo import to_roman
|
from pqcli.lingo import to_roman
|
||||||
from pqcli.mechanic import InventoryItem, Player, Simulation, Spell
|
from pqcli.mechanic import InventoryItem, Player, Simulation, Spell
|
||||||
from pqcli.ui.custom_line_box import CustomLineBox
|
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))
|
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):
|
class InventoryView(urwid.Pile):
|
||||||
def __init__(self, player: Player) -> None:
|
def __init__(self, player: Player) -> None:
|
||||||
self.player = player
|
self.player = player
|
||||||
@@ -205,6 +241,7 @@ class GameView(urwid.Pile):
|
|||||||
self.character_sheet_view = CharacterSheetView(player)
|
self.character_sheet_view = CharacterSheetView(player)
|
||||||
self.experience_view = ExperienceView(player)
|
self.experience_view = ExperienceView(player)
|
||||||
self.spell_book_view = SpellBookView(player)
|
self.spell_book_view = SpellBookView(player)
|
||||||
|
self.equipment_view = EquipmentView(player)
|
||||||
self.inventory_view = InventoryView(player)
|
self.inventory_view = InventoryView(player)
|
||||||
self.task_view = TaskView(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),
|
("pack", self.task_view),
|
||||||
|
|||||||
Reference in New Issue
Block a user