Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: data/contentcreation/pps/FabianLandau/mover/environments/mover.cc @ 10017

Last change on this file since 10017 was 4878, checked in by landauf, 17 years ago
File size: 10.7 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2007 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Fabian 'x3n' Landau
13   co-programmer:
14*/
15
16#include "sound/resource_sound_buffer.h"
17#include "sound_engine.h"
18#include "util/loading/load_param_xml.h"
19#include "util/loading/load_param.h"
20#include "util/loading/factory.h"
21#include "mover.h"
22
23#define CLOSED 0
24#define OPEN 1
25#define MOVE 2
26#define WAIT 3
27#define NEXT 4
28#define DELAY 5
29#define STAY 6
30
31ObjectListDefinition(Mover);
32CREATE_FACTORY(Mover);
33
34
35Mover::Mover(const TiXmlElement* root)
36{
37    PRINTF(0)("1_1 Mover %p created\n", this);
38    this->registerObject(this, Mover::_objectList);
39    this->toList(OM_ENVIRON);
40
41    this->bLoop = false;
42    this->bRepeat = false;
43    this->bWaitAfterEachStation = false;
44    this->bOnlyMoveWhileTriggered = false;
45    this->bAttachTrigger = false;
46    this->bReopen = false;
47    this->bReclose = false;
48   
49    this->triggers = 0;
50    this->stations = 0;
51
52    this->repeats = 0;
53    this->state = CLOSED;
54    this->station = 0;
55    this->repeatsToGo = 0;
56    this->time = 0;
57   
58    this->originCoor = Vector(0, 0, 0);
59    this->originDir = Vector(0, 0, 0);
60
61    this->soundSource_starting.setSourceNode(this);
62    this->soundSource_moving.setSourceNode(this);
63    this->soundSource_ending.setSourceNode(this);
64
65    PRINTF(0)("1_2\n");
66    if (root != NULL)
67        this->loadParams(root);
68       
69    this->updateNode(0.001);
70       
71    this->originCoor = this->getAbsCoor();
72    this->originDir = this->getAbsDir().getRotation();
73
74    PRINTF(0)("1_3\n");
75    if (this->stations)
76        this->station = this->stations->getNextStation(0);
77    PRINTF(0)("1_4\n");
78    if (this->triggers)
79        this->triggers->setBaseCoor(this->getAbsCoor());
80    PRINTF(0)("1_5\n");
81}
82
83Mover::~Mover()
84{
85    if (this->triggers)
86        delete this->triggers;
87    if (this->stations)
88        delete this->stations;
89   
90    if (this->soundSource_starting.isPlaying())
91        this->soundSource_starting.stop();
92    if (this->soundSource_moving.isPlaying())
93        this->soundSource_moving.stop();
94    if (this->soundSource_ending.isPlaying())
95        this->soundSource_ending.stop();
96}
97
98void Mover::loadParams(const TiXmlElement* root)
99{
100    PRINTF(0)("2_1\n");
101    WorldEntity::loadParams(root);
102
103    LoadParam(root, "bLoop", this, Mover, setLoop)
104        .describe("After getting triggered, the mover loops forever.")
105        .defaultValues(false);
106    LoadParam(root, "bRepeat", this, Mover, setRepeat)
107        .describe("After getting triggered, the mover moves n times.")
108        .defaultValues(1);
109    LoadParam(root, "bWaitAfterEachStation", this, Mover, setWaitAfterEachStation)
110        .describe("After each station, the mover waits until he gets triggered.")
111        .defaultValues(false);
112    LoadParam(root, "bOnlyMoveWhileTriggered", this, Mover, setOnlyMoveWhileTriggered)
113        .describe("The mover stops as soon as he gets untriggered.")
114        .defaultValues(false);
115    LoadParam(root, "bAttachTrigger", this, Mover, setAttachTrigger)
116        .describe("The trigger follows the mover.")
117        .defaultValues(false);
118    LoadParam(root, "bReopen", this, Mover, setReopen)
119        .describe("Stops closing and reopens the mover when he gets triggered again.")
120        .defaultValues(false);
121    LoadParam(root, "bReclose", this, Mover, setReclose)
122        .describe("Stops opening and recloses the mover when he gets untriggered.")
123        .defaultValues(false);
124    PRINTF(0)("2_2\n");
125    LoadParamXML(root, "triggers", this, Mover, setTriggers)
126        .describe("Adds a trigger that releases the mover.");
127    PRINTF(0)("2_3\n");
128    LoadParamXML(root, "stations", this, Mover, setStations)
129        .describe("Adds a station to the movers stations-list.");
130    PRINTF(0)("2_4\n");
131}
132
133void Mover::setTriggers(const TiXmlElement* root)
134{
135    PRINTF(0)("3_1\n");
136    this->triggers = new MoverTriggerList();
137    const TiXmlElement* element = root->FirstChildElement();
138   
139    PRINTF(0)("3_2\n");
140    while (element != NULL)
141    {
142        PRINTF(0)("3_3\n");
143//        PRINTF(0)("TiXmlElement Value:   %s\n", element->Value());
144        BaseObject *newObj = Factory::fabricate(element);
145//        PRINTF(0)("BaseObject ClassName: %s\n", newObj->getClassCName());
146//        MoverTrigger *newTrigger = ((MoverTrigger*)(&newObj));
147        MoverTrigger *newTrigger = (dynamic_cast< MoverTrigger *> ( newObj ));
148        this->triggers->addTrigger(newTrigger);
149//        this->triggers->addTrigger(MoverTrigger::createTrigger(element));
150        PRINTF(0)("3_4\n");
151        element = element->NextSiblingElement();
152        PRINTF(0)("3_5\n");
153    }
154    PRINTF(0)("3_6\n");
155}
156
157void Mover::setStations(const TiXmlElement* root)
158{
159    PRINTF(0)("4_1\n");
160    this->stations = new MoverStationList();
161    const TiXmlElement* element = root->FirstChildElement();
162
163    PRINTF(0)("4_2\n");
164    while (element != NULL)
165    {
166        PRINTF(0)("4_3\n");
167        this->stations->addStation(new MoverStation(element));
168        element = element->NextSiblingElement();
169    }
170    PRINTF(0)("4_4\n");
171}
172
173void Mover::tick(float dt)
174{
175//    PRINTF(0)("15_1 mover state of mover %p is %i, triggerlist is %p\n", this, this->state, this->triggers);
176    if (this->state == DELAY || this->state == MOVE || this->state == STAY)
177        this->time += dt;
178
179    if (this->state == NEXT)
180        this->changeState(this->next());
181       
182    if (this->state == WAIT)
183        this->changeState(this->wait());
184       
185    if (this->state == CLOSED)
186        this->changeState(this->closed());
187
188    if (this->state == OPEN)
189        this->changeState(this->open());
190
191    if (this->state == DELAY)
192        this->changeState(this->delay());
193
194    if (this->state == MOVE)
195        this->changeState(this->move(dt));
196
197    if (this->state == STAY)
198        this->changeState(this->stay());
199}
200
201void Mover::changeState(int state)
202{
203    if (this->state == state)
204        return;
205       
206    this->state = state;
207   
208    if (this->state == DELAY || this->state == STAY)
209        this->time = 0;
210}
211
212int Mover::closed()
213{
214    if (this->triggers && this->triggers->isTriggered())
215    {
216        if (this->bRepeat)
217            this->repeatsToGo = this->repeats;
218           
219        return DELAY;
220    }
221
222    return CLOSED;
223}
224
225int Mover::open()
226{
227    if (this->triggers && !this->triggers->isTriggered())
228    {
229        return DELAY;
230    }
231
232    return OPEN;
233}
234
235int Mover::wait()
236{
237    if (this->triggers && this->triggers->isTriggered())
238    {
239        this->soundSource_moving.play(this->stations->getMovingSound(this->station), OrxSound::SoundEngine::getInstance()->getEffectsVolume(), 0.5, true);
240        return MOVE;
241    }
242
243    return WAIT;
244}
245
246int Mover::next()
247{
248    bool isOpen = false;
249    bool isClosed = false;
250    if (this->stations)
251    {
252        isOpen = this->stations->isOpen(station);
253        isClosed = this->stations->isClosed(station);
254        this->station = this->stations->getNextStation(this->station);
255    }
256
257    if (isClosed && this->bRepeat)
258        this->repeatsToGo--;
259       
260    if (isClosed && (!this->bLoop && this->repeatsToGo <= 0))
261        return CLOSED;
262
263    if (isOpen && (!this->bLoop && this->repeatsToGo <= 0))
264        return OPEN;
265
266    if (this->bWaitAfterEachStation)
267        return WAIT;
268
269    if ((this->bLoop || this->repeats > 0) || (!isOpen && !isClosed))
270        return DELAY;
271       
272    return NEXT;
273}
274
275int Mover::delay()
276{
277    if (!this->stations || (this->time < this->stations->getDelay(this->station)))
278        return DELAY;
279
280    if (this->stations->getStartingSound(this->station).loaded())
281        this->soundSource_starting.play(this->stations->getStartingSound(this->station), OrxSound::SoundEngine::getInstance()->getEffectsVolume(), 0.5);
282    if (this->stations->getMovingSound(this->station).loaded())
283        this->soundSource_moving.play(this->stations->getMovingSound(this->station), OrxSound::SoundEngine::getInstance()->getEffectsVolume(), 0.5, true);
284
285    this->time = 0;
286   
287    return MOVE;
288}
289
290int Mover::move(float dt)
291{
292    if (this->stations)
293    {
294        this->setAbsCoor(this->originCoor + this->stations->getVelocity(this->station) * this->time);
295        this->setAbsDir(VtoQ(this->originDir + this->stations->getRotation(this->station) * this->time));
296    }
297   
298    if (this->bAttachTrigger && this->triggers)
299        this->triggers->setBaseCoor(this->getAbsCoor());
300
301    if (!this->bLoop && this->repeatsToGo <= 0)
302    {
303        if (this->stations && this->triggers && this->stations->changeDirection(this->bReopen, this->bReclose, this->triggers->isTriggered()))
304        {
305            this->time = this->stations->getMovingTime(this->station) - this->time;
306            this->originCoor = this->originCoor - this->stations->getRelTargetCoor(this->station);
307            this->originDir = this->originDir - this->stations->getRelTargetDir(this->station);
308        }
309    }
310
311    if (/*this->reachedStationsTarget(dt) || */(this->stations && (this->time >= 1.0 * this->stations->getMovingTime(this->station))))
312//    if (this->stations && (this->time >= this->stations->getMovingTime(this->station)))
313    {
314        this->setAbsCoor(this->originCoor + this->stations->getRelTargetCoor(this->station));
315        this->setAbsDir(VtoQ(this->originDir + this->stations->getRelTargetDir(this->station)));
316
317        if (this->stations->getEndingSound(this->station).loaded())
318            this->soundSource_ending.play(this->stations->getEndingSound(this->station), OrxSound::SoundEngine::getInstance()->getEffectsVolume(), 0.5);
319        this->soundSource_moving.stop();
320
321        this->originCoor = this->originCoor + this->stations->getRelTargetCoor(this->station);
322        this->originDir = this->originDir + this->stations->getRelTargetDir(this->station);
323       
324        return STAY;
325    }
326       
327    if (this->triggers && this->bOnlyMoveWhileTriggered && (!this->triggers->isTriggered()))
328    {
329        this->soundSource_moving.stop();
330        return WAIT;
331    }
332
333    return MOVE;
334}
335
336int Mover::stay()
337{
338    if (!this->stations || (this->time < this->stations->getStayOpenTime(this->station)))
339        return STAY;
340
341    return NEXT;
342}
343
344bool Mover::reachedStationsTarget(float dt)
345{
346    if (this->stations)
347        if ((this->getAbsCoor() - (this->originCoor + this->stations->getRelTargetCoor(this->station))).len() <= 1.2 * (this->stations->getVelocity(this->station) * dt).len())
348            if ((this->getAbsDir().getRotation() - (this->originDir + this->stations->getRelTargetDir(this->station))).len() <= 1.2 * (this->stations->getRotation(this->station) * dt).len())
349                return true;
350
351    return false;
352}
353
Note: See TracBrowser for help on using the repository browser.