Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 1479 was 1479, checked in by landauf, 16 years ago

added something like an AI… or at least something thats pretty close to what we call AI. it's not that clever, sometimes it does some sign errors. but hey, I don't care, at least it makes the game look more living.

File size: 20.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 *      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    }
146
147    bool SpaceShip::create(){
148      if(!myShip_){
149        if(network::Client::getSingleton() && objectID == network::Client::getSingleton()->getShipID())
150          myShip_=true;
151        else
152          HUD::getSingleton().addRadarObject(this->getNode(), 2);
153      }
154      if(Model::create())
155        this->init();
156      else
157        return false;
158      return true;
159    }
160
161    void SpaceShip::registerAllVariables(){
162      registerVar( &camName_, camName_.length()+1, network::STRING, 0x1);
163      registerVar( &maxSpeed_, sizeof(maxSpeed_), network::DATA, 0x1);
164      registerVar( &maxSideAndBackSpeed_, sizeof(maxSideAndBackSpeed_), network::DATA, 0x1);
165      registerVar( &maxRotation_, sizeof(maxRotation_), network::DATA, 0x1);
166      registerVar( &translationAcceleration_, sizeof(translationAcceleration_), network::DATA, 0x1);
167      registerVar( &rotationAcceleration_, sizeof(rotationAcceleration_), network::DATA, 0x1);
168      registerVar( &rotationAccelerationRadian_, sizeof(rotationAccelerationRadian_), network::DATA, 0x1);
169      registerVar( &translationDamping_, sizeof(translationDamping_), network::DATA, 0x1);
170      registerVar( &rotationDamping_, sizeof(rotationDamping_), network::DATA, 0x1);
171      registerVar( &rotationDampingRadian_, sizeof(rotationDampingRadian_), network::DATA, 0x1);
172
173    }
174
175    void SpaceShip::init()
176    {
177        // START CREATING THRUSTER
178        this->tt_ = new ParticleInterface(GraphicsEngine::getSingleton().getSceneManager(),"twinthruster" + this->getName(),"Orxonox/engineglow");
179        this->tt_->getParticleSystem()->setParameter("local_space","true");
180        this->tt_->newEmitter();
181/*
182        this->tt_->setDirection(Vector3(0,0,1));
183        this->tt_->setPositionOfEmitter(0, Vector3(20,-1,-15));
184        this->tt_->setPositionOfEmitter(1, Vector3(-20,-1,-15));
185*/
186        this->tt_->setDirection(Vector3(-1,0,0));
187        this->tt_->setPositionOfEmitter(0, Vector3(-15,20,-1));
188        this->tt_->setPositionOfEmitter(1, Vector3(-15,-20,-1));
189        this->tt_->setVelocity(50);
190
191        emitterRate_ = tt_->getRate();
192
193        Ogre::SceneNode* node2 = this->getNode()->createChildSceneNode(this->getName() + "particle2");
194        node2->setInheritScale(false);
195        tt_->addToSceneNode(node2);
196        // END CREATING THRUSTER
197
198        // START CREATING BLINKING LIGHTS
199        this->redBillboard_.setBillboardSet("Examples/Flare", ColourValue(1.0, 0.0, 0.0), 1);
200        this->greenBillboard_.setBillboardSet("Examples/Flare", ColourValue(0.0, 1.0, 0.0), 1);
201
202        this->redNode_ = this->getNode()->createChildSceneNode(this->getName() + "red", Vector3(0.3, 4.0, -0.3));
203        this->redNode_->setInheritScale(false);
204        this->greenNode_ = this->getNode()->createChildSceneNode(this->getName() + "green", Vector3(0.3, -4.0, -0.3));
205        this->greenNode_->setInheritScale(false);
206
207        this->redNode_->attachObject(this->redBillboard_.getBillboardSet());
208        this->redNode_->setScale(0.3, 0.3, 0.3);
209
210        this->greenNode_->attachObject(this->greenBillboard_.getBillboardSet());
211        this->greenNode_->setScale(0.3, 0.3, 0.3);
212        // END CREATING BLINKING LIGHTS
213
214        if (this->isExactlyA(Class(SpaceShip)))
215        {
216            // START of testing crosshair
217            this->crosshairNear_.setBillboardSet("Orxonox/Crosshair", ColourValue(1.0, 1.0, 0.0), 1);
218            this->crosshairFar_.setBillboardSet("Orxonox/Crosshair", ColourValue(1.0, 1.0, 0.0), 1);
219
220            this->chNearNode_ = this->getNode()->createChildSceneNode(this->getName() + "near", Vector3(50.0, 0.0, 0.0));
221            this->chNearNode_->setInheritScale(false);
222            this->chFarNode_ = this->getNode()->createChildSceneNode(this->getName() + "far", Vector3(200.0, 0.0, 0.0));
223            this->chFarNode_->setInheritScale(false);
224
225            this->chNearNode_->attachObject(this->crosshairNear_.getBillboardSet());
226            this->chNearNode_->setScale(0.2, 0.2, 0.2);
227
228            this->chFarNode_->attachObject(this->crosshairFar_.getBillboardSet());
229            this->chFarNode_->setScale(0.4, 0.4, 0.4);
230        }
231
232        createCamera();
233        // END of testing crosshair
234    }
235
236    void SpaceShip::setConfigValues()
237    {
238        SetConfigValue(bInvertYAxis_, false).description("Set this to true for joystick-like mouse behaviour (mouse up = ship down).");
239        SetConfigValue(reloadTime_, 0.125).description("The reload time of the weapon in seconds");
240        SetConfigValue(testvector_, Vector3()).description("asdfblah");
241    }
242
243    void SpaceShip::setCamera(const std::string& camera)
244    {
245      camName_=camera;
246      // change camera attributes here, if you want to ;)
247    }
248
249    void SpaceShip::getFocus(){
250      COUT(4) << "requesting focus" << std::endl;
251      if(network::Client::getSingleton()==0 || network::Client::getSingleton()->getShipID()==objectID)
252        CameraHandler::getInstance()->requestFocus(cam_);
253
254    }
255
256    Camera* SpaceShip::getCamera(){
257        return cam_;
258    }
259
260    void SpaceShip::createCamera(){
261//       COUT(4) << "begin camera creation" << std::endl;
262      this->camNode_ = this->getNode()->createChildSceneNode(camName_);
263      COUT(4) << "position: (this)" << this->getNode()->getPosition() << std::endl;
264      this->camNode_->setPosition(Vector3(-50,0,10));
265//      Quaternion q1 = Quaternion(Radian(Degree(90)),Vector3(0,-1,0));
266//      Quaternion q2 = Quaternion(Radian(Degree(90)),Vector3(0,0,-1));
267//      camNode_->setOrientation(q1*q2);
268      COUT(4) << "position: (cam)" << this->camNode_->getPosition() << std::endl;
269      cam_ = new Camera(this->camNode_);
270
271      cam_->setTargetNode(this->getNode());
272//        cam->setPosition(Vector3(0,-350,0));
273      Quaternion q1 = Quaternion(Radian(Degree(90)),Vector3(0,-1,0));
274      Quaternion q2 = Quaternion(Radian(Degree(90)),Vector3(1,0,0));
275      camNode_->setOrientation(q2*q1);
276      if(network::Client::getSingleton()!=0 && network::Client::getSingleton()->getShipID()==objectID){
277        this->setBacksync(true);
278        CameraHandler::getInstance()->requestFocus(cam_);
279      }
280
281    }
282
283    void SpaceShip::setMaxSpeed(float value)
284    { this->maxSpeed_ = value; }
285    void SpaceShip::setMaxSideAndBackSpeed(float value)
286    { this->maxSideAndBackSpeed_ = value; }
287    void SpaceShip::setMaxRotation(float value)
288    { this->maxRotation_ = value; this->maxRotationRadian_ = Radian(value); }
289    void SpaceShip::setTransAcc(float value)
290    { this->translationAcceleration_ = value; }
291    void SpaceShip::setRotAcc(float value)
292    { this->rotationAcceleration_ = value; this->rotationAccelerationRadian_ = Radian(value); }
293    void SpaceShip::setTransDamp(float value)
294    { this->translationDamping_ = value; }
295    void SpaceShip::setRotDamp(float value)
296    { this->rotationDamping_ = value; this->rotationDampingRadian_ = Radian(value); }
297
298    /**
299        @brief XML loading and saving.
300        @param xmlelement The XML-element
301        @param loading Loading (true) or saving (false)
302        @return The XML-element
303    */
304    void SpaceShip::XMLPort(Element& xmlelement, XMLPort::Mode mode)
305    {
306        Model::XMLPort(xmlelement, mode);
307
308        XMLPortParamLoadOnly(SpaceShip, "camera", setCamera, xmlelement, mode);
309        XMLPortParamLoadOnly(SpaceShip, "maxSpeed", setMaxSpeed, xmlelement, mode);
310        XMLPortParamLoadOnly(SpaceShip, "maxSideAndBackSpeed", setMaxSideAndBackSpeed, xmlelement, mode);
311        XMLPortParamLoadOnly(SpaceShip, "maxRotation", setMaxRotation, xmlelement, mode);
312        XMLPortParamLoadOnly(SpaceShip, "transAcc", setTransAcc, xmlelement, mode);
313        XMLPortParamLoadOnly(SpaceShip, "rotAcc", setRotAcc, xmlelement, mode);
314        XMLPortParamLoadOnly(SpaceShip, "transDamp", setTransDamp, xmlelement, mode);
315        XMLPortParamLoadOnly(SpaceShip, "rotDamp", setRotDamp, xmlelement, mode);
316        myShip_=true; // TODO: this is only a hack
317        SpaceShip::create();
318        getFocus();
319    }
320
321    int sgn(float x)
322    {
323        if (x >= 0)
324            return 1;
325        else
326            return -1;
327    }
328
329    std::string SpaceShip::whereAmI() {
330        return getConvertedValue<float, std::string>(SpaceShip::getLocalShip()->getPosition().x)
331        + "  " + getConvertedValue<float, std::string>(SpaceShip::getLocalShip()->getPosition().y)
332        + "  " + getConvertedValue<float, std::string>(SpaceShip::getLocalShip()->getPosition().z);
333    }
334
335    Vector3 SpaceShip::getDir() {
336        return currentDir_;
337    }
338
339    Vector3 SpaceShip::getOrth(){
340        return currentOrth_;
341    }
342
343    float SpaceShip::getMaxSpeed() { return maxSpeed_; }
344
345    void SpaceShip::tick(float dt)
346    {
347        currentDir_ = getOrientation()*initialDir_;
348                currentOrth_ = getOrientation()*initialOrth_;
349
350        if (this->cam_)
351            this->cam_->tick(dt);
352
353        if (this->redNode_ && this->greenNode_)
354        {
355            this->blinkTime_ += dt;
356            float redScale = 0.15 + 0.15 * sin(this->blinkTime_ * 10.0);
357            float greenScale = 0.15 - 0.15 * sin(this->blinkTime_ * 10.0);
358            this->redNode_->setScale(redScale, redScale, redScale);
359            this->greenNode_->setScale(greenScale, greenScale, greenScale);
360        }
361
362        if (this->timeToReload_ > 0)
363            this->timeToReload_ -= dt;
364        else
365            this->timeToReload_ = 0;
366
367        if (this->bLMousePressed_ && this->timeToReload_ <= 0)
368        {
369
370            Projectile *p;
371            if (this->isExactlyA(Class(SpaceShip)))
372                p = new RotatingProjectile(this);
373            else
374                p = new Projectile(this);
375            p->setColour(this->getProjectileColour());
376            p->create();
377            if(p->classID==0)
378              COUT(3) << "generated projectile with classid 0" <<  std::endl; // TODO: remove this output
379
380            p->setBacksync(true);
381            this->timeToReload_ = this->reloadTime_;
382        }
383
384
385        // #####################################
386        // ############# STEERING ##############
387        // #####################################
388
389        if (this->velocity_.x > this->maxSpeed_)
390            this->velocity_.x = this->maxSpeed_;
391        if (this->velocity_.x < -this->maxSideAndBackSpeed_)
392            this->velocity_.x = -this->maxSideAndBackSpeed_;
393        if (this->velocity_.y > this->maxSideAndBackSpeed_)
394            this->velocity_.y = this->maxSideAndBackSpeed_;
395        if (this->velocity_.y < -this->maxSideAndBackSpeed_)
396            this->velocity_.y = -this->maxSideAndBackSpeed_;
397        if (this->rotationRate_ > this->maxRotationRadian_)
398            this->rotationRate_ = this->maxRotationRadian_;
399        if (this->rotationRate_ < -this->maxRotationRadian_)
400            this->rotationRate_ = -this->maxRotationRadian_;
401
402        if (this->acceleration_.x == 0)
403        {
404            if (this->velocity_.x > 0)
405            {
406                this->velocity_.x -= (this->translationDamping_ * dt);
407                if (this->velocity_.x < 0)
408                    this->velocity_.x = 0;
409            }
410            else if (this->velocity_.x < 0)
411            {
412                this->velocity_.x += (this->translationDamping_ * dt);
413                if (this->velocity_.x > 0)
414                    this->velocity_.x = 0;
415            }
416        }
417
418        if (this->acceleration_.y == 0)
419        {
420            if (this->velocity_.y > 0)
421            {
422                this->velocity_.y -= (this->translationDamping_ * dt);
423                if (this->velocity_.y < 0)
424                    this->velocity_.y = 0;
425            }
426            else if (this->velocity_.y < 0)
427            {
428                this->velocity_.y += (this->translationDamping_ * dt);
429                if (this->velocity_.y > 0)
430                    this->velocity_.y = 0;
431            }
432        }
433
434        if (this->momentum_ == this->zeroRadian_)
435        {
436            if (this->rotationRate_ > this->zeroRadian_)
437            {
438                this->rotationRate_ -= (this->rotationDampingRadian_ * dt);
439                if (this->rotationRate_ < this->zeroRadian_)
440                    this->rotationRate_ = 0;
441            }
442            else if (this->rotationRate_ < this->zeroRadian_)
443            {
444                this->rotationRate_ += (this->rotationDampingRadian_ * dt);
445                if (this->rotationRate_ > this->zeroRadian_)
446                    this->rotationRate_ = 0;
447            }
448        }
449
450
451        WorldEntity::tick(dt);
452
453        this->roll(this->mouseXRotation_ * dt);
454        if (this->bInvertYAxis_)
455            this->yaw(Radian(-this->mouseYRotation_ * dt));
456        else
457            this->yaw(Radian(this->mouseYRotation_ * dt));
458
459        if (this->acceleration_.x > 0)
460            this->tt_->setRate(emitterRate_);
461        else
462            this->tt_->setRate(0);
463
464        if( myShip_ )
465        {
466          COUT(4) << "steering our ship: " << objectID << std::endl;
467          this->acceleration_.x = 0;
468          this->acceleration_.y = 0;
469          this->momentum_ = 0;
470          this->mouseXRotation_ = Radian(0);
471          this->mouseYRotation_ = Radian(0);
472          this->bLMousePressed_ = false;
473        }/*else
474          COUT(4) << "not steering ship: " << objectID << " our ship: " << network::Client::getSingleton()->getShipID() << std::endl;*/
475    }
476
477    void SpaceShip::movePitch(float val)
478    {   getLocalShip()->setMovePitch(val);   }
479    void SpaceShip::moveYaw(float val)
480    {   getLocalShip()->setMoveYaw(val);   }
481    void SpaceShip::moveRoll(float val)
482    {   getLocalShip()->setMoveRoll(val);   }
483    void SpaceShip::moveLongitudinal(float val)
484    {   getLocalShip()->setMoveLongitudinal(val);   }
485    void SpaceShip::moveLateral(float val)
486    {   getLocalShip()->setMoveLateral(val);   }
487    void SpaceShip::fire()
488    {   getLocalShip()->doFire();   }
489
490    void SpaceShip::setMovePitch(float val)
491    {
492        val = -val * val * sgn(val) * this->rotationAcceleration_;
493        if (val > this->maxRotation_)
494            val = this->maxRotation_;
495        if (val < -this->maxRotation_)
496            val = -this->maxRotation_;
497        this->mouseYRotation_ = Radian(val);
498    }
499
500    void SpaceShip::setMoveYaw(float val)
501    {
502        val = -val * val * sgn(val) * this->rotationAcceleration_;
503        if (val > this->maxRotation_)
504            val = this->maxRotation_;
505        if (val < -this->maxRotation_)
506            val = -this->maxRotation_;
507        this->mouseXRotation_ = Radian(val);
508    }
509
510    void SpaceShip::setMoveRoll(float val)
511    {
512        this->momentum_ = Radian(-this->rotationAccelerationRadian_ * val);
513        //COUT(3) << "rotating val: " << val << " acceleration: " << this->rotationAccelerationRadian_.valueDegrees() << std::endl;
514    }
515
516    void SpaceShip::setMoveLongitudinal(float val)
517    {
518        this->acceleration_.x = this->translationAcceleration_ * val;
519    }
520
521    void SpaceShip::setMoveLateral(float val)
522    {
523        this->acceleration_.y = -this->translationAcceleration_ * val;
524    }
525
526    void SpaceShip::doFire()
527    {
528        this->bLMousePressed_ = true;
529    }
530}
Note: See TracBrowser for help on using the repository browser.