changeset 356:ab41334e8a57

Added or1andov's code with a few adjustments to fix instance transparencies fixed[t:378] Added layer transparency support Added layer transparency to map editor
author prock@33b003aa-7bff-0310-803a-e67f0ece8222
date Thu, 24 Sep 2009 18:24:47 +0000
parents 8b125ec749d7
children 2cdce58c1109
files clients/editor/gui/layerdialog.xml clients/editor/scripts/gui/layerdialog.py clients/rio_de_hola/maps/shrine.xml engine/core/model/structures/layer.cpp engine/core/model/structures/layer.h engine/core/model/structures/layer.i engine/core/view/renderers/instancerenderer.cpp engine/core/view/visual.h engine/core/view/visual.i engine/extensions/savers.py engine/extensions/serializers/xmlmap.py
diffstat 11 files changed, 176 insertions(+), 113 deletions(-) [+]
line wrap: on
line diff
--- a/clients/editor/gui/layerdialog.xml	Tue Sep 22 19:03:53 2009 +0000
+++ b/clients/editor/gui/layerdialog.xml	Thu Sep 24 18:24:47 2009 +0000
@@ -29,6 +29,10 @@
 			<Label name="yOffsetLabel" text="Y:" hexpand="0" />
 			<TextField name="yOffsetBox" text="0.0" min_size="45,10" />
 		</HBox>
+		<HBox>
+			<Label name="transLabel" text="Transparency:" hexpand="0" />
+			<TextField name="transBox" text="0" min_size="45,10" />
+		</HBox>
 	</VBox>
 	
 	<HBox>
--- a/clients/editor/scripts/gui/layerdialog.py	Tue Sep 22 19:03:53 2009 +0000
+++ b/clients/editor/scripts/gui/layerdialog.py	Thu Sep 24 18:24:47 2009 +0000
@@ -58,7 +58,8 @@
 				"yScaleBox" : unicode(cg.getYScale()),
 				"rotBox" : unicode(cg.getRotation()),
 				"xOffsetBox" : unicode(cg.getXShift()),
-				"yOffsetBox" : unicode(cg.getYShift())
+				"yOffsetBox" : unicode(cg.getYShift()),
+				"transBox" : unicode(layer.getLayerTransparency())
 			})
 			
 			self._widget.findChild(name="pathingBox").selected = int(layer.getPathingStrategy())
@@ -108,6 +109,19 @@
 			print 'Please enter integer or decimal value for rotation.'
 			return
 			
+		try:
+			transparency = int(self._widget.collectData('transBox'))
+		except ValueError:
+			print 'Please enter an integer value in the range of 0-255 for transparency.'
+			return
+			
+		
+		#Clamp the transparency value between 0 and 255
+		if transparency < 0:
+			transparency = 0
+		if transparency > 255:
+			transparency = 255
+		
 		grid_type = int(self._widget.collectData('gridBox'))
 		pathing = int(self._widget.collectData('pathingBox'))
 
@@ -147,6 +161,7 @@
 				return
 		
 		layer.setPathingStrategy(pathing)
+		layer.setLayerTransparency(transparency)
 		
 		self.engine.getView().resetRenderers()
 		
--- a/clients/rio_de_hola/maps/shrine.xml	Tue Sep 22 19:03:53 2009 +0000
+++ b/clients/rio_de_hola/maps/shrine.xml	Thu Sep 24 18:24:47 2009 +0000
@@ -60,7 +60,7 @@
 	<import file="../objects/agents/boy/object.xml"></import>
 	<import file="../objects/agents/girl/object.xml"></import>
 	<import file="../objects/buildings/beach_bar/object.xml"></import>
