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, 17 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
RevLine 
[1383]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
[1906]29#include "OrxonoxStableHeaders.h"
[1383]30#include "Trigger.h"
31
[1906]32#include <OgreBillboard.h>
[1961]33#include "util/Debug.h"
[1383]34#include "core/CoreIncludes.h"
[1671]35#include "core/ConsoleCommand.h"
[1693]36#include "core/XMLPort.h"
[2019]37#include "objects/Scene.h"
[1383]38
39namespace orxonox
40{
[1671]41
[1969]42  SetConsoleCommand(Trigger, debugFlares, false).defaultValues(false);
[1671]43
[1383]44  CreateFactory(Trigger);
45
[2019]46  Trigger::Trigger(BaseObject* creator) : PositionableEntity(creator)
[1383]47  {
48    RegisterObject(Trigger);
49
[1671]50    mode_ = TM_EventTriggerAND;
[1693]51    bActive_ = false;
52    bInvertMode_ = false;
53    delay_ = 0.0;
54    bTriggered_ = false;
55    bUpdating_ = false;
[1851]56    remainingActivations_ = -1;
[1954]57    bStayOn_ = false;
[1851]58    latestState_ = 0x0;
[1671]59
[2019]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    }
[1969]65
[1671]66    this->getNode()->attachObject(debugBillboard_.getBillboardSet());
[1383]67  }
68
69  Trigger::~Trigger()
70  {
71  }
72
[1693]73  void Trigger::init()
[1383]74  {
[1693]75    timeSinceLastEvent_ = delay_;
[1383]76  }
77
[1969]78  void Trigger::debugFlares(bool bVisible)
[1671]79  {
[1969]80    for (ObjectList<Trigger>::iterator it = ObjectList<Trigger>::begin(); it != ObjectList<Trigger>::end(); ++it)
81      it->setVisible(bVisible);
[1671]82  }
83
[1969]84  void Trigger::changedVisibility()
85  {
86    debugBillboard_.setVisible(this->isVisible());
87  }
88
[1954]89  const Trigger* Trigger::getTrigger(unsigned int index) const
90  {
91    if (children_.size() <= index)
92      return NULL;
93
[1961]94    std::set<Trigger*>::const_iterator it;
[1954]95    it = children_.begin();
96
97    for ( unsigned int i = 0; i != index; i++ )
98    {
99      it++;
100    }
101    return *it;
102  }
103
[1671]104  void Trigger::tick(float dt)
105  {
[1693]106
[1851]107    bool newTriggered;
[1954]108    newTriggered = this->isTriggered();
[1693]109
[1954]110    // check if new triggering event is really new
111    if((this->latestState_ & 0x1) != newTriggered)
112    {
113      // create new state
114      if(newTriggered)
[1671]115      {
[1954]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
[1851]125          this->switchState();
[1671]126      }
[1954]127    }
[1693]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;
[1954]141      bTriggered_ = (newState & 0x1);
[1851]142      bActive_ = newState & 2;
[1693]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;
[1671]161  }
162
[1693]163  void Trigger::setBillboardColour(ColourValue colour)
164  {
165    this->debugBillboard_.getBillboardSet()->getBillboard(0)->setColour(colour);
166  }
167
[1851]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
[1541]179  bool Trigger::isTriggered(TriggerMode mode)
180  {
[1693]181    if(bUpdating_)
182      return bTriggered_;
183
[1671]184    if( children_.size() != 0 )
[1541]185    {
[1693]186      bUpdating_ = true;
187      bool returnval = false;
[1671]188      switch(mode)
189      {
190        case TM_EventTriggerAND:
[1693]191          returnval = checkAnd();
[1671]192          break;
193        case TM_EventTriggerOR:
[1693]194          returnval = checkOr();
[1671]195          break;
196        case TM_EventTriggerXOR:
[1693]197          returnval = checkXor();
[1671]198          break;
199        default:
[1693]200          returnval = false;
[1671]201          break;
202      }
[1693]203      if(bInvertMode_)
204        return !returnval;
205      else
206        return returnval;
[1541]207    }
[1671]208    return true;
[1541]209  }
210
[1693]211  void Trigger::setDelay(float delay)
212  {
213    this->delay_ = delay;
214  }
215
[1969]216  void Trigger::setMode(const std::string& modeName)
[1954]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
[1550]226  void Trigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
227  {
228    WorldEntity::XMLPort(xmlelement, mode);
[1693]229
230    XMLPortParamLoadOnly(Trigger, "delay", setDelay, xmlelement, mode);
[1954]231    XMLPortParamLoadOnly(Trigger, "stayOn", setStayOn, xmlelement, mode);
[1851]232    XMLPortParamLoadOnly(Trigger, "activations", setActivations, xmlelement, mode);
[1959]233    XMLPortParamLoadOnly(Trigger, "invert", setInvert, xmlelement, mode);
[1969]234    XMLPortParamLoadOnlyTemplate(Trigger, "mode", setMode, xmlelement, mode, const std::string&);
[1693]235
[1961]236    XMLPortObject(Trigger, Trigger, "", addTrigger, getTrigger, xmlelement, mode);
[1954]237
[1693]238    this->init();
[1550]239  }
240
[1383]241  void Trigger::addTrigger(Trigger* trig)
242  {
243    if (this != trig)
[1671]244      this->children_.insert(trig);
[1383]245  }
246
[1693]247  bool Trigger::switchState()
[1541]248  {
[1954]249    if ( remainingActivations_ <= -1 || this->latestState_ & 2 || remainingActivations_ > 0)
[1851]250    {
251      this->latestState_ ^= 2; // toggle state bit
252      // increase activation count
253      if (this->latestState_ & 2) remainingActivations_--;
254      this->storeState();
[1541]255
[1851]256      return true;
257    }
258    return false;
[1550]259  }
260
[1693]261
[1541]262  bool Trigger::checkAnd()
263  {
264    std::set<Trigger*>::iterator it;
[1671]265    for(it = this->children_.begin(); it != this->children_.end(); it++)
[1541]266    {
[1851]267      if(!((*it)->isActive()))
[1541]268        return false;
269    }
270    return true;
271  }
272
273  bool Trigger::checkOr()
274  {
275    std::set<Trigger*>::iterator it;
[1671]276    for(it = this->children_.begin(); it != this->children_.end(); it++)
[1541]277    {
[1851]278      if((*it)->isActive())
[1541]279        return true;
280    }
281    return false;
282  }
283
[1671]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    {
[1851]290      if(test && (*it)->isActive())
[1671]291        return false;
[1851]292      if((*it)->isActive())
[1671]293        test = true;
294    }
295    return test;
296  }
297
[1383]298}
Note: See TracBrowser for help on using the repository browser.