changeset 603:3ce19d33b51f pyntnclick

Rename state to game to not cause confusion with the other state
author Neil Muller <neil@dip.sun.ac.za>
date Sat, 11 Feb 2012 20:09:47 +0200
parents 1aac5a3b17e1
children 08647ef4d324
files gamelib/scenes/bridge.py gamelib/scenes/crew_quarters.py gamelib/scenes/cryo.py gamelib/scenes/engine.py gamelib/scenes/game_widgets.py gamelib/scenes/machine.py gamelib/scenes/manual.py gamelib/scenes/map.py gamelib/scenes/mess.py pyntnclick/cursor.py pyntnclick/gamescreen.py pyntnclick/main.py pyntnclick/state.py pyntnclick/widgets/__init__.py
diffstat 14 files changed, 188 insertions(+), 168 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/scenes/bridge.py	Sat Feb 11 20:05:22 2012 +0200
+++ b/gamelib/scenes/bridge.py	Sat Feb 11 20:09:47 2012 +0200
@@ -162,7 +162,7 @@
     INITIAL = 'chair'
 
     def get_description(self):
-        return self.state.current_scene.things['bridge.massagechair_base'] \
+        return self.game.current_scene.things['bridge.massagechair_base'] \
                    .get_description()
 
     def is_interactive(self, tool=None):
@@ -191,7 +191,7 @@
         return "A stethoscope hangs from the neck of the skeleton."
 
     def interact_without(self):
-        self.state.add_inventory_item('stethoscope')
+        self.game.add_inventory_item('stethoscope')
         self.scene.remove_thing(self)
         # Fill in the doctor's rect
         self.scene.doctor.rect.append(self.rect)
@@ -214,8 +214,8 @@
 
     def interact_with_duct_tape(self, item):
         taped_superconductor = TapedSuperconductor('taped_superconductor')
-        self.state.add_item(taped_superconductor)
-        self.state.replace_inventory_item(self.name, taped_superconductor.name)
+        self.game.add_item(taped_superconductor)
+        self.game.replace_inventory_item(self.name, taped_superconductor.name)
         return Result("You rip off a piece of duct tape and stick it on the"
                       " superconductor. It almost sticks to itself, but you"
                       " successfully avoid disaster.")
@@ -233,15 +233,15 @@
     INITIAL = 'superconductor'
 
     def interact_without(self):
-        self.state.add_inventory_item('superconductor')
-        self.state.current_scene.things['bridge.massagechair_base'] \
+        self.game.add_inventory_item('superconductor')
+        self.game.current_scene.things['bridge.massagechair_base'] \
                           .set_data('contains_superconductor', False)
         self.scene.remove_thing(self)
         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.state))
+                                 % PLAYER_ID), self.game))
 
 
 class StarField(Thing):
@@ -360,7 +360,7 @@
             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.state))
+                                    " technician." % PLAYER_ID, self.game))
 
 
 class ChairDetail(Scene):
@@ -388,11 +388,11 @@
     COMPUTER = 'bridge_comp_detail'
 
     def is_interactive(self, tool=None):
-        return self.state.detail_views[self.COMPUTER].get_data('tab') != 'log'
+        return self.game.detail_views[self.COMPUTER].get_data('tab') != 'log'
 
     def interact_without(self):
-        self.state.detail_views[self.COMPUTER].set_data('tab', 'log')
-        self.state.detail_views[self.COMPUTER].set_background()
+        self.game.detail_views[self.COMPUTER].set_data('tab', 'log')
+        self.game.detail_views[self.COMPUTER].set_background()
         return Result(soundfile='beep550.ogg')
 
 
@@ -408,12 +408,12 @@
     COMPUTER = 'bridge_comp_detail'
 
     def is_interactive(self, tool=None):
-        return (self.state.detail_views[self.COMPUTER].get_data('tab')
+        return (self.game.detail_views[self.COMPUTER].get_data('tab')
                 != 'alert')
 
     def interact_without(self):
-        self.state.detail_views[self.COMPUTER].set_data('tab', 'alert')
-        self.state.detail_views[self.COMPUTER].set_background()
+        self.game.detail_views[self.COMPUTER].set_data('tab', 'alert')
+        self.game.detail_views[self.COMPUTER].set_background()
         return Result(soundfile='beep550.ogg')
 
 
@@ -429,11 +429,11 @@
     COMPUTER = 'bridge_comp_detail'
 
     def is_interactive(self, tool=None):
-        return self.state.detail_views[self.COMPUTER].get_data('tab') != 'nav'
+        return self.game.detail_views[self.COMPUTER].get_data('tab') != 'nav'
 
     def interact_without(self):
-        self.state.detail_views[self.COMPUTER].set_data('tab', 'nav')
-        self.state.detail_views[self.COMPUTER].set_background()
+        self.game.detail_views[self.COMPUTER].set_data('tab', 'nav')
+        self.game.detail_views[self.COMPUTER].set_background()
         return Result(soundfile='beep550.ogg')
 
 
@@ -456,19 +456,19 @@
         self.set_interact('line')
 
     def is_interactive(self, tool=None):
-        return self.state.detail_views[self.COMPUTER].get_data('tab') == 'nav'
+        return self.game.detail_views[self.COMPUTER].get_data('tab') == 'nav'
 
     def interact_without(self):
-        if self.state.scenes['bridge'].get_data('ai status') == 'online':
+        if self.game.scenes['bridge'].get_data('ai status') == 'online':
             return make_jim_dialog("You are not authorized to change the"
-                                   " destination.", self.state)
+                                   " destination.", self.game)
         if not self.ai_blocked:
             return Result("There's no good reason to choose to go to the"
                           " penal colony.")
