Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/presentation/src/world_entities/weapons/bsp_weapon.cc @ 10761

Last change on this file since 10761 was 10718, checked in by rennerc, 18 years ago

dead gui :D

File size: 7.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: Reto Luechinger
13*/
14
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
17#include "bsp_weapon.h"
18#include "loading/load_param.h"
19#include "debug.h"
20#include "loading/load_param_xml.h"
21
22#include "environments/bsp_entity.h"
23#include "loading/fast_factory.h"
24#include "sound_engine.h"
25
26ObjectListDefinition(BspWeapon);
27CREATE_FACTORY(BspWeapon);
28
29ObjectListDefinition(MuzzleFlash);
30
31/**
32*  Standard constructor
33*/
34BspWeapon::BspWeapon ( OM_LIST list )
35{
36        this->init( list );
37}
38
39/**
40* destructs the BspWeapon, deletes allocated memory
41*/
42BspWeapon::~BspWeapon ()
43{
44  if ( soundSource_shoot.isPlaying() )
45    soundSource_shoot.stop();
46}
47
48/**
49* Constructor with XML Element
50*/
51BspWeapon::BspWeapon (const  TiXmlElement* root)
52{
53        this->init( OM_GROUP_00 );
54        if (root != NULL)
55        {
56                this->loadParams(root);
57        }
58}
59/**
60* XML Loader
61*/
62void BspWeapon::loadParams(const TiXmlElement* root)
63{
64        if (root != NULL)
65        {
66                WorldEntity::loadParams(root);
67
68                LoadParam(root, "Range", this, BspWeapon, setRange)
69                        .describe("the range after which the Weapon hits no more")
70                .defaultValues("");
71                LoadParam(root, "Damage", this, BspWeapon, setDamage)
72                        .describe("Damage that the weapon inflicts"); 
73                LoadParam(root, "FireRate", this, BspWeapon, setFireRate)
74                        .describe("how fast it shoots");
75                LoadParam(root, "AlwaysHits", this, BspWeapon, setAlwaysHits)
76                        .describe("No, if the weapon should hit with a probability");
77
78                LOAD_PARAM_START_CYCLE(root, element);
79                {
80                        if (root != 0){
81                                LoadParam_CYCLE(element, "addPoint", this, BspWeapon, addPoint)
82                                .describe("Adds a new Point for Gunfire");
83                        }
84                }
85                LOAD_PARAM_END_CYCLE(element);
86        }
87}
88
89void BspWeapon::addPoint(float x, float y, float z)
90{
91  gunFire.push_back( new MuzzleFlash() );
92        gunFire.back()->setParent( this->getParent() );
93        gunFire.back()->setRelCoor(x, y, z);
94}
95
96void BspWeapon::tick( float dt )
97{
98  //PRINTF(0)("BSPWEAPON TICK: %d %f %f\n", bFire, bRate, dt );
99        if (bFire) {
100                if (bRate <= 0) {
101                        bRate += fireRate;
102                        this->shoot();
103                }
104                else {
105                        bRate = bRate - dt;
106                }       
107        }
108        else {
109                bRate -= dt;
110                if (bRate < 0)
111                        bRate = 0;
112        }
113
114}
115
116void BspWeapon::init( OM_LIST list )
117{
118        bRate = 0.0;
119        bFire = false;
120        range = 1000;
121#ifdef DEBUG_AIMING
122        debugDist = 1000;
123#endif
124        damage = 10;
125        fireRate = 0.5;
126        alwaysHits = true;
127
128        this->registerObject(this, BspWeapon::_objectList);
129        this->aimingSystem = new AimingSystem( this );
130        this->aimingSystem->setParent( this );
131        this->aimingSystem->toList(list);
132       
133        this->soundSource_shoot.setSourceNode(this);
134        this->soundBuffer_shoot = OrxSound::ResourceSoundBuffer("sounds/explosions/doulette.wav");
135       
136}
137
138void BspWeapon::shoot()
139{
140
141  soundSource_shoot.play( soundBuffer_shoot, OrxSound::SoundEngine::getInstance()->getEffectsVolume(), 0.5);
142 
143for ( std::list<MuzzleFlash*>::iterator it = gunFire.begin(); it!=gunFire.end(); it++)
144{
145  (*it)->explode( 0.2 );
146}
147
148std::list<WorldEntity*>::iterator entityIterator;
149// for all bsp managers check all entities
150Vector pos = this->getAbsCoor();
151Vector dir = pos + this->getAbsDir().apply( Vector( 1, 0, 0 ) )*range;
152
153
154float shortestDist = range;
155for( ObjectList<BspEntity>::const_iterator bspIterator = BspEntity::objectList().begin();
156     bspIterator != BspEntity::objectList().end();
157     bspIterator++)
158{
159  float res = (dynamic_cast<BspEntity*>(*bspIterator)->getBspManager())->checkCollisionRay( pos, dir, dir.len() + 1 );
160
161  if ( res < shortestDist )
162    shortestDist = res;
163}
164
165WorldEntity* target = aimingSystem->getNearestTarget();
166aimingSystem->flushList();
167
168if ( target != NULL )
169{
170  if ( shortestDist < (pos - target->getAbsCoor()).len() )
171  {
172
173#ifdef DEBUG_AIMING
174    printf("HIT WALL\n");
175    this->debugDist = shortestDist;
176#endif
177    return;
178  }
179#ifdef DEBUG_AIMING
180  else
181  {
182    this->debugDist = 1000;
183  }
184#endif
185  if (!alwaysHits)
186  {
187    float r = rand();
188    r = r/RAND_MAX;
189    float res = (target->getAbsCoor() - this->getAbsCoor()).len();
190    float p = 1 - res*res/range/range;
191    if (r < p )
192    {
193#ifdef DEBUG_AIMING
194      printf( "HIT %s\n", target->getClassName().c_str() );
195#endif
196      target->hit( this->damage, this );
197    }
198#ifdef DEBUG_AIMING
199    else
200      printf( "MISHIT %s\n", target->getClassName().c_str() );
201#endif
202
203  }
204  else
205  {
206#ifdef DEBUG_AIMING
207    printf( "HIT %s\n", target->getClassName().c_str() );
208#endif
209    target->hit( this->damage, this );
210  }
211}
212
213
214
215       
216}
217
218void BspWeapon::draw() const
219{
220  WorldEntity::draw();
221
222  for ( std::list<MuzzleFlash*>::const_iterator it = gunFire.begin(); it!=gunFire.end(); it++)
223  {
224    (*it)->draw();
225  }
226#ifdef DEBUG_AIMING
227  glMatrixMode(GL_MODELVIEW);
228  glPushMatrix();
229
230  glPushAttrib(GL_ENABLE_BIT);
231
232  glDisable(GL_LIGHTING);
233  glDisable(GL_TEXTURE_2D);
234  glDisable(GL_BLEND);
235  glLineWidth(2.0);
236
237
238  Vector mp = this->getAbsCoor();
239  Vector op = this->getAbsDir().apply( Vector(1, 0, 0) );
240
241  op *= debugDist;
242  op += mp;
243
244  glColor3f(1.0, 1.0, 1.0 );
245  glBegin(GL_LINE_STRIP);
246    glVertex3f(mp.x, mp.y, mp.z);
247    glVertex3f(op.x, op.y, op.z);
248  glEnd();
249
250 
251  glPopAttrib();
252  glPopMatrix();
253#endif
254}
255
256void MuzzleFlash::draw( ) const
257{
258  if (explosionParticles) explosionParticles->draw();
259}
260
261void MuzzleFlash::activate()
262{
263        if (unlikely(explosionParticles == NULL))
264        {
265                explosionParticles = new SpriteParticles(5000);
266                explosionParticles->setName("MuzzleFlashExplosionParticles");
267                explosionParticles->setMaterialTexture("textures/radial-trans-noise.png");
268                explosionParticles->setLifeSpan(0.1, 0);
269                explosionParticles->setRadius(0.0, 8);
270                explosionParticles->setRadius(.5, 6.0);
271                explosionParticles->setRadius(1.0, 2.0);
272                explosionParticles->setColor(0.0, 1,0.7,0,1);
273                explosionParticles->setColor(0.4, 0.8,.5,0,1);
274                explosionParticles->setColor(0.8, 0.5,0,0,.8);
275                explosionParticles->setColor(1.0, 0,0,0,.6);
276    explosionParticles->toList(OM_DEAD_TICK);
277  }
278                       
279        this->emitter->setSystem(explosionParticles);
280        this->emitter->updateNode(.01);
281        this->emitter->updateNode(.01);
282        this->toList(OM_DEAD_TICK);
283        this->lifeCycle = 0.0;
284}
285
286void MuzzleFlash::explode(float lifetime)
287{
288        MuzzleFlash* explosion = this;
289        //explosion->setAbsCoor(this->getAbsCoor());
290        explosion->emitter->setSize(1, 1, 1);
291        explosion->activate();
292        explosion->lifeTime = lifetime;
293}
294
295MuzzleFlash::MuzzleFlash ()
296{
297  this->explosionParticles = NULL;
298  this->registerObject(this, MuzzleFlash::_objectList);
299  this->toList(OM_DEAD_TICK);
300
301  this->emitter = new BoxEmitter(Vector(10,10,10), 200, 45, M_2_PI);
302  this->emitter->addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
303  this->emitter->setParent(this);
304  this->emitter->setSpread(M_PI, M_PI);
305
306  this->lifeCycle = 0.0f;
307  this->lifeTime = .5f;
308
309}
310
311
312/**
313 *  standard deconstructor
314*/
315MuzzleFlash::~MuzzleFlash ()
316{
317  delete this->emitter;
318
319  /* this is normaly done by World.cc by deleting the ParticleEngine */
320  if (explosionParticles != NULL)
321  {
322    delete explosionParticles;
323    MuzzleFlash::explosionParticles = NULL;
324  }
325}
326
327void MuzzleFlash::deactivate()
328{
329  this->emitter->setSystem(NULL);
330  this->toList(OM_DEAD);
331}
332
333
334/**
335 *  signal tick, time dependent things will be handled here
336 * @param time since last tick
337*/
338void MuzzleFlash::tick (float dt)
339{
340  this->lifeCycle += dt;
341  if(this->lifeTime < this->lifeCycle)
342    this->deactivate();
343}
344
345
346
Note: See TracBrowser for help on using the repository browser.