Index: trunk/src/lib/graphics/effects/cloud_effect.cc
===================================================================
--- trunk/src/lib/graphics/effects/cloud_effect.cc	(revision 8783)
+++ trunk/src/lib/graphics/effects/cloud_effect.cc	(revision 8793)
@@ -1,16 +1,16 @@
 /*
-	orxonox - the future of 3D-vertical-scrollers
-
-	Copyright (C) 2004 orx
-
-	This program is free software; you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation; either version 2, or (at your option)
-	any later version.
-
+  orxonox - the future of 3D-vertical-scrollers
+ 
+  Copyright (C) 2004 orx
+ 
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+ 
 ### File Specific:
-	main-programmer: hdavid, amaechler
-
-	INSPIRED BY http://www.codesampler.com/usersrc/usersrc_6.htm#oglu_sky_dome_shader
+  main-programmer: hdavid, amaechler
+ 
+  INSPIRED BY http://www.codesampler.com/usersrc/usersrc_6.htm#oglu_sky_dome_shader
 */
 
@@ -22,5 +22,4 @@
 
 #include "material.h"
-#include <math.h>
 #include "state.h"
 #include "p_node.h"
@@ -30,4 +29,8 @@
 #include "parser/tinyxml/tinyxml.h"
 
+Vector  CloudEffect::cloudColor;
+Vector  CloudEffect::skyColor;
+Vector  CloudEffect::newCloudColor;
+Vector  CloudEffect::newSkyColor;
 
 using namespace std;
@@ -40,19 +43,23 @@
 CloudEffect::CloudEffect(const TiXmlElement* root)
 {
-	this->setClassID(CL_CLOUD_EFFECT, "CloudEffect");
-//  this->toList(OM_ENVIRON);
-
-	this->init();
-
-	if (root != NULL)
-		this->loadParams(root);
-
-	//if(cloudActivate)
-		this->activate();
+  this->setClassID(CL_CLOUD_EFFECT, "CloudEffect");
+
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+
+  if(cloudActivate)
+    this->activate();
 }
 
 CloudEffect::~CloudEffect()
 {
-	this->deactivate();
+  this->deactivate();
+
+  if (glIsTexture(noise3DTexName))
+    glDeleteTextures(1, &noise3DTexName);
+
+  delete shader;
 }
 
@@ -60,30 +67,54 @@
 void CloudEffect::init()
 {
-	PRINTF(0)("Initializing CloudEffect\n");
-  
-    /// initialization of the texture coords, speeds etc...
-/*  this->move = 0.0f;
-  this->g_WaterUV = 35.0f;
-  this->kNormalMapScale = 0.25f;
-  this->g_WaterFlow = 0.0015f;*/
-  
-  cloudMaterial.setDiffuseMap("pictures/sky/cloud1.jpg", GL_TEXTURE_2D, 0);
-
-  shader = new Shader(ResourceManager::getInstance()->getDataDir() + "/shaders/cloud.vert",
-                      ResourceManager::getInstance()->getDataDir() + "/shaders/cloud.frag");
-  
+  PRINTF(0)("Initializing CloudEffect\n");
+
+  this->offsetZ = 0;
+  this->animationSpeed = 2;
+  this->scale = 0.0004f;
+  this->atmosphericRadius = 4000;
+  this->planetRadius = 1500;
+  this->divs = 50;
+
+  skyColor = Vector(0.0f, 0.0f, 0.8f);
+  cloudColor = Vector(0.8f, 0.8f, 0.8f);
+  newSkyColor = skyColor;
+  newCloudColor = cloudColor;
+  this->fadeTime = 3;
+
+  this->noise3DTexSize = 128;
+  this->noise3DTexName = 0;
+
+  this->make3DNoiseTexture();
+
+  glGenTextures(1, &noise3DTexName);
+  glBindTexture(GL_TEXTURE_3D, noise3DTexName);
+
+  glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+  glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
+  glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+  glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA,
+               noise3DTexSize, noise3DTexSize, noise3DTexSize,
+               0, GL_RGBA, GL_UNSIGNED_BYTE, noise3DTexPtr);
+
+  this->skydome = new Skydome();
+  this->skydome->setTexture(noise3DTexName);
+
+  this->shader = new Shader(ResourceManager::getInstance()->getDataDir() + "/shaders/cloud.vert",
+                            ResourceManager::getInstance()->getDataDir() + "/shaders/cloud.frag");
+
   this->shader->activateShader();
 
   Shader::Uniform(shader, "Noise").set(0);
-  Shader::Uniform(shader, "SkyColor").set(0.0f, 0.0f, 0.8f);
-  Shader::Uniform(shader, "CloudColor").set(0.8f, 0.8f, 0.8f);
-  
-  // Change: Have to be updated each frame!like camerpos in mapped_water.cc
-  Shader::Uniform(shader, "Offset").set(0.0f, 0.0f, 0.0f);
-  
-  Shader::Uniform(shader, "LightPos").set(100.0f, 100.0f, 100.0f);
-  Shader::Uniform(shader, "Scale").set(1.0f);
-  
+
+  this->offset = new Shader::Uniform(shader, "Offset");
+  this->skycolor = new Shader::Uniform(shader, "SkyColor");
+  this->cloudcolor = new Shader::Uniform(shader, "CloudColor");
+
   this->shader->deactivateShader();
+
+  this->skydome->setShader(shader);
 }
 
@@ -91,14 +122,20 @@
 void CloudEffect::loadParams(const TiXmlElement* root)
 {
-	WeatherEffect::loadParams(root);
-
-	// LoadParam(root, "speed", this, CloudEffect, setCloudAnimation);
-	// LoadParam(root, "texture", this, CloudEffect, setCloudTexture);
-  /*
-	LOAD_PARAM_START_CYCLE(root, element);
-	{
-		LoadParam_CYCLE(element, "option", this, CloudEffect, setCloudOption);
-	}
-  LOAD_PARAM_END_CYCLE(element);*/
+  WeatherEffect::loadParams(root);
+
+  LoadParam(root, "speed", this, CloudEffect, setAnimationSpeed);
+  LoadParam(root, "scale", this, CloudEffect, setCloudScale);
+  LoadParam(root, "cloudcolor", this, CloudEffect, setCloudColor);
+  LoadParam(root, "skycolor", this, CloudEffect, setSkyColor);
+
+  LoadParam(root, "planetRadius", this, CloudEffect, setPlanetRadius);
+  LoadParam(root, "atmosphericRadius", this, CloudEffect, setAtmosphericRadius);
+  LoadParam(root, "divisions", this, CloudEffect, setDivisions);
+
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    LoadParam_CYCLE(element, "option", this, CloudEffect, setCloudOption);
+  }
+  LOAD_PARAM_END_CYCLE(element);
 }
 
@@ -106,53 +143,218 @@
 void CloudEffect::activate()
 {
-	PRINTF(0)( "Activating\n");
-
-//	this->cloudActivate = true;
+  PRINTF(0)( "Activating\n");
+
+  // Can only be set after the loadParams call
+  this->shader->activateShader();
+  Shader::Uniform(shader, "Scale").set(this->scale);
+  this->skycolor->set(skyColor.x, skyColor.y, skyColor.z);
+  this->cloudcolor->set(cloudColor.x, cloudColor.y, cloudColor.z);
+  this->shader->deactivateShader();
+
+  this->skydome->generateSkyPlane(this->divs, this->planetRadius, this->atmosphericRadius, 1, 1);
+
+  this->cloudActivate = true;
 }
 
 void CloudEffect::deactivate()
 {
-	PRINTF(0)("Deactivating CloudEffect\n");
-
-//	this->cloudActivate = false;
+  PRINTF(0)("Deactivating CloudEffect\n");
+
+  this->cloudActivate = false;
 }
 
 void CloudEffect::draw() const
-{
-	//if (!this->cloudActivate)
-	//	return;
-
-  //glMatrixMode(GL_MODELVIEW);
-  //glColor4f(1,1,1,1);
-  glPushMatrix();
-  //glTranslatef(0,this->waterHeight,0);
-
-  cloudMaterial.unselect();
-  cloudMaterial.select();
-
-  this->shader->activateShader();
-
-
-  glBegin(GL_QUADS);
-  
-  glTexCoord2f(1.0f, 1.0f); glVertex3f(0.0f, 0.0f,  0.0f);
-  glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.0f, 0.0f,  100.0f);
-  glTexCoord2f(0.0f, 0.0f); glVertex3f( 100.0f, 0.0f,  100.0f);
-  glTexCoord2f(1.0f, 0.0f); glVertex3f(100.0f, 0.0f,  0.0f);
-  
-  glEnd();
-
-  this->shader->deactivateShader();
-
-  cloudMaterial.unselect();
-
-  glPopMatrix();
-
-}
+  {}
 
 void CloudEffect::tick (float dt)
 {
-	//if (!this->cloudActivate)
-	//	return;
-}
-
+  if (this->cloudActivate)
+  {
+    this->offsetZ += 0.05 * dt * this->animationSpeed;
+
+    this->shader->activateShader();
+    this->offset->set(0.0f, 0.0f, offsetZ);
+    
+    //if(cloudColor != newCloudColor)
+    //{
+      // TODO: fade from cloudColor to newCloudColor
+      cloudColor = newCloudColor;
+      this->cloudcolor->set(this->cloudColor.x, this->cloudColor.y, this->cloudColor.z);
+    //}
+    //if(cloudColor != newCloudColor)
+    //{
+      // TODO: fade from skyColor to newSkyColor
+      skyColor = newSkyColor;
+      this->skycolor->set(this->skyColor.x, this->skyColor.y, this->skyColor.z);
+    //}
+    
+    this->shader->deactivateShader();
+  }
+}
+
+
+void CloudEffect::changeSkyColor(Vector color)
+{
+  newSkyColor = color;
+}
+
+
+void CloudEffect::changeCloudColor(Vector color)
+{
+  newCloudColor = color;
+}
+
+
+void CloudEffect::make3DNoiseTexture()
+{
+  int f, i, j, k, inc;
+  int startFrequency = 4;
+  int numOctaves = 4;
+  double ni[3];
+  double inci, incj, inck;
+  int frequency = startFrequency;
+  GLubyte *ptr;
+  double amp = 0.5;
+
+  if ((noise3DTexPtr = (GLubyte *) malloc(noise3DTexSize *
+                                          noise3DTexSize *
+                                          noise3DTexSize * 4)) == NULL)
+    PRINTF(0)("ERROR: Could not allocate 3D noise texture\n");
+
+  for (f=0, inc=0; f < numOctaves;
+       ++f, frequency *= 2, ++inc, amp *= 0.5)
+  {
+    SetNoiseFrequency(frequency);
+    ptr = noise3DTexPtr;
+    ni[0] = ni[1] = ni[2] = 0;
+
+    inci = 1.0 / (noise3DTexSize / frequency);
+    for (i=0; i<noise3DTexSize; ++i, ni[0] += inci)
+    {
+      incj = 1.0 / (noise3DTexSize / frequency);
+      for (j=0; j<noise3DTexSize; ++j, ni[1] += incj)
+      {
+        inck = 1.0 / (noise3DTexSize / frequency);
+        for (k=0; k<noise3DTexSize; ++k, ni[2] += inck, ptr+= 4)
+        {
+          *(ptr+inc) = (GLubyte) (((noise3(ni)+1.0) * amp)*128.0);
+        }
+      }
+    }
+  }
+}
+
+void CloudEffect::initNoise()
+{
+  int i, j, k;
+
+  srand(30757);
+  for (i = 0 ; i < B ; i++)
+  {
+    p[i] = i;
+    g1[i] = (double)((rand() % (B + B)) - B) / B;
+
+    for (j = 0 ; j < 2 ; j++)
+      g2[i][j] = (double)((rand() % (B + B)) - B) / B;
+    normalize2(g2[i]);
+
+    for (j = 0 ; j < 3 ; j++)
+      g3[i][j] = (double)((rand() % (B + B)) - B) / B;
+    normalize3(g3[i]);
+  }
+
+  while (--i)
+  {
+    k = p[i];
+    p[i] = p[j = rand() % B];
+    p[j] = k;
+  }
+
+  for (i = 0 ; i < B + 2 ; i++)
+  {
+    p[B + i] = p[i];
+    g1[B + i] = g1[i];
+    for (j = 0 ; j < 2 ; j++)
+      g2[B + i][j] = g2[i][j];
+    for (j = 0 ; j < 3 ; j++)
+      g3[B + i][j] = g3[i][j];
+  }
+}
+
+void CloudEffect::SetNoiseFrequency( int frequency)
+{
+  start = 1;
+  B = frequency;
+  BM = B-1;
+}
+
+double CloudEffect::noise3( double vec[3])
+{
+  int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
+  double rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
+  int i, j;
+
+  if (start)
+  {
+    start = 0;
+    initNoise();
+  }
+
+  setup(0, bx0,bx1, rx0,rx1);
+  setup(1, by0,by1, ry0,ry1);
+  setup(2, bz0,bz1, rz0,rz1);
+
+  i = p[ bx0 ];
+  j = p[ bx1 ];
+
+  b00 = p[ i + by0 ];
+  b10 = p[ j + by0 ];
+  b01 = p[ i + by1 ];
+  b11 = p[ j + by1 ];
+
+  t  = s_curve(rx0);
+  sy = s_curve(ry0);
+  sz = s_curve(rz0);
+
+  q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
+  q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
+  a = lerp(t, u, v);
+
+  q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
+  q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
+  b = lerp(t, u, v);
+
+  c = lerp(sy, a, b);
+
+  q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
+  q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
+  a = lerp(t, u, v);
+
+  q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
+  q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
+  b = lerp(t, u, v);
+
+  d = lerp(sy, a, b);
+
+  return lerp(sz, c, d);
+}
+
+void CloudEffect::normalize2( double v[2])
+{
+  double s;
+
+  s = sqrt(v[0] * v[0] + v[1] * v[1]);
+  v[0] = v[0] / s;
+  v[1] = v[1] / s;
+}
+
+void CloudEffect::normalize3( double v[3])
+{
+  double s;
+
+  s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+  v[0] = v[0] / s;
+  v[1] = v[1] / s;
+  v[2] = v[2] / s;
+}
+
Index: trunk/src/lib/graphics/effects/cloud_effect.h
===================================================================
--- trunk/src/lib/graphics/effects/cloud_effect.h	(revision 8783)
+++ trunk/src/lib/graphics/effects/cloud_effect.h	(revision 8793)
@@ -1,4 +1,5 @@
 /**
-* @file cloud_effect.h
+ * @file cloud_effect.h
+ * Creates clouds
 */
 
