Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/coll_rect.merge/src/world_entities/space_ships/spacecraft_2d.cc @ 10012

Last change on this file since 10012 was 10012, checked in by patrick, 17 years ago

now the attractor mines collide with the spaceshipt too, and vice versa

File size: 15.3 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 Grauer
13   co-programmer: ...
14
15*/
16
17#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
18
19#include "spacecraft_2d.h"
20
21#include "weapons/weapon_manager.h"
22#include "weapons/test_gun.h"
23#include "weapons/turret.h"
24#include "weapons/cannon.h"
25
26#include "util/loading/factory.h"
27#include "util/loading/load_param.h"
28#include "key_mapper.h"
29#include "state.h"
30
31#include "graphics_engine.h"
32#include "particles/dot_emitter.h"
33#include "particles/sprite_particles.h"
34
35#include "debug.h"
36
37#include "script_class.h"
38
39
40#include "class_id_DEPRECATED.h"
41ObjectListDefinitionID(Spacecraft2D, CL_SPACECRAFT_2D);
42CREATE_FACTORY(Spacecraft2D);
43
44CREATE_SCRIPTABLE_CLASS(Spacecraft2D,
45                        addMethod("hasPlayer", Executor0ret<Playable, lua_State*,bool>(&Playable::hasPlayer))
46                        //Coordinates
47                            ->addMethod("setAbsCoor", Executor3<PNode, lua_State*,float,float,float>(&PNode::setAbsCoor))
48                            ->addMethod("getAbsCoorX", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorX))
49                            ->addMethod("getAbsCoorY", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorY))
50                            ->addMethod("getAbsCoorZ", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorZ))
51                            ->addMethod("setAirFriction", Executor1<Spacecraft2D, lua_State*, float>(&Spacecraft2D::setAirFriction))
52                       );
53
54
55
56/**
57 * @brief loads a Spacecraft2D information from a specified file.
58 * @param fileName the name of the File to load the spacecraft_2d from (absolute path)
59 */
60Spacecraft2D::Spacecraft2D(const std::string& fileName)
61{
62  this->init();
63  TiXmlDocument doc(fileName);
64
65  if(!doc.LoadFile())
66  {
67    PRINTF(2)("Loading file %s failed for Spacecraft2D.\n", fileName.c_str());
68    return;
69  }
70
71  this->loadParams(doc.RootElement());
72}
73
74/**
75 * @brief creates a new Spaceship from Xml Data
76 * @param root the xml element containing spaceship data
77
78   @todo add more parameters to load
79*/
80Spacecraft2D::Spacecraft2D(const TiXmlElement* root)
81{
82  this->init();
83  if (root != NULL)
84    this->loadParams(root);
85
86
87
88  //weapons:
89  Weapon* wpRight = dynamic_cast<Weapon*>(Factory::fabricate("LaserCannon"));
90  wpRight->setName("Cannon_Right");
91  Weapon* wpLeft = dynamic_cast<Weapon*>(Factory::fabricate("LaserCannon"));
92  wpLeft->setName("Cannon_Left");
93
94  Weapon* turretLeft = dynamic_cast<Weapon*>(Factory::fabricate("BoomerangGun"));
95  wpRight->setName("Turret_Left");
96  Weapon* turretRight = dynamic_cast<Weapon*>(Factory::fabricate("BoomerangGun"));
97  wpLeft->setName("Turret_Right");
98
99  //  cannon->setName("BFG");
100
101  this->addWeapon(wpLeft, 1, 0);
102  this->addWeapon(wpRight,1 ,1);
103  this->addWeapon(turretLeft, 1, 2);
104  this->addWeapon(turretRight, 1, 3);
105
106  //this->addWeapon(cannon, 0, 2);
107
108  this->getWeaponManager().changeWeaponConfig(1);
109  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
110}
111
112
113/**
114 * @brief destructs the spacecraft_2d, deletes alocated memory
115 */
116Spacecraft2D::~Spacecraft2D ()
117{
118  this->setPlayer(NULL);
119  delete this->toTravelHeight;
120}
121
122
123/**
124 * @brief initializes a Spacecraft2D
125 */
126void Spacecraft2D::init()
127{
128  //  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
129  this->registerObject(this, Spacecraft2D::_objectList);
130
131  this->setSupportedPlaymodes(Playable::Full3D | Playable::Horizontal );
132
133  bForward = bBackward = bLeft = bRight = false;
134  mouseSensitivity = 0.005;
135
136  this->cameraLook = 0.0f;
137  this->rotation = 0.0f;
138  this->acceleration = 20.0f;
139  this->airFriction = 0.0f;
140
141
142  this->setHealthMax(1000);
143  this->setHealth(1000);
144  this->setDamage(100.0f);
145
146
147
148  /// 2D-MODE
149  this->toTravelHeight = NULL;
150  this->travelSpeed = 0.0f;
151  this->travelNode = new PNode();
152
153  this->loadModel("models/ships/mantawing.obj", 5.0f);
154
155  // camera - issue
156  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
157  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
158  //this->cameraNode.setParentMode(PNODE_ROTATE_MOVEMENT);
159  //this->cameraNode.setParent(this);
160
161  // PARTICLES
162  this->burstEmitter = new DotEmitter(200, 5.0, .01);
163  this->burstEmitter->setParent(this);
164  this->burstEmitter->setRelCoor(0, -0.7, 0);
165  this->burstEmitter->setRelDir(Quaternion(-M_PI, Vector(0,0,1)));
166  this->burstEmitter->setName("Spacecraft2D_Burst_emitter_Left");
167
168  this->burstSystem = new SpriteParticles(1000);
169  this->burstSystem->addEmitter(this->burstEmitter);
170  this->burstSystem->setName("SpaceShip_Burst_System");
171  ((SpriteParticles*)this->burstSystem)->setMaterialTexture("maps/radial-trans-noise.png");
172  this->burstSystem->setLifeSpan(1.0, .3);
173  this->burstSystem->setRadius(0.0, 1.5);
174  this->burstSystem->setRadius(0.05, 1.8);
175  this->burstSystem->setRadius(.5, .8);
176  this->burstSystem->setRadius(1.0, 0);
177  this->burstSystem->setColor(0.0, .7,.7,1,.5);
178  this->burstSystem->setColor(0.2, 0,0,0.8,.5);
179  this->burstSystem->setColor(0.5, .5,.5,.8,.3);
180  this->burstSystem->setColor(1.0, .8,.8,.8,.0);
181
182
183  //add events to the eventlist of the Playable
184  this->registerEvent(KeyMapper::PEV_FORWARD);
185  this->registerEvent(KeyMapper::PEV_BACKWARD);
186  this->registerEvent(KeyMapper::PEV_LEFT);
187  this->registerEvent(KeyMapper::PEV_RIGHT);
188  this->registerEvent(KeyMapper::PEV_FIRE1);
189  this->registerEvent(KeyMapper::PEV_NEXT_WEAPON);
190  this->registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON);
191  this->registerEvent(EV_MOUSE_MOTION);
192
193  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
194
195  // WEAPON_MANAGER configuration
196  this->getWeaponManager().setSlotCount(5);
197
198  this->getWeaponManager().setSlotPosition(0, Vector(1.843, -0.335, 2.029) * 5.0);
199  this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
200
201  this->getWeaponManager().setSlotPosition(1, Vector(1.843, -0.335, -2.029) * 5.0);
202  this->getWeaponManager().setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
203
204  /// TODO: THESE ARE TOO MUCH
205  this->getWeaponManager().setSlotPosition(2, Vector(-0.351, -.238, 1.406) * 5.0);
206  this->getWeaponManager().setSlotDirection(2, Quaternion(-1.7, Vector(0,1,0)));
207
208  this->getWeaponManager().setSlotPosition(3, Vector(-0.351, -.238, -1.406) * 5.0);
209  this->getWeaponManager().setSlotDirection(3, Quaternion(1.7, Vector(0,1,0)));
210
211  this->cameraNode.setRelCoor(1,5,0);
212  this->getWeaponManager().getFixedTarget()->setParent(&this->cameraNode);
213  this->getWeaponManager().getFixedTarget()->setRelCoor(1000,0,0);
214
215  registerVar( new SynchronizeableBool( &bForward, &bForward, "bForward", PERMISSION_OWNER ) );
216  registerVar( new SynchronizeableBool( &bBackward, &bBackward, "bBackward", PERMISSION_OWNER ) );
217  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
218  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
219  //registerVar( new SynchronizeableQuaternion( &direction, &direction, "direction", PERMISSION_OWNER ) );
220  registerVar( new SynchronizeableFloat( &cameraLook, &cameraLook, "cameraLook", PERMISSION_OWNER ) );
221  registerVar( new SynchronizeableFloat( &rotation, &rotation, "rotation", PERMISSION_OWNER ) );
222
223  this->setDamage( 1000.0f);
224  this->subscribeReaction(CoRe::CREngine::CR_OBJECT_DAMAGE, WorldEntity::staticClassID());
225
226}
227
228/**
229 * @brief loads the Settings of a Spacecraft2D from an XML-element.
230 * @param root the XML-element to load the Spaceship's properties from
231 */
232void Spacecraft2D::loadParams(const TiXmlElement* root)
233{
234  Playable::loadParams(root);
235
236  LoadParam(root, "travel-speed", this, Spacecraft2D, setTravelSpeed);
237  LoadParam(root, "travel-height", this, Spacecraft2D, setTravelHeight);
238  LoadParam(root, "travel-distance", this, Spacecraft2D, setTravelDistance);
239}
240
241void Spacecraft2D::setPlayDirection(const Quaternion& rot, float speed)
242{
243  this->direction = Quaternion (rot.getHeading(), Vector(0,1,0));
244}
245
246void Spacecraft2D::setTravelSpeed(float travelSpeed)
247{
248  this->travelSpeed = travelSpeed;
249}
250
251
252void Spacecraft2D::setTravelHeight(float travelHeight)
253{
254  if (this->toTravelHeight == NULL)
255    this->toTravelHeight = new float;
256  *this->toTravelHeight = travelHeight;
257}
258
259
260void Spacecraft2D::setTravelDistance(const Vector2D& distance)
261{
262  this->travelDistance = distance;
263}
264
265void Spacecraft2D::setTravelDistance(float x, float y)
266{
267  this->setTravelDistance(Vector2D(x, y));
268}
269
270
271
272void Spacecraft2D::enter()
273{
274  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( true);
275  this->setPlaymode(this->getPlaymode());
276}
277
278void Spacecraft2D::leave()
279{
280  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
281  this->detachCamera();
282
283}
284
285
286void Spacecraft2D::enterPlaymode(Playable::Playmode playmode)
287{
288  switch(playmode)
289  {
290    case Playable::Full3D:
291      if (State::getCameraNode != NULL)
292      {
293        Vector absCoor = this->getAbsCoor();
294        this->setParent(PNode::getNullParent());
295        this->setAbsCoor(absCoor);
296        State::getCameraNode()->setParentSoft(&this->cameraNode);
297        State::getCameraNode()->setRelCoorSoft(-10, 0,0);
298        State::getCameraTargetNode()->setParentSoft(&this->cameraNode);
299        State::getCameraTargetNode()->setRelCoorSoft(100, 0,0);
300
301      }
302      break;
303
304
305    case Playable::Horizontal:
306      if (State::getCameraNode != NULL)
307      {
308        this->debugNode(1);
309        this->travelNode->debugNode(1);
310
311        this->travelNode->setAbsCoor(this->getAbsCoor());
312        this->travelNode->updateNode(0.01f);
313
314        this->setParent(this->travelNode);
315        this->setRelCoor(0,0,0);
316
317        State::getCameraNode()->setParentSoft(this->travelNode);
318        State::getCameraNode()->setRelCoorSoft(-3, 100,0);
319        State::getCameraTargetNode()->setParentSoft(this->travelNode);
320        State::getCameraTargetNode()->setRelCoorSoft(5,0,1);
321
322
323        this->debugNode(1);
324        this->travelNode->debugNode(1);
325      }
326      break;
327
328    default:
329      PRINTF(2)("Playmode %s Not Implemented in %s\n", Playable::playmodeToString(this->getPlaymode()).c_str(), this->getClassCName());
330  }
331}
332
333
334
335/**
336 * @brief effect that occurs after the Spacecraft2D is spawned
337*/
338void Spacecraft2D::postSpawn ()
339{
340  //setCollision(new CollisionCluster(1.0, Vector(0,0,0)));
341}
342
343/**
344 * @brief the action occuring if the spacecraft_2d left the game
345*/
346void Spacecraft2D::leftWorld ()
347{}
348
349/**
350 * @brief this function is called, when two entities collide
351 * @param entity: the world entity with whom it collides
352 *
353 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
354 */
355void Spacecraft2D::collidesWith(WorldEntity* entity, const Vector& location)
356{
357  Playable::collidesWith(entity, location);
358}
359
360
361
362/**
363 * @brief the function called for each passing timeSnap
364 * @param time The timespan passed since last update
365*/
366void Spacecraft2D::tick (float dt)
367{
368  //  this->debugNode(1);
369  Playable::tick(dt);
370
371  // spaceship controlled movement
372  this->movement(dt);
373
374  // TRYING TO FIX PNode.
375  this->cameraNode.setAbsCoorSoft(this->getAbsCoor() + Vector(0.0f, 5.0f, 0.0f), 30.0f);
376  this->cameraNode.setRelDirSoft(this->getAbsDir(), 30.0f);
377}
378
379/**
380 * @brief calculate the velocity
381 * @param time the timeslice since the last frame
382*/
383void Spacecraft2D::movement (float dt)
384{
385  Vector accel(0.0, 0.0, 0.0);
386
387  if( this->bForward )
388  {
389    accel += Vector(this->acceleration, 0, 0);
390  }
391
392  if( this->bBackward )
393  {
394    accel -= Vector(this->acceleration, 0, 0);
395  }
396  if( this->bLeft)
397  {
398    accel -= Vector(0, 0, this->acceleration);
399  }
400
401  if( this->bRight)
402  {
403    accel += Vector(0, 0, this->acceleration);
404  }
405
406  switch(this->getPlaymode())
407  {
408    case Playable::Full3D:
409      {
410        Vector accelerationDir = this->getAbsDir().apply(accel * this->acceleration);
411
412        // this is the air friction (necessary for a smooth control)
413        Vector damping = (this->velocity * this->airFriction);
414
415
416        this->velocity += (accelerationDir - damping)* dt;
417        this->shiftCoor (this->velocity * dt);
418
419        // limit the maximum rotation speed.
420        if (this->rotation != 0.0f)
421        {
422          float maxRot = 10.0 * dt;
423          if (unlikely(this->rotation > maxRot)) this->rotation = maxRot;
424          if (unlikely(this->rotation < -maxRot)) this->rotation = -maxRot;
425          this->direction *= Quaternion(-M_PI/4.0*this->rotation, Vector(0,1,0));
426
427          this->rotation = 0.0f;
428        }
429
430        this->setRelDirSoft(this->direction * Quaternion(-cameraLook, Vector(0,0,1)), 5);
431      }
432      break;
433
434    case Playable::Horizontal:
435      {
436
437        if (this->toTravelHeight != NULL)
438        {
439          this->travelNode->shiftCoor(Vector(0, (*toTravelHeight - this->travelNode->getAbsCoor().y) * dt * 10.0, 0));
440          if (fabsf(this->travelNode->getAbsCoor().y - *this->toTravelHeight) < .1)
441          {
442            delete this->toTravelHeight;
443            this->toTravelHeight = NULL;
444          }
445        }
446        this->travelNode->shiftCoor(Vector(this->travelSpeed * dt, 0, 0));
447
448        accel.y = 0.0;
449
450        Vector accelerationDir = this->getAbsDir().apply(accel * this->acceleration);
451        accelerationDir.y = 0.0;
452
453        // this is the air friction (necessary for a smooth control)
454        Vector damping = (this->velocity * this->airFriction);
455
456
457        this->velocity += (accelerationDir - damping)* dt;
458
459        if (this->getRelCoor().z > this->travelDistance.y && velocity.z > 0.0)
460          this->velocity.z = 0.0f;
461        if (this->getRelCoor().z < -this->travelDistance.y && velocity.z < 0.0)
462          this->velocity.z = 0.0f;
463
464        if (this->getRelCoor().x > this->travelDistance.x && velocity.x > 0.0)
465          this->velocity.x = 0.0f;
466        if (this->getRelCoor().x < -this->travelDistance.x && velocity.x < 0.0)
467          this->velocity.x = 0.0f;
468
469
470        this->shiftCoor (this->velocity * dt);
471        if (accel.z == 0)
472          this->setRelDirSoft(Quaternion(0, Vector(0,0,0)), 5.0f);
473        else
474          this->setRelDirSoft(Quaternion(this->velocity.z * .004, Vector(1,0,0)), 4.5f);
475      }
476      break;
477
478    default:
479      PRINTF(2)("Playmode %s Not Implemented in %s\n", Playable::playmodeToString(this->getPlaymode()).c_str(), this->getClassCName());
480  }
481}
482
483
484void Spacecraft2D::draw() const
485{
486  WorldEntity::draw();
487}
488
489/**
490 * @todo switch statement ??
491 */
492void Spacecraft2D::process(const Event &event)
493{
494  Playable::process(event);
495
496  if( event.type == KeyMapper::PEV_LEFT)
497    this->bLeft = event.bPressed;
498  else if( event.type == KeyMapper::PEV_RIGHT)
499    this->bRight = event.bPressed;
500  else if( event.type == KeyMapper::PEV_FORWARD)
501    this->bForward = event.bPressed; //this->shiftCoor(0,.1,0);
502  else if( event.type == KeyMapper::PEV_BACKWARD)
503  {this->bBackward = event.bPressed; printf(" %f, %f, %f \n",getAbsCoorX(),getAbsCoorY(),getAbsCoorZ());} //this->shiftCoor(0,-.1,0);
504  else if( event.type == EV_MOUSE_MOTION)
505  {
506
507
508
509    if (this->getPlaymode() == Playable::Full3D)
510    {
511      float xMouse, yMouse;
512      xMouse = event.xRel*mouseSensitivity;
513      yMouse = event.yRel*mouseSensitivity;
514
515      // rotate the Player around the y-axis
516      this->rotation += xMouse;
517
518      this->cameraLook += yMouse;
519      // rotate the Camera around the z-axis
520      if (cameraLook > M_PI_4)
521        cameraLook = M_PI_4;
522      else if (cameraLook < -M_PI_4)
523        cameraLook = -M_PI_4;
524    }
525  }
526}
Note: See TracBrowser for help on using the repository browser.