changeset 750:ef4bda7d623d pyntnclick

Better state and inventory management.
author Jeremy Thurgood <firxen@gmail.com>
date Sun, 20 Jan 2013 20:20:36 +0200
parents a453731e4531
children d5afaadbd821
files gamelib/main.py gamelib/scenes/machine.py pyntnclick/gamescreen.py pyntnclick/main.py pyntnclick/state.py pyntnclick/tests/game_logic_utils.py
diffstat 6 files changed, 40 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/main.py	Sun Jan 20 18:57:17 2013 +0200
+++ b/gamelib/main.py	Sun Jan 20 20:20:36 2013 +0200
@@ -18,8 +18,8 @@
             }
     START_SCREEN = 'menu'
 
-    def __init__(self):
-        super(SuspendedSentence, self).__init__(SSState)
+    def game_state(self):
+        return SSState()
 
     def game_constants(self):
         return SSConstants()
--- a/gamelib/scenes/machine.py	Sun Jan 20 18:57:17 2013 +0200
+++ b/gamelib/scenes/machine.py	Sun Jan 20 20:20:36 2013 +0200
@@ -180,21 +180,21 @@
         else:
             welder_slot.set_data("contents", set())
             welder_slot.update_contents()
-            if self.game.items["cryo_pipes_one"] in self.game.inventory:
+            if self.game.is_in_inventory("cryo_pipes_one"):
                 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.game.items["cryo_pipes_two"] in self.game.inventory:
+            elif self.game.is_in_inventory("cryo_pipes_two"):
                 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.game.items["cryo_pipes_three"] in self.game.inventory:
+            elif self.game.is_in_inventory("cryo_pipes_three"):
                 # just for safety
                 return None
             else:
--- a/pyntnclick/gamescreen.py	Sun Jan 20 18:57:17 2013 +0200
+++ b/pyntnclick/gamescreen.py	Sun Jan 20 20:20:36 2013 +0200
@@ -115,14 +115,14 @@
             self.up_button.enable()
 
         max_slot = (self.inv_offset + len(self.slots))
-        if max_slot >= len(self.game.inventory):
+        if max_slot >= len(self.game.inventory()):
             self.down_button.disable()
         else:
             self.down_button.enable()
 
     @property
     def slot_items(self):
-        return self.game.inventory[self.inv_offset:][:len(self.slots)]
+        return self.game.inventory()[self.inv_offset:][:len(self.slots)]
 
     def mouse_down(self, event, widget):
         if event.button != 1:
@@ -256,6 +256,9 @@
         getattr(self, 'game_event_%s' % event_name, lambda d: None)(data)
 
     def game_event_restart(self, data):
+        self.reset_game(self.create_initial_state())
+
+    def reset_game(self, game_state=None):
         self._clear_all()
         self.game = self.create_initial_state()
 
--- a/pyntnclick/main.py	Sun Jan 20 18:57:17 2013 +0200
+++ b/pyntnclick/main.py	Sun Jan 20 20:20:36 2013 +0200
@@ -45,7 +45,7 @@
     RESOURCE_MODULE = 'data'
     SCENE_MODULE = 'gamelib.scenes'
 
-    def __init__(self, custom_data_cls=None):
+    def __init__(self):
         if self.INITIAL_SCENE is None:
             raise GameDescriptionError("A game must have an initial scene.")
         if not self.SCENE_LIST:
@@ -58,7 +58,6 @@
         self._scene_list = self.SCENE_LIST
         self._resource_module = self.RESOURCE_MODULE
         self._debug_rects = False
-        self._custom_data_cls = custom_data_cls
         self._screens = self.SCREENS.copy()
         self._screens['game'] = GameScreen
         self.resource = Resources(self._resource_module)
@@ -70,14 +69,15 @@
     def initial_state(self):
         """Create a copy of the initial game state."""
         initial_state = state.Game(self)
