Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/world_entities/playable.cc @ 9496

Last change on this file since 9496 was 9406, checked in by bensch, 18 years ago

orxonox/trunk: merged the proxy back

merged with commandsvn merge -r9346:HEAD https://svn.orxonox.net/orxonox/branches/proxy .

no conflicts

File size: 12.1 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
[7954]70  registerVar( new SynchronizeableInt( &score, &score, "score" ) );
71  registerVar( new SynchronizeableBool( &bFire, &bFire, "bFire", PERMISSION_OWNER));
[5838]72}
73
[6695]74
[7346]75/**
76 * @brief destroys the Playable
77 */
[5875]78Playable::~Playable()
[5838]79{
[6986]80  // THE DERIVED CLASS MUST UNSUBSCRIBE THE PLAYER THROUGH
81  // this->setPlayer(NULL);
82  // IN ITS DESTRUCTOR.
[8316]83
[6986]84  assert(this->currentPlayer == NULL);
[5875]85}
86
[7346]87/**
88 * @brief loads Playable parameters onto the Playable
89 * @param root the XML-root to load from
90 */
[7092]91void Playable::loadParams(const TiXmlElement* root)
92{
93  WorldEntity::loadParams(root);
94
[7346]95  LoadParam(root, "abs-dir", this, Playable, setPlayDirection);
[9061]96  LoadParam(root, "enter-radius", this, Playable, setEnterRadius)
97      .describe("The Distance one can enter the ship from.");
[7092]98}
99
[7346]100/**
101 * @brief picks up a powerup
102 * @param powerUp the PowerUp that should be picked.
103 * @returns true on success (pickup was picked, false otherwise)
104 *
105 * This function also checks if the Pickup can be picked up by this Playable
106 */
107bool Playable::pickup(PowerUp* powerUp)
108{
109  if(powerUp->isA(CL_WEAPON_POWER_UP))
110  {
111    return dynamic_cast<WeaponPowerUp*>(powerUp)->process(&this->getWeaponManager());
112  }
113  else if(powerUp->isA(CL_PARAM_POWER_UP))
114  {
115    ParamPowerUp* ppu = dynamic_cast<ParamPowerUp*>(powerUp);
116    switch(ppu->getType())
117    {
118      case POWERUP_PARAM_HEALTH:
119        this->increaseHealth(ppu->getValue());
120        return true;
121      case POWERUP_PARAM_MAX_HEALTH:
122        this->increaseHealthMax(ppu->getValue());
123        return true;
[8316]124      default:
125        /// EVERYTHING THAT IS NOT HANDLED
126        /// FIXME
127        return false;
[7346]128    }
129  }
130  return false;
131}
132
133/**
134 * @brief adds a Weapon to the Playable.
135 * @param weapon the Weapon to add.
136 * @param configID the Configuration ID to add this weapon to.
137 * @param slotID the slotID to add the Weapon to.
138 */
[7350]139bool Playable::addWeapon(Weapon* weapon, int configID, int slotID)
[6443]140{
[7350]141  if(this->weaponMan.addWeapon(weapon, configID, slotID))
142  {
143    this->weaponConfigChanged();
144    return true;
145  }
146  else
147  {
148    if (weapon != NULL)
149      PRINTF(2)("Unable to add Weapon (%s::%s) to %s::%s\n",
[9406]150                weapon->getClassCName(), weapon->getCName(), this->getClassCName(), this->getCName());
[7350]151    else
152      PRINTF(2)("No weapon defined\n");
153    return false;
[6443]154
[7350]155  }
[6443]156}
157
[7346]158/**
159 * @brief removes a Weapon.
160 * @param weapon the Weapon to remove.
161 */
[6443]162void Playable::removeWeapon(Weapon* weapon)
163{
[7337]164  this->weaponMan.removeWeapon(weapon);
[6443]165
[7338]166  this->weaponConfigChanged();
[6443]167}
168
[7346]169/**
170 * @brief jumps to the next WeaponConfiguration
171 */
[6444]172void Playable::nextWeaponConfig()
173{
[7337]174  this->weaponMan.nextWeaponConfig();
[7338]175  this->weaponConfigChanged();
[6444]176}
[6443]177
[7346]178/**
179 * @brief moves to the last WeaponConfiguration
180 */
[6444]181void Playable::previousWeaponConfig()
182{
[7337]183  this->weaponMan.previousWeaponConfig();
[7338]184  this->weaponConfigChanged();
[6444]185}
186
[7346]187/**
188 * @brief tells the Player, that the Weapon-Configuration has changed.
189 *
190 * TODO remove this
191 * This function is needed, so that the WeponManager of this Playable can easily update the HUD
192 */
[6568]193void Playable::weaponConfigChanged()
194{
[6578]195  if (this->currentPlayer != NULL)
196    this->currentPlayer->weaponConfigChanged();
[6568]197}
[6444]198
[7350]199/**
200 * @brief a Cheat that gives us some Weapons
201 */
202void Playable::addSomeWeapons_CHEAT()
203{
[7351]204  if (State::getPlayer() != NULL)
205  {
206    Playable* playable = State::getPlayer()->getPlayable();
207    if (playable != NULL)
208    {
209      PRINTF(2)("ADDING WEAPONS - you cheater\n");
210      playable->addWeapon(Weapon::createWeapon(CL_HYPERBLASTER));
211      playable->addWeapon(Weapon::createWeapon(CL_TURRET));
212      playable->addWeapon(Weapon::createWeapon(CL_AIMING_TURRET));
213      playable->addWeapon(Weapon::createWeapon(CL_CANNON));
214      playable->addWeapon(Weapon::createWeapon(CL_TARGETING_TURRET));
215      PRINTF(2)("ADDING WEAPONS FINISHED\n");
216    }
217  }
[7350]218}
[7346]219
[7173]220/**
[7346]221 * @brief subscribe to all events the controllable needs
222 * @param player the player that shall controll this Playable
223 * @returns false on error true otherwise.
224 */
225bool Playable::setPlayer(Player* player)
226{
227  // if we already have a Player inside do nothing
228  if (this->currentPlayer != NULL && player != NULL)
229  {
230    return false;
231  }
232
233  // eject the Player if player == NULL
234  if (this->currentPlayer != NULL && player == NULL)
235  {
236    PRINTF(4)("Player gets ejected\n");
237
238    // unsubscibe all events.
239    std::vector<int>::iterator ev;
240    for (ev = this->events.begin(); ev != events.end(); ev++)
[7868]241      player->unsubscribeEvent(ES_GAME, (*ev));
[7346]242
243    // leave the entity
244    this->leave();
245
246    // eject the current Player.
247    Player* ejectPlayer = this->currentPlayer;
248    this->currentPlayer = NULL;
249    // eject the Player.
250    ejectPlayer->setPlayable(NULL);
251
252    return true;
253  }
254
255  // get the new Player inside
256  if (this->currentPlayer == NULL && player != NULL)
257  {
258    PRINTF(4)("New Player gets inside\n");
259    this->currentPlayer = player;
260    if (this->currentPlayer->getPlayable() != this)
261      this->currentPlayer->setPlayable(this);
262
263    /*EventHandler*/
264    std::vector<int>::iterator ev;
265    for (ev = this->events.begin(); ev != events.end(); ev++)
[7868]266      player->subscribeEvent(ES_GAME, (*ev));
[7346]267
268    this->enter();
269    return true;
270  }
271
272  return false;
273}
274
275/**
276 * @brief attaches the current Camera to this Playable
277 *
278 * this function can be derived, so that any Playable can make the attachment differently.
279 */
280void Playable::attachCamera()
281{
282  State::getCameraNode()->setParentSoft(this);
283  State::getCameraTargetNode()->setParentSoft(this);
284
285}
286
287/**
288 * @brief detaches the Camera
289 * @see void Playable::attachCamera()
290 */
291void  Playable::detachCamera()
[8147]292{
293}
[7346]294
295
296/**
[7173]297 * @brief sets the CameraMode.
298 * @param cameraMode: the Mode to switch to.
299 */
300void Playable::setCameraMode(unsigned int cameraMode)
[7347]301{
302  State::getCamera()->setViewMode((Camera::ViewMode)cameraMode);
303}
[7338]304
[7346]305
[7338]306/**
307 * @brief sets the Playmode
308 * @param playmode the Playmode
309 * @returns true on success, false otherwise
310 */
[7339]311bool Playable::setPlaymode(Playable::Playmode playmode)
[7173]312{
[7338]313  if (!this->playmodeSupported(playmode))
314    return false;
315  else
[7345]316  {
[7347]317    this->enterPlaymode(playmode);
[7338]318    this->playmode = playmode;
[7345]319    return true;
320  }
[7173]321}
322
[7346]323/**
324 * @brief This function look, that the Playable rotates to the given rotation.
325 * @param angle the Angle around
326 * @param dirX directionX
327 * @param dirY directionY
328 * @param dirZ directionZ
329 * @param speed how fast to turn there.
330 */
331void Playable::setPlayDirection(float angle, float dirX, float dirY, float dirZ, float speed)
332{
333  this->setPlayDirection(Quaternion(angle, Vector(dirX, dirY, dirZ)), speed);
334}
[7173]335
[5872]336/**
[7346]337 * @brief all Playable will enter the Playmode Differently, say here how to do it.
338 * @param playmode the Playmode to enter.
339 *
340 * In this function all the actions that are required to enter the Playmode are described.
341 * e.g: camera, rotation, wait cycle and so on...
[7347]342 *
343 * on enter of this function the playmode is still the old playmode.
[7346]344 */
345void Playable::enterPlaymode(Playable::Playmode playmode)
346{
[7347]347  switch(playmode)
348  {
349    default:
350      this->attachCamera();
351      break;
352    case Playable::Horizontal:
353      this->setCameraMode(Camera::ViewTop);
354      break;
355    case Playable::Vertical:
356      this->setCameraMode(Camera::ViewLeft);
357      break;
358    case Playable::FromBehind:
359      this->setCameraMode(Camera::ViewBehind);
360      break;
361  }
[7346]362}
[7072]363
[7482]364
[7044]365void Playable::respawn()
[6966]366{
[7044]367  PRINTF(0)("Playable respawn\n");
368  // only if this is the spaceship of the player
[9235]369  if( State::getGameRules() && State::getPlayer() && this == State::getPlayer()->getPlayable())
[7044]370    State::getGameRules()->onPlayerSpawn();
[6966]371
[7118]372  this->reset();
373  this->bDead = false;
[6436]374}
375
[6966]376
[7088]377
[8724]378
[9235]379void Playable::destroy(WorldEntity* killer)
[7044]380{
[7118]381  if( !this->bDead)
382  {
383    PRINTF(0)("Playable dies\n");
[7338]384    // only if this is the spaceship of the player
[7118]385    if (State::isOnline())
386    {
387      if( this == State::getPlayer()->getPlayable())
388        State::getGameRules()->onPlayerDeath();
389    }
390    this->bDead = true;
[9406]391
[9235]392    if( State::getGameRules() != NULL)
393      State::getGameRules()->registerKill(Kill(killer, this));
[7072]394  }
[7044]395}
396
397
[6986]398
399
400
[5896]401/**
[7346]402 * @brief add an event to the event list of events this Playable can capture
[5898]403 * @param eventType the Type of event to add
[5889]404 */
[5896]405void Playable::registerEvent(int eventType)
[5889]406{
407  this->events.push_back(eventType);
408
[5896]409  if (this->currentPlayer != NULL)
[7868]410    this->currentPlayer->subscribeEvent(ES_GAME, eventType);
[5889]411}
412
[5896]413/**
[7339]414 * @brief remove an event to the event list this Playable can capture.
[5898]415 * @param event the event to unregister.
[5896]416 */
417void Playable::unregisterEvent(int eventType)
418{
[7338]419  std::vector<int>::iterator rmEvent = std::find(this->events.begin(), this->events.end(), eventType);
420  this->events.erase(rmEvent);
[5889]421
[5896]422  if (this->currentPlayer != NULL)
[7868]423    this->currentPlayer->unsubscribeEvent(ES_GAME, eventType);
[5896]424}
[5889]425
[6804]426/**
427 * @brief ticks a Playable
428 * @param dt: the passed time since the last Tick
429 */
430void Playable::tick(float dt)
431{
[7337]432  this->weaponMan.tick(dt);
[6804]433  if (this->bFire)
[7337]434    weaponMan.fire();
[6804]435}
[5896]436
[6804]437
438/**
439 * @brief processes Playable events.
440 * @param event the Captured Event.
441 */
442void Playable::process(const Event &event)
443{
444  if( event.type == KeyMapper::PEV_FIRE1)
445    this->bFire = event.bPressed;
446  else if( event.type == KeyMapper::PEV_NEXT_WEAPON && event.bPressed)
447  {
448    this->nextWeaponConfig();
449  }
450  else if ( event.type == KeyMapper::PEV_PREVIOUS_WEAPON && event.bPressed)
451    this->previousWeaponConfig();
452}
453
454
[6959]455
[7346]456/**
457 * @brief converts a string into a Playable::Playmode.
458 * @param playmode the string naming the Playable::Playmode to convert.
459 * @returns the Playable::Playmode converted from playmode.
460 */
[7339]461Playable::Playmode Playable::stringToPlaymode(const std::string& playmode)
462{
[7412]463  if (playmode == Playable::playmodeNames[0])
[7339]464    return Playable::Vertical;
[7412]465  if (playmode == Playable::playmodeNames[1])
[7339]466    return Playable::Horizontal;
[7412]467  if (playmode == Playable::playmodeNames[2])
[7339]468    return Playable::FromBehind;
[7412]469  if (playmode == Playable::playmodeNames[3])
[7339]470    return Playable::Full3D;
[8055]471  if (playmode == Playable::playmodeNames[4])
472    return Playable::FirstPerson;
[7339]473
474  return Playable::Full3D;
475}
476
[7346]477
478/**
479 * @brief converts a playmode into a string.
480 * @param playmode the Playable::Playmode to convert.
481 * @returns the String.
482 */
[7412]483const std::string& Playable::playmodeToString(Playable::Playmode playmode)
[7339]484{
485  switch(playmode)
486  {
487    case Playable::Vertical:
[7412]488      return Playable::playmodeNames[0];
[7339]489    case Playable::Horizontal:
[7412]490      return Playable::playmodeNames[1];
[7339]491    case Playable::FromBehind:
[7412]492      return Playable::playmodeNames[2];
[7339]493    case Playable::Full3D:
[7412]494      return Playable::playmodeNames[3];
[8055]495    case Playable::FirstPerson:
496      return Playable::playmodeNames[4];
[7339]497
498    default:
[7412]499      return Playable::playmodeNames[3];
[7339]500  }
[7412]501}
[7339]502
[7412]503/**
504 * @brief PlaymodeNames
505 */
506const std::string Playable::playmodeNames[] =
507{
508  "Vertical",
509  "Horizontal",
510  "FromBehind",
[8055]511  "Full3D",
512  "FirstPerson"
[7412]513};
Note: See TracBrowser for help on using the repository browser.