@@ -11,43 +12,125 @@
 #include "sound_source.h"
 
-#include "world_entity.h"
+#include "skydome.h"
 #include "material.h"
 #include "shader.h"
 
-class CloudEffect : public WeatherEffect {
-public:
-    CloudEffect(const TiXmlElement* root = NULL);
-    virtual ~CloudEffect();
+#define MAXB 0x100
+#define N 0x1000
+#define NP 12   /* 2^N */
+#define NM 0xfff
 
-    virtual void loadParams(const TiXmlElement* root);
-
-    virtual void init();
-
-    virtual void activate();
-    virtual void deactivate();
-
-    inline void activateCloud() {
-        this->activate();
-    }
-    inline void deactivateCloud() {
-        this->deactivate();
-    }
-
-    virtual void draw() const;
-    virtual void tick(float dt);
-
-    /*inline void setCloudOption(const std::string& option) {
-        if (option == "activate")
-    this->cloudActivate = true;
-}*/
+#define s_curve(t) ( t * t * (3. - 2. * t) )
+#define lerp(t, a, b) ( a + t * (b - a) )
+#define setup(i,b0,b1,r0,r1)\
+        t = vec[i] + N;\
+        b0 = ((int)t) & BM;\
+        b1 = (b0+1) & BM;\
+        r0 = t - (int)t;\
+        r1 = r0 - 1.;
+#define at2(rx,ry) ( rx * q[0] + ry * q[1] )
+#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
 
 
+class CloudEffect : public WeatherEffect
+{
+public:
+  CloudEffect(const TiXmlElement* root = NULL);
+  virtual ~CloudEffect();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual void init();
+
+  virtual void activate();
+  virtual void deactivate();
+
+  inline void activateCloud()
+  { this->activate(); }
+
+  inline void deactivateCloud()
+  { this->deactivate(); }
+
+  inline void setCloudOption(const std::string& option)
+  {
+    if (option == "activate")
+      this->cloudActivate = true;
+  }
+
+  inline void setAnimationSpeed(float speed)
+{ this->animationSpeed = speed; }
+
+  inline void setCloudScale(float scale)
+  { this->scale = scale; }
+
+  inline void setCloudColor(float colorX, float colorY, float colorZ)
+  { this->cloudColor = Vector(colorX, colorY, colorZ); }
+
+  inline void setSkyColor(float colorX, float colorY, float colorZ)
+  { this->skyColor = Vector(colorX, colorY, colorZ); }
+
+  inline void setPlanetRadius(float planetRadius)
+  { this->planetRadius = planetRadius; }
+
+  inline void setAtmosphericRadius(float atmosphericRadius)
+  { this->atmosphericRadius = atmosphericRadius; }
+
+  inline void setDivisions(int divs)
+  { this->divs = divs; }
+
+  virtual void draw() const;
+  virtual void tick(float dt);
+
+  static void changeSkyColor(Vector color);
+  static void changeCloudColor(Vector color);
+  
+  static Vector    cloudColor;
+  static Vector    skyColor;
+
+  void make3DNoiseTexture();
+  void initNoise();
+  void SetNoiseFrequency(int frequency);
+  double noise3(double vec[3]);
+  void normalize2(double v[2]);
+  void normalize3(double v[3]);
+
+  void generateSkyPlane(int divisions, float planetRadius, float atmosphereRadius,
+                        float hTile, float vTile);
 private:
-    //void initialize(char* fileName);
 
-    //bool        cloudActivate;
+  bool             cloudActivate;
+  float            animationSpeed;
+  float            fadeTime;
+  
+  static Vector           newSkyColor;
+  static Vector           newCloudColor;
 
-    Material                 cloudMaterial;
-    Shader*                 shader;
+  // Material                 cloudMaterial;
+  Skydome*         skydome;
+
+  // SHADER STUFF
+  Shader*          shader;
+  Shader::Uniform* offset;
+  Shader::Uniform* skycolor;
+  Shader::Uniform* cloudcolor;
+  float            offsetZ;
+  float            scale;
+  float            planetRadius;
+  float            atmosphericRadius;
+  int              divs;
+
+  // NOISE STUFF
+  int              noise3DTexSize;
+  GLuint           noise3DTexName;
+  GLubyte          *noise3DTexPtr;
+
+  int              p[MAXB + MAXB + 2];
+  double           g3[MAXB + MAXB + 2][3];
+  double           g2[MAXB + MAXB + 2][2];
+  double           g1[MAXB + MAXB + 2];
+
+  int              start;
+  int              B;
+  int              BM;
 };
 
Index: trunk/src/lib/graphics/effects/fog_effect.cc
===================================================================
--- trunk/src/lib/graphics/effects/fog_effect.cc	(revision 8783)
+++ trunk/src/lib/graphics/effects/fog_effect.cc	(revision 8793)
@@ -20,4 +20,5 @@
 #include "shell_command.h"
 
+// Define shell commands
 SHELL_COMMAND(activate, FogEffect, activateFog);
 SHELL_COMMAND(deactivate, FogEffect, deactivateFog);
@@ -25,70 +26,84 @@
 SHELL_COMMAND(fadeout, FogEffect, fadeOutFog);
 
-// TODO: Fix fades
-
 using namespace std;
 
 CREATE_FACTORY(FogEffect, CL_FOG_EFFECT);
 
+/**
+ * @brief standard constructor
+ */
 FogEffect::FogEffect(const TiXmlElement* root) {
     this->setClassID(CL_FOG_EFFECT, "FogEffect");
 
+    // Initialize values
     this->init();
 
+    // Load XML params
     if (root != NULL)
         this->loadParams(root);
 
+    // Activate fog, if chosen to be activated by default
     if (this->fogActivate)
         this->activate();
 }
 
-
+/**
+ * @brief standard destructor
+ */
 FogEffect::~FogEffect() {
     this->deactivate();
 }
 
-
+/**
+ * @brief initalizes the fog effect with default values
+ */
+void FogEffect::init() {
+    // default values
+  this->fogMode = GL_LINEAR;
+  this->fogDensity = 0.005;
+  this->fogStart = 0;
+  this->fogEnd = 300;
+  this->colorVector = Vector(0.6, 0.0, 0.0);
+
+    // init variables
+  this->fogFadeInDuration = 0;
+  this->fogFadeOutDuration = 0;
+  this->fogFadeDensity = 0;
+  this->fogFadeEnd = 0;
+
+  this->localTimer = 0;
+  this->fogActivate = false;
+  this->fogFadeInActivate = false;
+  this->fogFadeOutActivate = false;
+}
+
+/**
+ * @brief loads the fog effect parameters.
+ * @param root: the XML-Element to load the data from
+ */
 void FogEffect::loadParams(const TiXmlElement* root) {
     WeatherEffect::loadParams(root);
 
-    LoadParam(root, "mode", this, FogEffect, setFogMode);
-    LoadParam(root, "density", this, FogEffect, setFogDensity);
-    LoadParam(root, "range", this, FogEffect, setFogRange);
-    LoadParam(root, "color", this, FogEffect, setFogColor);
-    LoadParam(root, "fadeinduration", this, FogEffect, setFogFadeIn);
-    LoadParam(root, "fadeoutduration", this, FogEffect, setFogFadeOut);
+    LoadParam(root, "mode", this, FogEffect, setFogMode).describe("fog mode (linear, exponential)");;
+    LoadParam(root, "density", this, FogEffect, setFogDensity).describe("fog density if exp. fog");;
+    LoadParam(root, "range", this, FogEffect, setFogRange).describe("fog range: start, end");;
+    LoadParam(root, "color", this, FogEffect, setFogColor).describe("fog color: r,g,b");;
+    LoadParam(root, "fadeinduration", this, FogEffect, setFogFadeIn).describe("duration of the fade in");;
+    LoadParam(root, "fadeoutduration", this, FogEffect, setFogFadeOut).describe("duration of the fade out");;
 
     LOAD_PARAM_START_CYCLE(root, element);
     {
-        LoadParam_CYCLE(element, "option", this, FogEffect, setFogOption);
+      LoadParam_CYCLE(element, "option", this, FogEffect, setFogOption).describe("sets a fog option: activate");;
     }
     LOAD_PARAM_END_CYCLE(element);
 }
 
-void FogEffect::init() {
-    // default values
-    this->fogMode = GL_LINEAR;
-    this->fogDensity = 0.03;
-    this->fogStart = 0;
-    this->fogEnd = 50;
-    this->colorVector = Vector(0.3, 0.3, 0.3);
-
-    // init variables
-    this->fogFadeInDuration = 0;
-    this->fogFadeOutDuration = 0;
-    this->fogFadeDensity = 0;
-    this->localTimer = 0;
-    this->fogActivate = false;
-    this->fogFadeInActivate = false;
-    this->fogFadeOutActivate = false;
-
-}
-
-
+/**
+ * @brief activates the fog effect
+ */
 void FogEffect::activate() {
-    PRINTF(0)( "Enabling FogEffect, mode: %i, density: %f, start: %f, end: %f, color %f, %f, %f\n", this->fogMode, this->fogDensity, this->fogStart, this->fogEnd, this->colorVector.x, this->colorVector.y, this->colorVector.z);
-
-    this->fogActivate = true;
-
+    PRINTF(0)( "Activating FogEffect\n");
+
+    // init fogGL
     GLfloat fogColor[4] = { colorVector.x, colorVector.y, colorVector.z, 1.0};
     glFogi(GL_FOG_MODE, this->fogMode);
@@ -99,9 +114,12 @@
     glFogf(GL_FOG_END, this->fogEnd);
 
+    this->fogActivate = true;
+
     glEnable(GL_FOG);
-
-}
-
-
+}
+
+/**
+ * @brief deactivates the fog effect
+ */
 void FogEffect::deactivate() {
     PRINTF(0)("Deactivating FogEffect\n");
@@ -112,7 +130,9 @@
 
     glDisable(GL_FOG);
-
-}
-
+}
+
+/**
+ * @brief draws the fog effect
+ */
 void FogEffect::draw() const {
 
@@ -120,25 +140,43 @@
         return;
 
-    // If Fog Fade
-    if ( this->fogFadeInActivate || this->fogFadeOutActivate )
-        glFogf(GL_FOG_DENSITY, this->fogFadeDensity);
-
-}
-
+    // If fog is fading
+    if ( this->fogFadeInActivate || this->fogFadeOutActivate ) {
+        if ( this->fogMode == GL_LINEAR)
+            glFogf(GL_FOG_END, this->fogFadeEnd);
+        else
+            glFogf(GL_FOG_DENSITY, this->fogFadeDensity);
+    }
+}
+
+/**
+ * @brief ticks the fog effect
+ * @param dt: tick float
+ */
 void FogEffect::tick(float dt) {
+
     if (!this->fogActivate)
         return;
 
+    // If fog is fading in
     if ( this->fogFadeInActivate ) {
         this->localTimer += dt;
-        this->fogFadeDensity = ( this->localTimer / this->fogFadeInDuration ) * this->fogDensity;
-
-        if ( this->localTimer >= this->fogFadeOutDuration )
+
+        if ( this->fogMode == GL_LINEAR)
+          this->fogFadeEnd = 2000 * (1 - ( this->localTimer / this->fogFadeInDuration )) + this->fogEnd;
+        else
+            this->fogFadeDensity = ( this->localTimer / this->fogFadeInDuration ) * this->fogDensity;
+
+        if ( this->localTimer >= this->fogFadeInDuration )
             this->fogFadeInActivate = false;
     }
 
+    // If fog is fading out
     if ( this->fogFadeOutActivate ) {
         this->localTimer += dt;
-        this->fogFadeDensity = 1 - (( this->localTimer / this->fogFadeInDuration ) * this->fogDensity);
+
+        if ( this->fogMode == GL_LINEAR)
+          this->fogFadeEnd = 2000 * ( this->localTimer / this->fogFadeInDuration ) + this->fogEnd;
+        else
+            this->fogFadeDensity = 1 - (( this->localTimer / this->fogFadeInDuration ) * this->fogDensity);
 
         if ( this->localTimer >= this->fogFadeOutDuration )
@@ -147,4 +185,7 @@
 }
 
+/**
+ * @brief fades the fog in
+ */
 void FogEffect::fadeInFog() {
 
@@ -163,13 +204,14 @@
     this->localTimer = 0;
 
+    // Activate Fog
+    this->activate();
+
     // set FogFadeIn activate
     this->fogFadeInActivate = true;
-
-    // Activate Fog
-    this->activate();
-
-}
-
-
+}
+
+/**
+ * @brief fades the fog out
+ */
 void FogEffect::fadeOutFog() {
 
@@ -190,18 +232,4 @@
     // Reset local timer
     this->localTimer = 0;
-
-}
-
-
-GLint FogEffect::stringToFogMode(const std::string& mode) {
-    if(mode == "GL_LINEAR")
-        return GL_LINEAR;
-    else if(mode == "GL_EXP")
-        return GL_EXP;
-    else if(mode == "GL_EXP2" )
-        return GL_EXP2;
-    else
-        return -1;
-}
-
-
+}
+
Index: trunk/src/lib/graphics/effects/fog_effect.h
===================================================================
--- trunk/src/lib/graphics/effects/fog_effect.h	(revision 8783)
+++ trunk/src/lib/graphics/effects/fog_effect.h	(revision 8793)
@@ -1,4 +1,5 @@
 /**
-* @file fog_effect.h
+ * @file fog_effect.h
+ * Generates simple openGL fog
 */
 
