ui: add inventory view

This commit is contained in:
rr-
2018-11-05 21:04:40 +01:00
parent 1dd6749d67
commit 213b11c0bd
2 changed files with 98 additions and 18 deletions
+17 -10
View File
@@ -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),
+75 -2
View File
@@ -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(
[ [
(
"weight",
1,
urwid.Pile( urwid.Pile(
[ [
self.character_sheet_view, self.character_sheet_view,
("pack", self.experience_view), ("pack", self.experience_view),
self.spell_book_view, self.spell_book_view,
] ]
) ),
),
("weight", 2, urwid.Pile([self.inventory_view])),
] ]
), ),
("pack", self.task_view), ("pack", self.task_view),