Index: code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc
===================================================================
--- code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc	(revision 8079)
+++ code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc	(revision 8213)
@@ -43,4 +43,8 @@
 {
 
+    /*static*/ const std::string DistanceMultiTrigger::beaconModeOff_s = "off";
+    /*static*/ const std::string DistanceMultiTrigger::beaconModeIdentify_s = "identify";
+    /*static*/ const std::string DistanceMultiTrigger::beaconModeExlcude_s = "exclude";
+    
     CreateFactory(DistanceMultiTrigger);
 
@@ -49,11 +53,11 @@
         Default Constructor. Registers the object and initializes default values.
     */
-    DistanceMultiTrigger::DistanceMultiTrigger(BaseObject* creator) : MultiTrigger(creator)
+    DistanceMultiTrigger::DistanceMultiTrigger(BaseObject* creator) : MultiTrigger(creator), beaconMask_(NULL)
     {
         RegisterObject(DistanceMultiTrigger);
 
         this->distance_ = 100.0f;
+        this->setBeaconModeDirect(distanceMultiTriggerBeaconMode::off);
         this->targetName_ = "";
-        this->singleTargetMode_ = false;
     }
 
@@ -64,5 +68,6 @@
     DistanceMultiTrigger::~DistanceMultiTrigger()
     {
-
+        if(this->beaconMask_ != NULL)
+            delete this->beaconMask_;
     }
 
@@ -76,4 +81,5 @@
 
         XMLPortParam(DistanceMultiTrigger, "distance", setDistance, getDistance, xmlelement, mode);
+        XMLPortParam(DistanceMultiTrigger, "beaconMode", setBeaconMode, getBeaconMode, xmlelement, mode);
         XMLPortParam(DistanceMultiTrigger, "targetname", setTargetName, getTargetName, xmlelement, mode);
     }
@@ -126,19 +132,39 @@
 
         // Check for new objects that are in range
