Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/script_trigger/src/orxonox/objects/Trigger.cc @ 1693

Last change on this file since 1693 was 1693, checked in by bknecht, 16 years ago

Trigger delay queue is working, DistanceTrigger can be added to level and reacts… cool stuff

File size: 5.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 "Trigger.h"
30
31#include "core/Debug.h"
32#include <OgreBillboard.h>
33
34#include "core/CoreIncludes.h"
35#include "core/ConsoleCommand.h"
36#include "core/XMLPort.h"
37
38namespace orxonox
39{
40
41  ConsoleCommand(Trigger, setVisibility, AccessLevel::Debug, false).setDefaultValues(0);
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
56    debugBillboard_.setBillboardSet("Examples/Flare", ColourValue(1.0, 0.0, 0.0), 1);
57    this->getNode()->attachObject(debugBillboard_.getBillboardSet());
58  }
59
60  Trigger::~Trigger()
61  {
62  }
63
64  void Trigger::init()
65  {
66    this->setVisibility(true);
67    timeSinceLastEvent_ = delay_;
68  }
69
70  void Trigger::setVisibility(bool bVisible)
71  {
72    if(bVisible)
73      this->setScale(2,2,2);
74    else
75      this->setScale(0,0,0);
76  }
77
78  void Trigger::tick(float dt)
79  {
80
81    bool newTriggered = this->isTriggered();
82
83
84    // check if new triggering event is really new
85    if(this->latestState_ % 2 != newTriggered)
86    {
87      // create new state
88      if(newTriggered)
89      {
90        latestState_ |= 0x1; // set trigger bit
91        latestState_ ^= 0x10; // toggle state bit
92      }
93      else
94      {
95        latestState_ &= 0x11111110; // set trigger bit
96      }
97
98      // put state change into queue
99      this->stateChanges_.push(std::pair<float,char>(timeSinceLastEvent_, latestState_));
100      // reset time since last event
101      timeSinceLastEvent_ = 0.0;
102
103      if(this->stateChanges_.size() == 1)
104        remainingTime_ = stateChanges_.front().first;
105    }
106
107    if(remainingTime_ > 0.0)
108    {
109      remainingTime_ -= dt;
110      // only increase when acctually waiting for a state in the queue
111      if(timeSinceLastEvent_ >= 0.0)
112        timeSinceLastEvent_ += dt;
113    }
114
115    while(remainingTime_ <= 0.0 && stateChanges_.size() > 0)
116    {
117      // time ran out, change state to new one
118      char newState = stateChanges_.front().second;
119      bTriggered_ = newState % 2;
120      bActive_ = newState>>1 % 2;
121      this->stateChanges_.pop();
122      if(stateChanges_.size() != 0)
123        remainingTime_ = stateChanges_.front().first;
124      else
125        timeSinceLastEvent_ = delay_;
126    }
127
128
129
130    if (bTriggered_ && bActive_)
131      this->setBillboardColour(ColourValue(0.5, 1.0, 0.0));
132    else if (!bTriggered_ && bActive_)
133      this->setBillboardColour(ColourValue(0.0, 1.0, 0.0));
134    else if (bTriggered_ && !bActive_)
135      this->setBillboardColour(ColourValue(1.0, 0.5, 0.0));
136    else
137      this->setBillboardColour(ColourValue(1.0, 0.0, 0.0));
138    bUpdating_ = false;
139  }
140
141  void Trigger::setBillboardColour(ColourValue colour)
142  {
143    this->debugBillboard_.getBillboardSet()->getBillboard(0)->setColour(colour);
144  }
145
146  bool Trigger::isTriggered(TriggerMode mode)
147  {
148    if(bUpdating_)
149      return bTriggered_;
150
151    if( children_.size() != 0 )
152    {
153      bUpdating_ = true;
154      bool returnval = false;
155      switch(mode)
156      {
157        case TM_EventTriggerAND:
158          returnval = checkAnd();
159          break;
160        case TM_EventTriggerOR:
161          returnval = checkOr();
162          break;
163        case TM_EventTriggerXOR:
164          returnval = checkXor();
165          break;
166        default:
167          returnval = false;
168          break;
169      }
170      if(bInvertMode_)
171        return !returnval;
172      else
173        return returnval;
174    }
175    return true;
176  }
177
178  void Trigger::setDelay(float delay)
179  {
180    this->delay_ = delay;
181  }
182
183  void Trigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
184  {
185    WorldEntity::XMLPort(xmlelement, mode);
186
187    XMLPortParamLoadOnly(Trigger, "delay", setDelay, xmlelement, mode);
188
189    this->init();
190  }
191
192  void Trigger::addTrigger(Trigger* trig)
193  {
194    if (this != trig)
195      this->children_.insert(trig);
196  }
197
198  bool Trigger::switchState()
199  {
200    latestState_ ^= 0x10; // toggle state bit
201    // put state change into queue
202    this->stateChanges_.push(std::pair<float,char>(timeSinceLastEvent_, latestState_));
203    // reset time since last event
204    timeSinceLastEvent_ = 0.0;
205
206    if(this->stateChanges_.size() == 1)
207      remainingTime_ = stateChanges_.front().first;
208  }
209
210
211  bool Trigger::checkAnd()
212  {
213    std::set<Trigger*>::iterator it;
214    for(it = this->children_.begin(); it != this->children_.end(); it++)
215    {
216      if(!((*it)->isTriggered()))
217        return false;
218    }
219    return true;
220  }
221
222  bool Trigger::checkOr()
223  {
224    std::set<Trigger*>::iterator it;
225    for(it = this->children_.begin(); it != this->children_.end(); it++)
226    {
227      if((*it)->isTriggered())
228        return true;
229    }
230    return false;
231  }
232
233  bool Trigger::checkXor()
234  {
235    std::set<Trigger*>::iterator it;
236    bool test = false;
237    for(it = this->children_.begin(); it != this->children_.end(); it++)
238    {
239      if(test && (*it)->isTriggered())
240        return false;
241      if((*it)->isTriggered())
242        test = true;
243    }
244    return test;
245  }
246
247}
Note: See TracBrowser for help on using the repository browser.