Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/vs-enhencements/src/world_entities/npcs/actionbox_enemy.cc @ 10671

Last change on this file since 10671 was 10667, checked in by rennerc, 18 years ago

ActionboxEnemy

File size: 6.3 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 "actionbox_enemy.h"
27
28ObjectListDefinition(ActionboxEnemy);
29CREATE_FACTORY(ActionboxEnemy);
30
31ActionboxEnemy::ActionboxEnemy(const TiXmlElement* root)
32{
33  PRINTF(0)("ActionboxEnemy\n");
34 
35  this->registerObject(this, ActionboxEnemy::_objectList);
36  this->toList(OM_GROUP_00);
37 
38  this->isActive = true;
39 
40  this->pitch = 0.0f;
41  this->dPitch = 0.0;
42 
43  this->maxSpeed = 30;
44  this->acceleration = 3;
45  this->speed = 0;
46 
47  this->onEscape = false;
48 
49  if ( root )
50    this->loadParams( root );
51}
52
53ActionboxEnemy::~ActionboxEnemy()
54{
55}
56
57void ActionboxEnemy::loadParams(const TiXmlElement* root)
58{
59  WorldEntity::loadParams( root );
60}
61
62void ActionboxEnemy::tick( float dt )
63{
64  this->bFire = false;
65 
66  if ( !State::getPlayer() || !State::getPlayer()->getPlayable() )
67    return;
68 
69  Vector playerDir = State::getPlayer()->getPlayable()->getAbsDir().apply( Vector(1, 0, 0) );
70  Vector dist = this->getAbsCoor() - State::getPlayer()->getPlayable()->getAbsCoor();
71 
72  bool behindPlayer = playerDir.dot( dist ) < 0;
73 
74  if ( behindPlayer )
75    return;
76 
77  myDir = this->getAbsDir();
78  myCoor = this->getAbsCoor();
79 
80  this->pitch += this->dPitch*dt;
81  while ( pitch > 2*PI )
82    pitch -= 2*PI;
83  while ( pitch < 0 )
84    pitch += 2*PI;
85 
86  myDir *= qPitch.inverse();
87 
88  qPitch = Quaternion( pitch, Vector( 1, 0, 0 ) );
89 
90  if ( isActive && State::getActionBox() )
91  {
92    ActionBox* box = State::getActionBox();
93    if ( box->isPointInBox( this->getAbsCoor() ) )
94    {
95      attackPlayer( box, dt );
96    }
97    else
98    {
99      moveTowardsBox( box, dt );
100      onEscape = false;
101    }
102  }
103 
104  myDir *= qPitch;
105 
106  this->setAbsDir( myDir );
107  this->setAbsCoor( myCoor );
108}
109
110void ActionboxEnemy::attackPlayer( ActionBox * box, float dt )
111{
112  if ( !State::getPlayer() || !State::getPlayer()->getPlayable() || !box )
113    return;
114 
115  float distance = (State::getPlayer()->getPlayable()->getAbsCoor() - getAbsCoor() ).len();
116 
117  if ( distance > box->getDepth()/4.0 && !onEscape )
118  {
119    Vector targetPos = State::getPlayer()->getPlayable()->getAbsCoor();
120    Vector targetDir = State::getPlayer()->getPlayable()->getAbsCoor()-this->getAbsCoor();
121    moveTowards( targetPos, targetDir, dt );
122    if ( this->getAbsDir().apply( Vector(1, 0, 0) ).dot(targetDir) > 0.9 )
123    {
124      this->bFire = true;
125      PRINTF(0)("FIRE\n");
126    }
127  }
128  else
129  {
130    if ( !onEscape )
131    {
132      Vector ds = this->getAbsCoor() - State::getPlayer()->getPlayable()->getAbsCoor();
133      float projy = box->getAbsDir().apply( Vector(0, 1, 0) ).dot( ds );
134      float projz = box->getAbsDir().apply( Vector(0, 0, 1) ).dot( ds );
135      this->escapePoint = Vector( 0, projy, projz );
136      this->escapePoint.normalize();
137      this->escapePoint*= 2*box->getWidth_2();
138      PRINTF(0)("ESCAPE\n");
139    }
140    onEscape = true;
141   
142    Vector rEscapePoint = box->getAbsDir().apply(escapePoint);
143    Vector targetPos = State::getPlayer()->getPlayable()->getAbsCoor() + rEscapePoint;
144    Vector targetDir = State::getPlayer()->getPlayable()->getAbsCoor() + rEscapePoint - this->getAbsCoor();
145    moveTowards( targetPos, targetDir, dt );   
146  }
147}
148
149void ActionboxEnemy::moveTowards( Vector targetPos, Vector targetDir, float dt )
150{
151  Quaternion cur = myDir;
152  Quaternion rx( dt, Vector( 0, 0, 1 ) );
153 
154  Quaternion tmp1 = cur * rx;
155  Quaternion tmp2 = cur * rx.inverse();
156 
157  Quaternion dec;
158  if ( tmp1.apply( Vector(1, 0, 0) ).dot(targetDir) > tmp2.apply( Vector(1, 0, 0)).dot(targetDir) )
159    dec = tmp1;
160  else
161    dec = tmp2;
162 
163  float dp = dec.apply( Vector(1, 0, 0) ).dot(Vector(0, 1, 0));
164  if ( dp > -0.9 && dp < 0.9 )
165  {
166    cur = dec;
167  }
168 
169  Quaternion ry( dt, cur.inverse().apply( Vector( 0, 1, 0 ) ) );
170 
171  tmp1 = cur * ry;
172  tmp2 = cur * ry.inverse();
173 
174  if ( tmp1.apply( Vector(1, 0, 0) ).dot(targetDir) > tmp2.apply( Vector(1, 0, 0)).dot(targetDir) )
175    cur = tmp1;
176  else
177    cur = tmp2;
178 
179  myDir = cur;
180 
181  Vector fw = cur.apply( Vector(1, 0, 0) );
182 
183  this->speed += this->acceleration*dt;
184  if ( this->speed > this->maxSpeed )
185    this->speed = this->maxSpeed;
186  this->myCoor += fw*speed*dt;
187}
188
189void ActionboxEnemy::moveTowardsBox( ActionBox * box, float dt )
190{
191   
192  Vector targetPos = box->getAbsCoor() + box->getAbsDir().apply( Vector( 1, 0, 0 ) )*box->getDepth()*0.66f;
193  Vector targetDir = targetPos - myCoor;
194 
195  moveTowards(targetPos, targetDir, dt);
196}
197
198void ActionboxEnemy::draw( ) const
199{
200#if 0
201  Vector fw = this->getAbsDir().apply( Vector( 1, 0, 0 ) );
202  fw.normalize();
203  fw = fw * 100;
204 
205  Vector mp = this->getAbsCoor();
206  Vector op = mp + fw;
207 
208  Vector targetPos = State::getPlayer()->getPlayable()->getAbsCoor();
209  Vector dv = targetPos - this->getAbsCoor();
210  dv.normalize();
211  dv *= 100;
212  dv += mp;
213 
214  Vector spUp = this->getAbsDir().inverse().apply( this->getAbsDir().apply( Vector( 0, 1, 0 ) ) );
215  spUp.normalize();
216  spUp *= 100;
217  spUp += mp;
218 
219  Vector up = fw.cross( dv );
220  up += mp;
221 
222  //PRINTF(0)("DEBUG\n");
223  //mp.debug();
224  //op.debug();
225 
226  glMatrixMode(GL_MODELVIEW);
227  glPushMatrix();
228
229  glPushAttrib(GL_ENABLE_BIT);
230
231  glDisable(GL_LIGHTING);
232  glDisable(GL_TEXTURE_2D);
233  glDisable(GL_BLEND);
234  glLineWidth(2.0);
235  glColor3f(1.0, 0.0, 0.0 );
236 
237 
238  glBegin(GL_LINE_STRIP);
239    glVertex3f(mp.x, mp.y, mp.z);
240    glVertex3f(op.x, op.y, op.z);
241  glEnd();
242 
243  glColor3f(0.0, 1.0, 0.0 );
244  glBegin(GL_LINE_STRIP);
245    glVertex3f(mp.x, mp.y, mp.z);
246    glVertex3f(dv.x, dv.y, dv.z);
247  glEnd();
248 
249  glColor3f(0.0, 0.0, 1.0 );
250  glBegin(GL_LINE_STRIP);
251    glVertex3f(mp.x, mp.y, mp.z);
252    glVertex3f(up.x, up.y, up.z);
253  glEnd();
254 
255  glColor3f(1.0, 1.0, 1.0 );
256  glBegin(GL_LINE_STRIP);
257    glVertex3f(mp.x, mp.y, mp.z);
258    glVertex3f(spUp.x, spUp.y, spUp.z);
259  glEnd();
260
261  glPopMatrix();
262#endif
263  WorldEntity::draw();
264}
Note: See TracBrowser for help on using the repository browser.