# HG changeset patch # User Jeremy Thurgood # Date 1359206696 -7200 # Node ID a8510f4e2ea1709541ca849c336344924eff46b6 # Parent afe7b1cb16c02c0e63bb08a36ca4d3051e870503 Conditionally add things based on state. diff -r afe7b1cb16c0 -r a8510f4e2ea1 gamelib/scenes/bridge.py --- a/gamelib/scenes/bridge.py Sat Jan 26 13:24:01 2013 +0200 +++ b/gamelib/scenes/bridge.py Sat Jan 26 15:24:56 2013 +0200 @@ -8,9 +8,9 @@ from pyntnclick.cursor import CursorSprite from pyntnclick.state import Scene, Item, Thing, Result -from pyntnclick.scenewidgets import (InteractNoImage, InteractRectUnion, - InteractImage, InteractAnimated, - GenericDescThing) +from pyntnclick.scenewidgets import ( + InteractNoImage, InteractRectUnion, InteractImage, InteractAnimated, + GenericDescThing, TakeableThing) from gamelib.scenes.game_constants import PLAYER_ID from gamelib.scenes.game_widgets import Door, BaseCamera, make_jim_dialog @@ -176,8 +176,8 @@ CURSOR = CursorSprite('stethoscope.png') -class StethoscopeThing(Thing): - "Stehoscope on the doctor" +class StethoscopeThing(TakeableThing): + "Stethoscope on the doctor" NAME = 'bridge.stethoscope' @@ -186,13 +186,13 @@ } INITIAL = 'stethoscope' + ITEM = 'stethoscope' def get_description(self): return "A stethoscope hangs from the neck of the skeleton." def interact_without(self): - self.game.add_inventory_item('stethoscope') - self.scene.remove_thing(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" @@ -221,7 +221,7 @@ " successfully avoid disaster.") -class SuperconductorThing(Thing): +class SuperconductorThing(TakeableThing): "Superconductor from the massage chair." NAME = 'bridge.superconductor' @@ -231,12 +231,12 @@ } INITIAL = 'superconductor' + ITEM = 'superconductor' def interact_without(self): - self.game.add_inventory_item('superconductor') self.game.scenes['bridge'].things['bridge.massagechair_base'] \ .set_data('contains_superconductor', False) - self.scene.remove_thing(self) + 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. " diff -r afe7b1cb16c0 -r a8510f4e2ea1 gamelib/scenes/crew_quarters.py --- a/gamelib/scenes/crew_quarters.py Sat Jan 26 13:24:01 2013 +0200 +++ b/gamelib/scenes/crew_quarters.py Sat Jan 26 15:24:56 2013 +0200 @@ -2,8 +2,9 @@ from pyntnclick.cursor import CursorSprite from pyntnclick.state import Scene, Item, Thing, Result -from pyntnclick.scenewidgets import (InteractNoImage, InteractImage, - InteractAnimated, GenericDescThing) +from pyntnclick.scenewidgets import ( + InteractNoImage, InteractImage, InteractAnimated, GenericDescThing, + TakeableThing) from gamelib.scenes.game_constants import PLAYER_ID from gamelib.scenes.game_widgets import Door, BaseCamera, make_jim_dialog @@ -187,7 +188,7 @@ } -class PosterThing(Thing): +class PosterThing(TakeableThing): "A innocent poster on the wall" NAME = 'crew.poster' @@ -197,10 +198,10 @@ } INITIAL = 'poster' + ITEM = 'escher_poster' def interact_without(self): - self.game.add_inventory_item('escher_poster') - self.scene.remove_thing(self) + self.take() return Result("This poster will go nicely on your bedroom wall.") def get_description(self): diff -r afe7b1cb16c0 -r a8510f4e2ea1 gamelib/scenes/cryo.py --- a/gamelib/scenes/cryo.py Sat Jan 26 13:24:01 2013 +0200 +++ b/gamelib/scenes/cryo.py Sat Jan 26 15:24:56 2013 +0200 @@ -4,9 +4,9 @@ from pyntnclick.cursor import CursorSprite from pyntnclick.state import Scene, Item, CloneableItem, Thing, Result -from pyntnclick.scenewidgets import (InteractNoImage, InteractRectUnion, - InteractImage, InteractAnimated, - GenericDescThing) +from pyntnclick.scenewidgets import ( + InteractNoImage, InteractRectUnion, InteractImage, InteractAnimated, + GenericDescThing, TakeableThing) from gamelib.scenes.game_constants import PLAYER_ID from gamelib.scenes.game_widgets import Door, make_jim_dialog @@ -416,7 +416,7 @@ return "A computer terminal, with some text on it." -class TitaniumLegThing(Thing): +class TitaniumLegThing(TakeableThing): "Triangle in the cryo room." NAME = "cryo.titanium_leg" @@ -426,12 +426,12 @@ } INITIAL = "leg" + ITEM = 'titanium_leg' def interact_without(self): - self.game.add_inventory_item('titanium_leg') self.game.scenes['cryo'].things['cryo.unit.1'].set_data( 'contains_titanium_leg', False) - self.scene.remove_thing(self) + self.take() return Result("The skeletal occupant of this cryo unit has an" " artificial femur made of titanium. You take it.") diff -r afe7b1cb16c0 -r a8510f4e2ea1 gamelib/scenes/engine.py --- a/gamelib/scenes/engine.py Sat Jan 26 13:24:01 2013 +0200 +++ b/gamelib/scenes/engine.py Sat Jan 26 15:24:56 2013 +0200 @@ -2,9 +2,9 @@ from pyntnclick.cursor import CursorSprite from pyntnclick.state import Scene, Item, Thing, Result -from pyntnclick.scenewidgets import (InteractNoImage, InteractRectUnion, - InteractImage, InteractAnimated, - GenericDescThing) +from pyntnclick.scenewidgets import ( + InteractNoImage, InteractRectUnion, InteractImage, InteractAnimated, + GenericDescThing, TakeableThing) from gamelib.scenes.game_constants import PLAYER_ID from gamelib.scenes.game_widgets import Door, make_jim_dialog @@ -68,12 +68,13 @@ (562, 422, 30, 31), ) )) - self.add_thing(GenericDescThing('engine.engines', 8, - "The engines. They don't look like they are working.", - ( - (342, 261, 109, 81), - ) - )) + if not self.get_data('engine online'): + self.add_thing(GenericDescThing('engine.engines', 8, + "The engines. They don't look like they are working.", + ( + (342, 261, 109, 81), + ) + )) self.add_thing(GenericDescThing('engine.laser_cutter', 9, "A burned-out laser cutter. It may be responsible for the" " hole in the floor.", @@ -163,7 +164,7 @@ CURSOR = CursorSprite('can_opener_cursor.png') -class CanOpenerThing(Thing): +class CanOpenerThing(TakeableThing): NAME = 'engine.canopener' INTERACTS = { @@ -171,13 +172,13 @@ } INITIAL = 'canopener' + ITEM = 'canopener' def get_description(self): return "A can opener. Looks like you won't be starving" def interact_without(self): - self.game.add_inventory_item('canopener') - self.scene.remove_thing(self) + self.take() return Result("You pick up the can opener. It looks brand new; " "the vacuum has kept it in perfect condition.") diff -r afe7b1cb16c0 -r a8510f4e2ea1 gamelib/scenes/machine.py --- a/gamelib/scenes/machine.py Sat Jan 26 13:24:01 2013 +0200 +++ b/gamelib/scenes/machine.py Sat Jan 26 15:24:56 2013 +0200 @@ -2,8 +2,9 @@ from pyntnclick.state import Scene, Item, Thing, Result from pyntnclick.cursor import CursorSprite -from pyntnclick.scenewidgets import (InteractNoImage, InteractImage, - InteractAnimated, GenericDescThing) +from pyntnclick.scenewidgets import ( + InteractNoImage, InteractImage, InteractAnimated, GenericDescThing, + TakeableThing) from gamelib.scenes.game_widgets import Door @@ -276,7 +277,7 @@ CURSOR = CursorSprite('machete_cursor.png', 23, 1) -class ManualThing(Thing): +class ManualThing(TakeableThing): NAME = "machine.manual" @@ -285,10 +286,10 @@ } INITIAL = "manual" + ITEM = 'manual' def interact_without(self): - self.scene.remove_thing(self) - self.game.add_inventory_item("manual") + 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.") diff -r afe7b1cb16c0 -r a8510f4e2ea1 gamelib/scenes/mess.py --- a/gamelib/scenes/mess.py Sat Jan 26 13:24:01 2013 +0200 +++ b/gamelib/scenes/mess.py Sat Jan 26 15:24:56 2013 +0200 @@ -126,6 +126,9 @@ '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'),) diff -r afe7b1cb16c0 -r a8510f4e2ea1 pyntnclick/scenewidgets.py --- a/pyntnclick/scenewidgets.py Sat Jan 26 13:24:01 2013 +0200 +++ b/pyntnclick/scenewidgets.py Sat Jan 26 15:24:56 2013 +0200 @@ -129,6 +129,29 @@ return False +class TakeableThing(Thing): + "Thing that can be taken." + + INITIAL_DATA = { + 'taken': False, + } + + ITEM = None + + def __init__(self): + # In case a subclass replaces INITIAL_DATA and breaks 'taken'. + assert self.INITIAL_DATA['taken'] in (True, False) + super(TakeableThing, self).__init__() + + def should_add(self): + return not self.get_data('taken') + + def take(self): + self.set_data('taken', True) + self.game.add_inventory_item(self.ITEM) + self.scene.remove_thing(self) + + class GenericDescThing(Thing): "Thing with an InteractiveUnionRect and a description" diff -r afe7b1cb16c0 -r a8510f4e2ea1 pyntnclick/state.py --- a/pyntnclick/state.py Sat Jan 26 13:24:01 2013 +0200 +++ b/pyntnclick/state.py Sat Jan 26 15:24:56 2013 +0200 @@ -199,8 +199,13 @@ self.gd = game.gd self.resource = self.gd.resource self.sound = self.gd.sound + self.set_state(self.game.data) self.setup() + def set_state(self, state): + """Hack to allow set_state() to be called before setup().""" + pass + def setup(self): """Game developers should override this to do their setup. @@ -260,16 +265,14 @@ self.current_thing = None self._background = None - def set_game(self, game): - super(Scene, self).set_game(game) - self.set_state(game.data) - def add_item(self, item): self.game.add_item(item) def add_thing(self, thing): + thing.set_game(self.game) + if not thing.should_add(): + return self.things[thing.name] = thing - thing.set_game(self.game) thing.set_scene(self) def remove_thing(self, thing): @@ -364,6 +367,9 @@ def get_image(self, *image_name_fragments, **kw): return self.resource.get_image(*image_name_fragments, **kw) + def set_state(self, state): + return super(Scene, self).set_state(state) + class InteractiveMixin(object): def is_interactive(self, tool=None): @@ -437,6 +443,9 @@ else: self.rect = [x.move(self.scene.OFFSET) for x in self.rect] + def should_add(self): + return True + def set_scene(self, scene): assert self.scene is None self.scene = scene