class CryoContainers(Thing): NAME = 'engine.cryo_containers' INTERACTS = { 'empty': InteractImage(118, 211, 'cryo_empty.png'), 'full': InteractImage(118, 211, 'cryo_full.png'), } INITIAL = 'empty' INITIAL_DATA = { 'filled': False, } def select_interact(self): if self.get_data('filled'): return 'full' return self.INITIAL def get_description(self): if not self.get_data('filled'): return _("Those are coolant reservoirs. They look empty.") return _("The coolant reservoirs are full.") def is_interactive(self, tool=None): return False
class ManualPage(Thing): """Page in the manual""" NAME = 'manual.page' INTERACTS = { 0: InteractImage(0, 0, 'manual_p1.png'), 1: InteractImage(0, 0, 'manual_p2.png'), 2: InteractImage(0, 0, 'manual_p3.png'), 3: InteractImage(0, 0, 'manual_p4.png'), } INITIAL = 0 INITIAL_DATA = { 'page': 0, } def is_interactive(self, tool=None): return False def select_interact(self): return self.get_data('page') def set_page(self, page): self.set_data('page', page) self.set_interact() self.scene.things['manual.page_prior'].set_display('on') self.scene.things['manual.page_next'].set_display('on') if page == 0: self.scene.things['manual.page_prior'].set_display('off') if page == len(self.INTERACTS) - 1: self.scene.things['manual.page_next'].set_display('off')
class JimPanel(Thing): "The panel to JIM's internals'" NAME = "jim_panel" INTERACTS = { 'closed': InteractNoImage(506, 430, 137, 47), 'open': InteractImage(500, 427, 'jim_panel_open.png'), 'broken': InteractImage(488, 412, 'jim_panel_destroyed.png'), } INITIAL = 'closed' def get_description(self): if self.scene.get_data('ai panel') == 'closed': return _("The sign reads 'Warning: Authorized Techinicians Only'.") def select_interact(self): status = self.scene.get_data('ai panel') return status or self.INITIAL def interact_without(self): ai_status = self.state.get_jim_state() if ai_status == 'online': return self.interact_default(None) elif self.scene.get_data('ai panel') == 'closed': return Result( _("You are unable to open the panel with your" " bare hands.")) elif self.scene.get_data('ai panel') == 'open': self.scene.set_data('ai panel', 'broken') self.state.break_ai() self.set_interact() return Result(_("You unplug various important-looking wires.")) def interact_with_machete(self, item): ai_status = self.state.get_jim_state() if ai_status == 'online': return self.interact_default(item) elif self.scene.get_data('ai panel') == 'closed': self.scene.set_data('ai panel', 'open') self.set_interact() return Result(_("Using the machete, you lever the panel off.")) elif self.scene.get_data('ai panel') == 'open': self.scene.set_data('ai panel', 'broken') self.state.break_ai() self.set_interact() return Result( _("You smash various delicate components with" " the machete.")) def interact_default(self, item): if self.state.get_jim_state() == 'online': return (Result(_('You feel a shock from the panel.')), make_jim_dialog( _("Prisoner %s. Please step away from the" " panel. You are not an authorized" " technician.") % PLAYER_ID, self.game))
class MonitorCamera(BaseCamera): "A Camera pointing to JIM" NAME = 'crew.camera' INTERACTS = { 'online': InteractImage(85, 97, 'camera_medium.png'), 'dead': InteractImage(85, 97, 'camera_medium_gray.png'), 'looping': InteractAnimated(85, 97, ('camera_medium.png', 'camera_medium_gray.png'), 15), }
class MonitorCamera(BaseCamera): "A camera on the bridge" NAME = "bridge.camera" INTERACTS = { 'online': InteractImage(33, 192, 'camera_small.png'), 'dead': InteractImage(33, 192, 'camera_small_gray.png'), 'looping': InteractAnimated(33, 192, ('camera_small.png', 'camera_small_gray.png'), 15), }
class CansOnShelf(Thing): NAME = "mess.cans" INTERACTS = { '3cans': InteractImage(165, 209, 'shelf_3_cans.png'), '2cans': InteractImage(165, 209, 'shelf_2_cans.png'), '1cans': InteractImage(165, 209, 'shelf_1_can.png'), '0cans': InteractNoImage(165, 209, 50, 50), } INITIAL = '3cans' INITIAL_DATA = { 'cans_available': 3, } def should_add(self): return self.get_data('cans_available') > 0 def select_interact(self): return '%icans' % (self.get_data('cans_available'), ) def interact_without(self): starting_cans = self.get_data('cans_available') if starting_cans > 0: self.game.add_inventory_item('full_can') self.set_data('cans_available', starting_cans - 1) self.set_interact() if starting_cans == 1: self.scene.remove_thing(self) return Result({ 3: _("Best before a long time in the past." " Better not eat these."), 2: _("Mmmm. Nutritious bacteria stew."), 1: _("Candied silkworms. Who stocked this place?!"), }[starting_cans]) else: return Result( _("The rest of the cans are rusted beyond " "usefulness.")) def get_description(self): return _("The contents of these cans look synthetic.")
class CryoPipeLeft(CryoPipeBase): "Left cryo pipe." NAME = "cryo.pipe.left" INTERACTS = { "fixed": InteractImage(117, 226, "intact_cryo_pipe_left.png"), "chopped": InteractNoImage(125, 192, 27, 258), }
class CryoPipeRightTop(CryoPipeBase): "Right cryo pipe, top." NAME = "cryo.pipe.right.top" INTERACTS = { "fixed": InteractImage(645, 212, "intact_cryo_pipe_right_top.png"), "chopped": InteractNoImage(643, 199, 31, 111), }
class CryoPipeRightBottom(CryoPipeBase): "Right cryo pipe, bottom." NAME = "cryo.pipe.right.bottom" INTERACTS = { "fixed": InteractImage(644, 333, "intact_cryo_pipe_right_bottom.png"), "chopped": InteractNoImage(644, 333, 31, 107), }
class CryoComputer(Thing): "Computer in the cryo room." NAME = "cryo.computer" INTERACTS = { "info": InteractAnimated(416, 290, ["comp_info.png", "comp_info2.png"], 10), "warn": InteractImage(416, 290, "comp_warn.png"), "error": InteractImage(416, 290, "comp_error.png"), } INITIAL = "info" def interact_without(self): return Result(detail_view='cryo_comp_detail') def interact_with_titanium_leg(self, item): return Result(_("Hitting it with the leg accomplishes nothing.")) def get_description(self): return _("A computer terminal, with some text on it.")
class FishbowlThing(Thing): "A safe, for keeping things safe." NAME = 'crew.fishbowl' INTERACTS = { 'fishbowl': InteractImage(356, 495, 'fishbowl_on_table.png'), 'fish_no_bowl': InteractImage(372, 517, 'fish_minus_bowl.png'), } INITIAL = 'fishbowl' INITIAL_DATA = { 'has_bowl': True, } def select_interact(self): if not self.get_data('has_bowl'): return 'fish_no_bowl' return self.INITIAL def interact_without(self): if not self.get_data('has_bowl'): return Result( _("What's the point of lugging around a very dead" " fish and a kilogram or so of sand?")) self.set_data('has_bowl', False) self.set_interact() self.game.add_inventory_item('fishbowl') return Result(_("The fishbowl is useful, but its contents aren't.")) def get_description(self): if self.get_data('has_bowl'): return _("This fishbowl looks exactly like an old science fiction" " space helmet.") else: return _("An evicted dead fish and some sand lie forlornly on the" " table")
class Engines(Thing): NAME = 'engine.engines' INTERACTS = { 'on': InteractImage(334, 253, 'engine_on.png'), } INITIAL = 'on' def is_interactive(self, tool=None): return False def get_description(self): return _("All systems are go! Or at least the engines are.")
class CrackedPipe(Thing): NAME = "engine.cracked_pipe" INTERACTS = { 'cracked': InteractImage(13, 402, 'cracked_pipe.png'), 'taped': InteractImage(13, 402, 'duct_taped_pipe.png'), } INITIAL = 'cracked' INITIAL_DATA = { 'fixed': False, } def get_description(self): if self.get_data('fixed'): return _("The duct tape appears to be holding.") else: return _("The pipe looks cracked and won't hold" " fluid until it's fixed.") def select_interact(self): if self.get_data('fixed'): return 'taped' return self.INITIAL def interact_with_duct_tape(self, item): if self.get_data('fixed'): return Result( _("The duct tape already there appears to be " "sufficient.")) else: self.set_data('fixed', True) self.set_interact() return Result( _("You apply your trusty duct tape to the " "creak, sealing it."))
class ManualThing(TakeableThing): NAME = "machine.manual" INTERACTS = { "manual": InteractImage(432, 493, "manual_on_floor.png"), } INITIAL = "manual" ITEM = 'manual' def interact_without(self): self.take() return Result(_("Ah! The ship's instruction manual. You'd feel better" " if the previous owner wasn't lying next to it with a" " gaping hole in his rib cage."))
class PageNext(PageBase): """Next page in the manual""" NAME = 'manual.page_next' INTERACTS = { 'on': InteractImage(185, 351, 'arrow_right.png'), 'off': InteractNoImage(185, 351, 34, 23), } INITIAL = 'on' INITIAL_DATA = { 'display': 'on', } def interact_without(self): self.set_page(self.get_page() + 1)
class PagePrior(PageBase): """Prior page in the manual""" NAME = 'manual.page_prior' INTERACTS = { 'on': InteractImage(36, 351, 'arrow_left.png'), 'off': InteractNoImage(31, 351, 34, 23), } INITIAL = 'off' INITIAL_DATA = { 'display': 'off', } def interact_without(self): self.set_page(self.get_page() - 1)
class PosterThing(TakeableThing): "A innocent poster on the wall" NAME = 'crew.poster' INTERACTS = { 'poster': InteractImage(29, 166, 'triangle_poster.png'), } INITIAL = 'poster' ITEM = 'escher_poster' def interact_without(self): self.take() return Result(_("This poster will go nicely on your bedroom wall.")) def get_description(self): return _("A paradoxical poster hangs below the security camera.")
class CanOpenerThing(TakeableThing): NAME = 'engine.canopener' INTERACTS = { 'canopener': InteractImage(565, 456, 'can_opener.png'), } INITIAL = 'canopener' ITEM = 'canopener' def get_description(self): return _("A can opener. Looks like you won't be starving") def interact_without(self): self.take() return Result( _("You pick up the can opener. It looks brand new; " "the vacuum has kept it in perfect condition."))
class SuperconductorThing(TakeableThing): "Superconductor from the massage chair." NAME = 'bridge.superconductor' INTERACTS = { 'superconductor': InteractImage(158, 138, 'superconductor.png'), } INITIAL = 'superconductor' ITEM = 'superconductor' def interact_without(self): self.game.scenes['bridge'].things['bridge.massagechair_base'] \ .set_data('contains_superconductor', False) self.take() return (Result(_("The superconductor module unclips easily.")), make_jim_dialog( _("Prisoner %s. That chair you've destroyed" " was property of the ship's captain. " "You will surely be punished.") % PLAYER_ID, self.game))
class StethoscopeThing(TakeableThing): "Stethoscope on the doctor" NAME = 'bridge.stethoscope' INTERACTS = { 'stethoscope': InteractImage(650, 178, 'hanging_stethoscope.png'), } INITIAL = 'stethoscope' ITEM = 'stethoscope' def get_description(self): return _("A stethoscope hangs from the neck of the skeleton.") def interact_without(self): self.take() # Fill in the doctor's rect self.scene.doctor.rect.append(self.rect) return Result( _("You pick up the stethoscope and verify that the" " doctor's heart has stopped. Probably a while ago."))
class TitaniumLegThing(TakeableThing): "Triangle in the cryo room." NAME = "cryo.titanium_leg" INTERACTS = { "leg": InteractImage(180, 132, "leg.png"), } INITIAL = "leg" ITEM = 'titanium_leg' def interact_without(self): self.game.scenes['cryo'].things['cryo.unit.1'].set_data( 'contains_titanium_leg', False) self.take() return Result( _("The skeletal occupant of this cryo unit has an" " artificial femur made of titanium. You take it.")) def get_description(self): return _("This femur looks synthetic.")
class Tubes(Thing): NAME = "mess.tubes" INTERACTS = { "blocked": InteractImage(250, 130, "blocking_broccoli.png"), "broken": InteractImage(250, 183, "broken_tubes.png"), "replaced": InteractImage(250, 183, "replaced_tubes.png"), "fixed": InteractImage(252, 183, "fixed_tubes.png"), } INITIAL = "blocked" INITIAL_DATA = { "status": "blocked", } def get_description(self): if self.get_data('status') == "blocked": return _("The broccoli seems to have become" " entangled with something.") elif self.get_data("status") == "broken": return _("These broken pipes look important.") elif self.get_data("status") == "replaced": return _("The pipes have been repaired but are the repairs" " aren't airtight, yet") else: return _("Your fix looks like it's holding up well.") def select_interact(self): return self.get_data('status') def interact_with_machete(self, item): if self.get_data("status") == "blocked": self.set_data("status", "broken") self.set_interact() return Result(_("With a flurry of disgusting mutant vegetable " "chunks, you clear the overgrown broccoli away " "from the access panel and reveal some broken " "tubes. They look important."), soundfile='chopping.ogg') elif self.get_data("status") == "broken": return Result(_("It looks broken enough already.")) elif self.get_data("status") == "replaced": return Result(_("Cutting holes won't repair the leaks.")) else: return Result( _("After all that effort fixing it, chopping it to " "bits doesn't seem very smart.")) def interact_with_cryo_pipes_three(self, item): if self.get_data("status") == "blocked": return Result(_("It would get lost in the fronds.")) else: self.game.remove_inventory_item(item.name) self.set_data('status', 'replaced') self.set_interact() self.scene.set_data('life support status', 'replaced') return Result( _("The pipes slot neatly into place, but don't make" " an airtight seal. One of the pipes has cracked" " slightly as well.")) def interact_with_duct_tape(self, item): if self.get_data("status") == "broken": return Result(_("It would get lost in the fronds.")) elif self.get_data("status") == 'fixed': return Result( _("There's quite enough tape on the ducting already.")) else: self.set_data("fixed", True) self.set_data("status", "fixed") self.set_interact() self.scene.set_data('life support status', 'fixed') return Result( _("It takes quite a lot of tape, but eventually " "everything is airtight and ready to hold " "pressure. Who'd've thought duct tape could " "actually be used to tape ducts?")) def interact_without(self): if self.get_data("status") == "blocked": return Result(_("The mutant broccoli resists your best efforts.")) elif self.get_data("status") == "broken": return Result( _("Shoving the broken pipes around doesn't help " "much.")) elif self.get_data("status") == "replaced": return Result( _("Do you really want to hold it together for the " "rest of the voyage?")) else: return Result( _("You don't find any leaks. Good job, Prisoner %s.") % PLAYER_ID)
class Safe(Thing): "A safe, for keeping things safe." NAME = 'crew.safe' INTERACTS = { 'safe': InteractNoImage(447, 238, 72, 73), 'full_safe': InteractImage(445, 227, 'open_safe_full.png'), 'empty_safe': InteractImage(445, 227, 'open_safe_empty.png'), } INITIAL = 'safe' INITIAL_DATA = { 'is_cracked': False, 'has_tape': True, } def select_interact(self): if self.get_data('is_cracked'): if self.get_data('has_tape'): return 'full_safe' return 'empty_safe' return self.INITIAL def interact_without(self): if self.get_data('is_cracked'): if self.get_data('has_tape'): self.set_data('has_tape', False) self.game.add_inventory_item('duct_tape') self.set_interact() return Result( _("Duct tape. It'll stick to everything except " "ducts, apparently.")) return Result( _("The perfectly balanced door swings " "frictionlessly to and fro. What craftsmanship!")) return Result( _("The safe is locked. This might be an interesting " "challenge, if suitable equipment can be found.")) def interact_with_stethoscope(self, item): if self.get_data('is_cracked'): return Result( _("It's already unlocked. " "There's no more challenge.")) # TODO: Wax lyrical some more about safecracking. self.set_data('is_cracked', True) self.set_interact() self.state.increase_sentence(20) return (Result( _("Even after centuries of neglect, the tumblers slide" " almost silently into place. Turns out the" " combination was '1 2 3 4 5'. An idiot must keep his" " luggage in here.")), make_jim_dialog( _("Prisoner %s, you have been observed" " committing a felony violation. This will" " go onto your permanent record, and your" " sentence will be extended by twenty" " years.") % PLAYER_ID, self.game), make_sentence_dialog(PLAYER_ID, self.game)) def get_description(self): return _("Ah, a vintage Knoxx & Co. model QR3. Quaint, but" " reasonably secure.")
class LaserWelderSlot(Thing): NAME = "machine.welder.slot" INTERACTS = { "empty": InteractImage(241, 310, "welder_empty.png"), "can": InteractImage(241, 310, "welder_can.png"), "tube": InteractImage(241, 310, "welder_pipe.png"), "can_and_tube": InteractImage(241, 310, "welder_can_pipe.png"), } INITIAL = "empty" INITIAL_DATA = { 'contents': [], } def select_interact(self): contents = self.get_data('contents') if not contents: return "empty" elif len(contents) == 1: if "can" in contents: return "can" elif "tube" in contents: return "tube" else: return "can_and_tube" def interact_without(self): return Result(_("You really don't want to put your hand in there.")) def interact_with_empty_can(self, item): contents = self.get_data('contents') if "can" in contents: return Result(_("There is already a can in the welder.")) self.game.remove_inventory_item(item.name) contents.append("can") self.set_interact() return Result(_("You carefully place the can in the laser welder.")) def interact_with_tube_fragment(self, item): contents = self.get_data('contents') if "tube" in contents: return Result(_("There is already a tube fragment in the welder.")) self.game.remove_inventory_item(item.name) contents.append("tube") self.set_interact() return Result(_("You carefully place the tube fragments in the" " laser welder.")) def get_description(self): contents = self.get_data('contents') if not contents: return (_("This is a Smith and Wesson 'zOMG' class high-precision" " laser welder.")) if len(contents) == 1: msg = _("The laser welder looks hungry, somehow.") if "can" in contents: msg += _(" It currently contains an empty can.") elif "tube" in contents: msg += _(" It currently contains a tube fragment.") elif len(contents) == 2: msg = _("The laser welder looks expectant. ") if "can" in contents and "tube" in contents: msg += _(" It currently contains an empty can and a" " tube fragment.") return msg
class SuperconductorSocket(Thing): NAME = 'engine.superconductor' INTERACTS = { 'broken': InteractImage(553, 260, 'superconductor_broken.png'), 'removed': InteractImage(553, 260, 'superconductor_socket.png'), 'fixed': InteractImage(553, 260, 'superconductor_fixed.png'), } INITIAL = 'broken' INITIAL_DATA = { 'present': True, 'working': False, } def get_description(self): if self.get_data('present') and not self.get_data('working'): return _("That superconductor looks burned out. It's wedged" " in there pretty firmly.") elif not self.get_data('present'): return _("An empty superconductor socket") else: return _("A working superconductor.") def select_interact(self): if not self.get_data('present'): return 'removed' if self.get_data('working'): return 'fixed' return self.INITIAL def interact_without(self): if self.get_data('present') and not self.get_data('working'): return Result( _("It's wedged in there pretty firmly, it won't" " come out.")) elif self.get_data('working'): return Result( _("You decide that working engines are more" " important than having a shiny superconductor.")) def interact_with_machete(self, item): if self.get_data('present') and not self.get_data('working'): self.set_data('present', False) self.set_interact() return Result( _("With leverage, the burned-out superconductor" " snaps out. You discard it.")) def interact_with_superconductor(self, item): if self.get_data('present'): return Result( _("It might help to remove the broken" " superconductor first")) else: return Result( _("You plug in the superconductor, and feel a hum " "as things kick into life. Unfortunately, it's " "the wrong size for the socket and just falls " "out again when you let go.")) def interact_with_taped_superconductor(self, item): if not self.get_data('present'): self.set_data('present', True) self.set_data('working', True) self.set_interact() self.game.remove_inventory_item(item.name) results = [ Result( _("The chair's superconductor looks over-specced" " for this job, but it should work.")) ] results.append(self.scene.engine_online_check()) return results else: return Result( _("It might help to remove the broken superconductor" " first."))
class CryoRoomDoor(Door): "Door to the cryo room." SCENE = "cryo" INTERACTS = { "shut": InteractNoImage(290, 260, 99, 152), "ajar": InteractImage(290, 260, "door_ajar.png"), "open": InteractImage(290, 260, "door_open.png"), } INITIAL = "shut" INITIAL_DATA = { 'door': "shut", } def interact_with_titanium_leg(self, item): if self.get_data('door') == "ajar": self.open_door() return Result(_("You wedge the titanium femur into the chain and" " twist. With a satisfying *snap*, the chain" " breaks and the door opens."), soundfile='break.ogg') elif self.get_data('door') == "shut": text = _("You bang on the door with the titanium femur. It makes a" " clanging sound.") return Result(text, soundfile='clang.ogg') else: return Result( _("You wave the femur in the doorway. Nothing" " happens.")) def interact_without(self): if self.get_data('door') == "shut": self.half_open_door() if self.get_data('door') != "open": return Result(_("It moves slightly and then stops. A chain on the" " other side is preventing it from opening" " completely."), soundfile='chain.ogg') else: self.game.change_scene('map') return None def interact_default(self, item): return self.interact_without() def select_interact(self): return self.get_data('door') or self.INITIAL def half_open_door(self): self.set_data('door', "ajar") self.set_interact() def open_door(self): self.set_data('door', "open") self.set_interact() def get_description(self): if self.get_data('door') == "open": return _('An open doorway leads to the rest of the ship.') elif self.get_data('door') == "ajar": return _("A rusty door. It can't open all the way because of a " "chain on the other side.") return _('A rusty door. It is currently closed.')