Index: /branches/mountain_lake/src/lib/graphics/effects/cloud_effect.cc
===================================================================
--- /branches/mountain_lake/src/lib/graphics/effects/cloud_effect.cc	(revision 8910)
+++ /branches/mountain_lake/src/lib/graphics/effects/cloud_effect.cc	(revision 8911)
@@ -1,15 +1,15 @@
 /*
   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
 */
@@ -30,12 +30,15 @@
 #include "parser/tinyxml/tinyxml.h"
 
-Vector  CloudEffect::cloudColor;
-Vector  CloudEffect::skyColor;
-Vector  CloudEffect::newCloudColor;
-Vector  CloudEffect::newSkyColor;
-
-bool CloudEffect::fadeSky;
-bool CloudEffect::fadeCloud;
-float CloudEffect::fadeTime;
+Vector    CloudEffect::cloudColor;
+Vector    CloudEffect::skyColor;
+Vector    CloudEffect::newCloudColor;
+Vector    CloudEffect::newSkyColor;
+
+bool      CloudEffect::fadeSky;
+bool      CloudEffect::fadeCloud;
+float     CloudEffect::fadeTime;
+bool      CloudEffect::flashSkyActivate;
+float     CloudEffect::localTimer;
+float     CloudEffect::flashTime;
 
 using namespace std;
@@ -48,405 +51,416 @@
 CREATE_FACTORY(CloudEffect, CL_CLOUD_EFFECT);
 
