Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/vs-enhencements/src/world_entities/space_ships/space_ship.cc @ 10670

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

moved "ship attributes" to world entity
electronic and shield widget not yet working

File size: 34.5 KB
Line 
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
22#include "util/loading/resource_manager.h"
23
24#include "weapons/test_gun.h"
25#include "weapons/light_blaster.h"
26#include "weapons/medium_blaster.h"
27#include "weapons/heavy_blaster.h"
28#include "weapons/rf_cannon.h"
29#include "weapons/nadion_laser.h"
30#include "weapons/disruptor.h"
31#include "weapons/swarm_launcher.h"
32#include "weapons/spike_thrower.h"
33#include "weapons/acid_launcher.h"
34#include "weapons/boomerang_gun.h"
35#include "weapons/turret.h"
36#include "weapons/cannon.h"
37
38#include "elements/glgui_energywidgetvertical.h"
39#include "glgui_bar.h"
40
41#include "particles/dot_emitter.h"
42#include "particles/emitter_node.h"
43#include "particles/sprite_particles.h"
44#include "effects/trail.h"
45
46#include "effects/wobblegrid.h"
47
48#include "util/loading/factory.h"
49#include "key_mapper.h"
50
51#include "network_game_manager.h"
52#include "shared_network_data.h"
53
54#include "items/power_ups/weapon_power_up.h"
55#include "items/power_ups/param_power_up.h"
56
57#include "graphics_engine.h"
58
59#include "plane.h"
60
61#include "state.h"
62#include "player.h"
63#include "tools/camera.h"
64#include "tools/cameraman.h"
65
66
67#include "util/loading/load_param.h"
68#include "time.h"
69
70#include "track/track.h"
71#include "track/action_box.h"
72
73
74ObjectListDefinition(SpaceShip);
75CREATE_FACTORY(SpaceShip);
76
77#include "script_class.h"
78CREATE_SCRIPTABLE_CLASS(SpaceShip,
79                        addMethod("hasPlayer", Executor0ret<Playable, lua_State*,bool>(&Playable::hasPlayer))
80                        ->addMethod("fire", Executor1<Playable, lua_State*, bool>(&Playable::fire))
81                        ->addMethod("loadModel", Executor2<WorldEntity, lua_State*,const std::string& ,float>(&WorldEntity::loadModel2))
82                        ->addMethod("setName", Executor1<BaseObject, lua_State*,const std::string&>(&BaseObject::setName))
83                        ->addMethod("hide", Executor0<WorldEntity, lua_State*>(&WorldEntity::hide))
84                        ->addMethod("unhide", Executor0<WorldEntity, lua_State*>(&WorldEntity::unhide))
85                        //Coordinates
86                        ->addMethod("setAbsCoor", Executor3<PNode, lua_State*,float,float,float>(&PNode::setAbsCoor))
87                        ->addMethod("getAbsCoorX", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorX))
88                        ->addMethod("getAbsCoorY", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorY))
89                        ->addMethod("getAbsCoorZ", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorZ))
90                        //->addMethod("setCameraSpeed", Executor1<SpaceShip, lua_State*, float>(&SpaceShip::setCameraSpeed))
91                        ->addMethod("pause", Executor1<WorldEntity, lua_State*, bool>(&WorldEntity::pauseTrack))
92                        ->addMethod("setCameraDist", Executor1<SpaceShip, lua_State*, float>(&SpaceShip::setCameraDistance))
93                       );
94
95/**
96 *  destructs the spaceship, deletes alocated memory
97 */
98SpaceShip::~SpaceShip ()
99{
100  this->setPlayer(NULL);
101}
102
103/**
104 * loads a Spaceships information from a specified file.
105 * @param fileName the name of the File to load the spaceship from (absolute path)
106 */
107SpaceShip::SpaceShip(const std::string& fileName)
108    : secWeaponMan(this) //,
109    //supportedPlaymodes(Playable::Vertical) ,
110    //playmode(Playable::Vertical)
111{
112  this->init();
113  TiXmlDocument doc(fileName);
114
115  if(!doc.LoadFile())
116  {
117    PRINTF(2)("Loading file %s failed for spaceship.\n", fileName.c_str());
118    return;
119  }
120
121  this->loadParams(doc.RootElement());
122}
123
124/**
125 *  creates a new Spaceship from Xml Data
126 * @param root the xml element containing spaceship data
127
128   @todo add more parameters to load
129*/
130SpaceShip::SpaceShip(const TiXmlElement* root)
131    : secWeaponMan(this) //,
132    //supportedPlaymodes(Playable::Vertical) ,
133    //playmode(Playable::Vertical)
134{
135  this->init();
136  //this->setParentMode(PNODE_REPARENT_DELETE_CHILDREN);
137  if (root != NULL)
138    this->loadParams(root);
139
140}
141
142
143/**
144 * initializes a Spaceship
145 */
146void SpaceShip::init()
147{
148
149  srand(time(0));   //initialize Random Nomber Generator
150
151  //  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
152  this->registerObject(this, SpaceShip::_objectList);
153  PRINTF(4)("SPACESHIP INIT\n");
154  this->weaponMan.setParentEntity( this);
155  //weapons:
156
157  this->weaponMan.setParentEntity( this);
158  this->secWeaponMan.setParentEntity( this);
159
160  this->weaponMan.setSlotCount(8);
161  this->secWeaponMan.setSlotCount(6);
162
163  this->weaponMan.createWeaponSlot(0, 3.270, 1.028, .155, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
164  this->weaponMan.createWeaponSlot(1, 3.270, 1.028, -.155, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
165  this->weaponMan.createWeaponSlot(2, 4.385, .063, .876, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
166  this->weaponMan.createWeaponSlot(3, 4.385, -.063, -.876, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
167  this->weaponMan.createWeaponSlot(4, 1.635, -.612, 2.691, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
168  this->weaponMan.createWeaponSlot(5, 1.536, -.612, -2.691, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
169  this->weaponMan.createWeaponSlot(6, 1.536, -.612, 3.254, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
170  this->weaponMan.createWeaponSlot(7, 1.536, -.612, -3.254, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
171
172
173  this->weaponMan.addWeaponToSlot(0, 0, "RFCannon");
174  this->weaponMan.addWeaponToSlot(0, 1, "RFCannon");
175  this->weaponMan.addWeaponToSlot(0, 2, "RFCannon");
176  this->weaponMan.addWeaponToSlot(0, 3, "RFCannon");
177  this->weaponMan.addWeaponToSlot(1, 0, "RFCannon");
178  this->weaponMan.addWeaponToSlot(1, 1, "RFCannon");
179  this->weaponMan.addWeaponToSlot(1, 2, "RFCannon");
180  this->weaponMan.addWeaponToSlot(1, 3, "RFCannon");
181
182  this->weaponMan.addWeaponToSlot(0, 4, "NadionLaser");
183  this->weaponMan.addWeaponToSlot(0, 5, "NadionLaser");
184  this->weaponMan.addWeaponToSlot(2, 4, "NadionLaser");
185  this->weaponMan.addWeaponToSlot(2, 5, "NadionLaser");
186
187  this->weaponMan.addWeaponToSlot(0, 6, "Disruptor");
188  this->weaponMan.addWeaponToSlot(0, 7, "Disruptor");
189  this->weaponMan.addWeaponToSlot(3, 6, "Disruptor");
190  this->weaponMan.addWeaponToSlot(3, 7, "Disruptor");
191
192
193  this->secWeaponMan.createWeaponSlot(0, 1.5, 3, 0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
194  this->secWeaponMan.createWeaponSlot(1, 2.6, 0, 3.0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
195  this->secWeaponMan.createWeaponSlot(2, 1.5, 0, -.5, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
196  this->secWeaponMan.createWeaponSlot(3, 1.5, 0, .5, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
197  this->secWeaponMan.createWeaponSlot(4, 1.5, 0, .5, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
198  this->secWeaponMan.createWeaponSlot(5, 1.5, 0, -.5, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
199
200  this->secWeaponMan.addWeaponToSlot(0, 2, "SwarmLauncher");
201
202
203  this->weaponMan.changeWeaponConfig(0);
204  this->secWeaponMan.changeWeaponConfig(0);
205
206
207  Playable::weaponConfigChanged();
208
209  setReactor(10);
210  setWeapon(10);
211  setEngine(15);
212
213
214//   loadEnergyShare(.3,.3,.4);
215//   loadShield(80, 100, .2, 2);
216//   loadHealth(100, 100, 0);
217//   loadElectronic(40, 50, .7, 3.0);
218
219//   this->loadModel("models/spaceships/fighter_redesign9.obj");
220  //this->setVisibiliy(false);
221
222  bForward = bBackward = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = bFire = bSecFire = false;
223
224//   this->setHealthMax(shieldMax);
225//   this->setHealth(shieldCur);
226
227  this->travelNode = new PNode();
228
229  // camera - issue
230  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
231  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
232
233
234//   this->electronicWidget = NULL;
235//   this->shieldWidget = NULL;
236
237  //add events to the eventlist
238  registerEvent(KeyMapper::PEV_FORWARD);
239  registerEvent(KeyMapper::PEV_BACKWARD);
240  registerEvent(KeyMapper::PEV_LEFT);
241  registerEvent(KeyMapper::PEV_RIGHT);
242  //registerEvent(SDLK_q);
243  //registerEvent(SDLK_e);
244  registerEvent(KeyMapper::PEV_FIRE1);
245  registerEvent(KeyMapper::PEV_FIRE2);                  // Added for secondary weapon support
246  registerEvent(KeyMapper::PEV_NEXT_WEAPON);
247  registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON);
248  //registerEvent(SDLK_PAGEUP);
249  //registerEvent(SDLK_PAGEDOWN);
250  registerEvent(EV_MOUSE_MOTION);
251
252
253  this->weaponMan.getFixedTarget()->setParent(this);
254  this->weaponMan.getFixedTarget()->setRelCoor(100000,0,0);
255
256
257  this->secWeaponMan.getFixedTarget()->setParent(this);
258  this->secWeaponMan.getFixedTarget()->setRelCoor(100000,0,0);
259  this->secWeaponMan.setRotationSpeed(0);
260
261  dynamic_cast<Element2D*>(this->weaponMan.getFixedTarget())->setVisibility( false);
262
263
264  registerVar( new SynchronizeableBool( &bForward, &bForward, "bForward", PERMISSION_OWNER ) );
265  registerVar( new SynchronizeableBool( &bBackward, &bBackward, "bBackward", PERMISSION_OWNER ) );
266  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
267  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
268  registerVar( new SynchronizeableFloat( &cameraLook, &cameraLook, "cameraLook", PERMISSION_OWNER ) );
269  registerVar( new SynchronizeableFloat( &rotation, &rotation, "rotation", PERMISSION_OWNER ) );
270  registerVar( new SynchronizeableBool( &bFire, &bFire, "bSecFire", PERMISSION_OWNER));
271  registerVar( new SynchronizeableVector( &velocity, &velocity, "velocity", PERMISSION_MASTER_SERVER ) );
272
273  //this->airFriction = 0.5f;
274  //this->travelDistancePlus = Vector2D(38.0, 43.0);
275  //this->travelDistanceMinus = Vector2D(-38.0, -43.0);
276  this->travelDistancePlus = Vector2D(50,50);
277  this->travelDistanceMinus = Vector2D(-50,-50);
278  this->isTravelDistanceInit = true;
279  this->actionWidthPercentage = 1;
280
281  this->cameraSpeed = 40;
282  this->cameraLook = 0.0f;
283  //this->airFriction = 0.0f;
284
285  srand(time(0));  //initaialize RNG
286
287  this->travelNode->debugDraw();
288
289  this->setSupportedPlaymodes(Playable::Horizontal | Playable::Vertical);
290
291
292//   this->toList(OM_GROUP_00);
293
294  if ( this->hasPlayer() ){
295    State::getPlayer()->hud().setShieldWidget(this->getShieldWidget());
296    State::getPlayer()->hud().setEnergyWidget(this->getElectronicWidget());
297  }
298}
299
300
301/**
302 * loads the Settings of a SpaceShip from an XML-element.
303 * @param root the XML-element to load the Spaceship's properties from
304 */
305void SpaceShip::loadParams(const TiXmlElement* root)
306{
307  Playable::loadParams(root);
308
309  LoadParam(root, "playmode", this, SpaceShip, setPlaymodeXML);
310  LoadParam(root, "cameraDistance", this, SpaceShip, setCameraDistance);
311  LoadParam(root, "cameraFovy", this, SpaceShip, setCameraFovy);
312  LoadParam(root, "actionWidthPercentage", this, SpaceShip, setActionWidthPercentage);
313
314  State::getCamera()->setViewMode(Camera::ViewNormal);
315  State::getCameraTargetNode()->setParent(this);
316  State::getCamera()->setParent(this);
317
318  LoadParam(root, "setReactor", this, SpaceShip, setReactor)
319  .describe("set reactor output");
320  LoadParam(root, "loadShield", this, WorldEntity, loadShield)
321  .describe("set shield parameters: current strenght , max strenght, threshhold value (0..1), regeneration rate");
322  LoadParam(root, "loadHealth", this, WorldEntity, loadHealth)
323  .describe("set armor/health parameters: current strenght , max strenght");
324  LoadParam(root, "loadElectronic", this, WorldEntity, loadElectronic)
325  .describe("set electronics parameters: current strenght , max strenght, threshhold value (0..1), regeneration rate");
326  LoadParam(root, "setEngine", this, SpaceShip, setEngine)
327  .describe("set base speed");
328  LoadParam(root, "loadEnergyShare", this, SpaceShip, loadEnergyShare)
329  .describe("set energy partitioning: shield, weapons, engine (sum should be 1)");
330  LoadParam(root, "setWeapon", this, SpaceShip, setWeapon)
331  .describe("set weapon regeneration");
332
333/*
334  LOAD_PARAM_START_CYCLE(root, element);
335  {
336    LoadParamXML_CYCLE(element, "weaponMan", this->weaponMan, WeaponManager, loadWeapons)
337    .describe("loads Weapons");
338  }
339  LOAD_PARAM_END_CYCLE(element);
340
341  LOAD_PARAM_START_CYCLE(root, element);
342  {
343    LoadParamXML_CYCLE(element, "secWeaponMan", this->secWeaponMan, WeaponManager, loadWeapons)
344    .describe("loads Weapons");
345  }
346  LOAD_PARAM_END_CYCLE(element);*/
347}
348
349
350void SpaceShip::setPlayDirection(const Quaternion& rot, float speed)
351{
352  //this->direction = Quaternion (rot.getHeading(), Vector(0,1,0));
353}
354
355void SpaceShip::reset()
356{
357  bForward = bBackward = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = bFire = bSecFire = false;
358
359  this->resetHealth();
360  this->resetShield();
361  this->resetElectronic();
362  this->velocity = Vector(0.0, 0.0, 0.0);
363}
364
365
366void SpaceShip::enter()
367{
368  this->secWeaponMan.showCrosshair();
369  this->toList( OM_GROUP_01 );
370  State::getPlayer()->hud().setRadarCenterNode(this->travelNode);
371  State::getPlayer()->hud().setOverlayActive(true);
372}
373
374void SpaceShip::leave()
375{
376  this->secWeaponMan.hideCrosshair();
377  this->toList( OM_GROUP_00);
378  State::getPlayer()->hud().setOverlayActive(false);
379  State::getCamera()->setEventHandling(true);
380  State::getPlayer()->hud().setRadarCenterNode(NULL);
381}
382
383
384/**
385 *  effect that occurs after the SpaceShip is spawned
386*/
387void SpaceShip::postSpawn ()
388{
389  if(this->hasPlayer())
390    Playable::postSpawn();
391}
392
393/**
394 *  the action occuring if the spaceship left the game
395*/
396void SpaceShip::leftWorld ()
397{
398
399}
400
401WorldEntity* ref = NULL;
402
403/**
404 *  draws the spaceship after transforming it.
405*/
406void SpaceShip::draw () const
407{
408  if( this->entityTrack != NULL && this->isDrawTrack())
409    this->entityTrack->drawGraph();
410
411  WorldEntity::draw();
412
413//   glMatrixMode(GL_MODELVIEW);
414//   glPushMatrix();
415
416//   float matrix[4][4];
417//   glTranslatef (this->getAbsCoor ().x-1, this->getAbsCoor ().y-.2, this->getAbsCoor ().z);
418//   this->getAbsDir().matrix (matrix);
419//   glMultMatrixf((float*)matrix);
420  //glScalef(2.0, 2.0, 2.0);  // no double rescale
421
422
423//   this->trail->draw();
424
425//   glTranslatef(0,0,-.5);
426//   this->trailL->draw();
427
428//   glTranslatef(0,0,1);
429//   this->trailR->draw();
430
431//   glPopMatrix();
432  //this->debug(0);
433}
434
435/**
436 *  the function called for each passing timeSnap
437 * @param time The timespan passed since last update
438*/
439void SpaceShip::tick (float time)
440{
441  // Playable::tick(time);
442
443 // this->test->tick(time);
444
445  // Own Tick Setup, as a different fire routine is used on the weapon manager
446  this->weaponMan.tick(time);
447  this->secWeaponMan.tick(time);
448
449  if( this->systemFailure() )
450    bFire = bSecFire = false;
451
452  // fire reqeust/release for primary weapons
453  if( this->bFire)
454    this->weaponMan.fire();
455  else
456    this->weaponMan.releaseFire();
457
458  // fire reqeust/release for secondary weapons
459  if( this->bSecFire)
460    this->secWeaponMan.fire();
461  else
462    this->secWeaponMan.releaseFire();
463
464  // Tracktick
465  if(this->entityTrack)
466    this->entityTrack->tick(time);
467
468
469  // Shield Regeneration and other regular calculations on the ship
470  this->regen(time);
471
472  // Weapon Regeneration and other regular calculations on the ship
473  this->weaponRegen(time);
474
475  // current engine speed output
476  this->engineSpeedCur = this->engineSpeedBase + this->reactorOutput * this->engineEnergyShare;
477
478  // calculation of maxSpeed and acceleration:
479  this->travelSpeed = this->engineSpeedCur * 5;
480  this->acceleration = this->travelSpeed * 2;
481
482  this->movement(time);
483
484   // TRYING TO FIX PNode.
485  this->cameraNode.setAbsCoorSoft(this->getAbsCoor() + Vector(0.0f, 5.0f, 0.0f), 30.0f);
486  this->cameraNode.setRelDirSoft(this->getAbsDir(), 30.0f);
487
488
489  this->velocity  = (this->getAbsCoor() - this->oldPos) / time;
490  this->oldPos    = this->getAbsCoor();
491
492//FIXME
493//   this->trail->tick(time);
494//   this->trailL->tick(time);
495//   this->trailR->tick(time);
496
497  if (!this->isTravelDistanceInit)
498  {
499    this->updateTravelDistance();
500    //this->isTravelDistanceInit = true;
501  }
502
503  //orient the spaceship in direction of the mouse
504  /*
505  rotQuat = Quaternion::quatSlerp( this->getAbsDir(), mouseDir, 0.5);//fabsf(time)*shipInertia);
506  if (this->getAbsDir().distance(rotQuat) > 0.00000000000001)
507    this->setAbsDir( rotQuat);
508  //this->setAbsDirSoft(mouseDir,5);
509  */
510  /*
511  this->shiftCoor(move);
512  */
513
514  //   PRINTF(0)("id of %s is: %i\n", this->getName(), this->getOMListNumber());
515
516}
517
518/**
519 * @todo switch statement ??
520 */
521void SpaceShip::process(const Event &event)
522{
523  //Playable::process(event);
524
525  if( event.type == KeyMapper::PEV_LEFT)
526    this->bLeft = event.bPressed;
527  else if( event.type == KeyMapper::PEV_RIGHT)
528  {
529    this->bRight = event.bPressed;
530//     printf("ShipCoors: %f , %f, %f \n", this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z);
531  }
532  else if( event.type == KeyMapper::PEV_FORWARD)
533  {
534    this->bForward = event.bPressed; //this->shiftCoor(0,.1,0);
535
536  }
537  else if( event.type == KeyMapper::PEV_BACKWARD)
538    this->bBackward = event.bPressed; //this->shiftCoor(0,-.1,0);
539  else if( event.type == KeyMapper::PEV_FIRE2)
540    this->bSecFire = event.bPressed;
541  else if( event.type == KeyMapper::PEV_FIRE1)
542    this->bFire = event.bPressed;
543  else if( event.type == KeyMapper::PEV_NEXT_WEAPON && event.bPressed)
544  {
545    this->nextWeaponConfig();
546  }
547  else if ( event.type == KeyMapper::PEV_PREVIOUS_WEAPON && event.bPressed)
548    this->previousWeaponConfig();
549
550  if (!(State::getCamera()->getEventHandling()))
551  {
552    //PRINTF(0)("\n\n\n\n\n\n\n\nSETCAMERA %x\n\n\n\n\n\n\n", State::getCamera());
553    if( event.type == KeyMapper::PEV_VIEW0)
554    {
555      State::getCamera()->setViewMode(Camera::ViewNormal);
556      State::getCameraTargetNode()->setParent(this);
557      State::getCamera()->setParent(this);
558    }
559    else if( event.type == KeyMapper::PEV_VIEW1)
560    {
561      State::getCamera()->setViewMode(Camera::ViewBehind);
562      State::getCameraTargetNode()->setParent(this);
563      State::getCamera()->setParent(this);
564    }
565    else if( event.type == KeyMapper::PEV_VIEW2)
566    {
567      State::getCamera()->setViewMode(Camera::ViewFront);
568      State::getCameraTargetNode()->setParent(this);
569      State::getCamera()->setParent(this);
570    }
571    else if( event.type == KeyMapper::PEV_VIEW3)
572    {
573      State::getCamera()->setViewMode(Camera::ViewLeft);
574      State::getCameraTargetNode()->setParent(this);
575      State::getCamera()->setParent(this);
576    }
577    else if( event.type == KeyMapper::PEV_VIEW4)
578    {
579      State::getCamera()->setViewMode(Camera::ViewRight);
580      State::getCameraTargetNode()->setParent(this);
581      State::getCamera()->setParent(this);
582    }
583    else if( event.type == KeyMapper::PEV_VIEW5)
584    {
585      State::getCamera()->setViewMode(Camera::ViewTop);
586      State::getCameraTargetNode()->setParent(this->travelNode);
587      State::getCamera()->setParent(this->travelNode);
588    }
589  }
590
591
592  /*
593  else if( event.type == EV_MOUSE_MOTION)
594  {
595
596    this->xMouse += event.xRel;
597    this->yMouse += event.yRel;
598  }
599  */
600}
601
602void SpaceShip::destroy( WorldEntity* killer )
603{
604  if(this->hasPlayer())
605    Playable::destroy( killer);
606
607  PRINTF(5)("spaceship destroy\n");
608
609  EmitterNode* node  = NULL;
610  DotEmitter* emitter = NULL;
611  SpriteParticles*  explosionParticles  = NULL;
612
613  explosionParticles = new SpriteParticles(200);
614  explosionParticles->setName("SpaceShipExplosionParticles");
615  explosionParticles->setLifeSpan(.2, .3);
616  explosionParticles->setRadius(0.0, 10.0);
617  explosionParticles->setRadius(.5, 6.0);
618  explosionParticles->setRadius(1.0, 3.0);
619  explosionParticles->setColor(0.0, 1,1,1,.9);
620  explosionParticles->setColor(0.1,  1,1,0,.9);
621  explosionParticles->setColor(0.5, .8,.4,0,.5);
622  explosionParticles->setColor(1.0, .2,.2,.2,.5);
623
624
625  emitter = new DotEmitter( 2000, 70, 360);
626  //emitter->setSpread( 0, M_2_PI);
627  emitter->setEmissionRate( 200.0);
628  //emitter->setEmissionVelocity( 200.0);
629  //emitter->setSystem( explosionParticles);
630  //emitter->setAbsCoor( this->getAbsCoor());
631
632  node  = new EmitterNode( .1f);
633  node->setupParticle( emitter, explosionParticles);
634  node->setAbsDir( this->getAbsDir());
635  node->setVelocity( this->getVelocity() * .9f);
636  node->setAbsCoor( this->getAbsCoor());
637  if( !node->start())
638    PRINTF(0)("Explosion node not correctly started!");
639/*
640  PNode* node          = new PNode();
641  node->setAbsCoor(this->getAbsCoor());
642  Explosion* explosion = new Explosion();
643  explosion->explode( node, Vector(5,5,5));
644*/
645/*
646  if( this->hasPlayer())
647  {
648        this->setAbsCoor(Vector(-10000,10000,10000));
649        this->hide();
650  }
651  else
652  {*/
653    this->setAbsCoor( this->getAbsCoor() + Vector(100,0,0) + Vector(1,0,0) * VECTOR_RAND(150).dot(Vector(1,0,0)));
654  //}
655
656}
657
658void SpaceShip::respawn( )
659{
660  Playable::respawn();
661}
662
663
664void SpaceShip::damage(float pDamage, float eDamage){
665  PRINTF(5)("ship hit for (%f,%f) \n",pDamage,eDamage);
666
667  static float tmp = this->decreaseShield(pDamage);
668  if( tmp > 0)
669  if ( this->decreaseHealth(tmp / 2) )
670    this->destroy(this);
671
672}
673
674
675
676/**
677 * Weapon regeneration
678 * does not use any reactor capacity, as it wouldn't work in a consistent way.
679 */
680void SpaceShip::weaponRegen(float time)
681{
682  float energy = ( this->reactorOutput * this->weaponEnergyShare + this->weaponEnergyRegen) * time ;
683  Weapon* weapon;
684  int weaponCount = 0;
685  for( unsigned int i=0; i < this->weaponMan.getSlotCount(); i++) {
686    weapon = this->weaponMan.getWeapon(i);
687    if( weapon != NULL && weapon->isActive()) {
688      weaponCount++;
689    }
690  }
691
692  if (weaponCount == 0)
693    return;
694  energy *= ( this->weaponMan.getSlotCount() / (float)weaponCount );
695
696  for( unsigned int i=0; i < this->weaponMan.getSlotCount(); i++) {
697    weapon = this->weaponMan.getWeapon(i);
698    if( weapon != NULL && weapon->isActive()) {
699      weapon->increaseEnergy( energy);
700    }
701  }
702  // weaponMan.increaseAmmunition( weapon, energy);
703}
704
705
706void SpaceShip::enterPlaymode(Playable::Playmode playmode){
707  switch(playmode)
708  {
709    case Playable::Full3D:
710      /*
711      if (State::getCameraNode != NULL)
712      {
713        Vector absCoor = this->getAbsCoor();
714        this->setParent(PNode::getNullParent());
715        this->setAbsCoor(absCoor);
716        State::getCameraNode()->setParentSoft(&this->cameraNode);
717        State::getCameraNode()->setRelCoorSoft(-10, 0,0);
718        State::getCameraTargetNode()->setParentSoft(&this->cameraNode);
719        State::getCameraTargetNode()->setRelCoorSoft(100, 0,0);
720
721      }
722      */
723      //break;
724
725      break;
726    case Playable::Horizontal:
727      if (State::getCameraNode != NULL)
728      {
729        this->debugNode(1);
730        this->travelNode->debugNode(1);
731
732        this->travelNode->setAbsCoor(this->getAbsCoor());
733        this->travelNode->updateNode(0.01f);
734
735        this->isTravelDistanceInit = false;
736
737        if(this->entityTrack)
738           this->travelNode->setParent(this->entityTrack->getTrackNode());
739
740        this->setParent(this->travelNode);
741        this->setRelCoor(0,0,0);
742
743        State::getCameraNode()->setParentSoft(this->travelNode);
744        //State::getCameraNode()->setParentSoft(this);
745        //State::getCameraNode()->setRelCoorSoft(-0.01, 40, 0);
746        State::getCameraTargetNode()->setParentSoft(this->travelNode);
747        //State::getCameraTargetNode()->setParentSoft(this);
748        //State::getCameraTargetNode()->setRelCoorSoft(0,0,0);
749        this->setCameraMode(Camera::ViewTop);
750        State::getCamera()->setEventHandling(false);
751        registerEvent(KeyMapper::PEV_VIEW0);
752        registerEvent(KeyMapper::PEV_VIEW1);
753        registerEvent(KeyMapper::PEV_VIEW2);
754        registerEvent(KeyMapper::PEV_VIEW3);
755        registerEvent(KeyMapper::PEV_VIEW4);
756        registerEvent(KeyMapper::PEV_VIEW5);
757
758        State::getCamera()->setParentMode(PNODE_ALL);
759
760        //this->updateTravelDistance();
761
762        this->debugNode(1);
763        this->travelNode->debugNode(1);
764      }
765      break;
766
767
768    case Playable::Vertical:
769    {
770        this->travelNode->setAbsCoor(this->getAbsCoor());
771        this->travelNode->updateNode(0.01f);
772
773        this->isTravelDistanceInit = false;
774
775        if(this->entityTrack)
776           this->travelNode->setParent(this->entityTrack->getTrackNode());
777
778        this->setParent(this->travelNode);
779        this->setRelCoor(0,0,0);
780
781        State::getCameraNode()->setParentSoft(this->travelNode);
782        //State::getCameraNode()->setParentSoft(this);
783        //State::getCameraNode()->setRelCoorSoft(-0.01, 40, 0);
784        State::getCameraTargetNode()->setParentSoft(this->travelNode);
785        //State::getCameraTargetNode()->setParentSoft(this);
786        //State::getCameraTargetNode()->setRelCoorSoft(0,0,0);
787        //this->setCameraMode(Camera::ViewNormal);
788        State::getCamera()->setEventHandling(false);
789
790        PRINTF(0)("\n\n\n\n\n\n\n\nSETCAMERA %x\n\n\n\n\n\n\n", State::getCamera());
791        State::getCamera()->setViewMode(Camera::ViewNormal);
792        State::getCameraTargetNode()->setParent(this);
793        State::getCamera()->setParent(this);
794
795
796        registerEvent(KeyMapper::PEV_VIEW0);
797        registerEvent(KeyMapper::PEV_VIEW1);
798        registerEvent(KeyMapper::PEV_VIEW2);
799        registerEvent(KeyMapper::PEV_VIEW3);
800        registerEvent(KeyMapper::PEV_VIEW4);
801        registerEvent(KeyMapper::PEV_VIEW5);
802
803        State::getCamera()->setParentMode(PNODE_ALL);
804
805      break;
806    }
807
808    default:
809      PRINTF(2)("Playmode %s Not Implemented in %s\n", Playable::playmodeToString(this->getPlaymode()).c_str(), this->getClassCName());
810  }
811}
812
813/**
814 * @brief calculate the velocity
815 * @param time the timeslice since the last frame
816*/
817
818void SpaceShip::movement (float dt)
819{
820  //by releasing the buttons, the velocity decreases with airCoeff*Acceleration. Should be strong enough so
821  //the ship doesn't slide too much.
822  float airCoeff = 2.5;
823  float pi = 3.14;
824
825  switch(this->getPlaymode())
826  {
827    case Playable::Horizontal:
828    {
829      // these routines will change the travel movement into zero in a short amout of time, if the player
830      // doesn't press any buttons.
831      if (this->travelVelocity.x >= 0)
832      {
833        if (this->travelVelocity.x > airCoeff*this->acceleration * dt)
834          this->travelVelocity.x -= airCoeff* this->acceleration * dt;
835        else
836          this->travelVelocity.x = 0;
837      }
838      else
839      {
840        if (this->travelVelocity.x < -airCoeff*this->acceleration * dt)
841          this->travelVelocity.x += airCoeff* this->acceleration * dt;
842        else
843          this->travelVelocity.x = 0;
844      }
845      if (this->travelVelocity.z >= 0)
846      {
847        if (this->travelVelocity.z > airCoeff*this->acceleration * dt)
848          this->travelVelocity.z -= airCoeff* this->acceleration * dt;
849        else
850          this->travelVelocity.z = 0;
851      }
852      else
853      {
854        if (this->travelVelocity.z < -airCoeff*this->acceleration * dt)
855          this->travelVelocity.z += airCoeff* this->acceleration * dt;
856        else
857          this->travelVelocity.z = 0;
858      }
859
860      // this will evite, that the ship moves outside the travelDistance- borders,when the player releases all buttons
861      // and its continuing to slide a bit.
862      Vector oldCoor = this->getRelCoor();
863      if (this->getRelCoor().x > this->travelDistancePlus.x) this->setRelCoor(this->travelDistancePlus.x, oldCoor.y, oldCoor.z);
864      if (this->getRelCoor().x < this->travelDistanceMinus.x) this->setRelCoor(this->travelDistanceMinus.x, oldCoor.y, oldCoor.z);
865      if (this->getRelCoor().z > this->travelDistancePlus.y) this->setRelCoor(oldCoor.x, oldCoor.y, this->travelDistancePlus.y);
866      if (this->getRelCoor().z < this->travelDistanceMinus.y) this->setRelCoor(oldCoor.x, oldCoor.y, this->travelDistanceMinus.y);
867
868      if( this->systemFailure() )
869        bForward = bBackward = bLeft = bRight = false;
870
871      if( this->bForward )
872      {
873        //printf("ShipCoorX: %f \n", this->getRelCoor().x);
874        if(this->getRelCoor().x < this->travelDistancePlus.x)
875        {
876          if (this->travelVelocity.x < this->travelSpeed)
877          {
878            this->travelVelocity.x += (airCoeff + 1.0)*this->acceleration*dt;
879          }
880          else
881          {
882            this->travelVelocity.x = this->travelSpeed;
883          }
884        }
885        else
886        {
887          this->travelVelocity.x = 0.0f;
888        }
889      }
890
891      if( this->bBackward )
892      {
893        if(this->getRelCoor().x > this->travelDistanceMinus.x)
894        {
895          if (this->travelVelocity.x > -this->travelSpeed)
896          {
897            this->travelVelocity.x -= (airCoeff + 1.0)*this->acceleration*dt;
898          }
899          else
900          {
901            this->travelVelocity.x = -this->travelSpeed;
902          }
903        }
904        else
905        {
906          this->travelVelocity.x = 0.0f;
907        }
908      }
909
910      if( this->bLeft)
911      {
912        if(this->getRelCoor().z > this->travelDistanceMinus.y)
913        {
914          if (this->travelVelocity.z > -this->travelSpeed)
915          {
916            this->travelVelocity.z -= (airCoeff + 1.0)*this->acceleration*dt;
917          }
918          else
919          {
920            this->travelVelocity.z = -this->travelSpeed;
921          }
922        }
923        else
924        {
925          this->travelVelocity.z = 0.0f;
926        }
927        this->setRelDirSoft(Quaternion(-pi/6, Vector(1,0,0)), 6);
928      }
929
930      if( this->bRight)
931      {
932        //printf("ShipCoorZ: %f \n", this->getRelCoor().z);
933        if(this->getRelCoor().z < this->travelDistancePlus.y)
934        {
935          if (this->travelVelocity.z < this->travelSpeed)
936          {
937            this->travelVelocity.z += (airCoeff + 1.0)*this->acceleration*dt;
938          }
939          else
940          {
941            this->travelVelocity.z = this->travelSpeed;
942          }
943        }
944        else
945        {
946          this->travelVelocity.z = 0.0f;
947        }
948        this->setRelDirSoft(Quaternion(pi/6, Vector(1,0,0)), 6);
949      }
950      if (!this->bRight && !this->bLeft)
951      {
952        this->setRelDirSoft(Quaternion(0, Vector(1,0,0)), 6);
953      }
954
955    //normalisation of the vectors (vector sum must be <= travelspeed)
956    float xzNorm = sqrt(pow(this->travelVelocity.x, 2) + pow(this->travelVelocity.z, 2));
957    if (xzNorm > this->travelSpeed)
958    {
959      this->travelVelocity.x = this->travelVelocity.x/xzNorm * this->travelSpeed;
960      this->travelVelocity.z = this->travelVelocity.z/xzNorm * this->travelSpeed;
961    }
962
963    //this moves camera and ship along the travel path.
964    if(!this->entityTrack)
965       this->travelNode->shiftCoor(Vector(this->cameraSpeed * dt, 0, 0));
966
967    break;
968    }
969    case Playable::Vertical:
970    {
971      if ( !entityTrack || !entityTrack->getActionBox() )
972      {
973        break;
974      }
975      ActionBox * box = entityTrack->getActionBox();
976
977      this->travelVelocity = Vector(0, 0, 0);
978      float ssss = 50;
979      if ( this->bForward )
980      {
981        this->travelVelocity += Vector( 0, ssss, 0 );
982      }
983      if ( this->bBackward )
984      {
985        this->travelVelocity += Vector( 0, -ssss, 0 );
986      }
987      if ( this->bLeft )
988      {
989        this->travelVelocity += Vector( 0, 0, -ssss );
990      }
991      if ( this->bRight )
992      {
993        this->travelVelocity += Vector( 0, 0, ssss );
994      }
995
996      Vector ds = this->travelVelocity*dt;
997      Vector newPos = this->getRelCoor() + ds;
998      if ( newPos.y < -(box->getHeight_2()) || newPos.y > box->getHeight_2() )
999      {
1000        this->travelVelocity.y = 0;
1001      }
1002      if ( newPos.z > box->getWidth_2() || newPos.z < -(box->getWidth_2()) )
1003      {
1004        this->travelVelocity.z = 0;
1005      }
1006    }
1007      break;
1008    default:
1009      PRINTF(4)("Playmode %s Not Implemented in %s\n", Playable::playmodeToString(this->getPlaymode()).c_str(), this->getClassCName());
1010  }
1011   //set new coordinates calculated through key- events.
1012  this->shiftCoor (this->travelVelocity * dt);
1013}
1014
1015void SpaceShip::setPlaymodeXML(const std::string& playmode)
1016{
1017  this->setPlaymode(Playable::stringToPlaymode(playmode));
1018}
1019
1020/**
1021 * @brief jumps to the next WeaponConfiguration
1022 */
1023void SpaceShip::nextWeaponConfig()
1024{
1025  PRINTF(0)("Requested next weapon config!\n");
1026  this->weaponMan.nextWeaponConfig();
1027  Playable::weaponConfigChanged();
1028}
1029
1030/**
1031 * @brief moves to the last WeaponConfiguration
1032 */
1033void SpaceShip::previousWeaponConfig()
1034{
1035  /*
1036  this->curWeaponPrimary    = (this->curWeaponPrimary + 1) % 3;
1037  this->weaponMan.changeWeaponConfig(this->curWeaponPrimary);
1038  */
1039  this->weaponMan.previousWeaponConfig();
1040  Playable::weaponConfigChanged();
1041}
1042
1043void SpaceShip::hit( float damage, WorldEntity* killer)
1044{
1045  this->damage(killer->getDamage(),0);
1046}
1047
1048// void SpaceShip::updateElectronicWidget()
1049// {
1050//   if (this->electronicWidget != NULL)
1051//   { //if it exists already: update it
1052//      this->electronicWidget->setMaximum(this->electronicMax);
1053//      this->electronicWidget->setValue(this->electronicCur);
1054//   }
1055//   else
1056//   { //create the widget
1057//     this->electronicWidget = new OrxGui::GLGuiEnergyWidgetVertical();
1058//     this->electronicWidget->getBarWidget()->setChangedValueColor(Color(1,0,0,1));
1059//     //this->electronicWidget->setDisplayedName("Electronics:");
1060//     //this->electronicWidget->setSize2D(100,20);
1061//     //this->electronicWidget->setAbsCoor2D(150,200);
1062//     this->updateElectronicWidget();
1063//     if (this->hasPlayer())
1064//       State::getPlayer()->hud().setEnergyWidget(this->electronicWidget);
1065//   }
1066// }
1067//
1068// void SpaceShip::updateShieldWidget()
1069// {
1070//   if (this->shieldWidget != NULL)
1071//   {
1072//     this->shieldWidget->setMaximum(this->shieldMax);
1073//     this->shieldWidget->setValue(this->shieldCur);;
1074//   }
1075//   else
1076//   {
1077//     this->shieldWidget = new OrxGui::GLGuiEnergyWidgetVertical();
1078//     this->shieldWidget->getBarWidget()->setChangedValueColor(Color(1,0,0,1));
1079//     //this->shieldWidget->setDisplayedName("Shield:");
1080//     //his->shieldWidget->setSize2D(100,20);
1081//     //this->shieldWidget->setAbsCoor2D(200,200);
1082//     this->updateShieldWidget();
1083//     if (this->hasPlayer())
1084//       State::getPlayer()->hud().setShiledWidget(this->shieldWidget);
1085//   }
1086// }
1087
1088void SpaceShip::setCameraDistance(float dist)
1089{
1090  Camera* c = State::getCamera();
1091  c->setViewTopDistance(dist);
1092
1093  if (this->hasPlayer())
1094    this->isTravelDistanceInit = false;
1095}
1096
1097void SpaceShip::setCameraFovy(float fovy)
1098{
1099
1100  Camera* c = State::getCamera();
1101  c->setViewTopFovy(fovy);
1102
1103  if (this->hasPlayer())
1104    this->isTravelDistanceInit = false;
1105}
1106
1107void SpaceShip::updateTravelDistance()
1108{
1109
1110  Camera* c = State::getCamera();
1111
1112  float x = 1.25 * this->actionWidthPercentage * fabsf(c->getAbsCoor().y) * tan(c->getFovy()*M_PI /360.0);
1113  float y = x / c->getAspectRatio() / this->actionWidthPercentage;
1114  //State::getCamera()->setAbsCoor(-5, 1000, 0);
1115
1116
1117  //State::getCamera()->getAbsCoor().print();
1118  //printf("CameraRelCoorY: %f \n", State::getCamera()->getRelCoor().y);
1119
1120  //printf("x: %f, y: %f \n", x, y);
1121  this->travelDistancePlus = Vector2D(y, x);
1122  this->travelDistanceMinus = Vector2D(-y, -x);
1123
1124  State::getPlayer()->hud().setOverlayPercentage(100-int(100*this->actionWidthPercentage));
1125//   PRINTF(0)("TravelDistance has been updated\n");
1126  this->isTravelDistanceInit = true;
1127}
1128
1129void SpaceShip::setActionWidthPercentage(int i)
1130{
1131  if (i>100) i=100;
1132  if (i<0) i=0;
1133  this->actionWidthPercentage = i/100.0;
1134
1135  if (this->hasPlayer())
1136    this->isTravelDistanceInit = false;
1137};
1138
1139
Note: See TracBrowser for help on using the repository browser.