Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/adm/src/world_entities/npcs/adm_turret.cc @ 10688

Last change on this file since 10688 was 10688, checked in by rennerc, 17 years ago

visibility check for player in adm

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