Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation2/src/orxonox/items/MultiStateEngine.cc @ 6327

Last change on this file since 6327 was 6327, checked in by rgrieder, 14 years ago

Engine synchronisation seems to work more or less.
Fire sound still doesn't work on client.

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