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