Index: /code/branches/presentation2/data/levels/templates/spaceship_assff.oxt
===================================================================
--- /code/branches/presentation2/data/levels/templates/spaceship_assff.oxt	(revision 6186)
+++ /code/branches/presentation2/data/levels/templates/spaceship_assff.oxt	(revision 6187)
@@ -70,5 +70,8 @@
    accelerationupdown    =  125
   >
-    <active>
+    <EffectContainer condition="idle">
+      <WorldSound mainstate="activity" source="sounds/Engine_idle.ogg" loop=1 active=false/>
+    </EffectContainer>
+    <EffectContainer condition="not idle">
       <FadingBillboard mainstate=activity active=false scale=0.1 position="0, 0, 9" colour="0.2, 0.65, 1.0, 1.0" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
 <!--
@@ -76,22 +79,23 @@
       <Light mainstate=visibility position="-8, 0, 8" diffuse="0.3, 0.6, 1.0" specular="0.3, 0.6, 1.0" attenuation="600, 1.0, 0.007, 0.0002" type=point />
 -->
-      <!--WorldSound mainstate=activity source="sounds/Engine_low.ogg" loop=1 /-->
-    </active>
-    <forward>
+    </EffectContainer>
+    <EffectContainer condition="normal or brake">
+      <WorldSound mainstate="activity" source="sounds/Engine_low.ogg" loop=1 active=false/>
+    </EffectContainer>
+    <EffectContainer condition="normal or boost">
       <Backlight mainstate=activity active=false scale=0.4 name=bltest position=" 7.6, 0, 6" colour="0.2, 0.65, 1.0, 1.0" width=15 length=1500 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
       <Backlight mainstate=activity active=false scale=0.4 name=bltest position="-7.6, 0, 6" colour="0.2, 0.65, 1.0, 1.0" width=15 length=1500 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
-      <WorldSound mainstate=activity source="sounds/Engine_low.ogg" loop=1 />
-    </forward>
-    <boost>
+    </EffectContainer>
+    <EffectContainer condition="boost">
       <Backlight mainstate=activity active=false scale=0.4 name=bltest position=" 7.6, 0, 6" colour="0.6, 0.75, 0.8, 0.7" width=40 length=1000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
       <Backlight mainstate=activity active=false scale=0.4 name=bltest position="-7.6, 0, 6" colour="0.6, 0.75, 0.8, 0.7" width=40 length=1000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
-      <!--WorldSound mainstate=activity source="sounds/Engine_high.ogg" loop=1 /-->
-    </boost>
-    <brake>
+      <WorldSound mainstate="activity" source="sounds/Engine_high.ogg" loop=1 active=false/>
+    </EffectContainer>
+    <EffectContainer condition="brake">
       <FadingBillboard mainstate=activity active=false scale=0.3 position=" 8, 0, 6" colour="0.5, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
       <FadingBillboard mainstate=activity active=false scale=0.3 position="-8, 0, 6" colour="0.5, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
       <FadingBillboard mainstate=activity active=false scale=0.15 position=" 8, 0, 6" colour="1.0, 0.0, 0.0, 1.0" material="Flares/backlightflare" turnontime=0.5 turnofftime=0.5 />
       <FadingBillboard mainstate=activity active=false scale=0.15 position="-8, 0, 6" colour="1.0, 0.0, 0.0, 1.0" material="Flares/backlightflare" turnontime=0.5 turnofftime=0.5 />
-    </brake>
+    </EffectContainer>
   </MultiStateEngine>
 </Template>
Index: /code/branches/presentation2/src/orxonox/items/MultiStateEngine.cc
===================================================================
--- /code/branches/presentation2/src/orxonox/items/MultiStateEngine.cc	(revision 6186)
+++ /code/branches/presentation2/src/orxonox/items/MultiStateEngine.cc	(revision 6187)
@@ -22,4 +22,5 @@
  *   Author:
  *      Fabian 'x3n' Landau
+ *      Reto Grieder
  *   Co-authors:
  *      ...
@@ -29,7 +30,14 @@
 #include "MultiStateEngine.h"
 
+extern "C" {
+#include <lua.h>
+}
+
+#include "util/Convert.h"
 #include "core/CoreIncludes.h"
 #include "core/GameMode.h"
