Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/proxy/src/world_entities/playable.cc @ 9649

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

yet another weekend commit, quite much work done:

  • introduced a new PERMISSION layer: PERMISSION_SERVER: the nearest server hast authority
  • tightening up permissions: brand new implementation to prevent sending unused variables in the network (less smog in the net:D_
  • removed some compiler warnings from some central modules
  • networkmonitor interface changed to work with networknodes mainly
  • better debug output for the network monitor
  • networnode inteface standardisation
  • force reconnection commands integration
File size: 12.9 KB
RevLine 
[5838]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:
[5841]12   main-programmer: Silvan Nellen
13   co-programmer: Benjamin Knecht
[5838]14*/
15
[5881]16
[5838]17#include "playable.h"
[5895]18
[7868]19#include "key_mapper.h"
20
[5875]21#include "player.h"
[6241]22#include "state.h"
[7347]23#include "camera.h"
24
[7193]25#include "util/loading/load_param.h"
[5838]26
[6547]27#include "power_ups/weapon_power_up.h"
28#include "power_ups/param_power_up.h"
[5872]29
[7044]30#include "game_rules.h"
[6547]31
[6959]32#include "dot_emitter.h"
33#include "sprite_particles.h"
34
[7121]35#include "shared_network_data.h"
36
[7118]37#include "effects/explosion.h"
[7482]38#include "kill.cc"
[6959]39
[7350]40#include "shell_command.h"
[7356]41SHELL_COMMAND_STATIC(orxoWeapon, Playable, Playable::addSomeWeapons_CHEAT)
42  ->setAlias("orxoWeapon");
[7118]43
[7350]44
[5838]45Playable::Playable()
[7338]46    : weaponMan(this),
47    supportedPlaymodes(Playable::Full3D),
48    playmode(Playable::Full3D)
[5838]49{
[6442]50  this->setClassID(CL_PLAYABLE, "Playable");
51  PRINTF(4)("PLAYABLE INIT\n");
52
53  this->toList(OM_GROUP_01);
54
55  // the reference to the Current Player is NULL, because we dont have one at the beginning.
56  this->currentPlayer = NULL;
[6695]57
[6804]58  this->bFire = false;
[6868]59  this->oldFlags = 0;
[6804]60
[6695]61  this->setSynchronized(true);
[6959]62
63  this->score = 0;
[7713]64  this->collider = NULL;
[9061]65  this->enterRadius = 10.0f;
[6959]66
[7118]67  this->bDead = false;
[9008]68
[8490]69
[9625]70  this->teamChangeHandler = registerVarId( new SynchronizeableInt( &this->teamId, &this->teamId, "team-id", PERMISSION_MASTER_SERVER ) );
71  registerVar( new SynchronizeableInt( &score, &score, "score", PERMISSION_MASTER_SERVER ) );
[7954]72  registerVar( new SynchronizeableBool( &bFire, &bFire, "bFire", PERMISSION_OWNER));
[5838]73}
74
[6695]75
[7346]76/**
77 * @brief destroys the Playable
78 */
[5875]79Playable::~Playable()
[5838]80{
[6986]81  // THE DERIVED CLASS MUST UNSUBSCRIBE THE PLAYER THROUGH
82  // this->setPlayer(NULL);
83  // IN ITS DESTRUCTOR.
[8316]84
[6986]85  assert(this->currentPlayer == NULL);
[5875]86}
87
[7346]88/**
89 * @brief loads Playable parameters onto the Playable
90 * @param root the XML-root to load from
91 */
[7092]92void Playable::loadParams(const TiXmlElement* root)
93{
94  WorldEntity::loadParams(root);
95
[7346]96  LoadParam(root, "abs-dir", this, Playable, setPlayDirection);
[9061]97  LoadParam(root, "enter-radius", this, Playable, setEnterRadius)
98      .describe("The Distance one can enter the ship from.");
[7092]99}
100
[7346]101/**
102 * @brief picks up a powerup
103 * @param powerUp the PowerUp that should be picked.
104 * @returns true on success (pickup was picked, false otherwise)
105 *
106 * This function also checks if the Pickup can be picked up by this Playable
107 */
108bool Playable::pickup(PowerUp* powerUp)
109{
110  if(powerUp->isA(CL_WEAPON_POWER_UP))
111  {
112    return dynamic_cast<WeaponPowerUp*>(powerUp)->process(&this->getWeaponManager());
113  }
114  else if(powerUp->isA(CL_PARAM_POWER_UP))
115  {
116    ParamPowerUp* ppu = dynamic_cast<ParamPowerUp*>(powerUp);
117    switch(ppu->getType())
118    {
119      case POWERUP_PARAM_HEALTH:
120        this->increaseHealth(ppu->getValue());
121        return true;
122      case POWERUP_PARAM_MAX_HEALTH:
123        this->increaseHealthMax(ppu->getValue());
124        return true;
[8316]125      default:
126        /// EVERYTHING THAT IS NOT HANDLED
127        /// FIXME
128        return false;
[7346]129    }
130  }
131  return false;
132}
133
134/**
135 * @brief adds a Weapon to the Playable.
136 * @param weapon the Weapon to add.
137 * @param configID the Configuration ID to add this weapon to.
138 * @param slotID the slotID to add the Weapon to.
139 */
[7350]140bool Playable::addWeapon(Weapon* weapon, int configID, int slotID)
[6443]141{
[7350]142  if(this->weaponMan.addWeapon(weapon, configID, slotID))
143  {
144    this->weaponConfigChanged();
145    return true;
146  }
147  else
148  {
149    if (weapon != NULL)
150      PRINTF(2)("Unable to add Weapon (%s::%s) to %s::%s\n",
[9406]151                weapon->getClassCName(), weapon->getCName(), this->getClassCName(), this->getCName());
[7350]152    else
153      PRINTF(2)("No weapon defined\n");
154    return false;
[6443]155
[7350]156  }
[6443]157}
158
[7346]159/**
160 * @brief removes a Weapon.
161 * @param weapon the Weapon to remove.
162 */
[6443]163void Playable::removeWeapon(Weapon* weapon)
164{
[7337]165  this->weaponMan.removeWeapon(weapon);
[6443]166
[7338]167  this->weaponConfigChanged();
[6443]168}
169
[7346]170/**
171 * @brief jumps to the next WeaponConfiguration
172 */
[6444]173void Playable::nextWeaponConfig()
174{
[7337]175  this->weaponMan.nextWeaponConfig();
[7338]176  this->weaponConfigChanged();
[6444]177}
[6443]178
[7346]179/**
180 * @brief moves to the last WeaponConfiguration
181 */
[6444]182void Playable::previousWeaponConfig()
183{
[7337]184  this->weaponMan.previousWeaponConfig();
[7338]185  this->weaponConfigChanged();
[6444]186}
187
[7346]188/**
189 * @brief tells the Player, that the Weapon-Configuration has changed.
190 *
191 * TODO remove this
192 * This function is needed, so that the WeponManager of this Playable can easily update the HUD
193 */
[6568]194void Playable::weaponConfigChanged()
195{
[6578]196  if (this->currentPlayer != NULL)
197    this->currentPlayer->weaponConfigChanged();
[6568]198}
[6444]199
[7350]200/**
201 * @brief a Cheat that gives us some Weapons
202 */
203void Playable::addSomeWeapons_CHEAT()
204{
[7351]205  if (State::getPlayer() != NULL)
206  {
207    Playable* playable = State::getPlayer()->getPlayable();
208    if (playable != NULL)
209    {
210      PRINTF(2)("ADDING WEAPONS - you cheater\n");
211      playable->addWeapon(Weapon::createWeapon(CL_HYPERBLASTER));
212      playable->addWeapon(Weapon::createWeapon(CL_TURRET));
213      playable->addWeapon(Weapon::createWeapon(CL_AIMING_TURRET));
214      playable->addWeapon(Weapon::createWeapon(CL_CANNON));
215      playable->addWeapon(Weapon::createWeapon(CL_TARGETING_TURRET));
216      PRINTF(2)("ADDING WEAPONS FINISHED\n");
217    }
218  }
[7350]219}
[7346]220
[7173]221/**
[7346]222 * @brief subscribe to all events the controllable needs
223 * @param player the player that shall controll this Playable
224 * @returns false on error true otherwise.
225 */
226bool Playable::setPlayer(Player* player)
227{
228  // if we already have a Player inside do nothing
229  if (this->currentPlayer != NULL && player != NULL)
230  {
231    return false;
232  }
233
234  // eject the Player if player == NULL
235  if (this->currentPlayer != NULL && player == NULL)
236  {
237    PRINTF(4)("Player gets ejected\n");
238
239    // unsubscibe all events.
240    std::vector<int>::iterator ev;
241    for (ev = this->events.begin(); ev != events.end(); ev++)
[7868]242      player->unsubscribeEvent(ES_GAME, (*ev));
[7346]243
244    // leave the entity
245    this->leave();
246
247    // eject the current Player.
248    Player* ejectPlayer = this->currentPlayer;
249    this->currentPlayer = NULL;
250    // eject the Player.
251    ejectPlayer->setPlayable(NULL);
252
253    return true;
254  }
255
256  // get the new Player inside
257  if (this->currentPlayer == NULL && player != NULL)
258  {
259    PRINTF(4)("New Player gets inside\n");
260    this->currentPlayer = player;
261    if (this->currentPlayer->getPlayable() != this)
262      this->currentPlayer->setPlayable(this);
263
264    /*EventHandler*/
265    std::vector<int>::iterator ev;
266    for (ev = this->events.begin(); ev != events.end(); ev++)
[7868]267      player->subscribeEvent(ES_GAME, (*ev));
[7346]268
269    this->enter();
270    return true;
271  }
272
273  return false;
274}
275
[9500]276
[7346]277/**
[9500]278 * @brief sets the TeamID and all the properties needed to be visible on the Playable
279 * @param teamID: the new TeamID of the Entity
280 */
281void Playable::setTeam(int teamID)
282{
283  /// Derive this function to make it look different with differen groups.
284  PRINTF(4)("No special team specific function implemented for %s::%s in Team %d\n", this->getClassCName(), this->getCName(), teamID);
285}
286
287
288/**
[7346]289 * @brief attaches the current Camera to this Playable
290 *
291 * this function can be derived, so that any Playable can make the attachment differently.
292 */
293void Playable::attachCamera()
294{
295  State::getCameraNode()->setParentSoft(this);
296  State::getCameraTargetNode()->setParentSoft(this);
297
298}
299
300/**
301 * @brief detaches the Camera
302 * @see void Playable::attachCamera()
303 */
304void  Playable::detachCamera()
[8147]305{
306}
[7346]307
308
309/**
[7173]310 * @brief sets the CameraMode.
311 * @param cameraMode: the Mode to switch to.
312 */
313void Playable::setCameraMode(unsigned int cameraMode)
[7347]314{
315  State::getCamera()->setViewMode((Camera::ViewMode)cameraMode);
316}
[7338]317
[7346]318
[7338]319/**
320 * @brief sets the Playmode
321 * @param playmode the Playmode
322 * @returns true on success, false otherwise
323 */
[7339]324bool Playable::setPlaymode(Playable::Playmode playmode)
[7173]325{
[7338]326  if (!this->playmodeSupported(playmode))
327    return false;
328  else
[7345]329  {
[7347]330    this->enterPlaymode(playmode);
[7338]331    this->playmode = playmode;
[7345]332    return true;
333  }
[7173]334}
335
[7346]336/**
337 * @brief This function look, that the Playable rotates to the given rotation.
338 * @param angle the Angle around
339 * @param dirX directionX
340 * @param dirY directionY
341 * @param dirZ directionZ
342 * @param speed how fast to turn there.
343 */
344void Playable::setPlayDirection(float angle, float dirX, float dirY, float dirZ, float speed)
345{
346  this->setPlayDirection(Quaternion(angle, Vector(dirX, dirY, dirZ)), speed);
347}
[7173]348
[5872]349/**
[7346]350 * @brief all Playable will enter the Playmode Differently, say here how to do it.
351 * @param playmode the Playmode to enter.
352 *
353 * In this function all the actions that are required to enter the Playmode are described.
354 * e.g: camera, rotation, wait cycle and so on...
[7347]355 *
356 * on enter of this function the playmode is still the old playmode.
[7346]357 */
358void Playable::enterPlaymode(Playable::Playmode playmode)
359{
[7347]360  switch(playmode)
361  {
362    default:
363      this->attachCamera();
364      break;
365    case Playable::Horizontal:
366      this->setCameraMode(Camera::ViewTop);
367      break;
368    case Playable::Vertical:
369      this->setCameraMode(Camera::ViewLeft);
370      break;
371    case Playable::FromBehind:
372      this->setCameraMode(Camera::ViewBehind);
373      break;
374  }
[7346]375}
[7072]376
[7482]377
[7044]378void Playable::respawn()
[6966]379{
[7044]380  PRINTF(0)("Playable respawn\n");
381  // only if this is the spaceship of the player
[9235]382  if( State::getGameRules() && State::getPlayer() && this == State::getPlayer()->getPlayable())
[7044]383    State::getGameRules()->onPlayerSpawn();
[6966]384
[7118]385  this->reset();
386  this->bDead = false;
[6436]387}
388
[6966]389
[7088]390
[8724]391
[9235]392void Playable::destroy(WorldEntity* killer)
[7044]393{
[7118]394  if( !this->bDead)
395  {
396    PRINTF(0)("Playable dies\n");
[7338]397    // only if this is the spaceship of the player
[7118]398    if (State::isOnline())
399    {
400      if( this == State::getPlayer()->getPlayable())
401        State::getGameRules()->onPlayerDeath();
402    }
403    this->bDead = true;
[9406]404
[9235]405    if( State::getGameRules() != NULL)
406      State::getGameRules()->registerKill(Kill(killer, this));
[7072]407  }
[7044]408}
409
410
[6986]411
412
413
[5896]414/**
[7346]415 * @brief add an event to the event list of events this Playable can capture
[5898]416 * @param eventType the Type of event to add
[5889]417 */
[5896]418void Playable::registerEvent(int eventType)
[5889]419{
420  this->events.push_back(eventType);
421
[5896]422  if (this->currentPlayer != NULL)
[7868]423    this->currentPlayer->subscribeEvent(ES_GAME, eventType);
[5889]424}
425
[5896]426/**
[7339]427 * @brief remove an event to the event list this Playable can capture.
[5898]428 * @param event the event to unregister.
[5896]429 */
430void Playable::unregisterEvent(int eventType)
431{
[7338]432  std::vector<int>::iterator rmEvent = std::find(this->events.begin(), this->events.end(), eventType);
433  this->events.erase(rmEvent);
[5889]434
[5896]435  if (this->currentPlayer != NULL)
[7868]436    this->currentPlayer->unsubscribeEvent(ES_GAME, eventType);
[5896]437}
[5889]438
[6804]439/**
440 * @brief ticks a Playable
441 * @param dt: the passed time since the last Tick
442 */
443void Playable::tick(float dt)
444{
[7337]445  this->weaponMan.tick(dt);
[6804]446  if (this->bFire)
[7337]447    weaponMan.fire();
[6804]448}
[5896]449
[6804]450
451/**
452 * @brief processes Playable events.
453 * @param event the Captured Event.
454 */
455void Playable::process(const Event &event)
456{
457  if( event.type == KeyMapper::PEV_FIRE1)
458    this->bFire = event.bPressed;
459  else if( event.type == KeyMapper::PEV_NEXT_WEAPON && event.bPressed)
460  {
461    this->nextWeaponConfig();
462  }
463  else if ( event.type == KeyMapper::PEV_PREVIOUS_WEAPON && event.bPressed)
464    this->previousWeaponConfig();
465}
466
467
[6959]468
[7346]469/**
470 * @brief converts a string into a Playable::Playmode.
471 * @param playmode the string naming the Playable::Playmode to convert.
472 * @returns the Playable::Playmode converted from playmode.
473 */
[7339]474Playable::Playmode Playable::stringToPlaymode(const std::string& playmode)
475{
[7412]476  if (playmode == Playable::playmodeNames[0])
[7339]477    return Playable::Vertical;
[7412]478  if (playmode == Playable::playmodeNames[1])
[7339]479    return Playable::Horizontal;
[7412]480  if (playmode == Playable::playmodeNames[2])
[7339]481    return Playable::FromBehind;
[7412]482  if (playmode == Playable::playmodeNames[3])
[7339]483    return Playable::Full3D;
[8055]484  if (playmode == Playable::playmodeNames[4])
485    return Playable::FirstPerson;
[7339]486
487  return Playable::Full3D;
488}
489
[7346]490
491/**
492 * @brief converts a playmode into a string.
493 * @param playmode the Playable::Playmode to convert.
494 * @returns the String.
495 */
[7412]496const std::string& Playable::playmodeToString(Playable::Playmode playmode)
[7339]497{
498  switch(playmode)
499  {
500    case Playable::Vertical:
[7412]501      return Playable::playmodeNames[0];
[7339]502    case Playable::Horizontal:
[7412]503      return Playable::playmodeNames[1];
[7339]504    case Playable::FromBehind:
[7412]505      return Playable::playmodeNames[2];
[7339]506    case Playable::Full3D:
[7412]507      return Playable::playmodeNames[3];
[8055]508    case Playable::FirstPerson:
509      return Playable::playmodeNames[4];
[7339]510
511    default:
[7412]512      return Playable::playmodeNames[3];
[7339]513  }
[7412]514}
[7339]515
[7412]516/**
517 * @brief PlaymodeNames
518 */
519const std::string Playable::playmodeNames[] =
520{
521  "Vertical",
522  "Horizontal",
523  "FromBehind",
[8055]524  "Full3D",
525  "FirstPerson"
[7412]526};
[9507]527
528
529/**
530 * handler for changes on registred vars
531 * @param id id's which changed
532 */
533void Playable::varChangeHandler( std::list< int > & id )
534{
535  if ( std::find( id.begin(), id.end(), this->teamChangeHandler) != id.end() )
536  {
537    this->setTeam(this->teamId);
538  }
539
540  WorldEntity::varChangeHandler(id);
541}
Note: See TracBrowser for help on using the repository browser.