Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network/src/orxonox/objects/SpaceShip.cc @ 1494

Last change on this file since 1494 was 1494, checked in by rgrieder, 16 years ago
  • set the svn:eol-style property to all files so, that where ever you check out, you'll get the right line endings (had to change every file with mixed endings to windows in order to set the property)
  • Property svn:eol-style set to native
File size: 20.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 *   Co-authors:
25 *      Benjamin Knecht
26 *
27 */
28
29#include "OrxonoxStableHeaders.h"
30#include "SpaceShip.h"
31
32#include <OgreCamera.h>
33#include <OgreRenderWindow.h>
34#include <OgreParticleSystem.h>
35#include <OgreSceneNode.h>
36
37#include "CameraHandler.h"
38#include "util/Convert.h"
39#include "util/Math.h"
40#include "core/CoreIncludes.h"
41#include "core/ConfigValueIncludes.h"
42#include "core/Debug.h"
43#include "GraphicsEngine.h"
44#include "core/InputManager.h"
45#include "particle/ParticleInterface.h"
46#include "Projectile.h"
47#include "RotatingProjectile.h"
48#include "core/XMLPort.h"
49#include "core/ConsoleCommand.h"
50#include "network/Client.h"
51#include "hud/HUD.h"
52
53namespace orxonox
54{
55    SetConsoleCommand(SpaceShip, setMaxSpeedTest, false).setAccessLevel(AccessLevel::Debug);
56    SetConsoleCommand(SpaceShip, whereAmI, true).setAccessLevel(AccessLevel::User);
57    SetConsoleCommand(SpaceShip, moveLongitudinal, true).setAccessLevel(AccessLevel::User).setDefaultValue(0, 1.0f).setAxisParamIndex(0).setKeybindMode(KeybindMode::OnHold);
58    SetConsoleCommand(SpaceShip, moveLateral, true).setAccessLevel(AccessLevel::User).setDefaultValue(0, 1.0f).setAxisParamIndex(0).setKeybindMode(KeybindMode::OnHold);
59    SetConsoleCommand(SpaceShip, moveYaw, true).setAccessLevel(AccessLevel::User).setDefaultValue(0, 1.0f).setAxisParamIndex(0).setKeybindMode(KeybindMode::OnHold);
60    SetConsoleCommand(SpaceShip, movePitch, true).setAccessLevel(AccessLevel::User).setDefaultValue(0, 1.0f).setAxisParamIndex(0).setKeybindMode(KeybindMode::OnHold);
61    SetConsoleCommand(SpaceShip, moveRoll, true).setAccessLevel(AccessLevel::User).setDefaultValue(0, 1.0f).setAxisParamIndex(0).setKeybindMode(KeybindMode::OnHold);
62    SetConsoleCommand(SpaceShip, fire, true).setAccessLevel(AccessLevel::User).setKeybindMode(KeybindMode::OnHold);
63    SetConsoleCommandGeneric(test1, SpaceShip, createConsoleCommand(createFunctor(&SpaceShip::setMaxSpeedTest), "setMaxSpeed"), false).setAccessLevel(AccessLevel::Debug);
64    SetConsoleCommandGeneric(test2, SpaceShip, createConsoleCommand(createFunctor(&SpaceShip::setMaxSpeedTest), "setMaxBlubber"), false).setAccessLevel(AccessLevel::Debug);
65    SetConsoleCommandGeneric(test3, SpaceShip, createConsoleCommand(createFunctor(&SpaceShip::setMaxSpeedTest), "setRofl"), false).setAccessLevel(AccessLevel::Debug);
66
67    CreateFactory(SpaceShip);
68
69    SpaceShip* SpaceShip::instance_s;
70
71    SpaceShip *SpaceShip::getLocalShip(){
72      Iterator<SpaceShip> it;
73      for(it = ObjectList<SpaceShip>::start(); it; ++it){
74        if( (it)->myShip_ )
75          return *it;
76      }
77      return NULL;
78    }
79
80    SpaceShip::SpaceShip() :
81      //testvector_(0,0,0),
82      //bInvertYAxis_(false),
83      setMouseEventCallback_(false),
84      bLMousePressed_(false),
85      bRMousePressed_(false),
86      camNode_(0),
87      cam_(0),
88      camName_("CamNode"),
89      tt_(0),
90      redNode_(0),
91      greenNode_(0),
92      blinkTime_(0.0f),
93      chNearNode_(0),
94      chFarNode_(0),
95      timeToReload_(0.0f),
96      //reloadTime_(0.0f),
97      maxSideAndBackSpeed_(0.0f),
98      maxSpeed_(0.0f),
99      maxRotation_(0.0f),
100      translationAcceleration_(0.0f),
101      rotationAcceleration_(0.0f),
102      translationDamping_(0.0f),
103      rotationDamping_(0.0f),
104      maxRotationRadian_(0),
105      rotationAccelerationRadian_(0),
106      rotationDampingRadian_(0),
107      zeroRadian_(0),
108      mouseXRotation_(0),
109      mouseYRotation_(0),
110      mouseX_(0.0f),
111      mouseY_(0.0f),
112      emitterRate_(0.0f),
113      myShip_(false),
114      teamNr_(0),
115      health_(100)
116    {
117        RegisterObject(SpaceShip);
118        this->registerAllVariables();
119
120        SpaceShip::instance_s = this;
121
122        this->setConfigValues();
123
124        initialDir_ = Vector3(1.0, 0.0, 0.0);
125        currentDir_ = initialDir_;
126        initialOrth_ = Vector3(0.0, 0.0, 1.0);
127        currentOrth_ = initialOrth_;
128
129        this->camName_ = this->getName() + "CamNode";
130
131        this->setRotationAxis(1, 0, 0);
132        this->setStatic(false);
133
134        COUT(3) << "Info: SpaceShip was loaded" << std::endl;
135    }
136
137    SpaceShip::~SpaceShip()
138    {
139        if (this->tt_)
140            delete this->tt_;
141        if(setMouseEventCallback_)
142          InputManager::removeMouseHandler("SpaceShip");
143        if (this->cam_)
144          delete this->cam_;
145        if (!Identifier::isCreatingHierarchy() && !myShip_ && &HUD::getSingleton()!=NULL)
146          //remove the radar object
147          HUD::getSingleton().removeRadarObject(this->getNode());
148    }
149
150    bool SpaceShip::create(){
151      if(!myShip_){
152        if(network::Client::getSingleton() && objectID == network::Client::getSingleton()->getShipID())
153          myShip_=true;
154        else
155          HUD::getSingleton().addRadarObject(this->getNode(), 3);
156      }
157      if(Model::create())
158        this->init();
159      else
160        return false;
161      return true;
162    }
163
164    void SpaceShip::registerAllVariables(){
165      registerVar( &camName_, camName_.length()+1, network::STRING, 0x1);
166      registerVar( &maxSpeed_, sizeof(maxSpeed_), network::DATA, 0x1);
167      registerVar( &maxSideAndBackSpeed_, sizeof(maxSideAndBackSpeed_), network::DATA, 0x1);
168      registerVar( &maxRotation_, sizeof(maxRotation_), network::DATA, 0x1);
169      registerVar( &translationAcceleration_, sizeof(translationAcceleration_), network::DATA, 0x1);
170      registerVar( &rotationAcceleration_, sizeof(rotationAcceleration_), network::DATA, 0x1);
171      registerVar( &rotationAccelerationRadian_, sizeof(rotationAccelerationRadian_), network::DATA, 0x1);
172      registerVar( &translationDamping_, sizeof(translationDamping_), network::DATA, 0x1);
173      registerVar( &rotationDamping_, sizeof(rotationDamping_), network::DATA, 0x1);
174      registerVar( &rotationDampingRadian_, sizeof(rotationDampingRadian_), network::DATA, 0x1);
175
176    }
177
178    void SpaceShip::init()
179    {
180        // START CREATING THRUSTER
181        this->tt_ = new ParticleInterface(GraphicsEngine::getSingleton().getSceneManager(),"twinthruster" + this->getName(),"Orxonox/engineglow");
182        this->tt_->getParticleSystem()->setParameter("local_space","true");
183        this->tt_->newEmitter();
184/*
185        this->tt_->setDirection(Vector3(0,0,1));
186        this->tt_->setPositionOfEmitter(0, Vector3(20,-1,-15));
187        this->tt_->setPositionOfEmitter(1, Vector3(-20,-1,-15));
188*/
189        this->tt_->setDirection(Vector3(-1,0,0));
190        this->tt_->setPositionOfEmitter(0, Vector3(-15,20,-1));
191        this->tt_->setPositionOfEmitter(1, Vector3(-15,-20,-1));
192        this->tt_->setVelocity(50);
193
194        emitterRate_ = tt_->getRate();
195
196        Ogre::SceneNode* node2 = this->getNode()->createChildSceneNode(this->getName() + "particle2");
197        node2->setInheritScale(false);
198        tt_->addToSceneNode(node2);
199        // END CREATING THRUSTER
200
201        // START CREATING BLINKING LIGHTS
202        this->redBillboard_.setBillboardSet("Examples/Flare", ColourValue(1.0, 0.0, 0.0), 1);
203        this->greenBillboard_.setBillboardSet("Examples/Flare", ColourValue(0.0, 1.0, 0.0), 1);
204
205        this->redNode_ = this->getNode()->createChildSceneNode(this->getName() + "red", Vector3(0.3, 4.0, -0.3));
206        this->redNode_->setInheritScale(false);
207        this->greenNode_ = this->getNode()->createChildSceneNode(this->getName() + "green", Vector3(0.3, -4.0, -0.3));
208        this->greenNode_->setInheritScale(false);
209
210        this->redNode_->attachObject(this->redBillboard_.getBillboardSet());
211        this->redNode_->setScale(0.3, 0.3, 0.3);
212
213        this->greenNode_->attachObject(this->greenBillboard_.getBillboardSet());
214        this->greenNode_->setScale(0.3, 0.3, 0.3);
215        // END CREATING BLINKING LIGHTS
216
217        if (this->isExactlyA(Class(SpaceShip)))
218        {
219            // START of testing crosshair
220            this->crosshairNear_.setBillboardSet("Orxonox/Crosshair", ColourValue(1.0, 1.0, 0.0), 1);
221            this->crosshairFar_.setBillboardSet("Orxonox/Crosshair", ColourValue(1.0, 1.0, 0.0), 1);
222
223            this->chNearNode_ = this->getNode()->createChildSceneNode(this->getName() + "near", Vector3(50.0, 0.0, 0.0));
224            this->chNearNode_->setInheritScale(false);
225            this->chFarNode_ = this->getNode()->createChildSceneNode(this->getName() + "far", Vector3(200.0, 0.0, 0.0));
226            this->chFarNode_->setInheritScale(false);
227
228            this->chNearNode_->attachObject(this->crosshairNear_.getBillboardSet());
229            this->chNearNode_->setScale(0.2, 0.2, 0.2);
230
231            this->chFarNode_->attachObject(this->crosshairFar_.getBillboardSet());
232            this->chFarNode_->setScale(0.4, 0.4, 0.4);
233        }
234
235        createCamera();
236        // END of testing crosshair
237    }
238
239    void SpaceShip::setConfigValues()
240    {
241        SetConfigValue(bInvertYAxis_, false).description("Set this to true for joystick-like mouse behaviour (mouse up = ship down).");
242        SetConfigValue(reloadTime_, 0.125).description("The reload time of the weapon in seconds");
243        SetConfigValue(testvector_, Vector3()).description("asdfblah");
244    }
245
246    void SpaceShip::setCamera(const std::string& camera)
247    {
248      camName_=camera;
249      // change camera attributes here, if you want to ;)
250    }
251
252    void SpaceShip::getFocus(){
253      COUT(4) << "requesting focus" << std::endl;
254      if(network::Client::getSingleton()==0 || network::Client::getSingleton()->getShipID()==objectID)
255        CameraHandler::getInstance()->requestFocus(cam_);
256
257    }
258
259    Camera* SpaceShip::getCamera(){
260        return cam_;
261    }
262
263    void SpaceShip::createCamera(){
264//       COUT(4) << "begin camera creation" << std::endl;
265      this->camNode_ = this->getNode()->createChildSceneNode(camName_);
266      COUT(4) << "position: (this)" << this->getNode()->getPosition() << std::endl;
267      this->camNode_->setPosition(Vector3(-50,0,10));
268//      Quaternion q1 = Quaternion(Radian(Degree(90)),Vector3(0,-1,0));
269//      Quaternion q2 = Quaternion(Radian(Degree(90)),Vector3(0,0,-1));
270//      camNode_->setOrientation(q1*q2);
271      COUT(4) << "position: (cam)" << this->camNode_->getPosition() << std::endl;
272      cam_ = new Camera(this->camNode_);
273
274      cam_->setTargetNode(this->getNode());
275//        cam->setPosition(Vector3(0,-350,0));
276      Quaternion q1 = Quaternion(Radian(Degree(90)),Vector3(0,-1,0));
277      Quaternion q2 = Quaternion(Radian(Degree(90)),Vector3(1,0,0));
278      camNode_->setOrientation(q2*q1);
279      if(network::Client::getSingleton()!=0 && network::Client::getSingleton()->getShipID()==objectID){
280        this->setBacksync(true);
281        CameraHandler::getInstance()->requestFocus(cam_);
282      }
283
284    }
285
286    void SpaceShip::setMaxSpeed(float value)
287    { this->maxSpeed_ = value; }
288    void SpaceShip::setMaxSideAndBackSpeed(float value)
289    { this->maxSideAndBackSpeed_ = value; }
290    void SpaceShip::setMaxRotation(float value)
291    { this->maxRotation_ = value; this->maxRotationRadian_ = Radian(value); }
292    void SpaceShip::setTransAcc(float value)
293    { this->translationAcceleration_ = value; }
294    void SpaceShip::setRotAcc(float value)
295    { this->rotationAcceleration_ = value; this->rotationAccelerationRadian_ = Radian(value); }
296    void SpaceShip::setTransDamp(float value)
297    { this->translationDamping_ = value; }
298    void SpaceShip::setRotDamp(float value)
299    { this->rotationDamping_ = value; this->rotationDampingRadian_ = Radian(value); }
300
301    /**
302        @brief XML loading and saving.
303        @param xmlelement The XML-element
304        @param loading Loading (true) or saving (false)
305        @return The XML-element
306    */
307    void SpaceShip::XMLPort(Element& xmlelement, XMLPort::Mode mode)
308    {
309        Model::XMLPort(xmlelement, mode);
310
311        XMLPortParamLoadOnly(SpaceShip, "camera", setCamera, xmlelement, mode);
312        XMLPortParamLoadOnly(SpaceShip, "maxSpeed", setMaxSpeed, xmlelement, mode);
313        XMLPortParamLoadOnly(SpaceShip, "maxSideAndBackSpeed", setMaxSideAndBackSpeed, xmlelement, mode);
314        XMLPortParamLoadOnly(SpaceShip, "maxRotation", setMaxRotation, xmlelement, mode);
315        XMLPortParamLoadOnly(SpaceShip, "transAcc", setTransAcc, xmlelement, mode);
316        XMLPortParamLoadOnly(SpaceShip, "rotAcc", setRotAcc, xmlelement, mode);
317        XMLPortParamLoadOnly(SpaceShip, "transDamp", setTransDamp, xmlelement, mode);
318        XMLPortParamLoadOnly(SpaceShip, "rotDamp", setRotDamp, xmlelement, mode);
319        myShip_=true; // TODO: this is only a hack
320
321        SpaceShip::create();
322        if (this->isExactlyA(Class(SpaceShip)))
323            getFocus();
324    }
325
326    int sgn(float x)
327    {
328        if (x >= 0)
329            return 1;
330        else
331            return -1;
332    }
333
334    std::string SpaceShip::whereAmI() {
335        return getConvertedValue<float, std::string>(SpaceShip::getLocalShip()->getPosition().x)
336        + "  " + getConvertedValue<float, std::string>(SpaceShip::getLocalShip()->getPosition().y)
337        + "  " + getConvertedValue<float, std::string>(SpaceShip::getLocalShip()->getPosition().z);
338    }
339
340    Vector3 SpaceShip::getDir() {
341        return currentDir_;
342    }
343
344    Vector3 SpaceShip::getOrth(){
345        return currentOrth_;
346    }
347
348    float SpaceShip::getMaxSpeed() { return maxSpeed_; }
349
350    void SpaceShip::tick(float dt)
351    {
352        currentDir_ = getOrientation()*initialDir_;
353                currentOrth_ = getOrientation()*initialOrth_;
354
355        if (this->cam_)
356            this->cam_->tick(dt);
357
358        if (this->redNode_ && this->greenNode_)
359        {
360            this->blinkTime_ += dt;
361            float redScale = 0.15 + 0.15 * sin(this->blinkTime_ * 10.0);
362            float greenScale = 0.15 - 0.15 * sin(this->blinkTime_ * 10.0);
363            this->redNode_->setScale(redScale, redScale, redScale);
364            this->greenNode_->setScale(greenScale, greenScale, greenScale);
365        }
366
367        if (this->timeToReload_ > 0)
368            this->timeToReload_ -= dt;
369        else
370            this->timeToReload_ = 0;
371
372        if (this->bLMousePressed_ && this->timeToReload_ <= 0)
373        {
374
375            Projectile *p;
376            if (this->isExactlyA(Class(SpaceShip)))
377                p = new RotatingProjectile(this);
378            else
379                p = new Projectile(this);
380            p->setColour(this->getProjectileColour());
381            p->create();
382            if(p->classID==0)
383              COUT(3) << "generated projectile with classid 0" <<  std::endl; // TODO: remove this output
384
385            p->setBacksync(true);
386            this->timeToReload_ = this->reloadTime_;
387        }
388
389
390        // #####################################
391        // ############# STEERING ##############
392        // #####################################
393
394        if (this->velocity_.x > this->maxSpeed_)
395            this->velocity_.x = this->maxSpeed_;
396        if (this->velocity_.x < -this->maxSideAndBackSpeed_)
397            this->velocity_.x = -this->maxSideAndBackSpeed_;
398        if (this->velocity_.y > this->maxSideAndBackSpeed_)
399            this->velocity_.y = this->maxSideAndBackSpeed_;
400        if (this->velocity_.y < -this->maxSideAndBackSpeed_)
401            this->velocity_.y = -this->maxSideAndBackSpeed_;
402        if (this->rotationRate_ > this->maxRotationRadian_)
403            this->rotationRate_ = this->maxRotationRadian_;
404        if (this->rotationRate_ < -this->maxRotationRadian_)
405            this->rotationRate_ = -this->maxRotationRadian_;
406
407        if (this->acceleration_.x == 0)
408        {
409            if (this->velocity_.x > 0)
410            {
411                this->velocity_.x -= (this->translationDamping_ * dt);
412                if (this->velocity_.x < 0)
413                    this->velocity_.x = 0;
414            }
415            else if (this->velocity_.x < 0)
416            {
417                this->velocity_.x += (this->translationDamping_ * dt);
418                if (this->velocity_.x > 0)
419                    this->velocity_.x = 0;
420            }
421        }
422
423        if (this->acceleration_.y == 0)
424        {
425            if (this->velocity_.y > 0)
426            {
427                this->velocity_.y -= (this->translationDamping_ * dt);
428                if (this->velocity_.y < 0)
429                    this->velocity_.y = 0;
430            }
431            else if (this->velocity_.y < 0)
432            {
433                this->velocity_.y += (this->translationDamping_ * dt);
434                if (this->velocity_.y > 0)
435                    this->velocity_.y = 0;
436            }
437        }
438
439        if (this->momentum_ == this->zeroRadian_)
440        {
441            if (this->rotationRate_ > this->zeroRadian_)
442            {
443                this->rotationRate_ -= (this->rotationDampingRadian_ * dt);
444                if (this->rotationRate_ < this->zeroRadian_)
445                    this->rotationRate_ = 0;
446            }
447            else if (this->rotationRate_ < this->zeroRadian_)
448            {
449                this->rotationRate_ += (this->rotationDampingRadian_ * dt);
450                if (this->rotationRate_ > this->zeroRadian_)
451                    this->rotationRate_ = 0;
452            }
453        }
454
455
456        WorldEntity::tick(dt);
457
458        this->roll(this->mouseXRotation_ * dt);
459        if (this->bInvertYAxis_)
460            this->yaw(Radian(-this->mouseYRotation_ * dt));
461        else
462            this->yaw(Radian(this->mouseYRotation_ * dt));
463
464        if (this->acceleration_.x > 0)
465            this->tt_->setRate(emitterRate_);
466        else
467            this->tt_->setRate(0);
468
469        if( myShip_ )
470        {
471          COUT(4) << "steering our ship: " << objectID << std::endl;
472          this->acceleration_.x = 0;
473          this->acceleration_.y = 0;
474          this->momentum_ = 0;
475          this->mouseXRotation_ = Radian(0);
476          this->mouseYRotation_ = Radian(0);
477          this->bLMousePressed_ = false;
478        }/*else
479          COUT(4) << "not steering ship: " << objectID << " our ship: " << network::Client::getSingleton()->getShipID() << std::endl;*/
480    }
481
482    void SpaceShip::movePitch(float val)
483    {   getLocalShip()->setMovePitch(val);   }
484    void SpaceShip::moveYaw(float val)
485    {   getLocalShip()->setMoveYaw(val);   }
486    void SpaceShip::moveRoll(float val)
487    {   getLocalShip()->setMoveRoll(val);   }
488    void SpaceShip::moveLongitudinal(float val)
489    {   getLocalShip()->setMoveLongitudinal(val);   }
490    void SpaceShip::moveLateral(float val)
491    {   getLocalShip()->setMoveLateral(val);   }
492    void SpaceShip::fire()
493    {   getLocalShip()->doFire();   }
494
495    void SpaceShip::setMovePitch(float val)
496    {
497        val = -val * val * sgn(val) * this->rotationAcceleration_;
498        if (val > this->maxRotation_)
499            val = this->maxRotation_;
500        if (val < -this->maxRotation_)
501            val = -this->maxRotation_;
502        this->mouseYRotation_ = Radian(val);
503    }
504
505    void SpaceShip::setMoveYaw(float val)
506    {
507        val = -val * val * sgn(val) * this->rotationAcceleration_;
508        if (val > this->maxRotation_)
509            val = this->maxRotation_;
510        if (val < -this->maxRotation_)
511            val = -this->maxRotation_;
512        this->mouseXRotation_ = Radian(val);
513    }
514
515    void SpaceShip::setMoveRoll(float val)
516    {
517        this->momentum_ = Radian(-this->rotationAccelerationRadian_ * val);
518        //COUT(3) << "rotating val: " << val << " acceleration: " << this->rotationAccelerationRadian_.valueDegrees() << std::endl;
519    }
520
521    void SpaceShip::setMoveLongitudinal(float val)
522    {
523        this->acceleration_.x = this->translationAcceleration_ * val;
524    }
525
526    void SpaceShip::setMoveLateral(float val)
527    {
528        this->acceleration_.y = -this->translationAcceleration_ * val;
529    }
530
531    void SpaceShip::doFire()
532    {
533        this->bLMousePressed_ = true;
534    }
535}
Note: See TracBrowser for help on using the repository browser.