Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

just another upload
GUI seems to work, but there are still some unexplainable segfaults

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