@@ -6,82 +7,107 @@
 #define _FOG_EFFECT
 
-
 #include "weather_effect.h"
 #include "glincl.h"
 #include "vector.h"
 
-class FogEffect : public WeatherEffect {
+class FogEffect : public WeatherEffect
+{
 public:
-    FogEffect(const TiXmlElement* root = NULL);
-    virtual ~FogEffect();
+  FogEffect(const TiXmlElement* root = NULL);
+  virtual ~FogEffect();
 
-    virtual void loadParams(const TiXmlElement* root);
+  virtual void loadParams(const TiXmlElement* root);
 
-    virtual void init();
+  virtual void init();
 
-    virtual void activate();
-    virtual void deactivate();
+  virtual void activate();
+  virtual void deactivate();
 
-    void activateFog() {
-        this->activate();
-    }
-    void deactivateFog() {
-        this->deactivate();
-    }
+  void activateFog()
+  {
+    this->activate();
+  }
 
-    virtual void draw() const;
-    virtual void tick(float dt);
+  void deactivateFog()
+  {
+    this->deactivate();
+  }
 
-    inline void setFogMode(const std::string& mode) {
-        this->fogMode = this->stringToFogMode(mode);
-    }
-    inline void setFogDensity(float density) {
-        this->fogDensity = density;
-    }
-    inline void setFogRange(float start, float end) {
-        this->fogStart = start;
-        this->fogEnd = end;
-    }
-    inline void setFogColor(float r, float g, float b) {
-        this->colorVector = Vector(r, g, b);
-    }
-    inline void setFogFadeIn(float fadein) {
-        this->fogFadeInDuration = fadein;
-    }
-    inline void setFogFadeOut(float fadeout) {
-        this->fogFadeOutDuration = fadeout;
-    }
+  virtual void draw() const;
+  virtual void tick(float dt);
 
-    inline void setFogOption(const std::string& option) {
-        if (option == "activate")
-            this->fogActivate = true;
-    }
+  inline void setFogMode(const std::string& mode)
+  {
+    this->fogMode = this->stringToFogMode(mode);
+  }
 
-    void fadeInFog();
-    void fadeOutFog();
+  inline void setFogDensity(float density)
+  {
+    this->fogDensity = density;
+  }
+
+  inline void setFogRange(float start, float end)
+  {
+    this->fogStart = start;
+    this->fogEnd = end;
+  }
+
+  inline void setFogColor(float r, float g, float b)
+  {
+    this->colorVector = Vector(r, g, b);
+  }
+
+  inline void setFogFadeIn(float fadein)
+  {
+    this->fogFadeInDuration = fadein;
+  }
+
+  inline void setFogFadeOut(float fadeout)
+  {
+    this->fogFadeOutDuration = fadeout;
+  }
+
+  inline void setFogOption(const std::string& option)
+  {
+    if (option == "activate")
+      this->fogActivate = true;
+  }
+
+  void fadeInFog();
+  void fadeOutFog();
 
 
 private:
-    GLint stringToFogMode(const std::string& mode);
+  inline GLint stringToFogMode(const std::string& mode)
+  {
+    if(mode == "GL_LINEAR")
+      return GL_LINEAR;
+    else if(mode == "GL_EXP")
+      return GL_EXP;
+    else if(mode == "GL_EXP2" )
+      return GL_EXP2;
+    else
+      return -1;
+  }
 
-    bool          fogActivate;
+  bool          fogActivate;
 
-    bool          fogFadeInActivate;
-    bool          fogFadeOutActivate;
+  bool          fogFadeInActivate;
+  bool          fogFadeOutActivate;
 
-    GLfloat       fogFadeInDuration;
-    GLfloat       fogFadeOutDuration;
+  GLfloat       fogFadeInDuration;
+  GLfloat       fogFadeOutDuration;
 
-    float         localTimer;
+  GLint         fogMode;
+  GLfloat       fogDensity;
+  GLfloat       fogFadeDensity;
 
-    GLint         fogMode;
-    GLfloat       fogDensity;
-    GLfloat       fogFadeDensity;
+  GLfloat       fogStart;
+  GLfloat       fogEnd;
+  GLfloat       fogFadeEnd;
 
-    GLfloat       fogStart;
-    GLfloat       fogEnd;
-    Vector        colorVector;
+  Vector        colorVector;
+  float         localTimer; 
 };
 
-
 #endif  /* _FOG_EFFECT */
Index: trunk/src/lib/graphics/effects/lightening_effect.cc
===================================================================
--- trunk/src/lib/graphics/effects/lightening_effect.cc	(revision 8783)
+++ trunk/src/lib/graphics/effects/lightening_effect.cc	(revision 8793)
@@ -16,6 +16,9 @@
 
 #include "state.h"
+
 #include "util/loading/load_param.h"
 #include "util/loading/factory.h"
+#include "util/loading/resource_manager.h"
+
 #include "effects/billboard.h"
 
@@ -33,40 +36,38 @@
 CREATE_FACTORY(LighteningEffect, CL_LIGHTENING_EFFECT);
 
-// TODO: FIx Lightening with Fog enabled
-
 LighteningEffect::LighteningEffect(const TiXmlElement* root)
 {
-	this->setClassID(CL_LIGHTENING_EFFECT, "LighteningEffect");
-
-	this->init();
-
-	if (root != NULL)
-		this->loadParams(root);
-
-	if(this->lighteningActivate)
-		this->activate();
+  this->setClassID(CL_LIGHTENING_EFFECT, "LighteningEffect");
+
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+
+  if(this->lighteningActivate)
+    this->activate();
 }
 
 LighteningEffect::~LighteningEffect()
 {
-	this->deactivate();
+  this->deactivate();
 }
 
 void LighteningEffect::loadParams(const TiXmlElement* root)
 {
-	WeatherEffect::loadParams(root);
-
-	LoadParam(root, "coord", this, LighteningEffect, coord);
-	LoadParam(root, "frequency", this, LighteningEffect, setFlashFrequency);
-	LoadParam(root, "const-time", this, LighteningEffect, setFlashConstTime);
-	LoadParam(root, "rising-time", this, LighteningEffect, setFlashRisingTime);
-	LoadParam(root, "size", this, LighteningEffect, setFlashSize);
-	LoadParam(root, "seed", this, LighteningEffect, setFlashSeed);
-
-	LOAD_PARAM_START_CYCLE(root, element);
-	{
-		LoadParam_CYCLE(element, "option", this, LighteningEffect, setLighteningOption);
-	}
-	LOAD_PARAM_END_CYCLE(element);
+  WeatherEffect::loadParams(root);
+
+  LoadParam(root, "coord", this, LighteningEffect, coord);
+  LoadParam(root, "frequency", this, LighteningEffect, setFlashFrequency);
+  LoadParam(root, "const-time", this, LighteningEffect, setFlashConstTime);
+  LoadParam(root, "rising-time", this, LighteningEffect, setFlashRisingTime);
+  LoadParam(root, "size", this, LighteningEffect, setFlashSize);
+  LoadParam(root, "seed", this, LighteningEffect, setFlashSeed);
+
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    LoadParam_CYCLE(element, "option", this, LighteningEffect, setLighteningOption);
+  }
+  LOAD_PARAM_END_CYCLE(element);
 }
 
