Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10335 was 10335, checked in by bknecht, 17 years ago

track now works pretty good. I'm really pleased. Check it out, it doesn't crash anymore

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