-        if self.state.scenes['bridge'].get_data('ai status') == 'looping':
+        if self.game.scenes['bridge'].get_data('ai status') == 'looping':
             return Result("You could change the destination, but when JIM"
                           " recovers, it'll just get reset.")
-        if self.state.scenes['bridge'].get_data('ai status') == 'dead':
+        if self.game.scenes['bridge'].get_data('ai status') == 'dead':
             return Result("You change the destination.",
                           soundfile="beep550.ogg", end_game=True)
 
@@ -485,14 +485,14 @@
     COMPUTER = 'bridge_comp_detail'
 
     def is_interactive(self, tool=None):
-        tab = self.state.detail_views[self.COMPUTER].get_data('tab')
-        page = self.state.detail_views[self.COMPUTER].get_data('log page')
+        tab = self.game.detail_views[self.COMPUTER].get_data('tab')
+        page = self.game.detail_views[self.COMPUTER].get_data('log page')
         return tab == 'log' and page > 0
 
     def interact_without(self):
-        page = self.state.detail_views[self.COMPUTER].get_data('log page')
-        self.state.detail_views[self.COMPUTER].set_data('log page', page - 1)
-        self.state.detail_views[self.COMPUTER].set_background()
+        page = self.game.detail_views[self.COMPUTER].get_data('log page')
+        self.game.detail_views[self.COMPUTER].set_data('log page', page - 1)
+        self.game.detail_views[self.COMPUTER].set_background()
         return Result(soundfile='beep550.ogg')
 
 
@@ -508,15 +508,15 @@
     COMPUTER = 'bridge_comp_detail'
 
     def is_interactive(self, tool=None):
-        tab = self.state.detail_views[self.COMPUTER].get_data('tab')
-        page = self.state.detail_views[self.COMPUTER].get_data('log page')
-        max_page = self.state.detail_views[self.COMPUTER].get_data('max page')
+        tab = self.game.detail_views[self.COMPUTER].get_data('tab')
+        page = self.game.detail_views[self.COMPUTER].get_data('log page')
+        max_page = self.game.detail_views[self.COMPUTER].get_data('max page')
         return tab == 'log' and (page + 1) < max_page
 
     def interact_without(self):
-        page = self.state.detail_views[self.COMPUTER].get_data('log page')
-        self.state.detail_views[self.COMPUTER].set_data('log page', page + 1)
-        self.state.detail_views[self.COMPUTER].set_background()
+        page = self.game.detail_views[self.COMPUTER].get_data('log page')
+        self.game.detail_views[self.COMPUTER].set_data('log page', page + 1)
+        self.game.detail_views[self.COMPUTER].set_background()
         return Result(soundfile='beep550.ogg')
 
 
@@ -618,9 +618,9 @@
                 thing.scene = None
 
     def _get_nav_page(self):
-        if not self.state.scenes['engine'].get_data('engine online'):
+        if not self.game.scenes['engine'].get_data('engine online'):
             return self._nav_messages['engine offline']
-        elif (not self.state.scenes['mess'].get_data('life support status')
+        elif (not self.game.scenes['mess'].get_data('life support status')
               == 'fixed'):
             return self._nav_messages['life support']
         else:
@@ -631,24 +631,24 @@
 
     def _draw_alerts(self, surface):
         xpos, ypos = self.ALERT_OFFSET
-        if self.state.scenes['bridge'].get_data('ai status') == 'looping':
+        if self.game.scenes['bridge'].get_data('ai status') == 'looping':
             surface.blit(self._alert_messages['ai looping'], (xpos, ypos))
             ypos += (self._alert_messages['ai looping'].get_size()[1]
                      + self.ALERT_SPACING)
-        if self.state.scenes['bridge'].get_data('ai status') == 'dead':
+        if self.game.scenes['bridge'].get_data('ai status') == 'dead':
             surface.blit(self._alert_messages['ai offline'], (xpos, ypos))
             ypos += (self._alert_messages['ai offline'].get_size()[1]
                      + self.ALERT_SPACING)
-        if not self.state.scenes['engine'].get_data('engine online'):
+        if not self.game.scenes['engine'].get_data('engine online'):
             surface.blit(self._alert_messages['engine offline'], (xpos, ypos))
             ypos += (self._alert_messages['engine offline'].get_size()[1]
                      + self.ALERT_SPACING)
-        if (self.state.scenes['mess'].get_data('life support status')
+        if (self.game.scenes['mess'].get_data('life support status')
             == 'broken'):
             surface.blit(self._alert_messages['life support'], (xpos, ypos))
             ypos += (self._alert_messages['life support'].get_size()[1]
                      + self.ALERT_SPACING)
-        if (self.state.scenes['mess'].get_data('life support status')
+        if (self.game.scenes['mess'].get_data('life support status')
             == 'replaced'):
             surface.blit(self._alert_messages['life support partial'],
                          (xpos, ypos))
--- a/gamelib/scenes/crew_quarters.py	Sat Feb 11 20:05:22 2012 +0200
+++ b/gamelib/scenes/crew_quarters.py	Sat Feb 11 20:09:47 2012 +0200
@@ -66,7 +66,7 @@
         if self.get_data('is_cracked'):
             if self.get_data('has_tape'):
                 self.set_data('has_tape', False)
-                self.state.add_inventory_item('duct_tape')
+                self.game.add_inventory_item('duct_tape')
                 self.set_interact('empty_safe')
                 return Result("Duct tape. It'll stick to everything except "
                               "ducts, apparently.")
@@ -90,7 +90,7 @@
                           " committing a felony violation. This will go onto"
                           " your permanent record, and your sentence may be"
                           " extended by up to twenty years."
-                          % PLAYER_ID, self.state))
+                          % PLAYER_ID, self.game))
 
     def get_description(self):
         return "Ah, a vintage Knoxx & Co. model QR3. Quaint, but" \
@@ -119,7 +119,7 @@
                     " fish and a kilogram or so of sand?")
         self.set_interact('fish_no_bowl')
         self.set_data('has_bowl', False)
-        self.state.add_inventory_item('fishbowl')
+        self.game.add_inventory_item('fishbowl')
         return Result("The fishbowl is useful, but its contents aren't.")
 
     def get_description(self):
@@ -140,8 +140,8 @@
 
     def interact_with_duct_tape(self, item):
         helmet = FishbowlHelmet('helmet')
-        self.state.add_item(helmet)
-        self.state.replace_inventory_item(self.name, helmet.name)
+        self.game.add_item(helmet)
+        self.game.replace_inventory_item(self.name, helmet.name)
         return Result("You duct tape the edges of the helmet. The seal is"
                 " crude, but it will serve as a workable helmet if needed.")
 
@@ -187,7 +187,7 @@
     INITIAL = 'poster'
 
     def interact_without(self):
-        self.state.add_inventory_item('escher_poster')
+        self.game.add_inventory_item('escher_poster')
         self.scene.remove_thing(self)
         return Result("This poster will go nicely on your bedroom wall.")
 
--- a/gamelib/scenes/cryo.py	Sat Feb 11 20:05:22 2012 +0200
+++ b/gamelib/scenes/cryo.py	Sat Feb 11 20:09:47 2012 +0200
@@ -139,7 +139,7 @@
                     "the ship. Your behaviour during this time will "
                     "be noted on your record and will be relayed to "
                     "prison officials when we reach the destination. "
-                    "Please report to the bridge." % PLAYER_ID, self.state)
+                    "Please report to the bridge." % PLAYER_ID, self.game)
 
     def leave(self):
         # Stop music
@@ -159,18 +159,18 @@
         if self.get_data('fixed'):
             self.set_data('fixed', False)
             pipe = TubeFragment('tube_fragment')
-            self.state.add_item(pipe)
-            self.state.add_inventory_item(pipe.name)
+            self.game.add_item(pipe)
+            self.game.add_inventory_item(pipe.name)
             self.set_interact("chopped")
             responses = [Result("It takes more effort than one would expect,"
                 " but eventually the pipe is separated from the wall.",
                 soundfile="chop-chop.ogg")]
-            if self.state.current_scene.get_data('vandalism_warn'):
-                self.state.current_scene.set_data('vandalism_warn', False)
+            if self.game.current_scene.get_data('vandalism_warn'):
+                self.game.current_scene.set_data('vandalism_warn', False)
                 responses.append(make_jim_dialog(
                     ("Prisoner %s. Vandalism is an offence punishable by a "
                      "minimum of an additional 6 months to your sentence."
-                    ) % PLAYER_ID, self.state))
+                    ) % PLAYER_ID, self.game))
             return responses
 
     def is_interactive(self, tool=None):
@@ -361,7 +361,7 @@
                     " other side is preventing it from opening completely.",
                     soundfile='chain.ogg')
         else:
-            self.state.set_current_scene('map')
+            self.game.set_current_scene('map')
             return None
 
     def interact_default(self, item):
@@ -420,8 +420,8 @@
     INITIAL = "leg"
 
     def interact_without(self):
-        self.state.add_inventory_item('titanium_leg')
-        self.state.current_scene.things['cryo.unit.1'].set_data(
+        self.game.add_inventory_item('titanium_leg')
+        self.game.current_scene.things['cryo.unit.1'].set_data(
                 'contains_titanium_leg', False)
         self.scene.remove_thing(self)
         return Result("The skeletal occupant of this cryo unit has an"
@@ -477,8 +477,8 @@
 
     def interact_with_detergent_bottle(self, item):
         full = FullBottle('full_detergent_bottle')
-        self.state.add_item(full)
-        self.state.replace_inventory_item(item.name, full.name)
+        self.game.add_item(full)
+        self.game.replace_inventory_item(item.name, full.name)
         return Result("You scoop up some coolant and fill the bottle.")
 
 
@@ -494,7 +494,7 @@
             self.FOLDER, self.BACKGROUND_FIXED)
 
     def draw_background(self, surface):
-        if self.state.scenes['engine'].get_data('engine online'):
+        if self.game.scenes['engine'].get_data('engine online'):
             surface.blit(self._background_fixed, self.OFFSET, None)
         else:
             surface.blit(self._background, self.OFFSET, None)
--- a/gamelib/scenes/engine.py	Sat Feb 11 20:05:22 2012 +0200
+++ b/gamelib/scenes/engine.py	Sat Feb 11 20:09:47 2012 +0200
@@ -131,7 +131,7 @@
             return make_jim_dialog("The engines are now operational. You have"
                                    "done a satisfactory job, Prisoner %s."
                                    % PLAYER_ID,
-                                   self.state)
+                                   self.game)
 
     def enter(self):
         if self.get_data('greet'):
