Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

actionboxenemy: less weapons

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