comparison gamelib/scenes/cryo.py @ 854:3577c51029f1 default tip

Remove Suspended Sentence. pyntnclick is the library we extracted from it
author Stefano Rivera <stefano@rivera.za.net>
date Sat, 21 Jun 2014 22:15:54 +0200
parents f95830b58336
children
comparison
equal deleted inserted replaced
853:f95830b58336 854:3577c51029f1
1 """Cryo room where the prisoner starts out."""
2
3 import random
4
5 from pyntnclick.i18n import _
6 from pyntnclick.utils import render_text
7 from pyntnclick.cursor import CursorSprite
8 from pyntnclick.state import Scene, Item, CloneableItem, Thing, Result
9 from pyntnclick.scenewidgets import (
10 InteractNoImage, InteractRectUnion, InteractImage, InteractAnimated,
11 GenericDescThing, TakeableThing)
12
13 from gamelib.scenes.game_constants import PLAYER_ID
14 from gamelib.scenes.game_widgets import Door, make_jim_dialog
15
16
17 class Cryo(Scene):
18
19 FOLDER = "cryo"
20 BACKGROUND = "cryo_room.png"
21
22 INITIAL_DATA = {
23 'greet': True,
24 'vandalism_warn': True,
25 'sentence': 30,
26 }
27
28 # sounds that will be played randomly as background noise
29 MUSIC = [
30 'drip1.ogg',
31 'drip2.ogg',
32 'drip3.ogg',
33 'creaking.ogg',
34 'silent.ogg',
35 'silent.ogg',
36 ]
37
38 def setup(self):
39 self.add_item_factory(TitaniumLeg)
40 self.add_item_factory(TubeFragment)
41 self.add_item_factory(FullBottle)
42 self.add_thing(CryoUnitAlpha())
43 self.add_thing(CryoRoomDoor())
44 self.add_thing(CryoComputer())
45 self.add_thing(CryoPipeLeft())
46 self.add_thing(CryoPipeRightTop())
47 self.add_thing(CryoPipeRightBottom())
48 self.add_thing(CryoPools())
49
50 # Flavour items
51 # pipes
52 self.add_thing(GenericDescThing('cryo.pipes', 1,
53 _("These pipes carry cooling fluid to the cryo units."),
54 (
55 (552, 145, 129, 66),
56 (636, 82, 165, 60),
57 (140, 135, 112, 73),
58 (11, 63, 140, 67),
59 )))
60 self.add_thing(UncuttableCryoPipes())
61
62 # cryo units
63 self.add_thing(GenericCryoUnit(2,
64 _("An empty cryo chamber."),
65 _("Prisoner 81E4-C8900480E635. Embezzlement. 20 years."),
66 (
67 (155, 430, 50, 35),
68 (125, 450, 60, 35),
69 (95, 470, 60, 35),
70 (55, 490, 60, 55),
71 )))
72
73 self.add_thing(GenericCryoUnit(3,
74 _("A working cryo chamber. The frosted glass obscures the details"
75 " of the occupant."),
76 _("Prisoner 9334-CE1EB0243BAB. Murder. 40 years."),
77 (
78 (215, 430, 50, 35),
79 (205, 450, 50, 35),
80 (185, 470, 50, 35),
81 (125, 505, 80, 40),
82 )))
83
84 self.add_thing(GenericCryoUnit(4,
85 _("A broken cryo chamber. The skeleton inside has been picked"
86 " clean."),
87 _("Prisoner BFBC-8BF4C6B7492B. Importing illegal alien biomatter."
88 " 15 years."),
89 (
90 (275, 430, 50, 70),
91 (255, 460, 50, 70),
92 (235, 490, 50, 60),
93 )))
94
95 self.add_thing(GenericCryoUnit(5,
96 _("A working cryo chamber. The frosted glass obscures the details "
97 "of the occupant."),
98 _("Prisoner B520-99495B8C41CE. Copyright infringement. 60 years."),
99 (
100 (340, 430, 50, 70),
101 (330, 500, 60, 50),
102 )))
103
104 self.add_thing(GenericCryoUnit(6,
105 _("An empty cryo unit. Recently filled by you."),
106 _("Prisoner %s. Safecracking, grand larceny. 30 years.")
107 % PLAYER_ID,
108 (
109 (399, 426, 70, 56),
110 (404, 455, 69, 120),
111 )))
112
113 self.add_thing(GenericCryoUnit(7,
114 _("An empty cryo unit."),
115 _("Prisoner 83F1-CE32D3234749. Spamming. 5 years."),
116 (
117 (472, 432, 58, 51),
118 (488, 455, 41, 134),
119 (517, 487, 42, 93),
120 )))
121
122 self.add_thing(GenericCryoUnit(8,
123 _("An empty cryo unit."),
124 _("Prisoner A455-9DF9F43C43E5. Medical malpractice. 10 years."),
125 (
126 (596, 419, 69, 39),
127 (616, 442, 82, 40),
128 (648, 467, 84, 37),
129 (681, 491, 97, 60),
130 )))
131
132 def enter(self):
133 # Setup music
134 pieces = [self.sound.get_music(x) for x in self.MUSIC]
135 background_playlist = self.sound.get_playlist(pieces, random=True,
136 repeat=True)
137 self.sound.change_playlist(background_playlist)
138 if self.get_data('greet'):
139 self.set_data('greet', False)
140 return make_jim_dialog(
141 _("Greetings, Prisoner %s. I am the Judicial "
142 "Incarceration Monitor. "
143 "You have been woken early under the terms of the "
144 "emergency conscription act to assist with repairs to "
145 "the ship. Your behaviour during this time will "
146 "be noted on your record and will be relayed to "
147 "prison officials when we reach the destination. "
148 "Please report to the bridge.") % PLAYER_ID, self.game)
149
150 def leave(self):
151 # Stop music
152 self.sound.change_playlist(None)
153
154
155 class CryoPipeBase(Thing):
156 "Base class for cryo pipes that need to be stolen."
157
158 INITIAL = "fixed"
159
160 INITIAL_DATA = {
161 'fixed': True,
162 }
163
164 def select_interact(self):
165 if not self.get_data('fixed'):
166 return 'chopped'
167 return self.INITIAL
168
169 def interact_with_machete(self, item):
170 if self.get_data('fixed'):
171 self.set_data('fixed', False)
172 self.game.add_inventory_item('tube_fragment')
173 self.set_interact()
174 responses = [Result(_("It takes more effort than one would expect,"
175 " but eventually the pipe is separated from"
176 " the wall."), soundfile="chop-chop.ogg")]
177 if self.game.get_current_scene().get_data('vandalism_warn'):
178 self.game.get_current_scene().set_data('vandalism_warn', False)
179 responses.append(make_jim_dialog(
180 _("Prisoner %s. Vandalism is an offence punishable by a "
181 "minimum of an additional 6 months to your sentence."
182 ) % PLAYER_ID, self.game))
183 return responses
184
185 def is_interactive(self, tool=None):
186 return self.get_data('fixed')
187
188 def interact_without(self):
189 if self.get_data('fixed'):
190 return Result(_("These pipes aren't attached to the wall very"
191 " solidly."))
192 return None
193
194 def get_description(self):
195 if self.get_data('fixed'):
196 return _("These pipes carry cooling fluid to empty cryo units.")
197 return _("There used to be a pipe carrying cooling fluid here.")
198
199
200 class UncuttableCryoPipes(Thing):
201 "Base class for cryo pipes that can't be cut down."
202
203 NAME = "cryo.pipes.2"
204
205 INTERACTS = {
206 "fixed": InteractRectUnion((
207 (2, 130, 44, 394),
208 (756, 127, 52, 393),))
209 }
210
211 INITIAL = "fixed"
212
213 def interact_with_machete(self, item):
214 return Result(_("These pipes carry fluid to the working cryo units."
215 " Chopping them down doesn't seem sensible."))
216
217 def is_interactive(self, tool=None):
218 return True
219
220 def interact_without(self):
221 return Result(
222 _("These pipes aren't attached to the wall very solidly."))
223
224 def get_description(self):
225 return _("These pipes carry cooling fluid to the working cryo units.")
226
227
228 class TubeFragment(CloneableItem):
229 "Obtained after cutting down a cryo room pipe."
230
231 NAME = "tube_fragment"
232 INVENTORY_IMAGE = "tube_fragment.png"
233 CURSOR = CursorSprite('tube_fragment_cursor.png')
234 TOOL_NAME = "tube_fragment"
235 MAX_COUNT = 3
236
237
238 class CryoPipeLeft(CryoPipeBase):
239 "Left cryo pipe."
240
241 NAME = "cryo.pipe.left"
242 INTERACTS = {
243 "fixed": InteractImage(117, 226, "intact_cryo_pipe_left.png"),
244 "chopped": InteractNoImage(125, 192, 27, 258),
245 }
246
247
248 class CryoPipeRightTop(CryoPipeBase):
249 "Right cryo pipe, top."
250
251 NAME = "cryo.pipe.right.top"
252 INTERACTS = {
253 "fixed": InteractImage(645, 212, "intact_cryo_pipe_right_top.png"),
254 "chopped": InteractNoImage(643, 199, 31, 111),
255 }
256
257
258 class CryoPipeRightBottom(CryoPipeBase):
259 "Right cryo pipe, bottom."
260
261 NAME = "cryo.pipe.right.bottom"
262 INTERACTS = {
263 "fixed": InteractImage(644, 333, "intact_cryo_pipe_right_bottom.png"),
264 "chopped": InteractNoImage(644, 333, 31, 107),
265 }
266
267
268 class TitaniumLeg(Item):
269 "Titanium leg, found on a piratical corpse."
270
271 NAME = 'titanium_leg'
272 INVENTORY_IMAGE = "titanium_femur.png"
273 CURSOR = CursorSprite('titanium_femur_cursor.png', 13, 5)
274
275
276 class CryoUnitAlpha(Thing):
277 "Cryo unit containing titanium leg."
278
279 NAME = "cryo.unit.1"
280
281 INTERACTS = {
282 "unit": InteractRectUnion((
283 (531, 430, 64, 49),
284 (560, 460, 57, 47),
285 (583, 482, 65, 69),
286 (600, 508, 71, 48),
287 ))
288 }
289
290 INITIAL = "unit"
291
292 INITIAL_DATA = {
293 'contains_titanium_leg': True,
294 }
295
296 def interact_without(self):
297 return Result(detail_view='cryo_detail')
298
299 def interact_with_titanium_leg(self, item):
300 return Result(_("You hit the chamber that used to hold this very leg."
301 " Nothing happens as a result."),
302 soundfile="clang2.ogg")
303
304 def get_description(self):
305 if self.get_data('contains_titanium_leg'):
306 return _("A broken cryo chamber, with a poor unfortunate corpse"
307 " inside.")
308 return _("A broken cryo chamber. The corpse inside is missing a leg.")
309
310
311 class GenericCryoUnit(GenericDescThing):
312 "Generic Cryo unit"
313
314 def __init__(self, number, description, detailed_description, areas):
315 super(GenericCryoUnit, self).__init__('cryo.unit', number,
316 description, areas)
317 self.detailed_description = detailed_description
318
319 def is_interactive(self, tool=None):
320 return True
321
322 def interact_without(self):
323 return Result(self.detailed_description)
324
325 def get_description(self):
326 return self.description
327
328 def interact_with_titanium_leg(self, item):
329 return Result(random.choice([
330 _("You bang on the chamber with the titanium femur. Nothing"
331 " much happens."),
332 _("Hitting the cryo unit with the femur doesn't achieve"
333 " anything."),
334 _("You hit the chamber with the femur. Nothing happens."),
335 ]), soundfile="clang2.ogg")
336
337
338 class CryoRoomDoor(Door):
339 "Door to the cryo room."
340
341 SCENE = "cryo"
342
343 INTERACTS = {
344 "shut": InteractNoImage(290, 260, 99, 152),
345 "ajar": InteractImage(290, 260, "door_ajar.png"),
346 "open": InteractImage(290, 260, "door_open.png"),
347 }
348
349 INITIAL = "shut"
350
351 INITIAL_DATA = {
352 'door': "shut",
353 }
354
355 def interact_with_titanium_leg(self, item):
356 if self.get_data('door') == "ajar":
357 self.open_door()
358 return Result(_("You wedge the titanium femur into the chain and"
359 " twist. With a satisfying *snap*, the chain"
360 " breaks and the door opens."),
361 soundfile='break.ogg')
362 elif self.get_data('door') == "shut":
363 text = _("You bang on the door with the titanium femur. It makes a"
364 " clanging sound.")
365 return Result(text, soundfile='clang.ogg')
366 else:
367 return Result(_("You wave the femur in the doorway. Nothing"
368 " happens."))
369
370 def interact_without(self):
371 if self.get_data('door') == "shut":
372 self.half_open_door()
373 if self.get_data('door') != "open":
374 return Result(_("It moves slightly and then stops. A chain on the"
375 " other side is preventing it from opening"
376 " completely."), soundfile='chain.ogg')
377 else:
378 self.game.change_scene('map')
379 return None
380
381 def interact_default(self, item):
382 return self.interact_without()
383
384 def select_interact(self):
385 return self.get_data('door') or self.INITIAL
386
387 def half_open_door(self):
388 self.set_data('door', "ajar")
389 self.set_interact()
390
391 def open_door(self):
392 self.set_data('door', "open")
393 self.set_interact()
394
395 def get_description(self):
396 if self.get_data('door') == "open":
397 return _('An open doorway leads to the rest of the ship.')
398 elif self.get_data('door') == "ajar":
399 return _("A rusty door. It can't open all the way because of a "
400 "chain on the other side.")
401 return _('A rusty door. It is currently closed.')
402
403
404 class CryoComputer(Thing):
405 "Computer in the cryo room."
406
407 NAME = "cryo.computer"
408
409 INTERACTS = {
410 "info": InteractAnimated(416, 290, ["comp_info.png", "comp_info2.png"],
411 10),
412 "warn": InteractImage(416, 290, "comp_warn.png"),
413 "error": InteractImage(416, 290, "comp_error.png"),
414 }
415
416 INITIAL = "info"
417
418 def interact_without(self):
419 return Result(detail_view='cryo_comp_detail')
420
421 def interact_with_titanium_leg(self, item):
422 return Result(_("Hitting it with the leg accomplishes nothing."))
423
424 def get_description(self):
425 return _("A computer terminal, with some text on it.")
426
427
428 class TitaniumLegThing(TakeableThing):
429 "Triangle in the cryo room."
430
431 NAME = "cryo.titanium_leg"
432
433 INTERACTS = {
434 "leg": InteractImage(180, 132, "leg.png"),
435 }
436
437 INITIAL = "leg"
438 ITEM = 'titanium_leg'
439
440 def interact_without(self):
441 self.game.scenes['cryo'].things['cryo.unit.1'].set_data(
442 'contains_titanium_leg', False)
443 self.take()
444 return Result(_("The skeletal occupant of this cryo unit has an"
445 " artificial femur made of titanium. You take it."))
446
447 def get_description(self):
448 return _("This femur looks synthetic.")
449
450
451 class PlaqueThing(Thing):
452 "Plaque on the detailed cryo chamber"
453
454 NAME = "cryo.plaque"
455
456 INTERACTS = {
457 "plaque": InteractNoImage(60, 40, 35, 24),
458 }
459
460 INITIAL = "plaque"
461
462 def interact_without(self):
463 return Result(
464 _("The plaque is welded to the unit. You can't shift it."))
465
466 def get_description(self):
467 return _("'Prisoner 98CC-764E646391EE. War crimes. 45 years.")
468
469
470 class FullBottle(Item):
471 NAME = 'full_detergent_bottle'
472 INVENTORY_IMAGE = 'bottle_full.png'
473 CURSOR = CursorSprite('bottle_full_cursor.png', 27, 7)
474
475
476 class CryoPools(Thing):
477 "Handy for cooling engines"
478
479 NAME = 'cryo.pool'
480
481 INTERACTS = {
482 'pools': InteractRectUnion((
483 (444, 216, 125, 67),
484 (44, 133, 74, 107),
485 (485, 396, 97, 34),
486 )),
487 }
488
489 INITIAL = 'pools'
490
491 def get_description(self):
492 return _("Coolant leaks disturbingly from the bulkheads.")
493
494 def interact_without(self):
495 return Result(_("It's gooey"))
496
497 def interact_with_detergent_bottle(self, item):
498 self.game.replace_inventory_item(item.name, 'full_detergent_bottle')
499 return Result(_("You scoop up some coolant and fill the bottle."))
500
501
502 class CryoCompDetail(Scene):
503
504 FOLDER = "cryo"
505 BACKGROUND = "comp_info_detail.png"
506 NAME = "cryo_comp_detail"
507
508 def setup(self):
509 background = self.get_image(
510 self.FOLDER, self.BACKGROUND)
511 # Add the common text strings
512 bg = (0, 0, 0, 0)
513 fg = 'lightgreen'
514 font = 'DejaVuSans-Bold.ttf'
515 size = 18
516
517 background.blit(render_text(_("Info"),
518 font, 24, fg, bg, self.resource, (90, 25), False), (25, 60))
519 background.blit(render_text(_("Cryo Units Online: 2, 4"),
520 font, size, fg, bg, self.resource, (240, 30), False), (15, 120))
521 background.blit(render_text(_("Crew Active: 0"),
522 font, size, fg, bg, self.resource, (240, 30), False), (15, 170))
523 background.blit(render_text(_("Current Trip Time: 97558 days"),
524 font, size, fg, bg, self.resource, (340, 30), False), (15, 210))
525 background.blit(render_text(_("Expected Time of Arrival:"),
526 font, size, fg, bg, self.resource, (340, 30), False), (15, 240))
527
528 self._background_fixed = background.copy()
529 self._background_offline = background.copy()
530
531 self._background_fixed.blit(render_text(_("397 days"),
532 font, size, fg, bg, self.resource, (340, 30), False), (275, 240))
533
534 self._background_offline.blit(render_text(
535 _("<Error: Division by Zero Error>"),
536 font, size, fg, bg, self.resource, (340, 30), False), (275, 240))
537
538 def draw_background(self, surface):
539 if self.game.scenes['engine'].get_data('engine online'):
540 surface.blit(self._background_fixed, self.OFFSET, None)
541 else:
542 surface.blit(self._background_offline, self.OFFSET, None)
543
544
545 class CryoUnitWithCorpse(Scene):
546
547 FOLDER = "cryo"
548 BACKGROUND = "cryo_unit_detail.png"
549 NAME = "cryo_detail"
550
551 def setup(self):
552 self.add_thing(TitaniumLegThing())
553 self.add_thing(PlaqueThing())
554
555
556 SCENES = [Cryo]
557 DETAIL_VIEWS = [CryoUnitWithCorpse, CryoCompDetail]