-	<layer x_offset="0.0" pathing="cell_edges_and_diagonals" y_offset="0.0" grid_type="square" id="TechdemoMapTileLayer" x_scale="1.0" y_scale="1.0" rotation="0.0">
+	<layer x_offset="0.0" pathing="cell_edges_and_diagonals" y_offset="0.0" grid_type="square" id="TechdemoMapTileLayer" transparency="0" x_scale="1.0" y_scale="1.0" rotation="0.0">
 		<instances>
 			<i x="-1.0" o="sands:01" y="1.0" r="0" z="0.0" ns="http://www.fifengine.de/xml/rio_de_hola"></i>
 			<i x="0.0" o="sands:01" z="0.0" y="1.0" r="0"></i>
@@ -4740,7 +4740,7 @@
 			<i x="7.0" o="sands:01" z="0.0" y="-24.0" r="0"></i>
 		</instances>
 	</layer>
-	<layer x_offset="0.0" pathing="cell_edges_and_diagonals" y_offset="0.0" grid_type="square" id="GroundLayer" x_scale="0.5" y_scale="0.5" rotation="0.0">
+	<layer x_offset="0.0" pathing="cell_edges_and_diagonals" y_offset="0.0" grid_type="square" id="GroundLayer" transparency="0" x_scale="0.5" y_scale="0.5" rotation="0.0">
 		<instances>
 			<i x="9.0" o="sands:02" z="0.0" y="9.0" r="0"></i>
 			<i x="-2.0" o="sands:02" z="0.0" y="0.0" r="0"></i>
@@ -5176,7 +5176,7 @@
 			<i x="-34.0" o="sands:02" z="0.0" y="-27.0" r="0"></i>
 		</instances>
 	</layer>
-	<layer x_offset="0.0" pathing="cell_edges_and_diagonals" y_offset="0.0" grid_type="square" id="TechdemoMapGroundObjectLayer" x_scale="0.5" y_scale="0.5" rotation="0.0">
+	<layer x_offset="0.0" pathing="cell_edges_and_diagonals" y_offset="0.0" grid_type="square" id="TechdemoMapGroundObjectLayer" transparency="0" x_scale="0.5" y_scale="0.5" rotation="0.0">
 		<instances>
 			<i x="8.0" o="shrine" z="0.0" y="-1.0" r="180"></i>
 			<i x="11.0" o="shrine" z="0.0" y="-1.0" r="0"></i>
--- a/engine/core/model/structures/layer.cpp	Tue Sep 22 19:03:53 2009 +0000
+++ b/engine/core/model/structures/layer.cpp	Thu Sep 24 18:24:47 2009 +0000
@@ -44,6 +44,7 @@
 		: m_id(identifier),
 		m_map(map),
 		m_instances_visibility(true),
+		m_transparency(0),
 		m_instanceTree(new InstanceTree()),
 		m_grid(grid),
 		m_pathingstrategy(CELL_EDGES_ONLY),
@@ -63,10 +64,10 @@
 
 	Instance* Layer::createInstance(Object* object, const ModelCoordinate& p, const std::string& id) {
 		ExactModelCoordinate emc(static_cast<double>(p.x), static_cast<double>(p.y), static_cast<double>(p.z));
-		return createInstance(object, emc, id);	
+		return createInstance(object, emc, id);
 	}
 
