Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

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

File size: 7.7 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004-2006 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: Marc Schaerrer, Nicolas Schlumberger
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"
24#include "space_ships/space_ship.h"
25#include "effects/trail.h"
26
27#include "debug.h"
28
29
30
31#include "math/vector.h"
32
33ObjectListDefinition(SwarmProjectile);
34CREATE_FAST_FACTORY_STATIC(SwarmProjectile);
35
36/**
37 *  standard constructor
38*/
39SwarmProjectile::SwarmProjectile () : Projectile()
40{
41  this->loadModel("models/projectiles/swarm_projectile.obj", .333); // no double rescale (see draw())
42  this->loadExplosionSound("sounds/explosions/explosion_4.wav");
43
44
45  this->setMinEnergy(1);
46  this->setHealthMax(10);
47  this->lifeSpan = 4.0;
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);
53
54  this->turningSpeed = 10;
55
56  this->physDamage = 200;
57  this->elecDamage = 0;
58
59  this->trail = new Trail(2.5, 4, .2, this);
60  this->trail->setTexture( "textures/laser.png");
61
62//   this->maxVelocity = 300;
63
64  this->smoke = new Trail(20, 10, .3, this);
65  this->smoke->setTexture ("textures/engine.png");
66
67  this->angle = 0;
68
69
70
71  this->origList = this->getOMListNumber();
72  this->toList(OM_ENVIRON);
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  }
88  // delete this->emitter;
89  delete this->trail;
90  delete this->smoke;
91}
92
93SpriteParticles* SwarmProjectile::explosionParticles = NULL;
94
95
96
97void SwarmProjectile::activate()
98{
99  this->toList(OM_ENVIRON);
100  if (unlikely(SwarmProjectile::explosionParticles == NULL))
101  {
102    SwarmProjectile::explosionParticles = new SpriteParticles(200);
103    SwarmProjectile::explosionParticles->setName("SwarmProjectileExplosionParticles");
104    SwarmProjectile::explosionParticles->setMaterialTexture("textures/radial-trans-noise.png");
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
115  this->emitter->setEmissionRate(50.0);
116  this->emitter->setEmissionVelocity(0.0);
117  this->emitter->setInheritSpeed(0);
118
119  this->setHealth(10.0* (float)rand()/(float)RAND_MAX);
120
121//   this->maxVelocity = 300;
122
123//   this->rotationSpeed = 360;
124  this->angle = 0;
125
126  this->curDir = this->lastDir = this->velocity;
127}
128
129
130void SwarmProjectile::deactivate()
131{
132  this->emitter->setSystem(NULL);
133  this->lifeCycle = 0.0;
134
135  this->toList(OM_DEAD);
136//   this->removeNode();
137  SwarmProjectile::fastFactory->kill(this);
138}
139
140
141void SwarmProjectile::hit (WorldEntity* entity, float damage)
142{
143  if (this->hitEntity != entity)
144    this->destroy( entity );
145  this->hitEntity = entity;
146  //dynamic_cast<SpaceShip*>(entity)->damage(this->getPhysDamage(),this->getElecDamage());
147 // this->destroy(this);
148  this->deactivate();
149}
150
151
152void SwarmProjectile::setTarget(PNode* target)
153{
154    this->target = target;
155}
156
157
158
159/**
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{
168  if (unlikely(curDirection.len() == 0))
169    return curDirection;
170  //printf("recalculating direction\n");
171  float tmp = angleRad ( curDirection, estTargetDir);
172  if ( unlikely(tmp == 0) ) { return curDirection * maxVelocity / curDirection.len(); }
173//   printf("turning angle: %f\ntemp: %f\n", angle, tmp);
174
175  if( fabsf(angle) >  fabsf(tmp) )
176    angle = tmp;
177  else
178    angle *= tmp/fabsf(tmp);
179
180  Vector d = curDirection.cross(estTargetDir).cross(curDirection);
181  d.normalize();
182  if( unlikely( fabsf(angle) == 90)) { return d; } //avoid complication
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/**
194 *  signal tick, time dependent things will be handled here
195 * @param time since last tick
196*/
197void SwarmProjectile::tick (float time)
198{
199  if(unlikely(this->target == NULL)) /** Check whether the target still exists*/
200    this->deactivate();
201
202
203
204/** old  guiding function*/
205
206  static float projectileVelocity = this->getVelocity().len();
207  if (target != NULL){
208    static Vector estTargetDir = (this->target->getAbsCoor() - this->getAbsCoor()).getNormalized();
209    this->velocity = this->newDirection(this->velocity, estTargetDir, this->turningSpeed * time );
210  }
211  else
212    if (likely(projectileVelocity != 0 || projectileVelocity != this->maxVelocity) )
213      this->velocity *= (this->maxVelocity / projectileVelocity); // set speed to max
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);*/
217
218  this->shiftCoor(this->velocity * time);
219
220  if(this->tickLifeCycle(time))
221    this->deactivate();
222
223  this->trail->tick(time);
224  this->smoke->tick(time);
225
226  this->angle += this->rotationSpeed * time;
227
228  while (this->angle > 360)
229  {
230    this->angle -= 360;
231  }
232
233  this->lastDir = this->curDir;
234  this->curDir = this->velocity;
235
236  if( this->target != NULL && (this->getAbsCoor() - this->target->getAbsCoor()).len() < 3)   // HACK  Temp fake workaround for collision :)
237  {
238    dynamic_cast<WorldEntity*>(target)->destroy(this); //hit(this->getDamage(), this);
239    this->deactivate();
240    PRINTF(0)("Target was hit by Swarm Missile!\n");
241  }
242  else if( this->target == NULL)
243    this->deactivate();
244}
245
246/**
247 *  the function gets called, when the projectile is destroyed
248 */
249void SwarmProjectile::destroy (WorldEntity* killer)
250{
251
252//   printf("THIS SHOULD WORK!\n");
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);
261  this->deactivate();
262
263}
264
265
266void SwarmProjectile::draw () const
267{
268  glMatrixMode(GL_MODELVIEW);
269  glPushMatrix();
270
271  Vector tmpDir = this->curDir; // *.7 + this->lastDir * .3;
272  tmpDir.slerpTo(this->lastDir, .4);
273
274  float matrix[4][4];
275  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
276  Vector tmpRot = this->getAbsCoor().cross(tmpDir);
277  glRotatef (angleDeg ( this->getAbsCoor(), tmpDir), tmpRot.x, tmpRot.y, tmpRot.z );
278  glRotatef(this->angle, 1.0f, 0.0f, 0.0f); //spinning missile
279  this->getAbsDir().matrix (matrix);
280  glMultMatrixf((float*)matrix);
281  this->getModel()->draw();
282  glTranslatef(-.9,0,0);
283  this->trail->draw();
284  glTranslatef( -1.1, 0, 0);
285  this->smoke->draw();
286  glPopMatrix();
287}
Note: See TracBrowser for help on using the repository browser.