Package fife :: Package extensions :: Package serializers :: Module xmlmapsaver
[hide private]
[frames] | no frames]

Source Code for Module fife.extensions.serializers.xmlmapsaver

  1  # -*- coding: utf-8 -*- 
  2   
  3  # #################################################################### 
  4  #  Copyright (C) 2005-2019 by the FIFE team 
  5  #  http://www.fifengine.net 
  6  #  This file is part of FIFE. 
  7  # 
  8  #  FIFE is free software; you can redistribute it and/or 
  9  #  modify it under the terms of the GNU Lesser General Public 
 10  #  License as published by the Free Software Foundation; either 
 11  #  version 2.1 of the License, or (at your option) any later version. 
 12  # 
 13  #  This library is distributed in the hope that it will be useful, 
 14  #  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 16  #  Lesser General Public License for more details. 
 17  # 
 18  #  You should have received a copy of the GNU Lesser General Public 
 19  #  License along with this library; if not, write to the 
 20  #  Free Software Foundation, Inc., 
 21  #  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA 
 22  # #################################################################### 
 23   
 24  from builtins import zip 
 25  from builtins import str 
 26  from builtins import range 
 27  from builtins import object 
 28  import os 
 29  from xml.sax.saxutils import XMLGenerator 
 30  from xml.sax.xmlreader import AttributesNSImpl 
 31  from fife.extensions.serializers import * 
 32   
 33  from fife import fife 
 34   
 35  MAPFORMAT = '1.0' 
 36   
 37  fileExtensions = ('xml',) 