-CloudEffect::CloudEffect(const TiXmlElement* root)
-{
-  this->setClassID(CL_CLOUD_EFFECT, "CloudEffect");
-
-  this->init();
-
-  if (root != NULL)
-    this->loadParams(root);
-
-  if(cloudActivate)
-    this->activate();
-}
-
-CloudEffect::~CloudEffect()
-{
-  this->deactivate();
-
-  if (glIsTexture(noise3DTexName))
-    glDeleteTextures(1, &noise3DTexName);
-
-  delete shader;
-}
-
-
-void CloudEffect::init()
-{
-  PRINTF(0)("Initializing CloudEffect\n");
-
-  this->offsetZ = 0;
-  this->animationSpeed = 2;
-  this->scale = 0.0004f;
-  this->atmosphericRadius = 4000;
-  this->planetRadius = 1500;
-  this->divs = 15;
-  fadeSky = false;
-  fadeCloud = false;
-
-  skyColor = Vector(0.0f, 0.0f, 0.8f);
-  cloudColor = Vector(0.8f, 0.8f, 0.8f);
-  newSkyColor = skyColor;
-  newCloudColor = cloudColor;
-
-  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);
-
-  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);
-}
-
-
-void CloudEffect::loadParams(const TiXmlElement* root)
-{
-  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);
-}
-
-
-void CloudEffect::activate()
-{
-  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;
-}
-
-void CloudEffect::draw() const
-  {}
-
-void CloudEffect::tick (float dt)
-{
-  if (this->cloudActivate)
-  {
-    this->offsetZ += 0.05 * dt * this->animationSpeed;
+CloudEffect::CloudEffect(const TiXmlElement* root) {
+    this->setClassID(CL_CLOUD_EFFECT, "CloudEffect");
+
+    this->init();
+
+    if (root != NULL)
+        this->loadParams(root);
+
+    if(cloudActivate)
+        this->activate();
+}
+
+CloudEffect::~CloudEffect() {
+    this->deactivate();
+
+    if (glIsTexture(noise3DTexName))
+        glDeleteTextures(1, &noise3DTexName);
+
+    delete shader;
+}
+
+
+void CloudEffect::init() {
+    PRINTF(0)("Initializing CloudEffect\n");
+
+    // default values
+    this->offsetZ = 0;
+    this->animationSpeed = 2;
+    this->scale = 0.0004f;
+    this->atmosphericRadius = 4000;
+    this->planetRadius = 1500;
+    this->divs = 15;
+    fadeSky = false;
+    fadeCloud = false;
+
+    flashSkyActivate = false;
+    localTimer = 0;
+    flashTime = 0;
+
+    skyColor = Vector(0.0f, 0.0f, 0.8f);
+    cloudColor = Vector(0.8f, 0.8f, 0.8f);
+    newSkyColor = skyColor;
+    newCloudColor = cloudColor;
+
+    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();
-    this->offset->set(0.0f, 0.0f, offsetZ);
-
-    if(cloudColor != newCloudColor)
+
+    Shader::Uniform(shader, "Noise").set(0);
+
+    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);
+}
+
+
+void CloudEffect::loadParams(const TiXmlElement* root) {
+    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);
     {
-      if(fadeCloud)
-      {
-        this->cloudColorFadeX = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudX);
-        this->cloudColorFadeX->setInfinity(ANIM_INF_CONSTANT);
-        this->cloudColorFadeY = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudY);
-        this->cloudColorFadeY->setInfinity(ANIM_INF_CONSTANT);
-        this->cloudColorFadeZ = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudZ);
-        this->cloudColorFadeZ->setInfinity(ANIM_INF_CONSTANT);
-
-        this->cloudColorFadeX->addKeyFrame(cloudColor.x, fadeTime, ANIM_LINEAR);
-        this->cloudColorFadeX->addKeyFrame(newCloudColor.x, 0, ANIM_LINEAR);
-
-        this->cloudColorFadeY->addKeyFrame(cloudColor.y, fadeTime, ANIM_LINEAR);
-        this->cloudColorFadeY->addKeyFrame(newCloudColor.y, 0, ANIM_LINEAR);
-
-        this->cloudColorFadeZ->addKeyFrame(cloudColor.z, fadeTime, ANIM_LINEAR);
-        this->cloudColorFadeZ->addKeyFrame(newCloudColor.z, 0, ANIM_LINEAR);
-
-        fadeCloud = false;
-
-        this->cloudColorFadeX->replay();
-        this->cloudColorFadeY->replay();
-        this->cloudColorFadeZ->replay();
-      }
-
-      this->cloudcolor->set(this->cloudColor.x, this->cloudColor.y, this->cloudColor.z);
-    }
-
-    if(skyColor != newSkyColor)
-    {
-      if(fadeSky)
-      {
-        this->skyColorFadeX = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyX);
-        this->skyColorFadeX->setInfinity(ANIM_INF_CONSTANT);
-        this->skyColorFadeY = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyY);
-        this->skyColorFadeY->setInfinity(ANIM_INF_CONSTANT);
-        this->skyColorFadeZ = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyZ);
-        this->skyColorFadeZ->setInfinity(ANIM_INF_CONSTANT);
-
-        this->skyColorFadeX->addKeyFrame(skyColor.x, fadeTime, ANIM_LINEAR);
-        this->skyColorFadeX->addKeyFrame(newSkyColor.x, 0, ANIM_LINEAR);
-
-        this->skyColorFadeY->addKeyFrame(skyColor.y, fadeTime, ANIM_LINEAR);
-        this->skyColorFadeY->addKeyFrame(newSkyColor.y, 0, ANIM_LINEAR);
-
-        this->skyColorFadeZ->addKeyFrame(skyColor.z, fadeTime, ANIM_LINEAR);
-        this->skyColorFadeZ->addKeyFrame(newSkyColor.z, 0, ANIM_LINEAR);
-
-        fadeSky = false;
-
-        this->skyColorFadeX->replay();
-        this->skyColorFadeY->replay();
-        this->skyColorFadeZ->replay();
-      }
-
-      this->skycolor->set(this->skyColor.x, this->skyColor.y, this->skyColor.z);
-    }
-
+        LoadParam_CYCLE(element, "option", this, CloudEffect, setCloudOption);
+    }
+    LOAD_PARAM_END_CYCLE(element);
+}
+
+
+void CloudEffect::activate() {
+    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();
-  }
-}
-
-
-void CloudEffect::setColorSkyX(float color)
-{
-  skyColor.x = color;
-}
-void CloudEffect::setColorSkyY(float color)
-{
-  skyColor.y = color;
-}
-void CloudEffect::setColorSkyZ(float color)
-{
-  skyColor.z = color;
-}
-void CloudEffect::setColorCloudX(float color)
-{
-  cloudColor.x = color;
-}
-void CloudEffect::setColorCloudY(float color)
-{
-  cloudColor.y = color;
-}
-void CloudEffect::setColorCloudZ(float color)
-{
-  cloudColor.z = color;
-}
-
-void CloudEffect::changeSkyColor(Vector color, float time)
-{
-  newSkyColor = color;
-  fadeSky = true;
-  fadeTime = time;
-}
-
-
-void CloudEffect::changeCloudColor(Vector color, float time)
-{
-  newCloudColor = color;
-  fadeCloud = true;
-  fadeTime = time;
-}
-
-void CloudEffect::shellSkyColor(float colorX, float colorY, float colorZ, float time)
-{
-  changeSkyColor( Vector(colorX, colorY, colorZ), time);
-}
-void CloudEffect::shellCloudColor(float colorX, float colorY, float colorZ, float time)
-{
-  changeCloudColor( Vector(colorX, colorY, colorZ), time);
-}
-
-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);
+
+    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;
+}
+
+void CloudEffect::draw() const {}
+
+void CloudEffect::tick (float dt) {
+
+    if (this->cloudActivate) {
+
+        localTimer += dt;
+
+        this->offsetZ += 0.05 * dt * this->animationSpeed;
+
+        this->shader->activateShader();
+        this->offset->set(0.0f, 0.0f, offsetZ);
+
+        if (flashSkyActivate) {
+
+            this->skycolor->set(1, 1, 1);
+            PRINTF(0)("SkyColor set to white\n");
+
+            if (localTimer > flashTime) {
+                flashSkyActivate = false;
+                this->skycolor->set(this->skyColor.x, this->skyColor.y, this->skyColor.z);
+                PRINTF(0)("SkyColor reset\n");
+            }
+
+        } else {
+
+            if(cloudColor != newCloudColor) {
+
+                if(fadeCloud) {
+
+                    this->cloudColorFadeX = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudX);
+                    this->cloudColorFadeX->setInfinity(ANIM_INF_CONSTANT);
+                    this->cloudColorFadeY = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudY);
+                    this->cloudColorFadeY->setInfinity(ANIM_INF_CONSTANT);
+                    this->cloudColorFadeZ = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudZ);
+                    this->cloudColorFadeZ->setInfinity(ANIM_INF_CONSTANT);
+
+                    this->cloudColorFadeX->addKeyFrame(cloudColor.x, fadeTime, ANIM_LINEAR);
+                    this->cloudColorFadeX->addKeyFrame(newCloudColor.x, 0, ANIM_LINEAR);
+
+                    this->cloudColorFadeY->addKeyFrame(cloudColor.y, fadeTime, ANIM_LINEAR);
+                    this->cloudColorFadeY->addKeyFrame(newCloudColor.y, 0, ANIM_LINEAR);
+
+                    this->cloudColorFadeZ->addKeyFrame(cloudColor.z, fadeTime, ANIM_LINEAR);
+                    this->cloudColorFadeZ->addKeyFrame(newCloudColor.z, 0, ANIM_LINEAR);
+
+                    fadeCloud = false;
+
+                    this->cloudColorFadeX->replay();
+                    this->cloudColorFadeY->replay();
+                    this->cloudColorFadeZ->replay();
+                }
+
+                this->cloudcolor->set(this->cloudColor.x, this->cloudColor.y, this->cloudColor.z);
+            }
+
+            if(skyColor != newSkyColor) {
+
+                if(fadeSky) {
+
+                    this->skyColorFadeX = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyX);
+                    this->skyColorFadeX->setInfinity(ANIM_INF_CONSTANT);
+                    this->skyColorFadeY = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyY);
+                    this->skyColorFadeY->setInfinity(ANIM_INF_CONSTANT);
+                    this->skyColorFadeZ = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyZ);
+                    this->skyColorFadeZ->setInfinity(ANIM_INF_CONSTANT);
+
+                    this->skyColorFadeX->addKeyFrame(skyColor.x, fadeTime, ANIM_LINEAR);
+                    this->skyColorFadeX->addKeyFrame(newSkyColor.x, 0, ANIM_LINEAR);
+
+                    this->skyColorFadeY->addKeyFrame(skyColor.y, fadeTime, ANIM_LINEAR);
+                    this->skyColorFadeY->addKeyFrame(newSkyColor.y, 0, ANIM_LINEAR);
+
+                    this->skyColorFadeZ->addKeyFrame(skyColor.z, fadeTime, ANIM_LINEAR);
+                    this->skyColorFadeZ->addKeyFrame(newSkyColor.z, 0, ANIM_LINEAR);
+
+                    fadeSky = false;
+
+                    this->skyColorFadeX->replay();
+                    this->skyColorFadeY->replay();
+                    this->skyColorFadeZ->replay();
+                }
+
+                this->skycolor->set(this->skyColor.x, this->skyColor.y, this->skyColor.z);
+            }
         }