-	Instance* Layer::createInstance(Object* object, const ExactModelCoordinate& p, const std::string& id) { 
+	Instance* Layer::createInstance(Object* object, const ExactModelCoordinate& p, const std::string& id) {
 		Location l;
 		l.setLayer(this);
 		l.setExactLayerCoordinates(p);
@@ -74,7 +75,7 @@
 		Instance* instance = new Instance(object, l, id);
 		m_instances.push_back(instance);
 		m_instanceTree->addInstance(instance);
-		
+
 		std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
 		while (i != m_changelisteners.end()) {
 			(*i)->onInstanceCreate(this, instance);
@@ -83,13 +84,13 @@
 		m_changed = true;
 		return instance;
 	}
-	
+
 	bool Layer::addInstance(Instance* instance, const ExactModelCoordinate& p){
         if( !instance ){
             FL_ERR(_log, "Tried to add an instance to layer, but given instance is invalid");
             return false;
         }
-        
+
 	    Location l;
 		l.setLayer(this);
 		l.setExactLayerCoordinates(p);
@@ -105,14 +106,14 @@
 		m_changed = true;
 		return true;
 	}
-	
+
 	void Layer::deleteInstance(Instance* instance) {
 		std::vector<LayerChangeListener*>::iterator i = m_changelisteners.begin();
 		while (i != m_changelisteners.end()) {
 			(*i)->onInstanceDelete(this, instance);
 			++i;
 		}
-	
+
 		std::vector<Instance*>::iterator it = m_instances.begin();
 		for(; it != m_instances.end(); ++it) {
 			if(*it == instance) {
@@ -168,7 +169,7 @@
 		if (!layer) {
 			layer = this;
 		}
-		
+
 		bool first_found = false;
 		for (std::vector<Instance*>::const_iterator i = m_instances.begin(); i != m_instances.end(); ++i) {
 			if (!first_found) {
@@ -177,19 +178,19 @@
 				first_found = true;
 			} else {
 				ModelCoordinate coord = (*i)->getLocationRef().getLayerCoordinates(layer);
-	
+
 				if(coord.x < min.x) {
 					min.x = coord.x;
 				}
-				
+
 				if(coord.x > max.x) {
 					max.x = coord.x;
 				}
-	
+
 				if(coord.y < min.y) {
 					min.y = coord.y;
 				}
-				
+
 				if(coord.y > max.y) {
 					max.y = coord.y;
 				}
@@ -204,6 +205,15 @@
 	void Layer::setInstancesVisible(bool vis) {
 		m_instances_visibility = vis;
 	}
+
+	void Layer::setLayerTransparency(uint8_t transparency) {
+		m_transparency = transparency;
+	}
+
+	uint8_t Layer::getLayerTransparency() {
+		return m_transparency;
+	}
+
 	void Layer::toggleInstancesVisible() {
 		m_instances_visibility = !m_instances_visibility;
 	}
@@ -242,7 +252,7 @@
 		m_changed = false;
 		return retval;
 	}
-	
+
 	void Layer::addChangeListener(LayerChangeListener* listener) {
 		m_changelisteners.push_back(listener);
 	}
--- a/engine/core/model/structures/layer.h	Tue Sep 22 19:03:53 2009 +0000
+++ b/engine/core/model/structures/layer.h	Thu Sep 24 18:24:47 2009 +0000
@@ -51,33 +51,33 @@
 	 *
 	 * CELL_EDGES_ONLY allows pather to use only cell edges when moving instances from cell to cell on map
 	 * CELL_EDGES_AND_DIAGONALS allows pather to use both cell edges and diagonals when moving instances from cell to cell on map
-	 * FREEFORM allows pather to find shortest route regardless of cellgrid used on the layer 
+	 * FREEFORM allows pather to find shortest route regardless of cellgrid used on the layer
 	 */
 	enum PathingStrategy {
 		CELL_EDGES_ONLY,
 		CELL_EDGES_AND_DIAGONALS,
 		FREEFORM
 	};
-	
+
 	/** Listener interface for changes happening on a layer
 	 */
 	class LayerChangeListener {
 	public:
 		virtual ~LayerChangeListener() {};
-		
+
 		/** Called when some instance is changed on layer. @see InstanceChangeType
 		 * @param layer where change occurred
 		 * @param changedInstances list of instances containing some changes
 		 * @note Does not report creations and deletions
 		 */
 		virtual void onLayerChanged(Layer* layer, std::vector<Instance*>& changedInstances) = 0;
-		
+
 		/** Called when some instance gets created on layer
 		 * @param layer where change occurred
 		 * @param instance which got created
 		 */
 		virtual void onInstanceCreate(Layer* layer, Instance* instance) = 0;
-		
+
 		/** Called when some instance gets deleted on layer
 		 * @param layer where change occurred
 		 * @param instance which will be deleted
@@ -85,8 +85,8 @@
 		 */
 		virtual void onInstanceDelete(Layer* layer, Instance* instance) = 0;
 	};
-	
-	
+
+
 	/** A basic layer on a map
 	 */
 	class Layer : public ResourceClass {
@@ -122,7 +122,7 @@
 			 */
 			void setCellGrid(CellGrid* grid) { m_grid = grid; }
 
-			/** Get the instance tree. 
+			/** Get the instance tree.
 			 * @return this layers instance tree.
 			 */
 			InstanceTree* getInstanceTree(void) const { return m_instanceTree; }
@@ -139,12 +139,12 @@
 			/** Add an instance of an object at a specific position
 			 */
 			Instance* createInstance(Object* object, const ExactModelCoordinate& p, const std::string& id="");
-			
+
 			/** Add a valid instance at a specific position. This is temporary. It will be moved to a higher level
 			later so that we can ensure that each Instance only lives in one layer.
 			 */
 			bool addInstance(Instance* instance, const ExactModelCoordinate& p);
-						
+
 			/** Remove an instance from the layer
 			 */
 			void deleteInstance(Instance* object);
@@ -171,6 +171,15 @@
 			 */
 			void setInstancesVisible(bool vis);
 
+			/** Sets the transparency of all instances on the layer.  0=opaque, 255=transparent
+			 * @parm transparency Transparency value from 0-255.
+			*/
+			void setLayerTransparency(uint8_t transparency);
+
+			/** Returns the layer's transparency value
+			*/
+			uint8_t getLayerTransparency();
+
 			/** Retrieves the minimum/maximum coordinates of instances on the layer.
 			 * @param min A reference to a ModelCoordinate that will hold the minimum coordinate.
 			 * @param max A reference to a ModelCoordinate that will hold the maximum coordinate.
@@ -199,31 +208,31 @@
 			 * @returns true if layer was changed since the last update, false otherwise
 			 */
 			bool update();
-			
+
 			/** Sets pathing strategy for the layer
 			 * @see PathingStrategy
 			 */
 			void setPathingStrategy(PathingStrategy strategy) { m_pathingstrategy = strategy; }
-			
+
 			/** Gets pathing strategy for the layer
 			 * @see PathingStrategy
 			 */
 			PathingStrategy getPathingStrategy() const { return m_pathingstrategy; }
-			
+
 			/** Adds new change listener
 			* @param listener to add
 			*/
 			void addChangeListener(LayerChangeListener* listener);
-	
+
 			/** Removes associated change listener
 			* @param listener to remove
 			*/
 			void removeChangeListener(LayerChangeListener* listener);
-			
+
 			/** Returns true, if layer information was changed during previous update round
 			*/
 			bool isChanged() { return m_changed; }
-			
+
 			/** Returns instances that were changed during previous update round.
 			 * @note does not contain created or deleted instances
 			 */
@@ -236,24 +245,26 @@
 
 			bool m_instances_visibility;
 
+			uint8_t m_transparency;
+
 			// all the instances on this layer
 			std::vector<Instance*> m_instances;
-	
+
 			//The instance tree
 			InstanceTree* m_instanceTree;
 
 			// layer's cellgrid
 			CellGrid* m_grid;
-			
+
 			// pathing strategy for the layer
 			PathingStrategy m_pathingstrategy;
-			
+
 			// listeners for layer changes
 			std::vector<LayerChangeListener*> m_changelisteners;
-			
+
 			// holds changed instances after each update
 			std::vector<Instance*> m_changedinstances;
-			
+
 			// true if layer (or it's instance) information was changed during previous update round
 			bool m_changed;
 	};
--- a/engine/core/model/structures/layer.i	Tue Sep 22 19:03:53 2009 +0000
+++ b/engine/core/model/structures/layer.i	Thu Sep 24 18:24:47 2009 +0000
@@ -77,6 +77,8 @@
 			Instance* getInstance(const std::string& id);
 
 			void setInstancesVisible(bool vis);
+			void setLayerTransparency(uint8_t transparency);
+			uint8_t getLayerTransparency();
 			bool cellContainsBlockingInstance(const ModelCoordinate& cellCoordinate);
 			void toggleInstancesVisible();
 			bool areInstancesVisible() const;
--- a/engine/core/view/renderers/instancerenderer.cpp	Tue Sep 22 19:03:53 2009 +0000
+++ b/engine/core/view/renderers/instancerenderer.cpp	Thu Sep 24 18:24:47 2009 +0000
@@ -54,34 +54,34 @@
 namespace FIFE {
 	static Logger _log(LM_VIEWVIEW);
 
-	InstanceRenderer::OutlineInfo::OutlineInfo(): 
-		r(0), 
-		g(0), 
-		b(0), 
-		width(1), 
-		outline(NULL), 
+	InstanceRenderer::OutlineInfo::OutlineInfo():
+		r(0),
+		g(0),
+		b(0),
+		width(1),
+		outline(NULL),
 		curimg(NULL) {
 	}
 	InstanceRenderer::ColoringInfo::ColoringInfo():
-		r(0), 
-		g(0), 
-		b(0), 
+		r(0),
+		g(0),
+		b(0),
 		overlay(NULL),
 		curimg(NULL) {
 	}
-	
-	InstanceRenderer::OutlineInfo::~OutlineInfo() { 
+
+	InstanceRenderer::OutlineInfo::~OutlineInfo() {
 		delete outline;
 	}
-	
+
 	InstanceRenderer::ColoringInfo::~ColoringInfo() {
 		delete overlay;
 	}
-	
+
 	InstanceRenderer* InstanceRenderer::getInstance(IRendererContainer* cnt) {
 		return dynamic_cast<InstanceRenderer*>(cnt->getRenderer("InstanceRenderer"));
 	}
-	
+
 	InstanceRenderer::InstanceRenderer(RenderBackend* renderbackend, int position, ImagePool* imagepool, AnimationPool* animpool):
 		RendererBase(renderbackend, position),
 		m_imagepool(imagepool),
@@ -102,21 +102,21 @@
 
 	InstanceRenderer::~InstanceRenderer() {
 	}
-	
+
 	void InstanceRenderer::render(Camera* cam, Layer* layer, std::vector<Instance*>& instances) {
 		// patch #335 by abeyer
 		if (!layer->areInstancesVisible()) {
 			FL_DBG(_log, "Layer instances hidden");
 			return;
 		}
-			
+
 		FL_DBG(_log, "Iterating layer...");
 		CellGrid* cg = layer->getCellGrid();
 		if (!cg) {
 			FL_WARN(_log, "No cellgrid assigned to layer, cannot draw instances");
 			return;
 		}
-		
+
 		const bool any_effects = !(m_instance_outlines.empty() && m_instance_colorings.empty());
 
 		std::vector<Instance*>::const_iterator instance_it = instances.begin();
@@ -124,46 +124,59 @@
 			FL_DBG(_log, "Iterating instances...");
 			Instance* instance = (*instance_it);
 			InstanceVisual* visual = instance->getVisual<InstanceVisual>();
+
+			unsigned char trans = visual->getTransparency();
+
+			/**
+			 *  the instance transparency value take precedence. If it's 0 use the layer trans
+			 *
+			 *	\todo Instances cannot be completely opaque when their layer's transparency is non zero.
+			 */
+			if (trans == 0) {
+				unsigned char layer_trans = layer->getLayerTransparency();
+				trans = layer_trans;
+			}
+
 			InstanceVisualCacheItem& vc = visual->getCacheItem(cam);
 			FL_DBG(_log, LMsg("Instance layer coordinates = ") << instance->getLocationRef().getLayerCoordinates());
-			
+
 			if (any_effects) {
 				InstanceToOutlines_t::iterator outline_it = m_instance_outlines.find(instance);
 				if (outline_it != m_instance_outlines.end()) {
-					bindOutline(outline_it->second, vc, cam)->render(vc.dimensions);
+					bindOutline(outline_it->second, vc, cam)->render(vc.dimensions, 255-trans);
 				}
-			
+
 				InstanceToColoring_t::iterator coloring_it = m_instance_colorings.find(instance);
 				if (coloring_it != m_instance_colorings.end()) {
-					bindColoring(coloring_it->second, vc, cam)->render(vc.dimensions);
+					bindColoring(coloring_it->second, vc, cam)->render(vc.dimensions, 255-trans);
 					continue; // Skip normal rendering after drawing overlay
 				}
 			}
-			
-			vc.image->render(vc.dimensions);
+
+			vc.image->render(vc.dimensions, 255-trans);
 		}
 	}
-	
+
 	Image* InstanceRenderer::bindOutline(OutlineInfo& info, InstanceVisualCacheItem& vc, Camera* cam) {
 		if (info.curimg == vc.image) {
 			return info.outline;
 		} else {
 			info.curimg = vc.image;
 		}
-		
+
 		if (info.outline) {
 			delete info.outline; // delete old mask
 			info.outline = NULL;
 		}
 		SDL_Surface* surface = vc.image->getSurface();
 		SDL_Surface* outline_surface = SDL_ConvertSurface(surface, surface->format, surface->flags);
-		
+
 		// needs to use SDLImage here, since GlImage does not support drawing primitives atm
 		SDLImage* img = new SDLImage(outline_surface);
-		
+
 		// TODO: optimize...
 		uint8_t r, g, b, a = 0;
-		
+
 		// vertical sweep
 		for (unsigned int x = 0; x < img->getWidth(); x ++) {
 			uint8_t prev_a = 0;
@@ -202,7 +215,7 @@
 				prev_a = a;
 			}
 		}
-		
+
 		// In case of OpenGL backend, SDLImage needs to be converted
 		info.outline = m_renderbackend->createImage(img->detachSurface());
 		delete img;
@@ -221,12 +234,12 @@
 		}
 		SDL_Surface* surface = vc.image->getSurface();
 		SDL_Surface* overlay_surface = SDL_ConvertSurface(surface, surface->format, surface->flags);
-		
+
 		// needs to use SDLImage here, since GlImage does not support drawing primitives atm
 		SDLImage* img = new SDLImage(overlay_surface);
-		
+
 		uint8_t r, g, b, a = 0;
-		
+
 		for (unsigned int x = 0; x < img->getWidth(); x ++) {
 			for (unsigned int y = 0; y < img->getHeight(); y ++) {
 				vc.image->getPixelRGBA(x, y, &r, &g, &b, &a);
@@ -235,7 +248,7 @@
 				}
 			}
 		}
-		
+
 		// In case of OpenGL backend, SDLImage needs to be converted
 		info.overlay = m_renderbackend->createImage(img->detachSurface());
 		delete img;
@@ -248,7 +261,7 @@
 		info.g = g;
 		info.b = b;
 		info.width = width;
-		
+
 		m_instance_outlines[instance] = info;
 	}
 
@@ -257,29 +270,29 @@
 		info.r = r;
 		info.g = g;
 		info.b = b;
-		
+
 		m_instance_colorings[instance] = info;
 	}
 
 	void InstanceRenderer::removeOutlined(Instance* instance) {
 		m_instance_outlines.erase(instance);
 	}
-	
+
 	void InstanceRenderer::removeColored(Instance* instance) {
 		m_instance_colorings.erase(instance);
 	}
-	
+
 	void InstanceRenderer::removeAllOutlines() {
 		m_instance_outlines.clear();
 	}
-	
+
 	void InstanceRenderer::removeAllColored() {
 		m_instance_colorings.clear();
 	}
-	
+
 	void InstanceRenderer::reset() {
 		removeAllOutlines();
 		removeAllColored();
 	}
-	
+
 }
--- a/engine/core/view/visual.h	Tue Sep 22 19:03:53 2009 +0000
+++ b/engine/core/view/visual.h	Thu Sep 24 18:24:47 2009 +0000
@@ -38,7 +38,7 @@
 	class Instance;
 	class Action;
 	class Image;
-	
+
 	/** Base class for all 2 dimensional visual classes
 	 * Visual classes are extensions to visualize the stuff in model (e.g. instances)
 	 * The reason why its separated is to keep model view-agnostic, so that we could
@@ -49,35 +49,35 @@
 		/** Destructor
 		 */
 		virtual ~Visual2DGfx();
-		
+
 		/** Sets transparency value for object to be visualized
 		 *  @param stackposition new stack position
 		 */
 		void setTransparency(uint8_t transparency) { m_transparency = transparency; }
-		
+
 		/** Gets current transparency value (0-255)
 		 *  @return current transparency value
 		 */
 		unsigned int getTransparency() { return m_transparency; }
-	
+
 		/** Sets visibility value for object to be visualized
 		 *  @param visible is object visible or not
 		 */
 		void setVisible(bool visible) { m_visible = visible; }
-		
+
 		/** Is instance visible or not
 		 *  @return is instance visible or not
 		 */
 		unsigned int isVisible() { return m_visible; }
-	
+
 	protected:
 		/** Constructor
 		 */
 		Visual2DGfx();
-		
+
 		uint8_t m_transparency;
 		uint8_t m_visible;
-	
+
 	};
 
 	/** Object visual contains data that is needed for visualizing objects
@@ -87,11 +87,11 @@
 		/** Constructs and assigns it to the passed item
 		 */
 		static ObjectVisual* create(Object* object);
-		
+
 		/** Destructor
 		 */
 		virtual ~ObjectVisual();
-		
+
 		/** Adds new static image with given angle (degrees)
 		 * Static images are used in case there are no actions active in the instance
 		 * There can be several static images for different angles, that are used in
@@ -102,26 +102,26 @@
 		  @param image_index index of image to use for given degress
 		 */
 		void addStaticImage(unsigned int angle, int image_index);
-		
+
 		/** Returns closest matching static image for given angle
 		 * @return id for static image
 		 */
 		int getStaticImageIndexByAngle(int angle);
-		
+
 		/** Returns closest matching image angle for given angle
 		 * @return closest matching angle
 		 */
 		int getClosestMatchingAngle(int angle);
-		
+
 		/** Returns list of available static image angles for this object
 		 */
 		void getStaticImageAngles(std::vector<int>& angles);
-		
+
 	private:
 		/** Constructor
 		 */
 		ObjectVisual();
-		
+
 		type_angle2id m_angle2img;
 	};
 
