Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

npc does not yet move again. strange

File size: 12.6 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#include "generic_npc.h"
20
21
22#include "util/loading/factory.h"
23#include "util/loading/load_param.h"
24
25#include "interactive_model.h"
26#include "md2/md2Model.h"
27
28#include "sound_buffer.h"
29
30#include "loading/resource_manager.h"
31
32
33CREATE_FACTORY(GenericNPC, CL_GENERIC_NPC);
34
35#include "script_class.h"
36CREATE_SCRIPTABLE_CLASS(GenericNPC, CL_GENERIC_NPC,
37                        // Move
38                        addMethod("walkTo", ExecutorLua3<GenericNPC,float,float,float>(&GenericNPC::walkTo))
39                        ->addMethod("runTo", ExecutorLua3<GenericNPC,float,float,float>(&GenericNPC::runTo))
40                        ->addMethod("turnTo", ExecutorLua1<GenericNPC,float>(&GenericNPC::turnTo))
41                        ->addMethod("finalGoalReached", ExecutorLua0ret<GenericNPC,bool>(&GenericNPC::finalGoalReached))
42                        // Display
43                        ->addMethod("hide", ExecutorLua0<WorldEntity>(&WorldEntity::hide))
44                        ->addMethod("unhide", ExecutorLua0<WorldEntity>(&WorldEntity::unhide))
45                        // Coordinates
46                        ->addMethod("getAbsCoorX", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorX))
47                        ->addMethod("getAbsCoorY", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorY))
48                        ->addMethod("getAbsCoorZ", ExecutorLua0ret<PNode, float>(&PNode::getAbsCoorZ))
49                        ->addMethod("setAbsCoor", ExecutorLua3<PNode,float,float,float>(&PNode::setAbsCoor))
50                        ->addMethod("setAbsDir", ExecutorLua4<PNode,float,float,float,float>(&PNode::setAbsDir))
51
52                       );
53
54
55
56/**
57 * constructor
58 */
59GenericNPC::GenericNPC(const TiXmlElement* root)
60    : NPC(root)
61{
62  this->init();
63
64  if (root != NULL)
65    this->loadParams(root);
66}
67
68
69/**
70 * deconstructor
71 */
72GenericNPC::~GenericNPC ()
73{}
74
75
76/**
77 * initializing the npc enity
78 */
79void GenericNPC::init()
80{
81  this->setClassID(CL_GENERIC_NPC, "GenericNPC");
82  this->toList(OM_GROUP_00);
83
84  if (this->soundBuffer != NULL)
85    ResourceManager::getInstance()->unload(this->soundBuffer);
86  this->soundBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/rain.wav", WAV);
87
88  time = 30.0f;
89
90  // collision reaction registration
91//   this->subscribeReaction(CREngine::CR_PHYSICS_GROUND_WALK, CL_BSP_ENTITY);
92}
93
94
95/**
96 * loads the Settings of a MD2Creature from an XML-element.
97 * @param root the XML-element to load the MD2Creature's properties from
98 */
99void GenericNPC::loadParams(const TiXmlElement* root)
100{
101  NPC::loadParams(root);
102
103}
104
105
106/**
107 * sets the animation of this npc
108 * @param anumationIndex: the animation index
109 * @param anumPlaybackMode: the playback mode
110 */
111void GenericNPC::setAnimation(int animationIndex, int animPlaybackMode)
112{
113  if( likely(this->getModel(0) != NULL))
114    ((InteractiveModel*)this->getModel(0))->setAnimation(animationIndex, animPlaybackMode);
115}
116
117
118
119/**
120 * @returns the current animation number
121 */
122int GenericNPC::getAnimation()
123{
124  if( likely(this->getModel(0) != NULL))
125    return ((InteractiveModel*)this->getModel(0))->getAnimation();
126  else
127    return -1;
128}
129
130
131
132/**
133 * @returns true if animation is finished
134 */
135bool GenericNPC::isAnimationFinished()
136{
137  if( likely(this->getModel(0) != NULL))
138    return ((InteractiveModel*)this->getModel(0))->isAnimationFinished();
139  else
140    return false;
141}
142
143
144/**
145 * sets the animation speed of this entity
146 */
147void GenericNPC::setAnimationSpeed(float speed)
148{
149  if( likely(this->getModel(0) != NULL))
150    ((InteractiveModel*)this->getModel(0))->setAnimationSpeed(speed);
151}
152
153
154
155/**
156 * sets the animation of this npc
157 * @param anumationIndex: the animation index
158 * @param anumPlaybackMode: the playback mode
159 */
160void GenericNPC::playAnimation(int animationIndex, int animPlaybackMode)
161{
162  if( likely(this->getModel(0) != NULL))
163    ((InteractiveModel*)this->getModel(0))->setAnimation(animationIndex, animPlaybackMode);
164
165}
166
167
168/**
169 * play a sound
170 * @param filename: name of the file
171 */
172void GenericNPC::playSound(std::string filename)
173{}
174
175
176
177/**
178 * stops the generic animation
179 */
180void GenericNPC::stop()
181{}
182
183
184
185void GenericNPC::initNPC()
186{
187
188  this->unsubscribeReaction();
189
190  if (!this->behaviourList.empty())
191  {
192    GenericNPC::Anim currentAnimation = this->behaviourList.front();
193
194    switch(this->behaviourList.front().type)
195    {
196      case Walk:
197      {
198        if( this->getAnimation() != RUN)
199          this->setAnimation(RUN, MD2_ANIM_LOOP);
200
201        Vector dir = (currentAnimation.v - this->getAbsCoor());
202        dir.y = 0.0f;
203        dir.getNormalized();
204        this->setAbsDir(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)));
205
206        this->setAnimationSpeed(0.5f);
207      }
208        break;
209      case Run:
210      {
211        if( this->getAnimation() != RUN)
212          this->setAnimation(RUN, MD2_ANIM_LOOP);
213
214        Vector dir = (currentAnimation.v - this->getAbsCoor()).getNormalized();
215        this->setAbsDir(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)));
216
217        this->setAnimationSpeed(1.0f);
218      }
219        break;
220      case Crouch:
221      {
222        if( this->getAnimation() != CROUCH_WALK)
223          this->setAnimation(CROUCH_WALK, MD2_ANIM_LOOP);
224
225        Vector dir = (currentAnimation.v - this->getAbsCoor()).getNormalized();
226        this->setAbsDir(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)));
227
228        this->setAnimationSpeed(1.0f);
229      }
230        break;
231      case LookAt:
232        if( this->getAnimation() != STAND)
233          this->setAnimation(STAND, MD2_ANIM_LOOP);
234        break;
235      case Shoot:
236        if( this->getAnimation() != STAND)
237          this->setAnimation(STAND, MD2_ANIM_LOOP);
238        break;
239
240      default:
241        if( this->getAnimation() != STAND)
242          this->setAnimation(STAND, MD2_ANIM_LOOP);
243        break;
244
245    }
246  }
247}
248
249
250void GenericNPC::nextStep()
251{
252  if (!this->behaviourList.empty())
253    this->behaviourList.pop_front();
254  else
255    return;
256
257
258  if (!this->behaviourList.empty())
259  {
260    GenericNPC::Anim currentAnimation = this->behaviourList.front();
261
262    switch( currentAnimation.type)
263    {
264      case Walk:
265      {
266        if( this->getAnimation() != RUN)
267          this->setAnimation(RUN, MD2_ANIM_LOOP);
268
269        Vector dir = (currentAnimation.v - this->getAbsCoor());
270        dir.y = 0.0f;
271        dir.getNormalized();
272        this->setAbsDirSoft(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)), 4.0);
273
274        this->setAnimationSpeed(0.5f);
275      }
276        break;
277      case Run:
278      {
279        if( this->getAnimation() != RUN)
280          this->setAnimation(RUN, MD2_ANIM_LOOP);
281
282        Vector dir = (currentAnimation.v - this->getAbsCoor()).getNormalized();
283        this->setAbsDirSoft(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)), 4.0);
284
285        this->setAnimationSpeed(1.0f);
286      }
287        break;
288      case Crouch:
289      {
290        if( this->getAnimation() != CROUCH_WALK)
291          this->setAnimation(CROUCH_WALK, MD2_ANIM_LOOP);
292
293        Vector dir = (currentAnimation.v - this->getAbsCoor()).getNormalized();
294        this->setAbsDirSoft(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)), 4.0);
295
296        this->setAnimationSpeed(1.0f);
297      }
298        break;
299      case LookAt:
300      {
301        if( this->getAnimation() != STAND)
302          this->setAnimation(STAND, MD2_ANIM_LOOP);
303      }
304        break;
305      case Shoot:
306        if( this->getAnimation() != STAND)
307        this->setAnimation(STAND, MD2_ANIM_LOOP);
308        break;
309
310      default:
311        if( this->getAnimation() != STAND)
312        this->setAnimation(STAND, MD2_ANIM_LOOP);
313        break;
314
315    }
316  }
317  else
318  {
319    this->setAnimation(STAND, MD2_ANIM_LOOP);
320  }
321}
322
323
324
325
326void GenericNPC::walkTo(const Vector& coordinate)
327{
328
329  GenericNPC::Anim anim;
330  anim.v = coordinate;
331  anim.type = Walk;
332  anim.speed = 30.0f;
333
334  if( this->behaviourList.empty())
335  {
336    this->behaviourList.push_back(anim);
337    this->initNPC();
338  }
339  else
340    this->behaviourList.push_back(anim);
341}
342
343void GenericNPC::walkTo(float x, float y, float z)
344{
345  //printf("Walking to %f, %f, %f \n",x,y,z);
346  this->walkTo(Vector(x,y,z));
347
348}
349
350/* running functions */
351void GenericNPC::runTo(const Vector& coordinate)
352{
353  GenericNPC::Anim anim;
354  anim.v = coordinate;
355  anim.type = Run;
356  anim.speed = 60.0f;
357
358  if( this->behaviourList.empty())
359  {
360    this->behaviourList.push_back(anim);
361    this->initNPC();
362  }
363  else
364    this->behaviourList.push_back(anim);
365}
366
367void GenericNPC::runTo(float x, float y, float z)
368{
369  this->runTo(Vector(x,y,z));
370}
371
372/* couching functinos */
373void GenericNPC::crouchTo(const Vector& coordinate)
374{
375  GenericNPC::Anim anim;
376  anim.v = coordinate;
377  anim.type = Crouch;
378
379  if( this->behaviourList.empty())
380  {
381    this->behaviourList.push_back(anim);
382    this->initNPC();
383  }
384  else
385    this->behaviourList.push_back(anim);
386}
387void GenericNPC::crouchTo(float x, float y, float z)
388{
389  this->crouchTo(Vector(x,y,z));
390}
391
392
393
394void GenericNPC::turnTo(float degreeInY)
395{
396  GenericNPC::Anim anim;
397  anim.q = Quaternion(Vector(0,1,0), degreeInY);
398  anim.type = TurnTo;
399
400  if( this->behaviourList.empty())
401  {
402    this->behaviourList.push_back(anim);
403    this->initNPC();
404  }
405  else
406    this->behaviourList.push_back(anim);
407}
408
409
410
411/**
412 * lookat a world entity
413 * @param worldEntity: the worldentity to look at
414 */
415void GenericNPC::lookAt(WorldEntity* worldEntity)
416{
417  GenericNPC::Anim anim;
418  anim.entity = worldEntity;
419  anim.type = LookAt;
420
421  if( this->behaviourList.empty())
422  {
423    this->behaviourList.push_back(anim);
424    this->initNPC();
425  }
426  else
427    this->behaviourList.push_back(anim);
428}
429
430
431
432
433/**
434 * talk to a world entity and play a sound/music/voice
435 * @param worldEntity: entity
436 * @param dialogNr: sound nr to be played (from the xml load tags)
437 */
438void GenericNPC::talkTo(WorldEntity* worldEntity, int dialogNr)
439{}
440
441
442/**
443 * world entity to shoot at if there is any weapon on the npc
444 * @param entity: entity to shoot entity
445 */
446void GenericNPC::shootAt(WorldEntity* entity)
447{}
448
449
450
451
452
453
454
455
456
457
458/**
459 * tick this world entity
460 * @param time: time in seconds expirded since the last tick
461 */
462void GenericNPC::tick (float dt)
463{
464  if( likely(this->getModel(0) != NULL))
465    ((InteractiveModel*)this->getModel(0))->tick(dt);
466
467
468  if (!this->behaviourList.empty())
469  {
470    GenericNPC::Anim currentAnimation = this->behaviourList.front();
471
472    switch( currentAnimation.type)
473    {
474      case Walk:
475        {
476          Vector dest = currentAnimation.v - this->getAbsCoor();
477          if (dest.len() < .5)
478          {
479            this->nextStep();
480          }
481          else
482          {
483            dest.y = 0.0f;
484            this->shiftCoor(dest.getNormalized() * currentAnimation.speed * dt);
485          }
486        }
487        break;
488
489      case Run:
490      {
491        Vector dest = currentAnimation.v - this->getAbsCoor();
492        if (dest.len() < .5)
493          this->nextStep();
494        else
495        {
496          this->shiftCoor(dest.getNormalized() * currentAnimation.speed * dt);
497        }
498      }
499      break;
500
501      case Crouch:
502      {
503        Vector dest = currentAnimation.v - this->getAbsCoor();
504        if (dest.len() < .5)
505          this->nextStep();
506        else
507        {
508          this->shiftCoor(dest.getNormalized() * currentAnimation.speed * dt);
509        }
510      }
511      break;
512
513      case TurnTo:
514        //Quaternion direction = this->
515        break;
516
517      case LookAt:
518        break;
519
520      case Shoot:
521        break;
522
523      default:
524        break;
525
526    }
527  }
528
529  // physical falling of the player
530//   if( !this->isOnGround())
531//   {
532//     this->fallVelocity += 300.0f * dt;
533//     velocity -= Vector(0.0, 1.0, 0.0) * this->fallVelocity;
534//    // PRINTF(0)("%s is not on ground\n", this->getName());
535//     this->shiftCoor(Vector(0, -this->fallVelocity * dt,0));
536//   }
537//   else
538//   {
539//     this->fallVelocity = 0.0f;
540//   }
541
542
543
544}
545
546
547
548void GenericNPC::destroy()
549{
550  int randi = (int)(5.0f * (float)rand()/(float)RAND_MAX);
551
552  this->setAnimationSpeed(1.0f);
553
554  if( randi == 1)
555    this->setAnimation(DEATH_FALLBACK, MD2_ANIM_ONCE);
556  else if( randi == 2)
557    this->setAnimation(DEATH_FALLFORWARD, MD2_ANIM_ONCE);
558  else if( randi == 3)
559    this->setAnimation(DEATH_FALLBACKSLOW, MD2_ANIM_ONCE);
560  else if( randi == 4)
561    this->setAnimation(CROUCH_DEATH, MD2_ANIM_ONCE);
562  else
563    this->setAnimation(DEATH_FALLBACK, MD2_ANIM_ONCE);
564}
565
Note: See TracBrowser for help on using the repository browser.