mirror of
https://github.com/rr-/pq-cli.git
synced 2026-09-29 06:44:00 -06:00
ui: add inventory view
This commit is contained in:
+17
-10
@@ -99,15 +99,17 @@ class QuestBook:
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Item:
|
class InventoryItem:
|
||||||
name: str
|
name: str
|
||||||
quantity: int
|
quantity: int
|
||||||
|
|
||||||
|
|
||||||
class Inventory:
|
class Inventory(SignalMixin):
|
||||||
|
signals = ["gold_change", "item_add", "item_change", "item_del"]
|
||||||
|
|
||||||
def __init__(self, capacity: int = 0) -> None:
|
def __init__(self, capacity: int = 0) -> None:
|
||||||
self._gold = 0
|
self._gold = 0
|
||||||
self._items: T.List[Item] = []
|
self._items: T.List[InventoryItem] = []
|
||||||
self.encum_bar = Bar(max_=capacity)
|
self.encum_bar = Bar(max_=capacity)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -117,9 +119,12 @@ class Inventory:
|
|||||||
def __len__(self) -> int:
|
def __len__(self) -> int:
|
||||||
return len(self._items)
|
return len(self._items)
|
||||||
|
|
||||||
def __iter__(self) -> T.Iterator[Item]:
|
def __iter__(self) -> T.Iterator[InventoryItem]:
|
||||||
return iter(self._items)
|
return iter(self._items)
|
||||||
|
|
||||||
|
def __getitem__(self, idx: int) -> InventoryItem:
|
||||||
|
return self._items[idx]
|
||||||
|
|
||||||
def add_gold(self, quantity: int) -> None:
|
def add_gold(self, quantity: int) -> None:
|
||||||
logger.info(
|
logger.info(
|
||||||
"%s %s",
|
"%s %s",
|
||||||
@@ -127,24 +132,26 @@ class Inventory:
|
|||||||
indefinite("gold piece", abs(quantity)),
|
indefinite("gold piece", abs(quantity)),
|
||||||
)
|
)
|
||||||
self._gold += quantity
|
self._gold += quantity
|
||||||
|
self.emit("gold_change")
|
||||||
def item_at(self, index: int) -> Item:
|
|
||||||
return self._items[index]
|
|
||||||
|
|
||||||
def pop(self, index: int) -> None:
|
def pop(self, index: int) -> None:
|
||||||
item = self._items[index]
|
item = self._items[index]
|
||||||
logger.info("Lost %s (qty=%d)", item.name, item.quantity)
|
logger.info("Lost %s (qty=%d)", item.name, item.quantity)
|
||||||
self._items.pop(index)
|
self._items.pop(index)
|
||||||
self.sync_encumbrance()
|
self.sync_encumbrance()
|
||||||
|
self.emit("item_del", item)
|
||||||
|
|
||||||
def add(self, item_name: str, quantity: int) -> None:
|
def add(self, item_name: str, quantity: int) -> None:
|
||||||
logger.info("Gained %s", indefinite(item_name, quantity))
|
logger.info("Gained %s", indefinite(item_name, quantity))
|
||||||
for item in self._items:
|
for item in self._items:
|
||||||
if item.name == item_name:
|
if item.name == item_name:
|
||||||
item.quantity += quantity
|
item.quantity += quantity
|
||||||
|
self.emit("item_change", item)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
self._items.append(Item(name=item_name, quantity=quantity))
|
item = InventoryItem(name=item_name, quantity=quantity)
|
||||||
|
self._items.append(item)
|
||||||
|
self.emit("item_add", item)
|
||||||
self.sync_encumbrance()
|
self.sync_encumbrance()
|
||||||
|
|
||||||
def sync_encumbrance(self) -> None:
|
def sync_encumbrance(self) -> None:
|
||||||
@@ -449,7 +456,7 @@ class Simulation:
|
|||||||
|
|
||||||
elif isinstance(self.player.task, (HeadingToMarketTask, SellTask)):
|
elif isinstance(self.player.task, (HeadingToMarketTask, SellTask)):
|
||||||
if isinstance(self.player.task, SellTask):
|
if isinstance(self.player.task, SellTask):
|
||||||
item = self.player.inventory.item_at(0)
|
item = self.player.inventory[0]
|
||||||
amount = item.quantity * self.player.level
|
amount = item.quantity * self.player.level
|
||||||
if " of " in item.name:
|
if " of " in item.name:
|
||||||
amount *= (1 + random.below_low(10)) * (
|
amount *= (1 + random.below_low(10)) * (
|
||||||
@@ -458,7 +465,7 @@ class Simulation:
|
|||||||
self.player.inventory.pop(0)
|
self.player.inventory.pop(0)
|
||||||
self.player.inventory.add_gold(amount)
|
self.player.inventory.add_gold(amount)
|
||||||
if len(self.player.inventory):
|
if len(self.player.inventory):
|
||||||
item = self.player.inventory.item_at(0)
|
item = self.player.inventory[0]
|
||||||
self.player.set_task(
|
self.player.set_task(
|
||||||
SellTask(
|
SellTask(
|
||||||
"Selling " + indefinite(item.name, item.quantity),
|
"Selling " + indefinite(item.name, item.quantity),
|
||||||
|
|||||||
+81
-8
@@ -5,7 +5,7 @@ import urwid
|
|||||||
|
|
||||||
from pqcli.config import StatType
|
from pqcli.config import StatType
|
||||||
from pqcli.lingo import to_roman
|
from pqcli.lingo import to_roman
|
||||||
from pqcli.mechanic import 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
|
||||||
from pqcli.ui.custom_progress_bar import CustomProgressBar
|
from pqcli.ui.custom_progress_bar import CustomProgressBar
|
||||||
|
|
||||||
@@ -99,6 +99,73 @@ class SpellBookView(CustomLineBox):
|
|||||||
widget.contents[1][0].set_text(to_roman(spell.level))
|
widget.contents[1][0].set_text(to_roman(spell.level))
|
||||||
|
|
||||||
|
|
||||||
|
class InventoryView(urwid.Pile):
|
||||||
|
def __init__(self, player: Player) -> None:
|
||||||
|
self.player = player
|
||||||
|
|
||||||
|
self.gold_text = urwid.Text("")
|
||||||
|
self.list_box = urwid.ListBox(
|
||||||
|
[urwid.Columns([urwid.Text("Gold"), self.gold_text])]
|
||||||
|
)
|
||||||
|
self.encumbrance_bar = CustomProgressBar()
|
||||||
|
|
||||||
|
self.player.inventory.connect("gold_change", self.sync_gold)
|
||||||
|
self.player.inventory.connect("item_add", self.sync_item_add)
|
||||||
|
self.player.inventory.connect("item_del", self.sync_item_del)
|
||||||
|
self.player.inventory.connect("item_change", self.sync_item_change)
|
||||||
|
self.player.inventory.encum_bar.connect(
|
||||||
|
"change", self.sync_encumbrance_position
|
||||||
|
)
|
||||||
|
self.sync_gold()
|
||||||
|
self.sync_items()
|
||||||
|
self.sync_encumbrance_position()
|
||||||
|
|
||||||
|
super().__init__(
|
||||||
|
[
|
||||||
|
CustomLineBox(self.list_box, title="Inventory"),
|
||||||
|
(1, urwid.Filler(urwid.Text("Encumbrance"))),
|
||||||
|
(1, urwid.Filler(self.encumbrance_bar)),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
def sync_gold(self) -> None:
|
||||||
|
self.gold_text.set_text(str(self.player.inventory.gold))
|
||||||
|
|
||||||
|
def sync_items(self) -> None:
|
||||||
|
del self.list_box.body[1:]
|
||||||
|
for item in self.player.inventory:
|
||||||
|
self.sync_item_add(item)
|
||||||
|
|
||||||
|
def sync_encumbrance_position(self) -> None:
|
||||||
|
self.encumbrance_bar.set_completion(
|
||||||
|
self.player.inventory.encum_bar.position
|
||||||
|
)
|
||||||
|
self.encumbrance_bar.set_max(self.player.inventory.encum_bar.max_)
|
||||||
|
|
||||||
|
def sync_item_add(self, item: InventoryItem) -> None:
|
||||||
|
self.list_box.body.append(
|
||||||
|
urwid.Columns(
|
||||||
|
[urwid.Text(item.name), urwid.Text(str(item.quantity))]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def sync_item_del(self, item: InventoryItem) -> None:
|
||||||
|
idx = self.get_item_idx_by_name(item.name)
|
||||||
|
if idx is not None:
|
||||||
|
del self.list_box.body[idx]
|
||||||
|
|
||||||
|
def sync_item_change(self, item: InventoryItem) -> None:
|
||||||
|
idx = self.get_item_idx_by_name(item.name)
|
||||||
|
if idx is not None:
|
||||||
|
self.list_box.body[idx].contents[1][0].set_text(str(item.quantity))
|
||||||
|
|
||||||
|
def get_item_idx_by_name(self, name: str) -> T.Optional[int]:
|
||||||
|
for i, column_widget in enumerate(self.list_box.body):
|
||||||
|
if column_widget.contents[0][0].text == name:
|
||||||
|
return i
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class TaskView(urwid.Pile):
|
class TaskView(urwid.Pile):
|
||||||
def __init__(self, player: Player) -> None:
|
def __init__(self, player: Player) -> None:
|
||||||
self.player = player
|
self.player = player
|
||||||
@@ -138,19 +205,25 @@ 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.inventory_view = InventoryView(player)
|
||||||
self.task_view = TaskView(player)
|
self.task_view = TaskView(player)
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
[
|
[
|
||||||
urwid.Columns(
|
urwid.Columns(
|
||||||
[
|
[
|
||||||
urwid.Pile(
|
(
|
||||||
[
|
"weight",
|
||||||
self.character_sheet_view,
|
1,
|
||||||
("pack", self.experience_view),
|
urwid.Pile(
|
||||||
self.spell_book_view,
|
[
|
||||||
]
|
self.character_sheet_view,
|
||||||
)
|
("pack", self.experience_view),
|
||||||
|
self.spell_book_view,
|
||||||
|
]
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("weight", 2, urwid.Pile([self.inventory_view])),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
("pack", self.task_view),
|
("pack", self.task_view),
|
||||||
|
|||||||
Reference in New Issue
Block a user