@@ -132,23 +132,23 @@
 	class InstanceVisualCacheItem {
 	public:
 		InstanceVisualCacheItem();
-	
+
 		/** Returns closest matching static image for given angle
 		* @return id for static image
 		* @see ObjectVisual::getStaticImageIndexByAngle
 		*/
 		int getStaticImageIndexByAngle(unsigned int angle, Instance* instance);
-	
+
 		// point where instance was drawn during the previous render
 		ScreenPoint screenpoint;
-		
+
 		// dimensions of this visual during the previous render
 		Rect dimensions;
-		
+
 		// image used during previous render
 		Image* image;
-		
-		// current facing angle 
+
+		// current facing angle
 		int facing_angle;
 	private:
 		int m_cached_static_img_id;
@@ -162,28 +162,28 @@
 		/** Constructs and assigns it to the passed item
 		 */
 		static InstanceVisual* create(Instance* instance);
-		
+
 		/** Destructor
 		 */
 		virtual ~InstanceVisual();
-		
+
 		/** Sets stack position of the instance
 		 *  Stack position is used to define the order in which instances residing
 		 *  in the same location are drawn
 		 *  @param stackposition new stack position
 		 */
 		void setStackPosition(int stackposition) { m_stackposition = stackposition; }
-		
+
 		/** Gets current stack position of instance
 		 *  @return current stack position
 		 */
 		int getStackPosition() { return m_stackposition; }
-		
+
 		/** Get camera specific cache item for the visual
 		 *  @return cache item
 		 */
 		inline InstanceVisualCacheItem& getCacheItem(Camera* cam) { return m_cache[cam]; }
-		
+
 	private:
 		/** Constructor
 		 */
@@ -192,7 +192,7 @@
 		// there is separate cache item for each camera
 		std::map<Camera*, InstanceVisualCacheItem> m_cache;
 	};
