Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10156 was 10156, checked in by marcscha, 17 years ago

Addition of billboard calc to wobblegrid. Temp addition to show it of in spaceship

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