From 99cb204d29a63bf5f4edb40b25f4fc1a6605fbd1 Mon Sep 17 00:00:00 2001
From: Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>
Date: Wed, 22 Jun 2011 21:47:53 +0200
Subject: Made possible to separate the dye colors and channels for particle
 effects.

It is now possible to write, for instance:

<particlefx>my-particle-file.xml|#cbcb78,345678</particlefx>

and in my-particle-file.xml:
...
<property image="my-image.png|W" />
...

This will permit the use (and reuse) of generic particle files.

Conflicts:

	src/particle.cpp
	src/particleemitter.cpp
	src/particleemitter.h
	src/simpleanimation.cpp
---
 src/animationparticle.cpp  |  5 +++--
 src/animationparticle.h    |  3 ++-
 src/particle.cpp           | 23 ++++++++++++++++-------
 src/particleemitter.cpp    | 10 ++++++++--
 src/particleemitter.h      |  8 +++-----
 src/rotationalparticle.cpp |  5 +++--
 src/rotationalparticle.h   |  3 ++-
 src/simpleanimation.cpp    | 16 +++++++++++++---
 src/simpleanimation.h      |  6 ++++--
 9 files changed, 54 insertions(+), 25 deletions(-)

diff --git a/src/animationparticle.cpp b/src/animationparticle.cpp
index fbe0e29df..b20625a42 100644
--- a/src/animationparticle.cpp
+++ b/src/animationparticle.cpp
@@ -33,9 +33,10 @@ AnimationParticle::AnimationParticle(Map *map, Animation *animation):
 {
 }
 
-AnimationParticle::AnimationParticle(Map *map, xmlNodePtr animationNode):
+AnimationParticle::AnimationParticle(Map *map, xmlNodePtr animationNode,
+                                     const std::string& dyePalettes):
     ImageParticle(map, 0),
-    mAnimation(new SimpleAnimation(animationNode))
+    mAnimation(new SimpleAnimation(animationNode, dyePalettes))
 {
 }
 
diff --git a/src/animationparticle.h b/src/animationparticle.h
index 6c1975710..984d3dc14 100644
--- a/src/animationparticle.h
+++ b/src/animationparticle.h
@@ -36,7 +36,8 @@ class AnimationParticle : public ImageParticle
     public:
         AnimationParticle(Map *map, Animation *animation);
 
-        AnimationParticle(Map *map, xmlNodePtr animationNode);
+        AnimationParticle(Map *map, xmlNodePtr animationNode,
+                          const std::string& dyePalettes = std::string());
 
         ~AnimationParticle();
 
diff --git a/src/particle.cpp b/src/particle.cpp
index ecc68e6cc..eca9307ea 100644
--- a/src/particle.cpp
+++ b/src/particle.cpp
@@ -25,6 +25,7 @@
 
 #include "animationparticle.h"
 #include "configuration.h"
+#include "resources/dye.h"
 #include "imageparticle.h"
 #include "log.h"
 #include "map.h"
@@ -282,7 +283,12 @@ Particle *Particle::addEffect(const std::string &particleEffectFile,
 {
     Particle *newParticle = NULL;
 
-    XML::Document doc(particleEffectFile);
+    std::string::size_type pos = particleEffectFile.find('|');
+    std::string dyePalettes;
+    if (pos != std::string::npos)
+        dyePalettes = particleEffectFile.substr(pos + 1);
+
+    XML::Document doc(particleEffectFile.substr(0, pos));
     xmlNodePtr rootNode = doc.rootNode();
 
     if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "effect"))
