Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gameimmersion/src/orxonox/worldentities/pawns/SpaceShip.cc @ 8254

Last change on this file since 8254 was 8254, checked in by dboehi, 13 years ago

Added possibibility to change the frequency of the shaking camera in the
space ship configuration file.

  • Property svn:eol-style set to native
File size: 10.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 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "SpaceShip.h"
30
31#include <BulletDynamics/Dynamics/btRigidBody.h>
32
33#include "core/CoreIncludes.h"
34#include "core/ConfigValueIncludes.h"
35#include "core/Template.h"
36#include "core/XMLPort.h"
37#include "items/Engine.h"
38#include "graphics/Camera.h"
39#include "CameraManager.h"
40
41namespace orxonox
42{
43    const float orientationGain = 100;
44    CreateFactory(SpaceShip);
45
46    SpaceShip::SpaceShip(BaseObject* creator) : Pawn(creator)
47    {
48        RegisterObject(SpaceShip);
49
50        this->primaryThrust_  = 100;
51        this->auxilaryThrust_ =  30;
52        this->rotationThrust_ =  10;
53
54        this->localLinearAcceleration_.setValue(0, 0, 0);
55        this->localAngularAcceleration_.setValue(0, 0, 0);
56        this->bBoost_ = false;
57        this->bPermanentBoost_ = false;
58        this->steering_ = Vector3::ZERO;
59        this->engine_ = 0;
60
61        this->boostPower_ = 10.0f;
62        this->initialBoostPower_ = 10.0f;
63        this->boostRate_ = 5.0;
64        this->boostPowerRate_ = 1.0;
65        this->boostCooldownDuration_ = 5.0;
66        this->bBoostCooldown_ = false;
67
68        this->bInvertYAxis_ = false;
69
70        this->setDestroyWhenPlayerLeft(true);
71
72        // SpaceShip is always a physical object per default
73        // Be aware of this call: The collision type legality check will not reach derived classes!
74        this->setCollisionType(WorldEntity::Dynamic);
75        // Get notification about collisions
76        this->enableCollisionCallback();
77
78        this->setConfigValues();
79        this->registerVariables();
80       
81        Camera* c = CameraManager::getInstance().getActiveCamera();
82        this->cameraOriginalPosition = c->getPosition();
83        this->cameraOriginalOrientation = c->getOrientation();
84
85        this->shakeFrequency_ = 20;
86        this->shakeAmplitude_ = 40;
87        this->shakeDt_ = 0;
88    }
89
90    SpaceShip::~SpaceShip()
91    {
92        if (this->isInitialized() && this->engine_)
93            this->engine_->destroy();
94    }
95
96    void SpaceShip::XMLPort(Element& xmlelement, XMLPort::Mode mode)
97    {
98        SUPER(SpaceShip, XMLPort, xmlelement, mode);
99
100        XMLPortParam(SpaceShip, "engine",            setEngineTemplate,    getEngineTemplate,    xmlelement, mode);
101        XMLPortParamVariable(SpaceShip, "primaryThrust",  primaryThrust_,  xmlelement, mode);
102        XMLPortParamVariable(SpaceShip, "auxilaryThrust", auxilaryThrust_, xmlelement, mode);
103        XMLPortParamVariable(SpaceShip, "rotationThrust", rotationThrust_, xmlelement, mode);
104        XMLPortParamVariable(SpaceShip, "boostPower", initialBoostPower_, xmlelement, mode);
105        XMLPortParamVariable(SpaceShip, "boostPowerRate", boostPowerRate_, xmlelement, mode);
106        XMLPortParamVariable(SpaceShip, "boostRate", boostRate_, xmlelement, mode);
107        XMLPortParamVariable(SpaceShip, "boostCooldownDuration", boostCooldownDuration_, xmlelement, mode);
108        XMLPortParamVariable(SpaceShip, "shakeFrequency", shakeFrequency_, xmlelement, mode);
109    }
110
111    void SpaceShip::registerVariables()
112    {
113        registerVariable(this->primaryThrust_,  VariableDirection::ToClient);
114        registerVariable(this->auxilaryThrust_, VariableDirection::ToClient);
115        registerVariable(this->rotationThrust_, VariableDirection::ToClient);
116    }
117
118    void SpaceShip::setConfigValues()
119    {
120        SetConfigValue(bInvertYAxis_, false).description("Set this to true for joystick-like mouse behaviour (mouse up = ship down).");
121    }
122
123    bool SpaceShip::isCollisionTypeLegal(WorldEntity::CollisionType type) const
124    {
125        if (type != WorldEntity::Dynamic)
126        {
127            CCOUT(1) << "Error: Cannot tell a SpaceShip not to be dynamic! Ignoring." << std::endl;
128            assert(false); // Only in debug mode
129            return false;
130        }
131        else
132            return true;
133    }
134
135    void SpaceShip::tick(float dt)
136    {
137        SUPER(SpaceShip, tick, dt);
138
139        if (this->hasLocalController())
140        {
141/*
142            this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() * getMass() * this->auxilaryThrust_);
143            this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() * getMass() * this->auxilaryThrust_);
144            if (this->localLinearAcceleration_.z() > 0)
145                this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() * getMass() * this->auxilaryThrust_);
146            else
147                this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() * getMass() * this->primaryThrust_);
148            this->physicalBody_->applyCentralForce(physicalBody_->getWorldTransform().getBasis() * this->localLinearAcceleration_);
149            this->localLinearAcceleration_.setValue(0, 0, 0);
150*/
151            if (!this->isInMouseLook())
152            {
153                this->localAngularAcceleration_ *= this->getLocalInertia() * this->rotationThrust_;
154                this->physicalBody_->applyTorque(physicalBody_->getWorldTransform().getBasis() * this->localAngularAcceleration_);
155            }
156
157            this->localAngularAcceleration_.setValue(0, 0, 0);
158
159            if(!this->bBoostCooldown_ && this->boostPower_ < this->initialBoostPower_)
160            {
161                this->boostPower_ += this->boostPowerRate_*dt;
162            }
163
164
165        Camera* c = this->getCamera();
166            if(this->bBoost_)
167            {
168                this->boostPower_ -=this->boostRate_*dt;
169                if(this->boostPower_ <= 0.0f)
170                {
171                    this->bBoost_ = false;
172                    this->bBoostCooldown_ = true;
173                    this->timer_.setTimer(this->boostCooldownDuration_, false, createExecutor(createFunctor(&SpaceShip::boostCooledDown, this)));
174                   
175                }
176                else
177                {
178                        this->shakeDt_ += dt;
179
180                        //Shaking Camera effect
181                        if (c != 0)
182                        {
183
184                                if (c->getAngularVelocity() == Vector3(0,0,0))
185                                {
186                                        c->setAngularVelocity(Vector3(2,0,0));
187
188                                        //set the delta to half the period time,
189                                        //so the camera shakes up and down.
190                                        this->shakeDt_ = 1/(2 * this->shakeFrequency_);
191                                }
192
193
194                                //toggle the rotation
195                                if (1/(this->shakeFrequency_) <= shakeDt_)
196                                {
197                                        c->setAngularVelocity(-c->getAngularVelocity());
198                                        shakeDt_ = 0;
199                                }
200                        }
201                }
202            }
203            else
204            {
205                    //reset the camera, if the boost is not active
206                    //TODO: don't call this every tick
207                    this->resetCamera();
208            }
209        }
210    }
211
212    void SpaceShip::boostCooledDown(void)
213    {
214        this->bBoostCooldown_ = false;
215    }
216
217    void SpaceShip::moveFrontBack(const Vector2& value)
218    {
219        this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() - value.x);
220        this->steering_.z = -value.x;
221    }
222
223    void SpaceShip::moveRightLeft(const Vector2& value)
224    {
225        this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() + value.x);
226        this->steering_.x = value.x;
227    }
228
229    void SpaceShip::moveUpDown(const Vector2& value)
230    {
231        this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() + value.x);
232        this->steering_.y = value.x;
233    }
234
235    void SpaceShip::rotateYaw(const Vector2& value)
236    {
237        this->localAngularAcceleration_.setY(this->localAngularAcceleration_.y() + value.x);
238
239        Pawn::rotateYaw(value);
240    }
241
242    void SpaceShip::rotatePitch(const Vector2& value)
243    {
244        this->localAngularAcceleration_.setX(this->localAngularAcceleration_.x() + value.x);
245
246        Pawn::rotatePitch(value);
247    }
248
249    void SpaceShip::rotateRoll(const Vector2& value)
250    {
251        this->localAngularAcceleration_.setZ(this->localAngularAcceleration_.z() + value.x);
252
253        Pawn::rotateRoll(value);
254    }
255
256    // TODO: something seems to call this function every tick, could probably handled a little more efficiently!
257    void SpaceShip::setBoost(bool bBoost)
258    {
259        if(bBoost == this->bBoost_)
260            return;
261
262        if(bBoost)
263            this->boost();
264        else
265        {
266            this->bBoost_ = false;
267        }
268    }
269
270    void SpaceShip::fire()
271    {
272    }
273
274    void SpaceShip::boost()
275    {
276        if(!this->bBoostCooldown_)
277            this->bBoost_ = true;
278    }
279
280    void SpaceShip::loadEngineTemplate()
281    {
282        if (!this->enginetemplate_.empty())
283        {
284            Template* temp = Template::getTemplate(this->enginetemplate_);
285
286            if (temp)
287            {
288                Identifier* identifier = temp->getBaseclassIdentifier();
289
290                if (identifier)
291                {
292                    BaseObject* object = identifier->fabricate(this);
293                    this->engine_ = orxonox_cast<Engine*>(object);
294
295                    if (this->engine_)
296                    {
297                        this->engine_->addTemplate(temp);
298                        this->engine_->addToSpaceShip(this);
299                    }
300                    else
301                    {
302                        object->destroy();
303                    }
304                }
305            }
306        }
307    }
308
309    void SpaceShip::setEngine(Engine* engine)
310    {
311        this->engine_ = engine;
312        if (engine && engine->getShip() != this)
313            engine->addToSpaceShip(this);
314    }
315
316    std::vector<PickupCarrier*>* SpaceShip::getCarrierChildren(void) const
317    {
318        std::vector<PickupCarrier*>* list = new std::vector<PickupCarrier*>();
319        list->push_back(this->engine_);
320        return list;
321    }
322   
323    void SpaceShip::resetCamera()
324    {
325            Camera *c = this->getCamera();
326           
327            assert(c != 0);
328           
329            c->setAngularVelocity(Vector3(0,0,0));
330            c->setPosition(this->cameraOriginalPosition);
331            c->setOrientation(this->cameraOriginalOrientation);
332    }
333}
Note: See TracBrowser for help on using the repository browser.