@@ -176,7 +176,7 @@
         return "A can opener. Looks like you won't be starving"
 
     def interact_without(self):
-        self.state.add_inventory_item('canopener')
+        self.game.add_inventory_item('canopener')
         self.scene.remove_thing(self)
         return Result("You pick up the can opener. It looks brand new; "
                       "the vacuum has kept it in perfect condition.")
@@ -237,7 +237,7 @@
             self.set_interact('fixed')
             self.set_data('present', True)
             self.set_data('working', True)
-            self.state.remove_inventory_item(item.name)
+            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())
@@ -294,7 +294,7 @@
         if not self.scene.things['engine.cracked_pipe'].get_data('fixed'):
             return Result("Pouring the precious cryo fluid into a"
                     " container connected to a cracked pipe would be a waste.")
-        self.state.remove_inventory_item(item.name)
+        self.game.remove_inventory_item(item.name)
         self.scene.things['engine.cryo_containers'].set_data('filled', True)
         self.scene.things['engine.cryo_containers'].set_interact('full')
         results = [Result("You fill the reservoirs. "
@@ -542,7 +542,7 @@
 
     def _draw_alerts(self, surface):
         xpos, ypos = self.ALERT_OFFSET
-        engine = self.state.scenes['engine']
+        engine = self.game.scenes['engine']
         if not engine.things['engine.cracked_pipe'].get_data('fixed'):
             image = self._alert_messages['cryo leaking']
             surface.blit(image, (xpos, ypos))
--- a/gamelib/scenes/game_widgets.py	Sat Feb 11 20:05:22 2012 +0200
+++ b/gamelib/scenes/game_widgets.py	Sat Feb 11 20:09:47 2012 +0200
@@ -19,7 +19,7 @@
 
     def interact_without(self):
         """Go to map."""
-        self.state.set_current_scene("map")
+        self.game.set_current_scene("map")
 
     def get_description(self):
         return 'An open doorway leads to the rest of the ship.'
@@ -45,7 +45,7 @@
     }
 
     def get_description(self):
-        status = self.state.scenes['bridge'].get_data('ai status')
+        status = self.game.scenes['bridge'].get_data('ai status')
         if status == 'online':
             return "A security camera watches over the room"
         elif status == 'looping':
@@ -55,19 +55,19 @@
             return "The security camera is powered down"
 
     def is_interactive(self, tool=None):
-        return self.state.scenes['bridge'].get_data('ai status') == 'online'
+        return self.game.scenes['bridge'].get_data('ai status') == 'online'
 
     def interact_with_escher_poster(self, item):
         # Order matters here, because of helper function
-        if self.state.scenes['bridge'].get_data('ai status') == 'online':
+        if self.game.scenes['bridge'].get_data('ai status') == 'online':
             ai_response = make_jim_dialog("3D scene reconstruction failed."
                     " Critical error. Entering emergency shutdown.",
-                    self.state)
-            self.state.scenes['bridge'].set_data('ai status', 'looping')
+                    self.game)
+            self.game.scenes['bridge'].set_data('ai status', 'looping')
             return ai_response
 
     def animate(self):
-        ai_status = self.state.scenes['bridge'].get_data('ai status')
+        ai_status = self.game.scenes['bridge'].get_data('ai status')
         if ai_status != self.get_data('status'):
             self.set_data('status', ai_status)
             self.set_interact(ai_status)
--- a/gamelib/scenes/machine.py	Sat Feb 11 20:05:22 2012 +0200
+++ b/gamelib/scenes/machine.py	Sat Feb 11 20:09:47 2012 +0200
@@ -120,7 +120,7 @@
         contents = self.get_data('contents')
         if "can" in contents:
             return Result("There is already a can in the welder.")
-        self.state.remove_inventory_item(item.name)
+        self.game.remove_inventory_item(item.name)
         contents.add("can")
         self.update_contents()
         return Result("You carefully place the can in the laser welder.")
@@ -129,7 +129,7 @@
         contents = self.get_data('contents')
         if "tube" in contents:
             return Result("There is already a tube fragment in the welder.")