+#include "core/LuaState.h"
 #include "core/XMLPort.h"
+#include "worldentities/EffectContainer.h"
 #include "worldentities/pawns/SpaceShip.h"
 
@@ -37,9 +45,4 @@
 {
     static const float FORWARD_EFFECT_VELOCITY_THRESHOLD = 20;
-
-    static const unsigned char STATE_ACTIVE  = 1;
-    static const unsigned char STATE_FORWARD = 2;
-    static const unsigned char STATE_BOOST   = 4;
-    static const unsigned char STATE_BRAKE   = 8;
 
     CreateFactory(MultiStateEngine);
@@ -49,4 +52,5 @@
         RegisterObject(MultiStateEngine);
 
+        this->lua_ = new LuaState();
         this->state_ = 0;
 
@@ -59,12 +63,8 @@
         {
             // We have no ship, so the effects are not attached and won't be destroyed automatically
-            for (std::list<WorldEntity*>::const_iterator it = this->activeEffects_.begin(); it != this->activeEffects_.end(); ++it)
-                (*it)->destroy();
-            for (std::list<WorldEntity*>::const_iterator it = this->forwardEffects_.begin(); it != this->forwardEffects_.end(); ++it)
-                (*it)->destroy();
-            for (std::list<WorldEntity*>::const_iterator it = this->boostEffects_.begin(); it != this->boostEffects_.end(); ++it)
-                (*it)->destroy();
-            for (std::list<WorldEntity*>::const_iterator it = this->brakeEffects_.begin(); it != this->brakeEffects_.end(); ++it)
-                (*it)->destroy();
+            for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
+                for (std::vector<WorldEntity*>::const_iterator it2 = (*it)->getEffectsBegin(); it2 != (*it)->getEffectsBegin(); ++it2)
+                    (*it2)->destroy();
+            delete this->lua_;
         }
     }
@@ -73,9 +73,5 @@
     {
         SUPER(MultiStateEngine, XMLPort, xmlelement, mode);
-
-        XMLPortObject(MultiStateEngine, WorldEntity, "active",  addActiveEffect,  getActiveEffect,  xmlelement, mode);
-        XMLPortObject(MultiStateEngine, WorldEntity, "forward", addForwardEffect, getForwardEffect, xmlelement, mode);
-        XMLPortObject(MultiStateEngine, WorldEntity, "boost",   addBoostEffect,   getBoostEffect,   xmlelement, mode);
-        XMLPortObject(MultiStateEngine, WorldEntity, "brake",   addBrakeEffect,   getBrakeEffect,   xmlelement, mode);
+        XMLPortObject(MultiStateEngine, EffectContainer, "",  addEffectContainer,  getEffectContainer,  xmlelement, mode);
     }
 
@@ -97,39 +93,49 @@
 
                 bool forward = (direction.z < 0 && velocity.z < -FORWARD_EFFECT_VELOCITY_THRESHOLD);
-                bool boost = (this->getShip()->getBoost() && forward);
-                bool brake = (direction.z > 0 && velocity.z < 0);
-                bool active = (direction != Vector3::ZERO && !brake);
 
-                if (active)
-                    this->state_ |= STATE_ACTIVE;
+                int newState = 0;
+                if (this->getShip()->getBoost() && forward)
+                    newState = Boost;
+                else if (forward && !newState) // newState == Boost
+                    newState = Normal;
+                else if (direction.z > 0 && velocity.z < 0)
+                    newState = Brake;
                 else
-                    this->state_ &= ~STATE_ACTIVE;
+                    newState = Idle;
 
