Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/objects/triggers/Trigger.cc @ 6372

Last change on this file since 6372 was 5929, checked in by rgrieder, 15 years ago

Merged core5 branch back to the trunk.
Key features include clean level unloading and an extended XML event system.

Two important notes:
Delete your keybindings.ini files! * or you will still get parser errors when loading the key bindings.
Delete build_dir/lib/modules/libgamestates.module! * or orxonox won't start.
Best thing to do is to delete the build folder ;)

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