Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/objects/worldentities/triggers/Trigger.cc @ 3012

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

Merged r1-2096 of questsystem5 back to trunk

I hope there weren't more "hidden merge changes" in r2909 than the one in OverlayGroup (removeElement) (and related to this the adjustments in NotificationQueue).

The corresponding media commit seems not yet to be done, but it doesn't break the build.

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