Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

some small adjustments in Trigger (console command and xmlport)

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