[Orxonox-commit 3520] r8206 - in code/branches/dockingsystem2: data/levels src/modules/objects/triggers

dafrick at orxonox.net dafrick at orxonox.net
Thu Apr 7 22:19:16 CEST 2011


Author: dafrick
Date: 2011-04-07 22:19:16 +0200 (Thu, 07 Apr 2011)
New Revision: 8206

Modified:
   code/branches/dockingsystem2/data/levels/docking.oxw
   code/branches/dockingsystem2/data/levels/fightInOurBack.oxw
   code/branches/dockingsystem2/data/levels/pirateAttack.oxw
   code/branches/dockingsystem2/data/levels/theTimeMachine.oxw
   code/branches/dockingsystem2/src/modules/objects/triggers/DistanceMultiTrigger.cc
   code/branches/dockingsystem2/src/modules/objects/triggers/DistanceMultiTrigger.h
   code/branches/dockingsystem2/src/modules/objects/triggers/DistanceTrigger.cc
   code/branches/dockingsystem2/src/modules/objects/triggers/DistanceTrigger.h
   code/branches/dockingsystem2/src/modules/objects/triggers/MultiTrigger.cc
Log:
Extending DistanceTrigger (both the normal and the MultiTrigger version). DistanceTriggerBeacons, can now also be used to exclude specific objects from triggering a DistanceTrigger.
Beware: The syntax for the DistanceTrigger, used with a DistanceTriggerBeacon has changed.
It was: <DistanceTrigger target="DistanceTriggerBeacon" targetname="someBeacon" />
And is now: <DistanceTrigger target="WhateverTargetYouWantYourTriggerToReactTo" beaconMode="identify" targetname="someBeacon" />
Consult the documentation in DistanceMultiTrigger for it's specific usage, the DistanceTrigger works analogously.


Modified: code/branches/dockingsystem2/data/levels/docking.oxw
===================================================================
--- code/branches/dockingsystem2/data/levels/docking.oxw	2011-04-07 19:00:56 UTC (rev 8205)
+++ code/branches/dockingsystem2/data/levels/docking.oxw	2011-04-07 20:19:16 UTC (rev 8206)
@@ -52,10 +52,11 @@
                 </execute>
             </events>
             <attached>
-                <DistanceMultiTrigger position="0,0,0" distance="20" target="Pawn" name="dockMe" />
+                <DistanceTrigger position="0,0,0" distance="20" target="Pawn" beaconMode="exclude" targetname="beacon1" name="dockMe" />
                 <Billboard material="Examples/Flare" colour="1.0, 0, 0" />
             </attached>
         </Dock>
+        <DistanceTriggerBeacon name="beacon1" />
       
         <TeamSpawnPoint team=1 position="150,0,7" direction="-1,0,0" roll=90 yaw=0 spawnclass=SpaceShip pawndesign=spaceshipassff />
         <TeamSpawnPoint team=1 position="0,0,7" lookat="-1,0,0" roll="90"  yaw=0 spawnclass=SpaceShip pawndesign=spaceshipassff />

Modified: code/branches/dockingsystem2/data/levels/fightInOurBack.oxw
===================================================================
--- code/branches/dockingsystem2/data/levels/fightInOurBack.oxw	2011-04-07 19:00:56 UTC (rev 8205)
+++ code/branches/dockingsystem2/data/levels/fightInOurBack.oxw	2011-04-07 20:19:16 UTC (rev 8206)
@@ -134,7 +134,7 @@
                 </execute>
             </events>
             <attached>
-                <DistanceTrigger name="FightInOurBack_MainStart_FollowStart" position="0,0,0" distance="50" target="DistanceTriggerBeacon" targetname="PlayerDistanceTrigger" />
+                <DistanceTrigger name="FightInOurBack_MainStart_FollowStart" position="0,0,0" distance="50" target="Pawn" beaconMode="identify" targetname="PlayerDistanceTrigger" />
                 <!--<Billboard position="0,0,0" colour="1.0,1.0,1.0" material="Examples/Flare" />-->
             </attached>
         </QuestEffectBeacon>
