Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8829 was 8829, checked in by snellen, 18 years ago

continued working on turning:turning doesn't quite work

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