-	
+
 	/** Action visual contains data that is needed to visualize different actions on screen
 	 */
 	class ActionVisual: public Visual2DGfx {
@@ -200,29 +200,29 @@
 		/** Constructs and assigns it to the passed item
 		 */
 		static ActionVisual* create(Action* action);
-		
+
 		/** Destructor
 		 */
 		virtual ~ActionVisual();
-		
+
 		/** Adds new animation with given angle (degrees)
 		 */
 		void addAnimation(unsigned int angle, int animation_index);
-		
+
 		/** Gets index to animation closest to given angle
 		 * @return animation index, -1 if no animations available
 		 */
 		int getAnimationIndexByAngle(int angle);
-		
+
 	private:
 		/** Constructor
 		 */
 		ActionVisual();
-		
+
 		// animations associated with this action (handles to pool)
 		//   mapping = direction -> animation
 		type_angle2id m_animations;
 	};
-	
+
 }
 #endif
--- a/engine/core/view/visual.i	Tue Sep 22 19:03:53 2009 +0000
+++ b/engine/core/view/visual.i	Thu Sep 24 18:24:47 2009 +0000
@@ -29,7 +29,7 @@
 	public:
 		virtual ~Visual2DGfx();
 		void setTransparency(uint8_t transparency);
-		unsigned int getTransparency();
+		uint8_t getTransparency();
 		void setVisible(bool visible);
 		unsigned int isVisible();
 	private:
