data/shopgui.py (view raw)
1"""
2This class controls the textbox GUI for any shop state.
3A Gui object is created and updated by the shop state.
4"""
5
6import pygame as pg
7from . import setup
8from . components import textbox
9from . import constants as c
10
11
12class Gui(object):
13 """Class that controls the GUI of the shop state"""
14 def __init__(self, level):
15 self.level = level
16 self.player_inventory = level.game_data['player inventory']
17 self.name = level.name
18 self.state = 'dialogue'
19 self.no_selling = ['Inn', 'Magic Shop']
20 self.font = pg.font.Font(setup.FONTS['Fixedsys500c'], 22)
21 self.index = 0
22 self.timer = 0.0
23 self.allow_input = False
24 self.item = level.item
25 self.dialogue = level.dialogue
26 self.accept_dialogue = level.accept_dialogue
27 self.arrow = textbox.NextArrow()
28 self.selection_arrow = textbox.NextArrow()
29 self.arrow_pos1 = (50, 485)
30 self.arrow_pos2 = (50, 535)
31 self.selection_arrow.rect.topleft = self.arrow_pos1
32 self.dialogue_box = self.make_dialogue_box(self.dialogue, self.index)
33 self.gold_box = self.make_gold_box()
34 self.selection_box = self.make_selection_box()
35 self.state_dict = self.make_state_dict()
36
37
38 def make_dialogue_box(self, dialogue_list, index):
39 """Make the sprite that controls the dialogue"""
40 image = setup.GFX['dialoguebox']
41 rect = image.get_rect()
42 surface = pg.Surface(rect.size)
43 surface.set_colorkey(c.BLACK)
44 surface.blit(image, rect)
45 dialogue = self.font.render(dialogue_list[index],
46 True,
47 c.NEAR_BLACK)
48 dialogue_rect = dialogue.get_rect(left=50, top=50)
49 surface.blit(dialogue, dialogue_rect)
50 sprite = pg.sprite.Sprite()
51 sprite.image = surface
52 sprite.rect = rect
53 self.check_to_draw_arrow(sprite)
54
55 return sprite
56
57
58 def make_selection_box(self):
59 """Make the box for the player to select options"""
60 image = setup.GFX['shopbox']
61 rect = image.get_rect(bottom=608)
62
63 surface = pg.Surface(rect.size)
64 surface.set_colorkey(c.BLACK)
65 surface.blit(image, (0, 0))
66
67 if self.state == 'select':
68 choices = self.item['dialogue']
69 elif self.state == 'confirm':
70 choices = ['Yes',
71 'No']
72 elif self.state == 'buysell':
73 choices = ['Buy',
74 'Sell']
75 else:
76 choices = ['Not',
77 'assigned']
78 choice1 = self.font.render(choices[0], True, c.NEAR_BLACK)
79 choice1_rect = choice1.get_rect(x=200, y=25)
80 choice2 = self.font.render(choices[1], True, c.NEAR_BLACK)
81 choice2_rect = choice2.get_rect(x=200, y=75)
82 surface.blit(choice1, choice1_rect)
83 surface.blit(choice2, choice2_rect)
84 sprite = pg.sprite.Sprite()
85 sprite.image = surface
86 sprite.rect = rect
87
88 return sprite
89
90
91
92 def check_to_draw_arrow(self, sprite):
93 """Blink arrow if more text needs to be read"""
94 if self.index < len(self.dialogue) - 1:
95 sprite.image.blit(self.arrow.image, self.arrow.rect)
96
97
98 def make_gold_box(self):
99 """Make the box to display total gold"""
100 image = setup.GFX['goldbox']
101 rect = image.get_rect(bottom=608, right=800)
102
103 surface = pg.Surface(rect.size)
104 surface.set_colorkey(c.BLACK)
105 surface.blit(image, (0, 0))
106 gold = self.player_inventory['gold']
107 text = 'Gold: ' + str(gold)
108 text_render = self.font.render(text, True, c.NEAR_BLACK)
109 text_rect = text_render.get_rect(x=80, y=60)
110
111 surface.blit(text_render, text_rect)
112
113 sprite = pg.sprite.Sprite()
114 sprite.image = surface
115 sprite.rect = rect
116
117 return sprite
118
119
120
121 def make_state_dict(self):
122 """Make the state dictionary for the GUI behavior"""
123 state_dict = {'dialogue': self.control_dialogue,
124 'select': self.make_selection,
125 'confirm': self.confirm_selection,
126 'reject': self.reject_insufficient_gold,
127 'accept': self.accept_purchase,
128 'hasitem': self.has_item,
129 'buysell': self.buy_sell}
130
131 return state_dict
132
133
134 def control_dialogue(self, keys, current_time):
135 """Control the dialogue boxes"""
136 self.dialogue_box = self.make_dialogue_box(self.dialogue, self.index)
137
138 if self.index < (len(self.dialogue) - 1) and self.allow_input:
139 if keys[pg.K_SPACE]:
140 self.index += 1
141 self.allow_input = False
142
143 if self.index == (len(self.dialogue) - 1):
144 self.state = self.begin_new_transaction()
145
146
147 if not keys[pg.K_SPACE]:
148 self.allow_input = True
149
150
151 def make_selection(self, keys, current_time):
152 """Control the selection"""
153 self.dialogue_box = self.make_dialogue_box(self.dialogue, self.index)
154 self.selection_box = self.make_selection_box()
155 self.gold_box = self.make_gold_box()
156
157 if keys[pg.K_DOWN]:
158 self.selection_arrow.rect.topleft = self.arrow_pos2
159 elif keys[pg.K_UP]:
160 self.selection_arrow.rect.topleft = self.arrow_pos1
161 elif keys[pg.K_SPACE] and (current_time - self.timer) > 200:
162 if self.allow_input:
163 if self.selection_arrow.rect.topleft == self.arrow_pos2:
164 self.level.done = True
165 self.level.game_data['last direction'] = 'down'
166 elif self.selection_arrow.rect.topleft == self.arrow_pos1:
167 self.state = 'confirm'
168 self.timer = current_time
169 self.allow_input = False
170
171 if not keys[pg.K_SPACE]:
172 self.allow_input = True
173
174
175
176 def confirm_selection(self, keys, current_time):
177 """Confirm selection state for GUI"""
178 dialogue = ['Are you sure?']
179 self.selection_box = self.make_selection_box()
180 self.gold_box = self.make_gold_box()
181 self.dialogue_box = self.make_dialogue_box(dialogue, 0)
182
183 if keys[pg.K_DOWN]:
184 self.selection_arrow.rect.topleft = self.arrow_pos2
185 elif keys[pg.K_UP]:
186 self.selection_arrow.rect.topleft = self.arrow_pos1
187 elif keys[pg.K_SPACE] and self.allow_input:
188 if self.selection_arrow.rect.topleft == self.arrow_pos1:
189 self.buy_item()
190 self.allow_input = False
191 else:
192 self.state = self.begin_new_transaction()
193 self.allow_input = False
194 self.timer = current_time
195 self.selection_arrow.rect.topleft = self.arrow_pos1
196
197 if not keys[pg.K_SPACE]:
198 self.allow_input = True
199
200
201 def begin_new_transaction(self):
202 """Set state to buysell or select, depending if the shop
203 is a Inn/Magic shop or not"""
204 if self.level.name in self.no_selling:
205 state = 'select'
206 else:
207 state = 'buysell'
208
209 return state
210
211
212 def buy_item(self):
213 """Attempt to allow player to purchase item"""
214 self.player_inventory['gold'] -= self.item['price']
215
216 if self.player_inventory['gold'] < 0:
217 self.player_inventory['gold'] += self.item['price']
218 self.state = 'reject'
219 else:
220 if (self.item['type'] == 'Fire Spell' and
221 'Fire Spell' in self.player_inventory):
222 self.state = 'hasitem'
223 self.player_inventory['gold'] += self.item['price']
224 else:
225 self.state = 'accept'
226 self.add_player_item(self.item)
227
228
229 def reject_insufficient_gold(self, keys, current_time):
230 """Reject player selection if they do not have enough gold"""
231 dialogue = ["You don't have enough gold!"]
232 self.dialogue_box = self.make_dialogue_box(dialogue, 0)
233
234 if keys[pg.K_SPACE] and self.allow_input:
235 self.state = self.begin_new_transaction()
236 self.selection_arrow.rect.topleft = self.arrow_pos1
237 self.allow_input = False
238
239 if not keys[pg.K_SPACE]:
240 self.allow_input = True
241
242
243 def accept_purchase(self, keys, current_time):
244 """Accept purchase and confirm with message"""
245 self.dialogue_box = self.make_dialogue_box(self.accept_dialogue, 0)
246 self.gold_box = self.make_gold_box()
247
248 if keys[pg.K_SPACE] and self.allow_input:
249 self.state = self.begin_new_transaction()
250 self.selection_arrow.rect.topleft = self.arrow_pos1
251 self.allow_input = False
252
253 if not keys[pg.K_SPACE]:
254 self.allow_input = True
255
256
257 def has_item(self, keys, current_time):
258 """Tell player he has item already"""
259 dialogue = ["You have that item already."]
260 self.dialogue_box = self.make_dialogue_box(dialogue, 0)
261
262 if keys[pg.K_SPACE] and self.allow_input:
263 self.state = self.begin_new_transaction()
264 self.selection_arrow.rect.topleft = self.arrow_pos1
265 self.allow_input = False
266
267 if not keys[pg.K_SPACE]:
268 self.allow_input = True
269
270
271 def buy_sell(self, keys, current_time):
272 """Ask player if they want to buy or sell something"""
273 dialogue = ["Would you like to buy or sell an item?"]
274 self.dialogue_box = self.make_dialogue_box(dialogue, 0)
275 self.selection_box = self.make_selection_box()
276
277 if keys[pg.K_DOWN]:
278 self.selection_arrow.rect.topleft = self.arrow_pos2
279 elif keys[pg.K_UP]:
280 self.selection_arrow.rect.topleft = self.arrow_pos1
281 elif keys[pg.K_SPACE] and self.allow_input:
282 if self.selection_arrow.rect.topleft == self.arrow_pos1:
283 self.state = 'select'
284 self.allow_input = False
285 else:
286 self.state = 'select'
287 self.allow_input = False
288 self.selection_arrow.rect.topleft = self.arrow_pos1
289
290 if not keys[pg.K_SPACE]:
291 self.allow_input = True
292
293
294 def add_player_item(self, item):
295 """Add item to player's inventory"""
296 item_type = item['type']
297 quantity = item['quantity']
298 player_item = self.level.game_data['player inventory']
299
300 if item_type in player_item:
301 player_item[item_type] += quantity
302 elif quantity > 0:
303 player_item[item_type] = quantity
304
305
306
307 def update(self, keys, current_time):
308 """Updates the shop GUI"""
309 state_function = self.state_dict[self.state]
310 state_function(keys, current_time)
311
312
313 def draw(self, surface):
314 """Draw GUI to level surface"""
315 state_list1 = ['dialogue', 'reject', 'accept', 'hasitem']
316 state_list2 = ['select', 'confirm', 'buysell']
317
318 surface.blit(self.dialogue_box.image, self.dialogue_box.rect)
319 surface.blit(self.gold_box.image, self.gold_box.rect)
320 if self.state in state_list2:
321 surface.blit(self.selection_box.image, self.selection_box.rect)
322 surface.blit(self.selection_arrow.image, self.selection_arrow.rect)
323