@@ -152,7 +152,7 @@
             </events>
             <attached>
                 <!--<Billboard position="0,0,0" colour="1,1,1" material="Examples/Flare" />-->
-                <DistanceTrigger name="FightInOurBack_FollowEnd_DTranspStart_AssisStart" position="0,0,0" distance="1000" target="DistanceTriggerBeacon" targetname="PlayerDistanceTrigger" stayactive=1 activations=1 />
+                <DistanceTrigger name="FightInOurBack_FollowEnd_DTranspStart_AssisStart" position="0,0,0" distance="1000" target="Pawn" beaconMode="identify" targetname="PlayerDistanceTrigger" stayactive=1 activations=1 />
             </attached>
         </QuestEffectBeacon>
     
@@ -315,7 +315,7 @@
 <!--Creating spaceships (player's team) OK-->
 <!---->
 <!--Trigger to activate this Team (TEAM NO 1)-->
-    <DistanceTrigger name="activateTeam0No1" position="8000,0,3100" distance="1000" target="DistanceTriggerBeacon" targetname="PlayerDistanceTrigger" activations="1" stayactive="true" />
+    <DistanceTrigger name="activateTeam0No1" position="8000,0,3100" distance="1000" target="Pawn" beaconMode="identify" targetname="PlayerDistanceTrigger" activations="1" stayactive="true" />
 
 <!--TEAM NO 1 (activationType : distance || killing a spaceship what belongs to TEAM 0 NO 0)-->
 <?lua for i=0,9,1 do
@@ -475,7 +475,7 @@
 <!--Creating spaceships (enemy) END -->
 
 <Trigger invert=true name="activateFirstSpawnpoint">
-    <DistanceTrigger name="activateSecondSpawnpoint" position="10000,0,3000" distance="1000" target="DistanceTriggerBeacon" targetname="PlayerDistanceTrigger" activations="1" stayactive="true" />
+    <DistanceTrigger name="activateSecondSpawnpoint" position="10000,0,3000" distance="1000" target="Pawn" beaconMode="identify" targetname="PlayerDistanceTrigger" activations="1" stayactive="true" />
 </Trigger>
 
     </Scene>

Modified: code/branches/dockingsystem2/data/levels/pirateAttack.oxw
===================================================================
--- code/branches/dockingsystem2/data/levels/pirateAttack.oxw	2011-04-07 19:00:56 UTC (rev 8205)
+++ code/branches/dockingsystem2/data/levels/pirateAttack.oxw	2011-04-07 20:19:16 UTC (rev 8206)
@@ -141,7 +141,7 @@
                 </execute>
             </events>
             <attached>
-                <DistanceTrigger name=questbeacon1 position="0,0,0" distance=100 target=DistanceTriggerBeacon targetname=Me/>
+                <DistanceTrigger name=questbeacon1 position="0,0,0" distance=100 target="Pawn" beaconMode="identify" targetname=Me/>
             </attached>
             </QuestEffectBeacon>
           </attached>
@@ -155,7 +155,7 @@
         <QuestEffectBeacon position="250,-300,-1500" times=1>
                     <attached>
                         <Billboard position="0,0,0" scale=3 colour="1.0,1.0,0" material="Examples/Flare" />
-                        <DistanceTrigger name=questbeacon2 targetname=Me position="0,0,0" target=DistanceTriggerBeacon distance=400 />
+                        <DistanceTrigger name=questbeacon2 targetname=Me position="0,0,0" target="Pawn" beaconMode="identify" distance=400 />
                     </attached>
                     <effects>
                         <AddQuest questId="3159b4d4-bc86-4190-ba1d-4530668dfe31" />
@@ -170,7 +170,7 @@
         <!-- Hint to first Quest-->
         <QuestEffectBeacon position="0,0,0" times=1>
                     <attached>
-                        <DistanceTrigger name=questbeacon3  position="0,0,0" distance=300 target=DistanceTriggerBeacon targetname=Me delay="5" />
+                        <DistanceTrigger name=questbeacon3  position="0,0,0" distance=300 target="Pawn" beaconMode="identify" targetname=Me delay="5" />
                     </attached>
                     <effects>
                         <AddQuestHint hintId="2b85f32c-2433-4f1a-bdd4-f24d20c9403c" />
@@ -187,7 +187,7 @@
         <QuestEffectBeacon position="600,300,-6000" times=1>
                     <attached>
                         <Billboard position="0,0,0" scale=3 colour="0,1.0,0" material="Examples/Flare" />
-                        <DistanceTrigger name=questbeacon4  position="0,0,0" distance=200 target=DistanceTriggerBeacon targetname=Me />
+                        <DistanceTrigger name=questbeacon4  position="0,0,0" distance=200 target="Pawn" beaconMode="identify" targetname=Me />
                     </attached>
     
                     <effects>
@@ -206,7 +206,7 @@
         <!-- Wrong way 1-->
         <QuestEffectBeacon position="7600,300,-8000" times=1>
                     <attached>
-                        <DistanceTrigger name=questbeacon5  position="0,0,0" distance=300 target=DistanceTriggerBeacon targetname=Me />
+                        <DistanceTrigger name=questbeacon5  position="0,0,0" distance=300 target="Pawn" beaconMode="identify" targetname=Me />
                     </attached>
                     <effects>
                         <AddQuest questId="9930a598-98bc-4ff8-8cc0-31311a6ccaaa" />
@@ -221,7 +221,7 @@
         <!-- Wrong way 2-->
         <QuestEffectBeacon position="1600,2300,-10000" times=1>
                     <attached>
-                        <DistanceTrigger name=questbeacon8  position="0,0,0" distance=300 target=DistanceTriggerBeacon targetname=Me />
+                        <DistanceTrigger name=questbeacon8  position="0,0,0" distance=300 target="Pawn" beaconMode="identify" targetname=Me />
                     </attached>
                     <effects>
                         <AddQuest questId="9930a598-98bc-4ff8-8cc0-31311a6ccaab" />
@@ -236,7 +236,7 @@
         <!-- Base found!-->
         <QuestEffectBeacon position="4600,5300,-11000" times=1>
                     <attached>
-                        <DistanceTrigger name=questbeacon6  position="0,0,0" distance=600 target=DistanceTriggerBeacon targetname=Me />
+                        <DistanceTrigger name=questbeacon6  position="0,0,0" distance=600 target="Pawn" beaconMode="identify" targetname=Me />
                     </attached>
                     <effects>
                         <CompleteQuest questId="8d8ed3a6-74a6-4491-9172-26155cff151d" />
@@ -254,7 +254,7 @@
         <!--Stick found-->
         <QuestEffectBeacon position="4800,5785,-10725" times=1>
                     <attached>
-                        <DistanceTrigger name=questbeacon7  position="0,0,0" distance=30 target=DistanceTriggerBeacon targetname=Me />
+                        <DistanceTrigger name=questbeacon7  position="0,0,0" distance=30 target="Pawn" beaconMode="identify" targetname=Me />
                     </attached>
                     <effects>
                         <CompleteQuest questId="8a62408b-c47b-4e02-bd3d-06bb9ec0b363" />
@@ -273,7 +273,7 @@
         <QuestEffectBeacon position="4000,4000,-20000" times=1>
                     <attached>
                         <Billboard position="0,0,0" scale=3 colour="0,0,1.0" material="Examples/Flare" />
-                        <DistanceTrigger name=questbeacon9 position="0,0,0" distance=500 target=DistanceTriggerBeacon targetname=Me />
+                        <DistanceTrigger name=questbeacon9 position="0,0,0" distance=500 target="Pawn" beaconMode="identify" targetname=Me />
                     </attached>
                     <effects>
                         <CompleteQuest questId="85380d05-b791-45d1-82e9-01f0bc930367" />

Modified: code/branches/dockingsystem2/data/levels/theTimeMachine.oxw
===================================================================
--- code/branches/dockingsystem2/data/levels/theTimeMachine.oxw	2011-04-07 19:00:56 UTC (rev 8205)
+++ code/branches/dockingsystem2/data/levels/theTimeMachine.oxw	2011-04-07 20:19:16 UTC (rev 8206)
@@ -93,7 +93,7 @@
 <!--Triggers (used for the Time Machine effect)___________________________________________________________________________________________________________________________________________-->
     
         <!--TRIGGERS IF THE PLAYERS REACHES THE "TIME MACHINE"-->
-        <DistanceTrigger name="EnterTimeMachine" position="0,0,0" distance="100" target="DistanceTriggerBeacon" targetname="PlayerDistanceTrigger" >
+        <DistanceTrigger name="EnterTimeMachine" position="0,0,0" distance="100" target="Pawn" beaconMode="identify" targetname="PlayerDistanceTrigger" >
             <attached>
                 <Billboard position="0,0,0" material="Examples/Flare" colour="0, 0, 1" scale=1/>
                 <Billboard position="100,0,0" material="Examples/Flare" colour="0, 0, 1" scale=1/>

Modified: code/branches/dockingsystem2/src/modules/objects/triggers/DistanceMultiTrigger.cc
===================================================================
--- code/branches/dockingsystem2/src/modules/objects/triggers/DistanceMultiTrigger.cc	2011-04-07 19:00:56 UTC (rev 8205)
+++ code/branches/dockingsystem2/src/modules/objects/triggers/DistanceMultiTrigger.cc	2011-04-07 20:19:16 UTC (rev 8206)
@@ -42,19 +42,23 @@
 namespace orxonox
 {
 
+    /*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);
 
     /**
     @brief
         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;
     }
 
     /**
@@ -63,7 +67,8 @@
     */
     DistanceMultiTrigger::~DistanceMultiTrigger()
     {
-
+        if(this->beaconMask_ != NULL)
+            delete this->beaconMask_;
     }
 
     /**
@@ -75,6 +80,7 @@
         SUPER(DistanceMultiTrigger, XMLPort, xmlelement, mode);
 
         XMLPortParam(DistanceMultiTrigger, "distance", setDistance, getDistance, xmlelement, mode);
+        XMLPortParam(DistanceMultiTrigger, "beaconMode", setBeaconMode, getBeaconMode, xmlelement, mode);
         XMLPortParam(DistanceMultiTrigger, "targetname", setTargetName, getTargetName, xmlelement, mode);
     }
 
@@ -125,21 +131,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(this->beaconMode_ == distanceMultiTriggerBeaconMode::identify)
+            targetMask = *this->beaconMask_;
+
+        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 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 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(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;
             }
 
@@ -152,8 +176,8 @@
                 if(!this->addToRange(entity))
                     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();
 
                 // If no queue has been created, yet.
@@ -170,22 +194,62 @@
 
         return queue;
     }
-
+    
     /**
     @brief
-        Set the target name of DistanceTriggerBeacons that triggers this DistanceMultiTrigger.
-    @param targetname
-        The name of the DistanceTriggerBeacon as a string.
+        Set the beacon mode.
+    @param mode
+        The mode as an enum.
     */
-    void DistanceMultiTrigger::setTargetName(const std::string& targetname)
+    void DistanceMultiTrigger::setBeaconModeDirect(distanceMultiTriggerBeaconMode::Value mode)
     {
-        // If the targetname is no blank string single-target mode is enabled.
-        if(targetname != "")
-            this->singleTargetMode_ = true;
+        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;
     }
 
     /**

Modified: code/branches/dockingsystem2/src/modules/objects/triggers/DistanceMultiTrigger.h
===================================================================
--- code/branches/dockingsystem2/src/modules/objects/triggers/DistanceMultiTrigger.h	2011-04-07 19:00:56 UTC (rev 8205)
+++ code/branches/dockingsystem2/src/modules/objects/triggers/DistanceMultiTrigger.h	2011-04-07 20:19:16 UTC (rev 8206)
@@ -50,10 +50,26 @@
 
     /**
     @brief
-        The DistanceMultiTrigger is a MultiTrigger that triggers whenever an object (that is of the specified target type) is in a specified range of the DistanceMultiTrigger. The object can be specified further by adding a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" (by just attaching it) to the objects that can trigger this DistanceMultiTrigger and specify the name of the @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" with the parameter <em>targetname</em> and only objects that have a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" with that name will trigger the DistanceMultiTrigger.
+        Enum for the beacon mode of the DistanceMultiTrigger.
+        
+    @ingroup MultiTrigger
+    */
+    namespace distanceMultiTriggerBeaconMode
+    {
+        enum Value {
+            off,
+            identify,
+            exclude
+        };
+    }
+
+    /**
+    @brief
+        The DistanceMultiTrigger is a MultiTrigger that triggers whenever an object (that is of the specified target type) is in a specified range of the DistanceMultiTrigger. The object can be specified further by setting the <em>beaconMode</em> and attaching a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" to the object.
         Parameters are (additional to the ones of MultiTrigger):
         - @b distance Which specifies the maximum distance at which the DistanceMultiTrigger still triggers. Default is 100.
-        - @b targetname Which, if not left blank, causes the DistancMultiTrigger to be in <em>single-target</em> mode, meaning, that it only reacts to objects that have a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" (therefore the target has to be set to @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" for it to work), with the name specified by <em>targetname</em>, attached.
+        - @b beaconMode Which specifies, whether the DistanceMultiTrigger operates on @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacons" or not. If <em>off</em> the DistanceMultiTrigger works as usual. If set to <em>identify</em> the DistanceMultiTrigger is only triggered by objects that have a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon", with the same name as specified in <em>targetname</em>, attached to them. If set to <em>exclude</em> the DistanceMultiTrigger is only triggered by objects that don't have a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon", with the same name as specified in <em>targetname</em>, attached to them. Default is <em>off</em>.
+        - @b targetname Which, if not left blank, causes the DistanceMultiTrigger to be in <em>identify</em> beaconMode (unless otherwise specified), meaning, that it only reacts to objects that have a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" with the name specified by <em>targetname</em>, attached.
 
         A simple DistanceMultiTrigger would look like this:
         @code
@@ -62,7 +78,7 @@
 
         An implementation that only reacts to objects with a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" attached would look like this:
         @code
-        <DistanceMultiTrigger position="0,0,0" target="DistanceMultiTrigger" targetname="beacon1" distance="30" />
+        <DistanceMultiTrigger position="0,0,0" target="Pawn" beaconMode="identify" targetname="beacon1" distance="30" />
         @endcode
         This particular DistanceMultiTrigger would only react if an object was in range, that had a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" with the name <em>beacon1</em> attached.
 
@@ -82,16 +98,8 @@
             virtual ~DistanceMultiTrigger(); //!< Destructor.
 
             void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a DistanceMultiTrigger object through XML.
-
-            void setTargetName(const std::string& targetname); //!< Set the target name of DistanceTriggerBeacons that triggers this DistanceMultiTrigger.
+            
             /**
-            @brief Get the target name of the DistanceTriggerbeacon, that triggers this DistanceMultiTrigger.
-            @return Returns the target name as a string.
-            */
-            inline const std::string& getTargetName(void)
-                { return this->targetName_; }
-
-            /**
             @brief Set the distance at which the DistanceMultiTrigger triggers.
             @param distance The distance.
             */
@@ -103,7 +111,30 @@
             */
             inline float getDistance() const
                 { return this->distance_; }
+            
+            void setBeaconModeDirect(distanceMultiTriggerBeaconMode::Value mode); //!< Set the beacon mode.
+            /**
+            @brief Get the beacon mode.
+            @return Returns the mode as an enum.
+            */
+            inline distanceMultiTriggerBeaconMode::Value getBeaconModeDirect(void) const
+                { return this->beaconMode_; }
+            void setBeaconMode(const std::string& mode); //!< Set the beacon mode.
+            const std::string& getBeaconMode(void) const; //!< Get the beacon mode.
 
+            /**
+            @brief Set the target name of DistanceTriggerBeacons that triggers this DistanceMultiTrigger.
+            @param targetname The name of the DistanceTriggerBeacon as a string.
+            */
+            inline void setTargetName(const std::string& targetname)
+                { this->targetName_ = targetname; }
+            /**
+            @brief Get the target name of the DistanceTriggerbeacon, that triggers this DistanceMultiTrigger.
+            @return Returns the target name as a string.
+            */
+            inline const std::string& getTargetName(void) const
+                { return this->targetName_; }
+
         protected:
             virtual std::queue<MultiTriggerState*>* letTrigger(void); //!< This method is called by the MultiTrigger to get information about new trigger events that need to be looked at.
 
@@ -111,9 +142,16 @@
             bool removeFromRange(WorldEntity* entity); //!< Remove a given entity from the set of entities, that currently are in range of the DistanceMultiTrigger.
 
         private:
+            //! Strings for the beacon modes.
+            static const std::string beaconModeOff_s;
+            static const std::string beaconModeIdentify_s;
+            static const std::string beaconModeExlcude_s;
+            
             float distance_; //!< The distance at which the DistanceMultiTrigger triggers.
+
+            distanceMultiTriggerBeaconMode::Value beaconMode_; //!< The beacon mode, the DistanceMultiTrigger is in.
             std::string targetName_; //!< The target name, used in <em>single-target</em> mode.
-            bool singleTargetMode_; //!< To indicate whe the MultiDistanceTrigger is in <em>single-target</em> mode.
+            ClassTreeMask* beaconMask_; //!< A mask, that only accepts DistanceTriggerBeacons.
 
             std::map<WorldEntity*, WeakPtr<WorldEntity>* > range_; //!< The set of entities that currently are in range of the DistanceMultiTrigger.
 

Modified: code/branches/dockingsystem2/src/modules/objects/triggers/DistanceTrigger.cc
===================================================================
--- code/branches/dockingsystem2/src/modules/objects/triggers/DistanceTrigger.cc	2011-04-07 19:00:56 UTC (rev 8205)
+++ code/branches/dockingsystem2/src/modules/objects/triggers/DistanceTrigger.cc	2011-04-07 20:19:16 UTC (rev 8206)
@@ -41,20 +41,26 @@
 
 namespace orxonox
 {
+    
+  /*static*/ const std::string DistanceTrigger::beaconModeOff_s = "off";
+  /*static*/ const std::string DistanceTrigger::beaconModeIdentify_s = "identify";
+  /*static*/ const std::string DistanceTrigger::beaconModeExlcude_s = "exclude";
+    
   CreateFactory(DistanceTrigger);
 
-  DistanceTrigger::DistanceTrigger(BaseObject* creator) : Trigger(creator)
+  DistanceTrigger::DistanceTrigger(BaseObject* creator) : Trigger(creator), beaconMask_(NULL)
   {
     RegisterObject(DistanceTrigger);
 
     this->distance_ = 100;
     this->targetMask_.exclude(Class(BaseObject));
     this->targetName_ = "";
-    this->singleTargetMode_ = false;
   }
 
   DistanceTrigger::~DistanceTrigger()
   {
+    if(this->beaconMask_ != NULL)
+      delete this->beaconMask_;
   }
 
   void DistanceTrigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
@@ -63,6 +69,7 @@
 
     XMLPortParam(DistanceTrigger, "distance", setDistance, getDistance, xmlelement, mode).defaultValues(100.0f);
     XMLPortParamLoadOnly(DistanceTrigger, "target", addTargets, xmlelement, mode).defaultValues("Pawn");
+    XMLPortParam(DistanceTrigger, "beaconMode", setBeaconMode, getBeaconMode, xmlelement, mode);
     XMLPortParam(DistanceTrigger, "targetname", setTargetName, getTargetName, xmlelement, mode);
   }
 
@@ -126,24 +133,43 @@
 
   bool DistanceTrigger::checkDistance()
   {
+    // Check for new objects that are in range
+    ClassTreeMask targetMask = this->targetMask_;
+    if(this->beaconMode_ == distanceTriggerBeaconMode::identify)
+     targetMask = *this->beaconMask_;
+    
     // Iterate through all objects
-    for (ClassTreeMaskObjectIterator it = this->targetMask_.begin(); it != this->targetMask_.end(); ++it)
+    for (ClassTreeMaskObjectIterator it = targetMask.begin(); it != targetMask.end(); ++it)
     {
       WorldEntity* entity = orxonox_cast<WorldEntity*>(*it);
       if (!entity)
         continue;
-
-      // If the DistanceTrigger is in single-target mode.
-      if(this->singleTargetMode_)
+      
+       // If the DistanceTrigger is in identify mode and the DistanceTriggerBeacon attached to the object has the wrong name we ignore it.
+      if(this->beaconMode_ == distanceTriggerBeaconMode::identify)
       {
-        // If the object that is a target is no DistanceTriggerBeacon, then the DistanceTrigger can't be in single-target-mode.
-        if(!(*it)->isA(ClassIdentifier<DistanceTriggerBeacon>::getIdentifier()))
+        if(entity->getName() != this->targetName_)
+            continue;
+        // If the object, the DistanceTriggerBeacon is attached to, is not a target of this DistanceMultiTrigger.
+        else if(this->targetMask_.isExcluded(entity->getParent()->getIdentifier()))
+            continue;
+      }
+    
+      // If the DistanceTrigger is in exclude mode and the DistanceTriggerBeacon attached to the object has the right name, we ignore it.
+      if(this->beaconMode_ == distanceTriggerBeaconMode::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) << "DistanceTrigger " << 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;
       }
 
@@ -151,12 +177,12 @@
       if (distanceVec.length() < this->distance_)
       {
 
-        // If the target is a player (resp. is a, or is derived from a, ControllableEntity) the triggeringPlayer is set to the target entity.
+        // If the target is a player (resp. is a, or is derived from a, Pawn) the triggeringPlayer is set to the target entity.
         if(this->isForPlayer())
         {
 
-          // 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_ == distanceTriggerBeaconMode::identify)
             entity = entity->getParent();
 
           Pawn* player = orxonox_cast<Pawn*>(entity);
@@ -169,6 +195,63 @@
 
     return false;
   }
+  
+  /**
+  @brief
+    Set the beacon mode.
+  @param mode
+    The mode as an enum.
+  */
+  void DistanceTrigger::setBeaconModeDirect(distanceTriggerBeaconMode::Value mode)
+  {
+    this->beaconMode_ = mode;
+    if(this->beaconMode_ == distanceTriggerBeaconMode::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& DistanceTrigger::getBeaconMode(void) const
+  {
+    switch(this->getBeaconModeDirect())
+    {
+      case distanceTriggerBeaconMode::off :
+        return DistanceTrigger::beaconModeOff_s;
+      case distanceTriggerBeaconMode::identify:
+        return DistanceTrigger::beaconModeIdentify_s;
+      case distanceTriggerBeaconMode::exclude:
+        return DistanceTrigger::beaconModeExlcude_s;
+      default :
+        assert(0); // This is impossible.
+        return BLANKSTRING;
+    }
+  }
+    
+  /**
+  @brief
+    Set the beacon mode.
+  @param mode
+    The mode as a string.
+  */
+  void DistanceTrigger::setBeaconMode(const std::string& mode)
+  {
+    if(mode == DistanceTrigger::beaconModeOff_s)
+      this->setBeaconModeDirect(distanceTriggerBeaconMode::off);
+    else if(mode == DistanceTrigger::beaconModeIdentify_s)
+      this->setBeaconModeDirect(distanceTriggerBeaconMode::identify);
+    else if(mode == DistanceTrigger::beaconModeExlcude_s)
+      this->setBeaconModeDirect(distanceTriggerBeaconMode::exclude);
+    else
+      COUT(1) << "Invalid beacon mode in DistanceTrigger." << endl;
+  }
 
   bool DistanceTrigger::isTriggered(TriggerMode::Value mode)
   {

Modified: code/branches/dockingsystem2/src/modules/objects/triggers/DistanceTrigger.h
===================================================================
--- code/branches/dockingsystem2/src/modules/objects/triggers/DistanceTrigger.h	2011-04-07 19:00:56 UTC (rev 8205)
+++ code/branches/dockingsystem2/src/modules/objects/triggers/DistanceTrigger.h	2011-04-07 20:19:16 UTC (rev 8206)
@@ -44,6 +44,21 @@
 
 namespace orxonox
 {
+    
+  /**
+  @brief
+      Enum for the beacon mode of the DistanceTrigger.
+      
+  @ingroup NormalTrigger
+  */
+  namespace distanceTriggerBeaconMode
+  {
+      enum Value {
+          off,
+          identify,
+          exclude
+      };
+  }
 
   /**
   @brief
@@ -68,15 +83,25 @@
       void removeTarget(Ogre::Node* targetNode);
       void removeTargets(const std::string& targets);
 
-      inline void setTargetName(const std::string& targetname)
-        { if(targetname != "") this->singleTargetMode_ = true; else this->singleTargetMode_ = false; this->targetName_ = targetname; }
-      inline const std::string& getTargetName(void)
-        { return this->targetName_; }
-
       inline void setDistance(float distance)
         { this->distance_ = distance; }
       inline float getDistance() const
         { return this->distance_; }
+        
+      void setBeaconModeDirect(distanceTriggerBeaconMode::Value mode); //!< Set the beacon mode.
+      /**
+      @brief Get the beacon mode.
+      @return Returns the mode as an enum.
+      */
+      inline distanceTriggerBeaconMode::Value getBeaconModeDirect(void) const
+        { return this->beaconMode_; }
+      void setBeaconMode(const std::string& mode); //!< Set the beacon mode.
+      const std::string& getBeaconMode(void) const; //!< Get the beacon mode.
+            
+      inline void setTargetName(const std::string& targetname)
+        { this->targetName_ = targetname; }
+      inline const std::string& getTargetName(void)
+        { return this->targetName_; }
 
       bool checkDistance();
 
@@ -87,10 +112,18 @@
       ClassTreeMask targetMask_;
 
     private:
+      //! Strings for the beacon modes.
+      static const std::string beaconModeOff_s;
+      static const std::string beaconModeIdentify_s;
+      static const std::string beaconModeExlcude_s;
+            
       std::set<Ogre::Node*> targetSet_;
+      
+      distanceTriggerBeaconMode::Value beaconMode_;
       std::string targetName_;
+      ClassTreeMask* beaconMask_; //!< A mask, that only accepts DistanceTriggerBeacons.
+      
       float distance_;
-      bool singleTargetMode_;
 
   };
 }

Modified: code/branches/dockingsystem2/src/modules/objects/triggers/MultiTrigger.cc
===================================================================
--- code/branches/dockingsystem2/src/modules/objects/triggers/MultiTrigger.cc	2011-04-07 19:00:56 UTC (rev 8205)
+++ code/branches/dockingsystem2/src/modules/objects/triggers/MultiTrigger.cc	2011-04-07 20:19:16 UTC (rev 8206)
@@ -311,7 +311,6 @@
         this->targetMask_.exclude(Class(MultiTrigger), true);
 
         // We only want WorldEntities
-        //TODO: Really?
         ClassTreeMask WEMask;
         WEMask.include(Class(WorldEntity));
         this->targetMask_ *= WEMask;




More information about the Orxonox-commit mailing list