Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/cpp11_v2/src/orxonox/items/MultiStateEngine.cc @ 10918

Last change on this file since 10918 was 10916, checked in by landauf, 10 years ago

use actual types instead of 'auto'. only exception is for complicated template types, e.g. when iterating over a map

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