Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/world_entities/creatures/fps_player.cc @ 10698

Last change on this file since 10698 was 10698, checked in by snellen, 17 years ago

merged adm, hud, vs-enhancements : beni's responsible for this commit. blame him!

File size: 16.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: Patrick Boenzli
13   co-programmer: ...
14
15*/
16
17#include "fps_player.h"
18
19#include "interactive_model.h"
20#include "state.h"
21#include "tools/camera.h"
22#include "player.h"
23
24#include "src/lib/util/loading/factory.h"
25
26#include "md2/md2Model.h"
27
28#include "weapons/weapon_manager.h"
29#include "weapons/test_gun.h"
30#include "weapons/turret.h"
31#include "weapons/cannon.h"
32#include "weapons/fps_sniper_rifle.h"
33#include "weapons/aiming_system.h"
34
35#include "aabb.h"
36#include "environments/bsp_entity.h"
37
38#include "key_mapper.h"
39
40#include "debug.h"
41
42#include "shared_network_data.h"
43
44
45
46ObjectListDefinition(FPSPlayer);
47CREATE_FACTORY(FPSPlayer);
48
49#include "script_class.h"
50CREATE_SCRIPTABLE_CLASS(FPSPlayer,
51                        addMethod("setAbsCoor", Executor3<PNode, lua_State*,float,float,float>(&PNode::setAbsCoor))
52                            ->addMethod("getAbsCoorX", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorX))
53                            ->addMethod("getAbsCoorY", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorY))
54                            ->addMethod("getAbsCoorZ", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorZ))
55                            ->addMethod("displayHUDText", Executor1<FPSPlayer, lua_State*, const std::string&>(&FPSPlayer::displayHUDText))
56                       );
57
58
59/**
60 *  destructs the FPSPlayer, deletes alocated memory
61 */
62FPSPlayer::~FPSPlayer ()
63{
64  this->setPlayer(NULL);
65
66  if( this->aimingSystem)
67    delete this->aimingSystem;
68}
69
70
71/**
72 *  creates a new FPSPlayer from Xml Data
73 * @param root the xml element containing FPSPlayer data
74 *
75 */
76FPSPlayer::FPSPlayer(const TiXmlElement* root)
77{
78  if (root != NULL)
79    this->loadParams(root);
80
81    this->updateNode(0.001);
82    this->init();
83}
84
85
86/**
87 * initializes a FPSPlayer
88 */
89void FPSPlayer::init()
90{
91  this->registerObject(this, FPSPlayer::_objectList);
92
93  this->bLeft = false;
94  this->bRight = false;
95  this->bForward = false;
96  this->bBackward = false;
97  this->bJump = false;
98  this->bPosBut = false;
99  this->bFire = false;
100  this->bFire2 = false;
101  this->changeZoom = true;
102  this->inZoomMode = false;
103  this->changingZoom = false;
104
105  this->xMouse = 0.0f;
106  this->yMouse = 0.0f;
107
108  this->setHealthMax(100);
109  this->setHealth(80);
110
111  this->fallVelocity = 0.0f;
112  this->jumpAcceleration = 0.0f;
113
114  this->cameraNode.setParent(this);
115
116  this->attitude = this->getAbsDir().getAttitude();
117  this->heading = this->getAbsDir().getHeading();
118
119  //add events to the eventlist
120  registerEvent(KeyMapper::PEV_FORWARD);
121  registerEvent(KeyMapper::PEV_BACKWARD);
122  registerEvent(KeyMapper::PEV_LEFT);
123  registerEvent(KeyMapper::PEV_RIGHT);
124  registerEvent(KeyMapper::PEV_FIRE1);
125  registerEvent(KeyMapper::PEV_FIRE2);
126  registerEvent(KeyMapper::PEV_JUMP);
127  registerEvent(KeyMapper::PEV_CROUCH);
128  registerEvent(EV_MOUSE_MOTION);
129
130  this->aimingSystem = NULL;
131
132  // weapon manager for the fps
133  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
134
135  if( State::isOnline())
136  {
137    Weapon* wpRight = new FPSSniperRifle(0);
138    wpRight->setName("testGun Right");
139    this->addWeapon(wpRight,1, 0);
140    wpRight->addChild(this->aimingSystem);
141
142    this->toList( OM_PLAYERS );
143  }
144
145  this->aimingSystem = new AimingSystem(this);
146
147
148  this->getWeaponManager().changeWeaponConfig(1);
149  this->getWeaponManager().setSlotCount(2);
150  this->getWeaponManager().setSlotDirection(0, Quaternion(M_PI_4*-0.55f, Vector(0,0,1)));
151  this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
152  this->getWeaponManager().setSlotDirection(1, Quaternion(M_PI_4*.5, Vector(1,0,0)));
153  this->getWeaponManager().setSlotPosition(0, Vector(1.5, -0.7, 1.1));
154  this->getWeaponManager().setSlotPosition(1, Vector(5.0, 0.0, 0.0));
155
156  this->getWeaponManager().setParentNode(&this->cameraNode);
157  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
158
159  this->getWeaponManager().getFixedTarget()->setParent(&this->cameraNode);
160  this->getWeaponManager().getFixedTarget()->setParentMode(PNODE_ALL);
161  this->getWeaponManager().getFixedTarget()->setRelCoor(10,0,0);
162
163
164  // network registration
165  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
166  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
167  registerVar( new SynchronizeableBool( &bForward, &bForward, "bForward", PERMISSION_OWNER ) );
168  registerVar( new SynchronizeableBool( &bBackward, &bBackward, "bBackward", PERMISSION_OWNER ) );
169  registerVar( new SynchronizeableBool( &bJump, &bJump, "bJump", PERMISSION_OWNER ) );
170  registerVar( new SynchronizeableFloat( &heading, &heading, "heading", PERMISSION_OWNER ) );
171  registerVar( new SynchronizeableFloat( &attitude, &attitude, "attitude", PERMISSION_OWNER ) );
172
173    //subscribe to collision reaction
174  this->subscribeReaction(CoRe::CREngine::CR_PHYSICS_FULL_WALK, BspEntity::staticClassID());
175
176  this->initWeapon = false;
177  this->damageTicker = 0.0f;
178
179}
180
181
182/**
183 * loads the Settings of a FPSPlayer from an XML-element.
184 * @param root the XML-element to load the Spaceship's properties from
185 */
186void FPSPlayer::loadParams(const TiXmlElement* root)
187{
188  Playable::loadParams(root);
189}
190
191/**
192 * was probabably designed for setting direction of FPSPlayer
193 * but hey, this connot work like this, can it?
194 */
195void FPSPlayer::setPlayDirection(const Quaternion& quat, float speed)
196{
197  this->attitude = this->getAbsDir().getAttitude();
198  this->heading = this->getAbsDir().getHeading();
199}
200
201/**
202 * Resets FPSPlayer stats and freezes its moving directions
203 *
204 */
205void FPSPlayer::reset()
206{
207  this->bLeft = false;
208  this->bRight = false;
209  this->bForward = false;
210  this->bBackward = false;
211  this->xMouse = 0.0f;
212  this->yMouse = 0.0f;
213  this->inZoomMode = false;
214
215  this->setHealth(80);
216}
217
218/**
219 * Defines what happens to camera and other important elements when changing
220 * into FPS-view
221 */
222void FPSPlayer::enter()
223{
224  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( true );
225
226  State::getCameraNode()->setParentSoft(&this->cameraNode);
227  State::getCameraTargetNode()->setParentSoft(&this->cameraNode);
228 
229  State::getCamera()->setViewMode(Camera::ViewFPS);
230 
231  this->getWeaponManager().getFixedTarget()->setParent(&this->cameraNode);
232  //this->getWeaponManager().getFixedTarget()->setParentMode(PNODE_ALL);
233  //this->getWeaponManager().getFixedTarget()->setRelCoor(100,0,0);
234
235  if ( !State::isOnline() )
236  {
237    this->respawn();
238  }
239}
240
241/**
242 * Defines what happens if active player leaves FPSPlayer
243 * (basicly hides crosshair and frees camera)
244 */
245void FPSPlayer::leave()
246{
247  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
248  this->detachCamera();
249}
250
251
252
253/**
254 *  the function called for each passing timeSnap
255 * @param time The timespan passed since last update
256 */
257void FPSPlayer::tick (float time)
258{
259     // Second init-step
260  if ( !this->initWeapon )
261  {
262    this->initWeapon = true;
263
264    this->cameraNode.setParentMode(PNODE_ROTATE_AND_MOVE);
265
266    this->getWeaponManager().getParentNode()->setParentMode(PNODE_ROTATE_AND_MOVE);
267    this->getWeaponManager().getFixedTarget()->setParent(&this->cameraNode);
268    //this->getWeaponManager().getFixedTarget()->setParentMode(PNODE_ROTATE_AND_MOVE);
269    State::getCamera()->setViewMode(Camera::ViewFPS);
270
271
272    if( this->aimingSystem != NULL)
273    {
274      this->aimingSystem->toList(OM_GROUP_01);
275      this->aimingSystem->setParent(&this->cameraNode);
276  //     this->aimingSystem->setParentMode(PNODE_ROTATE_AND_MOVE);
277      this->aimingSystem->setRelDir(Quaternion(M_PI_4*-0.58f, Vector(0,0,1)));
278      this->aimingSystem->setRelCoor(0, -1, -1);
279    }
280
281  }
282  // end of second init-step
283 
284  // This box represents the dimension of the used model
285  AABB* box = this->getModelAABB();
286
287  if( box != NULL)
288  {
289      float f = 1.0;
290      if( this->bCrouch )
291          f = 0.3*f;
292     
293      this->cameraNode.setRelCoor(0, box->halfLength[1] * f, 0);
294//      this->cameraNode.setRelCoor(10, box->halfLength[1] * f, 0);
295     float v = 0.1f;
296     this->getWeaponManager().setSlotPosition(0, Vector(-8.0, box->halfLength[1] * v, 1.1));
297     this->getWeaponManager().setSlotPosition(1, Vector(5.0, box->halfLength[1] * v, 0.0));
298  }
299 
300  /*
301  if( this->bFire2 )
302  {
303     
304      // to change Zoom on click
305      if( this->changeZoom )
306      {
307          this->changeZoom = false;
308          if( this->inZoomMode )
309          {
310              State::getCamera()->setViewMode(Camera::ViewFPS);
311              this->inZoomMode = false;
312          }
313          else
314          {
315              State::getCamera()->setViewMode(Camera::ViewFPSZoom);
316              this->inZoomMode = true;
317          }
318         
319      }
320     
321  }
322  else
323  {
324      this->changeZoom = true;
325  }*/
326  if( this->bFire2 )
327  {
328      if( this->changeZoom )
329      {
330          if( !this->inZoomMode || this->changingZoom )
331          {
332              this->inZoomMode = true;
333              this->changingZoom = true;
334              float fovy = State::getCamera()->getFovy();
335              if( fovy > 30 )
336                  State::getCamera()->setFovy( fovy - 10*time );
337          }
338          else
339          {
340                State::getCamera()->setViewMode(Camera::ViewFPS);
341                this->inZoomMode = false;
342                this->changeZoom = false;
343          }
344      }
345  }
346  else
347  {
348      this->changeZoom = true;
349      this->changingZoom = false;
350  }
351
352  this->getWeaponManager().tick(time);
353  if( this->bFire)
354  {
355    this->getWeaponManager().fire();
356  }
357
358
359  //dealing damage
360  if ( State::isOnline() && (SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/))
361  {
362    this->damageTicker -= time;
363
364    if ( this->damageTicker <= 0.0f && this->beFire() )
365    {
366      this->damageTicker = 0.25;
367
368      WorldEntity * victim = aimingSystem->getNearestTarget();
369
370      if ( victim )
371      {
372        PRINTF(0)("FIRE: hit %s\n", victim->getClassCName());
373        victim->hit( 20, this );
374      }
375      else
376      {
377        PRINTF(0)("FIRE: nothing hit\n");
378      }
379    }
380  }
381
382
383  if( ( xMouse != 0 || yMouse != 0 ) && (this->getOwner() == SharedNetworkData::getInstance()->getHostID() || !State::isOnline() ) )
384  {
385    xMouse *= time ;
386    yMouse *= time ;
387   
388    float amount;
389   
390    if( this->inZoomMode )
391        amount = 2.;
392    else
393        amount = 5.;
394
395    heading -= xMouse/amount;
396    attitude-= yMouse/amount;
397
398
399    if ( attitude > 1.95 )
400      attitude = 1.95;
401    else if ( attitude < -1.07 )
402      attitude = -1.07;
403
404    xMouse = yMouse = 0;
405  }
406
407  this->setAbsDir(Quaternion(heading, Vector(0,1,0)));
408  this->cameraNode.setRelDir(Quaternion( attitude, Vector( 0, 0, 1 ) ));
409
410  Vector velocity;
411
412  if ( this->bForward )
413  {
414    velocity += this->getAbsDirX();
415  }
416
417  if ( this->bBackward )
418  {
419    velocity -= this->getAbsDirX();
420  }
421
422  if ( this->bRight )
423  {
424    velocity += this->getAbsDirZ();
425  }
426
427  if ( this->bLeft )
428  {
429    velocity -= this->getAbsDirZ();
430  }
431
432  // Uncomment this if you want your current position to be prined to the console when you press the jump button
433  /* if( this->bJump)
434    {
435      printf("panicGuy:runTo( %f, %f, %f ) \n", this->getAbsCoorX(), this->getAbsCoorY(), this->getAbsCoorZ() );
436      this->bJump = false;
437    }*/
438
439  int speed;
440  if( this->bCrouch )
441      speed = 50;
442  else
443      speed = 100;
444  velocity *= speed;
445
446  if( this->getModel( 0) != NULL && this->getModel(0)->isA(InteractiveModel::staticClassID()))
447  {
448      if( this->bJump)
449      {
450          if( this->jumpAcceleration < 1.0f)
451          {
452              this->jumpAcceleration = 300.0f;
453
454              if( ((InteractiveModel*)this->getModel(0))->getAnimation() != JUMP)
455                  ((InteractiveModel*)this->getModel(0))->setAnimation(JUMP);
456          }
457       }
458       else if(velocity.len() != 0.0f)
459       {
460            if( this->bCrouch )
461            {
462                if( ((InteractiveModel*)this->getModel(0))->getAnimation() != CROUCH_WALK)
463                    ((InteractiveModel*)this->getModel(0))->setAnimation(CROUCH_WALK);
464            }
465            else
466            {
467                if( ((InteractiveModel*)this->getModel(0))->getAnimation() != RUN)
468                    ((InteractiveModel*)this->getModel(0))->setAnimation(RUN); 
469            }
470                 
471       }
472       else
473       {
474           if( this->bCrouch )
475           {
476               if( ((InteractiveModel*)this->getModel(0))->getAnimation() != CROUCH_STAND)
477                   ((InteractiveModel*)this->getModel(0))->setAnimation(CROUCH_STAND);
478           }
479           else
480           {
481               if( ((InteractiveModel*)this->getModel(0))->getAnimation() != STAND)
482                   ((InteractiveModel*)this->getModel(0))->setAnimation(STAND);
483           }
484       }
485       
486       if( this->bFire )
487       {
488           if( this->bCrouch )
489           {
490               if( ((InteractiveModel*)this->getModel(0))->getAnimation() != CROUCH_ATTACK)
491                   ((InteractiveModel*)this->getModel(0))->setAnimation(CROUCH_ATTACK);
492           }
493           else
494           {
495               if( ((InteractiveModel*)this->getModel(0))->getAnimation() != ATTACK)
496                   ((InteractiveModel*)this->getModel(0))->setAnimation(ATTACK);
497           }
498       }
499  }
500
501
502  velocity.y += this->jumpAcceleration;
503  if( this->jumpAcceleration > 1.0f)
504    this->jumpAcceleration *= pow(0.9f,time*100);
505
506
507  // physical falling of the player
508  if( !this->isOnGround())
509  {
510    if(this->fallVelocity + 300.0F*time < 10000.0f)this->fallVelocity += 300.0f * time;
511    velocity -= Vector(0.0, 1.0, 0.0) * this->fallVelocity;
512
513//     PRINTF(0)("vel %f\n", this->fallVelocity);
514  }
515  else
516  {
517    this->fallVelocity = 0.0f;
518  }
519  if((velocity * time).len() < 10.0f) this->shiftCoor( velocity*time );
520  else
521  {     
522         velocity.normalize();
523         velocity *= 10.0f;
524         this->shiftCoor( velocity );
525  }
526
527
528
529  if( likely(this->getModel(0) != NULL) && this->getModel(0)->isA(InteractiveModel::staticClassID()))
530  {
531    ((InteractiveModel*)this->getModel(0))->tick(time);
532  }
533
534  this->setOnGround(false);
535  if( this->aimingSystem != NULL)
536    this->aimingSystem->flushList();
537   
538}
539
540
541
542/**
543 *  draws the MD2Creature after transforming it.
544 */
545void FPSPlayer::draw () const
546{
547  // only draw if this entity is not the player since the player nevers sees himself
548  if( this->getCurrentPlayer() == NULL)
549    WorldEntity::draw();
550}
551
552
553
554/**
555 * checks events
556 */
557void FPSPlayer::process(const Event &event)
558{
559  Playable::process(event);
560
561  if( event.type == KeyMapper::PEV_LEFT)
562    this->bLeft = event.bPressed;
563  else if( event.type == KeyMapper::PEV_RIGHT)
564    this->bRight = event.bPressed;
565  else if( event.type == KeyMapper::PEV_FORWARD)
566    this->bForward = event.bPressed; //this->shiftCoor(0,.1,0);
567  else if( event.type == KeyMapper::PEV_BACKWARD)
568    this->bBackward = event.bPressed; //this->shiftCoor(0,-.1,0);
569  else if( event.type == KeyMapper::PEV_JUMP)
570    this->bJump = event.bPressed;
571  else if( event.type == KeyMapper::PEV_FIRE1)
572    this->bFire = event.bPressed;
573  else if( event.type == KeyMapper::PEV_FIRE2)
574    this->bFire2 = event.bPressed;
575  else if( event.type == KeyMapper::PEV_CROUCH)
576    this->bCrouch = event.bPressed;
577  else if( event.type == EV_MOUSE_MOTION)
578  {
579    this->xMouse += event.xRel;
580    this->yMouse += event.yRel;
581  }
582}
583
584/**
585 * respawns FPSplayer
586 */
587void FPSPlayer::respawn( )
588{
589  if( State::isOnline())
590    toList( OM_PLAYERS );
591
592  this->damageTicker = 0.0f;
593
594  Playable::respawn();
595}
596
597/**
598 * Kills the FPSplayer defining its killer
599 */
600void FPSPlayer::destroy( WorldEntity* killer )
601{
602  Playable::destroy( killer );
603
604  toList( OM_DEAD );
605}
606
607void FPSPlayer::displayHUDText( const std::string& message )
608{
609        State::getPlayer()->hud().notifyUser(message);
610}
Note: See TracBrowser for help on using the repository browser.