Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10685 was 10683, checked in by rennerc, 18 years ago

adm turret works now

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