Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/presentation/src/world_entities/npcs/actionbox_enemy.cc @ 10717

Last change on this file since 10717 was 10713, checked in by rennerc, 18 years ago
File size: 9.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: Christoph Renner
13   co-programmer:
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
17
18#include "loading/factory.h"
19#include "debug.h"
20#include "loading/load_param.h"
21#include "util/loading/load_param_xml.h"
22#include "state.h"
23#include "player.h"
24#include "playable.h"
25
26#include "particles/dot_emitter.h"
27#include "particles/emitter_node.h"
28#include "particles/sprite_particles.h"
29
30#include "actionbox_enemy.h"
31
32ObjectListDefinition(ActionboxEnemy);
33CREATE_FACTORY(ActionboxEnemy);
34
35ActionboxEnemy::ActionboxEnemy(const TiXmlElement* root)
36  :weaponMan(this)
37{
38  PRINTF(0)("ActionboxEnemy\n");
39 
40  this->registerObject(this, ActionboxEnemy::_objectList);
41  this->toList(OM_GROUP_00);
42 
43  this->isActive = true;
44 
45  this->pitch = 0.0f;
46  this->dPitch = 0.0;
47 
48  this->maxSpeed = 30;
49  this->acceleration = 3;
50  this->speed = 0;
51 
52  this->onEscape = false;
53 
54  if ( root )
55    this->loadParams( root );
56 
57 
58    this->weaponMan.setParentEntity( this);
59  //weapons:
60
61  this->weaponMan.setParentEntity( this);
62
63  this->weaponMan.setSlotCount(8);
64
65  this->weaponMan.createWeaponSlot(0, 3.270, 1.028, .155, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
66  this->weaponMan.createWeaponSlot(1, 3.270, 1.028, -.155, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
67  this->weaponMan.createWeaponSlot(2, 4.385, .063, .876, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
68  this->weaponMan.createWeaponSlot(3, 4.385, -.063, -.876, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
69  this->weaponMan.createWeaponSlot(4, 1.635, -.612, 2.691, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
70  this->weaponMan.createWeaponSlot(5, 1.536, -.612, -2.691, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
71  this->weaponMan.createWeaponSlot(6, 1.536, -.612, 3.254, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
72  this->weaponMan.createWeaponSlot(7, 1.536, -.612, -3.254, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
73
74
75  this->weaponMan.addWeaponToSlot(0, 0, "RFCannon");
76  this->weaponMan.addWeaponToSlot(0, 1, "RFCannon");
77  this->weaponMan.addWeaponToSlot(0, 2, "RFCannon");
78  this->weaponMan.addWeaponToSlot(0, 3, "RFCannon");
79  this->weaponMan.addWeaponToSlot(1, 0, "RFCannon");
80  this->weaponMan.addWeaponToSlot(1, 1, "RFCannon");
81  this->weaponMan.addWeaponToSlot(1, 2, "RFCannon");
82  this->weaponMan.addWeaponToSlot(1, 3, "RFCannon");
83
84  this->weaponMan.addWeaponToSlot(0, 4, "NadionLaser");
85  this->weaponMan.addWeaponToSlot(0, 5, "NadionLaser");
86  this->weaponMan.addWeaponToSlot(2, 4, "NadionLaser");
87  this->weaponMan.addWeaponToSlot(2, 5, "NadionLaser");
88
89  this->weaponMan.addWeaponToSlot(0, 6, "Disruptor");
90  this->weaponMan.addWeaponToSlot(0, 7, "Disruptor");
91  this->weaponMan.addWeaponToSlot(3, 6, "Disruptor");
92  this->weaponMan.addWeaponToSlot(3, 7, "Disruptor");
93 
94  this->weaponMan.changeWeaponConfig(0);
95 
96  this->weaponMan.getFixedTarget()->setParent(this);
97  this->weaponMan.getFixedTarget()->setRelCoor(100000,0,0);
98  this->weaponMan.hideCrosshair();
99}
100
101ActionboxEnemy::~ActionboxEnemy()
102{
103}
104
105void ActionboxEnemy::loadParams(const TiXmlElement* root)
106{
107  WorldEntity::loadParams( root );
108}
109
110void ActionboxEnemy::tick( float dt )
111{
112  weaponMan.tick( dt );
113  this->bFire = false;
114 
115  if ( !State::getPlayer() || !State::getPlayer()->getPlayable() )
116    return;
117 
118  Vector playerDir = State::getPlayer()->getPlayable()->getAbsDir().apply( Vector(1, 0, 0) );
119  Vector dist = this->getAbsCoor() - State::getPlayer()->getPlayable()->getAbsCoor();
120 
121  bool behindPlayer = playerDir.dot( dist ) < 0;
122 
123  if ( behindPlayer )
124    return;
125 
126  myDir = this->getAbsDir();
127  myCoor = this->getAbsCoor();
128 
129  this->pitch += this->dPitch*dt;
130  while ( pitch > 2*PI )
131    pitch -= 2*PI;
132  while ( pitch < 0 )
133    pitch += 2*PI;
134 
135  myDir *= qPitch.inverse();
136 
137  qPitch = Quaternion( pitch, Vector( 1, 0, 0 ) );
138 
139  if ( isActive && State::getActionBox() )
140  {
141    ActionBox* box = State::getActionBox();
142    if ( box->isPointInBox( this->getAbsCoor() ) )
143    {
144      attackPlayer( box, dt );
145    }
146    else
147    {
148      moveTowardsBox( box, dt );
149      onEscape = false;
150    }
151  }
152 
153  myDir *= qPitch;
154 
155  this->setAbsDir( myDir );
156  this->setAbsCoor( myCoor );
157}
158
159void ActionboxEnemy::attackPlayer( ActionBox * box, float dt )
160{
161  if ( !State::getPlayer() || !State::getPlayer()->getPlayable() || !box )
162    return;
163 
164  float distance = (State::getPlayer()->getPlayable()->getAbsCoor() - getAbsCoor() ).len();
165 
166  if ( distance > box->getDepth()/4.0 && !onEscape )
167  {
168    Vector targetPos = State::getPlayer()->getPlayable()->getAbsCoor();
169    Vector targetDir = State::getPlayer()->getPlayable()->getAbsCoor()-this->getAbsCoor();
170    moveTowards( targetPos, targetDir, dt );
171    if ( this->getAbsDir().apply( Vector(1, 0, 0) ).dot(targetDir) > 0.9 )
172    {
173      this->bFire = true;
174      weaponMan.fire();
175    }
176  }
177  else
178  {
179    if ( !onEscape )
180    {
181      Vector ds = this->getAbsCoor() - State::getPlayer()->getPlayable()->getAbsCoor();
182      float projy = box->getAbsDir().apply( Vector(0, 1, 0) ).dot( ds );
183      float projz = box->getAbsDir().apply( Vector(0, 0, 1) ).dot( ds );
184      this->escapePoint = Vector( 0, projy, projz );
185      this->escapePoint.normalize();
186      this->escapePoint*= 2*box->getWidth_2();
187      PRINTF(0)("ESCAPE\n");
188    }
189    onEscape = true;
190   
191    Vector rEscapePoint = box->getAbsDir().apply(escapePoint);
192    Vector targetPos = State::getPlayer()->getPlayable()->getAbsCoor() + rEscapePoint;
193    Vector targetDir = State::getPlayer()->getPlayable()->getAbsCoor() + rEscapePoint - this->getAbsCoor();
194    moveTowards( targetPos, targetDir, dt );   
195  }
196}
197
198void ActionboxEnemy::moveTowards( Vector targetPos, Vector targetDir, float dt )
199{
200  Quaternion cur = myDir;
201  Quaternion rx( dt, Vector( 0, 0, 1 ) );
202 
203  Quaternion tmp1 = cur * rx;
204  Quaternion tmp2 = cur * rx.inverse();
205 
206  Quaternion dec;
207  if ( tmp1.apply( Vector(1, 0, 0) ).dot(targetDir) > tmp2.apply( Vector(1, 0, 0)).dot(targetDir) )
208    dec = tmp1;
209  else
210    dec = tmp2;
211 
212  float dp = dec.apply( Vector(1, 0, 0) ).dot(Vector(0, 1, 0));
213  if ( dp > -0.9 && dp < 0.9 )
214  {
215    cur = dec;
216  }
217 
218  Quaternion ry( dt, cur.inverse().apply( Vector( 0, 1, 0 ) ) );
219 
220  tmp1 = cur * ry;
221  tmp2 = cur * ry.inverse();
222 
223  if ( tmp1.apply( Vector(1, 0, 0) ).dot(targetDir) > tmp2.apply( Vector(1, 0, 0)).dot(targetDir) )
224    cur = tmp1;
225  else
226    cur = tmp2;
227 
228  myDir = cur;
229 
230  Vector fw = cur.apply( Vector(1, 0, 0) );
231 
232  this->speed += this->acceleration*dt;
233  if ( this->speed > this->maxSpeed )
234    this->speed = this->maxSpeed;
235  this->myCoor += fw*speed*dt;
236}
237
238void ActionboxEnemy::moveTowardsBox( ActionBox * box, float dt )
239{
240   
241  Vector targetPos = box->getAbsCoor() + box->getAbsDir().apply( Vector( 1, 0, 0 ) )*box->getDepth()*0.66f;
242  Vector targetDir = targetPos - myCoor;
243 
244  moveTowards(targetPos, targetDir, dt);
245}
246
247void ActionboxEnemy::draw( ) const
248{
249#if 0
250  Vector fw = this->getAbsDir().apply( Vector( 1, 0, 0 ) );
251  fw.normalize();
252  fw = fw * 100;
253 
254  Vector mp = this->getAbsCoor();
255  Vector op = mp + fw;
256 
257  Vector targetPos = State::getPlayer()->getPlayable()->getAbsCoor();
258  Vector dv = targetPos - this->getAbsCoor();
259  dv.normalize();
260  dv *= 100;
261  dv += mp;
262 
263  Vector spUp = this->getAbsDir().inverse().apply( this->getAbsDir().apply( Vector( 0, 1, 0 ) ) );
264  spUp.normalize();
265  spUp *= 100;
266  spUp += mp;
267 
268  Vector up = fw.cross( dv );
269  up += mp;
270 
271  //PRINTF(0)("DEBUG\n");
272  //mp.debug();
273  //op.debug();
274 
275  glMatrixMode(GL_MODELVIEW);
276  glPushMatrix();
277
278  glPushAttrib(GL_ENABLE_BIT);
279
280  glDisable(GL_LIGHTING);
281  glDisable(GL_TEXTURE_2D);
282  glDisable(GL_BLEND);
283  glLineWidth(2.0);
284  glColor3f(1.0, 0.0, 0.0 );
285 
286 
287  glBegin(GL_LINE_STRIP);
288    glVertex3f(mp.x, mp.y, mp.z);
289    glVertex3f(op.x, op.y, op.z);
290  glEnd();
291 
292  glColor3f(0.0, 1.0, 0.0 );
293  glBegin(GL_LINE_STRIP);
294    glVertex3f(mp.x, mp.y, mp.z);
295    glVertex3f(dv.x, dv.y, dv.z);
296  glEnd();
297 
298  glColor3f(0.0, 0.0, 1.0 );
299  glBegin(GL_LINE_STRIP);
300    glVertex3f(mp.x, mp.y, mp.z);
301    glVertex3f(up.x, up.y, up.z);
302  glEnd();
303 
304  glColor3f(1.0, 1.0, 1.0 );
305  glBegin(GL_LINE_STRIP);
306    glVertex3f(mp.x, mp.y, mp.z);
307    glVertex3f(spUp.x, spUp.y, spUp.z);
308  glEnd();
309
310  glPopMatrix();
311#endif
312  WorldEntity::draw();
313}
314
315void ActionboxEnemy::destroy( WorldEntity * killer )
316{
317  EmitterNode* node  = NULL;
318  DotEmitter* emitter = NULL;
319  SpriteParticles*  explosionParticles  = NULL;
320
321  explosionParticles = new SpriteParticles(200);
322  explosionParticles->setName("SpaceShipExplosionParticles");
323  explosionParticles->setLifeSpan(.3, .7);
324  explosionParticles->setRadius(0.0, 10.0);
325  explosionParticles->setRadius(.5, 6.0);
326  explosionParticles->setRadius(1.0, 3.0);
327  explosionParticles->setColor(0.0, 1,1,1,.9);
328  explosionParticles->setColor(0.1,  1,1,0,.9);
329  explosionParticles->setColor(0.5, .8,.4,0,.5);
330  explosionParticles->setColor(1.0, .2,.2,.2,.5);
331
332
333  emitter = new DotEmitter( 2000, 70, 360);
334  emitter->setEmissionRate( 200.0);
335
336  node  = new EmitterNode( .4f );
337  node->setupParticle( emitter, explosionParticles);
338  node->setAbsDir( this->getAbsDir());
339  node->setVelocity( this->getVelocity() * .9f);
340  node->setAbsCoor( this->getAbsCoor());
341  if( !node->start())
342    PRINTF(0)("Explosion node not correctly started!");
343 
344  this->setAbsCoor( this->getAbsCoor() + Vector(100,0,0) + Vector(1,0,0) * VECTOR_RAND(150).dot(Vector(1,0,0)));
345 
346  toList( OM_DEAD );
347}
Note: See TracBrowser for help on using the repository browser.