Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/single_player_map/src/world_entities/npcs/generic_npc.cc @ 8957

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

animation should be initialized correctly now

File size: 9.8 KB
RevLine 
[8514]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
[8908]19#include "generic_npc.h"
[8514]20
[8908]21
[8514]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
[8516]28#include "sound_buffer.h"
29
30#include "loading/resource_manager.h"
31
[8514]32
33CREATE_FACTORY(GenericNPC, CL_GENERIC_NPC);
34
[8894]35#include "script_class.h"
36CREATE_SCRIPTABLE_CLASS(GenericNPC, CL_GENERIC_NPC,
[8913]37                        // Move
[8908]38                        addMethod("walkTo", ExecutorLua3<GenericNPC,float,float,float>(&GenericNPC::walkTo))
[8917]39                        ->addMethod("runTo", ExecutorLua3<GenericNPC,float,float,float>(&GenericNPC::runTo))
[8908]40                        ->addMethod("turnTo", ExecutorLua1<GenericNPC,float>(&GenericNPC::turnTo))
[8917]41                        ->addMethod("finalGoalReached", ExecutorLua0ret<GenericNPC,bool>(&GenericNPC::finalGoalReached))
[8913]42                        // Display
[8894]43                        ->addMethod("hide", ExecutorLua0<WorldEntity>(&WorldEntity::hide))
44                        ->addMethod("unhide", ExecutorLua0<WorldEntity>(&WorldEntity::unhide))
[8913]45                        // Coordinates
[8894]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))
[8908]51
[8894]52                       );
[8514]53
54
[8894]55
[8514]56/**
57 * constructor
58 */
59GenericNPC::GenericNPC(const TiXmlElement* root)
[8913]60    : NPC(root)
[8514]61{
62  this->init();
63
64  if (root != NULL)
65    this->loadParams(root);
66}
67
68
69/**
70 * deconstructor
71 */
72GenericNPC::~GenericNPC ()
[8913]73{}
[8514]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);
[8516]83
84  if (this->soundBuffer != NULL)
85    ResourceManager::getInstance()->unload(this->soundBuffer);
86  this->soundBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/rain.wav", WAV);
[8705]87
[8894]88  time = 30.0f;
[8705]89  // collision reaction registration
[8913]90  //   this->subscribeReaction(CREngine::CR_PHYSICS_GROUND_WALK, CL_BSP_ENTITY);
[8514]91}
92
93
94/**
95 * loads the Settings of a MD2Creature from an XML-element.
96 * @param root the XML-element to load the MD2Creature's properties from
97 */
98void GenericNPC::loadParams(const TiXmlElement* root)
99{
[8705]100  NPC::loadParams(root);
[8514]101
102}
103
104
105/**
106 * sets the animation of this npc
107 * @param anumationIndex: the animation index
108 * @param anumPlaybackMode: the playback mode
109 */
110void GenericNPC::setAnimation(int animationIndex, int animPlaybackMode)
111{
112  if( likely(this->getModel(0) != NULL))
113    ((InteractiveModel*)this->getModel(0))->setAnimation(animationIndex, animPlaybackMode);
114}
115
116
[8951]117
[8514]118/**
[8951]119 * @returns the current animation number
120 */
121int GenericNPC::getAnimation()
122{
123  if( likely(this->getModel(0) != NULL))
124    return ((InteractiveModel*)this->getModel(0))->getAnimation();
125  else
126    return -1;
127}
128
129
130
131/**
132 * @returns true if animation is finished
133 */
134bool GenericNPC::isAnimationFinished()
135{
136  if( likely(this->getModel(0) != NULL))
137    return ((InteractiveModel*)this->getModel(0))->isAnimationFinished();
138  else
139    return false;
140}
141
142
143
144/**
[8514]145 * sets the animation of this npc
146 * @param anumationIndex: the animation index
147 * @param anumPlaybackMode: the playback mode
148 */
[8705]149void GenericNPC::playAnimation(int animationIndex, int animPlaybackMode)
[8514]150{
151  if( likely(this->getModel(0) != NULL))
152    ((InteractiveModel*)this->getModel(0))->setAnimation(animationIndex, animPlaybackMode);
153
154}
155
156
157/**
158 * play a sound
159 * @param filename: name of the file
160 */
[8705]161void GenericNPC::playSound(std::string filename)
[8913]162{}
[8705]163
[8514]164
165
[8894]166/**
[8908]167 * stops the generic animation
[8894]168 */
[8908]169void GenericNPC::stop()
[8913]170{}
171
[8953]172
[8957]173
174void GenericNPC::initNPC()
175{
176  if (!this->behaviourList.empty())
177  {
178    switch(this->behaviourList.front().type)
179    {
180      case Walk:
181        if( this->getAnimation() != RUN)
182          this->setAnimation(RUN, MD2_ANIM_LOOP);
183        break;
184      case Run:
185        if( this->getAnimation() != RUN)
186          this->setAnimation(RUN, MD2_ANIM_LOOP);
187        break;
188      case Crouch:
189        if( this->getAnimation() != CROUCH_WALK)
190          this->setAnimation(CROUCH_WALK, MD2_ANIM_LOOP);
191        break;
192      case LookAt:
193        if( this->getAnimation() != STAND)
194          this->setAnimation(STAND, MD2_ANIM_LOOP);
195        break;
196      case Shoot:
197        if( this->getAnimation() != STAND)
198          this->setAnimation(STAND, MD2_ANIM_LOOP);
199        break;
200
201      default:
202        if( this->getAnimation() != STAND)
203          this->setAnimation(STAND, MD2_ANIM_LOOP);
204        break;
205
206    }
207  }
208}
209
210
[8913]211void GenericNPC::nextStep()
[8894]212{
[8913]213  if (!this->behaviourList.empty())
214    this->behaviourList.pop_front();
215  else
216    return;
[8802]217
[8913]218  if (!this->behaviourList.empty())
219  {
220    switch(this->behaviourList.front().type)
221    {
222      case Walk:
[8955]223        if( this->getAnimation() != RUN)
224          this->setAnimation(RUN, MD2_ANIM_LOOP);
[8913]225        break;
226      case Run:
[8955]227        if( this->getAnimation() != RUN)
228          this->setAnimation(RUN, MD2_ANIM_LOOP);
[8913]229        break;
230      case Crouch:
[8955]231        if( this->getAnimation() != CROUCH_WALK)
232          this->setAnimation(CROUCH_WALK, MD2_ANIM_LOOP);
[8913]233        break;
234      case LookAt:
[8955]235        if( this->getAnimation() != STAND)
236          this->setAnimation(STAND, MD2_ANIM_LOOP);
[8913]237        break;
238      case Shoot:
[8955]239        if( this->getAnimation() != STAND)
[8913]240        this->setAnimation(STAND, MD2_ANIM_LOOP);
241        break;
242
243      default:
[8955]244        if( this->getAnimation() != STAND)
[8913]245        this->setAnimation(STAND, MD2_ANIM_LOOP);
246        break;
247
248    }
249  }
250  else
251  {
252    this->setAnimation(STAND, MD2_ANIM_LOOP);
253  }
[8894]254}
255
[8802]256
[8957]257
258
[8908]259void GenericNPC::walkTo(const Vector& coordinate)
[8805]260{
[8936]261
[8909]262  GenericNPC::Anim anim;
263  anim.v = coordinate;
264  anim.type = Walk;
[8955]265  anim.speed = 30.0f;
[8909]266
[8955]267  if( this->behaviourList.empty())
268  {
269    this->behaviourList.push_back(anim);
[8957]270    this->initNPC();
[8955]271  }
272  else
273    this->behaviourList.push_back(anim);
[8805]274}
275
[8908]276void GenericNPC::walkTo(float x, float y, float z)
[8909]277{
[8952]278  //printf("Walking to %f, %f, %f \n",x,y,z);
[8909]279  this->walkTo(Vector(x,y,z));
[8894]280
[8909]281}
282
[8908]283/* running functions */
284void GenericNPC::runTo(const Vector& coordinate)
[8909]285{
286  GenericNPC::Anim anim;
287  anim.v = coordinate;
288  anim.type = Run;
289
[8957]290  if( this->behaviourList.empty())
291  {
292    this->behaviourList.push_back(anim);
293    this->initNPC();
294  }
295  else
296    this->behaviourList.push_back(anim);
[8909]297}
298
[8908]299void GenericNPC::runTo(float x, float y, float z)
[8909]300{
301  this->runTo(Vector(x,y,z));
302}
[8894]303
[8908]304/* couching functinos */
305void GenericNPC::crouchTo(const Vector& coordinate)
[8909]306{
307  GenericNPC::Anim anim;
308  anim.v = coordinate;
309  anim.type = Crouch;
310
[8957]311  if( this->behaviourList.empty())
312  {
313    this->behaviourList.push_back(anim);
314    this->initNPC();
315  }
316  else
317    this->behaviourList.push_back(anim);
[8909]318}
[8908]319void GenericNPC::crouchTo(float x, float y, float z)
[8909]320{
321  this->crouchTo(Vector(x,y,z));
322}
[8894]323
324
325
[8908]326void GenericNPC::turnTo(float degreeInY)
[8909]327{
328  GenericNPC::Anim anim;
329  anim.q = Quaternion(Vector(0,1,0), degreeInY);
330  anim.type = TurnTo;
[8894]331
[8957]332  if( this->behaviourList.empty())
333  {
334    this->behaviourList.push_back(anim);
335    this->initNPC();
336  }
337  else
338    this->behaviourList.push_back(anim);
[8909]339}
[8894]340
341
[8909]342
[8894]343/**
344 * lookat a world entity
345 * @param worldEntity: the worldentity to look at
346 */
[8908]347void GenericNPC::lookAt(WorldEntity* worldEntity)
[8909]348{
349  GenericNPC::Anim anim;
350  anim.entity = worldEntity;
351  anim.type = LookAt;
[8894]352
[8957]353  if( this->behaviourList.empty())
354  {
355    this->behaviourList.push_back(anim);
356    this->initNPC();
357  }
358  else
359    this->behaviourList.push_back(anim);
[8909]360}
[8894]361
362
363
[8909]364
[8894]365/**
366 * talk to a world entity and play a sound/music/voice
367 * @param worldEntity: entity
368 * @param dialogNr: sound nr to be played (from the xml load tags)
369 */
[8908]370void GenericNPC::talkTo(WorldEntity* worldEntity, int dialogNr)
[8894]371{}
372
373
374/**
375 * world entity to shoot at if there is any weapon on the npc
376 * @param entity: entity to shoot entity
377 */
378void GenericNPC::shootAt(WorldEntity* entity)
379{}
380
381
382
383
384
385
386
387
388
389
390/**
[8514]391 * tick this world entity
392 * @param time: time in seconds expirded since the last tick
393 */
[8914]394void GenericNPC::tick (float dt)
[8514]395{
396  if( likely(this->getModel(0) != NULL))
[8936]397    ((InteractiveModel*)this->getModel(0))->tick(dt);
[8894]398
[8909]399
400  if (!this->behaviourList.empty())
401  {
[8951]402    GenericNPC::Anim currentAnimation = this->behaviourList.front();
403    switch( currentAnimation.type)
[8909]404    {
405      case Walk:
[8913]406        {
[8951]407
[8953]408          Vector dest = currentAnimation.v - this->getAbsCoor();
409          if (dest.len() < .5)
[8914]410            this->nextStep();
411          else
412          {
[8954]413            this->shiftCoor(dest.getNormalized() * currentAnimation.speed * dt);
[8914]414          }
[8913]415        }
[8909]416        break;
[8951]417
[8909]418      case Run:
419        break;
[8951]420
[8909]421      case Crouch:
422        break;
[8951]423
[8914]424      case TurnTo:
425        //Quaternion direction = this->
426        break;
[8951]427
[8909]428      case LookAt:
429        break;
[8951]430
[8909]431      case Shoot:
432        break;
433
[8913]434      default:
435        break;
436
[8909]437    }
438  }
439
[8514]440}
441
442
443
444void GenericNPC::destroy()
445{
446  int randi = (int)(5.0f * (float)rand()/(float)RAND_MAX);
447
448  if( randi == 1)
449    this->setAnimation(DEATH_FALLBACK, MD2_ANIM_ONCE);
450  else if( randi == 2)
451    this->setAnimation(DEATH_FALLFORWARD, MD2_ANIM_ONCE);
452  else if( randi == 3)
453    this->setAnimation(DEATH_FALLBACKSLOW, MD2_ANIM_ONCE);
454  else if( randi == 4)
455    this->setAnimation(CROUCH_DEATH, MD2_ANIM_ONCE);
456  else
457    this->setAnimation(DEATH_FALLBACK, MD2_ANIM_ONCE);
458}
459
Note: See TracBrowser for help on using the repository browser.