Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Triggers now implemented. Trigger may now have children, two or four states, limited amount of activations and a delay.

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