data/states/shop.py (view raw)
1"""
2This class is the parent class of all shop states.
3This includes weapon, armour, magic and potion shops.
4It also includes the inn. These states are scaled
5twice as big as a level state.
6"""
7import copy
8import pygame as pg
9from .. import tools, setup
10from .. import constants as c
11from .. components import textbox, person
12
13
14class Gui(object):
15 """Class that controls the GUI of the shop state"""
16 def __init__(self, name, dialogue, level):
17 self.level = level
18 self.name = name
19 self.state = 'dialogue'
20 self.font = pg.font.Font(setup.FONTS['Fixedsys500c'], 22)
21 self.index = 0
22 self.timer = 0.0
23 self.dialogue = dialogue
24 self.arrow = textbox.NextArrow()
25 self.selection_arrow = textbox.NextArrow()
26 self.arrow_pos1 = (50, 485)
27 self.arrow_pos2 = (50, 535)
28 self.selection_arrow.rect.topleft = self.arrow_pos1
29 self.dialogue_box = self.make_dialogue_box(self.dialogue, self.index)
30 self.gold_box = self.make_gold_box()
31 self.selection_box = self.make_selection_box()
32 self.state_dict = self.make_state_dict()
33
34
35 def make_dialogue_box(self, dialogue_list, index):
36 """Make the sprite that controls the dialogue"""
37 image = setup.GFX['dialoguebox']
38 rect = image.get_rect()
39 surface = pg.Surface(rect.size)
40 surface.set_colorkey(c.BLACK)
41 surface.blit(image, rect)
42 dialogue = self.font.render(dialogue_list[index],
43 True,
44 c.NEAR_BLACK)
45 dialogue_rect = dialogue.get_rect(left=50, top=50)
46 surface.blit(dialogue, dialogue_rect)
47 sprite = pg.sprite.Sprite()
48 sprite.image = surface
49 sprite.rect = rect
50 self.check_to_draw_arrow(sprite)
51
52 return sprite
53
54
55 def make_selection_box(self):
56 """Make the box for the player to select options"""
57 image = setup.GFX['shopbox']
58 rect = image.get_rect(bottom=608)
59
60 surface = pg.Surface(rect.size)
61 surface.set_colorkey(c.BLACK)
62 surface.blit(image, (0, 0))
63 if self.state == 'select':
64 choices = ['Rent a room. (30 Gold)',
65 'Leave.']
66 elif self.state == 'confirm':
67 choices = ['Yes',
68 'No']
69 else:
70 choices = ['Not',
71 'assigned']
72 choice1 = self.font.render(choices[0], True, c.NEAR_BLACK)
73 choice1_rect = choice1.get_rect(x=200, y=25)
74 choice2 = self.font.render(choices[1], True, c.NEAR_BLACK)
75 choice2_rect = choice2.get_rect(x=200, y=75)
76 surface.blit(choice1, choice1_rect)
77 surface.blit(choice2, choice2_rect)
78 sprite = pg.sprite.Sprite()
79 sprite.image = surface
80 sprite.rect = rect
81
82 return sprite
83
84
85 def check_to_draw_arrow(self, sprite):
86 """Blink arrow if more text needs to be read"""
87 if self.index < len(self.dialogue) - 1:
88 sprite.image.blit(self.arrow.image, self.arrow.rect)
89
90
91 def make_gold_box(self):
92 """Make the box to display total gold"""
93 image = setup.GFX['goldbox']
94 rect = image.get_rect(bottom=608, right=800)
95
96 surface = pg.Surface(rect.size)
97 surface.set_colorkey(c.BLACK)
98 surface.blit(image, (0, 0))
99 gold = self.level.game_data['player items']['gold']
100 text = 'Gold: ' + str(gold)
101 text_render = self.font.render(text, True, c.NEAR_BLACK)
102 text_rect = text_render.get_rect(x=80, y=60)
103
104 surface.blit(text_render, text_rect)
105
106 sprite = pg.sprite.Sprite()
107 sprite.image = surface
108 sprite.rect = rect
109
110 return sprite
111
112
113
114 def make_state_dict(self):
115 """Make the state dictionary for the GUI behavior"""
116 state_dict = {'dialogue': self.control_dialogue,
117 'select': self.make_selection,
118 'confirm': self.confirm_selection,
119 'reject': self.reject_insufficient_gold,
120 'accept': self.accept_purchase}
121
122 return state_dict
123
124
125 def control_dialogue(self, keys, current_time):
126 """Control the dialogue boxes"""
127 self.dialogue_box = self.make_dialogue_box(self.dialogue, self.index)
128
129 if self.index < (len(self.dialogue) - 1):
130 if keys[pg.K_SPACE]:
131 self.index += 1
132
133 elif self.index == (len(self.dialogue) - 1):
134 self.state = 'select'
135 self.timer = current_time
136
137
138 def make_selection(self, keys, current_time):
139 """Control the selection"""
140 self.dialogue_box = self.make_dialogue_box(self.dialogue, self.index)
141 self.selection_box = self.make_selection_box()
142 self.gold_box = self.make_gold_box()
143
144 if keys[pg.K_DOWN]:
145 self.selection_arrow.rect.topleft = self.arrow_pos2
146 elif keys[pg.K_UP]:
147 self.selection_arrow.rect.topleft = self.arrow_pos1
148 elif keys[pg.K_SPACE] and (current_time - self.timer) > 200:
149 if self.selection_arrow.rect.topleft == self.arrow_pos2:
150 self.level.done = True
151 self.level.game_data['last direction'] = 'down'
152 elif self.selection_arrow.rect.topleft == self.arrow_pos1:
153 self.state = 'confirm'
154 self.timer = current_time
155
156
157
158 def confirm_selection(self, keys, current_time):
159 """Confirm selection state for GUI"""
160 dialogue = ['Are you sure?']
161 self.selection_box = self.make_selection_box()
162 self.gold_box = self.make_gold_box()
163 self.dialogue_box = self.make_dialogue_box(dialogue, 0)
164
165 if keys[pg.K_DOWN]:
166 self.selection_arrow.rect.topleft = self.arrow_pos2
167 elif keys[pg.K_UP]:
168 self.selection_arrow.rect.topleft = self.arrow_pos1
169 elif keys[pg.K_SPACE] and (current_time - self.timer) > 200:
170 if self.selection_arrow.rect.topleft == self.arrow_pos1:
171 self.level.game_data['player items']['gold'] -= 30
172 if self.level.game_data['player items']['gold'] < 0:
173 self.level.game_data['player items']['gold'] += 30
174 self.state = 'reject'
175 else:
176 self.state = 'accept'
177 else:
178 self.state = 'select'
179 self.timer = current_time
180 self.selection_arrow.rect.topleft = self.arrow_pos1
181
182
183 def reject_insufficient_gold(self, keys, current_time):
184 """Reject player selection if they do not have enough gold"""
185 dialogue = ["You don't have enough gold!"]
186 self.dialogue_box = self.make_dialogue_box(dialogue, 0)
187
188 if keys[pg.K_SPACE] and (current_time - self.timer) > 200:
189 self.state = 'select'
190 self.timer = current_time
191 self.selection_arrow.rect.topleft = self.arrow_pos1
192
193
194 def accept_purchase(self, keys, current_time):
195 """Accept purchase and confirm with message"""
196 dialogue = ["Your health has been restored!"]
197 self.dialogue_box = self.make_dialogue_box(dialogue, 0)
198 self.gold_box = self.make_gold_box()
199
200 if keys[pg.K_SPACE] and (current_time - self.timer) > 200:
201 self.state = 'select'
202 self.timer = current_time
203 self.selection_arrow.rect.topleft = self.arrow_pos1
204
205
206 def update(self, keys, current_time):
207 """Updates the shop GUI"""
208 state_function = self.state_dict[self.state]
209 state_function(keys, current_time)
210
211
212 def draw(self, surface):
213 """Draw GUI to level surface"""
214 state_list1 = ['dialogue', 'reject', 'accept']
215 state_list2 = ['select', 'confirm']
216
217 if self.state in state_list1:
218 surface.blit(self.dialogue_box.image, self.dialogue_box.rect)
219 surface.blit(self.gold_box.image, self.gold_box.rect)
220 elif self.state in state_list2:
221 surface.blit(self.dialogue_box.image, self.dialogue_box.rect)
222 surface.blit(self.selection_box.image, self.selection_box.rect)
223 surface.blit(self.selection_arrow.image, self.selection_arrow.rect)
224 surface.blit(self.gold_box.image, self.gold_box.rect)
225
226
227
228
229class Shop(tools._State):
230 """Basic shop state"""
231 def __init__(self, name):
232 super(Shop, self).__init__(name)
233 self.map_width = 13
234 self.map_height = 10
235
236 def startup(self, current_time, game_data):
237 """Startup state"""
238 self.game_data = game_data
239 self.current_time = current_time
240 self.state = 'normal'
241 self.get_image = tools.get_image
242 self.dialogue = self.make_dialogue()
243 self.background = self.make_background()
244 self.gui = Gui('Inn', self.dialogue, self)
245
246
247 def make_dialogue(self):
248 """Make the list of dialogue phrases"""
249 dialogue = ["Welcome to the " + self.name + "!",
250 "Would you like to rent a room to restore your health?"]
251
252 return dialogue
253
254
255
256 def make_background(self):
257 """Make the level surface"""
258 background = pg.sprite.Sprite()
259 surface = pg.Surface(c.SCREEN_SIZE).convert()
260 surface.fill(c.BLACK_BLUE)
261 background.image = surface
262 background.rect = background.image.get_rect()
263
264 player = self.make_sprite('player', 96, 32, 150)
265 shop_owner = self.make_sprite('man1', 32, 32, 600)
266 counter = self.make_counter()
267
268 background.image.blit(player.image, player.rect)
269 background.image.blit(shop_owner.image, shop_owner.rect)
270 background.image.blit(counter.image, counter.rect)
271
272 return background
273
274
275 def make_sprite(self, key, coordx, coordy, x, y=304):
276 """Get the image for the player"""
277 spritesheet = setup.GFX[key]
278 surface = pg.Surface((32, 32))
279 surface.set_colorkey(c.BLACK)
280 image = self.get_image(coordx, coordy, 32, 32, spritesheet)
281 rect = image.get_rect()
282 surface.blit(image, rect)
283
284 surface = pg.transform.scale(surface, (96, 96))
285 rect = surface.get_rect(left=x, centery=y)
286 sprite = pg.sprite.Sprite()
287 sprite.image = surface
288 sprite.rect = rect
289
290 return sprite
291
292
293 def make_counter(self):
294 """Make the counter to conduct business"""
295 sprite_sheet = copy.copy(setup.GFX['house'])
296 sprite = pg.sprite.Sprite()
297 sprite.image = self.get_image(102, 64, 26, 82, sprite_sheet)
298 sprite.image = pg.transform.scale2x(sprite.image)
299 sprite.rect = sprite.image.get_rect(left=550, top=225)
300
301 return sprite
302
303
304
305
306 def update(self, surface, keys, current_time):
307 """Update level state"""
308 self.gui.update(keys, current_time)
309 self.draw_level(surface)
310 if self.done:
311 self.next = c.TOWN
312
313
314 def draw_level(self, surface):
315 """Blit graphics to game surface"""
316 surface.blit(self.background.image, self.background.rect)
317 self.gui.draw(surface)