# HG changeset patch # User Neil Muller # Date 1282663494 -7200 # Node ID 48d24a48d0cec0a7a6477085b13309d2daa13ade # Parent d5f7cccfdb6c0265cb27446b787aea80f6eff788 Enter and leave hooks diff -r d5f7cccfdb6c -r 48d24a48d0ce gamelib/constants.py --- a/gamelib/constants.py Tue Aug 24 17:04:56 2010 +0200 +++ b/gamelib/constants.py Tue Aug 24 17:24:54 2010 +0200 @@ -14,3 +14,5 @@ FRAME_RATE = 25 DEBUG = True + +ENTER, LEAVE = 1, 2 diff -r d5f7cccfdb6c -r 48d24a48d0ce gamelib/gamescreen.py --- a/gamelib/gamescreen.py Tue Aug 24 17:04:56 2010 +0200 +++ b/gamelib/gamescreen.py Tue Aug 24 17:24:54 2010 +0200 @@ -75,25 +75,33 @@ def draw(self, surface): self.state.draw(surface) + def _process_result(self, result): + """Helper function to do the right thing with a result object""" + if result: + if result.sound: + result.sound.play() + if result.message: + # Display the message as a modal dialog + MessageDialog(result.message, 60).present() + # queue a redraw to show updated state + self.invalidate() + def mouse_down(self, event): if self.subwidgets: self.remove(self.detail) self.state.set_current_detail(None) else: result = self.state.interact(event.pos) - if result: - if result.sound: - result.sound.play() - if result.message: - # Display the message as a modal dialog - MessageDialog(result.message, 60).present() - # queue a redraw to show updated state - self.invalidate() + self._process_result(result) def animate(self): if self.state.animate(): # queue a redraw self.invalidate() + # We do this here so we can get enter and leave events regardless + # of what happens + result = self.state.check_enter_leave() + self._process_result(result) def mouse_move(self, event): if not self.subwidgets: diff -r d5f7cccfdb6c -r 48d24a48d0ce gamelib/scenes/bridge.py --- a/gamelib/scenes/bridge.py Tue Aug 24 17:04:56 2010 +0200 +++ b/gamelib/scenes/bridge.py Tue Aug 24 17:24:54 2010 +0200 @@ -1,6 +1,6 @@ """Bridge where the final showdown with the AI occurs.""" -from gamelib.state import Scene, Item, Thing +from gamelib.state import Scene, Item, Thing, Result class Bridge(Scene): @@ -17,5 +17,9 @@ 'accessible': False, } + def enter(self): + return Result("The bridge is in a sorry, shabby state") + + SCENES = [Bridge] diff -r d5f7cccfdb6c -r 48d24a48d0ce gamelib/scenes/cryo.py --- a/gamelib/scenes/cryo.py Tue Aug 24 17:04:56 2010 +0200 +++ b/gamelib/scenes/cryo.py Tue Aug 24 17:24:54 2010 +0200 @@ -15,6 +15,7 @@ INITIAL_DATA = { 'accessible': True, + 'greet' : True } def __init__(self, state): @@ -25,6 +26,15 @@ self.add_thing(CryoRoomDoor()) self.add_thing(CryoComputer()) + def enter(self): + if self.get_data('greet'): + self.set_data('greet', False) + return Result("Greetings Prisoner id. You have woken early under" + " the terms of the emergency conscription act to help with" + " repairs to the ship. Your behaviour during this time will" + " be added to your record and will be relayed to " + " prison officials when we reach the destination." + " Please report to the bridge.") class Triangle(Item): "Test item. Needs to go away at some point." diff -r d5f7cccfdb6c -r 48d24a48d0ce gamelib/state.py --- a/gamelib/state.py Tue Aug 24 17:04:56 2010 +0200 +++ b/gamelib/state.py Tue Aug 24 17:24:54 2010 +0200 @@ -30,6 +30,7 @@ #state.load_scenes("machine") #state.load_scenes("map") state.set_current_scene("cryo") + state.set_do_enter_leave() return state @@ -57,6 +58,11 @@ self.current_scene = None # current detail view self.current_detail = None + # scene we came from, for enter and leave processing + self.previous_scene = None + # scene transion helpers + self.do_check = None + self.old_pos = None def add_scene(self, scene): self.scenes[scene.name] = scene @@ -76,7 +82,11 @@ self.add_detail_view(scene_cls(self)) def set_current_scene(self, name): + old_scene = self.current_scene self.current_scene = self.scenes[name] + if old_scene and old_scene != self.current_scene: + self.previous_scene = old_scene + self.set_do_enter_leave() def set_current_detail(self, name): if name is None: @@ -98,7 +108,11 @@ self.tool = item def draw(self, surface): - self.current_scene.draw(surface) + if self.do_check and self.previous_scene and self.do_check == constants.LEAVE: + # We still need to handle leave events, so still display the scene + self.previous_scene.draw(surface) + else: + self.current_scene.draw(surface) def draw_detail(self, surface): self.current_detail.draw(surface) @@ -110,10 +124,33 @@ return self.current_detail.interact(self.tool, pos) def animate(self): - return self.current_scene.animate() + if not self.do_check: + return self.current_scene.animate() + + def check_enter_leave(self): + if not self.do_check: + return None + if self.do_check == constants.LEAVE: + self.do_check = constants.ENTER + if self.previous_scene: + return self.previous_scene.leave() + return None + elif self.do_check == constants.ENTER: + self.do_check = None + # Fix descriptions, etc. + if self.old_pos: + self.current_scene.mouse_move(self.tool, self.old_pos) + return self.current_scene.enter() + raise RuntimeError('invalid do_check value %s' % self.do_check) def mouse_move(self, pos): self.current_scene.mouse_move(self.tool, pos) + # So we can do sensible things on enter and leave + self.old_pos = pos + + def set_do_enter_leave(self): + """Flag that we need to run the enter loop""" + self.do_check = constants.LEAVE def mouse_move_detail(self, pos): self.current_detail.mouse_move(self.tool, pos) @@ -226,6 +263,13 @@ result = True return result + def enter(self): + return None + + def leave(self): + self._current_description = None + return None + def mouse_move(self, item, pos): """Call to check whether the cursor has entered / exited a thing.