Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/vs-enhencements/src/world_entities/projectiles/swarm_projectile.cc @ 10670

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

moved "ship attributes" to world entity
electronic and shield widget not yet working

File size: 7.7 KB
RevLine 
[10004]1/*
2   orxonox - the future of 3D-vertical-scrollers
3
[10104]4   Copyright (C) 2004-2006 orx
[10004]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
[10104]12   main-programmer: Marc Schaerrer, Nicolas Schlumberger
[10004]13   co-programmer:
14
15*/
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
17
18#include "swarm_projectile.h"
19
20#include "state.h"
21
22#include "particles/dot_emitter.h"
23#include "particles/sprite_particles.h"
[10064]24#include "space_ships/space_ship.h"
[10081]25#include "effects/trail.h"
[10004]26
27#include "debug.h"
28
29
[10366]30
[10079]31#include "math/vector.h"
32
[10366]33ObjectListDefinition(SwarmProjectile);
[10004]34CREATE_FAST_FACTORY_STATIC(SwarmProjectile);
35
36/**
37 *  standard constructor
38*/
39SwarmProjectile::SwarmProjectile () : Projectile()
40{
[10618]41  this->loadModel("models/projectiles/swarm_projectile.obj", .333); // no double rescale (see draw())
[10415]42  this->loadExplosionSound("sounds/explosions/explosion_4.wav");
[10004]43
44
45  this->setMinEnergy(1);
46  this->setHealthMax(10);
[10064]47  this->lifeSpan = 4.0;
[10004]48  this->agility = 3.5;
49
50  this->emitter = new DotEmitter(100, 5, M_2_PI);
51  this->emitter->setParent(this);
52  this->emitter->setSpread(M_PI, M_PI);
[10037]53
[10132]54  this->turningSpeed = 10;
[10080]55
56  this->physDamage = 200;
[10104]57  this->elecDamage = 0;
[10081]58
[10618]59  this->trail = new Trail(2.5, 4, .2, this);
[10420]60  this->trail->setTexture( "textures/laser.png");
[10345]61
[10618]62//   this->maxVelocity = 300;
[10345]63
[10618]64  this->smoke = new Trail(20, 10, .3, this);
65  this->smoke->setTexture ("textures/engine.png");
66
67  this->angle = 0;
68
69
70
[10345]71  this->origList = this->getOMListNumber();
72  this->toList(OM_ENVIRON);
[10004]73}
74
75
76/**
77 *  standard deconstructor
78*/
79SwarmProjectile::~SwarmProjectile ()
80{
81
82  if (SwarmProjectile::explosionParticles != NULL && SwarmProjectile::objectList().size() <= 1)
83  {
84    if (ParticleSystem::objectList().exists(SwarmProjectile::explosionParticles))
85      delete SwarmProjectile::explosionParticles;
86    SwarmProjectile::explosionParticles = NULL;
87  }
[10081]88  // delete this->emitter;
89  delete this->trail;
[10618]90  delete this->smoke;
[10004]91}
92
93SpriteParticles* SwarmProjectile::explosionParticles = NULL;
94
95
96
97void SwarmProjectile::activate()
98{
[10168]99  this->toList(OM_ENVIRON);
[10004]100  if (unlikely(SwarmProjectile::explosionParticles == NULL))
101  {
102    SwarmProjectile::explosionParticles = new SpriteParticles(200);
[10073]103    SwarmProjectile::explosionParticles->setName("SwarmProjectileExplosionParticles");
[10420]104    SwarmProjectile::explosionParticles->setMaterialTexture("textures/radial-trans-noise.png");
[10004]105    SwarmProjectile::explosionParticles->setLifeSpan(.5, .3);
106    SwarmProjectile::explosionParticles->setRadius(0.0, 10);
107    SwarmProjectile::explosionParticles->setRadius(.5, 15.0);
108    SwarmProjectile::explosionParticles->setRadius(1.0, 10.0);
109    SwarmProjectile::explosionParticles->setColor(0.0, 0,1,0,1);
110    SwarmProjectile::explosionParticles->setColor(0.5, .8,.8,0,.8);
111    SwarmProjectile::explosionParticles->setColor(0.8, .8,.8,.3,.8);
112    SwarmProjectile::explosionParticles->setColor(1.0, 1,1,1,.0);
113  }
114
[10078]115  this->emitter->setEmissionRate(50.0);
[10004]116  this->emitter->setEmissionVelocity(0.0);
[10078]117  this->emitter->setInheritSpeed(0);
[10004]118
119  this->setHealth(10.0* (float)rand()/(float)RAND_MAX);
[10079]120
[10618]121//   this->maxVelocity = 300;
[10079]122
[10618]123//   this->rotationSpeed = 360;
[10079]124  this->angle = 0;
[10087]125
126  this->curDir = this->lastDir = this->velocity;
[10004]127}
128
129
130void SwarmProjectile::deactivate()
131{
132  this->emitter->setSystem(NULL);
133  this->lifeCycle = 0.0;
134
135  this->toList(OM_DEAD);
[10649]136//   this->removeNode();
[10004]137  SwarmProjectile::fastFactory->kill(this);
138}
139
140
[10261]141void SwarmProjectile::hit (WorldEntity* entity, float damage)
[10004]142{
143  if (this->hitEntity != entity)
144    this->destroy( entity );
145  this->hitEntity = entity;
[10117]146  //dynamic_cast<SpaceShip*>(entity)->damage(this->getPhysDamage(),this->getElecDamage());
[10261]147 // this->destroy(this);
148  this->deactivate();
[10004]149}
150
[10035]151
[10080]152void SwarmProjectile::setTarget(PNode* target)
153{
154    this->target = target;
155}
[10035]156
[10080]157
158
[10004]159/**
[10035]160 *  this function gets called by tick to calculate the new flight direction
161 *  @param curDirection direction vector
162 *  @param estTargetDir target vector, pointing to where the target will be on hit
163 *  @param angle = tick * turningSpeed
164 *  @return (new) direction vector
165*/
166Vector SwarmProjectile::newDirection(Vector curDirection, Vector estTargetDir, float angle)
167{
[10038]168  if (unlikely(curDirection.len() == 0))
169    return curDirection;
[10080]170  //printf("recalculating direction\n");
171  float tmp = angleRad ( curDirection, estTargetDir);
[10035]172  if ( unlikely(tmp == 0) ) { return curDirection * maxVelocity / curDirection.len(); }
[10080]173//   printf("turning angle: %f\ntemp: %f\n", angle, tmp);
[10035]174
[10366]175  if( fabsf(angle) >  fabsf(tmp) )
[10132]176    angle = tmp;
177  else
178    angle *= tmp/fabsf(tmp);
[10035]179
180  Vector d = curDirection.cross(estTargetDir).cross(curDirection);
181  d.normalize();
[10132]182  if( unlikely( fabsf(angle) == 90)) { return d; } //avoid complication
[10035]183
184  Vector newDir = curDirection + d *  curDirection.len() * tan (angle);
185  newDir.normalize();
186  newDir *= curDirection.len();
187  return newDir;
188}
189
190
191
192
193/**
[10004]194 *  signal tick, time dependent things will be handled here
195 * @param time since last tick
196*/
197void SwarmProjectile::tick (float time)
198{
[10196]199  if(unlikely(this->target == NULL)) /** Check whether the target still exists*/
200    this->deactivate();
201
[10004]202
203
[10271]204/** old  guiding function*/
[10153]205
[10670]206  static float projectileVelocity = this->getVelocity().len();
[10087]207  if (target != NULL){
[10670]208    static Vector estTargetDir = (this->target->getAbsCoor() - this->getAbsCoor()).getNormalized();
[10080]209    this->velocity = this->newDirection(this->velocity, estTargetDir, this->turningSpeed * time );
[10087]210  }
211  else
[10104]212    if (likely(projectileVelocity != 0 || projectileVelocity != this->maxVelocity) )
[10087]213      this->velocity *= (this->maxVelocity / projectileVelocity); // set speed to max
[10271]214/*
215  printf("position: %f, %f, %f\n", this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z);
216  printf("target position: %f, %f, %f\n", this->target->getAbsCoor().x, this->target->getAbsCoor().y, this->target->getAbsCoor().z);*/
[10035]217
[10153]218  this->shiftCoor(this->velocity * time);
[10080]219
[10004]220  if(this->tickLifeCycle(time))
221    this->deactivate();
[10037]222
[10087]223  this->trail->tick(time);
[10618]224  this->smoke->tick(time);
[10081]225
[10087]226  this->angle += this->rotationSpeed * time;
[10618]227
[10188]228  while (this->angle > 360)
[10618]229  {
[10188]230    this->angle -= 360;
[10618]231  }
[10087]232
233  this->lastDir = this->curDir;
234  this->curDir = this->velocity;
[10345]235
[10545]236  if( this->target != NULL && (this->getAbsCoor() - this->target->getAbsCoor()).len() < 3)   // HACK  Temp fake workaround for collision :)
[10095]237  {
[10539]238    dynamic_cast<WorldEntity*>(target)->destroy(this); //hit(this->getDamage(), this);
[10345]239    this->deactivate();
[10539]240    PRINTF(0)("Target was hit by Swarm Missile!\n");
[10168]241  }
[10539]242  else if( this->target == NULL)
243    this->deactivate();
[10004]244}
245
246/**
247 *  the function gets called, when the projectile is destroyed
248 */
249void SwarmProjectile::destroy (WorldEntity* killer)
250{
251
[10109]252//   printf("THIS SHOULD WORK!\n");
[10004]253
254  Projectile::destroy( killer );
255  PRINTF(5)("DESTROY SwarmProjectile\n");
256  this->lifeCycle = .95; //!< @todo calculate this usefully.
257  this->emitter->setSystem(SwarmProjectile::explosionParticles);
258
259  this->emitter->setEmissionRate(1000.0);
260  this->emitter->setEmissionVelocity(50.0);
[10073]261  this->deactivate();
[10004]262
263}
264
265
266void SwarmProjectile::draw () const
267{
268  glMatrixMode(GL_MODELVIEW);
269  glPushMatrix();
270
[10132]271  Vector tmpDir = this->curDir; // *.7 + this->lastDir * .3;
272  tmpDir.slerpTo(this->lastDir, .4);
[10087]273
[10004]274  float matrix[4][4];
275  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
[10087]276  Vector tmpRot = this->getAbsCoor().cross(tmpDir);
[10547]277  glRotatef (angleDeg ( this->getAbsCoor(), tmpDir), tmpRot.x, tmpRot.y, tmpRot.z );
[10037]278  glRotatef(this->angle, 1.0f, 0.0f, 0.0f); //spinning missile
[10004]279  this->getAbsDir().matrix (matrix);
280  glMultMatrixf((float*)matrix);
281  this->getModel()->draw();
[10081]282  glTranslatef(-.9,0,0);
283  this->trail->draw();
[10618]284  glTranslatef( -1.1, 0, 0);
285  this->smoke->draw();
[10004]286  glPopMatrix();
287}
Note: See TracBrowser for help on using the repository browser.