comparison 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
comparison
equal deleted inserted replaced
791:56ec01e51f3d 792:bdaffaa8b6bf
1 """Utilities and base classes for dealing with scenes.""" 1 """Utilities and base classes for dealing with scenes."""
2 2
3 import os
4 import json
3 import copy 5 import copy
4 6
5 from widgets.text import LabelWidget 7 from widgets.text import LabelWidget
6 from pygame.color import Color 8 from pygame.color import Color
7 9
43 45
44 Games wanting to do fancier stuff with the state should 46 Games wanting to do fancier stuff with the state should
45 sub-class this and feed the subclass into 47 sub-class this and feed the subclass into
46 GameDescription via the custom_data parameter.""" 48 GameDescription via the custom_data parameter."""
47 49
48 def __init__(self): 50 def __init__(self, state_dict=None):
49 self._game_state = {'inventories': {'main': []}} 51 if state_dict is None:
52 state_dict = {'inventories': {'main': []}, 'current_scene': None}
53 self._game_state = copy.deepcopy(state_dict)
50 54
51 def __getitem__(self, key): 55 def __getitem__(self, key):
52 return self._game_state[key] 56 return self._game_state[key]
53 57
54 def __contains__(self, key): 58 def __contains__(self, key):
55 return key in self._game_state 59 return key in self._game_state
60
61 def export_data(self):
62 return copy.deepcopy(self._game_state)
56 63
57 def get_all_gizmo_data(self, state_key): 64 def get_all_gizmo_data(self, state_key):
58 """Get all state for a gizmo - returns a dict""" 65 """Get all state for a gizmo - returns a dict"""
59 return self[state_key] 66 return self[state_key]
60 67
69 def initialize_state(self, state_key, initial_data): 76 def initialize_state(self, state_key, initial_data):
70 """Initialize a gizmo entry""" 77 """Initialize a gizmo entry"""
71 if state_key not in self._game_state: 78 if state_key not in self._game_state:
72 self._game_state[state_key] = {} 79 self._game_state[state_key] = {}
73 if initial_data: 80 if initial_data:
74 # deep copy of INITIAL_DATA allows lists, sets and 81 # deep copy of INITIAL_DATA allows lists, dicts and other
75 # other mutable types to safely be used in INITIAL_DATA 82 # mutable types to safely be used in INITIAL_DATA
76 self._game_state[state_key].update(copy.deepcopy(initial_data)) 83 self._game_state[state_key].update(copy.deepcopy(initial_data))
77 84
78 def inventory(self, name='main'): 85 def inventory(self, name='main'):
79 return self['inventories'][name] 86 return self['inventories'][name]
87
88 def set_current_scene(self, scene_name):
89 self._game_state['current_scene'] = scene_name
90
91 @classmethod
92 def get_save_fn(cls, save_dir, save_name):
93 return os.path.join(save_dir, '%s.json' % (save_name,))
94
95 @classmethod
96 def load_game(cls, save_dir, save_name):
97 fn = cls.get_save_fn(save_dir, save_name)
98 if os.access(fn, os.R_OK):
99 f = open(fn, 'r')
100 state = json.load(f)
101 f.close()
102 return state
103
104 def save_game(self, save_dir, save_name):
105 fn = self.get_save_fn(save_dir, save_name)
106 if not os.path.isdir(save_dir):
107 os.makedirs(save_dir)
108 f = open(fn, 'w')
109 json.dump(self.export_data(), f)
110 f.close()
80 111
81 112
82 class Game(object): 113 class Game(object):
83 """Complete game state. 114 """Complete game state.
84 115
85 Game state consists of: 116 Game state consists of:
86 117
87 * items 118 * items
88 * scenes 119 * scenes
89 """ 120 """
90 def __init__(self, gd): 121 def __init__(self, gd, game_state):
91 # game description 122 # game description
92 self.gd = gd 123 self.gd = gd
93 # map of scene name -> Scene object 124 # map of scene name -> Scene object
94 self.scenes = {} 125 self.scenes = {}
95 # map of detail view name -> DetailView object 126 # map of detail view name -> DetailView object
99 # list of item objects in inventory 130 # list of item objects in inventory
100 self.current_inventory = 'main' 131 self.current_inventory = 'main'
101 # currently selected tool (item) 132 # currently selected tool (item)
102 self.tool = None 133 self.tool = None
103 # Global game data 134 # Global game data
104 self.data = self.gd.game_state() 135 self.data = game_state
105 # current scene
106 self.current_scene = None
107 # debug rects 136 # debug rects
108 self.debug_rects = False 137 self.debug_rects = False
138
139 def get_current_scene(self):
140 scene_name = self.data['current_scene']
141 if scene_name is not None:
142 return self.scenes[scene_name]
143 return None
109 144
110 def inventory(self, name=None): 145 def inventory(self, name=None):
111 if name is None: 146 if name is None:
112 name = self.current_inventory 147 name = self.current_inventory
113 return self.data.inventory(name) 148 return self.data.inventory(name)
151 186
152 def _update_inventory(self): 187 def _update_inventory(self):
153 ScreenEvent.post('game', 'inventory', None) 188 ScreenEvent.post('game', 'inventory', None)
154 189
155 def add_inventory_item(self, name): 190 def add_inventory_item(self, name):
156 self.inventory().append(self.items[name]) 191 self.inventory().append(name)
157 self._update_inventory() 192 self._update_inventory()
158 193
159 def is_in_inventory(self, name): 194 def is_in_inventory(self, name):
160 if name in self.items: 195 return name in self.inventory()
161 return self.items[name] in self.inventory()
162 return False
163 196
164 def remove_inventory_item(self, name): 197 def remove_inventory_item(self, name):
165 self.inventory().remove(self.items[name]) 198 self.inventory().remove(name)
166 # Unselect tool if it's removed 199 # Unselect tool if it's removed
167 if self.tool == self.items[name]: 200 if self.tool == self.items[name]:
168 self.set_tool(None) 201 self.set_tool(None)
169 self._update_inventory() 202 self._update_inventory()
170 203
171 def replace_inventory_item(self, old_item_name, new_item_name): 204 def replace_inventory_item(self, old_item_name, new_item_name):
172 """Try to replace an item in the inventory with a new one""" 205 """Try to replace an item in the inventory with a new one"""
173 try: 206 try:
174 index = self.inventory().index(self.items[old_item_name]) 207 index = self.inventory().index(old_item_name)
175 self.inventory()[index] = self.items[new_item_name] 208 self.inventory()[index] = new_item_name
176 if self.tool == self.items[old_item_name]: 209 if self.tool == self.items[old_item_name]:
177 self.set_tool(self.items[new_item_name]) 210 self.set_tool(self.items[new_item_name])
178 except ValueError: 211 except ValueError:
179 return False 212 return False
180 self._update_inventory() 213 self._update_inventory()