Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchy/src/orxonox/objects/Trigger.cc @ 2019

Last change on this file since 2019 was 2019, checked in by landauf, 16 years ago

many changes, most important: BaseObject takes now a pointer to it's creator which is needed to build a level hierarchy (with different scenes)

  • Property svn:eol-style set to native
File size: 7.3 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 *      Benjamin Knecht
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "OrxonoxStableHeaders.h"
30#include "Trigger.h"
31
32#include <OgreBillboard.h>
33#include "util/Debug.h"
34#include "core/CoreIncludes.h"
35#include "core/ConsoleCommand.h"
36#include "core/XMLPort.h"
37#include "objects/Scene.h"
38
39namespace orxonox
40{
41
42  SetConsoleCommand(Trigger, debugFlares, false).defaultValues(false);
43
44  CreateFactory(Trigger);
45
46  Trigger::Trigger(BaseObject* creator) : PositionableEntity(creator)
47  {
48    RegisterObject(Trigger);
49
50    mode_ = TM_EventTriggerAND;
51    bActive_ = false;
52    bInvertMode_ = false;
53    delay_ = 0.0;
54    bTriggered_ = false;
55    bUpdating_ = false;
56    remainingActivations_ = -1;
57    bStayOn_ = false;
58    latestState_ = 0x0;
59
60    if (this->getScene() && this->getScene()->getSceneManager())
61    {
62      debugBillboard_.setBillboardSet(this->getScene()->getSceneManager(), "Examples/Flare", ColourValue(1.0, 0.0, 0.0), 1);
63      debugBillboard_.setVisible(false);
64    }
65
66    this->getNode()->attachObject(debugBillboard_.getBillboardSet());
67  }
68
69  Trigger::~Trigger()
70  {
71  }
72
73  void Trigger::init()
74  {
75    timeSinceLastEvent_ = delay_;
76  }
77
78  void Trigger::debugFlares(bool bVisible)
79  {
80    for (ObjectList<Trigger>::iterator it = ObjectList<Trigger>::begin(); it != ObjectList<Trigger>::end(); ++it)
81      it->setVisible(bVisible);
82  }
83
84  void Trigger::changedVisibility()
85  {
86    debugBillboard_.setVisible(this->isVisible());
87  }
88
89  const Trigger* Trigger::getTrigger(unsigned int index) const
90  {
91    if (children_.size() <= index)
92      return NULL;
93
94    std::set<Trigger*>::const_iterator it;
95    it = children_.begin();
96
97    for ( unsigned int i = 0; i != index; i++ )
98    {
99      it++;
100    }
101    return *it;
102  }
103
104  void Trigger::tick(float dt)
105  {
106
107    bool newTriggered;
108    newTriggered = this->isTriggered();
109
110    // check if new triggering event is really new
111    if((this->latestState_ & 0x1) != newTriggered)
112    {
113      // create new state
114      if(newTriggered)
115      {
116        latestState_ |= 1; // set trigger bit
117        this->switchState();
118      }
119      else
120      {
121        latestState_ &= 0xFE; // set trigger bit
122        if (this->bStayOn_)
123          this->storeState();
124        else
125          this->switchState();
126      }
127    }
128
129    if(remainingTime_ > 0.0)
130    {
131      remainingTime_ -= dt;
132      // only increase when acctually waiting for a state in the queue
133      if(timeSinceLastEvent_ >= 0.0)
134        timeSinceLastEvent_ += dt;
135    }
136
137    while(remainingTime_ <= 0.0 && stateChanges_.size() > 0)
138    {
139      // time ran out, change state to new one
140      char newState = stateChanges_.front().second;
141      bTriggered_ = (newState & 0x1);
142      bActive_ = newState & 2;
143      this->stateChanges_.pop();
144      if(stateChanges_.size() != 0)
145        remainingTime_ = stateChanges_.front().first;
146      else
147        timeSinceLastEvent_ = delay_;
148    }
149
150
151
152    if (bTriggered_ && bActive_)
153      this->setBillboardColour(ColourValue(0.5, 1.0, 0.0));
154    else if (!bTriggered_ && bActive_)
155      this->setBillboardColour(ColourValue(0.0, 1.0, 0.0));
156    else if (bTriggered_ && !bActive_)
157      this->setBillboardColour(ColourValue(1.0, 0.5, 0.0));
158    else
159      this->setBillboardColour(ColourValue(1.0, 0.0, 0.0));
160    bUpdating_ = false;
161  }
162
163  void Trigger::setBillboardColour(ColourValue colour)
164  {
165    this->debugBillboard_.getBillboardSet()->getBillboard(0)->setColour(colour);
166  }
167
168  void Trigger::storeState()
169  {
170    // put state change into queue
171    this->stateChanges_.push(std::pair<float,char>(timeSinceLastEvent_, latestState_));
172    // reset time since last event
173    timeSinceLastEvent_ = 0.0;
174
175    if(this->stateChanges_.size() == 1)
176      remainingTime_ = stateChanges_.front().first;
177  }
178
179  bool Trigger::isTriggered(TriggerMode mode)
180  {
181    if(bUpdating_)
182      return bTriggered_;
183
184    if( children_.size() != 0 )
185    {
186      bUpdating_ = true;
187      bool returnval = false;
188      switch(mode)
189      {
190        case TM_EventTriggerAND:
191          returnval = checkAnd();
192          break;
193        case TM_EventTriggerOR:
194          returnval = checkOr();
195          break;
196        case TM_EventTriggerXOR:
197          returnval = checkXor();
198          break;
199        default:
200          returnval = false;
201          break;
202      }
203      if(bInvertMode_)
204        return !returnval;
205      else
206        return returnval;
207    }
208    return true;
209  }
210
211  void Trigger::setDelay(float delay)
212  {
213    this->delay_ = delay;
214  }
215
216  void Trigger::setMode(const std::string& modeName)
217  {
218    if (modeName == "and")
219      setMode(TM_EventTriggerAND);
220    else if (modeName == "or")
221      setMode(TM_EventTriggerOR);
222    else if (modeName == "xor")
223      setMode(TM_EventTriggerXOR);
224  }
225
226  void Trigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
227  {
228    WorldEntity::XMLPort(xmlelement, mode);
229
230    XMLPortParamLoadOnly(Trigger, "delay", setDelay, xmlelement, mode);
231    XMLPortParamLoadOnly(Trigger, "stayOn", setStayOn, xmlelement, mode);
232    XMLPortParamLoadOnly(Trigger, "activations", setActivations, xmlelement, mode);
233    XMLPortParamLoadOnly(Trigger, "invert", setInvert, xmlelement, mode);
234    XMLPortParamLoadOnlyTemplate(Trigger, "mode", setMode, xmlelement, mode, const std::string&);
235
236    XMLPortObject(Trigger, Trigger, "", addTrigger, getTrigger, xmlelement, mode);
237
238    this->init();
239  }
240
241  void Trigger::addTrigger(Trigger* trig)
242  {
243    if (this != trig)
244      this->children_.insert(trig);
245  }
246
247  bool Trigger::switchState()
248  {
249    if ( remainingActivations_ <= -1 || this->latestState_ & 2 || remainingActivations_ > 0)
250    {
251      this->latestState_ ^= 2; // toggle state bit
252      // increase activation count
253      if (this->latestState_ & 2) remainingActivations_--;
254      this->storeState();
255
256      return true;
257    }
258    return false;
259  }
260
261
262  bool Trigger::checkAnd()
263  {
264    std::set<Trigger*>::iterator it;
265    for(it = this->children_.begin(); it != this->children_.end(); it++)
266    {
267      if(!((*it)->isActive()))
268        return false;
269    }
270    return true;
271  }
272
273  bool Trigger::checkOr()
274  {
275    std::set<Trigger*>::iterator it;
276    for(it = this->children_.begin(); it != this->children_.end(); it++)
277    {
278      if((*it)->isActive())
279        return true;
280    }
281    return false;
282  }
283
284  bool Trigger::checkXor()
285  {
286    std::set<Trigger*>::iterator it;
287    bool test = false;
288    for(it = this->children_.begin(); it != this->children_.end(); it++)
289    {
290      if(test && (*it)->isActive())
291        return false;
292      if((*it)->isActive())
293        test = true;
294    }
295    return test;
296  }
297
298}
Note: See TracBrowser for help on using the repository browser.