Mercurial > pyntnclick
comparison gamelib/scenes/bridge.py @ 853:f95830b58336
Merge pyntnclick
author | Stefano Rivera <stefano@rivera.za.net> |
---|---|
date | Sat, 21 Jun 2014 22:04:35 +0200 |
parents | 6a345dcbb209 |
children |
comparison
equal
deleted
inserted
replaced
546:ad4d6ffd25d7 | 853:f95830b58336 |
---|---|
3 import random | 3 import random |
4 | 4 |
5 from pygame.colordict import THECOLORS | 5 from pygame.colordict import THECOLORS |
6 from pygame.color import Color | 6 from pygame.color import Color |
7 from pygame.rect import Rect | 7 from pygame.rect import Rect |
8 from albow.music import change_playlist, get_music, PlayList | 8 |
9 from albow.resource import get_image | 9 from pyntnclick.i18n import _ |
10 | 10 from pyntnclick.utils import render_text |
11 from gamelib.cursor import CursorSprite | 11 from pyntnclick.cursor import CursorSprite |
12 from gamelib.state import Scene, Item, Thing, Result | 12 from pyntnclick.state import Scene, Item, Thing, Result |
13 from gamelib.sound import get_current_playlist | 13 from pyntnclick.scenewidgets import ( |
14 from gamelib.constants import DEBUG | 14 InteractNoImage, InteractRectUnion, InteractImage, InteractAnimated, |
15 from gamelib.scenewidgets import (InteractNoImage, InteractRectUnion, | 15 GenericDescThing, TakeableThing, InteractText) |
16 InteractImage, InteractAnimated, | |
17 GenericDescThing) | |
18 | 16 |
19 from gamelib.scenes.game_constants import PLAYER_ID | 17 from gamelib.scenes.game_constants import PLAYER_ID |
20 from gamelib.scenes.game_widgets import Door, BaseCamera, make_jim_dialog | 18 from gamelib.scenes.game_widgets import Door, BaseCamera, make_jim_dialog |
21 | 19 |
22 | 20 |
41 INITIAL_DATA = { | 39 INITIAL_DATA = { |
42 'ai status': 'online', # online, looping, dead | 40 'ai status': 'online', # online, looping, dead |
43 'ai panel': 'closed', # closed, open, broken | 41 'ai panel': 'closed', # closed, open, broken |
44 } | 42 } |
45 | 43 |
46 def __init__(self, state): | 44 def setup(self): |
47 super(Bridge, self).__init__(state) | |
48 self.background_playlist = None | 45 self.background_playlist = None |
49 self.add_item(Superconductor('superconductor')) | 46 self.add_item_factory(Superconductor) |
50 self.add_item(Stethoscope('stethoscope')) | 47 self.add_item_factory(TapedSuperconductor) |
48 self.add_item_factory(Stethoscope) | |
51 self.add_thing(ToMap()) | 49 self.add_thing(ToMap()) |
52 self.add_thing(MonitorCamera()) | 50 self.add_thing(MonitorCamera()) |
53 self.add_thing(MassageChair()) | 51 self.add_thing(MassageChair()) |
54 self.add_thing(MassageChairBase()) | 52 self.add_thing(MassageChairBase()) |
55 self.add_thing(StethoscopeThing()) | 53 self.add_thing(StethoscopeThing()) |
57 self.add_thing(LeftLights()) | 55 self.add_thing(LeftLights()) |
58 self.add_thing(RightLights()) | 56 self.add_thing(RightLights()) |
59 self.add_thing(JimPanel()) | 57 self.add_thing(JimPanel()) |
60 self.add_thing(StarField()) | 58 self.add_thing(StarField()) |
61 self.add_thing(GenericDescThing('bridge.wires', 1, | 59 self.add_thing(GenericDescThing('bridge.wires', 1, |
62 "The brightly coloured wires contrast with the drab walls.", | 60 _("The brightly coloured wires contrast with the drab walls."), |
63 ((46, 4, 711, 143),))) | 61 ((46, 4, 711, 143),))) |
64 self.add_thing(GenericDescThing('bridge.note', 2, | 62 self.add_thing(GenericDescThing('bridge.note', 2, |
65 "\"Dammit JIM, I'm a doctor, not an engineer!\"", | 63 _("\"Dammit JIM, I'm a doctor, not an engineer!\""), |
66 ( | 64 ( |
67 (491, 494, 194, 105), | 65 (491, 494, 194, 105), |
68 (422, 533, 71, 66), | 66 (422, 533, 71, 66), |
69 ))) | 67 ))) |
70 self.doctor = GenericDescThing('bridge.skel', 3, | 68 self.doctor = GenericDescThing('bridge.skel', 3, |
71 "A skeleton hangs improbably from the wires.", | 69 _("A skeleton hangs improbably from the wires."), |
72 ( | 70 ( |
73 (632, 148, 40, 29), | 71 (632, 148, 40, 29), |
74 (683, 176, 30, 101), | 72 (683, 176, 30, 101), |
75 (652, 274, 45, 96), | 73 (652, 274, 45, 96), |
76 (639, 180, 11, 95), | 74 (639, 180, 11, 95), |
77 )) | 75 )) |
78 self.add_thing(self.doctor) | 76 self.add_thing(self.doctor) |
79 | 77 |
80 def enter(self): | 78 def enter(self): |
81 pieces = [get_music(x, prefix='sounds') for x in self.MUSIC] | 79 pieces = [self.sound.get_music(x) for x in self.MUSIC] |
82 self.background_playlist = PlayList(pieces, random=True, repeat=True) | 80 self.background_playlist = self.sound.get_playlist(pieces, random=True, |
83 change_playlist(self.background_playlist) | 81 repeat=True) |
82 self.sound.change_playlist(self.background_playlist) | |
84 | 83 |
85 def leave(self): | 84 def leave(self): |
86 change_playlist(None) | 85 self.sound.change_playlist(None) |
87 | 86 |
88 | 87 |
89 class ToMap(Door): | 88 class ToMap(Door): |
90 | 89 |
91 SCENE = "bridge" | 90 SCENE = "bridge" |
110 | 109 |
111 def interact_without(self): | 110 def interact_without(self): |
112 return Result(detail_view='bridge_comp_detail') | 111 return Result(detail_view='bridge_comp_detail') |
113 | 112 |
114 def interact_with_titanium_leg(self, item): | 113 def interact_with_titanium_leg(self, item): |
115 return Result("You can't break the duraplastic screen.") | 114 return Result(_("You can't break the duraplastic screen.")) |
116 | 115 |
117 def interact_with_machete(self, item): | 116 def interact_with_machete(self, item): |
118 return Result("Scratching the screen won't help you.") | 117 return Result(_("Scratching the screen won't help you.")) |
119 | 118 |
120 def get_description(self): | 119 def get_description(self): |
121 return "The main bridge computer screen." | 120 return _("The main bridge computer screen.") |
122 | 121 |
123 | 122 |
124 class MassageChairBase(Thing): | 123 class MassageChairBase(Thing): |
125 "The captain's massage chair, contains superconductor" | 124 "The captain's massage chair, contains superconductor" |
126 | 125 |
139 def interact_without(self): | 138 def interact_without(self): |
140 return Result(detail_view='chair_detail') | 139 return Result(detail_view='chair_detail') |
141 | 140 |
142 def get_description(self): | 141 def get_description(self): |
143 if self.get_data('contains_superconductor'): | 142 if self.get_data('contains_superconductor'): |
144 return ("A top of the line Massage-o-Matic Captain's Executive" | 143 return _("A top of the line Massage-o-Matic Captain's Executive" |
145 " Command Chair. It's massaging a skeleton.") | 144 " Command Chair. It's massaging a skeleton.") |
146 return "The chair won't work any more, it has no power." | 145 return _("The chair won't work any more, it has no power.") |
147 | 146 |
148 | 147 |
149 class MassageChair(Thing): | 148 class MassageChair(Thing): |
150 "The captain's massage chair, contains superconductor" | 149 "The captain's massage chair, contains superconductor" |
151 | 150 |
164 } | 163 } |
165 | 164 |
166 INITIAL = 'chair' | 165 INITIAL = 'chair' |
167 | 166 |
168 def get_description(self): | 167 def get_description(self): |
169 return self.state.current_scene.things['bridge.massagechair_base'] \ | 168 base = self.game.get_current_scene().things['bridge.massagechair_base'] |
170 .get_description() | 169 return base.get_description() |
171 | 170 |
172 def is_interactive(self, tool=None): | 171 def is_interactive(self, tool=None): |
173 return False | 172 return False |
174 | 173 |
175 | 174 |
176 class Stethoscope(Item): | 175 class Stethoscope(Item): |
177 "Used for cracking safes. Found on the doctor on the chair" | 176 "Used for cracking safes. Found on the doctor on the chair" |
178 | 177 |
178 NAME = 'stethoscope' | |
179 INVENTORY_IMAGE = 'stethoscope.png' | 179 INVENTORY_IMAGE = 'stethoscope.png' |
180 CURSOR = CursorSprite('stethoscope.png') | 180 CURSOR = CursorSprite('stethoscope.png') |
181 | 181 |
182 | 182 |
183 class StethoscopeThing(Thing): | 183 class StethoscopeThing(TakeableThing): |
184 "Stehoscope on the doctor" | 184 "Stethoscope on the doctor" |
185 | 185 |
186 NAME = 'bridge.stethoscope' | 186 NAME = 'bridge.stethoscope' |
187 | 187 |
188 INTERACTS = { | 188 INTERACTS = { |
189 'stethoscope': InteractImage(650, 178, 'hanging_stethoscope.png'), | 189 'stethoscope': InteractImage(650, 178, 'hanging_stethoscope.png'), |
190 } | 190 } |
191 | 191 |
192 INITIAL = 'stethoscope' | 192 INITIAL = 'stethoscope' |
193 ITEM = 'stethoscope' | |
193 | 194 |
194 def get_description(self): | 195 def get_description(self): |
195 return "A stethoscope hangs from the neck of the skeleton." | 196 return _("A stethoscope hangs from the neck of the skeleton.") |
196 | 197 |
197 def interact_without(self): | 198 def interact_without(self): |
198 self.state.add_inventory_item('stethoscope') | 199 self.take() |
199 self.scene.remove_thing(self) | |
200 # Fill in the doctor's rect | 200 # Fill in the doctor's rect |
201 self.scene.doctor.rect.append(self.rect) | 201 self.scene.doctor.rect.append(self.rect) |
202 return Result("You pick up the stethoscope and verify that the" | 202 return Result(_("You pick up the stethoscope and verify that the" |
203 " doctor's heart has stopped. Probably a while ago.") | 203 " doctor's heart has stopped. Probably a while ago.")) |
204 | 204 |
205 | 205 |
206 class TapedSuperconductor(Item): | 206 class TapedSuperconductor(Item): |
207 "Used for connecting high-powered parts of the ship up" | 207 "Used for connecting high-powered parts of the ship up" |
208 | 208 |
209 NAME = 'taped_superconductor' | |
209 INVENTORY_IMAGE = 'superconductor_taped.png' | 210 INVENTORY_IMAGE = 'superconductor_taped.png' |
210 CURSOR = CursorSprite('superconductor_taped_cursor.png') | 211 CURSOR = CursorSprite('superconductor_taped_cursor.png') |
211 | 212 |
212 | 213 |
213 class Superconductor(Item): | 214 class Superconductor(Item): |
214 "Used for connecting high-powered parts of the ship up" | 215 "Used for connecting high-powered parts of the ship up" |
215 | 216 |
217 NAME = 'superconductor' | |
216 INVENTORY_IMAGE = 'superconductor_fixed.png' | 218 INVENTORY_IMAGE = 'superconductor_fixed.png' |
217 CURSOR = CursorSprite('superconductor_fixed.png') | 219 CURSOR = CursorSprite('superconductor_fixed.png') |
218 | 220 |
219 def interact_with_duct_tape(self, item): | 221 def interact_with_duct_tape(self, item): |
220 taped_superconductor = TapedSuperconductor('taped_superconductor') | 222 self.game.replace_inventory_item(self.name, 'taped_superconductor') |
221 self.state.add_item(taped_superconductor) | 223 return Result(_("You rip off a piece of duct tape and stick it on the" |
222 self.state.replace_inventory_item(self.name, taped_superconductor.name) | 224 " superconductor. It almost sticks to itself, but you" |
223 return Result("You rip off a piece of duct tape and stick it on the" | 225 " successfully avoid disaster.")) |
224 " superconductor. It almost sticks to itself, but you" | 226 |
225 " successfully avoid disaster.") | 227 |
226 | 228 class SuperconductorThing(TakeableThing): |
227 | |
228 class SuperconductorThing(Thing): | |
229 "Superconductor from the massage chair." | 229 "Superconductor from the massage chair." |
230 | 230 |
231 NAME = 'bridge.superconductor' | 231 NAME = 'bridge.superconductor' |
232 | 232 |
233 INTERACTS = { | 233 INTERACTS = { |
234 'superconductor': InteractImage(158, 138, 'superconductor.png'), | 234 'superconductor': InteractImage(158, 138, 'superconductor.png'), |
235 } | 235 } |
236 | 236 |
237 INITIAL = 'superconductor' | 237 INITIAL = 'superconductor' |
238 | 238 ITEM = 'superconductor' |
239 def interact_without(self): | 239 |
240 self.state.add_inventory_item('superconductor') | 240 def interact_without(self): |
241 self.state.current_scene.things['bridge.massagechair_base'] \ | 241 self.game.scenes['bridge'].things['bridge.massagechair_base'] \ |
242 .set_data('contains_superconductor', False) | 242 .set_data('contains_superconductor', False) |
243 self.scene.remove_thing(self) | 243 self.take() |
244 return (Result("The superconductor module unclips easily."), | 244 return (Result(_("The superconductor module unclips easily.")), |
245 make_jim_dialog(("Prisoner %s. That chair you've destroyed" | 245 make_jim_dialog(_("Prisoner %s. That chair you've destroyed" |
246 " was property of the ship's captain. " | 246 " was property of the ship's captain. " |
247 "You will surely be punished." | 247 "You will surely be punished.") |
248 % PLAYER_ID), self.state)) | 248 % PLAYER_ID, self.game)) |
249 | 249 |
250 | 250 |
251 class StarField(Thing): | 251 class StarField(Thing): |
252 | 252 |
253 NAME = 'bridge.stars' | 253 NAME = 'bridge.stars' |
265 return False | 265 return False |
266 | 266 |
267 | 267 |
268 class BlinkingLights(Thing): | 268 class BlinkingLights(Thing): |
269 | 269 |
270 def __init__(self): | 270 def setup(self): |
271 super(BlinkingLights, self).__init__() | |
272 self.description = None | 271 self.description = None |
273 | 272 |
274 def is_interactive(self, tool=None): | 273 def is_interactive(self, tool=None): |
275 return False | 274 return False |
276 | 275 |
277 def leave(self): | 276 def leave(self): |
278 self.description = random.choice([ | 277 self.description = random.choice([ |
279 "The lights flash in interesting patterns.", | 278 _("The lights flash in interesting patterns."), |
280 "The flashing lights don't mean anything to you.", | 279 _("The flashing lights don't mean anything to you."), |
281 "The console lights flash and flicker.", | 280 _("The console lights flash and flicker."), |
282 ]) | 281 ]) |
283 | 282 |
284 def get_description(self): | 283 def get_description(self): |
285 if not self.description: | 284 if not self.description: |
286 self.leave() | 285 self.leave() |
330 | 329 |
331 INITIAL = 'closed' | 330 INITIAL = 'closed' |
332 | 331 |
333 def get_description(self): | 332 def get_description(self): |
334 if self.scene.get_data('ai panel') == 'closed': | 333 if self.scene.get_data('ai panel') == 'closed': |
335 return "The sign reads 'Warning: Authorized Techinicians Only'." | 334 return _("The sign reads 'Warning: Authorized Techinicians Only'.") |
336 | 335 |
337 def interact_without(self): | 336 def select_interact(self): |
338 if self.scene.get_data('ai status') == 'online': | 337 status = self.scene.get_data('ai panel') |
338 return status or self.INITIAL | |
339 | |
340 def interact_without(self): | |
341 ai_status = self.state.get_jim_state() | |
342 if ai_status == 'online': | |
339 return self.interact_default(None) | 343 return self.interact_default(None) |
340 elif self.scene.get_data('ai panel') == 'closed': | 344 elif self.scene.get_data('ai panel') == 'closed': |
341 return Result("You are unable to open the panel with your" | 345 return Result(_("You are unable to open the panel with your" |
342 " bare hands.") | 346 " bare hands.")) |
343 elif self.scene.get_data('ai panel') == 'open': | 347 elif self.scene.get_data('ai panel') == 'open': |
344 self.scene.set_data('ai panel', 'broken') | 348 self.scene.set_data('ai panel', 'broken') |
345 self.scene.set_data('ai status', 'dead') | 349 self.state.break_ai() |
346 self.set_interact('broken') | 350 self.set_interact() |
347 return Result("You unplug various important-looking wires.") | 351 return Result(_("You unplug various important-looking wires.")) |
348 | 352 |
349 def interact_with_machete(self, item): | 353 def interact_with_machete(self, item): |
350 if self.scene.get_data('ai status') == 'online': | 354 ai_status = self.state.get_jim_state() |
355 if ai_status == 'online': | |
351 return self.interact_default(item) | 356 return self.interact_default(item) |
352 elif self.scene.get_data('ai panel') == 'closed': | 357 elif self.scene.get_data('ai panel') == 'closed': |
353 self.scene.set_data('ai panel', 'open') | 358 self.scene.set_data('ai panel', 'open') |
354 self.set_interact('open') | 359 self.set_interact() |
355 return Result("Using the machete, you lever the panel off.") | 360 return Result(_("Using the machete, you lever the panel off.")) |
356 elif self.scene.get_data('ai panel') == 'open': | 361 elif self.scene.get_data('ai panel') == 'open': |
357 self.scene.set_data('ai panel', 'broken') | 362 self.scene.set_data('ai panel', 'broken') |
358 self.scene.set_data('ai status', 'dead') | 363 self.state.break_ai() |
359 self.set_interact('broken') | 364 self.set_interact() |
360 return Result("You smash various delicate components with" | 365 return Result(_("You smash various delicate components with" |
361 " the machete.") | 366 " the machete.")) |
362 | 367 |
363 def interact_default(self, item): | 368 def interact_default(self, item): |
364 if self.scene.get_data('ai status') == 'online': | 369 if self.state.get_jim_state() == 'online': |
365 return (Result('You feel a shock from the panel.'), | 370 return (Result(_('You feel a shock from the panel.')), |
366 make_jim_dialog("Prisoner %s. Please step away from the" | 371 make_jim_dialog(_("Prisoner %s. Please step away from the" |
367 " panel. You are not an authorized" | 372 " panel. You are not an authorized" |
368 " technician." % PLAYER_ID, self.state)) | 373 " technician.") % PLAYER_ID, self.game)) |
369 | 374 |
370 | 375 |
371 class ChairDetail(Scene): | 376 class ChairDetail(Scene): |
372 | 377 |
373 FOLDER = 'bridge' | 378 FOLDER = 'bridge' |
374 BACKGROUND = 'chair_detail.png' | 379 BACKGROUND = 'chair_detail.png' |
375 NAME = 'chair_detail' | 380 NAME = 'chair_detail' |
376 | 381 |
377 def __init__(self, state): | 382 def setup(self): |
378 super(ChairDetail, self).__init__(state) | |
379 self.add_thing(SuperconductorThing()) | 383 self.add_thing(SuperconductorThing()) |
380 | 384 |
381 | 385 |
382 # classes related the computer detail | 386 # classes related the computer detail |
383 | 387 |
386 """Tab for log screen""" | 390 """Tab for log screen""" |
387 | 391 |
388 NAME = 'bridge_comp.screen' | 392 NAME = 'bridge_comp.screen' |
389 | 393 |
390 INTERACTS = { | 394 INTERACTS = { |
391 'log tab': InteractNoImage(100, 53, 94, 37), | 395 'log tab': InteractText(100, 53, 94, 37, _("Logs"), |
396 'lightgreen', 20, 'DejaVuSans-Bold.ttf', True), | |
392 } | 397 } |
393 INITIAL = 'log tab' | 398 INITIAL = 'log tab' |
394 COMPUTER = 'bridge_comp_detail' | 399 COMPUTER = 'bridge_comp_detail' |
395 | 400 |
396 def is_interactive(self, tool=None): | 401 def is_interactive(self, tool=None): |
397 return self.state.detail_views[self.COMPUTER].get_data('tab') != 'log' | 402 return self.game.detail_views[self.COMPUTER].get_data('tab') != 'log' |
398 | 403 |
399 def interact_without(self): | 404 def interact_without(self): |
400 self.state.detail_views[self.COMPUTER].set_data('tab', 'log') | 405 self.game.detail_views[self.COMPUTER].set_data('tab', 'log') |
401 self.state.detail_views[self.COMPUTER].set_background() | 406 self.game.detail_views[self.COMPUTER].set_background() |
402 return Result(soundfile='beep550.ogg') | 407 return Result(soundfile='beep550.ogg') |
403 | 408 |
404 | 409 |
405 class AlertTab(Thing): | 410 class AlertTab(Thing): |
406 """Tab for alert screen""" | 411 """Tab for alert screen""" |
407 | 412 |
408 NAME = 'bridge_comp.alert_tab' | 413 NAME = 'bridge_comp.alert_tab' |
409 | 414 |
410 INTERACTS = { | 415 INTERACTS = { |
411 'alert tab': InteractNoImage(12, 53, 88, 37), | 416 'alert tab': InteractText(12, 53, 88, 37, _("Alerts"), |
417 'orange', 20, 'DejaVuSans-Bold.ttf', True), | |
412 } | 418 } |
413 INITIAL = 'alert tab' | 419 INITIAL = 'alert tab' |
414 COMPUTER = 'bridge_comp_detail' | 420 COMPUTER = 'bridge_comp_detail' |
415 | 421 |
416 def is_interactive(self, tool=None): | 422 def is_interactive(self, tool=None): |
417 return (self.state.detail_views[self.COMPUTER].get_data('tab') | 423 return (self.game.detail_views[self.COMPUTER].get_data('tab') |
418 != 'alert') | 424 != 'alert') |
419 | 425 |
420 def interact_without(self): | 426 def interact_without(self): |
421 self.state.detail_views[self.COMPUTER].set_data('tab', 'alert') | 427 self.game.detail_views[self.COMPUTER].set_data('tab', 'alert') |
422 self.state.detail_views[self.COMPUTER].set_background() | 428 self.game.detail_views[self.COMPUTER].set_background() |
423 return Result(soundfile='beep550.ogg') | 429 return Result(soundfile='beep550.ogg') |
424 | 430 |
425 | 431 |
426 class NavTab(Thing): | 432 class NavTab(Thing): |
427 """Tab for the Navigation screen""" | 433 """Tab for the Navigation screen""" |
428 | 434 |
429 NAME = 'bridge_comp.nav_tab' | 435 NAME = 'bridge_comp.nav_tab' |
430 | 436 |
431 INTERACTS = { | 437 INTERACTS = { |
432 'nav tab': InteractNoImage(197, 53, 126, 37), | 438 'nav tab': InteractText(197, 53, 126, 37, _("Navigation"), |
439 'darkblue', 20, 'DejaVuSans-Bold.ttf', True), | |
433 } | 440 } |
434 INITIAL = 'nav tab' | 441 INITIAL = 'nav tab' |
435 COMPUTER = 'bridge_comp_detail' | 442 COMPUTER = 'bridge_comp_detail' |
436 | 443 |
437 def is_interactive(self, tool=None): | 444 def is_interactive(self, tool=None): |
438 return self.state.detail_views[self.COMPUTER].get_data('tab') != 'nav' | 445 return self.game.detail_views[self.COMPUTER].get_data('tab') != 'nav' |
439 | 446 |
440 def interact_without(self): | 447 def interact_without(self): |
441 self.state.detail_views[self.COMPUTER].set_data('tab', 'nav') | 448 self.game.detail_views[self.COMPUTER].set_data('tab', 'nav') |
442 self.state.detail_views[self.COMPUTER].set_background() | 449 self.game.detail_views[self.COMPUTER].set_background() |
443 return Result(soundfile='beep550.ogg') | 450 return Result(soundfile='beep550.ogg') |
444 | 451 |
445 | 452 |
446 class DestNavPageLine(Thing): | 453 class DestNavPageLine(Thing): |
447 """The destination navigation lines.""" | 454 """The destination navigation lines.""" |
448 | 455 |
449 INITIAL = 'line' | 456 INITIAL = 'line' |
450 COMPUTER = 'bridge_comp_detail' | 457 COMPUTER = 'bridge_comp_detail' |
451 | 458 |
452 def __init__(self, number, rect, ai_blocked): | 459 def __init__(self, number, rect, ai_blocked, dest): |
453 super(DestNavPageLine, self).__init__() | 460 super(DestNavPageLine, self).__init__() |
454 self.name = 'bridge_comp.nav_line%s' % number | 461 self.name = 'bridge_comp.nav_line%s' % number |
455 if DEBUG: | 462 # set debugging higlight color for when DEBUG is on. |
456 self._interact_hilight_color = Color(THECOLORS.keys()[number]) | 463 self._interact_hilight_color = Color(THECOLORS.keys()[number]) |
457 r = Rect(rect) | 464 r = Rect(rect) |
465 # We dynamically generate the interact rect here. | |
458 self.interacts = {} | 466 self.interacts = {} |
459 self.interacts['line'] = InteractNoImage(r.x, r.y, r.w, r.h) | 467 self.interacts['line'] = InteractText(r.x, r.y, r.w, r.h, |
468 dest, 'darkblue', 16, 'DejaVuSans-Bold.ttf', False) | |
460 # Whether JIM blocks this | 469 # Whether JIM blocks this |
461 self.ai_blocked = ai_blocked | 470 self.ai_blocked = ai_blocked |
462 self.set_interact('line') | 471 self.set_interact() |
463 | 472 |
464 def is_interactive(self, tool=None): | 473 def is_interactive(self, tool=None): |
465 return self.state.detail_views[self.COMPUTER].get_data('tab') == 'nav' | 474 return self.game.detail_views[self.COMPUTER].get_data('tab') == 'nav' |
466 | 475 |
467 def interact_without(self): | 476 def interact_without(self): |
468 if self.state.scenes['bridge'].get_data('ai status') == 'online': | 477 if self.game.scenes['bridge'].get_data('ai status') == 'online': |
469 return make_jim_dialog("You are not authorized to change the" | 478 return make_jim_dialog(_("You are not authorized to change the" |
470 " destination.", self.state) | 479 " destination."), self.game) |
471 if not self.ai_blocked: | 480 if not self.ai_blocked: |
472 return Result("There's no good reason to choose to go to the" | 481 return Result(_("There's no good reason to choose to go to the" |
473 " penal colony.") | 482 " penal colony.")) |
474 if self.state.scenes['bridge'].get_data('ai status') == 'looping': | 483 if self.game.scenes['bridge'].get_data('ai status') == 'looping': |
475 return Result("You could change the destination, but when JIM" | 484 return Result(_("You could change the destination, but when JIM" |
476 " recovers, it'll just get reset.") | 485 " recovers, it'll just get reset.")) |
477 if self.state.scenes['bridge'].get_data('ai status') == 'dead': | 486 if self.game.scenes['bridge'].get_data('ai status') == 'dead': |
478 return Result("You change the destination.", | 487 return Result(_("You change the destination."), |
479 soundfile="beep550.ogg", end_game=True) | 488 soundfile="beep550.ogg", end_game=True) |
480 | 489 |
481 | 490 |
482 class CompUpButton(Thing): | 491 class CompUpButton(Thing): |
483 """Up button on log screen""" | 492 """Up button on log screen""" |
489 } | 498 } |
490 INITIAL = 'up' | 499 INITIAL = 'up' |
491 COMPUTER = 'bridge_comp_detail' | 500 COMPUTER = 'bridge_comp_detail' |
492 | 501 |
493 def is_interactive(self, tool=None): | 502 def is_interactive(self, tool=None): |
494 tab = self.state.detail_views[self.COMPUTER].get_data('tab') | 503 tab = self.game.detail_views[self.COMPUTER].get_data('tab') |
495 page = self.state.detail_views[self.COMPUTER].get_data('log page') | 504 page = self.game.detail_views[self.COMPUTER].get_data('log page') |
496 return tab == 'log' and page > 0 | 505 return tab == 'log' and page > 0 |
497 | 506 |
498 def interact_without(self): | 507 def interact_without(self): |
499 page = self.state.detail_views[self.COMPUTER].get_data('log page') | 508 page = self.game.detail_views[self.COMPUTER].get_data('log page') |
500 self.state.detail_views[self.COMPUTER].set_data('log page', page - 1) | 509 self.game.detail_views[self.COMPUTER].set_data('log page', page - 1) |
501 self.state.detail_views[self.COMPUTER].set_background() | 510 self.game.detail_views[self.COMPUTER].set_background() |
502 return Result(soundfile='beep550.ogg') | 511 return Result(soundfile='beep550.ogg') |
503 | 512 |
504 | 513 |
505 class CompDownButton(Thing): | 514 class CompDownButton(Thing): |
506 """Down button on log screen""" | 515 """Down button on log screen""" |
512 } | 521 } |
513 INITIAL = 'down' | 522 INITIAL = 'down' |
514 COMPUTER = 'bridge_comp_detail' | 523 COMPUTER = 'bridge_comp_detail' |
515 | 524 |
516 def is_interactive(self, tool=None): | 525 def is_interactive(self, tool=None): |
517 tab = self.state.detail_views[self.COMPUTER].get_data('tab') | 526 tab = self.game.detail_views[self.COMPUTER].get_data('tab') |
518 page = self.state.detail_views[self.COMPUTER].get_data('log page') | 527 page = self.game.detail_views[self.COMPUTER].get_data('log page') |
519 max_page = self.state.detail_views[self.COMPUTER].get_data('max page') | 528 max_page = self.game.detail_views[self.COMPUTER].get_data('max page') |
520 return tab == 'log' and (page + 1) < max_page | 529 return tab == 'log' and (page + 1) < max_page |
521 | 530 |
522 def interact_without(self): | 531 def interact_without(self): |
523 page = self.state.detail_views[self.COMPUTER].get_data('log page') | 532 page = self.game.detail_views[self.COMPUTER].get_data('log page') |
524 self.state.detail_views[self.COMPUTER].set_data('log page', page + 1) | 533 self.game.detail_views[self.COMPUTER].set_data('log page', page + 1) |
525 self.state.detail_views[self.COMPUTER].set_background() | 534 self.game.detail_views[self.COMPUTER].set_background() |
526 return Result(soundfile='beep550.ogg') | 535 return Result(soundfile='beep550.ogg') |
527 | 536 |
528 | 537 |
529 class MonitorCamera(BaseCamera): | 538 class MonitorCamera(BaseCamera): |
530 "A camera on the bridge" | 539 "A camera on the bridge" |
545 FOLDER = 'bridge' | 554 FOLDER = 'bridge' |
546 NAME = 'bridge_comp_detail' | 555 NAME = 'bridge_comp_detail' |
547 | 556 |
548 ALERT_BASE = 'comp_alert_base.png' | 557 ALERT_BASE = 'comp_alert_base.png' |
549 ALERTS = { | 558 ALERTS = { |
550 'ai looping': 'comp_alert_ai_looping.png', | 559 'hull breach': _("Hull breach detected: Engine Room"), |
551 'ai offline': 'comp_alert_ai_offline.png', | 560 'ai looping': _("AI Status: 3D scene reconstruction failed." |
552 'engine offline': 'comp_alert_engine_offline.png', | 561 " Recovery in progress"), |
553 'life support': 'comp_alert_life_support.png', | 562 'ai offline': _("AI System Offline"), |
554 'life support partial': 'comp_alert_life_support_partial.png', | 563 'engine offline': _("Engine Offline"), |
564 'life support': _("Life Support System: 20% operational"), | |
565 'life support partial': _("Life Support System: 40% operational"), | |
555 } | 566 } |
556 | 567 |
557 # Point to start drawing changeable alerts | 568 # Point to start drawing changeable alerts |
558 ALERT_OFFSET = (16, 140) | 569 ALERT_OFFSET = (16, 100) |
559 ALERT_SPACING = 4 | 570 ALERT_SPACING = 4 |
560 | 571 |
561 LOGS = ['comp_log_start.png', 'comp_log_1.png', | 572 LOG_BACKGROUND = 'comp_log_start.png' |
562 'comp_log_end.png'] | 573 |
563 | 574 LOGS = [_("<Error: Log corrupted. Unable to open Log>")] |
564 NAVIGATION = { | 575 |
565 'engine offline': 'bridge_nav_engine.png', | 576 NAVIGATION = 'bridge_nav_base.png' |
566 'life support': 'bridge_nav_life_support.png', | 577 |
567 'final': 'bridge_nav_dest.png', | 578 NAV_MESSAGES = { |
579 'engine offline': [ | |
580 _("Engine Offline: Navigation Disabled")], | |
581 'life support': [ | |
582 _("Life Support Marginal."), | |
583 _("Emergency Navigation Protocol Engaged."), | |
584 '', | |
585 _("Destination locked to:"), | |
586 _("Bounty Penal Colony Space Port, New South Australia")], | |
568 } | 587 } |
569 | 588 |
570 BACKGROUND = ALERT_BASE | 589 BACKGROUND = ALERT_BASE |
571 | 590 |
572 INITIAL_DATA = { | 591 INITIAL_DATA = { |
573 'tab': 'alert', | 592 'tab': 'alert', |
574 'log page': 0, | 593 'log page': 0, |
575 'max page': len(LOGS), | 594 'max page': len(LOGS), |
576 } | 595 } |
577 | 596 |
578 def __init__(self, state): | 597 def setup(self): |
579 super(BridgeCompDetail, self).__init__(state) | |
580 | |
581 self.add_thing(LogTab()) | 598 self.add_thing(LogTab()) |
582 self.add_thing(AlertTab()) | 599 self.add_thing(AlertTab()) |
583 self.add_thing(NavTab()) | 600 self.add_thing(NavTab()) |
584 #self.add_thing(CompUpButton()) | 601 #self.add_thing(CompUpButton()) |
585 #self.add_thing(CompDownButton()) | 602 #self.add_thing(CompDownButton()) |
586 self._scene_playlist = None | 603 self._scene_playlist = None |
587 self._alert = get_image(self.FOLDER, self.ALERT_BASE) | 604 self._alert = self.get_image(self.FOLDER, self.ALERT_BASE) |
588 self._alert_messages = {} | 605 self._alert_messages = {} |
589 self._nav_messages = {} | 606 self._nav_messages = {} |
590 for key, name in self.ALERTS.iteritems(): | 607 for key, text in self.ALERTS.iteritems(): |
591 self._alert_messages[key] = get_image(self.FOLDER, name) | 608 self._alert_messages[key] = render_text(text, |
592 for key, name in self.NAVIGATION.iteritems(): | 609 'DejaVuSans-Bold.ttf', 18, 'orange', (0, 0, 0, 0), |
593 self._nav_messages[key] = get_image(self.FOLDER, name) | 610 self.resource, (600, 25), False) |
611 self._nav_background = self.get_image(self.FOLDER, self.NAVIGATION) | |
612 #for key, name in self.NAVIGATION.iteritems(): | |
613 # self._nav_messages[key] = self.get_image(self.FOLDER, name) | |
594 self._nav_lines = [] | 614 self._nav_lines = [] |
595 self._nav_lines.append(DestNavPageLine(1, (14, 99, 595, 30), False)) | 615 self._nav_lines.append(DestNavPageLine(1, (12, 99, 610, 25), False, |
596 self._nav_lines.append(DestNavPageLine(2, (14, 135, 595, 30), True)) | 616 _("1. Bounty Penal Colony Space Port, New South Australia" |
597 self._nav_lines.append(DestNavPageLine(3, (14, 167, 595, 30), True)) | 617 " (397 days)"))) |
598 self._nav_lines.append(DestNavPageLine(4, (14, 203, 595, 30), True)) | 618 self._nav_lines.append(DestNavPageLine(2, (12, 135, 610, 25), True, |
599 self._nav_lines.append(DestNavPageLine(5, (14, 239, 595, 30), True)) | 619 _("2. Hedonia Space Station (782 days)"))) |
600 self._logs = [get_image(self.FOLDER, x) for x in self.LOGS] | 620 self._nav_lines.append(DestNavPageLine(3, (12, 167, 610, 25), True, |
621 _("3. Spinosa Health Resort, Prunus Secundus (1231 days)"))) | |
622 self._nav_lines.append(DestNavPageLine(4, (12, 203, 610, 25), True, | |
623 _("4. Achene Space Port, Indica Prspinosame (1621 days)"))) | |
624 self._nav_lines.append(DestNavPageLine(5, (12, 239, 610, 25), True, | |
625 _("5. Opioid Space Port, Gelatinosa Prime (1963 days)"))) | |
626 self._log_background = self.get_image(self.FOLDER, self.LOG_BACKGROUND) | |
627 self._logs = [] | |
628 for text in self.LOGS: | |
629 log_page = self._log_background.copy() | |
630 log_page.blit(render_text(text, 'DejaVuSans-Bold.ttf', 18, | |
631 'lightgreen', (0, 0, 0, 0), self.resource, (600, 25), False), | |
632 self.ALERT_OFFSET) | |
633 self._logs.append(log_page) | |
601 | 634 |
602 def enter(self): | 635 def enter(self): |
603 self._scene_playlist = get_current_playlist() | 636 self._scene_playlist = self.sound.get_current_playlist() |
604 change_playlist(None) | 637 self.sound.change_playlist(None) |
605 self.set_background() | 638 self.set_background() |
606 | 639 |
607 def leave(self): | 640 def leave(self): |
608 change_playlist(self._scene_playlist) | 641 self.sound.change_playlist(self._scene_playlist) |
609 | 642 |
610 def set_background(self): | 643 def set_background(self): |
611 if self.get_data('tab') == 'alert': | 644 if self.get_data('tab') == 'alert': |
612 self._clear_navigation() | 645 self._clear_navigation() |
613 self._background = self._alert | 646 self._background = self._alert.copy() |
647 self._draw_alerts() | |
614 elif self.get_data('tab') == 'log': | 648 elif self.get_data('tab') == 'log': |
615 self._clear_navigation() | 649 self._clear_navigation() |
616 self._background = self._logs[self.get_data('log page')] | 650 self._background = self._logs[self.get_data('log page')].copy() |
617 elif self.get_data('tab') == 'nav': | 651 elif self.get_data('tab') == 'nav': |
618 self._background = self._get_nav_page() | 652 self._background = self._get_nav_page() |
619 | 653 |
620 def _clear_navigation(self): | 654 def _clear_navigation(self): |
621 "Remove navigation things if necessary" | 655 "Remove navigation things if necessary" |
623 if thing.name in self.things.keys(): | 657 if thing.name in self.things.keys(): |
624 # Much fiddling to do the right thing when we reinsert it | 658 # Much fiddling to do the right thing when we reinsert it |
625 del self.things[thing.name] | 659 del self.things[thing.name] |
626 thing.scene = None | 660 thing.scene = None |
627 | 661 |
662 def _draw_nav_text(self, key): | |
663 surface = self._nav_background.copy() | |
664 xpos, ypos = self.ALERT_OFFSET | |
665 for line in self.NAV_MESSAGES[key]: | |
666 text = render_text(line, 'DejaVuSans-Bold.ttf', 18, | |
667 'darkblue', (0, 0, 0, 0), self.resource, (600, 25), False) | |
668 surface.blit(text, (xpos, ypos)) | |
669 ypos = ypos + text.get_height() + self.ALERT_SPACING | |
670 return surface | |
671 | |
628 def _get_nav_page(self): | 672 def _get_nav_page(self): |
629 if not self.state.scenes['engine'].get_data('engine online'): | 673 if not self.game.scenes['engine'].get_data('engine online'): |
630 return self._nav_messages['engine offline'] | 674 return self._draw_nav_text('engine offline') |
631 elif (not self.state.scenes['mess'].get_data('life support status') | 675 elif (not self.game.scenes['mess'].get_data('life support status') |
632 == 'fixed'): | 676 == 'fixed'): |
633 return self._nav_messages['life support'] | 677 return self._draw_nav_text('life support') |
634 else: | 678 else: |
635 for thing in self._nav_lines: | 679 for thing in self._nav_lines: |
636 if thing.name not in self.things: | 680 if thing.name not in self.things: |
637 self.add_thing(thing) | 681 self.add_thing(thing) |
638 return self._nav_messages['final'] | 682 return self._nav_background.copy() |
639 | 683 |
640 def _draw_alerts(self, surface): | 684 def _draw_alerts(self): |
641 xpos, ypos = self.ALERT_OFFSET | 685 xpos, ypos = self.ALERT_OFFSET |
642 if self.state.scenes['bridge'].get_data('ai status') == 'looping': | 686 self._background.blit(self._alert_messages['hull breach'], |
643 surface.blit(self._alert_messages['ai looping'], (xpos, ypos)) | 687 (xpos, ypos)) |
688 ypos += (self._alert_messages['hull breach'].get_size()[1] | |
689 + self.ALERT_SPACING) | |
690 if self.game.scenes['bridge'].get_data('ai status') == 'looping': | |
691 self._background.blit(self._alert_messages['ai looping'], | |
692 (xpos, ypos)) | |
644 ypos += (self._alert_messages['ai looping'].get_size()[1] | 693 ypos += (self._alert_messages['ai looping'].get_size()[1] |
645 + self.ALERT_SPACING) | 694 + self.ALERT_SPACING) |
646 if self.state.scenes['bridge'].get_data('ai status') == 'dead': | 695 if self.game.scenes['bridge'].get_data('ai status') == 'dead': |
647 surface.blit(self._alert_messages['ai offline'], (xpos, ypos)) | 696 self._background.blit(self._alert_messages['ai offline'], |
697 (xpos, ypos)) | |
648 ypos += (self._alert_messages['ai offline'].get_size()[1] | 698 ypos += (self._alert_messages['ai offline'].get_size()[1] |
649 + self.ALERT_SPACING) | 699 + self.ALERT_SPACING) |
650 if not self.state.scenes['engine'].get_data('engine online'): | 700 if not self.game.scenes['engine'].get_data('engine online'): |
651 surface.blit(self._alert_messages['engine offline'], (xpos, ypos)) | 701 self._background.blit(self._alert_messages['engine offline'], |
702 (xpos, ypos)) | |
652 ypos += (self._alert_messages['engine offline'].get_size()[1] | 703 ypos += (self._alert_messages['engine offline'].get_size()[1] |
653 + self.ALERT_SPACING) | 704 + self.ALERT_SPACING) |
654 if (self.state.scenes['mess'].get_data('life support status') | 705 if (self.game.scenes['mess'].get_data('life support status') |
655 == 'broken'): | 706 == 'broken'): |
656 surface.blit(self._alert_messages['life support'], (xpos, ypos)) | 707 self._background.blit(self._alert_messages['life support'], |
708 (xpos, ypos)) | |
657 ypos += (self._alert_messages['life support'].get_size()[1] | 709 ypos += (self._alert_messages['life support'].get_size()[1] |
658 + self.ALERT_SPACING) | 710 + self.ALERT_SPACING) |
659 if (self.state.scenes['mess'].get_data('life support status') | 711 if (self.game.scenes['mess'].get_data('life support status') |
660 == 'replaced'): | 712 == 'replaced'): |
661 surface.blit(self._alert_messages['life support partial'], | 713 self._background.blit(self._alert_messages['life support partial'], |
662 (xpos, ypos)) | 714 (xpos, ypos)) |
663 ypos += (self._alert_messages['life support partial'].get_size()[1] | 715 ypos += (self._alert_messages['life support partial'].get_size()[1] |
664 + self.ALERT_SPACING) | 716 + self.ALERT_SPACING) |
665 | 717 |
666 def draw_things(self, surface): | |
667 if self.get_data('tab') == 'alert': | |
668 self._draw_alerts(surface) | |
669 super(BridgeCompDetail, self).draw_things(surface) | |
670 | |
671 | 718 |
672 SCENES = [Bridge] | 719 SCENES = [Bridge] |
673 DETAIL_VIEWS = [ChairDetail, BridgeCompDetail] | 720 DETAIL_VIEWS = [ChairDetail, BridgeCompDetail] |