Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/tutorial2/src/orxonox/items/MultiStateEngine.cc @ 10022

Last change on this file since 10022 was 8727, checked in by dafrick, 13 years ago

Cleaning up in SpaceShip and Engine. Fixed several bugs.
Kicked localLinearAcceleration, primaryThrust and auxiliaryThrust out of the SpaceShip, since it wasn't used anymore.
Moved the trail lights back a bit.
Added some documentation to SpaceShip and Engine.
SpeedPickup is working again, will need some further tuning.

  • Property svn:eol-style set to native
File size: 9.2 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 *      Fabian 'x3n' Landau
24 *      Reto Grieder
25 *   Co-authors:
26 *      ...
27 *
28 */
29
30#include "MultiStateEngine.h"
31
32extern "C" {
33#include <lua.h>
34}
35
36#include "util/Convert.h"
37#include "core/CoreIncludes.h"
38#include "core/GameMode.h"
39#include "core/LuaState.h"
40#include "core/XMLPort.h"
41#include "worldentities/EffectContainer.h"
42#include "worldentities/pawns/SpaceShip.h"
43#include "sound/WorldSound.h"
44
45namespace orxonox
46{
47    static const float FORWARD_EFFECT_VELOCITY_THRESHOLD = 0;
48    static const float MAX_VELOCITY_NORMAL = 111;
49    static const float MAX_VELOCITY_BOOST = 221;
50
51    CreateFactory(MultiStateEngine);
52
53    MultiStateEngine::MultiStateEngine(BaseObject* creator) : Engine(creator)
54    {
55        RegisterObject(MultiStateEngine);
56
57        if (GameMode::isMaster())
58        {
59            this->defEngineSndNormal_ = new WorldSound(this);
60            this->defEngineSndBoost_  = new WorldSound(this);
61            this->defEngineSndNormal_->setLooping(true);
62            this->defEngineSndBoost_->setLooping(true);
63            this->lua_ = new LuaState();
64        }
65        else
66        {
67            this->defEngineSndBoost_ = 0;
68            this->defEngineSndNormal_ = 0;
69            this->lua_ = 0;
70        }
71        this->state_ = 0;
72        this->oldState_ = 0;
73
74        this->setSyncMode(ObjectDirection::Bidirectional);
75        this->registerVariables();
76    }
77
78    MultiStateEngine::~MultiStateEngine()
79    {
80        if (this->isInitialized())
81        {
82            if (!this->getShip())
83            {
84                // We have no ship, so the effects are not attached and won't be destroyed automatically
85                for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
86                    for (std::vector<WorldEntity*>::const_iterator it2 = (*it)->getEffectsBegin(); it2 != (*it)->getEffectsBegin(); ++it2)
87                        (*it2)->destroy();
88                if (this->defEngineSndNormal_)
89                    this->defEngineSndNormal_->destroy();
90                if (this->defEngineSndBoost_)
91                    this->defEngineSndBoost_->destroy();
92            }
93            if (this->lua_)
94                delete this->lua_;
95        }
96    }
97
98    void MultiStateEngine::XMLPort(Element& xmlelement, XMLPort::Mode mode)
99    {
100        SUPER(MultiStateEngine, XMLPort, xmlelement, mode);
101        XMLPortObject(MultiStateEngine, EffectContainer, "",  addEffectContainer,  getEffectContainer,  xmlelement, mode);
102        XMLPortParam(MultiStateEngine, "defEngineSndNormal",  setDefEngSndNormal,  getDefEngSndNormal,  xmlelement, mode);
103        XMLPortParam(MultiStateEngine, "defEngineSndBoost",  setDefEngSndBoost,  getDefEngSndBoost,  xmlelement, mode);
104    }
105
106    void MultiStateEngine::registerVariables()
107    {
108        registerVariable(this->state_, VariableDirection::ToServer);
109    }
110
111    void MultiStateEngine::run(float dt)
112    {
113        if (this->getShip())
114        {
115            const Vector3& velocity = this->getShip()->getLocalVelocity();
116
117            if (this->getShip()->hasLocalController())
118            {
119                const Vector3& direction = this->getSteering();
120                bool forward = (direction.z < 0.0 && velocity.z < -FORWARD_EFFECT_VELOCITY_THRESHOLD);
121
122                this->state_ = 0;
123                if (this->getShip()->isBoosting() && forward)
124                    this->state_ = Boost;
125                else if (forward && !this->state_) // this->state_ == Boost
126                    this->state_ = Normal;
127                else if (direction.z > 0.0 && velocity.z < 0.0)
128                    this->state_ = Brake;
129                else
130                    this->state_ = Idle;
131
132                if (this->state_ == Idle && this->getSpeedAdd() > 0)
133                    this->state_ = Normal;
134            }
135
136            if (GameMode::isMaster())
137            {
138                int changes = this->state_ | this->oldState_;
139
140                float pitch = velocity.length();
141                if (this->state_ & Normal)
142                    defEngineSndNormal_->setPitch(clamp(pitch/MAX_VELOCITY_NORMAL + 1, 0.5f, 2.0f));
143                if (this->state_ & Boost)
144                    defEngineSndBoost_->setPitch(clamp(pitch/MAX_VELOCITY_BOOST + 1, 0.5f, 2.0f));
145
146                if (changes & Idle)
147                {
148                    lua_pushboolean(this->lua_->getInternalLuaState(), this->state_ & Idle);
149                    lua_setglobal(this->lua_->getInternalLuaState(), "idle");
150                }
151                if (changes & Normal)
152                {
153                    lua_pushboolean(this->lua_->getInternalLuaState(), this->state_ & Normal);
154                    lua_setglobal(this->lua_->getInternalLuaState(), "normal");
155                    if (this->state_ & Normal)
156                        defEngineSndNormal_->play();
157                    else
158                        defEngineSndNormal_->stop();
159                }
160                if (changes & Brake)
161                {
162                    lua_pushboolean(this->lua_->getInternalLuaState(), this->state_ & Brake);
163                    lua_setglobal(this->lua_->getInternalLuaState(), "brake");
164                }
165                if (changes & Boost)
166                {
167                    lua_pushboolean(this->lua_->getInternalLuaState(), this->state_ & Boost);
168                    lua_setglobal(this->lua_->getInternalLuaState(), "boost");
169                    if (this->state_ & Boost)
170                        defEngineSndBoost_->play();
171                    else
172                        defEngineSndBoost_->stop();
173                }
174
175                this->oldState_ = this->state_;
176
177                // Update all effect conditions
178                for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
179                    (*it)->updateCondition();
180            }
181        }
182
183        Engine::run(dt);
184    }
185
186    void MultiStateEngine::addToSpaceShip(SpaceShip* ship)
187    {
188        Engine::addToSpaceShip(ship);
189
190        if (!ship)
191            return;
192
193        if( this->defEngineSndNormal_ )
194            this->getShip()->attach(defEngineSndNormal_);
195        if( this->defEngineSndBoost_ )
196            this->getShip()->attach(defEngineSndBoost_);
197
198        for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
199            for (std::vector<WorldEntity*>::const_iterator it2 = (*it)->getEffectsBegin(); it2 != (*it)->getEffectsEnd(); ++it2)
200                this->getShip()->attach(*it2);
201    }
202
203    void MultiStateEngine::addEffectContainer(EffectContainer* effect)
204    {
205        if (effect == NULL)
206            return;
207        effect->setLuaState(this->lua_, 'f' + multi_cast<std::string>(this->effectContainers_.size()));
208        this->effectContainers_.push_back(effect);
209        if (this->getShip())
210        {
211            for (std::vector<WorldEntity*>::const_iterator it = effect->getEffectsBegin(); it != effect->getEffectsBegin(); ++it)
212                this->getShip()->attach(*it);
213        }
214    }
215
216    EffectContainer* MultiStateEngine::getEffectContainer(unsigned int index) const
217    {
218        unsigned int i = 0;
219        for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
220        {
221            if (i == index)
222                return (*it);
223        }
224        return NULL;
225    }
226
227    void MultiStateEngine::setDefEngSndNormal(const std::string &engineSound)
228    {
229        if( defEngineSndNormal_ )
230            defEngineSndNormal_->setSource(engineSound);
231        else
232            assert(0); // This should never happen, because soundpointer is only available on master
233    }
234
235    const std::string& MultiStateEngine::getDefEngSndNormal()
236    {
237        if( defEngineSndNormal_ )
238            return defEngineSndNormal_->getSource();
239        else
240            assert(0);
241        return BLANKSTRING;
242    }
243
244    void MultiStateEngine::setDefEngSndBoost(const std::string &engineSound)
245    {
246        if( defEngineSndBoost_ )
247            defEngineSndBoost_->setSource(engineSound);
248        else
249            assert(0);
250    }
251
252    const std::string& MultiStateEngine::getDefEngSndBoost()
253    {
254        if( this->defEngineSndBoost_ )
255            return defEngineSndBoost_->getSource();
256        else
257            assert(0);
258        return BLANKSTRING;
259    }
260}
Note: See TracBrowser for help on using the repository browser.