Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/world_entities/player.cc @ 5832

Last change on this file since 5832 was 5829, checked in by patrick, 19 years ago

network: much work on multiplayability, does not yet work

File size: 12.8 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: Christian Meyer
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
17
18
19#include "executor/executor.h"
20#include "player.h"
21
22#include "track_manager.h"
23#include "objModel.h"
24#include "resource_manager.h"
25#include "factory.h"
26
27#include "weapons/weapon_manager.h"
28#include "weapons/test_gun.h"
29#include "weapons/turret.h"
30#include "weapons/cannon.h"
31
32#include "list.h"
33
34#include "event_handler.h"
35
36#include "event.h"
37
38using namespace std;
39
40CREATE_FACTORY(Player, CL_PLAYER);
41
42
43
44#define UP    0
45#define DOWN  1
46#define RIGHT 2
47#define LEFT  3
48#define TIME  4
49
50
51/**
52 * creates a new Player
53 * @param isFree if the player is free
54*/
55Player::Player()
56{
57  this->init();
58}
59
60/**
61 * loads a Players information from a specified file.
62 * @param fileName the name of the File to load the player from (absolute path)
63 */
64Player::Player(const char* fileName)
65{
66  this->init();
67  TiXmlDocument doc(fileName);
68
69  if(!doc.LoadFile())
70  {
71    PRINTF(2)("Loading file %s failed for player.\n", fileName);
72    return;
73  }
74
75  this->loadParams(doc.RootElement());
76}
77
78/**
79 *  creates a new Player from Xml Data
80 * @param root the xml element containing player data
81
82   @todo add more parameters to load
83*/
84Player::Player(const TiXmlElement* root)
85{
86  this->init();
87  if (root != NULL)
88    this->loadParams(root);
89
90  //weapons:
91  Weapon* wpRight = new TestGun(0);
92  wpRight->setName("testGun Right");
93  Weapon* wpLeft = new TestGun(1);
94  wpLeft->setName("testGun Left");
95  Weapon* cannon = dynamic_cast<Weapon*>(Factory::getFirst()->fabricate(CL_CANNON));
96
97  cannon->setName("BFG");
98
99  this->weaponMan->addWeapon(wpLeft, 1, 0);
100  this->weaponMan->addWeapon(wpRight,1 ,1);
101  this->weaponMan->addWeapon(cannon, 0, 6);
102
103  //this->weaponMan->addWeapon(turret, 3, 0);
104
105  this->weaponMan->changeWeaponConfig(1);
106}
107
108/**
109 *  destructs the player, deletes alocated memory
110 */
111Player::~Player ()
112{
113  /* do not delete the weapons, they are contained in the pnode tree
114  and will be deleted there.
115  this only frees the memory allocated to save the list.
116  */
117  delete this->weaponMan;
118  if( this->outData)
119    delete[] this->outData;
120  if( this->inData)
121    delete[] this->inData;
122}
123
124//#include "glgui_pushbutton.h"
125
126/**
127 * initializes a Player
128 */
129void Player::init()
130{
131//  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
132  this->setClassID(CL_PLAYER, "Player");
133
134  PRINTF(4)("PLAYER INIT\n");
135  travelSpeed = 15.0;
136  bUp = bDown = bLeft = bRight = bAscend = bDescend = false;
137  bFire = false;
138  acceleration = 10.0;
139
140//   GLGuiButton* button = new GLGuiPushButton();
141//   button->show();
142//   button->setLabel("orxonox");
143//   button->setBindNode(this);
144
145  this->weaponMan = new WeaponManager(this);
146  this->weaponMan->setSlotCount(7);
147
148  this->weaponMan->setSlotPosition(0, Vector(-2.6, .1, -3.0));
149  this->weaponMan->setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
150
151  this->weaponMan->setSlotPosition(1, Vector(-2.6, .1, 3.0));
152  this->weaponMan->setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
153
154  this->weaponMan->setSlotPosition(2, Vector(-1.5, .5, -.5));
155  this->weaponMan->setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0)));
156
157  this->weaponMan->setSlotPosition(3, Vector(-1.5, .5, .5));
158  this->weaponMan->setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0)));
159
160  this->weaponMan->setSlotPosition(4, Vector(-1.5, -.5, .5));
161  this->weaponMan->setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0)));
162
163  this->weaponMan->setSlotPosition(5, Vector(-1.5, -.5, -.5));
164  this->weaponMan->setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0)));
165//
166   this->weaponMan->setSlotPosition(6, Vector(-1, 0.0, 0));
167   this->weaponMan->setSlotCapability(6, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
168   //
169//   this->weaponMan->setSlotPosition(8, Vector(-2.5, -0.3, -2.0));
170//   this->weaponMan->setSlotDirection(8, Quaternion(-M_PI, Vector(1,0,0)));
171//
172//   this->weaponMan->setSlotPosition(9, Vector(-2.5, -0.3, 2.0));
173//   this->weaponMan->setSlotDirection(9, Quaternion(+M_PI, Vector(1,0,0)));:
174
175  this->outBufferLength = 100;
176  this->outLength = 0;
177  this->recLength = 0;
178  this->inBufferLength = 100;
179  this->inLength = 0;
180  this->sentLength = 0;
181  this->outData = new byte[this->outBufferLength];
182  this->inData = new byte[this->inBufferLength];
183}
184
185
186/**
187 * loads the Settings of a Player from an XML-element.
188 * @param root the XML-element to load the Player's properties from
189 */
190void Player::loadParams(const TiXmlElement* root)
191{
192  static_cast<WorldEntity*>(this)->loadParams(root);
193
194
195
196}
197
198/**
199 * adds a weapon to the weapon list of player
200 * @param weapon to add
201*/
202void Player::addWeapon(Weapon* weapon)
203{
204  this->weaponMan->addWeapon(weapon);
205}
206
207
208/**
209 *  removes a weapon from the player
210 * @param weapon to remove
211*/
212void Player::removeWeapon(Weapon* weapon)
213{
214  this->weaponMan->removeWeapon(weapon);
215}
216
217
218/**
219 *  effect that occurs after the player is spawned
220*/
221void Player::postSpawn ()
222{
223  //setCollision(new CollisionCluster(1.0, Vector(0,0,0)));
224}
225
226
227/**
228 *  the action occuring if the player left the game
229*/
230void Player::leftWorld ()
231{}
232
233
234WorldEntity* ref = NULL;
235/**
236 *  this function is called, when two entities collide
237 * @param entity: the world entity with whom it collides
238 *
239 * Implement behaviour like damage application or other miscellaneous collision stuff in this function
240 */
241void Player::collidesWith(WorldEntity* entity, const Vector& location)
242{
243  if (entity->isA(CL_TURRET_POWER_UP) && entity != ref)
244  {
245    this->ADDWEAPON();
246    ref = entity;
247    }
248//  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z);
249}
250
251/**
252 *  draws the player after transforming him.
253*/
254void Player::draw () const
255{
256  glMatrixMode(GL_MODELVIEW);
257  glPushMatrix();
258  /* translate */
259  glTranslatef (this->getAbsCoor ().x,
260                this->getAbsCoor ().y,
261                this->getAbsCoor ().z);
262  /* rotate */
263  Vector tmpRot = this->getAbsDir().getSpacialAxis();
264  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
265  this->model->draw();
266  glPopMatrix();
267
268  this->weaponMan->draw();
269
270  //this->debug(0);
271}
272
273
274/**
275 *  the function called for each passing timeSnap
276 * @param time The timespan passed since last update
277*/
278void Player::tick (float time)
279{
280  // player controlled movement
281  this->move(time);
282
283  this->weaponMan->tick(time);
284  // weapon system manipulation
285  this->weaponAction();
286}
287
288
289/**
290 *  action if player moves
291 * @param time the timeslice since the last frame
292*/
293void Player::move (float time)
294{
295  Vector accel(0.0, 0.0, 0.0);
296  Vector rot(0.0, 0.0, 0.0);
297  float rotVal = 0.0;
298  /* FIXME: calculating the direction and orthDirection every timeSlice is redundant! save it somewhere */
299  /* calculate the direction in which the craft is heading  */
300  Vector direction (1.0, 0.0, 0.0);
301  //direction = this->absDirection.apply (direction);
302  Vector orthDirection (0.0, 0.0, 1.0);
303  //orthDirection = orthDirection.cross (direction);
304
305
306  if( this->outLength >= this->outBufferLength) return;
307
308  if( this->bUp || this->bDown || this->bRight || this->bLeft)
309  {
310    this->outData[this->outLength++] = TIME;
311    this->outData[this->outLength++] = (byte)(lround(time * 100.0f));
312
313    PRINTF(0)("Writing TIME = %i, or %f\n", this->outData[this->outLength-1], time);
314  }
315
316  if( this->bUp && this->getRelCoor().x < 20)
317  {
318    accel += direction;
319    this->outData[this->outLength++] = UP;
320  }
321  if( this->bDown && this->getRelCoor().x > -5)
322  {
323    accel -= direction;
324    this->outData[this->outLength++] = DOWN;
325  }
326  if( this->bLeft && TrackManager::getInstance()->getWidth() > -this->getRelCoor().z*2)
327  {
328    accel -=(orthDirection);
329    rot +=Vector(1,0,0);
330    rotVal -= .4;
331    this->outData[this->outLength++] = LEFT;
332  }
333  if( this->bRight && TrackManager::getInstance()->getWidth() > this->getRelCoor().z*2)
334  {
335    accel += orthDirection;
336    rot += Vector(1,0,0);
337    rotVal += .4;
338    this->outData[this->outLength++] = RIGHT;
339  }
340  if (this->bAscend )
341  {
342    accel += Vector(0,1,0);
343    rot += Vector(0,0,1);
344    rotVal += .4;
345  }
346  if (this->bDescend )
347  {
348    accel -= Vector(0,1,0);
349    rot += Vector(0,0,1);
350    rotVal -= .4;
351  }
352
353
354  Vector move = accel * time *acceleration;
355
356/*  if (accel.z < 0)
357    this->setRelDirSoft(Quaternion(-.4, accel), 5);
358  else if (accel.z > 0)
359    this->setRelDirSoft(Quaternion(.4, accel), 5);
360  else*/
361  rot.normalize();
362  this->setRelDirSoft(Quaternion(rotVal, rot), 5);
363  this->shiftCoor (move);
364
365
366}
367
368
369/**
370 * weapon manipulation by the player
371*/
372void Player::weaponAction()
373{
374  if( this->bFire)
375    {
376      this->weaponMan->fire();
377    }
378}
379
380/**
381 * @todo switch statement ??
382 */
383void Player::process(const Event &event)
384{
385  if( event.type == KeyMapper::PEV_UP)
386      this->bUp = event.bPressed;
387  else if( event.type == KeyMapper::PEV_DOWN)
388      this->bDown = event.bPressed;
389  else if( event.type == KeyMapper::PEV_RIGHT)
390      this->bRight= event.bPressed;
391  else if( event.type == KeyMapper::PEV_LEFT)
392      this->bLeft = event.bPressed;
393  else if( event.type == KeyMapper::PEV_FIRE1)
394      this->bFire = event.bPressed;
395  else if( event.type == KeyMapper::PEV_NEXT_WEAPON && event.bPressed)
396    this->weaponMan->nextWeaponConfig();//if( !event.bPressed) this->bWeaponChange = !this->bWeaponChange;
397  else if ( event.type == KeyMapper::PEV_PREVIOUS_WEAPON && event.bPressed)
398    this->weaponMan->previousWeaponConfig();
399
400  else if( event.type == SDLK_PAGEUP)
401    this->bAscend = event.bPressed; //this->shiftCoor(0,.1,0);
402  else if( event.type == SDLK_PAGEDOWN)
403    this->bDescend = event.bPressed; //this->shiftCoor(0,-.1,0);
404}
405
406#include "weapons/aiming_turret.h"
407// FIXME THIS MIGHT BE CONSIDERED EITHER A FEATURE, OR A BUG
408void Player::ADDWEAPON()
409{
410  Weapon* turret = NULL;
411
412  if ((float)rand()/RAND_MAX < .1)
413  {
414    //if (this->weaponMan->hasFreeSlot(2, WTYPE_TURRET))
415    {
416      turret = new Turret();
417      this->weaponMan->addWeapon(turret, 2);
418      this->weaponMan->changeWeaponConfig(2);
419    }
420  }
421  else
422  {
423    //if (this->weaponMan->hasFreeSlot(3))
424    {
425      turret = new AimingTurret();
426      this->weaponMan->addWeapon(turret, 3);
427
428      this->weaponMan->changeWeaponConfig(3);
429    }
430  }
431
432  if(turret != NULL)
433  {
434    turret->setName("Turret");
435    turret->setStateDuration(WS_SHOOTING, (float)rand()/RAND_MAX*.5+.1);
436  }
437}
438
439
440
441
442/**
443 *  write data to Synchronizeable
444 */
445void Player::writeBytes(const byte* data, int length)
446{
447  PRINTF(0)("Player: got %i bytes of data\n", length);
448  this->inLength = length;
449
450  /*
451   bytes:  | 0  |  1  |
452           CODE  DIST
453
454
455  CODE:
456       0 :   Up
457       1 :   Down
458       2 :   Right
459       3 :   Left
460       4 :   TIME
461
462  DIST:
463      Coordinate diff multiplied by 100 and casted to a byte: byte a = (byte)(x * 100)
464
465  */
466
467  float time = 0.0f;
468
469  Vector accel(0.0, 0.0, 0.0);
470  Vector direction (1.0, 0.0, 0.0);
471  Vector orthDirection (0.0, 0.0, 1.0);
472
473  byte code = 0;
474
475  /* iterate through all bytes */
476  for( int i = 0; i < length; i++)
477  {
478    code = data[i];
479
480    /* is it a time code? */
481    if( code == TIME)
482    {
483      /* is it the first time */
484      if( time > 0.0f )
485      {
486        /* apply movement */
487        Vector move = accel * time;
488
489        if (accel.z < 0)
490          this->setRelDirSoft(Quaternion(-.4, Vector(1,0,0)), 5);
491        else if (accel.z > 0)
492          this->setRelDirSoft(Quaternion(.4, Vector(1,0,0)), 5);
493        else
494          this->setRelDirSoft(Quaternion(0, Vector(1,0,0)), 5);
495        this->shiftCoor (move);
496      }
497      /* read out new movement */
498      time = (float)(data[++i] / 100.0f);
499      PRINTF(0)("Got time: %f msec\n", time);
500    }
501    else if( code == UP && this->getRelCoor().x < 20)
502      accel = accel+(direction*acceleration);
503    else if( code == DOWN && this->getRelCoor().x > -5)
504      accel = accel -(direction*acceleration);
505    else if( code == LEFT && TrackManager::getInstance()->getWidth() > -this->getRelCoor().z*2)
506      accel = accel - (orthDirection*acceleration);
507    else if( code == RIGHT && TrackManager::getInstance()->getWidth() > this->getRelCoor().z*2)
508      accel = accel + (orthDirection*acceleration);
509  }
510
511
512
513
514  /* and debug output */
515  this->writeDebug();
516}
517
518
519/**
520 *  read data from Synchronizeable
521 */
522int Player::readBytes(byte* data)
523{
524  PRINTF(0)("Player: sent %i bytes of data\n", this->sentLength);
525
526  /* copy data */
527  for( int i = 0; i < this->outLength; ++i)
528    data[i] = this->outData[i];
529
530
531
532  /* debug msg */
533  this->readDebug();
534
535  int length = this->outLength;
536  this->outLength = 0;
537  /* return the length of the test */
538  return length;
539}
540
541
542void Player::writeDebug() const
543{
544
545}
546
547
548void Player::readDebug() const
549{
550
551}
552
Note: See TracBrowser for help on using the repository browser.