Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/playability/src/world_entities/projectiles/swarm_projectile.cc @ 10180

Last change on this file since 10180 was 10168, checked in by marcscha, 17 years ago

Acid Launcher and Acid Splash (projectile) finished.
Temporally dist check instead of collision on swarm projectile (collision manager problem which needs to be tracked down first)

File size: 9.0 KB
Line 
1
2/*
3   orxonox - the future of 3D-vertical-scrollers
4
5   Copyright (C) 2004-2006 orx
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2, or (at your option)
10   any later version.
11
12   ### File Specific
13   main-programmer: Marc Schaerrer, Nicolas Schlumberger
14   co-programmer:
15
16*/
17#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
18
19#include "swarm_projectile.h"
20
21#include "state.h"
22
23#include "particles/dot_emitter.h"
24#include "particles/sprite_particles.h"
25#include "space_ships/space_ship.h"
26#include "effects/trail.h"
27
28#include "debug.h"
29
30#include "class_id_DEPRECATED.h"
31
32#include "math/vector.h"
33
34ObjectListDefinitionID(SwarmProjectile, CL_SWARM_PROJECTILE);
35CREATE_FAST_FACTORY_STATIC(SwarmProjectile);
36
37/**
38 *  standard constructor
39*/
40SwarmProjectile::SwarmProjectile () : Projectile()
41{
42
43/*  this->loadModel("models/projectiles/orx-rocket.obj", 0.5);*/
44  this->loadModel("models/projectiles/swarm_projectile.obj"); // no double rescale (see draw())
45  this->loadExplosionSound("sound/explosions/explosion_4.wav");
46
47
48  this->setMinEnergy(1);
49  this->setHealthMax(10);
50  this->lifeSpan = 4.0;
51  this->agility = 3.5;
52
53  this->emitter = new DotEmitter(100, 5, M_2_PI);
54  this->emitter->setParent(this);
55  this->emitter->setSpread(M_PI, M_PI);
56
57  this->turningSpeed = 10;
58
59  this->physDamage = 200;
60  this->elecDamage = 0;
61
62  this->trail = new Trail(2.5,4,.2, this);
63  //this->trail->setParent( this);
64  this->trail->setTexture( "maps/laser.png");
65}
66
67
68/**
69 *  standard deconstructor
70*/
71SwarmProjectile::~SwarmProjectile ()
72{
73
74  if (SwarmProjectile::explosionParticles != NULL && SwarmProjectile::objectList().size() <= 1)
75  {
76    if (ParticleSystem::objectList().exists(SwarmProjectile::explosionParticles))
77      delete SwarmProjectile::explosionParticles;
78    SwarmProjectile::explosionParticles = NULL;
79  }
80  // delete this->emitter;
81  delete this->trail;
82}
83
84SpriteParticles* SwarmProjectile::explosionParticles = NULL;
85
86
87
88void SwarmProjectile::activate()
89{
90  this->toList(OM_ENVIRON);
91  if (unlikely(SwarmProjectile::explosionParticles == NULL))
92  {
93    SwarmProjectile::explosionParticles = new SpriteParticles(200);
94    SwarmProjectile::explosionParticles->setName("SwarmProjectileExplosionParticles");
95    SwarmProjectile::explosionParticles->setMaterialTexture("maps/radial-trans-noise.png");
96    SwarmProjectile::explosionParticles->setLifeSpan(.5, .3);
97    SwarmProjectile::explosionParticles->setRadius(0.0, 10);
98    SwarmProjectile::explosionParticles->setRadius(.5, 15.0);
99    SwarmProjectile::explosionParticles->setRadius(1.0, 10.0);
100    SwarmProjectile::explosionParticles->setColor(0.0, 0,1,0,1);
101    SwarmProjectile::explosionParticles->setColor(0.5, .8,.8,0,.8);
102    SwarmProjectile::explosionParticles->setColor(0.8, .8,.8,.3,.8);
103    SwarmProjectile::explosionParticles->setColor(1.0, 1,1,1,.0);
104  }
105
106  this->emitter->setEmissionRate(50.0);
107  this->emitter->setEmissionVelocity(0.0);
108  this->emitter->setInheritSpeed(0);
109
110  this->setHealth(10.0* (float)rand()/(float)RAND_MAX);
111
112  this->maxVelocity = 300;
113
114  this->rotationSpeed = 360;
115  this->angle = 0;
116
117  this->curDir = this->lastDir = this->velocity;
118}
119
120
121void SwarmProjectile::deactivate()
122{
123  this->emitter->setSystem(NULL);
124  this->lifeCycle = 0.0;
125
126  this->toList(OM_DEAD);
127  this->removeNode();
128  SwarmProjectile::fastFactory->kill(this);
129}
130
131
132void SwarmProjectile::collidesWith(WorldEntity* entity, const Vector& location)
133{
134  if (this->hitEntity != entity)
135    this->destroy( entity );
136  this->hitEntity = entity;
137  //dynamic_cast<SpaceShip*>(entity)->damage(this->getPhysDamage(),this->getElecDamage());
138  this->destroy(this);
139}
140
141
142void SwarmProjectile::setTarget(PNode* target)
143{
144    this->target = target;
145}
146
147
148
149/**
150 *  this function gets called by tick to calculate the new flight direction
151 *  @param curDirection direction vector
152 *  @param estTargetDir target vector, pointing to where the target will be on hit
153 *  @param angle = tick * turningSpeed
154 *  @return (new) direction vector
155*/
156Vector SwarmProjectile::newDirection(Vector curDirection, Vector estTargetDir, float angle)
157{
158  if (unlikely(curDirection.len() == 0))
159    return curDirection;
160  //printf("recalculating direction\n");
161  float tmp = angleRad ( curDirection, estTargetDir);
162  if ( unlikely(tmp == 0) ) { return curDirection * maxVelocity / curDirection.len(); }
163//   printf("turning angle: %f\ntemp: %f\n", angle, tmp);
164
165  if( fabsf(angle) >  fabsf(tmp) ) 
166    angle = tmp;
167  else
168    angle *= tmp/fabsf(tmp);
169
170  Vector d = curDirection.cross(estTargetDir).cross(curDirection);
171  d.normalize();
172  if( unlikely( fabsf(angle) == 90)) { return d; } //avoid complication
173
174  Vector newDir = curDirection + d *  curDirection.len() * tan (angle);
175  newDir.normalize();
176  newDir *= curDirection.len();
177  return newDir;
178}
179
180
181
182
183/**
184 *  signal tick, time dependent things will be handled here
185 * @param time since last tick
186*/
187void SwarmProjectile::tick (float time)
188{
189/*
190  Vector targetFarFarAway = this->getAbsCoor() + Vector(100000, 0, 0);
191
192  {
193    speed = velocity.len();
194    diffVector = ((targetFarFarAway - this->getAbsCoor()).getNormalized());
195
196    if(velocity.dot(diffVector) != 0)
197    {
198      correctionVector = (( ( diffVector *  (speed * speed/( velocity.dot(diffVector ) ) )) - velocity).getNormalized()) * agility;
199
200      if( (diffVector *  (speed * speed/( velocity.dot(diffVector ) ) ) -velocity).len() < agility )
201        velocity = ((diffVector *  (speed * speed/( velocity.dot(diffVector ) ) )).getNormalized())*agility;
202      else if(velocity.dot(diffVector) > 0)
203        velocity += correctionVector;
204      else if (velocity.dot(diffVector) < 0)
205        velocity -= correctionVector;
206    }
207    else
208      velocity += diffVector * agility;
209
210    this->setAbsDir(Quaternion(velocity, Vector(0,1,0)) * Quaternion ( -M_PI_2, Vector(0,1,0)));
211  }
212
213  velocity *= maxVelocity/velocity.len();
214  Vector v = this->velocity * (time);
215  this->shiftCoor(v);*/
216
217
218/** old  guiding functuion*/
219
220  float projectileVelocity = this->getVelocity().len();
221  if (target != NULL){
222    Vector estTargetDir = (this->target->getAbsCoor() - this->getAbsCoor()).getNormalized();
223    this->velocity = this->newDirection(this->velocity, estTargetDir, this->turningSpeed * time );
224  }
225  else
226    if (likely(projectileVelocity != 0 || projectileVelocity != this->maxVelocity) )
227      this->velocity *= (this->maxVelocity / projectileVelocity); // set speed to max
228
229//   printf("position: %f, %f, %f\n", this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z);
230//   printf("target position: %f, %f, %f\n", this->target->getAbsCoor().x, this->target->getAbsCoor().y, this->target->getAbsCoor().z);
231
232  this->shiftCoor(this->velocity * time);
233
234
235/*
236  Vector pjV = this->getVelocity();
237  Vector tV = this->target->getVelocity();
238  Vector pT = this->target->getAbsCoor() - this->getAbsCoor(); // vector projectile target
239
240  Vector a = tV.getNormalized() * pT.dot(tV.getNormalized());
241
242  float A = 2 * pT.len() * pT.len();
243  float B = 2 * a.len() * tV.len();
244  float D = 2 * sqrt(B * B - 4 * pT.len() * pT.len() *(tV.len() * tV.len() - pjV.len() * pjV.len()));
245  float tti;
246
247  if (A != 0){
248    if ( B < D ) tti = ( B + D ) / A;
249    else tti = ( B + D ) / A;
250  }
251  else tti = 0;
252
253
254  Vector estTargetDir;
255  if (tti == 0)
256    estTargetDir = pT.getNormalized() * pjV.len();
257  else
258    estTargetDir = pT / tti + pjV;
259
260  this->velocity = this->newDirection(this->velocity, estTargetDir, this->turningSpeed * time );
261
262  this->shiftCoor(this->velocity * (this->maxVelocity * time));*/
263
264  if(this->tickLifeCycle(time))
265    this->deactivate();
266
267  this->trail->tick(time);
268
269  this->angle += this->rotationSpeed * time;
270
271  this->lastDir = this->curDir;
272  this->curDir = this->velocity;
273  if( (this->getAbsCoor() - this->target->getAbsCoor()).len() < 3)   // FIXME  Temp fake workaround for collision :)
274  {
275    dynamic_cast<WorldEntity*>(target)->destroy( this);
276    this->destroy( this);
277  }
278}
279
280/**
281 *  the function gets called, when the projectile is destroyed
282 */
283void SwarmProjectile::destroy (WorldEntity* killer)
284{
285
286//   printf("THIS SHOULD WORK!\n");
287
288  Projectile::destroy( killer );
289  PRINTF(5)("DESTROY SwarmProjectile\n");
290  this->lifeCycle = .95; //!< @todo calculate this usefully.
291  this->emitter->setSystem(SwarmProjectile::explosionParticles);
292
293  this->emitter->setEmissionRate(1000.0);
294  this->emitter->setEmissionVelocity(50.0);
295  this->deactivate();
296
297}
298
299
300void SwarmProjectile::draw () const
301{
302  glMatrixMode(GL_MODELVIEW);
303  glPushMatrix();
304
305  Vector tmpDir = this->curDir; // *.7 + this->lastDir * .3;
306  tmpDir.slerpTo(this->lastDir, .4);
307
308  float matrix[4][4];
309  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
310  Vector tmpRot = this->getAbsCoor().cross(tmpDir);
311  glRotatef (angleDeg ( this->getAbsCoor(), tmpDir), tmpRot.x, tmpRot.y, tmpRot.z );
312  glRotatef(this->angle, 1.0f, 0.0f, 0.0f); //spinning missile
313  this->getAbsDir().matrix (matrix);
314  glMultMatrixf((float*)matrix);
315  //glScalef(2.0, 2.0, 2.0);  // no double rescale
316  this->getModel()->draw();
317  glTranslatef(-.9,0,0);
318  this->trail->draw();
319  glPopMatrix();
320}
Note: See TracBrowser for help on using the repository browser.