Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/world_entities/npcs/adm_turret.cc

Last change on this file was 10698, checked in by snellen, 17 years ago

merged adm, hud, vs-enhancements : beni's responsible for this commit. blame him!

File size: 8.9 KB
RevLine 
[10663]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 "adm_turret.h"
[10664]18#include "weapons/weapon_manager.h"
19#include "weapons/weapon.h"
[10663]20#include "lib/util/loading/factory.h"
21#include "world_entities/projectiles/projectile.h"
[10664]22#include "loading/load_param.h"
23#include "debug.h"
[10677]24#include "loading/load_param_xml.h"
[10663]25
[10688]26#include "environments/bsp_entity.h"
27
[10663]28ObjectListDefinition(AdmTurret);
29CREATE_FACTORY(AdmTurret);
30
31/**
32*  Standard constructor
33*/
34AdmTurret::AdmTurret ()
35{
[10664]36        this->init();
[10663]37}
38
39/**
[10666]40* destructs the turret, deletes allocated memory
[10663]41*/
42AdmTurret::~AdmTurret ()
43{
44          // will be deleted
45}
46
[10666]47/**
48* Constructor with XML Element
49*/
[10664]50AdmTurret::AdmTurret (const  TiXmlElement* root)
[10663]51{
[10664]52        this->init();
53        if (root != NULL)
54        {
55                this->loadParams(root);
56        }
[10663]57}
[10677]58/**
59* XML Loader
60*/
61void AdmTurret::loadParams(const TiXmlElement* root)
62{
63        if (root != NULL)
64        {
65                WorldEntity::loadParams(root);
[10664]66
[10677]67                LoadParam(root, "target", this, AdmTurret, setTarget)
68                        .describe("The filename of the World Entity, that is to be shot at")
69                        .defaultValues("");
[10681]70               
71                LoadParam(root, "type", this, AdmTurret, setType)
72                        .describe("floor|ceil"); 
[10677]73
74                LoadParamXML(root, "Cannons", this, AdmTurret, addCannons)
75                        .describe("add cannons to ADM");
76                LoadParamXML(root, "Sensor", this, AdmTurret, addSensor)
77                        .describe("add sensor to ADM");
[10694]78                LoadParamXML(root, "Weapon", this, AdmTurret, addWeapon)
79                        .describe("add weapon to ADM");
[10677]80
81        }
[10681]82//         this->removeNodeFlags( PNODE_ALL );
[10683]83        this->addNodeFlags( PNODE_ROTATE_AND_MOVE );
84        this->addNodeFlags( PNODE_REPARENT_KEEP_POSITION );
[10679]85       
[10683]86        //HACK this is needed to get the correct coordinates instead (0, 0, 0)
87        this->updateNode( 0 );
88       
[10681]89        if ( this->isCeil )
90        {
91          Vector a = this->sensor->getRelCoor();
92          this->sensor->setRelCoor( -a.x, -a.y, -a.z );
93          a = this->cannons->getRelCoor();
94          this->cannons->setRelCoor( -a.x, -a.y, -a.z );
95        }
[10677]96}
97
98/**
99* Sets Target onto the World Entity with filename "target", given as String
100*/
101void AdmTurret::setTarget(const std::string& target)
102{
103        WorldEntity* targetEntity = WorldEntity::objectList().getObject(target);
104        if (targetEntity != NULL) 
105        {
106                this->myTarget = targetEntity;
107        }
108        else
109        {
110                PRINTF(1)("ERROR ADMTURRET : Target %s does not exist\n", target.c_str());
111        }
112}
113
[10681]114void AdmTurret::setType( const std::string& type )
115{
116  if ( type == "floor" )
117  {
118    this->isCeil = false;
119    return;
120  }
121 
122  if ( type == "ceil" )
123  {
124    this->isCeil = true;
125    return;
126  }
127 
128  //invalid argument
129  PRINTF(1)("%s is not a valid type for AdmTurret\n", type.c_str());
130  assert("false");
131}
132
[10663]133void AdmTurret::init()
134{
[10664]135        this->registerObject(this, AdmTurret::_objectList);
[10679]136       
[10681]137        this->bodyAngle = this->cannonAngle = 0.0f;
138        this->isActive = true;
139        this->range = 400;
140        this->isCeil = false;
[10688]141        this->playerVisible = false;
[10698]142        this->weapon = NULL;
[10689]143
144       
[10663]145}
146
[10677]147void AdmTurret::tick(float dt)
[10663]148{
[10677]149  WorldEntity::tick(dt);
[10698]150  if (this->weapon) this->weapon->fire(false);
[10688]151  this->updatePlayerVisible();
[10664]152
[10677]153  //rotate sensor 2PI/sec
[10683]154  this->sensor->setAbsDir( this->sensor->getAbsDir() * Quaternion( PI*2*dt, Vector( 0, -1, 0 ) ) );
[10663]155
[10677]156
[10689]157  Vector playerPos = this->myTarget->getAbsCoor() + Vector(0, 12, 0);
[10681]158  Vector ds = playerPos - ( this->cannons->getAbsCoor() );
[10689]159  if ( isActive && ds.len() <= range && playerVisible )
160  {
[10681]161    this->moveTowards( ds,  dt);
[10694]162   
163    //if target within +/- 2.5 degrees of aim -> fire
164    Vector dv1 = ds;
165    dv1.normalize();
166    Vector dv2 = this->cannons->getAbsDir().apply( Vector(-1, 0, 0));
167    dv2.normalize();
168    float angle = dv1.dot(dv2);
169    if (angle > 0.999)
[10698]170    {
171        if (this->weapon) this->weapon->fire(true);
172    }
[10689]173  }
[10681]174  else
175    this->moveTowards( Vector(0, -1, 0), dt );
[10664]176}
[10663]177
[10664]178void AdmTurret::draw() const
179{
[10677]180  WorldEntity::draw();
181
[10694]182#if 0
[10677]183  glMatrixMode(GL_MODELVIEW);
184  glPushMatrix();
185
186  glPushAttrib(GL_ENABLE_BIT);
187
188  glDisable(GL_LIGHTING);
189  glDisable(GL_TEXTURE_2D);
190  glDisable(GL_BLEND);
191  glLineWidth(2.0);
192
193
194  Vector mp = this->cannons->getAbsCoor();
195  Vector op = this->cannons->getAbsDir().apply( Vector(-1, 0, 0) );
196  op *= 100;
197  op += mp;
198
199  glColor3f(1.0, 0.0, 0.0 );
200  glBegin(GL_LINE_STRIP);
201    glVertex3f(mp.x, mp.y, mp.z);
202    glVertex3f(op.x, op.y, op.z);
203  glEnd();
204
205  op = this->myTarget->getAbsCoor() - ( this->cannons->getAbsCoor() );
206  op += mp;
207
208  glColor3f(0.0, 1.0, 0.0 );
209  glBegin(GL_LINE_STRIP);
210    glVertex3f(mp.x, mp.y, mp.z);
211    glVertex3f(op.x, op.y, op.z);
212  glEnd();
213 
214  glPopAttrib();
215  glPopMatrix();
[10694]216#endif
[10664]217}
[10663]218
[10664]219void AdmTurret::collidesWith(WorldEntity* entity, const Vector& location)
220{
221}
[10663]222
[10664]223void AdmTurret::activate()
[10663]224{
225}
[10664]226
227void AdmTurret::deactivate()
228{
[10663]229}
230
[10677]231void AdmTurret::addCannons( const TiXmlElement * root )
232{
[10694]233  this->cannons = new WorldEntity();
[10677]234        this->cannons->setParent(this);
235        this->cannons->loadParams( root );
236
[10679]237        //this->cannons->addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
238        //this->cannons->addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
[10677]239       
240        this->cannons->toList( getOMListNumber() );
[10689]241
[10694]242
243}
244
245void AdmTurret::addWeapon( const TiXmlElement * root )
246{
[10689]247        this->weapon = new BspWeapon();
[10694]248        this->weapon->setParent( this->cannons );
[10690]249        this->weapon->loadParams(root);
[10689]250        this->weapon->toList( getOMListNumber() );
[10694]251        //this->weapon->setAbsCoor( this->cannons->getAbsCoor() );
[10689]252        this->weapon->setAbsDir( this->weapon->getAbsDir() * Quaternion( PI, Vector(0, 1, 0) ) );
[10677]253}
254
255void AdmTurret::addSensor( const TiXmlElement * root )
256{
[10694]257  this->sensor = new WorldEntity();
[10677]258        this->sensor->setParent(this);
259        this->sensor->loadParams( root );
260
[10679]261        //this->sensor->addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
262        //this->sensor->addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
[10677]263        this->sensor->toList( getOMListNumber() );
264}
265
266void AdmTurret::moveTowards( Vector targetDir, float dt )
267{
[10681]268  if ( this->cannons->getParent() != NullParent::getNullParent() )
[10683]269  {
[10681]270    this->cannons->setParent( NullParent::getNullParent() );
[10683]271    this->cannons->shiftCoor( this->getAbsCoor() );
272   
273    this->sensor->setParent( NullParent::getNullParent() );
274    this->sensor->shiftCoor( this->getAbsCoor() );
275  }
[10677]276 
[10681]277  targetDir.normalize();
[10677]278 
[10681]279  float dAngle = dt;
[10677]280 
[10681]281  float bestResult = -1.0f;
282  Quaternion bestBodyRot;
283  Quaternion bestCannonRot;
284  float bestBodyAngle = 0.0f;
285  float bestCannonAngle = 0.0f;
[10677]286 
[10683]287   Quaternion baseRot(0, Vector(1, 0, 0));
288   if ( isCeil )
289   {
290     baseRot = Quaternion( PI, Vector( 1, 0, 0 ) );
291   }
[10677]292 
[10681]293  for ( int dBodyAngle = -1; dBodyAngle<2; dBodyAngle++ )
[10679]294  {
[10681]295    for ( int dCannonAngle = -1; dCannonAngle<2; dCannonAngle++ )
296    {
297      float bodyAngle = this->bodyAngle + dBodyAngle*dAngle;
298      float cannonAngle = this->cannonAngle + dCannonAngle*dAngle;
299     
300      while ( bodyAngle > 2*PI )
301        bodyAngle -= 2*PI;
302      while ( bodyAngle < 0 )
303        bodyAngle += 2*PI;
304      while ( cannonAngle > 2*PI )
305        cannonAngle -= 2*PI;
306      while ( cannonAngle < 0 )
307        cannonAngle += 2*PI;
308     
309      Quaternion bodyRot( bodyAngle, Vector( 0, 1, 0 ) );
310      Quaternion cannonRot( cannonAngle, Vector( 0, 0, 1) );
311     
[10683]312       bodyRot = baseRot * bodyRot;
313       cannonRot = baseRot * cannonRot;
[10681]314     
315      float result = (bodyRot * cannonRot).apply( Vector( -1, 0, 0 ) ).dot( targetDir );
316     
317      if ( result > bestResult )
318      {
319        bestResult = result;
320        bestBodyRot = bodyRot;
321        bestBodyAngle = bodyAngle;
322        bestCannonRot = cannonRot;
323        bestCannonAngle = cannonAngle;
324      }
325    }
[10679]326  }
[10677]327 
[10681]328  this->bodyAngle = bestBodyAngle;
329  this->cannonAngle = bestCannonAngle;
330 
331  this->setAbsDir( bestBodyRot );
332  this->cannons->setAbsDir( bestBodyRot * bestCannonRot );
[10677]333}
[10688]334
335void AdmTurret::updatePlayerVisible( )
336{
337  std::list<WorldEntity*>::iterator entityIterator;
338  // for all bsp managers check all entities
339  Vector pos = this->cannons->getAbsCoor();
340  Vector dir = this->myTarget->getAbsCoor() - pos;
341
[10689]342
[10688]343  this->playerVisible = true;
344  for( ObjectList<BspEntity>::const_iterator bspIterator = BspEntity::objectList().begin();
345       bspIterator != BspEntity::objectList().end();
346       bspIterator++) {
347      float res = (dynamic_cast<BspEntity*>(*bspIterator)->getBspManager())->checkCollisionRay( pos, dir, dir.len() + 1 );
348     
349      if ( res < dir.len() )
350        this->playerVisible = false;
351  }
352}
Note: See TracBrowser for help on using the repository browser.