Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/objects/triggers/MultiTrigger.h @ 7018

Last change on this file since 7018 was 6864, checked in by dafrick, 15 years ago

Created a new MutliTrigger: EventMultiTrigger, which essentially does the same as EventTrigger but for every object that is a target as specified by teh EventMultiTrigger an Event is fired with information as being triggered by the target object.
This allows, e.g. to use the EventMultiTrigger to trigger QuestEffectBeacons.
I've also added a fireEvent() to Pawn such that an Event is fired when the Pawn is destroyed (forcebly). With EventMultiTrigger (but also with EventTrigger) one can now find out whether a Pawn died.
Here a little piece of example XML code to illustrate the usage:
<EventMutliTrigger name="trigger1">

<events>

<trigger>

<Spaceship />

</trigger>

</events>

</EventMultiTrigger>
To be able to implement this another feature was added to MultiTrigger, which is called broadcast. If enabled the MultiTrigger sends all Events triggered by NULL as to have come by all possible triggerers.

Additionally I've fixed a bug:
In DistanceMultiTrigger, an infinite loop occured under some circumstances. Not any more.

And did some niceifying (aka. documenting, renaming and code restructuring).

File size: 16.8 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Damian 'Mozork' Frick
24 *   Co-authors:
25 *      Benjamin Knecht
26 *
27*/
28
29/**
30    @file MultiTrigger.h
31    @brief Definition of the MultiTrigger class.
32*/
33
34#ifndef _MultiTrigger_H__
35#define _MultiTrigger_H__
36
37#include "objects/ObjectsPrereqs.h"
38
39#include "core/BaseObject.h"
40#include "core/ClassTreeMask.h"
41
42#include <set>
43#include <deque>
44
45#include "tools/interfaces/Tickable.h"
46#include "worldentities/StaticEntity.h"
47
48namespace orxonox
49{
50
51    //! The different modes the MultiTrigger can be in.
52    namespace MultiTriggerMode
53    {
54        enum Value
55        {
56            EventTriggerAND,
57            EventTriggerOR,
58            EventTriggerXOR,
59        };
60    }
61
62    //! Struct to handle MultiTrigger states internally.
63    struct MultiTriggerState
64    {
65        BaseObject* originator;
66        bool bTriggered;
67    };
68
69    /**
70    @brief
71        The MultiTrigger class implements a trigger that has a distinct state for each object triggering it.
72        In more detail: A Trigger is an object that can either be active or inactive, whith a specified behaviour how to switch between the two. A MultiTrigger generalizes that behaviour for multiple objects trigggering the trigger. A MultiTrigger can be active or inactive for any object triggering it, with the state for each object being completely independent of the state for other objects. Each time a switch occurs an Event is fired with as the originator a MultiTriggerContainer, containig a pointer to the pointer that caused the Event and a pointer to the object that caused the trigger to change it's activity.
73
74        MultiTriggers also allow for additional complexity which can be added trough the choice of the parameters explained (briefly) below:
75        But first you must understand a small implementational detail. There is a distinction between the MultiTrigger being triggered (there is the state 'triggered' for that) and the MultiTrigger being active (for that is the state 'activity'). From the outside only the activity is visible. The state 'triggered' 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 behaviour is, that the cativity changes, when the MultiTrigger transits from being triggered to not being triggered or the other way around.
76        The parameters are:
77            '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.
78            'switch':                   Switch is a bool, if true the MultiTrigger is in switch-mode, meaning, that the activity changes only when the trigger is triggered , this means, that now the activity only changes, when the trigger changes from not being triggered to being triggered but not the other way around. The default is false.
79            'stayactive':               Stay active is also a bool, if true the MultiTrigger stays active after it has been activated as many times as specified by the parameter activations. The default is -1, which is infinity.
80            'activations':              The number of activations until the trigger can't be triggered anymore. The default is -1, which is infinity.
81            'invert':                   Invert is a bool, if true the trigger is in invert-mode, 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 behaviour of the MultiTrigger. The default is false.
82            'simultaniousTriggerers':   The number of simultanious triggerers limits the number of object that are allowed to trigger the MultiTrigger at the same time. Or a little more precisely, the number of distinct objects the MultiTrigger has 'triggered' states for, at each point in time.
83            'mode':                     The mode describes how the MultiTrigger acts in relation to all the MultiTriggers, that are appended to it. There are 3 modes: 'and', meaning that the MultiTrigger can only be triggered if all the appended MultiTriggers are active. 'or', meaning that the MultiTrigger can only triggered if at least one of the appendend MultiTriggers is active. And 'xor', meaning that the MultiTrigger can only be triggered if one and only one appended MultiTrigger is active. Notice, that I wrote 'can only be active', that implies, that there is an addtitional 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 activity of a MultiTrigger is still coupled to the object that triggered it. The default is 'and'.
84            'broadcast'                 Broadcast is a bool, if true the MutliTrigger is in broadcast-mode, meaining, that all trigger events that are caused by no originator (originator is NULL) are broadcasted as having come from every possible originator, or more precisely as having come from all objects that are specified targets of this MultiTrigger.
85            'target':                   The target describes the kind of objects that are allowed to trigger this MultiTrigger. The default is 'Pawn'.
86            Also there is the possibility of appending MultiTriggers to the MultiTrigger just by adding them as subobjects in the XML description of your MultiTrigger.
87
88    @author
89        Damian 'Mozork' Frick
90    */
91    class _ObjectsExport MultiTrigger : public StaticEntity, public Tickable
92    {
93        public:
94            MultiTrigger(BaseObject* creator); //!< Constructor. Registers the objects and initializes default values.
95            ~MultiTrigger(); //!< Destructor.
96           
97            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a MultiTrigger object through XML.
98            virtual void tick(float dt); //!< A method that is executed each tick.
99           
100            bool isActive(BaseObject* triggerer = NULL); //!< Get whether the MultiTrigger is active for a given object.
101
102            /**
103            @brief Set the delay of the MultiTrigger.
104            @param delay The delay to be set.
105            */
106            inline void setDelay(float delay)
107                { if(delay > 0) this->delay_= delay; }
108            /**
109            @brief Get the delay of the MultiTrigger.
110            @return The delay.
111            */
112            inline float getDelay(void) const
113                { return this->delay_; }
114
115            /**
116            @brief Set switch-mode of the MultiTrigger.
117            @param bSwitch If true the MultiTrigger is set to switched.
118            */
119            inline void setSwitch(bool bSwitch)
120                { this->bSwitch_ = bSwitch; }
121            /**
122            @brief Get the switch-mode of the MultiTrigger.
123            @return Returns true if the MultiTriger is in switch-mode.
124            */
125            inline bool getSwitch(void) const
126                { return this->bSwitch_; }
127
128            /**
129            @brief Set the stay-active-mode of the MultiTrigger.
130            @param bStayActive If true the MultiTrigger is set to stay active.
131            */
132            inline void setStayActive(bool bStayActive)
133                { this->bStayActive_ = bStayActive; }
134            /**
135            @brief Get the stay-active-mode of the MultiTrigger.
136            @return Returns true if the MultiTrigger stays active.
137            */
138            inline bool getStayActive(void) const
139                { return this->bStayActive_; }
140
141            /**
142            @brief Set the number of activations the MultiTrigger can go through.
143            @param activations The number of activations. -1 denotes infinitely many activations.
144            */
145            inline void setActivations(int activations)
146                { if(activations >= 0 || activations == INF_s) this->remainingActivations_ = activations; }
147            /**
148            @brief Get the number of remaining activations of the MultiTrigger.
149            @return The number of activations. -1 denotes infinity.
150            */
151            inline int getActivations(void) const
152                { return this->remainingActivations_; }
153
154            /**
155            @brief Set the number of objects that are allowed to simultaniously trigger this MultiTrigger.
156            @param triggerers The number of objects. -1 denotes infinitely many.
157            */
158            inline void setSimultaniousTriggerers(int triggerers)
159                { if(triggerers >= 0 || triggerers == INF_s) this->maxNumSimultaniousTriggerers_ = triggerers; }
160            /**
161            @brief Get the number of objects that are allowed to simultaniously trigger this MultiTriggger.
162            @return Returns the number of objects. -1 denotes infinity.
163            */
164            inline int getSimultaniousTriggerers(void)
165                { return this->maxNumSimultaniousTriggerers_; }
166
167            /**
168            @brief Set the invert-mode of the MultiTrigger.
169            @param bInvert If true the MultiTrigger is set to invert.
170            */
171            inline void setInvert(bool bInvert)
172                { this->bInvertMode_ = bInvert; }
173            /**
174            @brief Get the invert-mode of the MultiTrigger.
175            @return Returns true if the MultiTrigger is set to invert.
176            */
177            inline bool getInvert(void) const
178                { return this->bInvertMode_; }
179
180            void setMode(const std::string& modeName); //!< Set the mode of the MultiTrigger.
181            /**
182            @brief Set the mode of the MultiTrigger.
183            @param mode The mode of the MultiTrigger.
184            */
185            inline void setMode(MultiTriggerMode::Value mode) //!< Get the mode of the MultiTrigger.
186                { this->mode_ = mode; }
187            const std::string& getModeString(void) const;
188            /**
189            @brief Get the mode of the MultiTrigger.
190            @return Returns and Enum for the mode of the MultiTrigger.
191            */
192            inline MultiTriggerMode::Value getMode() const
193                { return mode_; }
194
195            /**
196            @brief Set the broadcast-mode of the MultiTrigger.
197            @param bBroadcast If true the MultiTrigger is set to broadcast;
198            */
199            inline void setBroadcast(bool bBroadcast)
200                { this->bBroadcast_ = bBroadcast; }
201            /**
202            @brief Get the broadcast-mode of the MultiTrigger.
203            @return Returns true if the MultiTrigger is set to broadcast.
204            */
205            inline bool getBroadcast(void)
206                { return this->bBroadcast_; }
207
208            /**
209            @brief Get whether the input object is a target of the MultiTrigger.
210            @param target A pointer to the object.
211            @return Returns true if the input object is a target, false if not.
212            */
213            inline bool isTarget(BaseObject* target)
214                { if(target == NULL) return true; else return targetMask_.isIncluded(target->getIdentifier()); }
215            void addTargets(const std::string& targets); //!< Add some target to the MultiTrigger.
216            void removeTargets(const std::string& targets); //!< Remove some target from the MultiTrigger.
217           
218            void addTrigger(MultiTrigger* trigger); //!< Adds a MultiTrigger as a sub-trigger to the trigger.
219            const MultiTrigger* getTrigger(unsigned int index) const; //!< Get the sub-trigger of this MultiTrigger at the given index.
220           
221        protected:
222            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.
223
224            void changeTriggered(BaseObject* originator = NULL); //!< This method can be called by any class inheriting from MultiTrigger to change it's triggered status for a specified originator.
225           
226            bool isModeTriggered(BaseObject* triggerer = NULL); //!< Checks whetherx the MultiTrigger is triggered concerning it's sub-triggers.
227            bool isTriggered(BaseObject* triggerer = NULL); //!< Get whether the MultiTrigger is triggered for a given object.
228
229            void fire(bool status, BaseObject* originator = NULL);  //!< Helper method. Creates an Event for the given status and originator and fires it.
230            void broadcast(bool status); //!< Helper method. Broadcasts an Event for every object that is a target.
231
232            /**
233            @brief Adds the parent of a MultiTrigger.
234            @param parent A pointer to the parent MultiTrigger.
235            */
236            inline void addParentTrigger(MultiTrigger* parent)
237                { this->parentTrigger_ = parent; }
238           
239            /**
240            @brief Get the target mask used to identify the targets of this MultiTrigger.
241            @return Returns the target mask.
242            */
243            inline ClassTreeMask& getTargetMask(void)
244                { return this->targetMask_; }
245            /**
246            @brief Is called, when the target mask changes.
247            */
248            //TODO: Check if something mus be done here.
249            virtual void notifyMaskUpdate(void) {}
250           
251        private:
252            static const int INF_s; //!< Magic number for infinity.
253            //! Magic strings for the mode.
254            static const std::string and_s;
255            static const std::string or_s;
256            static const std::string xor_s;
257
258            void subTrigggerActivityChanged(BaseObject* originator); //!< This method is called by any sub-trigger to advertise changes in it's state to it's parent-trigger.
259           
260            bool addState(MultiTriggerState* state); //!< Helper method. Adds a state to the state queue, where the state will wait to become active.
261           
262            bool checkAnd(BaseObject* triggerer); //!< Checks whether the sub-triggers amount to true for the 'and' mode for a given object.
263            bool checkOr(BaseObject* triggerer); //!< Checks whether the sub-triggers amount to true for the 'or' mode for a given object.
264            bool checkXor(BaseObject* triggerer); //!< Checks whether the sub-triggers amount to true for the 'xor' mode for a given object.
265
266            /**
267            @brief Get the objects for which this MultiTrigger is active.
268            @return Returns a set with all the object this MultiTrigger is active for.
269            */
270            std::set<BaseObject*>& getActive(void)
271                { return this->active_; }
272
273            bool bFirstTick_; //!< Bool to distinguish the first tick form all the following.
274
275            float delay_; //!< The delay that is imposed on all new trigger events.
276            bool bSwitch_; //!< Bool for the switch-mode, if true the MultiTrigger behaves like a switch.
277            bool bStayActive_; //!< Bool for the stay-active-mode, if true the MultiTrigger stays active after its last activation.;
278           
279            int remainingActivations_; //!< The remaining activations of this MultiTrigger.
280            int maxNumSimultaniousTriggerers_; //!< The maximum number of objects simultaniously trigggering this MultiTrigger.
281
282            bool bInvertMode_; //!< Bool for the invert-mode, if true the MultiTrigger is inverted.
283            MultiTriggerMode::Value mode_; //!< The mode of the MultiTrigger.
284
285            bool bBroadcast_; //!< Bool for the broadcast-mode, if true all triggers go to all possible targets.
286
287            MultiTrigger* parentTrigger_;
288            std::set<MultiTrigger*> subTriggers_; //!< The sub-triggers of this MultiTrigger.
289           
290            std::set<BaseObject*> active_; //!< The set of all objects the MultiTrigger is active for.
291            std::set<BaseObject*> triggered_; //!< The set of all objects the MultiTrigger is triggered for.
292
293            std::deque< std::pair<float, MultiTriggerState*> > stateQueue_; //!< The queue of states waiting to become active.
294           
295            ClassTreeMask targetMask_; //!< The target mask, masking all objects that can trigger this MultiTrigger.
296           
297    };
298
299}
300
301#endif // _MultiTrigger_H__
Note: See TracBrowser for help on using the repository browser.