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