all repos — Legends-RPG @ 2de767605689fc11924fff2ea10628bb0e5b1961

A fantasy mini-RPG built with Python and Pygame.

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)