-
Notifications
You must be signed in to change notification settings - Fork 0
/
inventory_ui.py
157 lines (127 loc) · 3.5 KB
/
inventory_ui.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import curses
from items import *
from text_menu import GameTextMenu
def item_display_name(player, item):
name = item.name
if item is player.armor:
name += " (worn)"
elif item is player.weapon:
name += " (wielded)"
elif item is player.shield:
name += " (equipped)"
elif isinstance(item, Wand):
name += f" (charges: {item.charges})"
return name
def display_item(g, item):
player = g.get_player()
screen = g.screen
screen.erase()
menu = GameTextMenu(g)
menu.add_text(item_display_name(player, item))
menu.add_text(item.description)
menu.add_line()
if isinstance(item, Armor):
menu.add_text(f"Protection: {item.protection}")
menu.add_text(f"Encumbrance: {item.encumbrance}")
if item.stealth_pen > 0:
menu.add_text(f"Stealth penalty: {-item.stealth_pen}")
menu.add_line()
elif isinstance(item, Weapon):
menu.add_text(f"Base damage: {item.damage}")
if item.finesse:
menu.add_text("This is a finesse weapon.")
if item.heavy:
menu.add_text("This weapon is heavy; attacking with it takes a bit longer.")
if item.is_two_handed():
menu.add_text("This weapon requires two hands to wield.")
use_text = "Use"
can_throw = False
if isinstance(item, Weapon):
use_text = "Wield"
can_throw = item.thrown != False
elif isinstance(item, ThrownItem):
can_throw = True
elif isinstance(item, Armor):
use_text = "Wear"
menu.add_text(f"U - {use_text}")
if can_throw:
menu.add_text("T - Throw")
menu.add_text("D - Drop")
menu.add_text("Enter - cancel")
menu.display()
while True:
code = menu.getch()
if code == 10:
return False
elif chr(code) == "u":
player.use_item(item)
return True
elif chr(code) == "d":
player.drop_item(item)
return True
elif can_throw and chr(code) == "t":
player.throw_item(item)
return True
def consolidate_inventory_display(player):
counts = {}
items = {}
for item in player.inventory:
name = item_display_name(player, item)
if name not in counts:
counts[name] = 0
items[name] = item
counts[name] += 1
display = []
for name in sorted(items.keys()):
num = counts[name]
item = items[name]
if num > 1:
name += f" (x{num})"
display.append((name, item))
return display
def inventory_menu(g):
player = g.get_player()
display = consolidate_inventory_display(player)
screen = g.screen
scroll = 0
num_items = len(display)
max_scroll = max(0, num_items - 9)
can_scroll = max_scroll > 0
display_title = "View which item? Enter a number from 1 - 9, then press Enter (0 to cancel)."
if can_scroll:
display_title += " (W and S keys to scroll)"
select = 0
while True:
screen.erase()
screen.addstr(0, 0, display_title)
num_displayed = min(num_items, 9)
for i in range(num_displayed):
index = i + scroll
name, item = display[index]
color = curses.A_REVERSE if i == select else 0
screen.addstr(i + 2, 0, str(i+1), color)
string = f" - {name}"
if i == 0 and scroll > 0:
string += " [↑]"
elif i == num_displayed - 1 and scroll < max_scroll:
string += " [↓]"
screen.addstr(i + 2, 2, string)
screen.refresh()
key = screen.getch()
char = chr(key)
if can_scroll:
if char == "w":
scroll -= 1
elif char == "s":
scroll += 1
scroll = clamp(scroll, 0, max_scroll)
_, item = display[scroll + select]
if char == "0":
return False
elif char in "123456789":
value = int(char) - 1
if value < len(display):
select = value
if key == 10 and display_item(g, item):
return True
screen.erase()