data/components/textbox.py (view raw)
1__author__ = 'justinarmstrong'
2import copy
3import pygame as pg
4from .. import setup
5from .. import constants as c
6
7
8
9class NextArrow(pg.sprite.Sprite):
10 """Flashing arrow indicating more dialogue"""
11 def __init__(self):
12 super(NextArrow, self).__init__()
13 self.image = setup.GFX['fancyarrow']
14 self.rect = self.image.get_rect(right=780,
15 bottom=135)
16
17
18class DialogueBox(object):
19 """Text box used for dialogue"""
20 def __init__(self, dialogue, index=0, image_key='dialoguebox', item=None):
21 self.item = item
22 self.bground = setup.GFX[image_key]
23 self.rect = self.bground.get_rect(centerx=400)
24 self.arrow_timer = 0.0
25 self.font = pg.font.Font(setup.FONTS[c.MAIN_FONT], 22)
26 self.dialogue_list = dialogue
27 self.index = index
28 self.image = self.make_dialogue_box_image()
29 self.arrow = NextArrow()
30 self.check_to_draw_arrow()
31 self.done = False
32 self.allow_input = False
33 self.name = image_key
34
35
36 def make_dialogue_box_image(self):
37 """Make the image of the dialogue box"""
38 image = pg.Surface(self.rect.size)
39 image.set_colorkey(c.BLACK)
40 image.blit(self.bground, (0, 0))
41
42 dialogue_image = self.font.render(self.dialogue_list[self.index],
43 True,
44 c.NEAR_BLACK)
45 dialogue_rect = dialogue_image.get_rect(left=50, top=50)
46 image.blit(dialogue_image, dialogue_rect)
47
48 return image
49
50 def update(self, keys, current_time):
51 """Updates scrolling text"""
52 self.current_time = current_time
53 self.draw_box(current_time)
54 self.terminate_check(keys)
55
56 def draw_box(self, current_time, x=400):
57 """Reveal dialogue on textbox"""
58 self.image = self.make_dialogue_box_image()
59 self.check_to_draw_arrow()
60
61 def terminate_check(self, keys):
62 """Remove textbox from sprite group after 2 seconds"""
63 if keys[pg.K_SPACE] and self.allow_input:
64 self.done = True
65
66 if not keys[pg.K_SPACE]:
67 self.allow_input = True
68
69 def check_to_draw_arrow(self):
70 """Blink arrow if more text needs to be read"""
71 if self.index < len(self.dialogue_list) - 1:
72 self.image.blit(self.arrow.image, self.arrow.rect)
73 else:
74 pass
75
76
77class ItemBox(DialogueBox):
78 """Text box for information like obtaining new items"""
79 def __init__(self, dialogue, item=None):
80 super(ItemBox, self).__init__(None, 0, 'infobox', item)
81
82 def make_dialogue_box_image(self):
83 """Make the image of the dialogue box"""
84 image = pg.Surface(self.rect.size)
85 image.set_colorkey(c.BLACK)
86 image.blit(self.bground, (0, 0))
87
88 if self.item:
89 type = 'Healing Potion'
90 total = str(1)
91 dialogue = 'You received ' + total + ' ' + type + '.'
92 self.dialogue_list = [dialogue]
93 self.item = None
94
95 dialogue_image = self.font.render(self.dialogue_list[self.index],
96 False,
97 c.NEAR_BLACK)
98 dialogue_rect = dialogue_image.get_rect(left=50, top=50)
99 image.blit(dialogue_image, dialogue_rect)
100
101 return image
102
103
104class TextHandler(object):
105 """Handles interaction between sprites to create dialogue boxes"""
106
107 def __init__(self, level):
108 self.player = level.player
109 self.sprites = level.sprites
110 self.talking_sprite = None
111 self.textbox = None
112 self.allow_input = False
113 self.level = level
114 self.last_textbox_timer = 0.0
115 self.game_data = level.game_data
116
117 def update(self, keys, current_time):
118 """Checks for the creation of Dialogue boxes"""
119 if keys[pg.K_SPACE] and not self.textbox and self.allow_input:
120 for sprite in self.sprites:
121 if (current_time - self.last_textbox_timer) > 300:
122 if self.player.state == 'resting':
123 self.allow_input = False
124 self.check_for_dialogue(sprite)
125
126 if self.textbox:
127 if self.talking_sprite.name == 'treasurechest':
128 self.open_chest(self.talking_sprite)
129
130 self.textbox.update(keys, current_time)
131
132 if self.textbox.done:
133
134 if self.textbox.index < (len(self.textbox.dialogue_list) - 1):
135 index = self.textbox.index + 1
136 dialogue = self.textbox.dialogue_list
137 if self.textbox.name == 'dialoguebox':
138 self.textbox = DialogueBox(dialogue, index)
139 elif self.textbox.name == 'infobox':
140 self.textbox = ItemBox(dialogue, index)
141 elif self.talking_sprite.item:
142 self.check_for_item()
143 elif self.talking_sprite.battle:
144 self.game_data['battle type'] = self.talking_sprite.battle
145 self.end_dialogue(current_time)
146 self.level.switch_to_battle = True
147 elif self.talking_sprite.name == 'oldmanbrother' and \
148 self.game_data['talked to sick brother'] and \
149 not self.game_data['has brother elixir']:
150 self.talking_sprite.item = 'ELIXIR'
151 self.game_data['has brother elixir'] = True
152 self.check_for_item()
153 dialogue = ['Hurry! There is precious little time.']
154 self.talking_sprite.dialogue = dialogue
155 elif self.talking_sprite.name == 'oldman':
156 if self.game_data['has brother elixir'] and \
157 not self.game_data['elixir received']:
158 del self.game_data['player inventory']['ELIXIR']
159 self.game_data['elixir received'] = True
160 dialogue = ['My good health is thanks to you.',
161 'I will be forever in your debt.']
162 self.talking_sprite.dialogue = dialogue
163 elif not self.game_data['talked to sick brother']:
164 self.game_data['talked to sick brother'] = True
165
166 dialogue = ['Hurry to the NorthEast Shores!',
167 'I do not have much time left.']
168 self.talking_sprite.dialogue = dialogue
169 else:
170 self.end_dialogue(current_time)
171 elif self.talking_sprite.name == 'king':
172
173 if (self.game_data['crown quest']
174 and not self.game_data['delivered crown']):
175 retrieved_crown_dialogue = ['My crown! You recovered my stolen crown!!!',
176 'I can not believe what I see before my eyes.',
177 'You are truly a brave and noble warrior.',
178 'Henceforth, I name thee Grand Protector of this Town!',
179 'Go forth and be recognized.',
180 'You are the greatest warrior this world has ever known.']
181 self.talking_sprite.dialogue = retrieved_crown_dialogue
182 self.game_data['delivered crown'] = True
183 self.end_dialogue(current_time)
184 elif self.game_data['delivered crown']:
185 thank_you_dialogue = ['Thank you for retrieving my crown.',
186 'My kingdom is forever in your debt.']
187 self.talking_sprite.dialogue = thank_you_dialogue
188 self.end_dialogue(current_time)
189 else:
190 self.end_dialogue(current_time)
191 else:
192 self.end_dialogue(current_time)
193
194
195 if not keys[pg.K_SPACE]:
196 self.allow_input = True
197
198 def end_dialogue(self, current_time):
199 """
200 End dialogue state for level.
201 """
202 self.talking_sprite = None
203 self.level.state = 'normal'
204 self.textbox = None
205 self.last_textbox_timer = current_time
206 self.reset_sprite_direction()
207
208 def check_for_dialogue(self, sprite):
209 """Checks if a sprite is in the correct location to give dialogue"""
210 player = self.player
211 tile_x, tile_y = player.location
212
213 if player.direction == 'up':
214 if sprite.location == [tile_x, tile_y - 1]:
215 self.textbox = DialogueBox(sprite.dialogue)
216 sprite.direction = 'down'
217 self.talking_sprite = sprite
218 elif player.direction == 'down':
219 if sprite.location == [tile_x, tile_y + 1]:
220 self.textbox = DialogueBox(sprite.dialogue)
221 sprite.direction = 'up'
222 self.talking_sprite = sprite
223 elif player.direction == 'left':
224 if sprite.location == [tile_x - 1, tile_y]:
225 self.textbox = DialogueBox(sprite.dialogue)
226 sprite.direction = 'right'
227 self.talking_sprite = sprite
228 elif player.direction == 'right':
229 if sprite.location == [tile_x + 1, tile_y]:
230 self.textbox = DialogueBox(sprite.dialogue)
231 sprite.direction = 'left'
232 self.talking_sprite = sprite
233
234 def check_for_item(self):
235 """Checks if sprite has an item to give to the player"""
236 item = self.talking_sprite.item
237
238 if item:
239 if item in self.game_data['player inventory']:
240 if 'quantity' in self.game_data['player inventory'][item]:
241 self.game_data['player inventory'][item]['quantity'] += 1
242 else:
243 self.add_new_item_to_inventory(item)
244
245 self.update_game_items_info(self.talking_sprite)
246 self.talking_sprite.item = None
247
248 if self.talking_sprite.name == 'treasurechest':
249 self.talking_sprite.dialogue = ['Empty.']
250
251 if item == 'ELIXIR':
252 self.game_data['has brother elixir'] = True
253 self.game_data['old man gift'] = 'Fire Blast'
254 dialogue = ['Hurry! There is precious little time.']
255 self.level.reset_dialogue = self.talking_sprite, dialogue
256
257 def add_new_item_to_inventory(self, item):
258 inventory = self.game_data['player inventory']
259 potions = ['Healing Potion', 'Ether Potion']
260 if item in potions:
261 inventory[item] = dict([('quantity',1),
262 ('value',15)])
263 elif item == 'ELIXIR':
264 inventory[item] = dict([('quantity',1)])
265 elif item == 'Fire Blast':
266 inventory[item] = dict([('magic points', 25),
267 ('power', 10)])
268 else:
269 pass
270
271 def update_game_items_info(self, sprite):
272 if sprite.name == 'treasurechest':
273 self.game_data['treasure{}'.format(sprite.id)] = False
274 elif sprite.name == 'oldmanbrother':
275 self.game_data['brother elixir'] = False
276
277 def reset_sprite_direction(self):
278 """Reset sprite to default direction"""
279 for sprite in self.sprites:
280 if sprite.state == 'resting':
281 sprite.direction = sprite.default_direction
282
283
284 def draw(self, surface):
285 """Draws textbox to surface"""
286 if self.textbox:
287 surface.blit(self.textbox.image, self.textbox.rect)
288
289
290 def make_textbox(self, name, dialogue, item=None):
291 """Make textbox on demand"""
292 if name == 'itembox':
293 textbox = ItemBox(dialogue, item)
294 elif name == 'dialoguebox':
295 textbox = DialogueBox(dialogue)
296 else:
297 textbox = None
298
299 return textbox
300
301 def open_chest(self, sprite):
302 if sprite.name == 'treasurechest':
303 sprite.index = 1
304