38 -class XMLMapSaver(object):
39
40 - def __init__(self, filepath, engine, map, importList, state = 0, datastate = 0):
41 self.SModel, self.SMap, self.SLayer, self.SInstances, self.SObject, self.SAction = list(range(6)) 42 43 self.engine = engine 44 self.model = self.engine.getModel() 45 self.image_manager = self.engine.getImageManager() 46 47 if (state): 48 self.state = state 49 if (state == self.SMap): 50 self.map = datastate 51 else: 52 assert 0, "Invalid initialization state." 53 else: 54 self.state = self.SModel 55 56 self.stack = [ self.SModel ] 57 self.datastack = [ ] 58 59 self.file = open(filepath, 'w') 60 self.xmlout = XMLGenerator(self.file, 'ascii') 61 self.xmlout.startDocument() 62 63 self.indent_level = '' 64 65 self.nspace = None 66 67 self.map = map 68 self.importList = importList
69
70 - def startElement(self, name, attrs):
71 self.file.write(self.indent_level) 72 self.xmlout.startElementNS((None, name), name, attrs) 73 self.file.write('\n') 74 self.indent_level = self.indent_level + '\t'
75
76 - def endElement(self, name):
77 self.indent_level = self.indent_level[0:(len(self.indent_level) - 1)] 78 self.file.write(self.indent_level) 79 self.xmlout.endElementNS((None, name), name) 80 self.file.write('\n')
81
82 - def write_map(self):
83 assert self.state == self.SModel, "Declaration of <map> not at the top level." 84 85 attr_vals = { 86 (None, 'id'): self.map.getId(), 87 (None, 'format'): MAPFORMAT, 88 } 89 attr_names = { 90 (None, 'id'): 'id', 91 (None, 'format'): 'format', 92 } 93 attrs = AttributesNSImpl(attr_vals, attr_names) 94 self.startElement('map', attrs) 95 self.state = self.SMap 96 self.write_imports(self.map, self.importList) 97 self.write_layers(self.map) 98 self.write_camera(self.map) 99 self.endElement('map')
100
101 - def write_imports(self, map, importList):
102 for importdir in importList: 103 self.write_importdir(root_subfile(map.getFilename(), importdir)) 104 105 imports = [] 106 for layer in map.getLayers(): 107 for instance in layer.getInstances(): 108 file = instance.getObject().getFilename() 109 if not (file in imports): 110 if not self.have_superdir(file, importList): 111 imports.append(file) 112 self.write_import(root_subfile(map.getFilename(), file))
113
114 - def have_superdir(self, file, importList):
115 '''returns true, if file is in directories given in importList''' 116 for dir in importList: 117 have = True 118 for test in zip(dir.split(os.path.sep), file.split(os.path.sep)): 119 if test[0] != test[1]: have = False 120 if have: return True 121 122 return False
123
124 - def write_import(self, file):
125 attr_vals = { 126 (None, 'file'): file, 127 } 128 attr_names = { 129 (None, 'file'): 'file', 130 } 131 attrs = AttributesNSImpl(attr_vals, attr_names) 132 self.file.write(self.indent_level) 133 self.xmlout.startElementNS((None, 'import'), 'import', attrs) 134 self.xmlout.endElementNS((None, 'import'), 'import') 135 self.file.write('\n')
136
137 - def write_importdir(self, dir):
138 attr_vals = { 139 (None, 'dir'): dir, 140 } 141 attr_names = { 142 (None, 'dir'): 'dir', 143 } 144 attrs = AttributesNSImpl(attr_vals, attr_names) 145 self.file.write(self.indent_level) 146 self.xmlout.startElementNS((None, 'import'), 'import', attrs) 147 self.xmlout.endElementNS((None, 'import'), 'import') 148 self.file.write('\n')
149
150 - def pathing_val_to_str(self, val):
151 if val == fife.CELL_EDGES_AND_DIAGONALS: 152 return "cell_edges_and_diagonals" 153 if val == fife.FREEFORM: 154 return "freeform" 155 return "cell_edges_only"
156
157 - def layer_type_to_str(self, layer):
158 if layer.isWalkable(): return "walkable" 159 elif layer.isInteract(): return "interact" 160 return ""
161
162 - def write_layers(self, map):
163 for layer in map.getLayers(): 164 cellgrid = layer.getCellGrid() 165 attr_vals = { 166 (None, 'id'): layer.getId(), 167 (None, 'grid_type'): cellgrid.getType(), 168 (None, 'x_scale'): str(cellgrid.getXScale()), 169 (None, 'y_scale'): str(cellgrid.getYScale()), 170 (None, 'rotation'): str(cellgrid.getRotation()), 171 (None, 'x_offset'): str(cellgrid.getXShift()), 172 (None, 'y_offset'): str(cellgrid.getYShift()), 173 (None, 'z_offset'): str(cellgrid.getZShift()), 174 (None, 'pathing'): self.pathing_val_to_str(layer.getPathingStrategy()), 175 (None, 'transparency'): str(layer.getLayerTransparency()), 176 (None, 'layer_type'): str(self.layer_type_to_str(layer)), 177 (None, 'layer_type_id'): str(layer.getWalkableId()), 178 } 179 attr_names = { 180 (None, 'id'): 'id', 181 (None, 'grid_type'): 'grid_type', 182 (None, 'scaling'): 'scaling', 183 (None, 'rotation'): 'rotation', 184 (None, 'x_offset'): 'x_offset', 185 (None, 'y_offset'): 'y_offset', 186 (None, 'z_offset'): 'z_offset', 187 (None, 'pathing'): 'pathing', 188 (None, 'layer_type'): 'layer_type', 189 (None, 'layer_type_id'): 'layer_type_id', 190 } 191 attrs = AttributesNSImpl(attr_vals, attr_names) 192 self.startElement('layer', attrs) 193 self.write_instances(layer) 194 self.write_lights(layer) 195 self.endElement('layer')
196
197 - def write_instances(self, layer):
198 attrs = AttributesNSImpl({}, {}) 199 self.startElement('instances', attrs) 200 201 for inst in layer.getInstances(): 202 position = inst.getLocationRef().getExactLayerCoordinates() 203 204 attr_vals = { 205 (None, 'o'): inst.getObject().getId(), 206 (None, 'x'): str(position.x), 207 (None, 'y'): str(position.y), 208 (None, 'z'): str(position.z), 209 (None, 'r'): str(inst.getRotation()), 210 } 211 attr_names = { 212 (None, 'o'): 'o', 213 (None, 'x'): 'x', 214 (None, 'y'): 'y', 215 (None, 'z'): 'z', 216 (None, 'r'): 'r', 217 } 218 219 visual = inst.get2dGfxVisual(); 220 if visual: 221 attr_vals[(None, 'stackpos')] = str(visual.getStackPosition()) 222 attr_names[(None, 'stackpos')] = 'stackpos' 223 224 nspace = inst.getObject().getNamespace() 225 if nspace != self.nspace: 226 attr_vals[(None, 'ns')] = inst.getObject().getNamespace() 227 attr_names[(None, 'ns')] = 'ns' 228 self.nspace = nspace 229 230 instId = inst.getId() 231 if instId: 232 attr_vals[(None, 'id')] = inst.getId() 233 attr_names[(None, 'id')] = 'id' 234 235 if inst.isOverrideBlocking(): 236 attr_vals[(None, 'override_blocking')] = str(int(inst.isOverrideBlocking())) 237 attr_names[(None, 'override_blocking')] = 'override_blocking' 238 if inst.getObject().isBlocking() is not inst.isBlocking(): 239 attr_vals[(None, 'blocking')] = str(int(inst.isBlocking())) 240 attr_names[(None, 'blocking')] = 'blocking' 241 242 attrs = AttributesNSImpl(attr_vals, attr_names) 243 self.file.write(self.indent_level) 244 self.xmlout.startElementNS((None, 'i'), 'i', attrs) 245 self.xmlout.endElementNS((None, 'i'), 'i') 246 self.file.write('\n') 247 248 self.endElement('instances')
249
250 - def write_lights(self, layer):
251 attrs = AttributesNSImpl({}, {}) 252 self.startElement('lights', attrs) 253 254 cameras = layer.getMap().getCameras() 255 for cam in cameras: 256 hit = False 257 layers = cam.getRenderer("LightRenderer").getActiveLayers(); 258 for lay in layers: 259 if lay.getId() == layer.getId(): 260 hit = True 261 262 if hit == False: continue 263 264 renderer = fife.LightRenderer.getInstance(cam) 265 groups = renderer.getGroups() 266 for group in groups: 267 infos = renderer.getLightInfo(group) 268 for info in infos: 269 attr_vals = {} 270 attr_names = {} 271 type = info.getName() 272 attr_vals[(None, 'group')] = str(group) 273 attr_names[(None, 'group')] = 'group' 274 attr_vals[(None, 'type')] = str(type) 275 attr_names[(None, 'type')] = 'type' 276 attr_vals[(None, 'instance')] = str(info.getNode().getInstance().getId()) 277 attr_names[(None, 'instance')] = 'instance' 278 if info.getSrcBlend() > -1: 279 attr_vals[(None, 'src')] = str(info.getSrcBlend()) 280 attr_names[(None, 'src')] = 'src' 281 if info.getDstBlend() > -1: 282 attr_vals[(None, 'dst')] = str(info.getDstBlend()) 283 attr_names[(None, 'dst')] = 'dst' 284 if info.getStencil() > -1: 285 attr_vals[(None, 's_ref')] = str(info.getStencil()) 286 attr_names[(None, 's_ref')] = 's_ref' 287 attr_vals[(None, 'a_ref')] = str(info.getAlpha()) 288 attr_names[(None, 'a_ref')] = 'a_ref' 289 290 if type == 'simple': 291 if info.getRadius() > 0: 292 attr_vals[(None, 'radius')] = str(info.getRadius()) 293 attr_names[(None, 'radius')] = 'radius' 294 if info.getColor(): 295 color = info.getColor() 296 attr_vals[(None, 'color')] = '%d,%d,%d' % (color[0], color[1], color[2]) 297 attr_vals[(None, 'intensity')] = str(color[3]) 298 attr_names[(None, 'color')] = 'color' 299 attr_names[(None, 'intensity')] = 'intensity' 300 301 if info.getSubdivisions() != 32: 302 attr_vals[(None, 'subdivisions')] = str(info.getSubdivisions()) 303 attr_names[(None, 'subdivisions')] = 'subdivisions' 304 if info.getXStretch() > 1.001 or info.getXStretch() < 0.999: 305 attr_vals[(None, 'xstretch')] = str(info.getXStretch()) 306 attr_names[(None, 'xstretch')] = 'xstretch' 307 if info.getYStretch() > 1.001 or info.getYStretch() < 0.999: 308 attr_vals[(None, 'ystretch')] = str(info.getYStretch()) 309 attr_names[(None, 'ystretch')] = 'ystretch' 310 311 elif type == 'image': 312 if info.getImage() == 0: continue 313 img = info.getImage() 314 name = img.getName() 315 attr_vals[(None, 'image')] = str('../' + name) 316 attr_names[(None, 'image')] = 'image' 317 318 elif type == 'animation': 319 if info.getAnimation() == 0: continue 320 ani = info.getAnimation(); 321 count = 0 322 newstr = '' 323 image = ani.getFrame(ani.getActionFrame()) 324 fname = image.getName() 325 strings = ([str(s) for s in fname.split('/')]) 326 leng = len(strings) -1 327 while count < leng: 328 newstr = str(newstr + strings[count] + '/') 329 count += 1 330 331 name = str('../' + newstr + 'animation.' + fileExtensions[0]) 332 attr_vals[(None, 'animation')] = str(name) 333 attr_names[(None, 'animation')] = 'animation' 334 335 else: 336 continue 337 338 attrs = AttributesNSImpl(attr_vals, attr_names) 339 self.file.write(self.indent_level) 340 self.xmlout.startElementNS((None, 'l'), 'l', attrs) 341 self.xmlout.endElementNS((None, 'l'), 'l') 342 self.file.write('\n') 343 344 self.endElement('lights')
345 346 # Save the linked camera of a map.
347 - def write_camera( self, map ):
348 cameralist = map.getCameras() 349 350 for cam in cameralist: 351 if cam.getMap().getId() == map.getId(): 352 celldimensions = cam.getCellImageDimensions() 353 viewport = cam.getViewPort(); 354 355 attr_names = { 356 (None, 'id'): 'id', 357 (None, 'zoom'): 'zoom', 358 (None, 'tilt'): 'tile', 359 (None, 'rotation'): 'rotation', 360 (None, 'ref_cell_width'): 'ref_cell_width', 361 (None, 'ref_cell_height'): 'ref_cell_height', 362 } 363 364 attr_vals = { 365 (None, 'id'): cam.getId(), 366 (None, 'zoom'): str( cam.getZoom()), 367 (None, 'tilt'): str( cam.getTilt()), 368 (None, 'rotation'): str( cam.getRotation()), 369 (None, 'ref_cell_width'): str( celldimensions.x ), 370 (None, 'ref_cell_height'): str( celldimensions.y ), 371 } 372 373 # add a viewport entry if the cam isn't full sized 374 if not (viewport == self.engine.getRenderBackend().getArea()): 375 attr_names[(None,'viewport')] = 'viewport' 376 attr_vals[(None,'viewport')] = '%d,%d,%d,%d' % (viewport.x, viewport.y, viewport.w, viewport.h) 377 378 colors = cam.getLightingColor() 379 if colors[0] < 1.0 or colors[1] < 1.0 or colors[2] < 1.0: 380 attr_names[(None,'light_color')] = 'light_color' 381 attr_vals[(None,'light_color')] = '%f,%f,%f' % (colors[0], colors[1], colors[2]) 382 attrs = AttributesNSImpl( attr_vals, attr_names ) 383 self.startElement( 'camera', attrs ); 384 self.endElement( 'camera' );
385
386 - def flush(self):
387 self.xmlout.endDocument() 388 self.file.close()
389
390 - def saveResource(self):
391 self.write_map()
392