Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/playability/src/world_entities/space_ships/space_ship.cc @ 10152

Last change on this file since 10152 was 10152, checked in by nicolasc, 17 years ago

finished animation on heavy blaster, started light blaster
code needs some cleanup

File size: 31.5 KB
RevLine 
[6868]1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11### File Specific:
12   main-programmer: Benjamin Knecht
13   co-programmer: Silvan Nellen
14
15*/
16
17#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
18
19#include "executor/executor.h"
20#include "space_ship.h"
21
[7193]22#include "util/loading/resource_manager.h"
[6868]23
24#include "weapons/test_gun.h"
[9970]25#include "weapons/light_blaster.h"
26#include "weapons/medium_blaster.h"
27#include "weapons/heavy_blaster.h"
[10023]28#include "weapons/swarm_launcher.h"
[9970]29#include "weapons/boomerang_gun.h"
[6868]30#include "weapons/turret.h"
31#include "weapons/cannon.h"
32
[10120]33#include "elements/glgui_energywidgetvertical.h"
34
[9869]35#include "particles/dot_emitter.h"
[10073]36#include "particles/emitter_node.h"
[9869]37#include "particles/sprite_particles.h"
[10081]38#include "effects/trail.h"
[6868]39
[7193]40#include "util/loading/factory.h"
[6868]41#include "key_mapper.h"
42
43#include "network_game_manager.h"
[8708]44#include "shared_network_data.h"
[6868]45
46#include "power_ups/weapon_power_up.h"
47#include "power_ups/param_power_up.h"
48
49#include "graphics_engine.h"
50
51#include "plane.h"
52
53#include "state.h"
54#include "player.h"
55
[10113]56
[7193]57#include "util/loading/load_param.h"
[10020]58#include "time.h"
[6868]59
[10096]60#include "track/track.h"
[7056]61
[10096]62
[6868]63// #include "lib/gui/gl_gui/glgui_bar.h"
64// #include "lib/gui/gl_gui/glgui_pushbutton.h"
65
66
[9869]67#include "class_id_DEPRECATED.h"
68ObjectListDefinitionID(SpaceShip, CL_SPACE_SHIP);
69CREATE_FACTORY(SpaceShip);
[9406]70
[9061]71#include "script_class.h"
[9869]72CREATE_SCRIPTABLE_CLASS(SpaceShip,
73                        addMethod("hasPlayer", Executor0ret<Playable, lua_State*,bool>(&Playable::hasPlayer))
74                        ->addMethod("fire", Executor1<Playable, lua_State*, bool>(&Playable::fire))
75                        ->addMethod("loadModel", Executor2<WorldEntity, lua_State*,const std::string& ,float>(&WorldEntity::loadModel2))
76                        ->addMethod("setName", Executor1<BaseObject, lua_State*,const std::string&>(&BaseObject::setName))
77                        ->addMethod("hide", Executor0<WorldEntity, lua_State*>(&WorldEntity::hide))
78                        ->addMethod("unhide", Executor0<WorldEntity, lua_State*>(&WorldEntity::unhide))
79                        //Coordinates
80                        ->addMethod("setAbsCoor", Executor3<PNode, lua_State*,float,float,float>(&PNode::setAbsCoor))
81                        ->addMethod("getAbsCoorX", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorX))
82                        ->addMethod("getAbsCoorY", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorY))
83                        ->addMethod("getAbsCoorZ", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorZ))
[10017]84                        //->addMethod("setCameraSpeed", Executor1<SpaceShip, lua_State*, float>(&SpaceShip::setCameraSpeed))
[9061]85                       );
[6868]86
87/**
88 *  destructs the spaceship, deletes alocated memory
89 */
90SpaceShip::~SpaceShip ()
91{
[6986]92  this->setPlayer(NULL);
[6868]93}
94
95/**
96 * loads a Spaceships information from a specified file.
97 * @param fileName the name of the File to load the spaceship from (absolute path)
98 */
[7221]99SpaceShip::SpaceShip(const std::string& fileName)
[10019]100    : secWeaponMan(this) //,
101    //supportedPlaymodes(Playable::Vertical) ,
102    //playmode(Playable::Vertical)
[6868]103{
104  this->init();
105  TiXmlDocument doc(fileName);
106
107  if(!doc.LoadFile())
108  {
[7221]109    PRINTF(2)("Loading file %s failed for spaceship.\n", fileName.c_str());
[6868]110    return;
111  }
112
113  this->loadParams(doc.RootElement());
114}
115
116/**
117 *  creates a new Spaceship from Xml Data
118 * @param root the xml element containing spaceship data
119
120   @todo add more parameters to load
121*/
122SpaceShip::SpaceShip(const TiXmlElement* root)
[10019]123    : secWeaponMan(this) //,
124    //supportedPlaymodes(Playable::Vertical) ,
125    //playmode(Playable::Vertical)
[6868]126{
127  this->init();
[10081]128  //this->setParentMode(PNODE_REPARENT_DELETE_CHILDREN);
[6868]129  if (root != NULL)
130    this->loadParams(root);
131
132}
133
134
135/**
136 * initializes a Spaceship
137 */
138void SpaceShip::init()
139{
[9998]140
[10022]141  srand(time(0));   //initialize Random Nomber Generator
142
[9869]143  //  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
144  this->registerObject(this, SpaceShip::_objectList);
[6868]145  PRINTF(4)("SPACESHIP INIT\n");
[10121]146  this->weaponMan.setParentEntity( this);
[6868]147  //weapons:
[10098]148 
[9996]149  Weapon* wpRight1 = new LightBlaster ();
[10073]150  wpRight1->setName( "LightBlaster");
[10117]151  //wpRight1->setParent( this);
[9996]152  Weapon* wpLeft1 = new LightBlaster ();
[10073]153  wpLeft1->setName( "LightBlaster");
[10117]154  //wpLeft1->setParent( this);
[6868]155
[9996]156  Weapon* wpRight2 = new MediumBlaster ();
[10073]157  wpRight2->setName( "MediumBlaster");
[10117]158  //wpRight2->setParent( this);
[9996]159  Weapon* wpLeft2 = new MediumBlaster ();
[10073]160  wpLeft2->setName( "MediumBlaster");
[10117]161  //wpLeft2->setParent( this);
[10098]162 
[10152]163  Weapon* wpRight3 = new HeavyBlaster (1);
[10073]164  wpRight3->setName( "HeavyBlaster");
[10117]165  //wpRight3->setParent( this);
[10152]166  Weapon* wpLeft3 = new HeavyBlaster (0);
[10073]167  wpLeft3->setName( "HeavyBlaster");
[10117]168  //wpLeft3->setParent( this);
[9996]169
[10023]170  Weapon* cannon = new SwarmLauncher();
[10073]171  cannon->setName( "SwarmLauncher");
[10117]172  //cannon->setParent( this);
[6868]173
[9961]174
[10098]175  this->weaponMan.addWeapon( wpLeft1, 0, 0);
176  this->weaponMan.addWeapon( wpRight1, 0, 1);
[9998]177
[10121]178  this->weaponMan.addWeapon( wpLeft2, 1, 2);
179  this->weaponMan.addWeapon( wpRight2, 1, 3);
[9961]180
[10121]181  this->weaponMan.addWeapon( wpLeft3, 2, 4);
182  this->weaponMan.addWeapon( wpRight3, 2, 5);
[10113]183
[10152]184  this->weaponMan.addWeapon( wpLeft1, 3, 0);
185  this->weaponMan.addWeapon( wpRight1, 3, 1);
186
187  this->weaponMan.addWeapon( wpLeft2, 3, 2);
188  this->weaponMan.addWeapon( wpRight2, 3, 3);
189
190  this->weaponMan.addWeapon( wpLeft3, 3, 4);
191  this->weaponMan.addWeapon( wpRight3, 3, 5);
192
[10121]193  this->secWeaponMan.addWeapon( cannon, 0, 0);
[9998]194
[10113]195 
[10152]196  this->weaponMan.changeWeaponConfig(3);
[10113]197  this->secWeaponMan.changeWeaponConfig(0);
198
199  curWeaponPrimary    = 1;
[9970]200  curWeaponSecondary  = 0;
[9965]201
202  Playable::weaponConfigChanged();
203
[9970]204  reactorOutput     = 10;
[9965]205
[9970]206  weaponEnergyRegen = 10;       // 10 einheiten pro Sekunde
207  engineSpeedBase   = 5;
208  shieldRegen       = 2;
209
210  shieldEnergyShare = 0.3;
211  weaponEnergyShare = 0.3;
212  engineEnergyShare = 0.4;
213
214  shieldCur         = 20;
215  shieldMax         = 100;
[10020]216  shieldTH          = .2* shieldMax;   // shield power must be 20% before shield kicks in again
[9970]217
[10119]218  this->setHealth( 20);
219  this->setHealthMax( 100);
220
[10024]221  electronicCur = 50;
[10022]222  electronicMax = 50;
[10020]223  electronicRegen   = 3;
224  electronicTH      = .7 * electronicMax; // 30% of eDamage can be handled by the ship
225
[6868]226
[9970]227  this->loadModel("models/ships/mantawing.obj");
[10017]228  //this->setVisibiliy(false);
[6868]229
[10017]230  bForward = bBackward = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = bFire = bSecFire = false;
231 
[6868]232
[9970]233  this->setHealthMax(shieldMax);
234  this->setHealth(shieldCur);
[6868]235
[10017]236  this->travelNode = new PNode();
237
238  // camera - issue
239  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
240  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
241
[10120]242  // widget handling
[10139]243  /*
[10120]244  this->electronicWidget = new OrxGui::GLGuiEnergyWidgetVertical();
245  this->electronicWidget->setDisplayedName(std::string(this->getClassName()) + " Electronics:");
246  this->electronicWidget->setSize2D(30,400);
247  this->electronicWidget->setAbsCoor2D(150,200);
248  this->electronicWidget->shiftDir2D(270);
249  this->updateElectronicWidget();
250  this->shieldWidget = new OrxGui::GLGuiEnergyWidgetVertical();
251  this->shieldWidget->setDisplayedName(std::string(this->getClassName()) + " Shield:");
252  this->shieldWidget->setSize2D(30,400);
253  this->shieldWidget->setAbsCoor2D(200,200);
254  this->shieldWidget->shiftDir2D(270);
255  this->updateShieldWidget();
256  if (this->hasPlayer())
257  {
258    State::getPlayer()->hud().setShiledWidget(this->shieldWidget);
259    State::getPlayer()->hud().setEnergyWidget(this->electronicWidget);
260  }
[10139]261  */
262  this->electronicWidget = NULL;
263  this->shieldWidget = NULL;
[6868]264
265  //add events to the eventlist
[6997]266  registerEvent(KeyMapper::PEV_FORWARD);
267  registerEvent(KeyMapper::PEV_BACKWARD);
[6868]268  registerEvent(KeyMapper::PEV_LEFT);
269  registerEvent(KeyMapper::PEV_RIGHT);
270  //registerEvent(SDLK_q);
271  //registerEvent(SDLK_e);
272  registerEvent(KeyMapper::PEV_FIRE1);
[9958]273  registerEvent(KeyMapper::PEV_FIRE2);                  // Added for secondary weapon support
[6868]274  registerEvent(KeyMapper::PEV_NEXT_WEAPON);
275  registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON);
276  //registerEvent(SDLK_PAGEUP);
277  //registerEvent(SDLK_PAGEDOWN);
278  registerEvent(EV_MOUSE_MOTION);
279
[10073]280  this->weaponMan.setParentEntity( this);
281  this->secWeaponMan.setParentEntity( this);
282
[9965]283  this->weaponMan.setSlotCount(6);
[6868]284
[10152]285  this->weaponMan.setSlotPosition(0, Vector(0.0, 0, -3.0));
[9965]286  this->weaponMan.setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
[6868]287
[10152]288  this->weaponMan.setSlotPosition(1, Vector(0.0, 0, 3.0));
[9965]289  this->weaponMan.setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
[6868]290
[10064]291  this->weaponMan.setSlotPosition(2, Vector(-1.5, 0, -.5));
[9965]292  this->weaponMan.setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0)));
[6868]293
[10064]294  this->weaponMan.setSlotPosition(3, Vector(-1.5, 0, .5));
[9965]295  this->weaponMan.setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0)));
[6868]296
[10133]297  this->weaponMan.setSlotPosition(4, Vector(1.5, 0, .5));
[9965]298  this->weaponMan.setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0)));
[6868]299
[10133]300  this->weaponMan.setSlotPosition(5, Vector(1.5, 0, -.5));
[9965]301  this->weaponMan.setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0)));
[9961]302
303  this->secWeaponMan.setSlotCount(6);
304
[10073]305  this->secWeaponMan.setSlotPosition(0, Vector(1.5, 0, 0));
[9961]306  this->secWeaponMan.setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
307
[10073]308  this->secWeaponMan.setSlotPosition(1, Vector(2.6, 0, 3.0));
[9961]309  this->secWeaponMan.setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
310
[10073]311  this->secWeaponMan.setSlotPosition(2, Vector(1.5, 0, -.5));
[9961]312  this->secWeaponMan.setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0)));
313
[10073]314  this->secWeaponMan.setSlotPosition(3, Vector(1.5, 0, .5));
[9961]315  this->secWeaponMan.setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0)));
316
[10073]317  this->secWeaponMan.setSlotPosition(4, Vector(1.5, 0, .5));
[9961]318  this->secWeaponMan.setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0)));
319
[10073]320  this->secWeaponMan.setSlotPosition(5, Vector(1.5, 0, -.5));
[9961]321  this->secWeaponMan.setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0)));
[9965]322
[6868]323
[9965]324  this->weaponMan.getFixedTarget()->setParent(this);
325  this->weaponMan.getFixedTarget()->setRelCoor(100000,0,0);
[10004]326
[9998]327 
[9961]328  this->secWeaponMan.getFixedTarget()->setParent(this);
329  this->secWeaponMan.getFixedTarget()->setRelCoor(100000,0,0);
[10004]330  this->secWeaponMan.setRotationSpeed(0);
[6868]331
[9965]332  dynamic_cast<Element2D*>(this->weaponMan.getFixedTarget())->setVisibility( false);
[9961]333
[6868]334
[10017]335  registerVar( new SynchronizeableBool( &bForward, &bForward, "bForward", PERMISSION_OWNER ) );
336  registerVar( new SynchronizeableBool( &bBackward, &bBackward, "bBackward", PERMISSION_OWNER ) );
337  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
338  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
339  registerVar( new SynchronizeableFloat( &cameraLook, &cameraLook, "cameraLook", PERMISSION_OWNER ) );
340  registerVar( new SynchronizeableFloat( &rotation, &rotation, "rotation", PERMISSION_OWNER ) );
[10023]341  registerVar( new SynchronizeableBool( &bFire, &bFire, "bSecFire", PERMISSION_OWNER));
[10017]342  registerVar( new SynchronizeableVector( &velocity, &velocity, "velocity", PERMISSION_MASTER_SERVER ) );
343
344  //this->airFriction = 0.5f;
[10019]345  this->travelDistancePlus = Vector2D(38.0, 43.0);
346  this->travelDistanceMinus = Vector2D(-38.0, -43.0);
[10017]347  this->cameraSpeed = 40;
[10019]348  this->cameraLook = 0.0f;
349  //this->airFriction = 0.0f;
[10017]350
[10020]351  srand(time(0));  //initaialize RNG
352
[10017]353  this->travelNode->debugDraw();
[10032]354
355  this->setSupportedPlaymodes(Playable::Horizontal | Playable::Vertical);
[10081]356
357 
[10132]358  this->trail = new Trail( 30, 100, .2, this);
[10095]359  //this->trail->setParent( this);
[10081]360  this->trail->setTexture( "maps/engine.png");
361
[10132]362  this->trailL = new Trail( 30, 100, .2, this);
[10095]363  //this->trailL->setParent( this);
[10081]364  this->trailL->setTexture( "maps/engine.png");
365
[10132]366  this->trailR = new Trail( 30, 100, .2, this);
[10095]367  //this->trailR->setParent( this);
[10081]368  this->trailR->setTexture( "maps/engine.png");
[10098]369
[10113]370
[10098]371  this->toList(OM_GROUP_00);
[6868]372}
373
374
375/**
376 * loads the Settings of a SpaceShip from an XML-element.
377 * @param root the XML-element to load the Spaceship's properties from
378 */
379void SpaceShip::loadParams(const TiXmlElement* root)
380{
381  Playable::loadParams(root);
[10032]382
383  LoadParam(root, "playmode", this, SpaceShip, setPlaymodeXML);
[6868]384}
385
[10032]386
[10017]387void SpaceShip::setPlayDirection(const Quaternion& rot, float speed)
[7056]388{
[10032]389  //this->direction = Quaternion (rot.getHeading(), Vector(0,1,0));
[7056]390}
[6868]391
[7085]392void SpaceShip::reset()
393{
[10017]394  bForward = bBackward = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = bFire = bSecFire = false;
[7056]395
[10017]396  //xMouse = yMouse = 0;
[7085]397
398  this->setHealth(80);
399  this->velocity = Vector(0.0, 0.0, 0.0);
400}
401
402
[6868]403void SpaceShip::enter()
404{
[10004]405  this->secWeaponMan.showCrosshair();
[10095]406  this->toList( OM_GROUP_01 );
[10139]407  dynamic_cast <OrxGui::GLGuiEnergyWidgetVertical*> (State::getPlayer()->hud().getArmorWidget())->setDisplayedName("Armor");
[10004]408  //dynamic_cast<Element2D*>(this->secWeaponMan.getFixedTarget())->setVisibility( true);
[10019]409  //this->attachCamera();
[10032]410 // this->setPlaymode(Playable::Horizontal);
[6868]411}
412
413void SpaceShip::leave()
414{
[10004]415  this->secWeaponMan.hideCrosshair();
[10095]416  this->toList( OM_GROUP_00);
[10004]417  //dynamic_cast<Element2D*>(this->secWeaponMan.getFixedTarget())->setVisibility( false);
[10019]418  //this->detachCamera();
[6868]419}
420
421
422/**
423 *  effect that occurs after the SpaceShip is spawned
424*/
425void SpaceShip::postSpawn ()
426{
427  //setCollision(new CollisionCluster(1.0, Vector(0,0,0)));
428}
429
430/**
431 *  the action occuring if the spaceship left the game
432*/
433void SpaceShip::leftWorld ()
[10073]434{
435
[10064]436}
[6868]437
438WorldEntity* ref = NULL;
439/**
440 *  this function is called, when two entities collide
441 * @param entity: the world entity with whom it collides
442 *
443 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
444 */
445void SpaceShip::collidesWith(WorldEntity* entity, const Vector& location)
446{
447}
448
449/**
450 *  draws the spaceship after transforming it.
451*/
452void SpaceShip::draw () const
453{
454  WorldEntity::draw();
455
[10081]456  glMatrixMode(GL_MODELVIEW);
457  glPushMatrix();
458
459  float matrix[4][4];
460  glTranslatef (this->getAbsCoor ().x-1, this->getAbsCoor ().y-.2, this->getAbsCoor ().z);
461  this->getAbsDir().matrix (matrix);
462  glMultMatrixf((float*)matrix);
463  //glScalef(2.0, 2.0, 2.0);  // no double rescale
464 
465  this->trail->draw();
466 
467  glTranslatef(0,0,-.5);
468  this->trailL->draw();
469
470  glTranslatef(0,0,1);
471  this->trailR->draw();
472  glPopMatrix();
[6868]473  //this->debug(0);
474}
475
476/**
477 *  the function called for each passing timeSnap
478 * @param time The timespan passed since last update
479*/
480void SpaceShip::tick (float time)
481{
[9961]482  // Playable::tick(time);$
[6868]483
[9961]484  // Own Tick Setup, as a different fire routine is used on the weapon manager
[9965]485  this->weaponMan.tick(time);
[9961]486  this->secWeaponMan.tick(time);
487
[10020]488  if( this->systemFailure() )
489    bFire = bSecFire = false;
490
[10037]491  // fire reqeust/release for primary weapons
[9965]492  if( this->bFire)
493    this->weaponMan.fire();
[10036]494  else
495    this->weaponMan.releaseFire();
496
[10037]497  // fire reqeust/release for secondary weapons
[9961]498  if( this->bSecFire)
499    this->secWeaponMan.fire();
[10036]500  else
501    this->secWeaponMan.releaseFire();
[10096]502   
503  // Tracktick
504  if(this->entityTrack)
505    this->entityTrack->tick(time);
[9961]506
[9970]507
508  // Shield Regeneration and other regular calculations on the ship
509  this->regen(time);
510
511  // Weapon Regeneration and other regular calculations on the ship
[9965]512  this->weaponRegen(time);
513
[9970]514  // current engine speed output
515  this->engineSpeedCur = this->engineSpeedBase + this->reactorOutput * this->engineEnergyShare;
516
[10043]517  // calculation of maxSpeed and acceleration:
518  this->travelSpeed = this->engineSpeedCur * 5;
519  this->acceleration = this->travelSpeed * 2;
[9970]520
[10017]521  this->movement(time);
522
523   // TRYING TO FIX PNode.
524  this->cameraNode.setAbsCoorSoft(this->getAbsCoor() + Vector(0.0f, 5.0f, 0.0f), 30.0f);
525  this->cameraNode.setRelDirSoft(this->getAbsDir(), 30.0f);
526
[10095]527 
528  this->velocity  = (this->getAbsCoor() - this->oldPos) / time;
529  this->oldPos    = this->getAbsCoor();
530
[10081]531  this->trail->tick(time);
532  this->trailL->tick(time);
533  this->trailR->tick(time);
[10095]534
[10113]535  this->weaponMan.setParentEntity( this);
536  this->secWeaponMan.setParentEntity( this);
537
[6868]538  //orient the spaceship in direction of the mouse
[10017]539  /*
[9869]540  rotQuat = Quaternion::quatSlerp( this->getAbsDir(), mouseDir, 0.5);//fabsf(time)*shipInertia);
541  if (this->getAbsDir().distance(rotQuat) > 0.00000000000001)
[6868]542    this->setAbsDir( rotQuat);
[9869]543  //this->setAbsDirSoft(mouseDir,5);
[10017]544  */
[6868]545
546  // this is the air friction (necessary for a smooth control)
[10017]547  /*
[6868]548  if(travelSpeed >= 120) velocity -= velocity.getNormalized()*travelSpeed*travelSpeed*0.0001;
549  else if (travelSpeed <= 80) velocity -= velocity.getNormalized()*travelSpeed*0.001;
[10017]550  */
[6868]551
552  //other physics (gravity)
553  //if(travelSpeed < 120)
554  //move += Vector(0,-1,0)*60*time + Vector(0,1,0)*travelSpeed/2*time;
555
556  //hoover effect
557  //cycle += time;
558  //this->shiftCoor(Vector(0,1,0)*cos(this->cycle*2.0)*0.02);
559
560  //readjust
561  //if (this->getAbsDirZ().y > 0.1) this->shiftDir(Quaternion(time*0.3, Vector(1,0,0)));
562  //else if (this->getAbsDirZ().y < -0.1) this->shiftDir(Quaternion(-time*0.3, Vector(1,0,0)));
563
564  //SDL_WarpMouse(GraphicsEngine::getInstance()->getResolutionX()/2, GraphicsEngine::getInstance()->getResolutionY()/2);
565
[10017]566  /*
[6868]567  this->shiftCoor(move);
[10017]568  */
[6868]569
[9869]570  //   PRINTF(0)("id of %s is: %i\n", this->getName(), this->getOMListNumber());
[6868]571
572}
573
574/**
575 * @todo switch statement ??
576 */
577void SpaceShip::process(const Event &event)
578{
[9961]579  //Playable::process(event);
[10113]580 
[6868]581  if( event.type == KeyMapper::PEV_LEFT)
[10017]582    this->bLeft = event.bPressed;
[6868]583  else if( event.type == KeyMapper::PEV_RIGHT)
[10017]584    this->bRight = event.bPressed;
[6997]585  else if( event.type == KeyMapper::PEV_FORWARD)
[10017]586    this->bForward = event.bPressed; //this->shiftCoor(0,.1,0);
[6997]587  else if( event.type == KeyMapper::PEV_BACKWARD)
[10017]588    this->bBackward = event.bPressed; //this->shiftCoor(0,-.1,0);
[9961]589  else if( event.type == KeyMapper::PEV_FIRE2)
590    this->bSecFire = event.bPressed;
[9958]591  else if( event.type == KeyMapper::PEV_FIRE1)
[9965]592    this->bFire = event.bPressed;
[10113]593  else if( event.type == KeyMapper::PEV_NEXT_WEAPON && event.bPressed)
594  {
595    this->nextWeaponConfig();
596  }
597  else if ( event.type == KeyMapper::PEV_PREVIOUS_WEAPON && event.bPressed)
598    this->previousWeaponConfig();
[10017]599
600
601  /*
[6868]602  else if( event.type == EV_MOUSE_MOTION)
603  {
[9961]604
[6868]605    this->xMouse += event.xRel;
606    this->yMouse += event.yRel;
607  }
[10017]608  */
[6868]609}
610
[9235]611void SpaceShip::destroy( WorldEntity* killer )
[9008]612{
[10107]613  PRINTF(5)("spaceship destroy\n");
[10095]614 
[10073]615  EmitterNode* node  = NULL;
616  DotEmitter* emitter = NULL;
617  SpriteParticles*  explosionParticles  = NULL;
[10064]618
[10107]619  explosionParticles = new SpriteParticles(200);
620  explosionParticles->setName("SpaceShipExplosionParticles");
621  explosionParticles->setLifeSpan(.2, .3);
[10073]622  explosionParticles->setRadius(0.0, 10.0);
623  explosionParticles->setRadius(.5, 6.0);
624  explosionParticles->setRadius(1.0, 3.0);
[10098]625  explosionParticles->setColor(0.0, 1,1,1,.9);
626  explosionParticles->setColor(0.1,  1,1,0,.9);
627  explosionParticles->setColor(0.5, .8,.4,0,.5);
[10107]628  explosionParticles->setColor(1.0, .2,.2,.2,.5);
[10064]629
[10073]630 
[10107]631  emitter = new DotEmitter( 2000, 70, 360);
632  //emitter->setSpread( 0, M_2_PI);
633  emitter->setEmissionRate( 200.0);
[10098]634  //emitter->setEmissionVelocity( 200.0);
[10107]635  //emitter->setSystem( explosionParticles);
636  //emitter->setAbsCoor( this->getAbsCoor());
[10064]637
[10107]638  node  = new EmitterNode( .1f);
[10073]639  node->setupParticle( emitter, explosionParticles);
[10107]640  node->setAbsDir( this->getAbsDir());
641  node->setVelocity( this->getVelocity() * .9f);
[10073]642  node->setAbsCoor( this->getAbsCoor());
[10107]643  if( !node->start())
644    PRINTF(0)("Explosion node not correctly started!");
645
[10095]646/*
[10081]647  PNode* node          = new PNode();
648  node->setAbsCoor(this->getAbsCoor());
649  Explosion* explosion = new Explosion();
650  explosion->explode( node, Vector(5,5,5));
[10095]651*/
[10073]652
[10107]653  if( this->hasPlayer())
654  {
655        this->setAbsCoor(Vector(-10000,10000,10000));
656        this->hide();
657  }
658  else
659  {
[10113]660    this->setAbsCoor( this->getAbsCoor() + Vector(100,0,0) + Vector(1,0,0) * VECTOR_RAND(150).dot(Vector(1,0,0)));
[10107]661  }
662
[9008]663}
[6868]664
[9008]665void SpaceShip::respawn( )
666{
[10107]667  this->unhide();
[10081]668  /*for(ObjectList<PNode>::const_iterator it = this->getNodesChildren().begin(); it != this->getNodesChildren().end(); it++)
669  {
670    if( dynamic_cast<WorldEntity*>(*it) != NULL)
671      dynamic_cast<WorldEntity*>(*it)->toList( OM_GROUP_00);
672  }*/
[10098]673  /*
[10095]674  if( this->hasPlayer())
675  {
[10081]676    this->toList( OM_GROUP_01);
[10095]677    for(ObjectList<PNode>::const_iterator it = this->getNodesChildren().begin(); it != this->getNodesChildren().end(); it++)
678        {
679          if( likely( dynamic_cast<Weapon*>(*it) != NULL))
680                dynamic_cast<WorldEntity*>(*it)->toList( OM_GROUP_00_PROJ);
681        }
682  }
[10081]683  else
[10095]684  {
685    this->toList( OM_GROUP_00);
686    for(ObjectList<PNode>::const_iterator it = this->getNodesChildren().begin(); it != this->getNodesChildren().end(); it++)
687        {
688          if( likely( dynamic_cast<Weapon*>(*it) != NULL))
689                dynamic_cast<WorldEntity*>(*it)->toList( OM_GROUP_01_PROJ);
690        }
[10098]691  }*/
[10081]692
[9008]693}
[6868]694
695
[9957]696void SpaceShip::damage(float pDamage, float eDamage){
[10117]697  PRINTF(5)("ship hit for (%f,%f) \n",pDamage,eDamage);
[10081]698
[10064]699  if( this->shieldActive) {
[9950]700    if( this->shieldCur > pDamage) {
701      this->shieldCur = this->shieldCur - pDamage;
702    }
703    else { // shield <= pDamage
[9987]704      this->shieldCur -=pDamage;
705      this->shieldActive = false; //shield collapses
[10081]706      pDamage += this->shieldCur;
[9950]707      if( !this->shieldActive) {
[9957]708        this->armorCur -= pDamage / 2; // remaining damages hits armor at half rate
[9953]709        this->electronicCur -= eDamage;
[9950]710      }
711    }
712  }
713  else {
714    this->armorCur = this->armorCur - pDamage;
715    this->electronicCur = this->electronicCur - eDamage;
716  }
717  if( this->armorCur <= 0) { /* FIXME implement shipcrash*/ }
[10064]718    this->destroy(this);
[10119]719
[10120]720  updateElectronicWidget();
721  updateShieldWidget();
722
[10119]723  this->setHealth( this->armorCur);
[9950]724}
725
[9987]726
[9957]727void SpaceShip::regen(float time){
728  float tmp;
[9963]729  if (this->armorCur != this->armorMax || this->armorRegen != 0){
730    tmp = this->armorCur + this->armorRegen * time;
731    if ( tmp > electronicMax)
732      this->armorCur = this->armorMax;
733    else
734      this->armorCur = tmp;
735  }
736  if (this->shieldCur != this->shieldMax || this->shieldRegen != 0){
[9970]737    tmp =  this->shieldCur + (this->shieldRegen + this->reactorOutput * this->shieldEnergyShare) * time;
[9957]738    if( tmp > shieldMax)
[9953]739      this->shieldCur = this->shieldMax;
740    else
[9957]741      this->shieldCur = tmp;
742    this->shieldActive = ( this->shieldActive || this->shieldCur > shieldTH);
[10120]743
744    updateShieldWidget();
[9953]745  }
[9970]746
747  this->setHealth( this->shieldCur);      // FIXME currently just to test share system
748
[9963]749  if (this->electronicCur != this->electronicMax || this->electronicRegen != 0){
[9957]750    tmp = this->electronicCur + this->electronicRegen * time;
751    if ( tmp > electronicMax)
[9953]752      this->electronicCur = this->electronicMax;
753    else
[9957]754      this->electronicCur = tmp;
[10120]755
756    updateElectronicWidget();
[9953]757  }
[10120]758
[9950]759}
[9965]760
[9987]761
[9965]762/**
763 * Weapon regeneration
764 * does not use any reactor capacity, as it wouldn't work in a consistent way.
765 */
766void SpaceShip::weaponRegen(float time)
767{
768  float energy  = ( this->reactorOutput * this->weaponEnergyShare + this->weaponEnergyRegen) * time;
769  Weapon* weapon;
[9987]770  for( unsigned int i=0; i < this->weaponMan.getSlotCount(); i++)
[9965]771  {
772    weapon = this->weaponMan.getWeapon(i);
773    if( weapon != NULL && weapon->isActive())
774    {
775      weapon->increaseEnergy( energy);
776    }
777
778  }
779  // weaponMan.increaseAmmunition( weapon, energy);
780}
[9975]781
[9987]782
[9975]783void SpaceShip::enterPlaymode(Playable::Playmode playmode)
784{
[10017]785  switch(playmode)
786  {
787    case Playable::Full3D:
788      /*
789      if (State::getCameraNode != NULL)
790      {
791        Vector absCoor = this->getAbsCoor();
792        this->setParent(PNode::getNullParent());
793        this->setAbsCoor(absCoor);
794        State::getCameraNode()->setParentSoft(&this->cameraNode);
795        State::getCameraNode()->setRelCoorSoft(-10, 0,0);
796        State::getCameraTargetNode()->setParentSoft(&this->cameraNode);
797        State::getCameraTargetNode()->setRelCoorSoft(100, 0,0);
798
799      }
800      */
801      //break;
802
[10032]803      break;
804    case Playable::Horizontal:
[10017]805      if (State::getCameraNode != NULL)
806      {
807        this->debugNode(1);
808        this->travelNode->debugNode(1);
809
810        this->travelNode->setAbsCoor(this->getAbsCoor());
811        this->travelNode->updateNode(0.01f);
812
[10098]813        this->setParent(this->travelNode);
[10017]814        this->setRelCoor(0,0,0);
815
[10098]816        State::getCameraNode()->setParentSoft(this->travelNode);
817        //State::getCameraNode()->setParentSoft(this);
[10032]818        State::getCameraNode()->setRelCoorSoft(-0.01, 40, 0);
[10098]819        State::getCameraTargetNode()->setParentSoft(this->travelNode);
820        //State::getCameraTargetNode()->setParentSoft(this);
[10019]821        State::getCameraTargetNode()->setRelCoorSoft(0,0,0);
[10017]822
823        this->debugNode(1);
824        this->travelNode->debugNode(1);
825      }
826      break;
827
828    default:
829      PRINTF(2)("Playmode %s Not Implemented in %s\n", Playable::playmodeToString(this->getPlaymode()).c_str(), this->getClassCName());
830  }
[9975]831}
832
[10017]833/**
834 * @brief calculate the velocity
835 * @param time the timeslice since the last frame
836*/
[9987]837
[9975]838void SpaceShip::movement (float dt)
839{
[10019]840  //by releasing the buttons, the velocity decreases with airCoeff*Acceleration. Should be strong enough so
841  //the ship doesn't slide too much.
842  float airCoeff = 2.5;
843  float pi = 3.14;
[10098]844 
[10017]845
[10032]846  switch(this->getPlaymode())
[10017]847  {
[10032]848    case Playable::Horizontal:
[10017]849    {
[10032]850      // these routines will change the travel movement into zero in a short amout of time, if the player
851      // doesn't press any buttons.
[10098]852      if (this->travelVelocity.x >= 0)
[10017]853      {
[10098]854        if (this->travelVelocity.x > airCoeff*this->acceleration * dt)
855          this->travelVelocity.x -= airCoeff* this->acceleration * dt;
[10032]856        else
[10098]857          this->travelVelocity.x = 0;
[10017]858      }
859      else
860      {
[10098]861        if (this->travelVelocity.x < -airCoeff*this->acceleration * dt)
862          this->travelVelocity.x += airCoeff* this->acceleration * dt;
[10032]863        else
[10098]864          this->travelVelocity.x = 0;
[10017]865      }
[10098]866      if (this->travelVelocity.z >= 0)
[10017]867      {
[10098]868        if (this->travelVelocity.z > airCoeff*this->acceleration * dt)
869          this->travelVelocity.z -= airCoeff* this->acceleration * dt;
[10032]870        else
[10098]871          this->travelVelocity.z = 0;
[10017]872      }
873      else
874      {
[10098]875        if (this->travelVelocity.z < -airCoeff*this->acceleration * dt)
876          this->travelVelocity.z += airCoeff* this->acceleration * dt;
[10032]877        else
[10098]878          this->travelVelocity.z = 0;
[10017]879      }
[10032]880   
881      // this will evite, that the ship moves outside the travelDistance- borders,when the player releases all buttons
882      // and its continuing to slide a bit.
883      Vector oldCoor = this->getRelCoor();
884      if (this->getRelCoor().x > this->travelDistancePlus.x) this->setRelCoor(this->travelDistancePlus.x, oldCoor.y, oldCoor.z);
885      if (this->getRelCoor().x < this->travelDistanceMinus.x) this->setRelCoor(this->travelDistanceMinus.x, oldCoor.y, oldCoor.z);
886      if (this->getRelCoor().z > this->travelDistancePlus.y) this->setRelCoor(oldCoor.x, oldCoor.y, this->travelDistancePlus.y);
887      if (this->getRelCoor().z < this->travelDistanceMinus.y) this->setRelCoor(oldCoor.x, oldCoor.y, this->travelDistanceMinus.y);
888   
889      if( this->systemFailure() )
890        bForward = bBackward = bLeft = bRight = false;
891   
892      if( this->bForward )
[10019]893      {
[10032]894        if(this->getRelCoor().x < this->travelDistancePlus.x)
895        {
[10098]896          if (this->travelVelocity.x < this->travelSpeed)
[10032]897          {
[10098]898            this->travelVelocity.x += (airCoeff + 1.0)*this->acceleration*dt;
[10032]899          }
900          else
901          {
[10098]902            this->travelVelocity.x = this->travelSpeed;
[10032]903          }
904        }
905        else
906        {
[10098]907          this->travelVelocity.x = 0.0f;
[10032]908        }
[10019]909      }
[10032]910   
911      if( this->bBackward )
[10019]912      {
[10032]913        if(this->getRelCoor().x > this->travelDistanceMinus.x)
914        {
[10098]915          if (this->travelVelocity.x > -this->travelSpeed)
[10032]916          {
[10098]917            this->travelVelocity.x -= (airCoeff + 1.0)*this->acceleration*dt;
[10032]918          }
919          else
920          {
[10098]921            this->travelVelocity.x = -this->travelSpeed;
[10032]922          }
923        }
924        else
925        {
[10098]926          this->travelVelocity.x = 0.0f;
[10032]927        }
[10019]928      }
[10032]929   
930      if( this->bLeft)
[10019]931      {
[10032]932        if(this->getRelCoor().z > this->travelDistanceMinus.y)
933        {
[10098]934          if (this->travelVelocity.z > -this->travelSpeed)
[10032]935          {
[10098]936            this->travelVelocity.z -= (airCoeff + 1.0)*this->acceleration*dt;
[10032]937          }
938          else
939          {
[10098]940            this->travelVelocity.z = -this->travelSpeed;
[10032]941          }
942        }
943        else
944        {
[10098]945          this->travelVelocity.z = 0.0f;
[10032]946        }
[10043]947        this->setRelDirSoft(Quaternion(-pi/6, Vector(1,0,0)), 6);
[10019]948      }
[10032]949   
950      if( this->bRight)
[10019]951      {
[10032]952        if(this->getRelCoor().z < this->travelDistancePlus.y)
953        {
[10098]954          if (this->travelVelocity.z < this->travelSpeed)
[10032]955          {
[10098]956            this->travelVelocity.z += (airCoeff + 1.0)*this->acceleration*dt;
[10032]957          }
958          else
959          {
[10098]960            this->travelVelocity.z = this->travelSpeed;
[10032]961          }
962        }
963        else
964        {
[10098]965          this->travelVelocity.z = 0.0f;
[10032]966        }
[10043]967        this->setRelDirSoft(Quaternion(pi/6, Vector(1,0,0)), 6);
[10019]968      }
[10032]969      if (!this->bRight && !this->bLeft)
970      {
[10043]971        this->setRelDirSoft(Quaternion(0, Vector(1,0,0)), 6);
[10032]972      }
973
[10043]974    //normalisation of the vectors (vector sum must be <= travelspeed)
[10098]975    float xzNorm = sqrt(pow(this->travelVelocity.x, 2) + pow(this->travelVelocity.z, 2));
[10043]976    if (xzNorm > this->travelSpeed)
977    {
[10098]978      this->travelVelocity.x = this->travelVelocity.x/xzNorm * this->travelSpeed;
979      this->travelVelocity.z = this->travelVelocity.z/xzNorm * this->travelSpeed;
[10043]980    }
[10032]981
[10099]982    //this moves camera and ship along the travel path.
[10043]983    this->travelNode->shiftCoor(Vector(this->cameraSpeed * dt, 0, 0));
[10099]984
[10043]985    break;
[10019]986    }
[10032]987    case Playable::Vertical:
988      break;
[10017]989    default:
[10032]990      PRINTF(4)("Playmode %s Not Implemented in %s\n", Playable::playmodeToString(this->getPlaymode()).c_str(), this->getClassCName());
[10017]991  }
[10099]992   //set new coordinates calculated through key- events.
[10098]993  this->shiftCoor (this->travelVelocity * dt);
[9975]994}
[10017]995
[10032]996void SpaceShip::setPlaymodeXML(const std::string& playmode)
997{
998  this->setPlaymode(Playable::stringToPlaymode(playmode));
999}
1000
[10113]1001/**
1002 * @brief jumps to the next WeaponConfiguration
1003 */
1004void SpaceShip::nextWeaponConfig()
1005{
[10117]1006  PRINTF(0)("Requested next weapon config!\n");
1007  this->weaponMan.nextWeaponConfig();
[10113]1008  Playable::weaponConfigChanged();
1009}
1010
1011/**
1012 * @brief moves to the last WeaponConfiguration
1013 */
1014void SpaceShip::previousWeaponConfig()
1015{
[10117]1016  this->curWeaponPrimary    = (this->curWeaponPrimary + 1) % 3;
[10113]1017  this->weaponMan.changeWeaponConfig(this->curWeaponPrimary);
1018  Playable::weaponConfigChanged();
[10117]1019}
1020
1021void SpaceShip::hit(float damage, WorldEntity* killer)
1022{
1023  this->damage(killer->getDamage(),0);
1024  killer->collidesWith( this, this->getAbsCoor());
1025  //this->collidesWith(killer, this->getAbsCoor());
1026}
[10120]1027
1028void SpaceShip::updateElectronicWidget()
1029{
[10139]1030  if (this->electronicWidget != NULL)
1031  { //if it exists already: update it
1032     this->electronicWidget->setMaximum(this->electronicMax);
1033     this->electronicWidget->setValue(this->electronicCur);
1034  }
1035  else
1036  { //create the widget
1037    this->electronicWidget = new OrxGui::GLGuiEnergyWidgetVertical();
1038    this->electronicWidget->setDisplayedName("Electronics:");
1039    //this->electronicWidget->setSize2D(100,20);
1040    //this->electronicWidget->setAbsCoor2D(150,200);
1041    this->updateElectronicWidget();
1042    if (this->hasPlayer())
1043      State::getPlayer()->hud().setEnergyWidget(this->electronicWidget);
1044  }
[10120]1045}
1046
1047void SpaceShip::updateShieldWidget()
1048{
[10139]1049  if (this->shieldWidget != NULL)
1050  { 
1051    this->shieldWidget->setMaximum(this->shieldMax);
1052    this->shieldWidget->setValue(this->shieldCur);;
1053  }
1054  else
1055  {
1056    this->shieldWidget = new OrxGui::GLGuiEnergyWidgetVertical();
1057    this->shieldWidget->setDisplayedName("Shield:");
1058    //his->shieldWidget->setSize2D(100,20);
1059    //this->shieldWidget->setAbsCoor2D(200,200);
1060    this->updateShieldWidget();
1061    if (this->hasPlayer())
1062      State::getPlayer()->hud().setShiledWidget(this->shieldWidget);
1063  }
[10120]1064}
Note: See TracBrowser for help on using the repository browser.