-        if self._custom_data_cls:
-            initial_state.set_custom_data(self._custom_data_cls())
         initial_state.set_debug_rects(self._debug_rects)
         for scene in self._scene_list:
             initial_state.load_scenes(scene)
         initial_state.change_scene(self._initial_scene)
         return initial_state
 
+    def game_state(self):
+        return state.GameState()
+
     def game_constants(self):
         return GameConstants()
 
--- a/pyntnclick/state.py	Sun Jan 20 18:57:17 2013 +0200
+++ b/pyntnclick/state.py	Sun Jan 20 20:20:36 2013 +0200
@@ -45,13 +45,19 @@
             screen.end_game()
 
 
-class GameState(dict):
+class GameState(object):
     """This holds the serializable game state.
 
        Games wanting to do fancier stuff with the state should
        sub-class this and feed the subclass into
        GameDescription via the custom_data parameter."""
 
+    def __init__(self):
+        self._game_state = {'inventories': {'main': []}}
+
+    def __getitem__(self, key):
+        return self._game_state[key]
+
     def get_all_gizmo_data(self, state_key):
         """Get all state for a gizmo - returns a dict"""
         return self[state_key]
@@ -66,12 +72,15 @@
 
     def initialize_state(self, state_key, initial_data):
         """Initialize a gizmo entry"""
-        if state_key not in self:
-            self[state_key] = {}
+        if state_key not in self._game_state:
+            self._game_state[state_key] = {}
             if initial_data:
                 # deep copy of INITIAL_DATA allows lists, sets and
                 # other mutable types to safely be used in INITIAL_DATA
-                self[state_key].update(copy.deepcopy(initial_data))
+                self._game_state[state_key].update(copy.deepcopy(initial_data))
+
+    def inventory(self, name='main'):
+        return self['inventories'][name]
 
 
 class Game(object):
@@ -92,16 +101,21 @@
         # map of item name -> Item object
         self.items = {}
         # list of item objects in inventory
-        self.inventory = []
+        self.current_inventory = 'main'
         # currently selected tool (item)
         self.tool = None
         # Global game data
-        self.data = GameState()
+        self.data = self.gd.game_state()
         # current scene
         self.current_scene = None
         # debug rects
         self.debug_rects = False
 
+    def inventory(self, name=None):
+        if name is None:
+            name = self.current_inventory
+        return self.data.inventory(name)
+
     def set_custom_data(self, data_object):
         self.data = data_object
 
@@ -143,16 +157,16 @@
         ScreenEvent.post('game', 'inventory', None)
 
     def add_inventory_item(self, name):
-        self.inventory.append(self.items[name])
+        self.inventory().append(self.items[name])
         self._update_inventory()
 
     def is_in_inventory(self, name):
         if name in self.items:
-            return self.items[name] in self.inventory
+            return self.items[name] in self.inventory()
         return False
 
     def remove_inventory_item(self, name):
-        self.inventory.remove(self.items[name])
+        self.inventory().remove(self.items[name])
         # Unselect tool if it's removed
         if self.tool == self.items[name]:
             self.set_tool(None)
@@ -161,8 +175,8 @@
     def replace_inventory_item(self, old_item_name, new_item_name):
         """Try to replace an item in the inventory with a new one"""
         try:
-            index = self.inventory.index(self.items[old_item_name])
-            self.inventory[index] = self.items[new_item_name]
+            index = self.inventory().index(self.items[old_item_name])
+            self.inventory()[index] = self.items[new_item_name]
             if self.tool == self.items[old_item_name]:
                 self.set_tool(self.items[new_item_name])
         except ValueError:
--- a/pyntnclick/tests/game_logic_utils.py	Sun Jan 20 18:57:17 2013 +0200
+++ b/pyntnclick/tests/game_logic_utils.py	Sun Jan 20 20:20:36 2013 +0200
@@ -39,7 +39,7 @@
     def clear_inventory(self):
         # Remove all items from the inventory, ensuring tool is set to None
         self.state.set_tool(None)
-        self.state.inventory = []
+        self.state.inventory()[:] = []
 
     def set_game_data(self, key, value, thing=None):
         gizmo = self.state.current_scene