Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/world_entities/npcs/generic_npc.cc @ 8903

Last change on this file since 8903 was 8894, checked in by patrick, 18 years ago

merged the branche single_player_map with the trunk

File size: 12.5 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific
14   main-programmer: Patrick Boenzli
15   co-programmer:
16*/
17#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
18
19
20#include "util/loading/factory.h"
21#include "util/loading/load_param.h"
22
23#include "interactive_model.h"
24#include "md2/md2Model.h"
25
26#include "sound_buffer.h"
27
28#include "loading/resource_manager.h"
29
30#include "generic_npc.h"
31
32#include "animation/animation3d.h"
33
34using namespace std;
35
36
37
38CREATE_FACTORY(GenericNPC, CL_GENERIC_NPC);
39
40#include "script_class.h"
41CREATE_SCRIPTABLE_CLASS(GenericNPC, CL_GENERIC_NPC,
42                       // Move
43                        addMethod("walkTo", ExecutorLua3ret<GenericNPC,float,float,float,float>(&GenericNPC::walkTo))
44                        ->addMethod("setTime", ExecutorLua1<GenericNPC,float>(&GenericNPC::setTime))
45                        ->addMethod("turnTo", ExecutorLua4ret<GenericNPC,bool,float,float,float,float>(&GenericNPC::turnTo))
46                       // Display
47                        ->addMethod("hide", ExecutorLua0<WorldEntity>(&WorldEntity::hide))
48                        ->addMethod("unhide", ExecutorLua0<WorldEntity>(&WorldEntity::unhide))
49                       // Coordinates
50                        ->addMethod("getAbsCoorX", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorX))
51                        ->addMethod("getAbsCoorY", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorY))
52                        ->addMethod("getAbsCoorZ", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorZ))
53                        ->addMethod("setAbsCoor", ExecutorLua3<PNode,float,float,float>(&PNode::setAbsCoor))
54                        ->addMethod("setAbsDir", ExecutorLua4<PNode,float,float,float,float>(&PNode::setAbsDir))
55                           
56                       );
57
58
59
60/**
61 * constructor
62 */
63GenericNPC::GenericNPC(const TiXmlElement* root)
64  : NPC(root)
65{
66  this->init();
67
68  if (root != NULL)
69    this->loadParams(root);
70}
71
72
73GenericNPC::GenericNPC()
74  : NPC(NULL)
75{
76
77}
78
79/**
80 * deconstructor
81 */
82GenericNPC::~GenericNPC ()
83{
84  if( this->currentAnim != NULL)
85    delete this->currentAnim;
86}
87
88
89/**
90 * initializing the npc enity
91 */
92void GenericNPC::init()
93{
94  this->setClassID(CL_GENERIC_NPC, "GenericNPC");
95  this->toList(OM_GROUP_00);
96
97  if (this->soundBuffer != NULL)
98    ResourceManager::getInstance()->unload(this->soundBuffer);
99  this->soundBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/rain.wav", WAV);
100
101  time = 30.0f;
102  // collision reaction registration
103//   this->subscribeReaction(CREngine::CR_PHYSICS_GROUND_WALK, CL_BSP_ENTITY);
104}
105
106
107/**
108 * loads the Settings of a MD2Creature from an XML-element.
109 * @param root the XML-element to load the MD2Creature's properties from
110 */
111void GenericNPC::loadParams(const TiXmlElement* root)
112{
113  NPC::loadParams(root);
114
115}
116
117
118/**
119 * sets the animation of this npc
120 * @param anumationIndex: the animation index
121 * @param anumPlaybackMode: the playback mode
122 */
123void GenericNPC::setAnimation(int animationIndex, int animPlaybackMode)
124{
125  if( likely(this->getModel(0) != NULL))
126    ((InteractiveModel*)this->getModel(0))->setAnimation(animationIndex, animPlaybackMode);
127}
128
129
130/**
131 * sets the animation of this npc
132 * @param anumationIndex: the animation index
133 * @param anumPlaybackMode: the playback mode
134 */
135void GenericNPC::playAnimation(int animationIndex, int animPlaybackMode)
136{
137  if( likely(this->getModel(0) != NULL))
138    ((InteractiveModel*)this->getModel(0))->setAnimation(animationIndex, animPlaybackMode);
139
140}
141
142
143/**
144 * play a sound
145 * @param filename: name of the file
146 */
147void GenericNPC::playSound(std::string filename)
148{
149
150}
151
152
153/**
154 * walt to
155 * @param coordinate: coordinate to go to
156 */
157float GenericNPC::walkTo(float x, float y, float z, float qu, float qx, float qy, float qz)
158{
159  Vector destCoor = Vector(x, y, z);
160  Quaternion destDir = Quaternion(Vector(qx, qy, qz), qu);
161
162  // check if this is the current goal
163  if( this->destCoor != destCoor || this->destDir != destDir)
164  {
165    this->destCoor = destCoor;
166    this->destDir = destDir;
167
168    //float time = 100.0f;
169
170    if( this->currentAnim != NULL)
171      delete this->currentAnim;
172
173    this->currentAnim = new Animation3D(this);
174    this->currentAnim->addKeyFrame(this->getAbsCoor(), this->getAbsDir(), 0.0f, ANIM_LINEAR, ANIM_LINEAR);
175    this->currentAnim->addKeyFrame(this->getAbsCoor(), this->getAbsDir(), time, ANIM_LINEAR, ANIM_LINEAR);
176    this->currentAnim->addKeyFrame(this->destCoor, this->destDir, time, ANIM_LINEAR, ANIM_LINEAR);
177
178    this->currentAnim->setInfinity(ANIM_INF_CONSTANT);
179    this->currentAnim->play();
180
181    this->setAnimation(RUN, MD2_ANIM_LOOP);
182  }
183
184  // calculate the distance
185  Vector distance = this->getAbsCoor() - this->destCoor;
186  return distance.len();
187}
188
189
190/**
191 * walk to a specific place with direction
192 *
193 * @param x: x coordinate to go to
194 * @param y: y coordinate to go to
195 * @param z: z coordinate to go to
196 *
197 * without turning itself
198 */
199float GenericNPC::walkTo(float x, float y, float z)
200{
201  Quaternion q = this->getAbsDir();
202
203  //printf("%s moving to %f, %f, %f \n",this->getName(),x,y,z);
204
205  return this->walkTo(x, y, z, q.w, q.v.x, q.v.y, q.v.z);
206}
207
208/**
209 * walk to a specific place with direction
210 *
211 * @param x: x coordinate to go to
212 * @param y: y coordinate to go to
213 * @param qu: angle to rotate
214 * @param qx: x coordinate of rotation vector
215 * @param qy: y coordinate of rotation vector
216 * @param qz: z coordinate of rotation vector
217 *
218 */
219float GenericNPC::walkTo(float x, float y, float qu, float qx, float qy, float qz)
220{
221  return this->walkTo(x, y, 0.0f, qu, qx, qy, qz);
222}
223
224
225/**
226 * walk to a specific place with direction
227 *
228 * @param coor: vector place
229 * @param dir: direction
230 *
231 */
232float GenericNPC::walkTo(const Vector& coor, const Quaternion& dir)
233{
234  return this->walkTo(coor.x, coor.y, coor.z, dir.w, dir.v.x, dir.v.y, dir.v.z);
235}
236
237
238
239/**
240 * run to a specific place with direction
241 *
242 * @param x: x coordinate to go to
243 * @param y: y coordinate to go to
244 * @param z: z coordinate to go to
245 * @param qu: angle to rotate
246 * @param qx: x coordinate of rotation vector
247 * @param qy: y coordinate of rotation vector
248 * @param qz: z coordinate of rotation vector
249 *
250 */
251float GenericNPC::runTo(float x, float y, float z, float qu, float qx, float qy, float qz)
252{
253  Vector destCoor = Vector(x, y, z);
254  Quaternion destDir = Quaternion(Vector(qx, qy, qz), qu);
255
256  // check if this is the current goal
257  if( this->destCoor != destCoor || this->destDir != destDir)
258  {
259    this->destCoor = destCoor;
260    this->destDir = destDir;
261
262    float time = 5.0f;
263
264    if( this->currentAnim != NULL)
265      delete this->currentAnim;
266
267    this->currentAnim = new Animation3D(this);
268    this->currentAnim->addKeyFrame(this->getAbsCoor(), this->getAbsDir(), time, ANIM_LINEAR, ANIM_LINEAR);
269    this->currentAnim->addKeyFrame(this->destCoor, this->destDir, time, ANIM_LINEAR, ANIM_LINEAR);
270
271
272    this->currentAnim->setInfinity(ANIM_INF_CONSTANT);
273    this->currentAnim->play();
274
275    this->setAnimation(RUN, MD2_ANIM_LOOP);
276  }
277
278  // calculate the distance
279  Vector distance = this->getAbsCoor() - this->destCoor;
280  return distance.len();
281}
282
283
284/**
285 * run to a specific place with direction
286 *
287 * @param x: x coordinate to go to
288 * @param y: y coordinate to go to
289 * @param qu: angle to rotate
290 * @param qx: x coordinate of rotation vector
291 * @param qy: y coordinate of rotation vector
292 * @param qz: z coordinate of rotation vector
293 *
294 */
295float GenericNPC::runTo(float x, float y, float qu, float qx, float qy, float qz)
296{
297  this->runTo(x, y, 0.0f, qu, qx, qy, qz);
298}
299
300
301/**
302 * run to a specific place with direction
303 *
304 * @param coor: vector place
305 * @param dir: direction
306 *
307 */
308float GenericNPC::runTo(const Vector& coordinate, const Quaternion& dir)
309{
310  this->runTo(coordinate.x, coordinate.y, coordinate.z, dir.w, dir.v.x, dir.v.y, dir.v.z);
311}
312
313
314/**
315 * crouch to a specific place with direction
316 *
317 * @param x: x coordinate to go to
318 * @param y: y coordinate to go to
319 * @param z: z coordinate to go to
320 * @param qu: angle to rotate
321 * @param qx: x coordinate of rotation vector
322 * @param qy: y coordinate of rotation vector
323 * @param qz: z coordinate of rotation vector
324 *
325 */
326float GenericNPC::crouchTo(float x, float y, float z, float qu, float qx, float qy, float qz)
327{
328  Vector destCoor = Vector(x, y, z);
329  Quaternion destDir = Quaternion(Vector(qx, qy, qz), qu);
330
331  // check if this is the current goal
332  if( this->destCoor != destCoor || this->destDir != destDir)
333  {
334    this->destCoor = destCoor;
335    this->destDir = destDir;
336
337
338    if( this->currentAnim != NULL)
339      delete this->currentAnim;
340
341    this->currentAnim = new Animation3D(this);
342    this->currentAnim->addKeyFrame(this->getAbsCoor(), this->getAbsDir(), time, ANIM_LINEAR, ANIM_LINEAR);
343    this->currentAnim->addKeyFrame(this->destCoor, this->destDir, time, ANIM_LINEAR, ANIM_LINEAR);
344
345
346    this->currentAnim->setInfinity(ANIM_INF_CONSTANT);
347    this->currentAnim->play();
348
349    this->setAnimation(CROUCH_WALK, MD2_ANIM_LOOP);
350  }
351
352  // calculate the distance
353  Vector distance = this->getAbsCoor() - this->destCoor;
354  return distance.len();
355}
356
357
358/**
359 * couch to a specific place with direction
360 *
361 * @param x: x coordinate to go to
362 * @param y: y coordinate to go to
363 * @param qu: angle to rotate
364 * @param qx: x coordinate of rotation vector
365 * @param qy: y coordinate of rotation vector
366 * @param qz: z coordinate of rotation vector
367 *
368 */
369float GenericNPC::crouchTo(float x, float y, float qu, float qx, float qy, float qz)
370{
371  this->crouchTo(x, y, 0.0f, qu, qx, qy, qz);
372}
373
374
375
376/**
377 * crouch to a specific place with direction
378 *
379 * @param coor: vector place
380 * @param dir: direction
381 *
382 */
383float GenericNPC::crouchTo(const Vector& coordinate, const Quaternion& dir)
384{
385  this->crouchTo(coordinate.x, coordinate.y, coordinate.z, dir.w, dir.v.x, dir.v.y, dir.v.z);
386}
387
388
389/**
390 * stops the generic animation
391 */
392void GenericNPC::stop()
393{
394  if( this->currentAnim != NULL)
395  {
396    this->currentAnim->stop();
397    delete this->currentAnim;
398    this->currentAnim = NULL;
399
400    this->setAnimation(STAND, MD2_ANIM_LOOP);
401  }
402}
403
404
405/**
406 * lookat a world entity
407 * @param worldEntity: the worldentity to look at
408 */
409float GenericNPC::lookAt(WorldEntity* worldEntity)
410{}
411
412
413/**
414 * turns to a given direction
415 */
416bool GenericNPC::turnTo(float qu, float qx, float qy, float qz)
417{
418  Quaternion destDir = Quaternion(Vector(qx, qy, qz).getNormalized(), qu);
419
420  printf("Turning: %f, %f, %f, %f \n",qu,qx,qy,qz);
421  // check if this is the current goal
422  if( this->destDir != destDir)
423  {
424//     if( this->currentAnim != NULL)
425//       this->currentAnim->stop();
426//
427    PRINTF(0)("SET ANIMATION\n");
428    this->destDir = destDir;
429//
430
431
432    if( this->currentAnim != NULL)
433      delete this->currentAnim;
434
435    this->setAbsDir(destDir);
436/*
437    this->currentAnim = new Animation3D(this);
438    this->currentAnim->addKeyFrame(this->getAbsCoor(), this->getAbsDir(), 0.0f, ANIM_LINEAR, ANIM_LINEAR);
439    this->currentAnim->addKeyFrame(this->getAbsCoor(), this->getAbsDir(), time, ANIM_LINEAR, ANIM_LINEAR);
440    this->currentAnim->addKeyFrame(this->getAbsCoor(), this->destDir, time, ANIM_LINEAR, ANIM_LINEAR);
441
442
443    this->currentAnim->setInfinity(ANIM_INF_CONSTANT);
444    this->currentAnim->play();*/
445
446    this->setAnimation(STAND, MD2_ANIM_LOOP);
447  }
448
449  // calculate the distance
450  Vector distance = this->getAbsCoor() - this->destCoor;
451  return distance.len();
452}
453
454
455
456/**
457 * talk to a world entity and play a sound/music/voice
458 * @param worldEntity: entity
459 * @param dialogNr: sound nr to be played (from the xml load tags)
460 */
461float GenericNPC::talkTo(WorldEntity* worldEntity, int dialogNr)
462{}
463
464
465/**
466 * world entity to shoot at if there is any weapon on the npc
467 * @param entity: entity to shoot entity
468 */
469void GenericNPC::shootAt(WorldEntity* entity)
470{}
471
472
473
474
475
476
477
478
479
480
481/**
482 * tick this world entity
483 * @param time: time in seconds expirded since the last tick
484 */
485void GenericNPC::tick (float time)
486{
487  if( likely(this->getModel(0) != NULL))
488    ((InteractiveModel*)this->getModel(0))->tick(time);
489
490}
491
492
493
494void GenericNPC::destroy()
495{
496  int randi = (int)(5.0f * (float)rand()/(float)RAND_MAX);
497
498  if( randi == 1)
499    this->setAnimation(DEATH_FALLBACK, MD2_ANIM_ONCE);
500  else if( randi == 2)
501    this->setAnimation(DEATH_FALLFORWARD, MD2_ANIM_ONCE);
502  else if( randi == 3)
503    this->setAnimation(DEATH_FALLBACKSLOW, MD2_ANIM_ONCE);
504  else if( randi == 4)
505    this->setAnimation(CROUCH_DEATH, MD2_ANIM_ONCE);
506  else
507    this->setAnimation(DEATH_FALLBACK, MD2_ANIM_ONCE);
508}
509
Note: See TracBrowser for help on using the repository browser.