-        for(ClassTreeMaskObjectIterator it = this->getTargetMask().begin(); it != this->getTargetMask().end(); ++it)
+        ClassTreeMask targetMask = this->getTargetMask();
+        // If we are in identify-mode another target mask has to be applies to find the DistanceTriggerBeacons.
+        if(this->beaconMode_ == distanceMultiTriggerBeaconMode::identify)
+            targetMask = *this->beaconMask_;
+
+        // Iterate through all objects that are targets of the DistanceMultiTrigger.
+        for(ClassTreeMaskObjectIterator it = targetMask.begin(); it != targetMask.end(); ++it)
         {
             WorldEntity* entity = static_cast<WorldEntity*>(*it);
 
-            // If the DistanceMultiTrigger is in single-target mode.
-            if(this->singleTargetMode_)
-            {
-                // If the object that is a target is no DistanceTriggerBeacon, then the DistanceMultiTrigger can't be in single-target mode.
-                if(!entity->isA(ClassIdentifier<DistanceTriggerBeacon>::getIdentifier()))
+            // If the DistanceMultiTrigger is in identify-mode and the DistanceTriggerBeacon attached to the object has the wrong name we ignore it.
+            if(this->beaconMode_ == distanceMultiTriggerBeaconMode::identify)
+            {
+                if(entity->getName() != this->targetName_)
+                    continue;
+                // If the object, the DistanceTriggerBeacon is attached to, is not a target of this DistanceMultiTrigger.
+                else if(this->getTargetMask().isExcluded(entity->getParent()->getIdentifier()))
+                    continue;
+            }
+            
+            // If the DistanceMultiTrigger is in exclude mode and the DistanceTriggerBeacon attached to the object has the right name, we ignore it.
+            if(this->beaconMode_ == distanceMultiTriggerBeaconMode::exclude)
+            {
+                
+                const std::set<WorldEntity*> attached = entity->getAttachedObjects();
+                bool found = false;
+                for(std::set<WorldEntity*>::const_iterator it = attached.begin(); it != attached.end(); it++)
                 {
-                    this->singleTargetMode_ = false;
-                    COUT(2) << "DistanceMultiTrigger " << this->getName() << " (&" << this <<  ")" << "is in single-target mode but the target is '" << entity->getIdentifier()->getName() << "' instead of DistanceTriggerBeacon. Setting single-target mode to false." << std::endl;
+                    if((*it)->isA(ClassIdentifier<DistanceTriggerBeacon>::getIdentifier()) && static_cast<DistanceTriggerBeacon*>(*it)->getName() == this->targetName_)
+                    {
+                        found = true;
+                        break;
+                    }
                 }
-                // If the target name and the name of the DistancTriggerBeacon don't match.
-                else if(entity->getName().compare(this->targetName_) != 0)
+                if(found)
                     continue;
             }
@@ -153,6 +179,6 @@
                     continue;
 
-                // Change the entity to the parent of the DistanceTriggerBeacon (if in single-target-mode), which is the entity to which the beacon is attached.
-                if(this->singleTargetMode_)
+                // Change the entity to the parent of the DistanceTriggerBeacon (if in identify-mode), which is the entity to which the beacon is attached.
+                if(this->beaconMode_ == distanceMultiTriggerBeaconMode::identify)
                     entity = entity->getParent();
 
@@ -171,20 +197,60 @@
         return queue;
     }
-
-    /**
-    @brief
-        Set the target name of DistanceTriggerBeacons that triggers this DistanceMultiTrigger.
-    @param targetname
-        The name of the DistanceTriggerBeacon as a string.
-    */
-    void DistanceMultiTrigger::setTargetName(const std::string& targetname)
-    {
-        // If the targetname is no blank string single-target mode is enabled.
-        if(targetname != "")
-            this->singleTargetMode_ = true;
+    
+    /**
+    @brief
+        Set the beacon mode.
+    @param mode
+        The mode as an enum.
+    */
+    void DistanceMultiTrigger::setBeaconModeDirect(distanceMultiTriggerBeaconMode::Value mode)
+    {
+        this->beaconMode_ = mode;
+        if(this->beaconMode_ == distanceMultiTriggerBeaconMode::identify && this->beaconMask_ == NULL)
+        {
+            this->beaconMask_ = new ClassTreeMask();
+            this->beaconMask_->exclude(Class(BaseObject));
+            this->beaconMask_->include(Class(DistanceTriggerBeacon));
+        }
+    }
+    
+    /**
+    @brief
+        Get the beacon mode.
+    @return
+        Returns the mode as a string.
+    */
+    const std::string& DistanceMultiTrigger::getBeaconMode(void) const
+    {
+        switch(this->getBeaconModeDirect())
+        {
+            case distanceMultiTriggerBeaconMode::off :
+                return DistanceMultiTrigger::beaconModeOff_s;
+            case distanceMultiTriggerBeaconMode::identify:
+                return DistanceMultiTrigger::beaconModeIdentify_s;
+            case distanceMultiTriggerBeaconMode::exclude:
+                return DistanceMultiTrigger::beaconModeExlcude_s;
+            default :
+                assert(0); // This is impossible.
+                return BLANKSTRING;
+        }
+    }
+    
+    /**
+    @brief
+        Set the beacon mode.
+    @param mode
+        The mode as a string.
+    */
+    void DistanceMultiTrigger::setBeaconMode(const std::string& mode)
+    {
+        if(mode == DistanceMultiTrigger::beaconModeOff_s)
+            this->setBeaconModeDirect(distanceMultiTriggerBeaconMode::off);
+        else if(mode == DistanceMultiTrigger::beaconModeIdentify_s)
+            this->setBeaconModeDirect(distanceMultiTriggerBeaconMode::identify);
+        else if(mode == DistanceMultiTrigger::beaconModeExlcude_s)
+            this->setBeaconModeDirect(distanceMultiTriggerBeaconMode::exclude);
         else
-            this->singleTargetMode_ = false;
-
-        this->targetName_ = targetname;
+            COUT(1) << "Invalid beacon mode in DistanceMultiTrigger." << endl;
     }
 