-                if (forward)
-                    this->state_ |= STATE_FORWARD;
-                else
-                    this->state_ &= ~STATE_FORWARD;
+                if (newState != this->state_)
+                {
+                    int changes = newState | this->state_;
+                    if (changes & Idle)
+                    {
+                        lua_pushboolean(this->lua_->getInternalLuaState(), newState & Idle);
+                        lua_setglobal(this->lua_->getInternalLuaState(), "idle");
+                    }
+                    if (changes & Normal)
+                    {
+                        lua_pushboolean(this->lua_->getInternalLuaState(), newState & Normal);
+                        lua_setglobal(this->lua_->getInternalLuaState(), "normal");
+                    }
+                    if (changes & Brake)
+                    {
+                        lua_pushboolean(this->lua_->getInternalLuaState(), newState & Brake);
+                        lua_setglobal(this->lua_->getInternalLuaState(), "brake");
+                    }
+                    if (changes & Boost)
+                    {
+                        lua_pushboolean(this->lua_->getInternalLuaState(), newState & Boost);
+                        lua_setglobal(this->lua_->getInternalLuaState(), "boost");
+                    }
 
-                if (boost)
-                    this->state_ |= STATE_BOOST;
-                else
-                    this->state_ &= ~STATE_BOOST;
+                    // Update all effect conditions
+                    for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
+                        (*it)->updateCondition();
 
-                if (brake)
-                    this->state_ |= STATE_BRAKE;
-                else
-                    this->state_ &= ~STATE_BRAKE;
+                    this->state_ = newState;
+                }
             }
 
             if (GameMode::isMaster())
             {
-                for (std::list<WorldEntity*>::const_iterator it = this->activeEffects_.begin(); it != this->activeEffects_.end(); ++it)
-                    (*it)->setMainState(this->state_ & STATE_ACTIVE);
-                for (std::list<WorldEntity*>::const_iterator it = this->forwardEffects_.begin(); it != this->forwardEffects_.end(); ++it)
-                    (*it)->setMainState(this->state_ & STATE_FORWARD);
-                for (std::list<WorldEntity*>::const_iterator it = this->boostEffects_.begin(); it != this->boostEffects_.end(); ++it)
-                    (*it)->setMainState(this->state_ & STATE_BOOST);
-                for (std::list<WorldEntity*>::const_iterator it = this->brakeEffects_.begin(); it != this->brakeEffects_.end(); ++it)
-                    (*it)->setMainState(this->state_ & STATE_BRAKE);
             }
         }
@@ -145,88 +151,31 @@
             return;
 
-        for (std::list<WorldEntity*>::const_iterator it = this->activeEffects_.begin(); it != this->activeEffects_.end(); ++it)
-            ship->attach(*it);
-        for (std::list<WorldEntity*>::const_iterator it = this->forwardEffects_.begin(); it != this->forwardEffects_.end(); ++it)
-            ship->attach(*it);
-        for (std::list<WorldEntity*>::const_iterator it = this->boostEffects_.begin(); it != this->boostEffects_.end(); ++it)
-            ship->attach(*it);
-        for (std::list<WorldEntity*>::const_iterator it = this->brakeEffects_.begin(); it != this->brakeEffects_.end(); ++it)
-            ship->attach(*it);
+        for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
+            for (std::vector<WorldEntity*>::const_iterator it2 = (*it)->getEffectsBegin(); it2 != (*it)->getEffectsEnd(); ++it2)
+                this->getShip()->attach(*it2);
     }
 
-    void MultiStateEngine::addActiveEffect(WorldEntity* effect)
+    void MultiStateEngine::addEffectContainer(EffectContainer* effect)
     {
-        this->activeEffects_.push_back(effect);
+        if (effect == NULL)
+            return;
+        effect->setLuaState(this->lua_, "f" + multi_cast<std::string>(this->effectContainers_.size()));
+        this->effectContainers_.push_back(effect);
         if (this->getShip())
-            this->getShip()->attach(effect);
+        {
+            for (std::vector<WorldEntity*>::const_iterator it = effect->getEffectsBegin(); it != effect->getEffectsBegin(); ++it)
+                this->getShip()->attach(*it);
+        }
     }
 
-    void MultiStateEngine::addForwardEffect(WorldEntity* effect)
-    {
-        this->forwardEffects_.push_back(effect);
-        if (this->getShip())
-            this->getShip()->attach(effect);
-    }
-
-    void MultiStateEngine::addBoostEffect(WorldEntity* effect)
-    {
-        this->boostEffects_.push_back(effect);
-        if (this->getShip())
-            this->getShip()->attach(effect);
-    }
-
-    void MultiStateEngine::addBrakeEffect(WorldEntity* effect)
-    {
-        this->brakeEffects_.push_back(effect);
-        if (this->getShip())
-            this->getShip()->attach(effect);
-    }
-
-    WorldEntity* MultiStateEngine::getActiveEffect(unsigned int index) const
+    EffectContainer* MultiStateEngine::getEffectContainer(unsigned int index) const
     {
         unsigned int i = 0;
-        for (std::list<WorldEntity*>::const_iterator it = this->activeEffects_.begin(); it != this->activeEffects_.end(); ++it)
+        for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
         {
             if (i == index)
                 return (*it);
-            ++i;
         }
-        return 0;
-    }
-
-    WorldEntity* MultiStateEngine::getForwardEffect(unsigned int index) const
-    {
-        unsigned int i = 0;
-        for (std::list<WorldEntity*>::const_iterator it = this->forwardEffects_.begin(); it != this->forwardEffects_.end(); ++it)
-        {
-            if (i == index)
-                return (*it);
-            ++i;
-        }
-        return 0;
-    }
-
-    WorldEntity* MultiStateEngine::getBoostEffect(unsigned int index) const
-    {
-        unsigned int i = 0;
-        for (std::list<WorldEntity*>::const_iterator it = this->boostEffects_.begin(); it != this->boostEffects_.end(); ++it)
-        {
-            if (i == index)
-                return (*it);
-            ++i;
-        }
-        return 0;
-    }
-
-    WorldEntity* MultiStateEngine::getBrakeEffect(unsigned int index) const
-    {
-        unsigned int i = 0;
-        for (std::list<WorldEntity*>::const_iterator it = this->brakeEffects_.begin(); it != this->brakeEffects_.end(); ++it)
-        {
-            if (i == index)
-                return (*it);
-            ++i;
-        }
-        return 0;
+        return NULL;
     }
 }
Index: /code/branches/presentation2/src/orxonox/items/MultiStateEngine.h
===================================================================
--- /code/branches/presentation2/src/orxonox/items/MultiStateEngine.h	(revision 6186)
+++ /code/branches/presentation2/src/orxonox/items/MultiStateEngine.h	(revision 6187)
@@ -22,4 +22,5 @@
  *   Author:
  *      Fabian 'x3n' Landau
+ *      Reto Grieder
  *   Co-authors:
  *      ...
@@ -32,12 +33,23 @@
 #include "OrxonoxPrereqs.h"
 
-#include <list>
+#include <vector>
 #include "Engine.h"
 
 namespace orxonox
 {
+    // forward declaration
+    class EffectContainer;
+
     class _OrxonoxExport MultiStateEngine : public Engine
     {
         public:
+            enum EngineState
+            {
+                Idle    = 1,
+                Normal  = 2,
+                Brake   = 4,
+                Boost   = 8
+            };
+
             MultiStateEngine(BaseObject* creator);
             virtual ~MultiStateEngine();
@@ -50,20 +62,11 @@
             virtual void addToSpaceShip(SpaceShip* ship);
 
-            void addActiveEffect(WorldEntity* effect);
-            void addForwardEffect(WorldEntity* effect);
-            void addBoostEffect(WorldEntity* effect);
-            void addBrakeEffect(WorldEntity* effect);
-
-            WorldEntity* getActiveEffect(unsigned int index) const;
-            WorldEntity* getForwardEffect(unsigned int index) const;
-            WorldEntity* getBoostEffect(unsigned int index) const;
-            WorldEntity* getBrakeEffect(unsigned int index) const;
+            void addEffectContainer(EffectContainer* effect);
+            EffectContainer* getEffectContainer(unsigned int index) const;
 
         private:
-            unsigned char state_;
-            std::list<WorldEntity*> activeEffects_;
-            std::list<WorldEntity*> forwardEffects_;
-            std::list<WorldEntity*> boostEffects_;
-            std::list<WorldEntity*> brakeEffects_;
+            int state_;
+            LuaState* lua_;
+            std::vector<EffectContainer*> effectContainers_;
     };
 }
Index: /code/branches/presentation2/src/orxonox/worldentities/CMakeLists.txt
===================================================================
--- /code/branches/presentation2/src/orxonox/worldentities/CMakeLists.txt	(revision 6186)
+++ /code/branches/presentation2/src/orxonox/worldentities/CMakeLists.txt	(revision 6187)
@@ -7,4 +7,5 @@
 
   BigExplosion.cc
+  EffectContainer.cc
   ExplosionChunk.cc
   CameraPosition.cc
Index: /code/branches/presentation2/src/orxonox/worldentities/EffectContainer.cc
===================================================================
--- /code/branches/presentation2/src/orxonox/worldentities/EffectContainer.cc	(revision 6187)
+++ /code/branches/presentation2/src/orxonox/worldentities/EffectContainer.cc	(revision 6187)
@@ -0,0 +1,110 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "EffectContainer.h"
+
+extern "C" {
+#include <lua.h>
+}
+
+#include "core/CoreIncludes.h"
+#include "core/LuaState.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(EffectContainer);
+
+    EffectContainer::EffectContainer(BaseObject* creator)
+        : StaticEntity(creator)
+        , lua_(NULL)
+    {
+        RegisterObject(EffectContainer);
+    }
+
+    EffectContainer::~EffectContainer()
+    {
+    }
+
+    void EffectContainer::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(EffectContainer, XMLPort, xmlelement, mode);
+        XMLPortParam(EffectContainer, "condition", setCondition, getCondition, xmlelement, mode);
+        XMLPortObject(EffectContainer, WorldEntity, "", addEffect, getEffect, xmlelement, mode);
+    }
+
+    void EffectContainer::setCondition(const std::string& condition)
+    {
+        // TODO: Watch out for code injection!
+        this->condition_ = condition;
+        if (this->lua_)
+        {
+            this->lua_->doString(
+                this->functionName_ + " = function() \n"
+                "    return (" + condition + ") \n"
+                "end"
+            );
+        }
+    }
+
+    void EffectContainer::setLuaState(LuaState* state, const std::string& functionName)
+    {
+        this->functionName_ = functionName;
+        this->lua_ = state;
+        this->setCondition(this->condition_);
+    }
+
+    void EffectContainer::addEffect(WorldEntity* effect)
+    {
+        this->effects_.push_back(effect);
+    }
+
+    WorldEntity* EffectContainer::getEffect(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::vector<WorldEntity*>::const_iterator it = this->effects_.begin(); it != this->effects_.end(); ++it)
+            if (i == index)
+                return (*it);
+        return NULL;
+    }
+
+    void EffectContainer::updateCondition()
+    {
+        if (this->lua_)
+        {
+            lua_getglobal(this->lua_->getInternalLuaState(), this->functionName_.c_str());
+            lua_call(this->lua_->getInternalLuaState(), 0, 1);
+            bool result = (bool)lua_toboolean(this->lua_->getInternalLuaState(), -1);
+            lua_pop(this->lua_->getInternalLuaState(), 1);
+            for (std::vector<WorldEntity*>::const_iterator it = this->effects_.begin(); it != this->effects_.end(); ++it)
+            {
+                (*it)->setMainState(result);
+            }
+        }
+    }
+}
Index: /code/branches/presentation2/src/orxonox/worldentities/EffectContainer.h
===================================================================
--- /code/branches/presentation2/src/orxonox/worldentities/EffectContainer.h	(revision 6187)
+++ /code/branches/presentation2/src/orxonox/worldentities/EffectContainer.h	(revision 6187)
@@ -0,0 +1,71 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _EffectContainer_H__
+#define _EffectContainer_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <vector>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport EffectContainer : public BaseObject
+    {
+        public:
+            EffectContainer(BaseObject* creator);
+            virtual ~EffectContainer();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            void setLuaState(LuaState* state, const std::string& functionName);
+
+            void setCondition(const std::string& condition);
+            inline const std::string& getCondition() const
+                { return this->condition_; }
+
+            void addEffect(WorldEntity* effect);
+            WorldEntity* getEffect(unsigned int index) const;
+
+            inline std::vector<WorldEntity*>::const_iterator getEffectsBegin()
+                { return this->effects_.begin(); }
+            inline std::vector<WorldEntity*>::const_iterator getEffectsEnd()
+                { return this->effects_.end(); }
+
+            void updateCondition();
+
+        private:
+            std::string               condition_;
+            std::string               functionName_;
+            LuaState*                 lua_;
+            std::vector<WorldEntity*> effects_;
+    };
+}
+
+#endif /* _EffectContainer_H__ */
