Index: code/trunk/src/modules/objects/triggers/CMakeLists.txt
===================================================================
--- code/trunk/src/modules/objects/triggers/CMakeLists.txt	(revision 6417)
+++ code/trunk/src/modules/objects/triggers/CMakeLists.txt	(revision 6800)
@@ -1,6 +1,9 @@
 ADD_SOURCE_FILES(OBJECTS_SRC_FILES
-  Trigger.cc
+  CheckPoint.cc
+  DistanceMultiTrigger.cc
   DistanceTrigger.cc
   EventTrigger.cc
-  CheckPoint.cc
+  MultiTrigger.cc
+  MultiTriggerContainer.cc
+  Trigger.cc
 )
Index: code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc
===================================================================
--- code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc	(revision 6800)
+++ code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc	(revision 6800)
@@ -0,0 +1,109 @@
+/*
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+#include "DistanceMultiTrigger.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    
+    CreateFactory(DistanceMultiTrigger);
+    
+    DistanceMultiTrigger::DistanceMultiTrigger(BaseObject* creator) : MultiTrigger(creator)
+    {
+        RegisterObject(DistanceMultiTrigger);
+        
+        this->distance_ = 100.0f;
+    }
+    
+    DistanceMultiTrigger::~DistanceMultiTrigger()
+    {
+        
+    }
+    
+    void DistanceMultiTrigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(DistanceMultiTrigger, XMLPort, xmlelement, mode);
+
+        XMLPortParam(DistanceMultiTrigger, "distance", setDistance, getDistance, xmlelement, mode).defaultValues(100.0f);
+    }
+    
+    std::queue<MultiTriggerState*>* DistanceMultiTrigger::letTrigger(void)
+    {
+        ClassTreeMask targetMask = this->getTargetMask();
+        
+        std::queue<MultiTriggerState*>* queue = NULL;
+        // Check for new objects that are in range
+        for(ClassTreeMaskObjectIterator it = targetMask.begin(); it != targetMask.end(); ++it)
+        {
+            WorldEntity* entity = orxonox_cast<WorldEntity*>(*it);
+            if (entity == NULL || this->inRange(entity)) //If the object is no WorldEntity or is already in range.
+                continue;
+
+            Vector3 distanceVec = entity->getWorldPosition() - this->getWorldPosition();
+            if (distanceVec.length() < this->distance_)
+            {
+                if(!this->addToRange(entity))
+                    continue;
+                
+                if(queue == NULL)
+                {
+                    queue = new std::queue<MultiTriggerState*>();
+                }
+                MultiTriggerState* state = new MultiTriggerState;
+                state->bTriggered = true;
+                state->originator = entity;
+                queue->push(state);
+            }
+        }
+        
+        for(std::set<WorldEntity*>::iterator it = this->range_.begin(); it != this->range_.end(); it++)
+        {
+            Vector3 distanceVec = (*it)->getWorldPosition() - this->getWorldPosition();
+            if (distanceVec.length() >= this->distance_)
+            {
+                if(!this->removeFromRange(*it))
+                    continue;
+                
+                if(queue == NULL)
+                {
+                    queue = new std::queue<MultiTriggerState*>();
+                }
+                MultiTriggerState* state = new MultiTriggerState;
+                state->bTriggered = false;
+                state->originator = *it;
+                queue->push(state);
+            }
+        }
+        
+        return queue;
+    }
+    
+}
Index: code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.h
===================================================================
--- code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.h	(revision 6800)
+++ code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.h	(revision 6800)
@@ -0,0 +1,74 @@
+/*
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+#ifndef _DistanceMultiTrigger_H__
+#define _DistanceMultiTrigger_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include "worldentities/WorldEntity.h"
+#include <set>
+
+#include "MultiTrigger.h"
+
+namespace orxonox
+{
+
+    class _ObjectsExport DistanceMultiTrigger : public MultiTrigger
+    {
+        
+        public:
+            DistanceMultiTrigger(BaseObject* creator);
+            ~DistanceMultiTrigger();
+            
+            void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            
+            inline void setDistance(float distance)
+                { this->distance_ = distance; }
+            inline float getDistance() const
+                { return this->distance_; }
+                
+        protected:
+            virtual std::queue<MultiTriggerState*>* letTrigger(void);
+            
+            inline bool inRange(WorldEntity* entity)
+                { return this->range_.find(entity) != this->range_.end(); }
+            bool addToRange(WorldEntity* entity)
+                { std::pair<std::set<WorldEntity*>::iterator, bool> pair = this->range_.insert(entity); return pair.second; }
+            bool removeFromRange(WorldEntity* entity)
+                { return this->range_.erase(entity) > 0; }
+                
+        private:
+            float distance_;
+            std::set<WorldEntity*> range_;
+        
+    };
+    
+}
+
+#endif // _DistanceMultiTrigger_H__
Index: code/trunk/src/modules/objects/triggers/MultiTrigger.cc
===================================================================
--- code/trunk/src/modules/objects/triggers/MultiTrigger.cc	(revision 6800)
+++ code/trunk/src/modules/objects/triggers/MultiTrigger.cc	(revision 6800)
@@ -0,0 +1,412 @@
+/*
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      Benjamin Knecht
+ *
+*/
+
+#include "MultiTrigger.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+#include "MultiTriggerContainer.h"
+
+namespace orxonox
+{
+    
+    /*static*/ const int MultiTrigger::INF_s = -1;
+    /*static*/ const std::string MultiTrigger::or_s = "or";
+    /*static*/ const std::string MultiTrigger::and_s = "and";
+    /*static*/ const std::string MultiTrigger::xor_s = "xor";
+    
+    CreateFactory(MultiTrigger);
+    
+    //TODO: Clean up.
+    MultiTrigger::MultiTrigger(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(MultiTrigger);
+        
+        this->mode_ = MultiTriggerMode::EventTriggerAND;
+
+        this->bFirstTick_ = true;
+
+        this->bInvertMode_ = false;
+        this->bSwitch_ = false;
+        this->bStayActive_ = false;
+        this->delay_ = 0.0f;
+        this->remainingActivations_ = INF_s;
+        this->maxNumSimultaniousTriggerers_ = INF_s;
+        
+        this->targetMask_.exclude(Class(BaseObject));
+
+        this->setSyncMode(0x0);
+        
+    }
+    
+    //TODO: Document
+    MultiTrigger::~MultiTrigger()
+    {
+        COUT(4) << "Destorying MultiTrigger &" << this << ". " << this->stateQueue_.size() << " states still in queue. Deleting." << std::endl;
+        while(this->stateQueue_.size() > 0)
+        {
+            MultiTriggerState* state = this->stateQueue_.front().second;
+            this->stateQueue_.pop_front();
+            delete state;
+        }
+    }
+    
+    //TODO: Clean up?
+    void MultiTrigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(MultiTrigger, XMLPort, xmlelement, mode);
+
+        XMLPortParam(MultiTrigger, "delay", setDelay, getDelay, xmlelement, mode).defaultValues(0.0f);
+        XMLPortParam(MultiTrigger, "switch", setSwitch, getSwitch, xmlelement, mode).defaultValues(false);
+        XMLPortParam(MultiTrigger, "stayactive", setStayActive, getStayActive, xmlelement, mode).defaultValues(false);
+        XMLPortParam(MultiTrigger, "activations", setActivations, getActivations, xmlelement, mode).defaultValues(INF_s);
+        XMLPortParam(MultiTrigger, "invert", setInvert, getInvert, xmlelement, mode).defaultValues(false);
+        XMLPortParam(MultiTrigger, "simultaniousTriggerers", setSimultaniousTriggerers, getSimultaniousTriggerers, xmlelement, mode).defaultValues(INF_s);
+        XMLPortParamTemplate(MultiTrigger, "mode", setMode, getModeString, xmlelement, mode, const std::string&).defaultValues(MultiTrigger::and_s);
+        XMLPortParamLoadOnly(MultiTrigger, "target", addTargets, xmlelement, mode).defaultValues("ControllableEntity"); //TODO: Remove load only
+
+        XMLPortObject(MultiTrigger, MultiTrigger, "", addTrigger, getTrigger, xmlelement, mode);
+        
+        COUT(4) << "MultiTrigger &" << this << " created." << std::endl;
+    }
+    
+    //TODO: Document
+    void MultiTrigger::tick(float dt)
+    {
+        if(this->bFirstTick_) // If this is the first tick.
+        {
+            this->bFirstTick_ = false;
+            this->fire(false); //TODO: Does this work? Resp. Is it correct?
+        }
+
+        // Check if the object is active (this is NOT Trigger::isActive()!)
+        if (!this->BaseObject::isActive())
+            return;
+
+        SUPER(MultiTrigger, tick, dt);
+        
+        std::queue<MultiTriggerState*>* queue  = this->letTrigger();
+        if(queue != NULL)
+            COUT(4) << "MultiTrigger &" << this << ": " << queue->size() << " new states to state queue." << std::endl;
+        while(queue != NULL && queue->size() > 0)
+        {
+            //TODO: Be more efficient, Don't delete a state and create a new one immediately after that. Reuse!
+            MultiTriggerState* state = queue->front();
+            this->addState(state->bTriggered & this->isModeTriggered(state->originator), state->originator);
+            queue->pop();
+            delete state;
+        }
+        delete queue;
+
+        if (this->stateQueue_.size() > 0)
+        {
+            MultiTriggerState* state;
+            float timeRemaining;
+            for(int size = this->stateQueue_.size(); size >= 1; size--)
+            {
+                timeRemaining = this->stateQueue_.front().first;
+                state = this->stateQueue_.front().second;
+                if(timeRemaining <= dt)
+                {
+                    if(this->maxNumSimultaniousTriggerers_ == INF_s || this->triggered_.size() < (unsigned int)this->maxNumSimultaniousTriggerers_)
+                    {
+                        // Add the originator to the objects triggering this MultiTrigger.
+                        if(state->bTriggered == true)
+                        {
+                            this->triggered_.insert(state->originator);
+                        }
+                        // Remove the originator from the objects triggering this MultiTrigger.
+                        else
+                        {
+                            this->triggered_.erase(state->originator);
+                        }
+                        
+                        // Add the originator to the objects activating this MultiTrigger.
+                        if(state->bActive == true)
+                        {
+                            this->active_.insert(state->originator);
+                        }
+                        // Remove the originator from the objects activating this MultiTrigger.
+                        else
+                        {
+                            this->active_.erase(state->originator);
+                        }
+                        
+                        // Fire the event.
+                        this->fire(state->bActive, state->originator);
+                    }
+                    
+                    // Remove the state from the state queue.
+                    this->stateQueue_.pop_front();
+                    COUT(4) << "MultiTrigger &" << this << ": State processed, removing from state queue. originator: " << state->originator->getIdentifier()->getName() << " (&" << state->originator << "), active: " << state->bActive << "|" << this->isActive(state->originator) << ", triggered: " << state->bTriggered << "|" << this->isTriggered(state->originator) << "." << std::endl;
+                    delete state;
+                    size -= 1;
+                }
+                else
+                {
+                    this->stateQueue_.push_back(std::pair<float, MultiTriggerState*>(timeRemaining-dt, state));
+                    this->stateQueue_.pop_front();
+                    COUT(4) << "MultiTrigger &" << this << ": State processed, decreasing time remaining. originator: " << state->originator->getIdentifier()->getName() << " (&" << state->originator << "), active: " << state->bActive << ", triggered: " << state->bTriggered << ", time remaining: " << timeRemaining-dt << "." << std::endl;
+                }
+            }
+        }
+    }
+
+    //TODO: Document
+    bool MultiTrigger::isModeTriggered(BaseObject* triggerer)
+    {
+        if (this->children_.size() != 0)
+        {
+            bool returnVal = false;
+
+            switch (this->mode_)
+            {
+                case MultiTriggerMode::EventTriggerAND:
+                    returnVal = checkAnd(triggerer);
+                    break;
+                case MultiTriggerMode::EventTriggerOR:
+                    returnVal = checkOr(triggerer);
+                    break;
+                case MultiTriggerMode::EventTriggerXOR:
+                    returnVal = checkXor(triggerer);
+                    break;
+                default:
+                    returnVal = false;
+                    break;
+            }
+
+            return returnVal;
+        }
+        
+        return true;
+    }
+    
+    //TODO: Document
+    std::queue<MultiTriggerState*>* MultiTrigger::letTrigger(void)
+    {
+        std::queue<MultiTriggerState*>* queue = new std::queue<MultiTriggerState*>();
+        MultiTriggerState* state = new MultiTriggerState;
+        state->bTriggered = true;
+        state->originator = NULL;
+        queue->push(state);
+        return queue;
+    }
+    
+    //TODO: Document
+    bool MultiTrigger::isTriggered(BaseObject* triggerer)
+    {
+        std::set<BaseObject*>::iterator it = this->triggered_.find(triggerer);
+        if(it == this->triggered_.end())
+            return false;
+        return true;
+    }
+
+    //TODO: Document
+    bool MultiTrigger::checkAnd(BaseObject* triggerer)
+    {
+        std::set<MultiTrigger*>::iterator it;
+        for(it = this->children_.begin(); it != this->children_.end(); ++it)
+        {
+            if (!(*it)->isActive(triggerer))
+                return false;
+        }
+        return true;
+    }
+
+    //TODO: Document
+    bool MultiTrigger::checkOr(BaseObject* triggerer)
+    {
+        std::set<MultiTrigger*>::iterator it;
+        for(it = this->children_.begin(); it != this->children_.end(); ++it)
+        {
+            if ((*it)->isActive(triggerer))
+                return true;
+        }
+        return false;
+    }
+
+    //TODO: Document
+    bool MultiTrigger::checkXor(BaseObject* triggerer)
+    {
+        std::set<MultiTrigger*>::iterator it;
+        bool test = false;
+        for(it = this->children_.begin(); it != this->children_.end(); ++it)
+        {
+            if (test && (*it)->isActive(triggerer))
+                return false;
+            if ((*it)->isActive(triggerer))
+                test = true;
+        }
+        return test;
+    }
+    
+    //TODO: Document
+    bool MultiTrigger::addState(bool bTriggered, BaseObject* originator)
+    {
+        if(!this->isTarget(originator))
+            return false;
+        
+        bTriggered ^= this->bInvertMode_;
+        // If the state doesn't change.
+        if(this->isTriggered() && bTriggered)
+            return false;
+        
+        bool bActive = !this->isActive(originator);
+        
+        // If the MultiTrigger is in switch mode.
+        if(this->bSwitch_ && !bTriggered)
+            return false;
+        
+        // If the state changes to active.
+        if(this->remainingActivations_ != INF_s && bActive)
+        {
+            if(this->remainingActivations_ == 0)
+                return false;
+            this->remainingActivations_--;
+        }
+        else
+        {
+            // If the MultiTrigger should stay active and there are no more remaining activations.
+            if(this->bStayActive_ && this->remainingActivations_ == 0)
+                return false;
+        }
+        
+        COUT(4) << "MultiTrigger &" << this << ": State added to state queue. originator: " << originator->getIdentifier()->getName() << " (&" << originator << "), active: " << bActive << "|" << this->isActive(originator) << ", triggered: " << bTriggered << "|" << this->isTriggered(originator) <<  "." << std::endl;
+        
+        // Create state.
+        MultiTriggerState* state = new MultiTriggerState;
+        state->bActive = bActive;
+        state->bTriggered = bTriggered;
+        state->originator = originator;
+        this->stateQueue_.push_back(std::pair<float, MultiTriggerState*>(this->delay_, state));
+        
+        return true;
+    }
+
+    //TODO: Document
+    void MultiTrigger::setMode(const std::string& modeName)
+    {
+        if (modeName == MultiTrigger::and_s)
+            this->setMode(MultiTriggerMode::EventTriggerAND);
+        else if (modeName == MultiTrigger::or_s)
+            this->setMode(MultiTriggerMode::EventTriggerOR);
+        else if (modeName == MultiTrigger::xor_s)
+            this->setMode(MultiTriggerMode::EventTriggerXOR);
+    }
+
+    //TODO: Document
+    const std::string& MultiTrigger::getModeString() const
+    {
+        if (this->mode_ == MultiTriggerMode::EventTriggerAND)
+            return MultiTrigger::and_s;
+        else if (this->mode_ == MultiTriggerMode::EventTriggerOR)
+            return MultiTrigger::or_s;
+        else if (this->mode_ == MultiTriggerMode::EventTriggerXOR)
+            return MultiTrigger::xor_s;
+        else
+            return MultiTrigger::and_s;
+    }
+    
+    //TODO: Document
+    bool MultiTrigger::isActive(BaseObject* triggerer)
+    {
+        std::set<BaseObject*>::iterator it = this->active_.find(triggerer);
+        if(it == this->active_.end())
+            return false;
+        return true;
+    }
+
+    //TODO: Document
+    void MultiTrigger::addTrigger(MultiTrigger* trigger)
+    {
+        if (this != trigger && trigger != NULL)
+            this->children_.insert(trigger);
+    }
+
+    //TODO: Document
+    const MultiTrigger* MultiTrigger::getTrigger(unsigned int index) const
+    {
+        if (this->children_.size() <= index)
+            return NULL;
+
+        std::set<MultiTrigger*>::const_iterator it;
+        it = this->children_.begin();
+
+        for (unsigned int i = 0; i != index; ++i)
+            ++it;
+
+        return (*it);
+    }
+    
+    //TODO: Document
+    void MultiTrigger::fire(bool status, BaseObject* originator)
+    {
+        if(originator == NULL)
+        {
+            this->fireEvent(status);
+            return;
+        }
+        MultiTriggerContainer* container = new MultiTriggerContainer(this, this, originator);
+        this->fireEvent(status, container);
+        COUT(4) << "MultiTrigger &" << this << ": Fired event. originator: " << originator->getIdentifier()->getName() << " (&" << originator << "), status: " << status << "." << std::endl;
+        delete container;
+    }
+    
+    //TODO: Document
+    void MultiTrigger::addTargets(const std::string& targets)
+    {
+        Identifier* target = ClassByString(targets);
+
+        if (target == NULL)
+        {
+            COUT(1) << "Error: \"" << targets << "\" is not a valid class name to include in ClassTreeMask (in " << this->getName() << ", class " << this->getIdentifier()->getName() << ')' << std::endl;
+            return;
+        }
+
+        this->targetMask_.include(target);
+
+        // trigger shouldn't react on itself or other triggers
+        this->targetMask_.exclude(Class(MultiTrigger), true);
+
+        // we only want WorldEntities
+        ClassTreeMask WEMask;
+        WEMask.include(Class(WorldEntity));
+        this->targetMask_ *= WEMask;
+
+        this->notifyMaskUpdate();
+    }
+
+    //TODO: Document
+    void MultiTrigger::removeTargets(const std::string& targets)
+    {
+        Identifier* target = ClassByString(targets);
+        this->targetMask_.exclude(target);
+    }
+    
+}
Index: code/trunk/src/modules/objects/triggers/MultiTrigger.h
===================================================================
--- code/trunk/src/modules/objects/triggers/MultiTrigger.h	(revision 6800)
+++ code/trunk/src/modules/objects/triggers/MultiTrigger.h	(revision 6800)
@@ -0,0 +1,164 @@
+/*
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      Benjamin Knecht
+ *
+*/
+
+#ifndef _MultiTrigger_H__
+#define _MultiTrigger_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include "core/BaseObject.h"
+#include "core/ClassTreeMask.h"
+
+#include <set>
+#include <deque>
+
+#include "tools/interfaces/Tickable.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    
+    namespace MultiTriggerMode
+    {
+        enum Value
+        {
+            EventTriggerAND,
+            EventTriggerOR,
+            EventTriggerXOR,
+        };
+    }
+    
+    struct MultiTriggerState
+    {
+        BaseObject* originator;
+        bool bActive;
+        bool bTriggered;
+    };
+    
+    class _ObjectsExport MultiTrigger : public StaticEntity, public Tickable
+    {
+        public:
+            MultiTrigger(BaseObject* creator);
+            ~MultiTrigger();
+            
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void tick(float dt);
+            
+            bool isActive(BaseObject* triggerer = NULL);
+            void addTrigger(MultiTrigger* trigger);
+            const MultiTrigger* getTrigger(unsigned int index) const;
+            
+            void addTargets(const std::string& targets);
+            void removeTargets(const std::string& targets);
+            inline bool isTarget(BaseObject* target)
+                { return targetMask_.isIncluded(target->getIdentifier()); }
+            
+            void setMode(const std::string& modeName);
+            const std::string& getModeString(void) const;
+            inline void setMode(MultiTriggerMode::Value mode)
+                { this->mode_ = mode; }
+            inline MultiTriggerMode::Value getMode() const
+                { return mode_; }
+
+            inline void setInvert(bool bInvert)
+                { this->bInvertMode_ = bInvert; }
+            inline bool getInvert() const
+                { return this->bInvertMode_; }
+
+            inline void setSwitch(bool bSwitch)
+                { this->bSwitch_ = bSwitch; }
+            inline bool getSwitch() const
+                { return this->bSwitch_; }
+
+            inline void setStayActive(bool bStayActive)
+                { this->bStayActive_ = bStayActive; }
+            inline bool getStayActive() const
+                { return this->bStayActive_; }
+
+            inline void setActivations(int activations)
+                { this->remainingActivations_ = activations; }
+            inline int getActivations() const
+                { return this->remainingActivations_; }
+                
+            inline void setSimultaniousTriggerers(int triggerers)
+                { this->maxNumSimultaniousTriggerers_ = triggerers; }
+            inline int getSimultaniousTriggerers(void)
+                { return this->maxNumSimultaniousTriggerers_; }
+
+            inline void setDelay(float delay)
+                { this->delay_= delay; }
+            inline float getDelay() const
+                { return this->delay_; }
+            
+        protected:
+            void fire(bool status, BaseObject* originator = NULL);
+            
+            bool isModeTriggered(BaseObject* triggerer = NULL);
+            bool isTriggered(BaseObject* triggerer = NULL);
+            
+            virtual std::queue<MultiTriggerState*>* letTrigger(void);
+            
+            inline ClassTreeMask& getTargetMask(void)
+                { return this->targetMask_; }
+            virtual void notifyMaskUpdate(void) {}
+            
+        private:
+            static const int INF_s;
+            static const std::string or_s;
+            static const std::string and_s;
+            static const std::string xor_s;
+            
+            bool addState(bool bTriggered, BaseObject* originator = NULL);
+            
+            bool checkAnd(BaseObject* triggerer);
+            bool checkOr(BaseObject* triggerer);
+            bool checkXor(BaseObject* triggerer);
+
+            bool bFirstTick_;
+
+            MultiTriggerMode::Value mode_;
+            bool bInvertMode_;
+            bool bSwitch_;
+            bool bStayActive_;
+            float delay_;
+            int remainingActivations_;
+            int maxNumSimultaniousTriggerers_;
+            
+            std::set<BaseObject*> active_;
+            std::set<BaseObject*> triggered_;
+
+            std::set<MultiTrigger*> children_;
+            std::deque<std::pair<float, MultiTriggerState*> > stateQueue_;
+            
+            ClassTreeMask targetMask_;
+            
+    };
+
+}
+
+#endif // _MultiTrigger_H__
Index: code/trunk/src/modules/objects/triggers/MultiTriggerContainer.cc
===================================================================
--- code/trunk/src/modules/objects/triggers/MultiTriggerContainer.cc	(revision 6800)
+++ code/trunk/src/modules/objects/triggers/MultiTriggerContainer.cc	(revision 6800)
@@ -0,0 +1,56 @@
+/*
+ *   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:
+ *      ...
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+#include "MultiTriggerContainer.h"
+
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+
+    CreateFactory(MultiTriggerContainer);
+    
+    MultiTriggerContainer::MultiTriggerContainer(BaseObject* creator) : BaseObject(creator), originator_(NULL), data_(NULL)
+    {
+        RegisterObject(MultiTriggerContainer);
+        
+    }
+    
+    MultiTriggerContainer::MultiTriggerContainer(BaseObject* creator, MultiTrigger* originator, BaseObject* data) : BaseObject(creator), originator_(originator), data_(data)
+    {
+        RegisterObject(MultiTriggerContainer);
+        
+    }
+    
+    MultiTriggerContainer::~MultiTriggerContainer()
+    {
+        
+    }
+
+
+}
Index: code/trunk/src/modules/objects/triggers/MultiTriggerContainer.h
===================================================================
--- code/trunk/src/modules/objects/triggers/MultiTriggerContainer.h	(revision 6800)
+++ code/trunk/src/modules/objects/triggers/MultiTriggerContainer.h	(revision 6800)
@@ -0,0 +1,59 @@
+/*
+ *   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:
+ *      ...
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+#ifndef _MultiTriggerContainer_H__
+#define _MultiTriggerContainer_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+
+    class _ObjectsExport MultiTriggerContainer : public BaseObject
+    {
+        public:
+            
+            MultiTriggerContainer(BaseObject* creator);
+            MultiTriggerContainer(BaseObject* creator, MultiTrigger* originator, BaseObject* data);
+            ~MultiTriggerContainer();
+            
+            inline MultiTrigger* getOriginator(void)
+                { return this->originator_; }
+            inline BaseObject* getData(void)
+                { return this->data_; }
+            
+        private:
+            MultiTrigger* originator_;
+            BaseObject* data_;
+    };
+    
+}
+
+#endif // _MultiTriggerContainer_H__