--- a/engine/extensions/savers.py	Tue Sep 22 19:03:53 2009 +0000
+++ b/engine/extensions/savers.py	Thu Sep 24 18:24:47 2009 +0000
@@ -160,6 +160,7 @@
 				(None, 'x_offset'): str(cellgrid.getXShift()),
 				(None, 'y_offset'): str(cellgrid.getYShift()),
 				(None, 'pathing'): self.pathing_val_to_str(layer.getPathingStrategy()),
+				(None, 'transparency'): str(layer.getLayerTransparency()),
 			}
 			attr_names = {
 				(None, 'id'): 'id',
--- a/engine/extensions/serializers/xmlmap.py	Tue Sep 22 19:03:53 2009 +0000
+++ b/engine/extensions/serializers/xmlmap.py	Thu Sep 24 18:24:47 2009 +0000
@@ -157,13 +157,18 @@
 			x_offset = layer.get('x_offset')
 			y_offset = layer.get('y_offset')
 			pathing = layer.get('pathing')
-
+			transparency = layer.get('transparency')
+			
 			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 transparency: 
+				transparency = 0
+			else:
+				transparency = int(transparency)
 
 			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.']))
@@ -192,6 +197,8 @@
 				strgy = fife.FREEFORM
 			layer_obj.setPathingStrategy(strgy)
 
+			layer_obj.setLayerTransparency(transparency)
+
 			self.parse_instances(layer, layer_obj)
 
 			if self.callback is not None: