diff engine/extensions/serializers/xmlmap.py @ 0:4a0efb7baf70

* Datasets becomes the new trunk and retires after that :-)
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 29 Jun 2008 18:44:17 +0000
parents
children ca21a01f5b1e
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/engine/extensions/serializers/xmlmap.py	Sun Jun 29 18:44:17 2008 +0000
@@ -0,0 +1,247 @@
+import fife
+try:
+	import xml.etree.cElementTree as ET
+except:
+	import xml.etree.ElementTree as ET
+
+import loaders
+from serializers import *
+
+FORMAT = '1.0'
+
+class XMLMapLoader(fife.ResourceLoader):
+	def __init__(self, engine):
+		fife.ResourceLoader.__init__(self)
+		self.thisown = 0
+
+		self.engine = engine
+		self.vfs = self.engine.getVFS()
+		self.model = self.engine.getModel()
+		self.pool = self.engine.getImagePool()
+		self.anim_pool = self.engine.getAnimationPool()
+		self.map = None
+		self.source = None
+
+		self.nspace = None
+
+	def _err(self, msg):
+		raise SyntaxError(''.join(['File: ', self.source, ' . ', msg]))
+
+	def loadResource(self, location):
+		self.source = location.getFilename()
+		f = self.vfs.open(self.source)
+		f.thisown = 1
+		tree = ET.parse(f)
+		root = tree.getroot()
+
+		map = self.parse_map(root)
+		return map
+
+	def parse_map(self, mapelt):
+		if not mapelt:
+			self._err('No <map> element found at top level of map file definition.')
+		id,format = mapelt.get('id'),mapelt.get('format')
+
+		if not format == FORMAT: self._err(''.join(['This file has format ', format, ' but this loader has format ', FORMAT]))
+		if not id: self._err('Map declared without an identifier.')
+		
+		map = None
+		try:
+			self.map = self.model.createMap(str(id))
+			self.map.setResourceFile(self.source)
+		except fife.Exception, e: # NameClash appears as general fife.Exception; any ideas?
+			print e.getMessage()
+			print ''.join(['File: ', self.source, '. The map ', str(id), ' already exists! Ignoring map definition.'])
+			return None
+
+		# xml-specific directory imports. This is used by xml savers.
+		self.map.importDirs = []
+
+		self.parse_imports(mapelt, self.map)
+		self.parse_layers(mapelt, self.map)	
+		self.parse_cameras(mapelt, self.map)
+
+		return self.map
+
+	def parse_imports(self, mapelt, map):
+		for item in mapelt.findall('import'):
+			file = item.get('file')
+			if file:
+				file = reverse_root_subfile(self.source, file)
+			dir = item.get('dir')
+			if dir:
+				dir = reverse_root_subfile(self.source, dir)
+
+			if file and dir:
+				loaders.loadImportFile('/'.join(dir, file), self.engine)
+			elif file:
+				loaders.loadImportFile(file, self.engine)
+			elif dir:
+				loaders.loadImportDirRec(dir, self.engine)
+				map.importDirs.append(dir)
+			else:
+				print 'Empty import statement?'
+
+	def parse_layers(self, mapelt, map):
+		for layer in mapelt.findall('layer'):
+			id = layer.get('id')
+			grid_type = layer.get('grid_type')
+			x_scale = layer.get('x_scale')
+			y_scale = layer.get('y_scale')
+			rotation = layer.get('rotation')
+			x_offset = layer.get('x_offset')
+			y_offset = layer.get('y_offset')
+			pathing = "cell_edges_only"
+
+			if not x_scale: x_scale = 1.0
+			if not y_scale: y_scale = 1.0
+			if not rotation: rotation = 0.0
+			if not x_offset: x_offset = 0.0
+			if not y_offset: y_offset = 0.0
+			if not pathing: pathing = "cell_edges_only"
+
+			if not id: self._err('<layer> declared with no id attribute.')
+			if not grid_type: self._err(''.join(['Layer ', str(id), ' has no grid_type attribute.']))
+
+			allow_diagonals = pathing == "cell_edges_and_diagonals"
+			if grid_type == "square":
+				cellgrid = fife.SquareGrid(allow_diagonals)
+			else:
+				cellgrid = fife.HexGrid(allow_diagonals)
+			cellgrid.thisown = 0
+
+			cellgrid.setRotation(float(rotation))
+			cellgrid.setXScale(float(x_scale))
+			cellgrid.setYScale(float(y_scale))
+			cellgrid.setXShift(float(x_offset))
+			cellgrid.setYShift(float(y_offset))
+
+			layer_obj = None
+			try:
+				layer_obj = map.createLayer(str(id), cellgrid)
+			except fife.Exception, e:
+				print e.getMessage()
+				print 'The layer ' + str(id) + ' already exists! Ignoring this layer.'
+				continue
+		
+			strgy = fife.CELL_EDGES_ONLY
+			if pathing == "cell_edges_and_diagonals":
+				strgy = fife.CELL_EDGES_AND_DIAGONALS
+			if pathing == "freeform":
+				strgy = fife.FREEFORM
+			layer_obj.setPathingStrategy(strgy)
+
+			self.parse_instances(layer, layer_obj)
+		
+	def parse_instances(self, layerelt, layer):
+		instelt = layerelt.find('instances')
+
+		instances = instelt.findall('i')
+		instances.extend(instelt.findall('inst'))
+		instances.extend(instelt.findall('instance'))
+		for instance in instances:
+
+			objectID = instance.get('object')
+			if not objectID:
+				objectID = instance.get('obj')
+			if not objectID:
+				objectID = instance.get('o')
+
+			if not objectID: self._err('<instance> does not specify an object attribute.')
+
+			nspace = instance.get('namespace')
+			if not nspace:
+				nspace = instance.get('ns')
+			if not nspace:
+				nspace = self.nspace
+
+			if not nspace: self._err('<instance> %s does not specify an object namespace, and no default is available.' % str(objectID))
+
+			self.nspace = nspace
+
+			object = self.model.getObject(str(objectID), str(nspace))
+			if not object:
+				print ''.join(['Object with id=', str(objectID), ' ns=', str(nspace), ' could not be found. Omitting...'])
+				continue
+
+			x = instance.get('x')
+			y = instance.get('y')
+			z = instance.get('z')
+			stackpos = instance.get('stackpos')
+			id = instance.get('id')
+
+			if x:
+				x = float(x)
+				self.x = x
+			else:
+				self.x = self.x + 1
+				x = self.x
+
+			if y:
+				y = float(y)
+				self.y = y
+			else:
+				y = self.y
+		
+			if z:
+				z = float(z)
+			else:
+				z = 0.0
+		
+			if not id:
+				id = ''
+			else:
+				id = str(id)
+
+			inst = layer.createInstance(object, fife.ExactModelCoordinate(x,y,z), str(id))
+			
+			rotation = instance.get('r')
+			if not rotation:
+				rotation = instance.get('rotation')
+			if not rotation:
+				angles = object.get2dGfxVisual().getStaticImageAngles()
+				if angles:
+					rotation = angles[0]
+				else:
+					rotation = 0
+			else:
+				rotation = int(rotation)
+			inst.setRotation(rotation)
+			
+			fife.InstanceVisual.create(inst)
+			if (stackpos):
+				inst.get2dGfxVisual().setStackPosition(int(stackpos))
+
+			if (object.getAction('default')):
+				target = fife.Location(layer)
+				inst.act('default', target, True)
+
+	def parse_cameras(self, mapelt, map):
+		for camera in mapelt.findall('camera'):
+			id = camera.get('id')
+			zoom = camera.get('zoom')
+			tilt = camera.get('tilt')
+			rotation = camera.get('rotation')
+			ref_layer_id = camera.get('ref_layer_id')
+			ref_cell_width = camera.get('ref_cell_width')
+			ref_cell_height = camera.get('ref_cell_height')
+			viewport = camera.get('viewport')
+
+			if not zoom: zoom = 1
+			if not tilt: tilt = 0
+			if not rotation: rotation = 0
+
+			if not id: self._err('Camera declared without an id.')
+			if not viewport: self._err(''.join(['Camera ', str(id), ' declared without a viewport.']))
+			if not ref_layer_id: self._err(''.join(['Camera ', str(id), ' declared with no reference layer.']))
+			if not (ref_cell_width and ref_cell_height): self._err(''.join(['Camera ', str(id), ' declared without reference cell dimensions.']))
+
+			try:
+				cam = self.engine.getView().addCamera(str(id), map.getLayer(str(ref_layer_id)),fife.Rect(*[int(c) for c in viewport.split(',')]),fife.ExactModelCoordinate(0,0,0))
+
+				cam.setCellImageDimensions(int(ref_cell_width), int(ref_cell_height))
+				cam.setRotation(float(rotation))
+				cam.setTilt(float(tilt))
+				cam.setZoom(float(zoom))
+			except fife.Exception, e:
+				print e.getMessage()