@@ -306,19 +312,22 @@ Particle *Particle::addEffect(const std::string &particleEffectFile,
         // Animation
         if ((node = XML::findFirstChildByName(effectChildNode, "animation")))
         {
-            newParticle = new AnimationParticle(mMap, node);
+            newParticle = new AnimationParticle(mMap, node, dyePalettes);
         }
         // Rotational
         else if ((node = XML::findFirstChildByName(
                  effectChildNode, "rotation")))
         {
-            newParticle = new RotationalParticle(mMap, node);
+            newParticle = new RotationalParticle(mMap, node, dyePalettes);
         }
         // Image
         else if ((node = XML::findFirstChildByName(effectChildNode, "image")))
         {
-            Image *img = resman->getImage(reinterpret_cast<const char*>(
-                node->xmlChildrenNode->content));
+            std::string imageSrc = reinterpret_cast<const char*>(
+                node->xmlChildrenNode->content);
+            if (!imageSrc.empty() && !dyePalettes.empty())
+                Dye::instantiate(imageSrc, dyePalettes);
+            Image *img = resman->getImage(imageSrc);
 
             newParticle = new ImageParticle(mMap, img);
         }
@@ -353,8 +362,8 @@ Particle *Particle::addEffect(const std::string &particleEffectFile,
             if (xmlStrEqual(emitterNode->name, BAD_CAST "emitter"))
             {
                 ParticleEmitter *newEmitter;
-                newEmitter = new ParticleEmitter(
-                    emitterNode, newParticle, mMap, rotation);
+                newEmitter = new ParticleEmitter(emitterNode, newParticle,
+                    mMap, rotation, dyePalettes);
                 newParticle->addEmitter(newEmitter);
             }
             else if (xmlStrEqual(emitterNode->name, BAD_CAST "deatheffect"))
diff --git a/src/particleemitter.cpp b/src/particleemitter.cpp
index 844da5dad..6b6cca44b 100644
--- a/src/particleemitter.cpp
+++ b/src/particleemitter.cpp
@@ -27,6 +27,7 @@
 #include "particleemitter.h"
 #include "rotationalparticle.h"
 
+#include "resources/dye.h"
 #include "resources/image.h"
 #include "resources/imageset.h"
 #include "resources/resourcemanager.h"
@@ -39,7 +40,8 @@
 #define DEG_RAD_FACTOR 0.017453293f
 
 ParticleEmitter::ParticleEmitter(xmlNodePtr emitterNode, Particle *target,
-                                 Map *map, int rotation):
+                                 Map *map, int rotation,
+                                 const std::string& dyePalettes):
     mOutputPauseLeft(0),
     mParticleImage(0)
 {
@@ -99,6 +101,9 @@ ParticleEmitter::ParticleEmitter(xmlNodePtr emitterNode, Particle *target,
                 // Don't leak when multiple images are defined
                 if (!image.empty() && !mParticleImage)
                 {
+                    if (!dyePalettes.empty())
+                        Dye::instantiate(image, dyePalettes);
+
                     ResourceManager *resman = ResourceManager::getInstance();
                     mParticleImage = resman->getImage(image);
                 }
@@ -194,7 +199,8 @@ ParticleEmitter::ParticleEmitter(xmlNodePtr emitterNode, Particle *target,
         }
         else if (xmlStrEqual(propertyNode->name, BAD_CAST "emitter"))
         {
-            ParticleEmitter newEmitter(propertyNode, mParticleTarget, map);
+            ParticleEmitter newEmitter(propertyNode, mParticleTarget, map,
+                                       rotation, dyePalettes);
             mParticleChildEmitters.push_back(newEmitter);
         }
         else if (xmlStrEqual(propertyNode->name, BAD_CAST "rotation"))
diff --git a/src/particleemitter.h b/src/particleemitter.h
index 5a68584c6..e82483370 100644
--- a/src/particleemitter.h
+++ b/src/particleemitter.h
@@ -43,11 +43,9 @@ class Particle;
 class ParticleEmitter
 {
     public:
-        /**
-         * Constructor.
-         */
-        ParticleEmitter(xmlNodePtr emitterNode,  Particle *target,
-                        Map *map, int rotation = 0);
+        ParticleEmitter(xmlNodePtr emitterNode,  Particle *target, Map *map,
+                        int rotation = 0,
+                        const std::string& dyePalettes = std::string());
 
         /**
          * Copy Constructor (necessary for reference counting of particle images)
diff --git a/src/rotationalparticle.cpp b/src/rotationalparticle.cpp
index 8be11ee10..cd16ddf63 100644
--- a/src/rotationalparticle.cpp
+++ b/src/rotationalparticle.cpp
@@ -34,9 +34,10 @@ RotationalParticle::RotationalParticle(Map *map, Animation *animation):
 {
 }
 
-RotationalParticle::RotationalParticle(Map *map, xmlNodePtr animationNode):
+RotationalParticle::RotationalParticle(Map *map, xmlNodePtr animationNode,
+                                       const std::string& dyePalettes):
     ImageParticle(map, 0),
-    mAnimation(new SimpleAnimation(animationNode))
+    mAnimation(new SimpleAnimation(animationNode, dyePalettes))
 {
 }
 
diff --git a/src/rotationalparticle.h b/src/rotationalparticle.h
index d7b126f76..d5b91bc63 100644
--- a/src/rotationalparticle.h
+++ b/src/rotationalparticle.h
@@ -36,7 +36,8 @@ class RotationalParticle : public ImageParticle
     public:
         RotationalParticle(Map *map, Animation *animation);
 
-        RotationalParticle(Map *map, xmlNodePtr animationNode);
+        RotationalParticle(Map *map, xmlNodePtr animationNode,
+                           const std::string& dyePalettes = std::string());
 
         ~RotationalParticle();
 
diff --git a/src/simpleanimation.cpp b/src/simpleanimation.cpp
index a952d792b..e3591f30c 100644
--- a/src/simpleanimation.cpp
+++ b/src/simpleanimation.cpp
@@ -28,6 +28,7 @@
 #include "utils/stringutils.h"
 
 #include "resources/animation.h"
+#include "resources/dye.h"
 #include "resources/image.h"
 #include "resources/imageset.h"
 #include "resources/resourcemanager.h"
@@ -43,13 +44,14 @@ SimpleAnimation::SimpleAnimation(Animation *animation):
 {
 }
 
-SimpleAnimation::SimpleAnimation(xmlNodePtr animationNode):
+SimpleAnimation::SimpleAnimation(xmlNodePtr animationNode,
+                                 const std::string& dyePalettes):
     mAnimation(new Animation),
     mAnimationTime(0),
     mAnimationPhase(0),
     mInitialized(false)
 {
-    initializeAnimation(animationNode);
+    initializeAnimation(animationNode, dyePalettes);
     if (mAnimation)
         mCurrentFrame = mAnimation->getFrame(0);
     else
@@ -134,13 +136,21 @@ Image *SimpleAnimation::getCurrentImage() const
         return NULL;
 }
 
-void SimpleAnimation::initializeAnimation(xmlNodePtr animationNode)
+void SimpleAnimation::initializeAnimation(xmlNodePtr animationNode,
+                                          const std::string& dyePalettes)
 {
     mInitialized = false;
 
     if (!animationNode)
         return;
 
+    std::string imagePath = XML::getProperty(animationNode,
+                                                   "imageset", "");
+
+    // Instanciate the dye coloration.
+    if (!imagePath.empty() && !dyePalettes.empty())
+        Dye::instantiate(imagePath, dyePalettes);
+
     ImageSet *imageset = ResourceManager::getInstance()->getImageSet(
         XML::getProperty(animationNode, "imageset", ""),
         XML::getProperty(animationNode, "width", 0),
diff --git a/src/simpleanimation.h b/src/simpleanimation.h
index 572a7704c..000bb1399 100644
--- a/src/simpleanimation.h
+++ b/src/simpleanimation.h
@@ -47,7 +47,8 @@ class SimpleAnimation
         /**
          * Creates a simple animation that creates its animation from XML Data.
          */
-        SimpleAnimation(xmlNodePtr animationNode);
+        SimpleAnimation(xmlNodePtr animationNode,
+                        const std::string& dyePalettes = std::string());
 
         ~SimpleAnimation();
 
@@ -67,7 +68,8 @@ class SimpleAnimation
         Image *getCurrentImage() const;
 
     private:
-        void initializeAnimation(xmlNodePtr animationNode);
+        void initializeAnimation(xmlNodePtr animationNode,
+                                const std::string& dyePalettes = std::string());
 
         /** The hosted animation. */
         Animation *mAnimation;
-- 
cgit v1.2.3-70-g09d2