-        self.state.remove_inventory_item(item.name)
+        self.game.remove_inventory_item(item.name)
         contents.add("tube")
         self.update_contents()
         return Result("You carefully place the tube fragments in the"
@@ -180,25 +180,25 @@
         else:
             welder_slot.set_data("contents", set())
             welder_slot.update_contents()
-            if self.state.items["cryo_pipes_one"] in self.state.inventory:
-                self.state.replace_inventory_item("cryo_pipes_one",
+            if self.game.items["cryo_pipes_one"] in self.game.inventory:
+                self.game.replace_inventory_item("cryo_pipes_one",
                                                   "cryo_pipes_two")
                 return Result("With high-precision spitzensparken, you weld"
                               " together a second pipe. You bundle the two"
                               " pipes together.",
                         soundfile='laser.ogg')
-            elif self.state.items["cryo_pipes_two"] in self.state.inventory:
-                self.state.replace_inventory_item("cryo_pipes_two",
+            elif self.game.items["cryo_pipes_two"] in self.game.inventory:
+                self.game.replace_inventory_item("cryo_pipes_two",
                                                   "cryo_pipes_three")
                 return Result("With high-precision spitzensparken, you create"
                               " yet another pipe. You store it with the other"
                               " two.",
                         soundfile='laser.ogg')
-            elif self.state.items["cryo_pipes_three"] in self.state.inventory:
+            elif self.game.items["cryo_pipes_three"] in self.game.inventory:
                 # just for safety
                 return None
             else:
-                self.state.add_inventory_item("cryo_pipes_one")
+                self.game.add_inventory_item("cryo_pipes_one")
                 return Result("With high-precision spitzensparken, the can and"
                               " tube are welded into a whole greater than the"
                               " sum of the parts.",
@@ -260,7 +260,7 @@
                       " approach is in order?")
 
     def interact_with_titanium_leg(self, item):
-        self.state.replace_inventory_item(item.name, 'machete')
+        self.game.replace_inventory_item(item.name, 'machete')
         return Result("After much delicate grinding and a few close calls with"
                       " various body parts, the titanium femur now resembles"
                       " a machete more than a bone. Nice and sharp, too.",
@@ -289,7 +289,7 @@
 
     def interact_without(self):
         self.scene.remove_thing(self)
-        self.state.add_inventory_item("manual")
+        self.game.add_inventory_item("manual")
         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.")
--- a/gamelib/scenes/manual.py	Sat Feb 11 20:05:22 2012 +0200
+++ b/gamelib/scenes/manual.py	Sat Feb 11 20:09:47 2012 +0200
@@ -13,7 +13,7 @@
     "Displays manual pages"
 
     def get_page_thing(self):
-        return self.state.current_detail.things['manual.page']
+        return self.game.current_detail.things['manual.page']
 
     def get_page(self):
         return self.get_page_thing().get_data('page')
--- a/gamelib/scenes/map.py	Sat Feb 11 20:05:22 2012 +0200
+++ b/gamelib/scenes/map.py	Sat Feb 11 20:09:47 2012 +0200
@@ -40,13 +40,13 @@
                 "Under the terms of the emergency conscription "
                 "act, I have downloaded the ship's schematics to your "
                 "neural implant to help you navigate around the ship.",
-                self.state)
+                self.game)
             if ai1:
                 return ai1, make_jim_dialog("Prisoner %s, you are a "
                 "class 1 felon. Obtaining access to the ship's schematics "
                 "constitutes a level 2 offence and carries a minimal penalty "
                 "of an additional 3 years on your sentence." % PLAYER_ID,
-                self.state)
+                self.game)
 
 
 class DoorThing(Thing):
@@ -56,8 +56,8 @@
 
     def interact(self, _item):
         """Go to destination."""
-        if self.DEST in self.state.scenes:
-            self.state.set_current_scene(self.DEST)
+        if self.DEST in self.game.scenes:
+            self.game.set_current_scene(self.DEST)
 
 
 class ToCryo(DoorThing):
@@ -124,7 +124,7 @@
     INITIAL = 'door'
 
     def interact(self, item):
-        if not self.state.is_in_inventory('helmet'):
+        if not self.game.is_in_inventory('helmet'):
             return Result('The airlock refuses to open. The automated'
                     ' voice says: "Hull breach beyond this door. Personnel'
                     ' must be equipped for vacuum before entry."')
--- a/gamelib/scenes/mess.py	Sat Feb 11 20:05:22 2012 +0200
+++ b/gamelib/scenes/mess.py	Sat Feb 11 20:09:47 2012 +0200
@@ -63,8 +63,8 @@
 
     def interact_with_canopener(self, item):
         empty = EmptyCan('empty_can')
-        self.state.add_item(empty)
-        self.state.replace_inventory_item(self.name, empty.name)
+        self.game.add_item(empty)
+        self.game.replace_inventory_item(self.name, empty.name)
         return Result("You open both ends of the can, discarding the"
                       " hideous contents.")
 
@@ -91,8 +91,8 @@
 
     def interact_with_titanium_leg(self, item):
         dented = DentedCan("dented_can")
-        self.state.add_item(dented)
-        self.state.replace_inventory_item(self.name, dented.name)
+        self.game.add_item(dented)
+        self.game.replace_inventory_item(self.name, dented.name)
         return Result("You club the can with the femur. The can gets dented,"
                       " but doesn't open.", soundfile="can_hit.ogg")
 
@@ -130,8 +130,8 @@
         starting_cans = self.get_data('cans_available')
         if starting_cans > 0:
             can = FullCan("full_can")
-            self.state.add_item(can)
-            self.state.add_inventory_item(can.name)
+            self.game.add_item(can)
+            self.game.add_inventory_item(can.name)
             self.set_data('cans_available', starting_cans - 1)
             self.set_interact('%icans' % (starting_cans - 1))
             if starting_cans == 1:
@@ -199,7 +199,7 @@
         if self.get_data("status") == "blocked":
             return Result("It would get lost in the fronds.")
         else:
-            self.state.remove_inventory_item(item.name)
+            self.game.remove_inventory_item(item.name)
             self.set_data('status', 'replaced')
             self.set_interact("replaced")
             self.scene.set_data('life support status', 'replaced')
@@ -260,7 +260,7 @@
         return False
 
     def animate(self):
-        hiss = self.state.gd.sound.get_sound(self.HISS)
+        hiss = self.game.gd.sound.get_sound(self.HISS)
         if self.get_data('anim_pos') > -1:
             self.current_interact.animate()
             if self.get_data('anim_pos') > self.current_interact._anim_pos:
@@ -269,7 +269,7 @@
             else:
                 self.set_data('anim_pos', self.current_interact._anim_pos)
             return True
-        if randint(0, 30 * self.state.gd.constants.frame_rate) == 0:
+        if randint(0, 30 * self.game.gd.constants.frame_rate) == 0:
             self.set_interact('snake')
             self.set_data('anim_pos', 0)
             hiss.play()
@@ -297,7 +297,7 @@
             return Result("The remaining bottles leak.")
         self.set_data('taken', True)
         self.set_interact('taken')
-        self.state.add_inventory_item('detergent_bottle')
+        self.game.add_inventory_item('detergent_bottle')
         return Result("You pick up an empty dishwashing liquid bottle. You"
                       " can't find any sponges.")
 
--- a/pyntnclick/cursor.py	Sat Feb 11 20:05:22 2012 +0200
+++ b/pyntnclick/cursor.py	Sat Feb 11 20:09:47 2012 +0200
@@ -81,7 +81,7 @@
         self.draw_cursor(self.get_root().surface)
 
     def draw_cursor(self, surface):
-        self.set_cursor(self.screen.state.tool)
+        self.set_cursor(self.screen.game.tool)
         self.cursor.set_highlight(self.cursor_highlight())
         if self.cursor is not None:
             self._cursor_group.update()
@@ -110,9 +110,9 @@
     def cursor_highlight(self):
         if not Rect((0, 0), SCENE_SIZE).collidepoint(pygame.mouse.get_pos()):
             return False
-        if self.screen.state.highlight_override:
+        if self.screen.game.highlight_override:
             return True
-        current_thing = self.screen.state.current_thing
+        current_thing = self.screen.game.current_thing
         if current_thing:
             return current_thing.is_interactive()
         return False
--- a/pyntnclick/gamescreen.py	Sat Feb 11 20:05:22 2012 +0200
+++ b/pyntnclick/gamescreen.py	Sat Feb 11 20:09:47 2012 +0200
@@ -32,37 +32,37 @@
         PaletteView.__init__(self, (BUTTON_SIZE, BUTTON_SIZE), 1, 6,
                              scrolling=True)
         self.screen = screen
-        self.state = screen.state
+        self.game = screen.game
         self.state_widget = screen.state_widget
 
     def num_items(self):
-        return len(self.state.inventory)
+        return len(self.game.inventory)
 
     def draw_item(self, surface, item_no, rect):
-        item_image = self.state.inventory[item_no].get_inventory_image()
+        item_image = self.game.inventory[item_no].get_inventory_image()
         surface.blit(item_image, rect, None)
 
     def click_item(self, item_no, event):
-        item = self.state.inventory[item_no]
+        item = self.game.inventory[item_no]
         if self.item_is_selected(item_no):
             self.unselect()
-        elif item.is_interactive(self.state.tool):
-            result = item.interact(self.state.tool)
+        elif item.is_interactive(self.game.tool):
+            result = item.interact(self.game.tool)
             handle_result(result, self.state_widget)
         else:
-            self.state.set_tool(self.state.inventory[item_no])
+            self.game.set_tool(self.game.inventory[item_no])
 
     def mouse_down(self, event):
         if event.button != 1:
-            self.state.cancel_doodah(self.screen)
+            self.game.cancel_doodah(self.screen)
         else:
             PaletteView.mouse_down(self, event)
 
     def item_is_selected(self, item_no):
-        return self.state.tool is self.state.inventory[item_no]
+        return self.game.tool is self.game.inventory[item_no]
 
     def unselect(self):
-        self.state.set_tool(None)
+        self.game.set_tool(None)
 
 
 class StateWidget(Widget):
@@ -70,45 +70,45 @@
     def __init__(self, screen):
         Widget.__init__(self, Rect(0, 0, SCENE_SIZE[0], SCENE_SIZE[1]))
         self.screen = screen
-        self.state = screen.state
+        self.game = screen.game
         self.detail = DetailWindow(screen)
 
     def draw(self, surface):
-        if self.state.previous_scene and self.state.do_check == LEAVE:
+        if self.game.previous_scene and self.game.do_check == LEAVE:
             # We still need to handle leave events, so still display the scene
-            self.state.previous_scene.draw(surface, self)
+            self.game.previous_scene.draw(surface, self)
         else:
-            self.state.current_scene.draw(surface, self)
+            self.game.current_scene.draw(surface, self)
 
     def mouse_down(self, event):
         self.mouse_move(event)
         if event.button != 1:  # We have a right/middle click
-            self.state.cancel_doodah(self.screen)
+            self.game.cancel_doodah(self.screen)
         elif self.subwidgets:
             self.clear_detail()
             self._mouse_move(event.pos)
         else:
-            result = self.state.interact(event.pos)
+            result = self.game.interact(event.pos)
             handle_result(result, self)
 
     def animate(self):
-        if self.state.animate():
+        if self.game.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.screen)
+        result = self.game.check_enter_leave(self.screen)
         handle_result(result, self)
 
     def mouse_move(self, event):
-        self.state.highlight_override = False
+        self.game.highlight_override = False
         if not self.subwidgets:
             self._mouse_move(event.pos)
 
     def _mouse_move(self, pos):
-        self.state.highlight_override = False
-        self.state.current_scene.mouse_move(pos)
-        self.state.old_pos = pos
+        self.game.highlight_override = False
+        self.game.current_scene.mouse_move(pos)
+        self.game.old_pos = pos
 
     def show_message(self, message, style=None):
         # Display the message as a modal dialog
@@ -123,17 +123,17 @@
 
     def show_detail(self, detail):
         self.clear_detail()
-        detail_obj = self.state.set_current_detail(detail)
+        detail_obj = self.game.set_current_detail(detail)
         self.detail.set_image_rect(Rect((0, 0), detail_obj.get_detail_size()))
         self.add_centered(self.detail)
-        self.state.do_enter_detail()
+        self.game.do_enter_detail()
 
     def clear_detail(self):
         """Hide the detail view"""
-        if self.state.current_detail is not None:
+        if self.game.current_detail is not None:
             self.remove(self.detail)
-            self.state.do_leave_detail()
-            self.state.set_current_detail(None)
+            self.game.do_leave_detail()
+            self.game.set_current_detail(None)
             self._mouse_move(mouse.get_pos())
 
     def end_game(self):
@@ -146,7 +146,7 @@
         Widget.__init__(self)
         self.image_rect = None
         self.screen = screen
-        self.state = screen.state
+        self.game = screen.game
         self.border_width = 5
         self.border_color = (0, 0, 0)
         # parent only gets set when we get added to the scene
@@ -171,15 +171,15 @@
         overlay = scene_surface.convert_alpha()
         overlay.fill(Color(0, 0, 0, 191))
         scene_surface.blit(overlay, (0, 0))
-        self.state.current_detail.draw(
+        self.game.current_detail.draw(
             surface.subsurface(self.image_rect), self)
 
     def mouse_down(self, event):
         self.mouse_move(event)
         if event.button != 1:  # We have a right/middle click
-            self.state.cancel_doodah(self.screen)
+            self.game.cancel_doodah(self.screen)
         else:
-            result = self.state.interact_detail(
+            result = self.game.interact_detail(
                 self.global_to_local(event.pos))
             handle_result(result, self)
 
@@ -187,8 +187,8 @@
         self._mouse_move(event.pos)
 
     def _mouse_move(self, pos):
-        self.state.highlight_override = False
-        self.state.current_detail.mouse_move(self.global_to_local(pos))
+        self.game.highlight_override = False
+        self.game.current_detail.mouse_move(self.global_to_local(pos))
 
     def show_message(self, message, style=None):
         self.parent.show_message(message, style)
@@ -220,7 +220,7 @@
 
     def start_game(self):
         self._clear_all()
-        self.state = self.create_initial_state()
+        self.game = self.create_initial_state()
         self.state_widget = StateWidget(self)
         self.add(self.state_widget)
 
--- a/pyntnclick/main.py	Sat Feb 11 20:05:22 2012 +0200
+++ b/pyntnclick/main.py	Sat Feb 11 20:09:47 2012 +0200
@@ -66,7 +66,7 @@
 
     def initial_state(self):
         """Create a copy of the initial game state."""
-        initial_state = state.GameState(self)
+        initial_state = state.Game(self)
         initial_state.set_debug_rects(self._debug_rects)
         for scene in self._scene_list:
             initial_state.load_scenes(scene)
--- a/pyntnclick/state.py	Sat Feb 11 20:05:22 2012 +0200
+++ b/pyntnclick/state.py	Sat Feb 11 20:09:47 2012 +0200
@@ -22,7 +22,7 @@
 
     def play_sound(self, scene_widget):
         if self.soundfile:
-            sound = scene_widget.state.gd.sound.get_sound(self.soundfile)
+            sound = scene_widget.game.gd.sound.get_sound(self.soundfile)
             sound.play()
 
     def process(self, scene_widget):
@@ -52,7 +52,7 @@
                     res.process(scene_widget)
 
 
-class GameState(object):
+class Game(object):
     """Complete game state.
 
     Game state consists of:
@@ -73,6 +73,8 @@
         self.inventory = []
         # currently selected tool (item)
         self.tool = None
+        # Global game data
+        self.data = {}
         # current scene
         self.current_scene = None
         # current detail view
@@ -92,15 +94,15 @@
         self.debug_rects = value
 
     def add_scene(self, scene):
-        scene.set_state(self)
+        scene.set_game(self)
         self.scenes[scene.name] = scene
 
     def add_detail_view(self, detail_view):
-        detail_view.set_state(self)
+        detail_view.set_game(self)
         self.detail_views[detail_view.name] = detail_view
 
     def add_item(self, item):
-        item.set_state(self)
+        item.set_game(self)
         self.items[item.name] = item
 
     def load_scenes(self, modname):
@@ -205,14 +207,14 @@
 
     def __init__(self):
         """Set """
-        self.state = None
+        self.game = None
         self.gd = None
         self.resource = None
         self.sound = None
 
-    def set_state(self, state):
-        self.state = state
-        self.gd = state.gd
+    def set_game(self, game):
+        self.game = game
+        self.gd = game.gd
         self.resource = self.gd.resource
         self.sound = self.gd.sound
         self.setup()
@@ -230,20 +232,31 @@
 
     # initial data (optional, defaults to none)
     INITIAL_DATA = None
+    STATE_KEY = None
 
     def __init__(self):
         GameDeveloperGizmo.__init__(self)
-        self.data = {}
-        if self.INITIAL_DATA:
-            # deep copy of INITIAL_DATA allows lists, sets and
-            # other mutable types to safely be used in INITIAL_DATA
-            self.data.update(copy.deepcopy(self.INITIAL_DATA))
+        self.state_key = self.STATE_KEY
+        self.state = None  # set this with set_state if required
+
+    def set_state(self, state):
+        """Set the state object and initialize if needed"""
+        self.state = state
+        if self.state_key not in self.state:
+            self.state[self.state_key] = {}
+            if self.INITIAL_DATA:
+                # deep copy of INITIAL_DATA allows lists, sets and
+                # other mutable types to safely be used in INITIAL_DATA
+                self.state[self.state_key].update(
+                        copy.deepcopy(self.INITIAL_DATA))
 
     def set_data(self, key, value):
-        self.data[key] = value
+        if self.state:
+            self.state[self.state_key][key] = value
 
     def get_data(self, key):
-        return self.data.get(key, None)
+        if self.state:
+            return self.state[self.state_key].get(key, None)
 
 
 class Scene(StatefulGizmo):
@@ -265,27 +278,32 @@
         StatefulGizmo.__init__(self)
         # scene name
         self.name = self.NAME if self.NAME is not None else self.FOLDER
+        self.state_key = self.name
         # map of thing names -> Thing objects
         self.things = {}
         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.state.add_item(item)
+        self.game.add_item(item)
 
     def add_thing(self, thing):
         self.things[thing.name] = thing
-        thing.set_state(self.state)
+        thing.set_game(self.game)
         thing.set_scene(self)
 
     def remove_thing(self, thing):
         del self.things[thing.name]
-        if thing is self.state.current_thing:
-            self.state.current_thing.leave()
-            self.state.current_thing = None
+        if thing is self.game.current_thing:
+            self.game.current_thing.leave()
+            self.game.current_thing = None
 
     def _get_description(self):
-        text = (self.state.current_thing and
-                self.state.current_thing.get_description())
+        text = (self.game.current_thing and
+                self.game.current_thing.get_description())
         if text is None:
             return None
         label = BoomLabel(text)
@@ -332,8 +350,8 @@
 
         Returns a Result object to provide feedback to the player.
         """
-        if self.state.current_thing is not None:
-            return self.state.current_thing.interact(item)
+        if self.game.current_thing is not None:
+            return self.game.current_thing.interact(item)
 
     def animate(self):
         """Animate all the things in the scene.
@@ -352,14 +370,14 @@
         return None
 
     def update_current_thing(self, pos):
-        if self.state.current_thing is not None:
-            if not self.state.current_thing.contains(pos):
-                self.state.current_thing.leave()
-                self.state.current_thing = None
+        if self.game.current_thing is not None:
+            if not self.game.current_thing.contains(pos):
+                self.game.current_thing.leave()
+                self.game.current_thing = None
         for thing in self.things.itervalues():
             if thing.contains(pos):
-                thing.enter(self.state.tool)
-                self.state.current_thing = thing
+                thing.enter(self.game.tool)
+                self.game.current_thing = thing
                 break
 
     def mouse_move(self, pos):
@@ -430,6 +448,7 @@
         self.name = self.NAME
         # folder for resource (None is overridden by scene folder)
         self.folder = self.FOLDER
+        self.state_key = self.NAME
         # interacts
         self.interacts = self.INTERACTS
         # these are set by set_scene
@@ -453,7 +472,8 @@
         self.scene = scene
         if self.folder is None:
             self.folder = scene.FOLDER
-        self.state = scene.state
+        self.game = scene.game
+        self.set_state(self.game.data)
         for interact in self.interacts.itervalues():
             interact.set_thing(self)
         self.set_interact(self.INITIAL)
@@ -495,7 +515,7 @@
             self.current_interact.rect = old_rect.move(self.scene.OFFSET)
         self.current_interact.draw(surface)
         self.current_interact.rect = old_rect
-        if self.state.debug_rects and self._interact_hilight_color:
+        if self.game.debug_rects and self._interact_hilight_color:
             if hasattr(self.rect, 'collidepoint'):
                 frame_rect(surface, self._interact_hilight_color,
                         self.rect.inflate(1, 1), 1)
--- a/pyntnclick/widgets/__init__.py	Sat Feb 11 20:05:22 2012 +0200
+++ b/pyntnclick/widgets/__init__.py	Sat Feb 11 20:09:47 2012 +0200
@@ -92,7 +92,7 @@
         self.screen.state_widget.mouse_move(event)
 
     def mouse_move(self, event):
-        self.screen.state.highlight_override = True
+        self.screen.game.highlight_override = True
 
     def draw(self, surface):
         super(BoomButton, self).draw(surface)