Changeset 8213 for code/trunk
- Timestamp:
- Apr 9, 2011, 3:33:06 PM (14 years ago)
- Location:
- code/trunk
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk/data/levels/fightInOurBack.oxw
r8079 r8213 135 135 </events> 136 136 <attached> 137 <DistanceTrigger name="FightInOurBack_MainStart_FollowStart" position="0,0,0" distance="50" target=" DistanceTriggerBeacon" targetname="PlayerDistanceTrigger" />137 <DistanceTrigger name="FightInOurBack_MainStart_FollowStart" position="0,0,0" distance="50" target="Pawn" beaconMode="identify" targetname="PlayerDistanceTrigger" /> 138 138 <!--<Billboard position="0,0,0" colour="1.0,1.0,1.0" material="Examples/Flare" />--> 139 139 </attached> … … 153 153 <attached> 154 154 <!--<Billboard position="0,0,0" colour="1,1,1" material="Examples/Flare" />--> 155 <DistanceTrigger name="FightInOurBack_FollowEnd_DTranspStart_AssisStart" position="0,0,0" distance="1000" target=" DistanceTriggerBeacon" targetname="PlayerDistanceTrigger" stayactive=1 activations=1 />155 <DistanceTrigger name="FightInOurBack_FollowEnd_DTranspStart_AssisStart" position="0,0,0" distance="1000" target="Pawn" beaconMode="identify" targetname="PlayerDistanceTrigger" stayactive=1 activations=1 /> 156 156 </attached> 157 157 </QuestEffectBeacon> … … 316 316 <!----> 317 317 <!--Trigger to activate this Team (TEAM NO 1)--> 318 <DistanceTrigger name="activateTeam0No1" position="8000,0,3100" distance="1000" target=" DistanceTriggerBeacon" targetname="PlayerDistanceTrigger" activations="1" stayactive="true" />318 <DistanceTrigger name="activateTeam0No1" position="8000,0,3100" distance="1000" target="Pawn" beaconMode="identify" targetname="PlayerDistanceTrigger" activations="1" stayactive="true" /> 319 319 320 320 <!--TEAM NO 1 (activationType : distance || killing a spaceship what belongs to TEAM 0 NO 0)--> … … 476 476 477 477 <Trigger invert=true name="activateFirstSpawnpoint"> 478 <DistanceTrigger name="activateSecondSpawnpoint" position="10000,0,3000" distance="1000" target=" DistanceTriggerBeacon" targetname="PlayerDistanceTrigger" activations="1" stayactive="true" />478 <DistanceTrigger name="activateSecondSpawnpoint" position="10000,0,3000" distance="1000" target="Pawn" beaconMode="identify" targetname="PlayerDistanceTrigger" activations="1" stayactive="true" /> 479 479 </Trigger> 480 480 -
code/trunk/data/levels/pirateAttack.oxw
r7679 r8213 142 142 </events> 143 143 <attached> 144 <DistanceTrigger name=questbeacon1 position="0,0,0" distance=100 target= DistanceTriggerBeacontargetname=Me/>144 <DistanceTrigger name=questbeacon1 position="0,0,0" distance=100 target="Pawn" beaconMode="identify" targetname=Me/> 145 145 </attached> 146 146 </QuestEffectBeacon> … … 156 156 <attached> 157 157 <Billboard position="0,0,0" scale=3 colour="1.0,1.0,0" material="Examples/Flare" /> 158 <DistanceTrigger name=questbeacon2 targetname=Me position="0,0,0" target= DistanceTriggerBeacondistance=400 />158 <DistanceTrigger name=questbeacon2 targetname=Me position="0,0,0" target="Pawn" beaconMode="identify" distance=400 /> 159 159 </attached> 160 160 <effects> … … 171 171 <QuestEffectBeacon position="0,0,0" times=1> 172 172 <attached> 173 <DistanceTrigger name=questbeacon3 position="0,0,0" distance=300 target= DistanceTriggerBeacontargetname=Me delay="5" />173 <DistanceTrigger name=questbeacon3 position="0,0,0" distance=300 target="Pawn" beaconMode="identify" targetname=Me delay="5" /> 174 174 </attached> 175 175 <effects> … … 188 188 <attached> 189 189 <Billboard position="0,0,0" scale=3 colour="0,1.0,0" material="Examples/Flare" /> 190 <DistanceTrigger name=questbeacon4 position="0,0,0" distance=200 target= DistanceTriggerBeacontargetname=Me />190 <DistanceTrigger name=questbeacon4 position="0,0,0" distance=200 target="Pawn" beaconMode="identify" targetname=Me /> 191 191 </attached> 192 192 … … 207 207 <QuestEffectBeacon position="7600,300,-8000" times=1> 208 208 <attached> 209 <DistanceTrigger name=questbeacon5 position="0,0,0" distance=300 target= DistanceTriggerBeacontargetname=Me />209 <DistanceTrigger name=questbeacon5 position="0,0,0" distance=300 target="Pawn" beaconMode="identify" targetname=Me /> 210 210 </attached> 211 211 <effects> … … 222 222 <QuestEffectBeacon position="1600,2300,-10000" times=1> 223 223 <attached> 224 <DistanceTrigger name=questbeacon8 position="0,0,0" distance=300 target= DistanceTriggerBeacontargetname=Me />224 <DistanceTrigger name=questbeacon8 position="0,0,0" distance=300 target="Pawn" beaconMode="identify" targetname=Me /> 225 225 </attached> 226 226 <effects> … … 237 237 <QuestEffectBeacon position="4600,5300,-11000" times=1> 238 238 <attached> 239 <DistanceTrigger name=questbeacon6 position="0,0,0" distance=600 target= DistanceTriggerBeacontargetname=Me />239 <DistanceTrigger name=questbeacon6 position="0,0,0" distance=600 target="Pawn" beaconMode="identify" targetname=Me /> 240 240 </attached> 241 241 <effects> … … 255 255 <QuestEffectBeacon position="4800,5785,-10725" times=1> 256 256 <attached> 257 <DistanceTrigger name=questbeacon7 position="0,0,0" distance=30 target= DistanceTriggerBeacontargetname=Me />257 <DistanceTrigger name=questbeacon7 position="0,0,0" distance=30 target="Pawn" beaconMode="identify" targetname=Me /> 258 258 </attached> 259 259 <effects> … … 274 274 <attached> 275 275 <Billboard position="0,0,0" scale=3 colour="0,0,1.0" material="Examples/Flare" /> 276 <DistanceTrigger name=questbeacon9 position="0,0,0" distance=500 target= DistanceTriggerBeacontargetname=Me />276 <DistanceTrigger name=questbeacon9 position="0,0,0" distance=500 target="Pawn" beaconMode="identify" targetname=Me /> 277 277 </attached> 278 278 <effects> -
code/trunk/data/levels/theTimeMachine.oxw
r7845 r8213 94 94 95 95 <!--TRIGGERS IF THE PLAYERS REACHES THE "TIME MACHINE"--> 96 <DistanceTrigger name="EnterTimeMachine" position="0,0,0" distance="100" target=" DistanceTriggerBeacon" targetname="PlayerDistanceTrigger" >96 <DistanceTrigger name="EnterTimeMachine" position="0,0,0" distance="100" target="Pawn" beaconMode="identify" targetname="PlayerDistanceTrigger" > 97 97 <attached> 98 98 <Billboard position="0,0,0" material="Examples/Flare" colour="0, 0, 1" scale=1/> -
code/trunk/doc/api/groups/Triggers.dox
r8108 r8213 7 7 @defgroup NormalTrigger Trigger 8 8 @ingroup Triggers 9 10 @ref orxonox::Trigger "Triggers" are objects which react to certain events by changing their boolean state. That state is the trigger's activity @ref orxonox::Trigger can be either <em>active</em> or <em>not active</em>. 11 12 @section TriggerTechnicalDetails Technical Details 13 A common @ref orxonox::Trigger "Trigger" is an object that can either be <em>active</em> or <em>inactive</em>, with a specified behavior how to switch between the two. Each time a switch occurs an @ref orxonox::Event "Event" is fired (see the @ref Eventsystem "Eventsystem" for more information about how that works exactly), with th @ref orxonox::Trigger "Trigger" as the originator. This way the entity that reacts to the @ref orxonox::Trigger "Trigger" triggering receives information about the @ref orxonox::Trigger "Trigger" that created the @ref orxonox::Event "Event". If the @ref orxonox::Trigger "Trigger" is also a @ref orxonox::PlayerTrigger "PlayerTrigger", under some conditions, the entity that caused the @ref orxonox::Trigger "Trigger" to trigger can be accessed. 14 15 Also, just as with all triggers, @ref orxonox::Trigger "Triggers" can be nested (even with e.g. @ref orxonox::MultiTrigger "MultiTriggers"). 16 @code 17 <Trigger switch="true" delay="2"> 18 <DistanceTrigger position="100,0,0" distance="80" /> 19 <EventMultiTrigger ... /> 20 </Trigger> 21 @endcode 22 23 @ref orxonox::Trigger "Triggers" also allow for additional complexity which can be added through the choice of the parameters explained below. 24 But first it is important to understand a small implementation detail. There is a distinction between the @ref orxonox::Trigger "Trigger" being triggered (there is the state <em>triggered</em> for that) and the @ref orxonox::Trigger "Trigger" being active (for that is the state <em>activity</em>). From the outside only the <em>activity</em> is visible. The state <em>triggered</em> tells us whether the trigger is actually triggered, but it could pretend (for some reason, some of which we will see shortly) to be <em>active</em> to the outside, while it in fact isn't. The standard behavior is, that the <em>activity</em> changes, when the @ref orxonox::Trigger "Trigger" transits from being <em>triggered</em> to being <em>not triggered</em> or the other way around. 25 26 The parameters of the @ref orxonox::Trigger "Trigger" are: 27 - @b delay The delay is the time in seconds, that the trigger waits until it reacts (i.e. changes it's state) to the triggering condition being fulfilled. Internally this is handled by a state queue coupled with a counter, for each state that is delayed. The state becomes <em>active</em> when the counter runs out. This allows the @ref orxonox::Trigger "Trigger" to work even if the delay changes at runtime. However if the delay changes it only affects newly arriving states not the ones already in the queue. The default is <code>0.0</code>. 28 - @b switch Switch is a boolean, if <code>true</code> the @ref orxonox::Trigger "Trigger" is in <em>switch-mode</em>, meaning, that the <em>activity</em> changes only when the trigger is <em>triggered</em>, not when it is <em>not triggered</em> (Just like a light switch does). This means, that in <em>switch-mode</em> the <em>activity</em> only changes, when the trigger changes from being <em>not triggered</em> to being <em>triggered</em> but not the other way around. The default is <code>false</code>. 29 - @b stayActive Stay active is also a boolean, if <code>true</code> the @ref orxonox::Trigger "Trigger" stays active after it has been activated as many times as specified by the parameter <em>activations</em>. In essence this means, that after the last time it is activated it cannot be deactivated. The default is <code>false</code>. 30 - @b activations Activations is the number of times the @ref orxonox::Trigger "Trigger" can be activated until the trigger can't be triggered anymore. The default is <code>-1</code>, which denotes infinity. 31 - @b invert Invert is a boolean, if <code>true</code> the @ref orxonox::Trigger "Trigger" is in <em>invert-mode</em>, meaning, that if the triggering condition is fulfilled the @ref orxonox::Trigger "Trigger" will have the state <em>not triggered</em> and and if the condition is not fulfilled it will have the state <em>triggered</em>. In short it inverts the behavior of the @ref orxonox::Trigger "Trigger". The default is <code>false</code>. 32 - @b mode The mode describes how the @ref orxonox::Trigger "Trigger" acts in relation to all the triggers (its children), that are appended to it. There are 3 modes: <em>and</em>, meaning that the @ref orxonox::Trigger "Trigger" can only be triggered if all the appended triggers are active. <em>or</em>, meaning that the @ref orxonox::Trigger "Trigger" can only be triggered if at least one of the appended triggers is active. And <em>xor</em>, meaning that the @ref orxonox::Trigger "Trigger" can only be triggered if one and only one appended trigger is active. Note, that I wrote 'can only be active', that implies, that there is an additional condition to the <em>activity</em> of the @ref orxonox::Trigger "Trigger" and that is the fulfillment of the triggering condition (the @ref orxonox::Trigger "Trigger" class itself doesn't have one, but all derived classes should). Also bear in mind, that the <em>activity</em> of a @ref orxonox::Trigger "Trigger" is still coupled to the object that triggered it. The default is <em>and</em>. 33 34 @subsection Sub-typesOfTriggers Sub-types of Triggers 35 36 @subsubsection EventTrigger EventTrigger 37 An @ref orxonox::EventTrigger "EventTrigger" can either be used to be triggered when an @ref orxonox::Event "Event", that itself is triggering, arrives at its event port. 38 39 A common usage could look like this: 40 @code 41 <EventTrigger invert="true" delay="1"> 42 <events> 43 <trigger> 44 <Trigger ... /> 45 <Trigger ... /> 46 </trigger> 47 </events> 48 </EventTrigger> 49 @endcode 50 51 @subsubsection DistanceTrigger DistanceTrigger 52 The @ref orxonox::DistanceTrigger "DistanceTrigger" is a Trigger that triggers whenever an object (that is of the specified target type) is in a specified range of the @ref orxonox::DistanceTrigger "DistanceTrigger". The object can be specified further by setting the <em>beaconMode</em> and attaching a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" to the object. 53 Parameters are (additional to the ones of Trigger): 54 - @b distance Which specifies the maximum distance at which the @ref orxonox::DistanceTrigger "DistanceTrigger" still triggers, i.e. its range. Default is <code>100</code>. 55 - @b target Which specifies the class of objects that can trigger the @ref orxonox::DistanceTrigger "DistanceTrigger". Default is <code>"Pawn"</code>. 56 - @b beaconMode Which specifies, whether the @ref orxonox::DistanceTrigger "DistanceTrigger" operates on @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacons" or not. If <em>off</em> the DistanceMultiTrigger works as usual. If set to <em>identify</em> the @ref orxonox::DistanceTrigger "DistanceTrigger" 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 @ref orxonox::DistanceTrigger "DistanceTrigger" 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>. 57 - @b targetname Which specifies the name @ref oroxnox::DistanceTriggerBeacon "DistanceTriggerBeacons" need to have to make the @ref orxonox::DistanceTrigger "DistanceTrigger" react to them if it is in <em>beacon-mode</em> (the beaconMode is not <em>off</em>). 58 59 A simple @ref orxonox::DistanceTrigger "DistanceTrigger" could look like this: 60 @code 61 <DistanceTrigger position="0,0,0" switch="true" target="Pawn" distance="20" /> 62 @endcode 63 64 An implementation that only reacts to objects with a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" attached would look like this: 65 @code 66 <DistanceTrigger position="0,0,0" target="Pawn" beaconMode="identify" targetname="beacon1" distance="30" /> 67 @endcode 68 This particular @ref orxonox::DistanceTrigger "DistanceTrigger" would only react if an object was in range, that had a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" with the name <em>beacon1</em> attached. 9 69 10 70 @defgroup MultiTrigger MultiTrigger 11 71 @ingroup Triggers 12 72 13 @ref orxonox::MultiTrigger "MultiTriggers" are (as they are @ref orxonox::TriggerBase "Triggers") objects which react to certain events. They offer all the functionality that the common @ref orxonox::Trigger "Triggers" do with one significant difference. The common @ref orxonox::Trigger "Trigger" has just one state, it can either be <em> triggered</em> or <em>not triggered</em>, it doesn't discriminate between who's triggering (or not triggering) it. A @ref orxonox::MultiTrigger "MultiTrigger", on the other hand, has a distinct state (<em>triggered</em> or <em>not triggered</em>) for each entity that is defined as being able to trigger said @ref orxonox::MultiTrigger "MultiTrigger".73 @ref orxonox::MultiTrigger "MultiTriggers" are (as they are @ref orxonox::TriggerBase "Triggers") objects which react to certain events. They offer all the functionality that the common @ref orxonox::Trigger "Triggers" do with one significant difference. The common @ref orxonox::Trigger "Trigger" has just one state, it can either be <em>active</em> or <em>not acive</em>, it doesn't discriminate between who's triggering (or not triggering) it. A @ref orxonox::MultiTrigger "MultiTrigger", on the other hand, has a distinct state (<em>active</em> or <em>not actve</em>) for each entity that is defined as being able to trigger said @ref orxonox::MultiTrigger "MultiTrigger". 14 74 15 This difference becomes significant, when, for example, you want a @ref orxonox::DistanceTrigger "DistanceTrigger" to trigger a @ref orxonox::QuestEffectBeacon "QuestEffectBeacon" to hand out a @ref orxonox::Quest "Quest" to any @ref orxonox::Pawn "Pawn" that enters its range. With a simple @ref orxonox::DistanceTrigger "DistanceTrigger" (as opposed to the more complex @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger") the first @ref orxonox::Pawn "Pawn" to be in range would trigger it an receive the @ref orxonox::Quest "Quest", however if a second @ref orxonox::Pawn "Pawn" would enter the range, while the first @ref orxonox::Pawn "Pawn" still is in the range nothing would happen and even after the first @ref orxonox::Pawn "Pawn" left nothing would happen, since the whole time the @ref orxonox::DistanceTrigger "DistanceTrigger" would just be triggered. In contrast with a @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" the first @ref orxonox::Pawn "Pawn" would enter the range and the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" would have the state <em>triggered</em> for this exact @ref orxonox::Pawn "Pawn" (but for none else) and thus the @ref orxonox::Pawn "Pawn" would receive the @ref orxonox::Quest "Quest" and when the second @ref orxonox::Pawn "Pawn" enters the range the state of the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" for that second @ref orxonox::Pawn "Pawn" would change to <em>triggered</em> and it would receive the @ref orxonox::Quest "Quest" as well.75 This difference becomes significant, when, for example, you want a @ref orxonox::DistanceTrigger "DistanceTrigger" to trigger a @ref orxonox::QuestEffectBeacon "QuestEffectBeacon" to hand out a @ref orxonox::Quest "Quest" to any @ref orxonox::Pawn "Pawn" that enters its range. With a simple @ref orxonox::DistanceTrigger "DistanceTrigger" (as opposed to the more complex @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger") the first @ref orxonox::Pawn "Pawn" to be in range would trigger it an receive the @ref orxonox::Quest "Quest", however if a second @ref orxonox::Pawn "Pawn" would enter the range, while the first @ref orxonox::Pawn "Pawn" still is in the range nothing would happen and even after the first @ref orxonox::Pawn "Pawn" left nothing would happen, since the whole time the @ref orxonox::DistanceTrigger "DistanceTrigger" would just be <em>active</em>. In contrast with a @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" the first @ref orxonox::Pawn "Pawn" would enter the range and the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" would have the state <em>active</em> for this exact @ref orxonox::Pawn "Pawn" (but for none else) and thus the @ref orxonox::Pawn "Pawn" would receive the @ref orxonox::Quest "Quest" and when the second @ref orxonox::Pawn "Pawn" enters the range the state of the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" for that second @ref orxonox::Pawn "Pawn" would change to <em>active</em> and it would receive the @ref orxonox::Quest "Quest" as well. 16 76 17 77 @section WhenToUseMultiTriggers When to use MultiTriggers … … 20 80 @section HowToUseMultiTriggers How to use MultiTriggers 21 81 ... 82 83 @section HowToCreateANewMultiTrigger How to create a new MultiTrigger. 84 ... 22 85 23 86 @section MultiTriggerTechnicalDetails Technical Details 24 A common @ref orxonox::Trigger "Trigger" is an object that can either be <em>active</em> or <em>inactive</em>, with a specified behavior how to switch between the two. A @ref orxonox::MultiTrigger "MultiTrigger" generalizes that behavior for multiple objects triggering the trigger. A @ref orxonox::MultiTrigger "MultiTrigger" can be <em>active</em> or <em>inactive</em> for any object triggering it, with the state for each object being completely independent of the state for all other objects. Each time a switch occurs an @ref orxonox::Event "Event" is fired , with a @ref orxonox::MultiTriggerContainer "MultiTriggerContainer" as the originator, containing a pointer to the @ref orxonox::MultiTrigger "MultiTrigger" that caused the @ref orxonox::Event "Event" and a pointer to the object that caused the trigger to change it's activity. This way the entity that reacts to the @ref orxonox::MultiTrigger "MultiTrigger" triggering receives the information it needs about the entity that triggered the @ref orxonox::MultiTrigger "MultiTrigger".87 A common @ref orxonox::Trigger "Trigger" is an object that can either be <em>active</em> or <em>inactive</em>, with a specified behavior how to switch between the two. A @ref orxonox::MultiTrigger "MultiTrigger" generalizes that behavior for multiple objects triggering the trigger. A @ref orxonox::MultiTrigger "MultiTrigger" can be <em>active</em> or <em>inactive</em> for any object triggering it, with the state for each object being completely independent of the state for all other objects. Each time a switch occurs an @ref orxonox::Event "Event" is fired (see the @ref Eventsystem "Eventsystem" for more information about how that works exactly), with a @ref orxonox::MultiTriggerContainer "MultiTriggerContainer" as the originator, containing a pointer to the @ref orxonox::MultiTrigger "MultiTrigger" that caused the @ref orxonox::Event "Event" and a pointer to the object that caused the trigger to change it's activity. This way the entity that reacts to the @ref orxonox::MultiTrigger "MultiTrigger" triggering receives the information it needs about the entity that triggered the @ref orxonox::MultiTrigger "MultiTrigger". 25 88 26 Also, just as with all triggers, @ref orxonox::MultiTrigger "MultiTriggers" can be nested (even twith triggers other than @ref orxonox::MultiTrigger "MultiTriggers").89 Also, just as with all triggers, @ref orxonox::MultiTrigger "MultiTriggers" can be nested (even with triggers other than @ref orxonox::MultiTrigger "MultiTriggers"). 27 90 @code 28 91 <MultiTrigger switch="true" delay="2"> … … 33 96 34 97 @ref orxonox::MultiTrigger "MultiTriggers" also allow for additional complexity which can be added through the choice of the parameters (some of which are also present in the common @ref orxonox::Trigger "Trigger") explained (briefly) below. 35 But first it is important to understand a small implementation al detail. There is a distinction between the @ref orxonox::MultiTrigger "MultiTrigger" being triggered (there is the state <em>triggered</em> for that) and the @ref orxonox::MultiTrigger "MultiTrigger" being active (for that is the state <em>activity</em>). From the outside only the <em>activity</em> is visible (and has above been referred to as <em>triggered</em> for the sake of comprehensibility). The state <em>triggered</em> tells us whether the trigger is actually triggered, but it could pretend (for some reason, some of which we will see shortly) to be <em>triggered</em> to the outside, while it in fact isn't (but it would then be <em>active</em>). The standard behavior is, that the <em>activity</em> changes, when the @ref orxonox::MultiTrigger "MultiTrigger" transits from being triggered to not being triggered or the other way around. So to the inside a @ref orxonox::MultiTrigger "MultiTrigger" being <em>active</em> is synonymous to the @ref orxonox::MultiTrigger "MultiTrigger" being <em>triggered</em> to the outside.98 But first it is important to understand a small implementation detail. There is a distinction between the @ref orxonox::MultiTrigger "MultiTrigger" being triggered (there is the state <em>triggered</em> for that) and the @ref orxonox::MultiTrigger "MultiTrigger" being active (for that is the state <em>activity</em>). From the outside only the <em>activity</em> is visible. The state <em>triggered</em> tells us whether the trigger is actually triggered, but it could pretend (for some reason, some of which we will see shortly) to be <em>active</em> to the outside, while it in fact isn't. The standard behavior is, that the <em>activity</em> changes, when the @ref orxonox::MultiTrigger "MultiTrigger" transits from being <em>triggered</em> to being <em>not triggered</em> or the other way around. 36 99 37 100 The parameters of the @ref orxonox::MultiTrigger "MultiTrigger" are: 38 - @b delay The delay is the time in seconds, that the trigger waits until it reacts (i.e. changes it's state) to the triggering condition being fulfilled. Internally this is handled by a state queue coupled with a counter, for each state that is delayed. The state becomes <em>active</em> when the counter runs out. This allows the @ref orxonox::MultiTrigger "MultiTrigger" to work even if the delay changes at runtime. However if the delay changes it only affects newly arriving states not the ones already in the queue. The default is <code>0 </code>.101 - @b delay The delay is the time in seconds, that the trigger waits until it reacts (i.e. changes it's state) to the triggering condition being fulfilled. Internally this is handled by a state queue coupled with a counter, for each state that is delayed. The state becomes <em>active</em> when the counter runs out. This allows the @ref orxonox::MultiTrigger "MultiTrigger" to work even if the delay changes at runtime. However if the delay changes it only affects newly arriving states not the ones already in the queue. The default is <code>0.0</code>. 39 102 - @b switch Switch is a boolean, if <code>true</code> the @ref orxonox::MultiTrigger "MultiTrigger" is in <em>switch-mode</em>, meaning, that the <em>activity</em> changes only when the trigger is triggered, not when it is un-triggered (Just like a light switch does). This means, that in <em>switch-mode</em> the <em>activity</em> only changes, when the trigger changes from not being triggered to being triggered but not the other way around. The default is <code>false</code>. 40 103 - @b stayActive Stay active is also a boolean, if <code>true</code> the @ref orxonox::MultiTrigger "MultiTrigger" stays active after it has been activated as many times as specified by the parameter <em>activations</em>. In essence this means, that after the last time it is activated it cannot be deactivated. The default is <code>false</code>. … … 64 127 65 128 @subsubsection DistanceMultiTrigger DistanceMultiTrigger 66 A @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" is the MultiTriggerequivalent of the @ref orxonox::DistanceTrigger "DistanceTrigger" and works just the same way. It triggers (now separately for each object triggering it, since it's a @ref orxonox::MultiTrigger "MultiTrigger") whenever an object that is a target of the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" is in the specified range.129 A @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" is the @ref orxonox::MultiTrigger "MultiTrigger" equivalent of the @ref orxonox::DistanceTrigger "DistanceTrigger" and works just the same way. It triggers (now separately for each object triggering it, since it's a @ref orxonox::MultiTrigger "MultiTrigger") whenever an object that is a target of the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" is in the specified range. 67 130 68 Two additional parameters can be specified for the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" are the <em>distance</em>, which defines the maximum distance at which an object still triggers the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger", and the <em>targetname</em>. Setting the <em>targename</em> puts the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" in <em>single-target mode</em>. In this mode the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" can only be triggered by objects that have a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" with the name specified by <em>targetname</em> directly attached. For the <em>single-target mode</em> to work the target of the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" has to be set to <code>DistanceTriggerBeacon</code>. 131 The target object can be specified further by setting the <em>beaconMode</em> and attaching a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" to the object. 132 Parameters are (additional to the ones of @ref orxonox::MultiTrigger "MultiTrigger"): 133 - @b distance Which specifies the maximum distance at which the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" still triggers. Default is <code>100</code>. 134 - @b beaconMode Which specifies, whether the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" operates on @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacons" or not. If <em>off</em> the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" works as usual. If set to <em>identify</em> the @ref orxonox::DistanceMultiTrigger "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 @ref orxonox::DistanceMultiTrigger "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>. 135 - @b targetname Which specifies the name @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacons" need to have to make the @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" react to them if it is in <em>beacon-mode</em> (the beaconMode is not <em>off</em>). 69 136 70 A common usage (without @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon") would look like this:137 A simple @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" could look like this: 71 138 @code 72 < DistanceMultiTriggerposition="0,0,0" switch="true" target="Pawn" distance="20" />139 <@ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" position="0,0,0" switch="true" target="Pawn" distance="20" /> 73 140 @endcode 74 141 75 With @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" itwould look like this:142 An implementation that only reacts to objects with a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" attached would look like this: 76 143 @code 77 < DistanceMultiTrigger position="0,0,0" target="DistanceMultiTrigger" targetname="beacon1" distance="30" />144 <@ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" position="0,0,0" target="Pawn" beaconMode="identify" targetname="beacon1" distance="30" /> 78 145 @endcode 146 This particular @ref orxonox::DistanceMultiTrigger "DistanceMultiTrigger" would only react if an object was in range, that had a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" with the name <em>beacon1</em> attached. 79 147 */ -
code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc
r8079 r8213 43 43 { 44 44 45 /*static*/ const std::string DistanceMultiTrigger::beaconModeOff_s = "off"; 46 /*static*/ const std::string DistanceMultiTrigger::beaconModeIdentify_s = "identify"; 47 /*static*/ const std::string DistanceMultiTrigger::beaconModeExlcude_s = "exclude"; 48 45 49 CreateFactory(DistanceMultiTrigger); 46 50 … … 49 53 Default Constructor. Registers the object and initializes default values. 50 54 */ 51 DistanceMultiTrigger::DistanceMultiTrigger(BaseObject* creator) : MultiTrigger(creator) 55 DistanceMultiTrigger::DistanceMultiTrigger(BaseObject* creator) : MultiTrigger(creator), beaconMask_(NULL) 52 56 { 53 57 RegisterObject(DistanceMultiTrigger); 54 58 55 59 this->distance_ = 100.0f; 60 this->setBeaconModeDirect(distanceMultiTriggerBeaconMode::off); 56 61 this->targetName_ = ""; 57 this->singleTargetMode_ = false;58 62 } 59 63 … … 64 68 DistanceMultiTrigger::~DistanceMultiTrigger() 65 69 { 66 70 if(this->beaconMask_ != NULL) 71 delete this->beaconMask_; 67 72 } 68 73 … … 76 81 77 82 XMLPortParam(DistanceMultiTrigger, "distance", setDistance, getDistance, xmlelement, mode); 83 XMLPortParam(DistanceMultiTrigger, "beaconMode", setBeaconMode, getBeaconMode, xmlelement, mode); 78 84 XMLPortParam(DistanceMultiTrigger, "targetname", setTargetName, getTargetName, xmlelement, mode); 79 85 } … … 126 132 127 133 // Check for new objects that are in range 128 for(ClassTreeMaskObjectIterator it = this->getTargetMask().begin(); it != this->getTargetMask().end(); ++it) 134 ClassTreeMask targetMask = this->getTargetMask(); 135 // If we are in identify-mode another target mask has to be applies to find the DistanceTriggerBeacons. 136 if(this->beaconMode_ == distanceMultiTriggerBeaconMode::identify) 137 targetMask = *this->beaconMask_; 138 139 // Iterate through all objects that are targets of the DistanceMultiTrigger. 140 for(ClassTreeMaskObjectIterator it = targetMask.begin(); it != targetMask.end(); ++it) 129 141 { 130 142 WorldEntity* entity = static_cast<WorldEntity*>(*it); 131 143 132 // If the DistanceMultiTrigger is in single-target mode. 133 if(this->singleTargetMode_) 134 { 135 // If the object that is a target is no DistanceTriggerBeacon, then the DistanceMultiTrigger can't be in single-target mode. 136 if(!entity->isA(ClassIdentifier<DistanceTriggerBeacon>::getIdentifier())) 144 // If the DistanceMultiTrigger is in identify-mode and the DistanceTriggerBeacon attached to the object has the wrong name we ignore it. 145 if(this->beaconMode_ == distanceMultiTriggerBeaconMode::identify) 146 { 147 if(entity->getName() != this->targetName_) 148 continue; 149 // If the object, the DistanceTriggerBeacon is attached to, is not a target of this DistanceMultiTrigger. 150 else if(this->getTargetMask().isExcluded(entity->getParent()->getIdentifier())) 151 continue; 152 } 153 154 // If the DistanceMultiTrigger is in exclude mode and the DistanceTriggerBeacon attached to the object has the right name, we ignore it. 155 if(this->beaconMode_ == distanceMultiTriggerBeaconMode::exclude) 156 { 157 158 const std::set<WorldEntity*> attached = entity->getAttachedObjects(); 159 bool found = false; 160 for(std::set<WorldEntity*>::const_iterator it = attached.begin(); it != attached.end(); it++) 137 161 { 138 this->singleTargetMode_ = false; 139 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; 162 if((*it)->isA(ClassIdentifier<DistanceTriggerBeacon>::getIdentifier()) && static_cast<DistanceTriggerBeacon*>(*it)->getName() == this->targetName_) 163 { 164 found = true; 165 break; 166 } 140 167 } 141 // If the target name and the name of the DistancTriggerBeacon don't match. 142 else if(entity->getName().compare(this->targetName_) != 0) 168 if(found) 143 169 continue; 144 170 } … … 153 179 continue; 154 180 155 // Change the entity to the parent of the DistanceTriggerBeacon (if in single-target-mode), which is the entity to which the beacon is attached.156 if(this-> singleTargetMode_)181 // Change the entity to the parent of the DistanceTriggerBeacon (if in identify-mode), which is the entity to which the beacon is attached. 182 if(this->beaconMode_ == distanceMultiTriggerBeaconMode::identify) 157 183 entity = entity->getParent(); 158 184 … … 171 197 return queue; 172 198 } 173 174 /** 175 @brief 176 Set the target name of DistanceTriggerBeacons that triggers this DistanceMultiTrigger. 177 @param targetname 178 The name of the DistanceTriggerBeacon as a string. 179 */ 180 void DistanceMultiTrigger::setTargetName(const std::string& targetname) 181 { 182 // If the targetname is no blank string single-target mode is enabled. 183 if(targetname != "") 184 this->singleTargetMode_ = true; 199 200 /** 201 @brief 202 Set the beacon mode. 203 @param mode 204 The mode as an enum. 205 */ 206 void DistanceMultiTrigger::setBeaconModeDirect(distanceMultiTriggerBeaconMode::Value mode) 207 { 208 this->beaconMode_ = mode; 209 if(this->beaconMode_ == distanceMultiTriggerBeaconMode::identify && this->beaconMask_ == NULL) 210 { 211 this->beaconMask_ = new ClassTreeMask(); 212 this->beaconMask_->exclude(Class(BaseObject)); 213 this->beaconMask_->include(Class(DistanceTriggerBeacon)); 214 } 215 } 216 217 /** 218 @brief 219 Get the beacon mode. 220 @return 221 Returns the mode as a string. 222 */ 223 const std::string& DistanceMultiTrigger::getBeaconMode(void) const 224 { 225 switch(this->getBeaconModeDirect()) 226 { 227 case distanceMultiTriggerBeaconMode::off : 228 return DistanceMultiTrigger::beaconModeOff_s; 229 case distanceMultiTriggerBeaconMode::identify: 230 return DistanceMultiTrigger::beaconModeIdentify_s; 231 case distanceMultiTriggerBeaconMode::exclude: 232 return DistanceMultiTrigger::beaconModeExlcude_s; 233 default : 234 assert(0); // This is impossible. 235 return BLANKSTRING; 236 } 237 } 238 239 /** 240 @brief 241 Set the beacon mode. 242 @param mode 243 The mode as a string. 244 */ 245 void DistanceMultiTrigger::setBeaconMode(const std::string& mode) 246 { 247 if(mode == DistanceMultiTrigger::beaconModeOff_s) 248 this->setBeaconModeDirect(distanceMultiTriggerBeaconMode::off); 249 else if(mode == DistanceMultiTrigger::beaconModeIdentify_s) 250 this->setBeaconModeDirect(distanceMultiTriggerBeaconMode::identify); 251 else if(mode == DistanceMultiTrigger::beaconModeExlcude_s) 252 this->setBeaconModeDirect(distanceMultiTriggerBeaconMode::exclude); 185 253 else 186 this->singleTargetMode_ = false; 187 188 this->targetName_ = targetname; 254 COUT(1) << "Invalid beacon mode in DistanceMultiTrigger." << endl; 189 255 } 190 256 -
code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.h
r7601 r8213 51 51 /** 52 52 @brief 53 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. 53 Enum for the beacon mode of the DistanceMultiTrigger. 54 55 @ingroup MultiTrigger 56 */ 57 namespace distanceMultiTriggerBeaconMode 58 { 59 enum Value { 60 off, //!< The DistanceMultiTrigger is not in <em>beacon-mode</em>. 61 identify, //!< The DistanceTrigger is in <em>identify-mode</em>. 62 exclude //!< The DistanceTrigger is in <em>exclude-mode</em>. 63 }; 64 } 65 66 /** 67 @brief 68 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. 54 69 Parameters are (additional to the ones of MultiTrigger): 55 - @b distance Which specifies the maximum distance at which the DistanceMultiTrigger still triggers. Default is 100. 56 - @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. 70 - @b distance Which specifies the maximum distance at which the DistanceMultiTrigger still triggers. Default is <code>100</code>. 71 - @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>. 72 - @b targetname Which specifies the name @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacons" need to have to make the DistanceMultiTrigger react to them if it is in <em>beacon-mode</em> (the beaconMode is not <em>off</em>). 57 73 58 A simple DistanceMultiTrigger would look like this:74 A simple DistanceMultiTrigger could look like this: 59 75 @code 60 76 <DistanceMultiTrigger position="0,0,0" switch="true" target="Pawn" distance="20" /> … … 63 79 An implementation that only reacts to objects with a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" attached would look like this: 64 80 @code 65 <DistanceMultiTrigger position="0,0,0" target=" DistanceMultiTrigger" targetname="beacon1" distance="30" />81 <DistanceMultiTrigger position="0,0,0" target="Pawn" beaconMode="identify" targetname="beacon1" distance="30" /> 66 82 @endcode 67 83 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. 68 84 69 85 @see MultiTrigger 70 For more information on MultiTriggers.86 For more information on @ref orxonox::MultiTrigger "MultiTriggers". 71 87 72 88 @author … … 79 95 80 96 public: 81 DistanceMultiTrigger(BaseObject* creator); // !<Default Constructor. Registers the object and initializes default values.82 virtual ~DistanceMultiTrigger(); // !<Destructor.97 DistanceMultiTrigger(BaseObject* creator); // Default Constructor. Registers the object and initializes default values. 98 virtual ~DistanceMultiTrigger(); // Destructor. 83 99 84 void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a DistanceMultiTrigger object through XML. 85 86 void setTargetName(const std::string& targetname); //!< Set the target name of DistanceTriggerBeacons that triggers this DistanceMultiTrigger. 87 /** 88 @brief Get the target name of the DistanceTriggerbeacon, that triggers this DistanceMultiTrigger. 89 @return Returns the target name as a string. 90 */ 91 inline const std::string& getTargetName(void) 92 { return this->targetName_; } 93 100 void XMLPort(Element& xmlelement, XMLPort::Mode mode); // Method for creating a DistanceMultiTrigger object through XML. 101 94 102 /** 95 103 @brief Set the distance at which the DistanceMultiTrigger triggers. … … 104 112 inline float getDistance() const 105 113 { return this->distance_; } 114 115 void setBeaconModeDirect(distanceMultiTriggerBeaconMode::Value mode); // Set the beacon mode. 116 /** 117 @brief Get the beacon mode. 118 @return Returns the mode as an enum. 119 */ 120 inline distanceMultiTriggerBeaconMode::Value getBeaconModeDirect(void) const 121 { return this->beaconMode_; } 122 void setBeaconMode(const std::string& mode); // Set the beacon mode. 123 const std::string& getBeaconMode(void) const; // Get the beacon mode. 124 125 /** 126 @brief Set the target name of DistanceTriggerBeacons that triggers this DistanceMultiTrigger. 127 @param targetname The name of the DistanceTriggerBeacon as a string. 128 */ 129 inline void setTargetName(const std::string& targetname) 130 { this->targetName_ = targetname; } 131 /** 132 @brief Get the target name of the DistanceTriggerbeacon, that triggers this DistanceMultiTrigger. 133 @return Returns the target name as a string. 134 */ 135 inline const std::string& getTargetName(void) const 136 { return this->targetName_; } 106 137 107 138 protected: 108 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.139 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. 109 140 110 bool addToRange(WorldEntity* entity); // !<Add a given entity to the entities, that currently are in range of the DistanceMultiTrigger.111 bool removeFromRange(WorldEntity* entity); // !<Remove a given entity from the set of entities, that currently are in range of the DistanceMultiTrigger.141 bool addToRange(WorldEntity* entity); // Add a given entity to the entities, that currently are in range of the DistanceMultiTrigger. 142 bool removeFromRange(WorldEntity* entity); // Remove a given entity from the set of entities, that currently are in range of the DistanceMultiTrigger. 112 143 113 144 private: 145 //! Strings for the beacon modes. 146 static const std::string beaconModeOff_s; 147 static const std::string beaconModeIdentify_s; 148 static const std::string beaconModeExlcude_s; 149 114 150 float distance_; //!< The distance at which the DistanceMultiTrigger triggers. 151 152 distanceMultiTriggerBeaconMode::Value beaconMode_; //!< The beacon mode, the DistanceMultiTrigger is in. 115 153 std::string targetName_; //!< The target name, used in <em>single-target</em> mode. 116 bool singleTargetMode_; //!< To indicate whe the MultiDistanceTrigger is in <em>single-target</em> mode.154 ClassTreeMask* beaconMask_; //!< A mask, that only accepts DistanceTriggerBeacons. 117 155 118 156 std::map<WorldEntity*, WeakPtr<WorldEntity>* > range_; //!< The set of entities that currently are in range of the DistanceMultiTrigger. -
code/trunk/src/modules/objects/triggers/DistanceTrigger.cc
r8079 r8213 37 37 #include "core/CoreIncludes.h" 38 38 #include "core/XMLPort.h" 39 39 40 #include "worldentities/pawns/Pawn.h" 41 40 42 #include "DistanceTriggerBeacon.h" 41 43 42 44 namespace orxonox 43 45 { 44 CreateFactory(DistanceTrigger); 45 46 DistanceTrigger::DistanceTrigger(BaseObject* creator) : Trigger(creator) 47 { 48 RegisterObject(DistanceTrigger); 49 50 this->distance_ = 100; 51 this->targetMask_.exclude(Class(BaseObject)); 52 this->targetName_ = ""; 53 this->singleTargetMode_ = false; 54 } 55 56 DistanceTrigger::~DistanceTrigger() 57 { 58 } 59 60 void DistanceTrigger::XMLPort(Element& xmlelement, XMLPort::Mode mode) 61 { 62 SUPER(DistanceTrigger, XMLPort, xmlelement, mode); 63 64 XMLPortParam(DistanceTrigger, "distance", setDistance, getDistance, xmlelement, mode).defaultValues(100.0f); 65 XMLPortParamLoadOnly(DistanceTrigger, "target", addTargets, xmlelement, mode).defaultValues("Pawn"); 66 XMLPortParam(DistanceTrigger, "targetname", setTargetName, getTargetName, xmlelement, mode); 67 } 68 69 void DistanceTrigger::addTarget(Ogre::Node* targetNode) 70 { 71 this->targetSet_.insert(targetNode); 72 } 73 74 void DistanceTrigger::removeTarget(Ogre::Node* targetNode) 75 { 76 int returnval = this->targetSet_.erase(targetNode); 77 if (returnval == 0) 78 { 79 COUT(2) << "Warning: Node " << targetNode << " did not exist in targetSet of trigger " << this << " !" << std::endl; 80 COUT(4) << "Content of targetSet of trigger " << this << " :" << std::endl; 81 std::set<Ogre::Node*>::iterator it; 82 for (it = this->targetSet_.begin(); it != this->targetSet_.end(); ++it) 83 { 84 COUT(4) << *it << std::endl; 85 } 86 COUT(4) << "End of targetSet of trigger " << this << std::endl; 87 } 88 } 89 90 void DistanceTrigger::addTargets(const std::string& targets) 91 { 92 Identifier* targetId = ClassByString(targets); 93 94 //! Checks whether the target is (or is derived from) a ControllableEntity. 95 Identifier* pawnId = Class(Pawn); 96 Identifier* distanceTriggerBeaconId = Class(DistanceTriggerBeacon); 97 if(targetId->isA(pawnId) || targetId->isA(distanceTriggerBeaconId)) 98 { 99 this->setForPlayer(true); 100 } 101 102 if (!targetId) 103 { 104 COUT(1) << "Error: \"" << targets << "\" is not a valid class name to include in ClassTreeMask (in " << this->getName() << ", class " << this->getIdentifier()->getName() << ')' << std::endl; 105 return; 106 } 107 108 this->targetMask_.include(targetId); 109 110 // trigger shouldn't react on itself or other triggers 111 this->targetMask_.exclude(Class(Trigger), true); 112 113 // we only want WorldEntities 114 ClassTreeMask WEMask; 115 WEMask.include(Class(WorldEntity)); 116 this->targetMask_ *= WEMask; 117 118 this->notifyMaskUpdate(); 119 } 120 121 void DistanceTrigger::removeTargets(const std::string& targets) 122 { 123 Identifier* targetId = ClassByString(targets); 124 this->targetMask_.exclude(targetId); 125 } 126 127 bool DistanceTrigger::checkDistance() 128 { 129 // Iterate through all objects 130 for (ClassTreeMaskObjectIterator it = this->targetMask_.begin(); it != this->targetMask_.end(); ++it) 131 { 132 WorldEntity* entity = orxonox_cast<WorldEntity*>(*it); 133 if (!entity) 134 continue; 135 136 // If the DistanceTrigger is in single-target mode. 137 if(this->singleTargetMode_) 138 { 139 // If the object that is a target is no DistanceTriggerBeacon, then the DistanceTrigger can't be in single-target-mode. 140 if(!(*it)->isA(ClassIdentifier<DistanceTriggerBeacon>::getIdentifier())) 141 { 142 this->singleTargetMode_ = false; 143 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; 144 } 145 // If the target name and the name of the DistancTriggerBeacon don't match. 146 else if(entity->getName().compare(this->targetName_) != 0) 147 continue; 148 } 149 150 Vector3 distanceVec = entity->getWorldPosition() - this->getWorldPosition(); 151 if (distanceVec.length() < this->distance_) 152 { 153 154 // If the target is a player (resp. is a, or is derived from a, ControllableEntity) the triggeringPlayer is set to the target entity. 155 if(this->isForPlayer()) 156 { 157 158 // Change the entity to the parent of the DistanceTriggerBeacon (if in single-target-mode), which is the entity to which the beacon is attached. 159 if(this->singleTargetMode_) 160 entity = entity->getParent(); 161 162 Pawn* player = orxonox_cast<Pawn*>(entity); 163 this->setTriggeringPlayer(player); 164 } 165 166 return true; 167 } 168 } 169 170 return false; 171 } 172 173 bool DistanceTrigger::isTriggered(TriggerMode::Value mode) 174 { 175 if (Trigger::isTriggered(mode)) 176 { 177 return checkDistance(); 178 } 179 else 180 return false; 181 } 46 47 /*static*/ const std::string DistanceTrigger::beaconModeOff_s = "off"; 48 /*static*/ const std::string DistanceTrigger::beaconModeIdentify_s = "identify"; 49 /*static*/ const std::string DistanceTrigger::beaconModeExlcude_s = "exclude"; 50 51 CreateFactory(DistanceTrigger); 52 53 /** 54 @brief 55 Constructor. Registers and initializes the object. 56 @param creator 57 The creator of this trigger. 58 */ 59 DistanceTrigger::DistanceTrigger(BaseObject* creator) : Trigger(creator), beaconMask_(NULL) 60 { 61 RegisterObject(DistanceTrigger); 62 63 this->distance_ = 100; 64 this->targetMask_.exclude(Class(BaseObject)); 65 this->targetName_ = ""; 66 } 67 68 /** 69 @brief 70 Destructor. 71 */ 72 DistanceTrigger::~DistanceTrigger() 73 { 74 // Delete the beacon mask if it exists. 75 if(this->beaconMask_ != NULL) 76 delete this->beaconMask_; 77 } 78 79 /** 80 @brief 81 Method for creating a DistanceTrigger object through XML. 82 */ 83 void DistanceTrigger::XMLPort(Element& xmlelement, XMLPort::Mode mode) 84 { 85 SUPER(DistanceTrigger, XMLPort, xmlelement, mode); 86 87 XMLPortParam(DistanceTrigger, "distance", setDistance, getDistance, xmlelement, mode).defaultValues(100.0f); 88 XMLPortParamLoadOnly(DistanceTrigger, "target", addTarget, xmlelement, mode).defaultValues("Pawn"); 89 XMLPortParam(DistanceTrigger, "beaconMode", setBeaconMode, getBeaconMode, xmlelement, mode); 90 XMLPortParam(DistanceTrigger, "targetname", setTargetName, getTargetName, xmlelement, mode); 91 } 92 93 /** 94 @brief 95 Add some target to the DistanceTrigger. 96 @param targetStr 97 The target class name as a string. 98 */ 99 void DistanceTrigger::addTarget(const std::string& targetStr) 100 { 101 Identifier* targetId = ClassByString(targetStr); 102 103 // Checks whether the target is (or is derived from) a Pawn and if so set the PlayerTrigger aspect of this trigger to be for the player, meaning, that from this Trigger one can derive the Pawn that caused it to trigger. 104 Identifier* pawnId = Class(Pawn); 105 if(targetId->isA(pawnId)) 106 this->setForPlayer(true); 107 108 if (targetId == NULL) 109 { 110 COUT(1) << "Error: \"" << targetStr << "\" is not a valid class name to include in ClassTreeMask (in " << this->getName() << ", class " << this->getIdentifier()->getName() << ')' << std::endl; 111 return; 112 } 113 114 // Add the target to the target mask. 115 this->targetMask_.include(targetId); 116 117 // The DistanceTrigger shouldn't react to itself or other triggers. 118 this->targetMask_.exclude(Class(TriggerBase), true); 119 120 // We only want WorldEntities (since only they have a position) 121 ClassTreeMask WEMask; 122 WEMask.include(Class(WorldEntity)); 123 this->targetMask_ *= WEMask; 124 125 this->notifyMaskUpdate(); // Inform interested parties that the target mask has been updated. 126 } 127 128 /** 129 @brief 130 Remove some target from the DistanceTrigger. 131 @param targetStr 132 The target class name as a string. 133 */ 134 void DistanceTrigger::removeTarget(const std::string& targetStr) 135 { 136 Identifier* targetId = ClassByString(targetStr); 137 this->targetMask_.exclude(targetId); 138 } 139 140 /** 141 @brief 142 Check, whether there are entities that are targets of this DistanceTrigger in its range. 143 @return 144 Returns true if there are valid entities in its range. 145 */ 146 bool DistanceTrigger::checkDistance() 147 { 148 // Check whether there is a cached object, it still exists and whether it is still in range, if so nothing further needs to be done. 149 if(this->cache_.get() != NULL) 150 { 151 if((this->cache_.get()->getWorldPosition() - this->getWorldPosition()).length() < this->distance_) 152 return true; 153 else 154 this->cache_.reset(); 155 } 156 157 // Check for new objects that are in range 158 ClassTreeMask targetMask = this->targetMask_; 159 // If we are in identify-mode another target mask has to be applies to find the DistanceTriggerBeacons. 160 if(this->beaconMode_ == distanceTriggerBeaconMode::identify) 161 targetMask = *this->beaconMask_; 162 163 // Iterate through all objects that are targets of the DistanceTrigger. 164 for (ClassTreeMaskObjectIterator it = targetMask.begin(); it != targetMask.end(); ++it) 165 { 166 WorldEntity* entity = static_cast<WorldEntity*>(*it); 167 168 // If the DistanceTrigger is in identify-mode and the DistanceTriggerBeacon attached to the object has the wrong name we ignore it. 169 if(this->beaconMode_ == distanceTriggerBeaconMode::identify) 170 { 171 if(entity->getName() != this->targetName_) 172 continue; 173 // If the object, the DistanceTriggerBeacon is attached to, is not a target of this DistanceMultiTrigger. 174 else if(this->targetMask_.isExcluded(entity->getParent()->getIdentifier())) 175 continue; 176 } 177 178 // If the DistanceTrigger is in exclude mode and the DistanceTriggerBeacon attached to the object has the right name, we ignore it. 179 if(this->beaconMode_ == distanceTriggerBeaconMode::exclude) 180 { 181 182 const std::set<WorldEntity*> attached = entity->getAttachedObjects(); 183 bool found = false; 184 for(std::set<WorldEntity*>::const_iterator it = attached.begin(); it != attached.end(); it++) 185 { 186 if((*it)->isA(ClassIdentifier<DistanceTriggerBeacon>::getIdentifier()) && static_cast<DistanceTriggerBeacon*>(*it)->getName() == this->targetName_) 187 { 188 found = true; 189 break; 190 } 191 } 192 if(found) 193 continue; 194 } 195 196 // Check if the entity is in range. 197 Vector3 distanceVec = entity->getWorldPosition() - this->getWorldPosition(); 198 if (distanceVec.length() < this->distance_) 199 { 200 // If the target is a player (resp. is a, or is derived from a, Pawn) the triggeringPlayer is set to the target entity. 201 if(this->isForPlayer()) 202 { 203 // Change the entity to the parent of the DistanceTriggerBeacon (if in identify-mode), which is the entity to which the beacon is attached. 204 if(this->beaconMode_ == distanceTriggerBeaconMode::identify) 205 entity = entity->getParent(); 206 207 Pawn* player = orxonox_cast<Pawn*>(entity); 208 this->setTriggeringPlayer(player); 209 } 210 211 // Add the entity to the cache. 212 this->cache_ = WeakPtr<WorldEntity>(entity); 213 214 return true; 215 } 216 } 217 218 return false; 219 } 220 221 /** 222 @brief 223 Set the beacon mode. 224 @param mode 225 The mode as an enum. 226 */ 227 void DistanceTrigger::setBeaconModeDirect(distanceTriggerBeaconMode::Value mode) 228 { 229 this->beaconMode_ = mode; 230 if(this->beaconMode_ == distanceTriggerBeaconMode::identify && this->beaconMask_ == NULL) 231 { 232 this->beaconMask_ = new ClassTreeMask(); 233 this->beaconMask_->exclude(Class(BaseObject)); 234 this->beaconMask_->include(Class(DistanceTriggerBeacon)); 235 } 236 } 237 238 /** 239 @brief 240 Get the beacon mode. 241 @return 242 Returns the mode as a string. 243 */ 244 const std::string& DistanceTrigger::getBeaconMode(void) const 245 { 246 switch(this->getBeaconModeDirect()) 247 { 248 case distanceTriggerBeaconMode::off : 249 return DistanceTrigger::beaconModeOff_s; 250 case distanceTriggerBeaconMode::identify: 251 return DistanceTrigger::beaconModeIdentify_s; 252 case distanceTriggerBeaconMode::exclude: 253 return DistanceTrigger::beaconModeExlcude_s; 254 default : 255 assert(0); // This is impossible. 256 return BLANKSTRING; 257 } 258 } 259 260 /** 261 @brief 262 Set the beacon mode. 263 @param mode 264 The mode as a string. 265 */ 266 void DistanceTrigger::setBeaconMode(const std::string& mode) 267 { 268 if(mode == DistanceTrigger::beaconModeOff_s) 269 this->setBeaconModeDirect(distanceTriggerBeaconMode::off); 270 else if(mode == DistanceTrigger::beaconModeIdentify_s) 271 this->setBeaconModeDirect(distanceTriggerBeaconMode::identify); 272 else if(mode == DistanceTrigger::beaconModeExlcude_s) 273 this->setBeaconModeDirect(distanceTriggerBeaconMode::exclude); 274 else 275 COUT(1) << "Invalid beacon mode in DistanceTrigger." << endl; 276 } 277 278 /** 279 @brief 280 Check whether the DistanceTrigger is triggered. 281 It is triggered if it is triggered according only to its mode (i.e. its sub-triggers) and if a target is in range. 282 @param 283 Returns true if it is triggered ,false if not. 284 */ 285 bool DistanceTrigger::isTriggered(TriggerMode::Value mode) 286 { 287 if (Trigger::isTriggered(mode)) 288 return checkDistance(); 289 else 290 return false; 291 } 182 292 } -
code/trunk/src/modules/objects/triggers/DistanceTrigger.h
r8079 r8213 39 39 40 40 #include <set> 41 41 42 #include "core/ClassTreeMask.h" 43 44 #include "interfaces/PlayerTrigger.h" 45 42 46 #include "Trigger.h" 43 #include "interfaces/PlayerTrigger.h"44 47 45 48 namespace orxonox 46 49 { 47 50 48 51 /** 49 52 @brief 50 51 @author 52 Benjamin Knecht 53 @author 54 Damian 'Mozork' Frick 55 53 Enum for the beacon mode of the DistanceTrigger. 54 56 55 @ingroup NormalTrigger 57 56 */ 58 class _ObjectsExport DistanceTrigger : public Trigger, public PlayerTrigger57 namespace distanceTriggerBeaconMode 59 58 { 60 public: 61 DistanceTrigger(BaseObject* creator); 62 virtual ~DistanceTrigger(); 59 enum Value { 60 off, 61 identify, 62 exclude 63 }; 64 } 63 65 64 virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); 66 /** 67 @brief 68 The DistanceTrigger is a Trigger that triggers whenever an object (that is of the specified target type) is in a specified range of the DistanceTrigger. The object can be specified further by setting the <em>beaconMode</em> and attaching a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" to the object. 69 Parameters are (additional to the ones of Trigger): 70 - @b distance Which specifies the maximum distance at which the DistanceTrigger still triggers, i.e. its range. Default is <code>100</code>. 71 - @b target Which specifies the class of objects that can trigger the DistanceTrigger. Default is <code>"Pawn"</code>. 72 - @b beaconMode Which specifies, whether the DistanceTrigger operates on @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacons" or not. If <em>off</em> the DistanceMultiTrigger works as usual. If set to <em>identify</em> the DistanceTrigger 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 DistanceTrigger 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>. 73 - @b targetname Which specifies the name @ref oroxnox::DistanceTriggerBeacon "DistanceTriggerBeacons" need to have to make the DistanceTrigger react to them if it is in <em>beacon-mode</em> (the beaconMode is not <em>off</em>). 65 74 66 void addTarget(Ogre::Node* targetNode);67 void addTargets(const std::string& targets);68 void removeTarget(Ogre::Node* targetNode);69 void removeTargets(const std::string& targets);75 A simple DistanceTrigger could look like this: 76 @code 77 <DistanceTrigger position="0,0,0" switch="true" target="Pawn" distance="20" /> 78 @endcode 70 79 71 inline void setTargetName(const std::string& targetname) 72 { if(targetname != "") this->singleTargetMode_ = true; else this->singleTargetMode_ = false; this->targetName_ = targetname; } 73 inline const std::string& getTargetName(void) 74 { return this->targetName_; } 80 An implementation that only reacts to objects with a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" attached would look like this: 81 @code 82 <DistanceTrigger position="0,0,0" target="Pawn" beaconMode="identify" targetname="beacon1" distance="30" /> 83 @endcode 84 This particular DistanceTrigger would only react if an object was in range, that had a @ref orxonox::DistanceTriggerBeacon "DistanceTriggerBeacon" with the name <em>beacon1</em> attached. 75 85 76 inline void setDistance(float distance) 77 { this->distance_ = distance; } 78 inline float getDistance() const 79 { return this->distance_; } 86 @see Trigger 87 For more information on @ref orxonox::Trigger "Triggers". 80 88 81 bool checkDistance(); 89 @author 90 Benjamin Knecht 91 @author 92 Damian 'Mozork' Frick 82 93 83 protected: 84 virtual bool isTriggered(TriggerMode::Value mode); 85 virtual void notifyMaskUpdate() {} 94 @ingroup NormalTrigger 95 */ 96 class _ObjectsExport DistanceTrigger : public Trigger, public PlayerTrigger 97 { 98 public: 99 DistanceTrigger(BaseObject* creator); // Constructor. Registers and initializes the object. 100 virtual ~DistanceTrigger(); 86 101 87 ClassTreeMask targetMask_;102 virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); // Method for creating a DistanceTrigger object through XML. 88 103 89 private: 90 std::set<Ogre::Node*> targetSet_; 91 std::string targetName_; 92 float distance_; 93 bool singleTargetMode_; 104 void addTarget(const std::string& targets); // Add some target to the DistanceTrigger. 105 void removeTarget(const std::string& targets); // Remove some target from the DistanceTrigger. 94 106 95 }; 107 /** 108 @brief Set the range of the DistanceTrigger. 109 @param distance The range to be set. 110 */ 111 inline void setDistance(float distance) 112 { this->distance_ = distance; } 113 /** 114 @brief Get the range of the DistanceTrigger. 115 @return Returns the range of the distance trigger. 116 */ 117 inline float getDistance() const 118 { return this->distance_; } 119 120 void setBeaconModeDirect(distanceTriggerBeaconMode::Value mode); // Set the beacon mode. 121 /** 122 @brief Get the beacon mode. 123 @return Returns the mode as an enum. 124 */ 125 inline distanceTriggerBeaconMode::Value getBeaconModeDirect(void) const 126 { return this->beaconMode_; } 127 void setBeaconMode(const std::string& mode); // Set the beacon mode. 128 const std::string& getBeaconMode(void) const; // Get the beacon mode. 129 130 /** 131 @brief Set the name a DistanceTriggerBeacon needs to have to make the DistanceTrigger react to it if in beacon-mode. 132 @param targetname The name as a string. 133 */ 134 inline void setTargetName(const std::string& targetname) 135 { this->targetName_ = targetname; } 136 /** 137 @brief Get the target name. 138 @return Returns the target name as a string. 139 */ 140 inline const std::string& getTargetName(void) 141 { return this->targetName_; } 142 143 bool checkDistance(); // Check, whether there are entities that are targets of this DistanceTrigger in its range. 144 145 protected: 146 virtual bool isTriggered(TriggerMode::Value mode); // Check whether the DistanceTrigger is triggered. 147 /** 148 @brief Notifies interested parties about a change of the DistanceTrigger's target mask. 149 */ 150 virtual void notifyMaskUpdate() {} 151 152 ClassTreeMask targetMask_; //!< The target mask, specifies by which types of objects the DistanceTrigger can be triggered. 153 154 private: 155 //! Strings for the beacon modes. 156 static const std::string beaconModeOff_s; 157 static const std::string beaconModeIdentify_s; 158 static const std::string beaconModeExlcude_s; 159 160 float distance_; //!< The range of the DistanceTrigger. 161 162 distanceTriggerBeaconMode::Value beaconMode_; //!< The beacon mode. 163 std::string targetName_; //!< The name a DistanceTriggerBeacon needs to have to make the DistanceTrigger react to it if in beacon-mode. 164 ClassTreeMask* beaconMask_; //!< A mask, that only accepts DistanceTriggerBeacons. 165 166 WeakPtr<WorldEntity> cache_; //!< Caches the entity that triggered the DistanceTrigger last. 167 }; 96 168 } 97 169 -
code/trunk/src/modules/objects/triggers/EventMultiTrigger.h
r7601 r8213 62 62 63 63 @see MultiTrigger 64 For more information on MultiTriggers.64 For more information on @ref orxonox::MultiTrigger "MultiTriggers". 65 65 66 66 @author -
code/trunk/src/modules/objects/triggers/EventTrigger.cc
r7601 r8213 42 42 CreateFactory(EventTrigger); 43 43 44 /** 45 @brief 46 Constructor. Registers and initializes the object. 47 @param creator 48 The creator of the EventTrigger. 49 */ 44 50 EventTrigger::EventTrigger(BaseObject* creator) : Trigger(creator) 45 51 { … … 49 55 } 50 56 57 /** 58 @brief 59 Destructor. 60 */ 51 61 EventTrigger::~EventTrigger() 52 62 { 53 63 } 54 64 65 /** 66 @brief 67 Creates an event port. 68 */ 55 69 void EventTrigger::XMLEventPort(Element& xmlelement, XMLPort::Mode mode) 56 70 { … … 60 74 } 61 75 76 /** 77 @brief 78 Check whether the EventTrigger should be triggered. 79 It should be triggered if it is triggered according just to its sub-triggers and if the last event that came in was an event that changed from not triggered to triggered. 80 */ 62 81 bool EventTrigger::isTriggered(TriggerMode::Value mode) 63 82 { -
code/trunk/src/modules/objects/triggers/EventTrigger.h
r7601 r8213 37 37 38 38 #include "objects/ObjectsPrereqs.h" 39 39 40 #include "Trigger.h" 40 41 … … 44 45 /** 45 46 @brief 47 The EventTrigger class provides a way to have a Trigger triggered by any kinds of @ref orxonox::Event "Events". 48 49 Example: 50 @code 51 <EventTrigger invert="true"> 52 <events> 53 <trigger> 54 <TriggerBase ... /> 55 <EventListener ... /> 56 </trigger> 57 </events> 58 </EventTrigger> 59 @endcode 60 61 @see Trigger 62 For more information on @ref oroxnox::Trigger "Triggers". 46 63 47 64 @author … … 53 70 { 54 71 public: 55 EventTrigger(BaseObject* creator); 72 EventTrigger(BaseObject* creator); // Constructor. Registers and initializes the object. 56 73 virtual ~EventTrigger(); 57 74 58 virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode); 75 virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode); // Creates an event port. 59 76 77 /** 78 @brief Method that is called when a new event comes in. 79 The tick call makes sure the state change takes effect immediately. 80 @param bTriggered The state of the incoming event. 81 */ 60 82 inline void trigger(bool bTriggered) 61 83 { this->bEventTriggered_ = bTriggered; this->tick(0); } 62 84 63 85 protected: 64 virtual bool isTriggered(TriggerMode::Value mode); 86 virtual bool isTriggered(TriggerMode::Value mode); // Check whether the EventTrigger should be triggered. 65 87 66 88 private: 67 bool bEventTriggered_; 89 bool bEventTriggered_; //!< Boolean to keep track of what the state of the last event was. 68 90 }; 69 91 } -
code/trunk/src/modules/objects/triggers/MultiTrigger.cc
r8193 r8213 92 92 XMLPortParam(MultiTrigger, "simultaneousTriggerers", setSimultaneousTriggerers, getSimultaneousTriggerers, xmlelement, mode); 93 93 XMLPortParam(MultiTrigger, "broadcast", setBroadcast, getBroadcast, xmlelement, mode); 94 XMLPortParamLoadOnly(MultiTrigger, "target", addTarget s, xmlelement, mode).defaultValues("Pawn"); //TODO: Remove load only94 XMLPortParamLoadOnly(MultiTrigger, "target", addTarget, xmlelement, mode).defaultValues("Pawn"); //TODO: Remove load only 95 95 96 96 COUT(4) << "MultiTrigger '" << this->getName() << "' (&" << this << ") created." << std::endl; … … 275 275 /** 276 276 @brief 277 Getwhether the MultiTrigger is active for a given object.277 Check whether the MultiTrigger is active for a given object. 278 278 @param triggerer 279 279 A pointer to the object. … … 293 293 Add some target to the MultiTrigger. 294 294 @param targetStr 295 The target as a string.296 */ 297 void MultiTrigger::addTarget s(const std::string& targetStr)295 The target class name as a string. 296 */ 297 void MultiTrigger::addTarget(const std::string& targetStr) 298 298 { 299 299 Identifier* target = ClassByString(targetStr); … … 308 308 this->targetMask_.include(target); 309 309 310 // A MultiTrigger shouldn't react to itself or other MultiTriggers.311 this->targetMask_.exclude(Class( MultiTrigger), true);310 // A MultiTrigger shouldn't react to itself or other triggers. 311 this->targetMask_.exclude(Class(TriggerBase), true); 312 312 313 313 // We only want WorldEntities … … 324 324 The target to be removed as a string. 325 325 */ 326 void MultiTrigger::removeTarget s(const std::string& targetStr)326 void MultiTrigger::removeTarget(const std::string& targetStr) 327 327 { 328 328 Identifier* target = ClassByString(targetStr); -
code/trunk/src/modules/objects/triggers/MultiTrigger.h
r7601 r8213 67 67 68 68 MultiTriggers also allow for additional complexity which can be added through the choice of the parameters explained (briefly) below: 69 But first you must understand a small implementation al detail. There is a distinction between the MultiTrigger being triggered (there is the state <em>triggered</em> for that) and the MultiTrigger being active (for that is the state <em>activity</em>). From the outside only the <em>activity</em> is visible. The state <em>triggered</em> tells us whether the trigger is actually triggered, but it could pretend (for some reason, some of which we will see shortly) to be triggered (or to the outside, active), while it in fact isn't. The standard behavior is, that the <em>activity</em> changes, when the MultiTrigger transits from being triggered to not being triggeredor the other way around.69 But first you must understand a small implementation detail. There is a distinction between the MultiTrigger being triggered (there is the state <em>triggered</em> for that) and the MultiTrigger being active (for that is the state <em>activity</em>). From the outside only the <em>activity</em> is visible. The state <em>triggered</em> tells us whether the trigger is actually triggered, but it could pretend (for some reason, some of which we will see shortly) to be <em>active</em>, while it in fact isn't. The standard behavior is, that the <em>activity</em> changes, when the MultiTrigger transits from being <em>triggered</em> to being <em>not triggered</em> or the other way around. 70 70 The parameters are: 71 71 - @b delay The delay is the time that the trigger waits until it reacts (i.e. changes it's state) to the triggering condition being fulfilled. 72 - @b switch Switch is a boolean, if true the MultiTrigger is in switch-mode, meaning, that the <em>activity</em> changes only when the trigger is triggered, this means, that now the <em>activity</em> only changes, when the trigger changes from not being triggered to being triggered but not the other way around. The default is false.73 - @b stayactive Stay active is also a boolean, if true the MultiTrigger stays active after it has been activated as many times as specified by the parameter activations. The default is false.74 - @b activations The number of activations until the trigger can't be triggered anymore. The default is -1, which is infinity.75 - @b invert Invert is a boolean, if true the trigger is in <em>invert-mode</em>, meaning, that if the triggering condition is fulfilled the MultiTrigger will have the state not triggered and and if the condition is not fulfilled it will have the state triggered. In short it just inverts the behavior of the MultiTrigger. The default is false.76 - @b simultaneousTriggerers The number of simultaneous triggerers limits the number of objects that are allowed to trigger the MultiTrigger at the same time. Or more precisely, the number of distinct objects the MultiTrigger has <em>triggered</em> states for, at each point in time. The default is -1, which denotes infinity.77 - @b mode The mode describes how the MultiTrigger acts in relation to all the triggers, that are appended to it. There are 3 modes: <em>and</em>, meaning that the MultiTrigger can only be triggered if all the appended triggers are active. <em>or</em>, meaning that the MultiTrigger can only triggered if at least one of the appended triggers is active. And <em>xor</em>, meaning that the MultiTrigger can only be triggered if one and only one appended trigger is active. Note, that I wrote <em>can only be active</em>, that implies, that there is an additional condition to the activity of the MultiTrigger and that is the fulfillment of the triggering condition (the MultiTrigger itself doesn't have one, but all derived classes should). Also bear in mind, that the activityof a MultiTrigger is still coupled to the object that triggered it. The default is <em>and</em>.72 - @b switch Switch is a boolean, if true the MultiTrigger is in <em>switch-mode</em>, meaning, that the <em>activity</em> changes only when the trigger is triggered, this means, that now the <em>activity</em> only changes, when the trigger changes from not being triggered to being triggered but not the other way around. The default is <code>false</code>. 73 - @b stayactive Stay active is also a boolean, if true the MultiTrigger stays active after it has been activated as many times as specified by the parameter <em>activations</em>. The default is <code>false</code>. 74 - @b activations The number of times the MultiTrigger can be activated until the trigger can't be triggered anymore. The default is <code>-1</code>, which denotes infinity. 75 - @b invert Invert is a boolean, if true the MultiTrigger is in <em>invert-mode</em>, meaning, that if the triggering condition is fulfilled the MultiTrigger will have the state <em>not triggered</em> and and if the condition is not fulfilled it will have the state <em>triggered</em>. In short it just inverts the behavior of the MultiTrigger. The default is <code>false</code>. 76 - @b simultaneousTriggerers The number of simultaneous triggerers limits the number of objects that are allowed to trigger the MultiTrigger at the same time. Or more precisely, the number of distinct objects the MultiTrigger has <em>triggered</em> states for, at each point in time. The default is <code>-1</code>, which denotes infinity. 77 - @b mode The mode describes how the MultiTrigger acts in relation to all the triggers, that are appended to it. There are 3 modes: <em>and</em>, meaning that the MultiTrigger can only be triggered if all the appended triggers are active. <em>or</em>, meaning that the MultiTrigger can only triggered if at least one of the appended triggers is active. And <em>xor</em>, meaning that the MultiTrigger can only be triggered if one and only one appended trigger is active. Note, that I wrote <em>can only be active</em>, that implies, that there is an additional condition to the <em>activity</em> of the MultiTrigger and that is the fulfillment of the triggering condition (the MultiTrigger itself doesn't have one, but all derived classes should). Also bear in mind, that the <em>activity</em> of a MultiTrigger is still coupled to the object that triggered it. The default is <em>and</em>. 78 78 - @b broadcast Broadcast is a boolean, if true the MutliTrigger is in <em>broadcast-mode</em>, meaning, that all trigger events that are caused by no originator (originator is NULL) are broadcast as having come from every possible originator, or more precisely as having come from all objects that are specified targets of this MultiTrigger. The default is false. 79 79 - @b target The target describes the kind of objects that are allowed to trigger this MultiTrigger. The default is @ref orxonox::Pawn "Pawn". … … 111 111 inline bool isActive(void) const 112 112 { return this->isActive(NULL); } 113 bool isActive(BaseObject* triggerer = NULL) const; //!< Getwhether the MultiTrigger is active for a given object.113 bool isActive(BaseObject* triggerer = NULL) const; //!< Check whether the MultiTrigger is active for a given object. 114 114 115 115 /** … … 158 158 void broadcast(bool status); //!< Helper method. Broadcasts an Event for every object that is a target. 159 159 160 void addTarget s(const std::string& targets); //!< Add some target to the MultiTrigger.161 void removeTarget s(const std::string& targets); //!< Remove some target from the MultiTrigger.160 void addTarget(const std::string& targets); //!< Add some target to the MultiTrigger. 161 void removeTarget(const std::string& targets); //!< Remove some target from the MultiTrigger. 162 162 163 163 /** -
code/trunk/src/modules/objects/triggers/Trigger.cc
r7601 r8213 39 39 #include "core/XMLPort.h" 40 40 #include "core/command/ConsoleCommand.h" 41 41 42 #include "Scene.h" 42 43 … … 44 45 { 45 46 46 SetConsoleCommand("Trigger", "debugFlares", &Trigger::debugFlares).defaultValues(false); 47 48 CreateFactory(Trigger); 49 50 Trigger::Trigger(BaseObject* creator) : TriggerBase(creator) 51 { 52 RegisterObject(Trigger); 53 54 this->bActive_ = false; 55 this->bTriggered_ = false; 56 this->latestState_ = 0x0; 57 58 this->remainingTime_ = 0.0f; 59 this->timeSinceLastEvent_ = 0.0f; 60 61 // this->bUpdating_ = false; 62 63 if (this->getScene() && GameMode::showsGraphics()) 64 { 65 this->debugBillboard_.setBillboardSet(this->getScene()->getSceneManager(), "Examples/Flare", ColourValue(1.0, 0.0, 0.0), 1); 66 this->debugBillboard_.setVisible(false); 67 68 if (this->debugBillboard_.getBillboardSet()) 69 this->attachOgreObject(this->debugBillboard_.getBillboardSet()); 70 } 71 72 this->setSyncMode(0x0); 73 } 74 75 Trigger::~Trigger() 76 { 77 } 78 79 void Trigger::XMLPort(Element& xmlelement, XMLPort::Mode mode) 80 { 81 SUPER(Trigger, XMLPort, xmlelement, mode); 82 } 83 84 void Trigger::tick(float dt) 85 { 86 if(this->bFirstTick_) 87 { 88 this->bFirstTick_ = false; 89 this->triggered(false); 90 } 91 92 // Check if the object is active (this is NOT Trigger::isActive()!) 93 if (!this->BaseObject::isActive()) 94 return; 95 96 SUPER(Trigger, tick, dt); 97 98 bool newTriggered = this->isTriggered() ^ this->getInvert(); 99 100 // check if new triggering event is really new 101 if ((this->latestState_ & 0x1) != newTriggered) 102 { 103 // create new state 104 if (newTriggered) 105 { 106 this->latestState_ |= 1; // set trigger bit to 1 107 this->switchState(); 108 } 109 else 110 { 111 this->latestState_ &= 0xFE; // set trigger bit to 0 112 if (!this->getSwitch()) 113 this->switchState(); 114 } 115 } 116 117 if (this->remainingTime_ > 0.0) 118 { 119 this->remainingTime_ -= dt; 120 // only increase when acctually waiting for a state in the queue 121 if (this->timeSinceLastEvent_ >= 0.0) 122 this->timeSinceLastEvent_ += dt; 123 } 124 125 while (this->remainingTime_ <= 0.0 && this->stateChanges_.size() > 0) 126 { 127 // time ran out, change state to new one 128 char newState = this->stateChanges_.front().second; 129 this->bTriggered_ = (newState & 0x1); 130 this->bActive_ = newState & 2; 131 this->triggered(this->bActive_); 132 this->stateChanges_.pop(); 133 if (this->stateChanges_.size() != 0) 134 this->remainingTime_ = this->stateChanges_.front().first; 135 else 47 SetConsoleCommand("Trigger", "debugFlares", &Trigger::debugFlares).defaultValues(false); 48 49 CreateFactory(Trigger); 50 51 /** 52 @brief 53 Constructor. Registers and initializes the object. 54 @param creator 55 The creator of the Trigger. 56 */ 57 Trigger::Trigger(BaseObject* creator) : TriggerBase(creator) 58 { 59 RegisterObject(Trigger); 60 61 this->bActive_ = false; 62 this->bTriggered_ = false; 63 this->latestState_ = 0x0; 64 65 this->remainingTime_ = 0.0f; 66 this->timeSinceLastEvent_ = 0.0f; 67 68 // Set the debug billboard. 69 if (this->getScene() && GameMode::showsGraphics()) 70 { 71 this->debugBillboard_.setBillboardSet(this->getScene()->getSceneManager(), "Examples/Flare", ColourValue(1.0, 0.0, 0.0), 1); 72 this->debugBillboard_.setVisible(false); 73 74 if (this->debugBillboard_.getBillboardSet()) 75 this->attachOgreObject(this->debugBillboard_.getBillboardSet()); 76 } 77 78 this->setSyncMode(0x0); 79 } 80 81 /** 82 @brief 83 Destructor. 84 */ 85 Trigger::~Trigger() 86 { 87 88 } 89 90 /** 91 @brief 92 Method for creating a Trigger object through XML. 93 */ 94 void Trigger::XMLPort(Element& xmlelement, XMLPort::Mode mode) 95 { 96 SUPER(Trigger, XMLPort, xmlelement, mode); 97 } 98 99 /** 100 @brief 101 102 @param dt 103 The time elapsed since last tick. 104 */ 105 void Trigger::tick(float dt) 106 { 107 // If this is the first tick, announce, that the trigger is not triggered. 108 // This is needed, e.g. for an inverted trigger, that needs to announce at the beginning, that it is active. 109 if (this->bFirstTick_) 110 { 111 this->bFirstTick_ = false; 112 this->triggered(false); 113 } 114 115 // Check if the object is active (this is NOT Trigger::isActive()!) 116 // If the object is not active we do nothing. 117 if (!this->BaseObject::isActive()) 118 return; 119 120 SUPER(Trigger, tick, dt); 121 122 // Apply the invert operation. 123 bool newTriggered = this->isTriggered() ^ this->getInvert(); 124 125 // Check if new triggering event is really new. (i.e. if the previous triggering state is not the same as the current) 126 if ((this->latestState_ & 0x1) != newTriggered) 127 { 128 // Create new state 129 if (newTriggered) 130 { 131 this->latestState_ |= 1; // Set triggered bit to 1. 132 this->switchState(); // Toggle the activity of the trigger. 133 } 134 else 135 { 136 this->latestState_ &= 0xFE; // Set triggered bit to 0. 137 // If this trigger is not in switched-mode (i.e. it switches its activity only if it changes from not triggered to triggered and not the other way around), the activity of the trigger is toggled. 138 if (!this->getSwitch()) 139 this->switchState(); 140 } 141 } 142 143 // If there is time remaining, i.e. there are states in the queue waiting to take effect. 144 if (this->remainingTime_ > 0.0) 145 { 146 // Discount the last tick time from the time remaining. 147 this->remainingTime_ -= dt; 148 // Increase the time since the last event (the time since the last state took effect), but only when actually waiting for a state in the queue 149 if (this->timeSinceLastEvent_ >= 0.0) 150 this->timeSinceLastEvent_ += dt; 151 } 152 153 // If the remaining time has run out and there are states in the queue waiting to take effect. 154 while (this->remainingTime_ <= 0.0 && this->stateChanges_.size() > 0) 155 { 156 // Get the state to take effect and apply it. 157 char newState = this->stateChanges_.front().second; 158 this->bTriggered_ = (newState & 0x1); 159 this->bActive_ = newState & 0x2; 160 161 // Fire a triggered (or un-triggered, depending on the activity) event. 162 this->triggered(this->bActive_); 163 164 // Remove the state that was just applied from the queue. 165 this->stateChanges_.pop(); 166 167 // If there are still states in the queue, set the remaining time to the time of the next state to take effect. 168 if (this->stateChanges_.size() != 0) 169 this->remainingTime_ = this->stateChanges_.front().first; 170 // Else the time since the last event is set to the delay. 171 else 172 this->timeSinceLastEvent_ = this->getDelay(); 173 } 174 175 // Set the color of the debug billboard according to the current state of the trigger. 176 if (this->bTriggered_ && this->bActive_) 177 this->setBillboardColour(ColourValue(0.5, 1.0, 0.0)); 178 else if (!this->bTriggered_ && this->bActive_) 179 this->setBillboardColour(ColourValue(0.0, 1.0, 0.0)); 180 else if (this->bTriggered_ && !this->bActive_) 181 this->setBillboardColour(ColourValue(1.0, 0.5, 0.0)); 182 else 183 this->setBillboardColour(ColourValue(1.0, 0.0, 0.0)); 184 } 185 186 /** 187 @brief 188 Fires an event with the input triggered state. 189 @param bIsTriggered 190 The triggered state. 191 */ 192 void Trigger::triggered(bool bIsTriggered) 193 { 194 this->fireEvent(bIsTriggered); 195 } 196 197 /** 198 @brief 199 Check whether the Trigger should be triggered, given only its sub-triggers, given a specific mode. 200 @param mode 201 The Trigger mode. Specifies how the sub-triggers are combined and how they affect the Trigger. 202 @return 203 Returns true if the Trigger should be triggered and false if not. 204 */ 205 bool Trigger::isTriggered(TriggerMode::Value mode) 206 { 207 // If the trigger has sub-triggers. 208 if (this->children_.size() > 0) 209 { 210 switch (mode) 211 { 212 case TriggerMode::EventTriggerAND: 213 return checkAnd(); 214 case TriggerMode::EventTriggerOR: 215 return checkOr(); 216 case TriggerMode::EventTriggerXOR: 217 return checkXor(); 218 default: 219 return false; 220 } 221 } 222 // If the trigger has no sub-triggers, whether it is triggered should only depend on itself and nothing else, thus this returns true. 223 return true; 224 } 225 226 /** 227 @brief 228 Check whether all the sub-triggers of this Trigger are active. 229 This is in fact the conjunction (logical AND) of the activity of all its sub-triggers. 230 @return 231 Returns true if all the sub-triggers of this Trigger are active, false if at least one of them is not active. 232 */ 233 bool Trigger::checkAnd() 234 { 235 // Iterate over all sub-triggers. 236 for (std::set<TriggerBase*>::iterator it = this->children_.begin(); it != this->children_.end(); ++it) 237 { 238 if (!(*it)->isActive()) 239 return false; 240 } 241 return true; 242 } 243 244 /** 245 @brief 246 Check whether at least one of the sub-triggers of this Trigger is active. 247 This is in fact the disjunction (logical OR) of the activity of all its sub-triggers. 248 @return 249 Returns true if at least one of the sub-triggers of this Trigger is active, false if none of them is active. 250 */ 251 bool Trigger::checkOr() 252 { 253 // Iterate over all sub-triggers. 254 for (std::set<TriggerBase*>::iterator it = this->children_.begin(); it != this->children_.end(); ++it) 255 { 256 if ((*it)->isActive()) 257 return true; 258 } 259 return false; 260 } 261 262 /** 263 @brief 264 Check whether exactly one of the sub-triggers of this Trigger is active. 265 This is in fact the logical XOR of the activity of all its sub-triggers. 266 @return 267 Returns true if exactly one of the sub-triggers of this Trigger is active, false if none of them or two or more of them are active. 268 */ 269 bool Trigger::checkXor() 270 { 271 bool test = false; 272 for (std::set<TriggerBase*>::iterator it = this->children_.begin(); it != this->children_.end(); ++it) 273 { 274 if (test && (*it)->isActive()) 275 return false; 276 if ((*it)->isActive()) 277 test = true; 278 } 279 return test; 280 } 281 282 /** 283 @brief 284 Switch (toggle) the activity of the Trigger. 285 @return 286 Returns true if the activity of the Trigger has changed. False if not. 287 */ 288 bool Trigger::switchState() 289 { 290 // If the previous state was active and there are no remaining activations, but the trigger stays active. 291 // or if the previous state was inactive and there are no remaining activations. 292 // the activity is not switched. 293 if (( (this->latestState_ & 0x2) && this->getStayActive() && (this->remainingActivations_ <= 0)) 294 || (!(this->latestState_ & 0x2) && (this->remainingActivations_ == 0))) 295 return false; 296 // Else the activity is switched. 297 else 298 { 299 this->latestState_ ^= 0x2; // Toggle activity bit. 300 301 // If the activity has switched to active, decrease the remaining activations. 302 if (this->latestState_ & 0x2 && this->remainingActivations_ > 0) 303 this->remainingActivations_--; 304 305 // Store the new state in the queue. 306 this->storeState(); 307 308 return true; 309 } 310 } 311 312 /** 313 @brief 314 Stores the state in the queue. 315 The queue is a list of states that are waiting to take effect paired with the time it has to wait after its preceding state takes effect. 316 */ 317 void Trigger::storeState() 318 { 319 // Put the state change into the queue. 320 this->stateChanges_.push(std::pair<float, char>(this->timeSinceLastEvent_, this->latestState_)); 321 // Reset time since last event 322 this->timeSinceLastEvent_ = 0.0; 323 324 // If there is just one state in the queue. (i.e. the one that we just added), The remaining time is set to the time it takes for the next state to take effect. 325 if (this->stateChanges_.size() == 1) 326 this->remainingTime_ = this->stateChanges_.front().first; 327 } 328 329 /** 330 @brief 331 React to a change in delay. 332 Only newly arriving states are affected by a change in delay. 333 */ 334 void Trigger::delayChanged(void) 335 { 136 336 this->timeSinceLastEvent_ = this->getDelay(); 137 337 } 138 338 139 if (this->bTriggered_ && this->bActive_) 140 this->setBillboardColour(ColourValue(0.5, 1.0, 0.0)); 141 else if (!this->bTriggered_ && this->bActive_) 142 this->setBillboardColour(ColourValue(0.0, 1.0, 0.0)); 143 else if (this->bTriggered_ && !this->bActive_) 144 this->setBillboardColour(ColourValue(1.0, 0.5, 0.0)); 145 else 146 this->setBillboardColour(ColourValue(1.0, 0.0, 0.0)); 147 } 148 149 void Trigger::triggered(bool bIsTriggered) 150 { 151 this->fireEvent(bIsTriggered); 152 } 153 154 bool Trigger::isTriggered(TriggerMode::Value mode) 155 { 156 // if (this->bUpdating_) 157 // return this->bTriggered_; 158 159 // this->bUpdating_ = true; 160 if (this->children_.size() != 0) 161 { 162 bool returnval = false; 163 164 switch (mode) 165 { 166 case TriggerMode::EventTriggerAND: 167 returnval = checkAnd(); 168 break; 169 case TriggerMode::EventTriggerOR: 170 returnval = checkOr(); 171 break; 172 case TriggerMode::EventTriggerXOR: 173 returnval = checkXor(); 174 break; 175 default: 176 returnval = false; 177 break; 178 } 179 // this->bUpdating_ = false; 180 181 return returnval; 182 } 183 return true; 184 } 185 186 bool Trigger::checkAnd() 187 { 188 std::set<TriggerBase*>::iterator it; 189 for(it = this->children_.begin(); it != this->children_.end(); ++it) 190 { 191 if (!(*it)->isActive()) 192 return false; 193 } 194 return true; 195 } 196 197 bool Trigger::checkOr() 198 { 199 std::set<TriggerBase*>::iterator it; 200 for(it = this->children_.begin(); it != this->children_.end(); ++it) 201 { 202 if ((*it)->isActive()) 203 return true; 204 } 205 return false; 206 } 207 208 bool Trigger::checkXor() 209 { 210 std::set<TriggerBase*>::iterator it; 211 bool test = false; 212 for(it = this->children_.begin(); it != this->children_.end(); ++it) 213 { 214 if (test && (*it)->isActive()) 215 return false; 216 if ((*it)->isActive()) 217 test = true; 218 } 219 return test; 220 } 221 222 bool Trigger::switchState() 223 { 224 if (( (this->latestState_ & 2) && this->getStayActive() && (this->remainingActivations_ <= 0)) 225 || (!(this->latestState_ & 2) && (this->remainingActivations_ == 0))) 226 return false; 227 else 228 { 229 this->latestState_ ^= 2; // toggle state bit 230 231 // increase activation count 232 if (this->latestState_ & 2 && this->remainingActivations_ > 0) 233 this->remainingActivations_--; 234 235 this->storeState(); 236 237 return true; 238 } 239 } 240 241 void Trigger::storeState() 242 { 243 // put state change into queue 244 this->stateChanges_.push(std::pair<float, char>(this->timeSinceLastEvent_, this->latestState_)); 245 // reset time since last event 246 this->timeSinceLastEvent_ = 0.0; 247 248 if (this->stateChanges_.size() == 1) 249 this->remainingTime_ = this->stateChanges_.front().first; 250 } 251 252 void Trigger::delayChanged(void) 253 { 254 this->timeSinceLastEvent_ = this->getDelay(); 255 } 256 257 void Trigger::debugFlares(bool bVisible) 258 { 259 for (ObjectList<Trigger>::iterator it = ObjectList<Trigger>::begin(); it != ObjectList<Trigger>::end(); ++it) 260 it->setVisible(bVisible); 261 } 262 263 void Trigger::setBillboardColour(const ColourValue& colour) 264 { 265 this->debugBillboard_.setColour(colour); 266 } 267 268 void Trigger::changedVisibility() 269 { 270 SUPER(Trigger, changedVisibility); 271 272 this->debugBillboard_.setVisible(this->isVisible()); 273 } 339 /** 340 @brief 341 Set the visibility of all debug billboards of all Triggers. 342 @param bVisible 343 The visibility the billboards are set to. 344 */ 345 void Trigger::debugFlares(bool bVisible) 346 { 347 // Iterate over all Triggers. 348 for (ObjectList<Trigger>::iterator it = ObjectList<Trigger>::begin(); it != ObjectList<Trigger>::end(); ++it) 349 it->setVisible(bVisible); 350 } 351 352 /** 353 @brief 354 Set the colour of the debug billboard. 355 @param colour 356 The colour the billboard is set to. 357 */ 358 void Trigger::setBillboardColour(const ColourValue& colour) 359 { 360 this->debugBillboard_.setColour(colour); 361 } 362 363 /** 364 @brief 365 React to a change of visibility of the trigger by adjusting the visibility of the debug billboards. 366 */ 367 void Trigger::changedVisibility() 368 { 369 SUPER(Trigger, changedVisibility); 370 371 this->debugBillboard_.setVisible(this->isVisible()); 372 } 274 373 } -
code/trunk/src/modules/objects/triggers/Trigger.h
r7601 r8213 48 48 { 49 49 50 /** 51 @brief 52 53 @author 54 Benjamin Knecht 50 /** 51 @brief 52 A Trigger is an object that can either be <em>active</em> or <em>inactive</em>, with a specified behavior how to switch between the two. Each time a switch occurs an @ref orxonox::Event "Event" is fired with as the originator the Trigger that caused the @ref orxonox::Event "Event". 53 54 Triggers also allow for additional complexity which can be added through the choice of the parameters explained below: 55 But first it is imperative to understand a small implementation detail. There is a distinction between the Trigger being triggered (there is the state <em>triggered</em> for that) and the Trigger being active (for that is the state <em>activity</em>). From the outside only the <em>activity</em> is visible. The state <em>triggered</em> tells us whether the trigger is actually triggered, but it could pretend (for some reason, some of which we will see shortly) to be <em>active</em>, while it in fact isn't. The standard behavior is, that the <em>activity</em> changes, when the Trigger transits from being <em>triggered</em> to being <em>not triggered</em> or the other way around. 56 The parameters are: 57 - @b delay The delay is the time that the trigger waits until it reacts (i.e. changes it's state) to the triggering condition being fulfilled. 58 - @b switch Switch is a boolean, if true the Trigger is in <em>switch-mode</em>, meaning, that the <em>activity</em> changes only when the trigger is triggered, this means, that now the <em>activity</em> only changes, when the trigger changes from not being triggered to being triggered but not the other way around. The default is <code>false</code>. 59 - @b stayactive Stay active is also a boolean, if true the Trigger stays active after it has been activated as many times as specified by the parameter <em>activations</em>. The default is <code>false</code>. 60 - @b activations The number of times the Trigger can be activated until the trigger can't be triggered anymore. The default is <code>-1</code>, which denotes infinity. 61 - @b invert Invert is a boolean, if true the Trigger is in <em>invert-mode</em>, meaning, that if the triggering condition is fulfilled the Trigger will have the state <em>not triggered</em> and and if the condition is not fulfilled it will have the state <em>triggered</em>. In short it just inverts the behavior of the Trigger. The default is <code>false</code>. 62 - @b mode The mode describes how the Trigger acts in relation to all the triggers, that are appended to it. There are 3 modes: <em>and</em>, meaning that the Trigger can only be triggered if all the appended triggers are active. <em>or</em>, meaning that the Trigger can only triggered if at least one of the appended triggers is active. And <em>xor</em>, meaning that the Trigger can only be triggered if one and only one appended trigger is active. Note, that I wrote <em>can only be active</em>, that implies, that there is an additional condition to the <em>activity</em> of the Trigger and that is the fulfillment of the triggering condition (the Trigger itself doesn't have one, but all derived classes should). Also bear in mind, that the <em>activity</em> of a Trigger is still coupled to the object that triggered it. The default is <em>and</em>. 63 - Also there is the possibility of appending triggers (as long as they inherit from TriggerBase) to the Trigger just by adding them as children in the XML description of your Trigger. 55 64 56 @ingroup NormalTrigger 57 */ 58 class _ObjectsExport Trigger : public TriggerBase 59 { 60 public: 61 Trigger(BaseObject* creator); 62 virtual ~Trigger(); 65 An example of a Trigger created through XML would look like this: 66 @code 67 <Trigger position="0,0,0" delay="1.3" switch="true" stayactive="true" activations="7" invert="true" mode="xor" broadcast="false" target="Pawn"> 68 <TriggerBase /> 69 ... 70 <TriggerBase /> 71 </Trigger> 72 @endcode 63 73 64 virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);65 virtual void tick(float dt);74 @author 75 Benjamin Knecht 66 76 67 inline bool isActive(void) const 68 { return this->bActive_; } 77 @ingroup NormalTrigger 78 */ 79 class _ObjectsExport Trigger : public TriggerBase 80 { 81 public: 82 Trigger(BaseObject* creator); // Constructor. Registers and initializes the object. 83 virtual ~Trigger(); 69 84 70 inline void setVisible(bool visibility)71 { this->debugBillboard_.setVisible(visibility); }85 virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); // Method for creating a Trigger object through XML. 86 virtual void tick(float dt); 72 87 73 void delayChanged(void); 88 /** 89 @brief Check whether the Trigger is active. 90 @return Returns if the Trigger is active. 91 */ 92 inline bool isActive(void) const 93 { return this->bActive_; } 74 94 75 bool switchState();95 void delayChanged(void); // React to a change in delay. 76 96 77 static void debugFlares(bool bVisible);78 virtual void changedVisibility();97 static void debugFlares(bool bVisible); // Set the visibility of all debug billboards of all Triggers. 98 virtual void changedVisibility(); // React to a change of visibility of the trigger by adjusting the visibility of the debug billboards. 79 99 80 protected: 81 inline bool isTriggered() { return this->isTriggered(this->mode_); } 82 virtual bool isTriggered(TriggerMode::Value mode); 83 virtual void triggered(bool bIsTriggered); 100 protected: 101 /** 102 @brief Check whether the Trigger is triggered according to its mode. 103 @return Returns true if the Trigger is triggered, false if not. 104 */ 105 inline bool isTriggered() 106 { return this->isTriggered(this->mode_); } 107 virtual bool isTriggered(TriggerMode::Value mode); // Check whether the Trigger should be triggered, given only its sub-triggers, given a specific mode. 108 virtual void triggered(bool bIsTriggered); // Fires an event with the input triggered state. 84 109 85 private: 86 bool checkAnd(); 87 bool checkOr(); 88 bool checkXor(); 89 void setBillboardColour(const ColourValue& colour); 90 void storeState(); 110 private: 111 bool switchState(); // Switch (toggle) the activity (to the outside the triggered state) of the trigger. 112 void storeState(); // Stores the state in the queue. 113 114 bool checkAnd(); // Check whether all the sub-triggers of this Trigger are active. 115 bool checkOr(); // Check whether at least one of the sub-triggers of this Trigger is active. 116 bool checkXor(); // Check whether exactly one of the sub-triggers of this Trigger is active. 117 118 void setBillboardColour(const ColourValue& colour); // Set the colour of the debug billboard. 91 119 92 bool bActive_;93 bool bTriggered_;120 bool bActive_; //!< Whether the trigger is active (to the outside triggered). 121 bool bTriggered_; //!< Whether the trigger is triggered (to the inside). 94 122 95 char latestState_;96 float remainingTime_;97 float timeSinceLastEvent_;123 char latestState_; //!< Temporarily stores a state consisting of whether the trigger is triggeres at the first bit (least significant bit) and its activity at the second bit. 124 float remainingTime_; //!< The time until the next state (in the queue) takes effect. 125 float timeSinceLastEvent_; //!< The time since the last event came in. 98 126 99 // bool bUpdating_; 100 BillboardSet debugBillboard_; 127 BillboardSet debugBillboard_; //!< A set of debug billboards to visualize the state of the trigger. 101 128 102 std::queue<std::pair<float, char> > stateChanges_;103 };129 std::queue<std::pair<float, char> > stateChanges_; //!< A queue of state changes (in the same format as latestState_) paired with the time they will take effect since the last state change took effect. 130 }; 104 131 105 132 } -
code/trunk/src/modules/objects/triggers/TriggerBase.h
r8193 r8213 64 64 /** 65 65 @brief 66 The TriggerBase class is a base class for the two types of triggers, the (normal) @ref orxonox::Trigger "Triggers" and the @ref orxonox::MultiTrigger "MultiTriggers", it encompasses the shared data and functionality between these two types of triggers, but is in itself not a trigger that has any meaningful behavio ur and thus should not be instantiated.66 The TriggerBase class is a base class for the two types of triggers, the (normal) @ref orxonox::Trigger "Triggers" and the @ref orxonox::MultiTrigger "MultiTriggers", it encompasses the shared data and functionality between these two types of triggers, but is in itself not a trigger that has any meaningful behavior and thus should not be instantiated. 67 67 68 68 @author … … 81 81 82 82 /** 83 @brief Check whether the trigger is active. 83 @brief Check whether the trigger is active. (i.e. triggered to the outside) 84 84 @return Returns if the trigger is active. 85 85 */
Note: See TracChangeset
for help on using the changeset viewer.