@@ -74,76 +75,75 @@
 void LighteningEffect::init()
 {
-	//default values
-	this->lighteningActivate = false;
-
-	this->time = 0.0;
-	this->flashFrequency = 4.0f;
-	this->mainFrequency = 4.0f;
-	this->flashConstTime = 0.1f;
-	this->flashRisingTime = 0.03f;
-
-	this->width = 700.0f;
-	this->height = 250.0f;
-	this->seedWidth = 50.0f;
-	this->seedHeight = 50.0f;
-	this->bNewCoordinate = false;
+  //default values
+  this->lighteningActivate = false;
+
+  this->flashFrequency = 4.0f;
+  this->flashFrequencyBase = 4.0f;
+  this->flashFrequencySeed = 2.0f;
+
+  this->flashHoldTime = 0.1f;
+  this->flashRisingTime = 0.03f;
+
+  this->seedX = 500.f;
+  this->seedZ = 1000.0f;
+
+  this->width = 700.0f;
+  this->height = 250.0f;
+  this->seedWidth = 50.0f;
+  this->seedHeight = 50.0f;
+
   this->lighteningMove = false;
 
-	this->seedX = 500.f;
-	this->seedZ = 1000.0f;
-	this->seedTime = 2.0f;
-
-  this->mainPosX = 3000;
+  this->mainPosX = 1200;
   this->mainPosY = 900;
   this->mainPosZ = 0;
 
-	// initialize lightening textures
-	this->billboard[0] = new Billboard(NULL);
-	this->billboard[0]->setTexture("maps/lightning_bolt1.png");
-	this->billboard[0]->setSize(this->width, this->height);
-	this->billboard[0]->setVisibiliy(false);
-
-	this->billboard[1] = new Billboard(NULL);
-	this->billboard[1]->setTexture("maps/lightning_bolt2.png");
-	this->billboard[1]->setSize(this->width, this->height);
-	this->billboard[1]->setVisibiliy(false);
-
-	this->billboard[2] = new Billboard(NULL);
-	this->billboard[2]->setTexture("maps/lightning_bolt3.png");
-	this->billboard[2]->setSize(this->width, this->height);
-	this->billboard[2]->setVisibiliy(false);
-
-	this->billboard[3] = new Billboard(NULL);
-	this->billboard[3]->setTexture("maps/lightning_bolt4.png");
-	this->billboard[3]->setSize(this->width, this->height);
-	this->billboard[3]->setVisibiliy(false);
-
-	if (this->lighteningMove) {
-		this->cameraCoor = State::getCameraNode()->getAbsCoor();
-		this->billboard[0]->setAbsCoor(this->cameraCoor.x+3000,900,this->cameraCoor.z+0);
-		this->billboard[1]->setAbsCoor(this->cameraCoor.x+3000,900,this->cameraCoor.z+0);
-		this->billboard[2]->setAbsCoor(this->cameraCoor.x+3000,900,this->cameraCoor.z+0);
-		this->billboard[3]->setAbsCoor(this->cameraCoor.x+3000,900,this->cameraCoor.z+0);
-	} else {
-		this->billboard[0]->setAbsCoor(3000,900,0);
-		this->billboard[1]->setAbsCoor(3000,900,0);
-		this->billboard[2]->setAbsCoor(3000,900,0);
-		this->billboard[3]->setAbsCoor(3000,900,0);
-	}
-
-	this->flashLight = new Light();
-	this->flashLight->setDiffuseColor(0,0,0);
-	this->flashLight->setSpecularColor(0,0,0);
-
-	/*
-	this->soundSource = NULL;
-	this->thunderBuffer = NULL;
-
-	this->soundSource.setSourceNode(this);
-
-	//load sound
-	if (this->thunderBuffer != NULL)
-	ResourceManager::getInstance()->unload(this->thunderBuffer);
-	this->thunderBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/thunder.wav", WAV);*/
+  this->time = 0.0;
+
+  // initialize lightening textures
+  this->billboard[0] = new Billboard(NULL);
+  this->billboard[0]->setTexture("maps/lightning_bolt1.png");
+  this->billboard[0]->setSize(this->width, this->height);
+  this->billboard[0]->setVisibiliy(false);
+
+  this->billboard[1] = new Billboard(NULL);
+  this->billboard[1]->setTexture("maps/lightning_bolt2.png");
+  this->billboard[1]->setSize(this->width, this->height);
+  this->billboard[1]->setVisibiliy(false);
+
+  this->billboard[2] = new Billboard(NULL);
+  this->billboard[2]->setTexture("maps/lightning_bolt3.png");
+  this->billboard[2]->setSize(this->width, this->height);
+  this->billboard[2]->setVisibiliy(false);
+
+  this->billboard[3] = new Billboard(NULL);
+  this->billboard[3]->setTexture("maps/lightning_bolt4.png");
+  this->billboard[3]->setSize(this->width, this->height);
+  this->billboard[3]->setVisibiliy(false);
+
+  if (this->lighteningMove)
+  {
+    this->cameraCoor = State::getCameraNode()->getAbsCoor();
+    this->billboard[0]->setAbsCoor(this->cameraCoor.x+1200,900,this->cameraCoor.z+0);
+    this->billboard[1]->setAbsCoor(this->cameraCoor.x+1200,900,this->cameraCoor.z+0);
+    this->billboard[2]->setAbsCoor(this->cameraCoor.x+1200,900,this->cameraCoor.z+0);
+    this->billboard[3]->setAbsCoor(this->cameraCoor.x+1200,900,this->cameraCoor.z+0);
+  }
+  else
+  {
+    this->billboard[0]->setAbsCoor(1200,900,0);
+    this->billboard[1]->setAbsCoor(1200,900,0);
+    this->billboard[2]->setAbsCoor(1200,900,0);
+    this->billboard[3]->setAbsCoor(1200,900,0);
+  }
+
+  this->flashLight = new Light();
+  this->flashLight->setDiffuseColor(0,0,0);
+  this->flashLight->setSpecularColor(0,0,0);
+
+  //load sound
+  if (this->thunderBuffer != NULL)
+    ResourceManager::getInstance()->unload(this->thunderBuffer);
+  this->thunderBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/atmosphere/thunder.wav", WAV);
 
 }
@@ -151,20 +151,23 @@
 void LighteningEffect::coord(float x, float y, float z)
 {
-	if (this->lighteningMove) {
-		this->cameraCoor = State::getCameraNode()->getAbsCoor();
-		this->billboard[0]->setAbsCoor(this->cameraCoor.x+x, y, this->cameraCoor.z+z);
-		this->billboard[1]->setAbsCoor(this->cameraCoor.x+x, y, this->cameraCoor.z+z);
-		this->billboard[2]->setAbsCoor(this->cameraCoor.x+x, y, this->cameraCoor.z+z);
-		this->billboard[3]->setAbsCoor(this->cameraCoor.x+x, y, this->cameraCoor.z+z);
-	} else {
-		this->billboard[0]->setAbsCoor(x, y, z);
-		this->billboard[1]->setAbsCoor(x, y, z);
-		this->billboard[2]->setAbsCoor(x, y, z);
-		this->billboard[3]->setAbsCoor(x, y, z);
-	}
-
-	this->mainPosX = x;
-	this->mainPosY = y;
-	this->mainPosZ = z;
+  if (this->lighteningMove)
+  {
+    this->cameraCoor = State::getCameraNode()->getAbsCoor();
+    this->billboard[0]->setAbsCoor(this->cameraCoor.x+x, y, this->cameraCoor.z+z);
+    this->billboard[1]->setAbsCoor(this->cameraCoor.x+x, y, this->cameraCoor.z+z);
+    this->billboard[2]->setAbsCoor(this->cameraCoor.x+x, y, this->cameraCoor.z+z);
+    this->billboard[3]->setAbsCoor(this->cameraCoor.x+x, y, this->cameraCoor.z+z);
+  }
+  else
+  {
+    this->billboard[0]->setAbsCoor(x, y, z);
+    this->billboard[1]->setAbsCoor(x, y, z);
+    this->billboard[2]->setAbsCoor(x, y, z);
+    this->billboard[3]->setAbsCoor(x, y, z);
+  }
+
+  this->mainPosX = x;
+  this->mainPosY = y;
+  this->mainPosZ = z;
 }
 
@@ -172,13 +175,13 @@
 void LighteningEffect::setFlashSize(float width, float height, float seedWidth, float seedHeight)
 {
-	this->width = width;
-	this->height = height;
-	this->seedWidth = seedWidth;
-	this->seedHeight = seedHeight;
-
-	this->billboard[0]->setSize(this->width, this->height);
-	this->billboard[1]->setSize(this->width, this->height);
-	this->billboard[2]->setSize(this->width, this->height);
-	this->billboard[3]->setSize(this->width, this->height);
+  this->width = width;
+  this->height = height;
+  this->seedWidth = seedWidth;
+  this->seedHeight = seedHeight;
+
+  this->billboard[0]->setSize(this->width, this->height);
+  this->billboard[1]->setSize(this->width, this->height);
+  this->billboard[2]->setSize(this->width, this->height);
+  this->billboard[3]->setSize(this->width, this->height);
 }
 
@@ -186,8 +189,8 @@
 void LighteningEffect::activate()
 {
-	PRINTF(0)( "Activating LighteningEffect\n" );
-	this->lighteningActivate = true;
-
-	this->time = 0;
+  PRINTF(0)( "Activating LighteningEffect\n" );
+  this->lighteningActivate = true;
+
+  this->time = 0;
 }
 
@@ -195,104 +198,105 @@
 void LighteningEffect::deactivate()
 {
-	PRINTF(0)("Deactivating LighteningEffect\n");
-	this->lighteningActivate = false;
-
-	this->billboard[0]->setVisibiliy(false);
-	this->billboard[1]->setVisibiliy(false);
-	this->billboard[2]->setVisibiliy(false);
-	this->billboard[3]->setVisibiliy(false);
+  PRINTF(0)("Deactivating LighteningEffect\n");
+  this->lighteningActivate = false;
+
+  this->billboard[0]->setVisibiliy(false);
+  this->billboard[1]->setVisibiliy(false);
+  this->billboard[2]->setVisibiliy(false);
+  this->billboard[3]->setVisibiliy(false);
 }
 
 void LighteningEffect::tick (float dt)
 {
-	if(!lighteningActivate)
-		return;
-
-	this->time += dt;
-
-	// TODO: Make random flashing with short light dingsda:)
-
-	if( this->time > this->flashFrequency) {
-
-		this->billboard[0]->setVisibiliy(true);
-		this->time = 0.0f;
-
-		this->flashLight->setAbsCoor(this->billboard[0]->getAbsCoor().x, this->billboard[0]->getAbsCoor().y, this->billboard[0]->getAbsCoor().z);
-
-		// flash environmental lightening
-		this->flashLight->setDiffuseColor(1,1,1);
-		this->flashLight->setSpecularColor(1,1,1);
-
-		//this->soundSource.play(this->thunderBuffer);
-
-	} else if( this->billboard[3]->isVisible() && this->time > this->flashConstTime) {
-
-		this->billboard[3]->setVisibiliy(false);
-		this->time = 0.0f;
-		this->flashLight->setDiffuseColor(0,0,0);
-		this->flashLight->setSpecularColor(0,0,0);
-		this->bNewCoordinate = true;
-
-	}
-
-	if( this->billboard[2]->isVisible() && this->time > this->flashRisingTime) {
-
-		this->billboard[2]->setVisibiliy(false);
-		this->billboard[3]->setVisibiliy(true);
-		// this->flashLight->setDiffuseColor(1,1,1);
-		// this->flashLight->setSpecularColor(1,1,1);
-
-	} else if( this->billboard[1]->isVisible() && this->time > this->flashRisingTime*2/3 ) {
-
-		this->billboard[1]->setVisibiliy(false);
-		this->billboard[2]->setVisibiliy(true);
-		//this->flashLight->setDiffuseColor(0,0,0);
-		//this->flashLight->setSpecularColor(0,0,0);
-
-	} else if( this->billboard[0]->isVisible() && this->time > this->flashRisingTime*1/3 ) {
-
-		this->billboard[0]->setVisibiliy(false);
-		this->billboard[1]->setVisibiliy(true);
-		//this->flashLight->setDiffuseColor(1,1,1);
-		//this->flashLight->setSpecularColor(1,1,1);
-
-	}
-
-	if( this->bNewCoordinate) {
-		float posX, posZ;
-
-		if(this->lighteningMove) {
-
-			this->cameraCoor = State::getCameraNode()->getAbsCoor();
-			posX = this->mainPosX - this->seedX * (float)rand()/(float)RAND_MAX + this->cameraCoor.x;
-			posZ = this->mainPosZ + this->seedZ * (float)rand()/(float)RAND_MAX + this->cameraCoor.z;
-
-		} else {
-
-			posX = this->mainPosX - this->seedX * (float)rand()/(float)RAND_MAX;
-			posZ = this->mainPosZ + this->seedZ * (float)rand()/(float)RAND_MAX;
-
-		}
-
-		this->billboard[0]->setAbsCoor(posX, this->mainPosY, posZ);
-		this->billboard[1]->setAbsCoor(posX, this->mainPosY, posZ);
-		this->billboard[2]->setAbsCoor(posX, this->mainPosY, posZ);
-		this->billboard[3]->setAbsCoor(posX, this->mainPosY, posZ);
-
-		this->flashFrequency = this->mainFrequency + this->seedTime * (float)rand()/(float)RAND_MAX;
-
-		float w = this->width + this->seedWidth * (float)rand()/(float)RAND_MAX;
-		float h = this->height + this->seedHeight * (float)rand()/(float)RAND_MAX;
-
-		this->billboard[0]->setSize(w, h);
-		this->billboard[1]->setSize(w, h);
-		this->billboard[2]->setSize(w, h);
-		this->billboard[3]->setSize(w, h);
-
-		this->bNewCoordinate = false;
-	}
-}
-
-void LighteningEffect::draw() const
-{
-}
+  if(!lighteningActivate)
+    return;
+
+  this->time += dt;
+
+  float x;
+  x = (float)rand()/(float)RAND_MAX;
+
+  // TODO: Make random flashing with short light dingsda:)
+
+  if( this->time > this->flashFrequency)
+  {
+    // Reset timer
+    this->time = 0.0f;
+
+    // Move billboard to start position
+    this->flashLight->setAbsCoor(this->billboard[0]->getAbsCoor().x, this->billboard[0]->getAbsCoor().y, this->billboard[0]->getAbsCoor().z);
+
+    // Start a flash & lightening cycle
+    this->billboard[0]->setVisibiliy(true);
+
+    // Lighten up environment
+    this->flashLight->setDiffuseColor(1,1,1);
+    this->flashLight->setSpecularColor(1,1,1);
+
+    // Play thunder sound
+    this->soundSource.play(this->thunderBuffer);
+  }
+
+  if( this->billboard[0]->isVisible() && this->time > this->flashRisingTime*1/3 )
+  {
+    this->billboard[0]->setVisibiliy(false);
+    this->billboard[1]->setVisibiliy(true);
+  }
+  else if( this->billboard[1]->isVisible() && this->time > this->flashRisingTime*2/3 )
+  {
+    this->billboard[1]->setVisibiliy(false);
+    this->billboard[2]->setVisibiliy(true);
+
+  }
+  else if( this->billboard[2]->isVisible() && this->time > this->flashRisingTime)
+  {
+    this->billboard[2]->setVisibiliy(false);
+    this->billboard[3]->setVisibiliy(true);
+  }
+
+  if( this->billboard[3]->isVisible() && this->time > this->flashHoldTime)
+  {
+    this->billboard[3]->setVisibiliy(false);
+    this->time = 0.0f;
+    this->flashLight->setDiffuseColor(0,0,0);
+    this->flashLight->setSpecularColor(0,0,0);
+
+    this->newCoordinates();
+  }
+}
+
+void LighteningEffect::newCoordinates() {
+
+    float posX, posZ;
+
+    if(this->lighteningMove)
+    {
+
+      this->cameraCoor = State::getCameraNode()->getAbsCoor();
+      posX = this->mainPosX - this->seedX * (float)rand()/(float)RAND_MAX + this->cameraCoor.x;
+      posZ = this->mainPosZ + this->seedZ * (float)rand()/(float)RAND_MAX + this->cameraCoor.z;
+
+    }
+    else
+    {
+
+      posX = this->mainPosX - this->seedX * (float)rand()/(float)RAND_MAX;
+      posZ = this->mainPosZ + this->seedZ * (float)rand()/(float)RAND_MAX;
+
+    }
+
+    this->billboard[0]->setAbsCoor(posX, this->mainPosY, posZ);
+    this->billboard[1]->setAbsCoor(posX, this->mainPosY, posZ);
+    this->billboard[2]->setAbsCoor(posX, this->mainPosY, posZ);
+    this->billboard[3]->setAbsCoor(posX, this->mainPosY, posZ);
+
+    this->flashFrequency = this->flashFrequencyBase + this->flashFrequencySeed * (float)rand()/(float)RAND_MAX;
+
+    float w = this->width + this->seedWidth * (float)rand()/(float)RAND_MAX;
+    float h = this->height + this->seedHeight * (float)rand()/(float)RAND_MAX;
+
+    this->billboard[0]->setSize(w, h);
+    this->billboard[1]->setSize(w, h);
+    this->billboard[2]->setSize(w, h);
+    this->billboard[3]->setSize(w, h);
+}
Index: trunk/src/lib/graphics/effects/lightening_effect.h
===================================================================
--- trunk/src/lib/graphics/effects/lightening_effect.h	(revision 8783)
+++ trunk/src/lib/graphics/effects/lightening_effect.h	(revision 8793)
@@ -33,10 +33,9 @@
 		inline  void deactivateLightening() { this->deactivate(); }
 
-		virtual void draw() const;
 		virtual void tick(float dt);
-		
+
 		void coord(float x, float y, float z);
 		void setFlashSize(float width, float height, float seedWidth, float seedHeight);
-		
+
 		inline void setLighteningOption(const std::string& option) {
 			if (option == "activate") this->lighteningActivate = true;
@@ -44,24 +43,24 @@
 		}
 
-		inline void setFlashFrequency(float mainFrequency, float seedTime) {
-			this->mainFrequency = mainFrequency;
-			this->flashFrequency = mainFrequency;
-			this->seedTime = seedTime;
+		inline void setFlashFrequency(float baseFrequency, float seedTime) {
+			this->flashFrequencyBase = baseFrequency;
+			this->flashFrequency = baseFrequency;
+			this->flashFrequencySeed = seedTime;
 		}
-		
-		inline void setFlashConstTime(float flashConstTime) { this->flashConstTime = flashConstTime; }
+
+		inline void setFlashConstTime(float holdTime) { this->flashHoldTime = holdTime; }
 
 		inline void setFlashRisingTime(float flashRisingTime) {
-			if(flashRisingTime > this->flashConstTime)
-				this->flashRisingTime = this->flashConstTime/2;
+			if(flashRisingTime > this->flashHoldTime)
+				this->flashRisingTime = this->flashHoldTime * 0.5;
 			else
 				this->flashRisingTime = flashRisingTime;
 		}
-		
+
 		inline void setFlashSeed(float seedX, float seedZ) {
 			this->seedX = seedX;
 			this->seedZ = seedZ;
 		}
-		
+
 
 	private:
@@ -69,32 +68,33 @@
 		bool lighteningActivate;
 		bool lighteningMove;
-		
+
 		float flashFrequency;
-		float mainFrequency;
-		float flashConstTime;
+		float flashFrequencyBase;
+		float flashHoldTime;
 		float flashRisingTime;
-		
+
 		float time;
-		
-		bool  bNewCoordinate;
+
 		float width;
 		float height;
 		float seedWidth;
 		float seedHeight;
-		
+
 		float seedX;
 		float seedZ;
-		float seedTime;
-		
+		float flashFrequencySeed;
+
 		float mainPosX;
 		float mainPosY;
 		float mainPosZ;
-		
+
+    void newCoordinates();
+
 		Vector cameraCoor;
-		
+
 		Light* flashLight;
-		
-		//OrxSound::SoundSource    soundSource;
-		//OrxSound::SoundBuffer*   thunderBuffer;
+
+		OrxSound::SoundSource    soundSource;
+		OrxSound::SoundBuffer*   thunderBuffer;
 
 };
Index: trunk/src/lib/graphics/effects/rain_effect.cc
===================================================================
--- trunk/src/lib/graphics/effects/rain_effect.cc	(revision 8783)
+++ trunk/src/lib/graphics/effects/rain_effect.cc	(revision 8793)
@@ -1,14 +1,14 @@
 /*
-orxonox - the future of 3D-vertical-scrollers
-
-Copyright (C) 2004 orx
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
+  orxonox - the future of 3D-vertical-scrollers
+ 
+  Copyright (C) 2004 orx
+ 
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+ 
 ### File Specific:
-main-programmer: hdavid, amaechler
+  main-programmer: hdavid, amaechler
 */
 
@@ -26,7 +26,9 @@
 #include "shell_command.h"
 #include "light.h"
+#include "cloud_effect.h"
 
 #include "parser/tinyxml/tinyxml.h"
 
+// Define shell commands
 SHELL_COMMAND(activate, RainEffect, activateRain);
 SHELL_COMMAND(deactivate, RainEffect, deactivateRain);
@@ -38,222 +40,283 @@
 CREATE_FACTORY(RainEffect, CL_RAIN_EFFECT);
 
-/* TODO:
-  - test multiple rain emitters
-  - Think about what happens with building poss. to hang movewithcam off
-  - Possible to activate lightening
-  - turn off visibility when in a building
-  - variable emitter size depending on playable
+/**
+ * @brief standard constructor
+ */
+RainEffect::RainEffect(const TiXmlElement* root)
+{
+  this->setClassID(CL_RAIN_EFFECT, "RainEffect");
+
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+
+  //load rain sound
+  if (this->rainBuffer != NULL)
+    ResourceManager::getInstance()->unload(this->rainBuffer);
+  this->rainBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/atmosphere/rain.wav", WAV);
+
+  //load wind sound
+  if (this->rainWindForce != 0)
+  {
+    if (this->windBuffer != NULL)
+      ResourceManager::getInstance()->unload(this->windBuffer);
+    this->windBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/atmosphere/wind.wav", WAV);
+  }
+
+  if(rainActivate)
+  {
+    this->activate();
+    RainEffect::rainParticles->precache((int)this->rainLife * 2);
+  }
+}
+
+/**
+ * @brief standard deconstructor
+ */
+RainEffect::~RainEffect()
+{
+  this->deactivate();
+
+  if (this->rainBuffer != NULL)
+    ResourceManager::getInstance()->unload(this->rainBuffer);
+
+  if (this->windBuffer != NULL)
+    ResourceManager::getInstance()->unload(this->windBuffer);
+}
+
+/**
+ * @brief initalizes the rain effect with default values
+ */
+void RainEffect::init()
+{
+  //Default values
+  this->rainActivate = false;
+  this->rainMove = false;
+  this->rainCoord = Vector(500, 500, 500);
+  this->rainSize = Vector2D(1000, 1000);
+  this->rainRate = 4000;
+  this->rainVelocity = -300;
+  this->rainLife = 4;
+  this->rainWindForce  = 0;
+  this->rainFadeInDuration = 0;
+  this->rainFadeOutDuration = 0;
+  
+  this->cloudColor = Vector(0.8f, 0.8f, 0.8f);
+  this->skyColor = Vector(0.0f, 0.0f, 0.0f);
+
+  this->rainMaxParticles = this->rainRate * this->rainLife;
+  this->localTimer = 0;
+  this->soundRainVolume = 0.3f;
+  this->emitter = new PlaneEmitter(this->rainSize);
+
+  lightMan = LightManager::getInstance();
+  this->rainAmbient = lightMan->getAmbientColor();
+}
+
+/**
+ * @brief loads the rain effect parameters.
+ * @param root: the XML-Element to load the data from
+ */
+void RainEffect::loadParams(const TiXmlElement* root)
+{
+  WeatherEffect::loadParams(root);
+
+  LoadParam(root, "coord", this, RainEffect, setRainCoord);
+  LoadParam(root, "size", this, RainEffect, setRainSize);
+  LoadParam(root, "rate", this, RainEffect, setRainRate);
+  LoadParam(root, "velocity", this, RainEffect, setRainVelocity);
+  LoadParam(root, "life", this, RainEffect, setRainLife);
+  LoadParam(root, "wind", this, RainEffect, setRainWind);
+  LoadParam(root, "fadeinduration", this, RainEffect, setRainFadeIn);
+  LoadParam(root, "fadeoutduration", this, RainEffect, setRainFadeOut);
+  LoadParam(root, "cloudcolor", this, RainEffect, setCloudColor);
+  LoadParam(root, "skycolor", this, RainEffect, setSkyColor);
+
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    LoadParam_CYCLE(element, "option", this, RainEffect, setRainOption);
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+SparkParticles* RainEffect::rainParticles = NULL;
+
+/**
+ * @brief activates the rain effect
+ */
+void RainEffect::activate()
+{
+  PRINTF(0)( "Activating RainEffect, coord: %f, %f, %f, size: %f, %f, rate: %f, velocity: %f, moveRain: %s\n", this->rainCoord.x, this->rainCoord.y, this->rainCoord.z, this->rainSize.x, this-> rainSize.y, this->rainRate, this->rainVelocity, this->rainMove ? "true" : "false" );
+
+  this->rainActivate = true;
+
+  if (unlikely(RainEffect::rainParticles == NULL))
+  {
+    RainEffect::rainParticles = new SparkParticles((int) this->rainMaxParticles);
+    RainEffect::rainParticles->setName("RainParticles");
+    RainEffect::rainParticles->setLifeSpan(this->rainLife, 2);
+    RainEffect::rainParticles->setRadius(0, 0.03);
+    RainEffect::rainParticles->setRadius(0.2, 0.02);
+    RainEffect::rainParticles->setRadius(1, 0.01);
+    RainEffect::rainParticles->setColor(0, 0.3, 0.3, 0.5, 0.2); // grey blue 1
+    RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2); // grey blue 2
+    RainEffect::rainParticles->setColor(1, 0.7, 0.7, 0.7, 0.2); // light grey
+  }
+
+  this->emitter->setSystem(RainEffect::rainParticles);
+
+  this->emitter->setRelCoor(this->rainCoord);
+
+  this->emitter->setEmissionRate(this->rainRate);
+  this->emitter->setEmissionVelocity(this->rainVelocity);
+
+  this->emitter->setSpread(this->rainWindForce / 50, 0.2);
+
+  // plays the rain sound and loops it 
+  this->soundSource.play(this->rainBuffer, this->soundRainVolume, true);
+
+  // if there is wind, play the wind sound
+  if (this->rainWindForce != 0)
+    this->soundSource.play(this->windBuffer, 0.1f * this->rainWindForce, true);
+
+  if (this->rainFadeInDuration == 0)
+    lightMan->setAmbientColor(.1,.1,.1);
+  
+  // Change the cloudcolor,skycolor
+  this->oldCloudColor = CloudEffect::cloudColor;
+  this->oldSkyColor = CloudEffect::skyColor;
+  CloudEffect::changeCloudColor(this->cloudColor);
+  CloudEffect::changeSkyColor(this->skyColor);
+}
+
+/**
+ * @brief deactivates the rain effect
+ */
+void RainEffect::deactivate()
+{
+  PRINTF(0)("Deactivating RainEffect\n");
+
+  this->rainActivate = false;
+  this->emitter->setSystem(NULL);
+
+  // Stop Sound
+  this->soundSource.stop();
+
+  // Restore Light Ambient
+  lightMan->setAmbientColor(this->rainAmbient, this->rainAmbient, this->rainAmbient);
+  
+  CloudEffect::changeCloudColor(this->oldCloudColor);
+  CloudEffect::changeSkyColor(this->oldSkyColor);
+}
+
+/**
+ * @brief ticks the rain effect
+ * @param dt: tick float
+ */
+void RainEffect::tick (float dt)
+{
+  if (!this->rainActivate)
+    return;
+
+  if (this->rainMove)
+  {
+    this->rainCoord = State::getCameraNode()->getAbsCoor();
+    this->emitter->setRelCoor(this->rainCoord.x , this->rainCoord.y+800, this->rainCoord.z);
+  }
+
+  if (this->rainFadeInDuration != 0 && this->localTimer < this->rainFadeInDuration)
+  {
+    this->localTimer += dt;
+    float progress = this->localTimer / this->rainFadeInDuration;
+
+    // Dim Light
+    lightMan->setAmbientColor(1 - progress * 0.9, 1 - progress * 0.9, 1 - progress * 0.9);
+
+    // use alpha in color to fade in
+    RainEffect::rainParticles->setColor(0,   0.3, 0.3, 0.5, 0.2 * progress); // grey blue 1
+    RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2 * progress); // grey blue 2
+    RainEffect::rainParticles->setColor(1,   0.7, 0.7, 0.7, 0.2 * progress); // light grey
+
+    // increase radius for more "heavy" rain
+    RainEffect::rainParticles->setRadius(0, 0.03 * progress);
+    RainEffect::rainParticles->setRadius(0.2, 0.02 * progress);
+    RainEffect::rainParticles->setRadius(1, 0.01 * progress);
+
+    // increase sound volume
+    if (!this->soundSource.isPlaying())
+      this->soundSource.play(this->rainBuffer, this->soundRainVolume, true);
+
+    this->soundSource.gain(this->rainBuffer, this->soundRainVolume * progress);
+  }
+  else if ( this->rainFadeOutDuration != 0 )
+  {
+    if ( this->localTimer < this->rainFadeOutDuration )
+    {
+      this->localTimer += dt;
+      float progress = 1 - (this->localTimer / this->rainFadeOutDuration);
+
+      // Fade In Light
+      lightMan->setAmbientColor(1 - progress * 0.9, 1 - progress * 0.9, 1 - progress * 0.9);
+
+      // use alpha in color to fade out
+      RainEffect::rainParticles->setColor(0,   0.3, 0.3, 0.5, 0.2 * progress); // grey blue 1
+      RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2 * progress); // grey blue 2
+      RainEffect::rainParticles->setColor(1,   0.7, 0.7, 0.7, 0.2 * progress); // light grey
+
+      // decrease radius
+      RainEffect::rainParticles->setRadius(0, 0.03 * progress);
+      RainEffect::rainParticles->setRadius(0.2, 0.02 * progress);
+      RainEffect::rainParticles->setRadius(1, 0.01 * progress);
+
+      // decrease sound volume
+      if (!this->soundSource.isPlaying())
+        this->soundSource.play(this->rainBuffer, this->soundRainVolume, true);
+
+      this->soundSource.gain(this->rainBuffer, this->soundRainVolume * progress);
+    }
+    else
+      this->deactivate();
+  }
+}
+
+/**
+ * @brief starts raining slowly
 */
-
-RainEffect::RainEffect(const TiXmlElement* root) {
-    this->setClassID(CL_RAIN_EFFECT, "RainEffect");
-
-    this->init();
-
-    if (root != NULL)
-        this->loadParams(root);
-
-    //load rain sound
-    if (this->rainBuffer != NULL)
-        ResourceManager::getInstance()->unload(this->rainBuffer);
-    this->rainBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/atmosphere/rain.wav", WAV);
-
-    //load wind sound
-    if (this->rainWindForce != 0) {
-        if (this->windBuffer != NULL)
-            ResourceManager::getInstance()->unload(this->windBuffer);
-        this->windBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/atmosphere/wind.wav", WAV);
-    }
-
-    if(rainActivate) {
-        this->activate();
-        RainEffect::rainParticles->precache((int)this->rainLife * 5); // TODO: Figure out the correct value
-    }
-}
-
-RainEffect::~RainEffect() {
+void RainEffect::startRaining()
+{
+
+  if (this->rainActivate)
     this->deactivate();
 
-    if (this->rainBuffer != NULL)
-        ResourceManager::getInstance()->unload(this->rainBuffer);
-
-    if (this->windBuffer != NULL)
-        ResourceManager::getInstance()->unload(this->windBuffer);
-}
-
-void RainEffect::loadParams(const TiXmlElement* root) {
-    WeatherEffect::loadParams(root);
-
-    LoadParam(root, "coord", this, RainEffect, setRainCoord);
-    LoadParam(root, "size", this, RainEffect, setRainSize);
-    LoadParam(root, "rate", this, RainEffect, setRainRate);
-    LoadParam(root, "velocity", this, RainEffect, setRainVelocity);
-    LoadParam(root, "life", this, RainEffect, setRainLife);
-    LoadParam(root, "wind", this, RainEffect, setRainWind);
-    LoadParam(root, "fadeinduration", this, RainEffect, setRainFadeIn);
-    LoadParam(root, "fadeoutduration", this, RainEffect, setRainFadeOut);
-
-    LOAD_PARAM_START_CYCLE(root, element);
-    {
-        LoadParam_CYCLE(element, "option", this, RainEffect, setRainOption);
-    }
-    LOAD_PARAM_END_CYCLE(element);
-
-}
-
-
-void RainEffect::init() {
-    //Default values
-    this->rainActivate = false;
-    this->rainMove = false;
-    this->rainCoord = Vector(500, 500, 500);
-    this->rainSize = Vector2D(1000, 1000);
-    this->rainRate = 4000;
-    this->rainVelocity = -300;
-    this->rainLife = 4;
-    this->rainMaxParticles = this->rainRate * this->rainLife;
-    this->rainWindForce  = 0;
-    this->rainFadeInDuration = 0;
-    this->rainFadeOutDuration = 0;
-    this->localTimer = 0;
-    this->soundRainVolume = 0.8f;
-
-    this->emitter = new PlaneEmitter(this->rainSize);
-
-    lightMan = LightManager::getInstance();
-    this->rainAmbient = lightMan->getAmbientColor();
-}
-
-
-SparkParticles* RainEffect::rainParticles = NULL;
-
-void RainEffect::activate() {
-    PRINTF(0)( "Activating RainEffect, coord: %f, %f, %f, size: %f, %f, rate: %f, velocity: %f, moveRain: %s\n", this->rainCoord.x, this->rainCoord.y, this->rainCoord.z, this->rainSize.x, this-> rainSize.y, this->rainRate, this->rainVelocity, this->rainMove ? "true" : "false" );
-
-    this->rainActivate = true;
-
-    if (unlikely(RainEffect::rainParticles == NULL)) {
-        RainEffect::rainParticles = new SparkParticles((int) this->rainMaxParticles);
-        RainEffect::rainParticles->setName("RainParticles");
-        RainEffect::rainParticles->setLifeSpan(this->rainLife, 2);
-        RainEffect::rainParticles->setRadius(0, 0.03);
-        RainEffect::rainParticles->setRadius(0.2, 0.02);
-        RainEffect::rainParticles->setRadius(1, 0.01);
-        RainEffect::rainParticles->setColor(0, 0.3, 0.3, 0.5, 0.2); // grey blue 1
-        RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2); // grey blue 2
-        RainEffect::rainParticles->setColor(1, 0.7, 0.7, 0.7, 0.2); // light grey
-    }
-
-    this->emitter->setSystem(RainEffect::rainParticles);
-
-    this->emitter->setRelCoor(this->rainCoord);
-
-    this->emitter->setEmissionRate(this->rainRate);
-    this->emitter->setEmissionVelocity(this->rainVelocity);
-
-    this->emitter->setSpread(this->rainWindForce / 50, 0.2);
-
-    this->soundSource.play(this->rainBuffer, this->soundRainVolume, true);
-
-    if (this->rainWindForce != 0)
-        this->soundSource.play(this->windBuffer, 0.1f * this->rainWindForce, true);
-
-    if (this->rainFadeInDuration == 0)
-        lightMan->setAmbientColor(.1,.1,.1);
-
-}
-
-
-void RainEffect::deactivate() {
-    PRINTF(0)("Deactivating RainEffect\n");
-
-    this->rainActivate = false;
-    this->emitter->setSystem(NULL);
-
-    // Stop Sound
-    this->soundSource.stop();
-
-    // Restore Light Ambient
-    lightMan->setAmbientColor(this->rainAmbient, this->rainAmbient, this->rainAmbient);
-
-}
-
-void RainEffect::tick (float dt) {
-    if (!this->rainActivate)
-        return;
-
-    if (this->rainMove) {
-        this->rainCoord = State::getCameraNode()->getAbsCoor();
-        this->emitter->setRelCoor(this->rainCoord.x , this->rainCoord.y+800, this->rainCoord.z);
-    }
-
-    if (this->rainFadeInDuration != 0 && this->localTimer < this->rainFadeInDuration) {
-        this->localTimer += dt;
-        float progress = this->localTimer / this->rainFadeInDuration;
-
-        // Dim Light
-        lightMan->setAmbientColor(1 - progress * 0.9, 1 - progress * 0.9, 1 - progress * 0.9);
-
-        // use alpha in color to fade in
-        RainEffect::rainParticles->setColor(0,   0.3, 0.3, 0.5, 0.2 * progress); // grey blue 1
-        RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2 * progress); // grey blue 2
-        RainEffect::rainParticles->setColor(1,   0.7, 0.7, 0.7, 0.2 * progress); // light grey
-
-        // increase radius for more "heavy" rain
-        RainEffect::rainParticles->setRadius(0, 0.03 * progress);
-        RainEffect::rainParticles->setRadius(0.2, 0.02 * progress);
-        RainEffect::rainParticles->setRadius(1, 0.01 * progress);
-
-        // increase sound volume
-        // this->soundSource.fadein(this->rainBuffer, 10);
-    } else if ( this->rainFadeOutDuration != 0 ) {
-        if ( this->localTimer < this->rainFadeOutDuration ) {
-            this->localTimer += dt;
-            float progress = 1 - (this->localTimer / this->rainFadeOutDuration);
-
-            // Fade In Light
-            lightMan->setAmbientColor(1 - progress * 0.9, 1 - progress * 0.9, 1 - progress * 0.9);
-
-            // use alpha in color to fade out
-            RainEffect::rainParticles->setColor(0,   0.3, 0.3, 0.5, 0.2 * progress); // grey blue 1
-            RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2 * progress); // grey blue 2
-            RainEffect::rainParticles->setColor(1,   0.7, 0.7, 0.7, 0.2 * progress); // light grey
-
-            // decrease radius
-            RainEffect::rainParticles->setRadius(0, 0.03 * progress);
-            RainEffect::rainParticles->setRadius(0.2, 0.02 * progress);
-            RainEffect::rainParticles->setRadius(1, 0.01 * progress);
-
-            // decrease sound volume
-            // this->soundSource.fadeout(this->rainBuffer, 10);
-        } else
-            this->deactivate();
-    }
-
-}
-
-void RainEffect::startRaining() {
-
-    if (this->rainActivate)
-        this->deactivate();
-
-    if (!this->rainFadeInDuration > 0)
-        this->rainFadeInDuration = 20;
-
-    this->localTimer = 0;
-
+  if (!this->rainFadeInDuration > 0)
+    this->rainFadeInDuration = 20;
+
+  this->localTimer = 0;
+
+  this->activate();
+}
+
+/**
+ * @brief stops raining slowly
+ */
+void RainEffect::stopRaining()
+{
+
+  if (!this->rainActivate)
     this->activate();
 
-}
-
-void RainEffect::stopRaining() {
-
-    if (!this->rainActivate)
-        this->activate();
-
-    if (!this->rainFadeOutDuration > 0)
-        this->rainFadeOutDuration = 20;
-
-    this->localTimer = 0;
-
-}
+  if (!this->rainFadeOutDuration > 0)
+    this->rainFadeOutDuration = 20;
+
+  this->localTimer = 0;
+}
+
+/**
+ * @brief hides the rain
+ */
+void RainEffect::hideRain()
+{
+  RainEffect::rainParticles->setColor(0, 0,0,0, 0);
+  RainEffect::rainParticles->setColor(0, 0,0,0, 0);
+}
Index: trunk/src/lib/graphics/effects/rain_effect.h
===================================================================
--- trunk/src/lib/graphics/effects/rain_effect.h	(revision 8783)
+++ trunk/src/lib/graphics/effects/rain_effect.h	(revision 8793)
@@ -1,8 +1,11 @@
 /**
-* @file rain_effect.h
+ * @file rain_effect.h
+ * Generates rain using the particle engine
 */
 
 #ifndef _RAIN_EFFECT
 #define _RAIN_EFFECT
+
+#include "weather_effect.h"
 
 #include "vector.h"
@@ -15,95 +18,123 @@
 class PlainEmitter;
 class LightManager;
-
-#include "weather_effect.h"
+class CloudEffect;
 
 #include "sound_buffer.h"
 #include "sound_source.h"
 
+class RainEffect : public WeatherEffect
+{
+public:
+  RainEffect(const TiXmlElement* root = NULL);
+  virtual ~RainEffect();
 
-class RainEffect : public WeatherEffect {
-public:
-    RainEffect(const TiXmlElement* root = NULL);
-    virtual ~RainEffect();
+  virtual void loadParams(const TiXmlElement* root);
 
-    virtual void loadParams(const TiXmlElement* root);
+  virtual void init();
 
-    virtual void init();
+  virtual void activate();
+  virtual void deactivate();
 
-    virtual void activate();
-    virtual void deactivate();
+  inline void activateRain()
+  {
+    this->activate();
+  }
 
-    inline void activateRain() {
-        this->activate();
-    }
-    inline void deactivateRain() {
-        this->deactivate();
-    }
+  inline void deactivateRain()
+  {
+    this->deactivate();
+  }
 
-    virtual void tick(float dt);
+  virtual void tick(float dt);
 
-    void startRaining();
-    void stopRaining();
+  void startRaining();
+  void stopRaining();
 
-    inline void setRainCoord(float x, float y, float z) {
-        this->rainCoord = Vector(x, y, z);
-    }
-    inline void setRainSize(float x, float y) {
-        this->rainSize = Vector2D(x, y);
-    }
-    inline void setRainRate(float rate) {
-        this->rainRate = rate;
-    }
-    inline void setRainVelocity(float velocity) {
-        this->rainVelocity = -velocity;
-    }
-    inline void setRainLife(float life) {
-        this->rainLife = life;
-    }
-    inline void setRainWind(int force) {
-        this->rainWindForce = force;
-    }
+  void hideRain();
 
-    inline void setRainFadeIn(float fadein) {
-        this->rainFadeInDuration = fadein;
-    }
-    inline void setRainFadeOut(float fadeout) {
-        this->rainFadeOutDuration = fadeout;
-    }
+  inline void setRainCoord(float x, float y, float z)
+  {
+    this->rainCoord = Vector(x, y, z);
+  }
+  inline void setRainSize(float x, float y)
+  {
+    this->rainSize = Vector2D(x, y);
+  }
+  inline void setRainRate(float rate)
+  {
+    this->rainRate = rate;
+  }
+  inline void setRainVelocity(float velocity)
+  {
+    this->rainVelocity = -velocity;
+  }
+  inline void setRainLife(float life)
+  {
+    this->rainLife = life;
+  }
+  inline void setRainWind(int force)
+  {
+    this->rainWindForce = force;
+  }
 
-    inline void setRainOption(const std::string& option) {
-        if (option == "moverain")
-            this->rainMove = true;
-        if (option == "activate")
-            this->rainActivate = true;
-    }
+  inline void setRainFadeIn(float fadein)
+  {
+    this->rainFadeInDuration = fadein;
+  }
+  inline void setRainFadeOut(float fadeout)
+  {
+    this->rainFadeOutDuration = fadeout;
+  }
+  
+  inline void setCloudColor(float colorX, float colorY, float colorZ)
+  {
+    this->cloudColor = Vector(colorX, colorY, colorZ);
+  }
+  inline void setSkyColor(float colorX, float colorY, float colorZ)
+  {
+    this->skyColor = Vector(colorX, colorY, colorZ);
+  }
+
+  inline void setRainOption(const std::string& option)
+  {
+    if (option == "moverain")
+      this->rainMove = true;
+    if (option == "activate")
+      this->rainActivate = true;
+  }
 
 
 private:
-    static SparkParticles*      rainParticles;
-    ParticleEmitter*            emitter;
+  static SparkParticles*      rainParticles;
+  ParticleEmitter*            emitter;
 
-    GLfloat         rainFadeInDuration;
-    GLfloat         rainFadeOutDuration;
-    float           localTimer;
+  float                       localTimer;
 
-    Vector          rainCoord;
-    Vector2D        rainSize;
-    GLfloat         rainRate;
-    GLfloat         rainVelocity;
-    GLfloat         rainLife;
-    GLfloat         rainMaxParticles;
-    int             rainWindForce;
-    bool            rainMove;
-    bool            rainActivate;
+  GLfloat                     rainFadeInDuration;
+  GLfloat                     rainFadeOutDuration;
 
-    OrxSound::SoundSource     soundSource;
-    OrxSound::SoundBuffer*      rainBuffer;
-    OrxSound::SoundBuffer*      windBuffer;
+  Vector                      rainCoord;
+  Vector2D                    rainSize;
+  GLfloat                     rainRate;
+  GLfloat                     rainVelocity;
+  GLfloat                     rainLife;
+  GLfloat                     rainMaxParticles;
+  int                         rainWindForce;
+  bool                        rainMove;
+  bool                        rainActivate;
 
-    float         soundRainVolume;
+  OrxSound::SoundSource       soundSource;
+  OrxSound::SoundBuffer*      rainBuffer;
+  OrxSound::SoundBuffer*      windBuffer;
 
-    LightManager*       lightMan;
-    GLfloat         rainAmbient;
+  float                       soundRainVolume;
+
+  LightManager*               lightMan;
+  GLfloat                     rainAmbient;
+  
+  Vector oldSkyColor;
+  Vector oldCloudColor;
+  Vector skyColor;
+  Vector cloudColor;
 
 };
Index: trunk/src/lib/graphics/effects/snow_effect.cc
===================================================================
--- trunk/src/lib/graphics/effects/snow_effect.cc	(revision 8783)
+++ trunk/src/lib/graphics/effects/snow_effect.cc	(revision 8793)
@@ -56,5 +56,5 @@
 		this->activate();
     SnowEffect::snowParticles->precache((int) this->snowLife);
-  }  
+  }
 }
 
@@ -143,5 +143,5 @@
   if (this->snowWindForce != 0)
     this->soundSource.play(this->windBuffer, 0.1f * this->snowWindForce, true);
- 
+
 }
 
Index: trunk/src/lib/graphics/effects/sun_effect.cc
===================================================================
--- trunk/src/lib/graphics/effects/sun_effect.cc	(revision 8783)
+++ trunk/src/lib/graphics/effects/sun_effect.cc	(revision 8793)
@@ -56,5 +56,5 @@
  *  initializes the graphics effect
  */
-bool SunEffect::init()
+void SunEffect::init()
 {}
 
Index: trunk/src/lib/graphics/effects/sun_effect.h
===================================================================
--- trunk/src/lib/graphics/effects/sun_effect.h	(revision 8783)
+++ trunk/src/lib/graphics/effects/sun_effect.h	(revision 8793)
@@ -1,5 +1,5 @@
 /*!
  * @file sun_effect.h
- *  
+ *
  */
 
@@ -20,8 +20,8 @@
     virtual void loadParams(const TiXmlElement* root);
 
-    virtual bool init();
+    virtual void init();
 
-    virtual bool activate() = 0;
-    virtual bool deactivate() = 0;
+    virtual void activate() = 0;
+    virtual void deactivate() = 0;
 
     virtual void draw() const;
Index: trunk/src/lib/sound/sound_source.cc
===================================================================
--- trunk/src/lib/sound/sound_source.cc	(revision 8783)
+++ trunk/src/lib/sound/sound_source.cc	(revision 8793)
@@ -164,6 +164,7 @@
 
   /**
-  * @brief Plays back buffer on this Source with gain
-  * @param buffer the buffer to play back on this Source
+   * @brief Plays back buffer on this Source with gain
+   * @param buffer the buffer to play back on this Source
+   * @param gain the gain of the sound buffer 
   */
   void SoundSource::play(const SoundBuffer* buffer, float gain)
@@ -189,9 +190,11 @@
       SoundEngine::checkError("Play Source", __LINE__);
   }
-  
-   /**
+
+  /**
    * @brief Plays back buffer on this Source with gain and looping possibility
    * @param buffer the buffer to play back on this Source
-    */
+   *  @param gain the gain of the sound buffer
+   * @param loop if true, sound gets looped
+   */
   void SoundSource::play(const SoundBuffer* buffer, float gain, bool loop)
   {
@@ -204,10 +207,10 @@
     alSourceStop(this->sourceID);
     alSourcei (this->sourceID, AL_BUFFER, buffer->getID());
-    
+
     if (loop)
-        alSourcei (this->sourceID, AL_LOOPING,  AL_TRUE);
+      alSourcei (this->sourceID, AL_LOOPING,  AL_TRUE);
     else
-        alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE);
-    
+      alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE);
+
     alSourcef (this->sourceID, AL_GAIN, gain);
 
@@ -220,10 +223,20 @@
     if (DEBUG_LEVEL >= 3)
       SoundEngine::checkError("Play Source", __LINE__);
-  } 
-
-
-  /**
-  * @brief Stops playback of a SoundSource
-  */
+  }
+
+  /**
+   * @brief Changes the volume of an (active) buffer
+   * @param buffer the buffer to play back on this Source
+   * @param gain the new gain value
+   */
+  void SoundSource::gain(const SoundBuffer* buffer, float gain)
+  {
+    // alSourcei (this->sourceID, AL_BUFFER, buffer->getID());
+    alSourcef (this->sourceID, AL_GAIN, gain);
+  }
+
+  /**
+   * @brief Stops playback of a SoundSource
+   */
   void SoundSource::stop()
   {
Index: trunk/src/lib/sound/sound_source.h
===================================================================
--- trunk/src/lib/sound/sound_source.h	(revision 8783)
+++ trunk/src/lib/sound/sound_source.h	(revision 8793)
@@ -14,57 +14,58 @@
 namespace OrxSound
 {
-	class SoundBuffer;
-	//! A class that represents a SoundSource
-	class SoundSource : public BaseObject
-	{
-		public:
-			SoundSource(const PNode* sourceNode = NULL, const SoundBuffer* buffer = NULL);
-			SoundSource(const SoundSource& source);
-			SoundSource& operator=(const SoundSource& source);
-			bool operator==(const SoundSource& source);
-			
-			virtual ~SoundSource();
-			
-			// user interaction
-			void play();
-			void play(const SoundBuffer* buffer);
-			void play(const SoundBuffer* buffer, float gain);
-      void play(const SoundBuffer* buffer, float gain, bool loop);   
+  class SoundBuffer;
+  //! A class that represents a SoundSource
+  class SoundSource : public BaseObject
+  {
+  public:
+    SoundSource(const PNode* sourceNode = NULL, const SoundBuffer* buffer = NULL);
+    SoundSource(const SoundSource& source);
+    SoundSource& operator=(const SoundSource& source);
+    bool operator==(const SoundSource& source);
 
-			void stop();
-			void pause();
-			void rewind();
-			void fadein(const SoundBuffer* buffer, ALfloat duration);
-			
-			
-			// development functions
-			/** @returns The ID of this Source */
-			inline ALuint getID() const { return this->sourceID; };
-			/** @returns true, if the Source is Playing */
-			inline bool   isPlaying() const { return this->bPlay; };
-			void setSourceNode(const PNode* sourceNode);
-			/** @returns the SoundBuffer of this Source */
-			inline const SoundBuffer* getBuffer() const { return this->buffer; };
-			/** @returns the SourceNode of this Source */
-			inline const PNode* getNode() const { return this->sourceNode; };
-			/** @param resident if the Source is Resident */
-			inline void setResident(bool resident) { this->resident = resident; };
-			/** @returns true if the alSource is Resident */
-			inline bool isResident() const { return this->resident; };
-			
-			void setRolloffFactor(ALfloat rolloffFactor);
-			
-			static void resetSource(ALuint sourceID);
-		
-		private:
-			bool retrieveSource();
-			
-		private:
-			bool                   bPlay;		//!< If the Source is Playing.
-			bool                   resident;	//!< If the alSource should be resident (if true, the alSource will be returned on deletion).
-			ALuint                 sourceID;	//!< The ID of the Source
-			const SoundBuffer*     buffer;		//!< The buffer to play in this source.
-			const PNode*           sourceNode;	//!< The SourceNode representing the position/velocity... of this source.
-	};
+    virtual ~SoundSource();
+
+    // user interaction
+    void play();
+    void play(const SoundBuffer* buffer);
+    void play(const SoundBuffer* buffer, float gain);
+    void play(const SoundBuffer* buffer, float gain, bool loop);
+
+    void gain(const SoundBuffer* buffer, float gain);
+
+    void stop();
+    void pause();
+    void rewind();
+    void fadein(const SoundBuffer* buffer, ALfloat duration);
+
+    // development functions
+    /** @returns The ID of this Source */
+    inline ALuint getID() const { return this->sourceID; };
+    /** @returns true, if the Source is Playing */
+    inline bool isPlaying() const { return this->bPlay; };
+    void setSourceNode(const PNode* sourceNode);
+    /** @returns the SoundBuffer of this Source */
+    inline const SoundBuffer* getBuffer() const { return this->buffer; };
+    /** @returns the SourceNode of this Source */
+    inline const PNode* getNode() const { return this->sourceNode; };
+    /** @param resident if the Source is Resident */
+    inline void setResident(bool resident) { this->resident = resident; };
+    /** @returns true if the alSource is Resident */
+    inline bool isResident() const { return this->resident; };
+
+    void setRolloffFactor(ALfloat rolloffFactor);
+
+    static void resetSource(ALuint sourceID);
+
+  private:
+    bool                   retrieveSource();
+
+  private:
+    bool                   bPlay;       //!< If the Source is Playing.
+    bool                   resident;    //!< If the alSource should be resident (if true, the alSource will be returned on deletion).
+    ALuint                 sourceID;    //!< The ID of the Source
+    const SoundBuffer*     buffer;      //!< The buffer to play in this source.
+    const PNode*           sourceNode;  //!< The SourceNode representing the position/velocity... of this source.
+  };
 }
 #endif /* _SOUND_SOURCE_H */
