Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

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

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