-      }
-    }
-  }
-}
-
-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;
-}
-
+
+        this->shader->deactivateShader();
+    }
+}
+
+
+void CloudEffect::setColorSkyX(float color) {
+    skyColor.x = color;
+}
+void CloudEffect::setColorSkyY(float color) {
+    skyColor.y = color;
+}
+void CloudEffect::setColorSkyZ(float color) {
+    skyColor.z = color;
+}
+void CloudEffect::setColorCloudX(float color) {
+    cloudColor.x = color;
+}
+void CloudEffect::setColorCloudY(float color) {
+    cloudColor.y = color;
+}
+void CloudEffect::setColorCloudZ(float color) {
+    cloudColor.z = color;
+}
+
+void CloudEffect::changeSkyColor(Vector color, float time) {
+    newSkyColor = color;
+    fadeSky = true;
+    fadeTime = time;
+}
+
+
+void CloudEffect::changeCloudColor(Vector color, float time) {
+    newCloudColor = color;
+    fadeCloud = true;
+    fadeTime = time;
+}
+
+void CloudEffect::shellSkyColor(float colorX, float colorY, float colorZ, float time) {
+    changeSkyColor( Vector(colorX, colorY, colorZ), time);
+}
+
+void CloudEffect::shellCloudColor(float colorX, float colorY, float colorZ, float time) {
+    changeCloudColor( Vector(colorX, colorY, colorZ), time);
+}
+
+void CloudEffect::flashSky( float time ) {
+
+  flashSkyActivate = true;
+  localTimer = 0;
+  flashTime = time;
+
+}
+
+
+
+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: /branches/mountain_lake/src/lib/graphics/effects/cloud_effect.h
===================================================================
--- /branches/mountain_lake/src/lib/graphics/effects/cloud_effect.h	(revision 8910)
+++ /branches/mountain_lake/src/lib/graphics/effects/cloud_effect.h	(revision 8911)
@@ -1,5 +1,5 @@
 /**
  * @file cloud_effect.h
- * Creates clouds
+ * Create clouds
 */
 
@@ -33,127 +33,143 @@
 
 // FORWARD DECLARATION
-template <class T> class tAnimation;
+template <class T>
+class tAnimation;
 
+class CloudEffect : public WeatherEffect {
 
-class CloudEffect : public WeatherEffect
-{
 public:
-  CloudEffect(const TiXmlElement* root = NULL);
-  virtual ~CloudEffect();
 
-  virtual void loadParams(const TiXmlElement* root);
+    CloudEffect(const TiXmlElement* root = NULL);
+    virtual ~CloudEffect();
 
-  virtual void init();
+    virtual void loadParams(const TiXmlElement* root);
 
-  virtual void activate();
-  virtual void deactivate();
+    virtual void init();
 
-  inline void activateCloud()
-  { this->activate(); }
+    virtual void activate();
+    virtual void deactivate();
 
-  inline void deactivateCloud()
-  { this->deactivate(); }
+    inline void activateCloud() {
+        this->activate();
+    }
 
-  inline void setCloudOption(const std::string& option)
-  {
-    if (option == "activate")
-      this->cloudActivate = true;
-  }
+    inline void deactivateCloud() {
+        this->deactivate();
+    }
 
-  inline void setAnimationSpeed(float speed)
-{ this->animationSpeed = speed; }
+    inline void setCloudOption(const std::string& option) {
+        if (option == "activate")
+            this->cloudActivate = true;
+    }
 
-  inline void setCloudScale(float scale)
-  { this->scale = scale; }
+    inline void setAnimationSpeed(float speed) {
+        this->animationSpeed = speed;
+    }
 
-  inline void setCloudColor(float colorX, float colorY, float colorZ)
-  { this->cloudColor = Vector(colorX, colorY, colorZ); }
+    inline void setCloudScale(float scale) {
+        this->scale = scale;
+    }
 
-  inline void setSkyColor(float colorX, float colorY, float colorZ)
-  { this->skyColor = Vector(colorX, colorY, colorZ); }
+    inline void setCloudColor(float colorX, float colorY, float colorZ) {
+        this->cloudColor = Vector(colorX, colorY, colorZ);
+    }
 
-  inline void setPlanetRadius(float planetRadius)
-  { this->planetRadius = planetRadius; }
+    inline void setSkyColor(float colorX, float colorY, float colorZ) {
+        this->skyColor = Vector(colorX, colorY, colorZ);
+    }
 
-  inline void setAtmosphericRadius(float atmosphericRadius)
-  { this->atmosphericRadius = atmosphericRadius; }
+    inline void setPlanetRadius(float planetRadius) {
+        this->planetRadius = planetRadius;
+    }
 
-  inline void setDivisions(int divs)
-  { this->divs = divs; }
+    inline void setAtmosphericRadius(float atmosphericRadius) {
+        this->atmosphericRadius = atmosphericRadius;
+    }
 
-  virtual void draw() const;
-  virtual void tick(float dt);
+    inline void setDivisions(int divs) {
+        this->divs = divs;
+    }
 
-  static void changeSkyColor(Vector color, float time);
-  static void changeCloudColor(Vector color, float time);
-  
-  void setColorSkyX(float color);
-  void setColorSkyY(float color);
-  void setColorSkyZ(float color);
-  void setColorCloudX(float color);
-  void setColorCloudY(float color);
-  void setColorCloudZ(float color);
-  
-  static Vector    cloudColor;
-  static Vector    skyColor;
+    virtual void draw() const;
+    virtual void tick(float dt);
 
-  void make3DNoiseTexture();
-  void initNoise();
-  void SetNoiseFrequency(int frequency);
-  double noise3(double vec[3]);
-  void normalize2(double v[2]);
-  void normalize3(double v[3]);
+    static void changeSkyColor(Vector color, float time);
+    static void changeCloudColor(Vector color, float time);
 
-  void generateSkyPlane(int divisions, float planetRadius, float atmosphereRadius,
-                        float hTile, float vTile);
-  
-  void shellSkyColor(float colorX, float colorY, float colorZ, float time);
-  void shellCloudColor(float colorX, float colorY, float colorZ, float time);
-  
+    void setColorSkyX(float color);
+    void setColorSkyY(float color);
+    void setColorSkyZ(float color);
+    void setColorCloudX(float color);
+    void setColorCloudY(float color);
+    void setColorCloudZ(float 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);
+
+    void shellSkyColor(float colorX, float colorY, float colorZ, float time);
+    void shellCloudColor(float colorX, float colorY, float colorZ, float time);
+
+    static void flashSky(float time);
+
 private:
 
-  bool             cloudActivate;
-  float            animationSpeed;
-  
-  static Vector           newSkyColor;
-  static Vector           newCloudColor;
+    bool                    cloudActivate;
+    float                   animationSpeed;
 
-  // Material                 cloudMaterial;
-  Skydome*         skydome;
-  
-  tAnimation<CloudEffect>*  skyColorFadeX;
-  tAnimation<CloudEffect>*  skyColorFadeY;
-  tAnimation<CloudEffect>*  skyColorFadeZ;
-  tAnimation<CloudEffect>*  cloudColorFadeX;
-  tAnimation<CloudEffect>*  cloudColorFadeY;
-  tAnimation<CloudEffect>*  cloudColorFadeZ;
-  static bool fadeSky;
-  static bool fadeCloud;
-  static float fadeTime;
+    static Vector           newSkyColor;
+    static Vector           newCloudColor;
 
-  // SHADER STUFF
-  Shader*          shader;
-  Shader::Uniform* offset;
-  Shader::Uniform* skycolor;
-  Shader::Uniform* cloudcolor;
-  float            offsetZ;
-  float            scale;
-  float            planetRadius;
-  float            atmosphericRadius;
-  int              divs;
+    // Material             cloudMaterial;
+    Skydome*                 skydome;
 
-  // NOISE STUFF
-  int              noise3DTexSize;
-  GLuint           noise3DTexName;
-  GLubyte          *noise3DTexPtr;
+    tAnimation<CloudEffect>*  skyColorFadeX;
+    tAnimation<CloudEffect>*  skyColorFadeY;
+    tAnimation<CloudEffect>*  skyColorFadeZ;
+    tAnimation<CloudEffect>*  cloudColorFadeX;
+    tAnimation<CloudEffect>*  cloudColorFadeY;
+    tAnimation<CloudEffect>*  cloudColorFadeZ;
+    static bool fadeSky;
+    static bool fadeCloud;
+    static float fadeTime;
 
-  int              p[MAXB + MAXB + 2];
-  double           g3[MAXB + MAXB + 2][3];
-  double           g2[MAXB + MAXB + 2][2];
-  double           g1[MAXB + MAXB + 2];
+    // SHADER STUFF
+    Shader*          shader;
+    Shader::Uniform* offset;
+    Shader::Uniform* skycolor;
+    Shader::Uniform* cloudcolor;
+    float            offsetZ;
+    float            scale;
+    float            planetRadius;
+    float            atmosphericRadius;
+    int              divs;
 
-  int              start;
-  int              B;
-  int              BM;
+    // 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;
+
+    static bool      flashSkyActivate;
+    static float     localTimer;
+    static float     flashTime;
+
 };
 
Index: /branches/mountain_lake/src/lib/graphics/effects/lightning_effect.cc
===================================================================
--- /branches/mountain_lake/src/lib/graphics/effects/lightning_effect.cc	(revision 8910)
+++ /branches/mountain_lake/src/lib/graphics/effects/lightning_effect.cc	(revision 8911)
@@ -28,4 +28,5 @@
 #include "shell_command.h"
 #include "light.h"
+#include "cloud_effect.h"
 
 SHELL_COMMAND(activate, LightningEffect, activateLightning);
@@ -198,4 +199,6 @@
         this->flashLight->setSpecularColor(1,1,1);
 
+        CloudEffect::flashSky(0.02);
+
         // Play thunder sound
         this->soundSource.play(this->thunderBuffer);
@@ -216,7 +219,9 @@
     if( this->thunderBolt[3]->isVisible() && this->time > this->flashHoldTime) {
         this->thunderBolt[3]->setVisibiliy(false);
+
         this->time = 0.0f;
         this->flashLight->setDiffuseColor(0,0,0);
         this->flashLight->setSpecularColor(0,0,0);
+        CloudEffect::changeSkyColor(Vector(0,0,1), 0.02);
 
         this->newCoordinates();
Index: /branches/mountain_lake/src/lib/graphics/effects/lightning_effect.h
===================================================================
--- /branches/mountain_lake/src/lib/graphics/effects/lightning_effect.h	(revision 8910)
+++ /branches/mountain_lake/src/lib/graphics/effects/lightning_effect.h	(revision 8911)
@@ -103,4 +103,5 @@
     float mainPosZ;
 
+    Vector origSkyColor;
     Vector cameraCoor;
 
