Mercurial > pyntnclick
diff pyntnclick/state.py @ 792:bdaffaa8b6bf pyntnclick
Loading and saving! (Plus a bunch of other stuff to make it possible.)
author | Jeremy Thurgood <firxen@gmail.com> |
---|---|
date | Sun, 27 Jan 2013 12:43:28 +0200 |
parents | a8510f4e2ea1 |
children | bcc9277a23e6 |
line wrap: on
line diff
--- a/pyntnclick/state.py Sat Jan 26 20:29:58 2013 +0200 +++ b/pyntnclick/state.py Sun Jan 27 12:43:28 2013 +0200 @@ -1,5 +1,7 @@ """Utilities and base classes for dealing with scenes.""" +import os +import json import copy from widgets.text import LabelWidget @@ -45,8 +47,10 @@ sub-class this and feed the subclass into GameDescription via the custom_data parameter.""" - def __init__(self): - self._game_state = {'inventories': {'main': []}} + def __init__(self, state_dict=None): + if state_dict is None: + state_dict = {'inventories': {'main': []}, 'current_scene': None} + self._game_state = copy.deepcopy(state_dict) def __getitem__(self, key): return self._game_state[key] @@ -54,6 +58,9 @@ def __contains__(self, key): return key in self._game_state + def export_data(self): + return copy.deepcopy(self._game_state) + def get_all_gizmo_data(self, state_key): """Get all state for a gizmo - returns a dict""" return self[state_key] @@ -71,13 +78,37 @@ 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 + # deep copy of INITIAL_DATA allows lists, dicts and other + # mutable types to safely be used in INITIAL_DATA self._game_state[state_key].update(copy.deepcopy(initial_data)) def inventory(self, name='main'): return self['inventories'][name] + def set_current_scene(self, scene_name): + self._game_state['current_scene'] = scene_name + + @classmethod + def get_save_fn(cls, save_dir, save_name): + return os.path.join(save_dir, '%s.json' % (save_name,)) + + @classmethod + def load_game(cls, save_dir, save_name): + fn = cls.get_save_fn(save_dir, save_name) + if os.access(fn, os.R_OK): + f = open(fn, 'r') + state = json.load(f) + f.close() + return state + + def save_game(self, save_dir, save_name): + fn = self.get_save_fn(save_dir, save_name) + if not os.path.isdir(save_dir): + os.makedirs(save_dir) + f = open(fn, 'w') + json.dump(self.export_data(), f) + f.close() + class Game(object): """Complete game state. @@ -87,7 +118,7 @@ * items * scenes """ - def __init__(self, gd): + def __init__(self, gd, game_state): # game description self.gd = gd # map of scene name -> Scene object @@ -101,12 +132,16 @@ # currently selected tool (item) self.tool = None # Global game data - self.data = self.gd.game_state() - # current scene - self.current_scene = None + self.data = game_state # debug rects self.debug_rects = False + def get_current_scene(self): + scene_name = self.data['current_scene'] + if scene_name is not None: + return self.scenes[scene_name] + return None + def inventory(self, name=None): if name is None: name = self.current_inventory @@ -153,16 +188,14 @@ ScreenEvent.post('game', 'inventory', None) def add_inventory_item(self, name): - self.inventory().append(self.items[name]) + self.inventory().append(name) self._update_inventory() def is_in_inventory(self, name): - if name in self.items: - return self.items[name] in self.inventory() - return False + return name in self.inventory() def remove_inventory_item(self, name): - self.inventory().remove(self.items[name]) + self.inventory().remove(name) # Unselect tool if it's removed if self.tool == self.items[name]: self.set_tool(None) @@ -171,8 +204,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(old_item_name) + self.inventory()[index] = new_item_name if self.tool == self.items[old_item_name]: self.set_tool(self.items[new_item_name]) except ValueError: