Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/world_entities/playable.cc @ 7545

Last change on this file since 7545 was 7444, checked in by rennerc, 19 years ago

new network system implemented. yet with a lot of empty function bodys

File size: 12.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: Silvan Nellen
13   co-programmer: Benjamin Knecht
14*/
15
16
17#include "playable.h"
18#include "event_handler.h"
19
20#include "player.h"
21#include "state.h"
22#include "camera.h"
23
24#include "util/loading/load_param.h"
25
26#include "power_ups/weapon_power_up.h"
27#include "power_ups/param_power_up.h"
28
29#include "game_rules.h"
30
31#include "dot_emitter.h"
32#include "sprite_particles.h"
33
34#include "shared_network_data.h"
35
36#include "effects/explosion.h"
37
38#include "shell_command.h"
39SHELL_COMMAND_STATIC(orxoWeapon, Playable, Playable::addSomeWeapons_CHEAT)
40  ->setAlias("orxoWeapon");
41
42
43Playable::Playable()
44    : weaponMan(this),
45    supportedPlaymodes(Playable::Full3D),
46    playmode(Playable::Full3D)
47{
48  this->setClassID(CL_PLAYABLE, "Playable");
49  PRINTF(4)("PLAYABLE INIT\n");
50
51  this->toList(OM_GROUP_01);
52
53  // the reference to the Current Player is NULL, because we dont have one at the beginning.
54  this->currentPlayer = NULL;
55
56  this->bFire = false;
57  this->oldFlags = 0;
58
59  this->setSynchronized(true);
60
61  this->score = 0;
62
63  this->bDead = false;
64 
65  registerVar( new SynchronizeableInt( &score, &score, "score" ) );
66}
67
68
69/**
70 * @brief destroys the Playable
71 */
72Playable::~Playable()
73{
74  // THE DERIVED CLASS MUST UNSUBSCRIBE THE PLAYER THROUGH
75  // this->setPlayer(NULL);
76  // IN ITS DESTRUCTOR.
77  assert(this->currentPlayer == NULL);
78}
79
80/**
81 * @brief loads Playable parameters onto the Playable
82 * @param root the XML-root to load from
83 */
84void Playable::loadParams(const TiXmlElement* root)
85{
86  WorldEntity::loadParams(root);
87
88  LoadParam(root, "abs-dir", this, Playable, setPlayDirection);
89}
90
91/**
92 * @brief picks up a powerup
93 * @param powerUp the PowerUp that should be picked.
94 * @returns true on success (pickup was picked, false otherwise)
95 *
96 * This function also checks if the Pickup can be picked up by this Playable
97 */
98bool Playable::pickup(PowerUp* powerUp)
99{
100  if(powerUp->isA(CL_WEAPON_POWER_UP))
101  {
102    return dynamic_cast<WeaponPowerUp*>(powerUp)->process(&this->getWeaponManager());
103  }
104  else if(powerUp->isA(CL_PARAM_POWER_UP))
105  {
106    ParamPowerUp* ppu = dynamic_cast<ParamPowerUp*>(powerUp);
107    switch(ppu->getType())
108    {
109      case POWERUP_PARAM_HEALTH:
110        this->increaseHealth(ppu->getValue());
111        return true;
112      case POWERUP_PARAM_MAX_HEALTH:
113        this->increaseHealthMax(ppu->getValue());
114        return true;
115    }
116  }
117  return false;
118}
119
120/**
121 * @brief adds a Weapon to the Playable.
122 * @param weapon the Weapon to add.
123 * @param configID the Configuration ID to add this weapon to.
124 * @param slotID the slotID to add the Weapon to.
125 */
126bool Playable::addWeapon(Weapon* weapon, int configID, int slotID)
127{
128  if(this->weaponMan.addWeapon(weapon, configID, slotID))
129  {
130    this->weaponConfigChanged();
131    return true;
132  }
133  else
134  {
135    if (weapon != NULL)
136      PRINTF(2)("Unable to add Weapon (%s::%s) to %s::%s\n",
137                weapon->getClassName(), weapon->getName(), this->getClassName(), this->getName());
138    else
139      PRINTF(2)("No weapon defined\n");
140    return false;
141
142  }
143}
144
145/**
146 * @brief removes a Weapon.
147 * @param weapon the Weapon to remove.
148 */
149void Playable::removeWeapon(Weapon* weapon)
150{
151  this->weaponMan.removeWeapon(weapon);
152
153  this->weaponConfigChanged();
154}
155
156/**
157 * @brief jumps to the next WeaponConfiguration
158 */
159void Playable::nextWeaponConfig()
160{
161  this->weaponMan.nextWeaponConfig();
162  this->weaponConfigChanged();
163}
164
165/**
166 * @brief moves to the last WeaponConfiguration
167 */
168void Playable::previousWeaponConfig()
169{
170  this->weaponMan.previousWeaponConfig();
171  this->weaponConfigChanged();
172}
173
174/**
175 * @brief tells the Player, that the Weapon-Configuration has changed.
176 *
177 * TODO remove this
178 * This function is needed, so that the WeponManager of this Playable can easily update the HUD
179 */
180void Playable::weaponConfigChanged()
181{
182  if (this->currentPlayer != NULL)
183    this->currentPlayer->weaponConfigChanged();
184}
185
186/**
187 * @brief a Cheat that gives us some Weapons
188 */
189void Playable::addSomeWeapons_CHEAT()
190{
191  if (State::getPlayer() != NULL)
192  {
193    Playable* playable = State::getPlayer()->getPlayable();
194    if (playable != NULL)
195    {
196      PRINTF(2)("ADDING WEAPONS - you cheater\n");
197      playable->addWeapon(Weapon::createWeapon(CL_HYPERBLASTER));
198      playable->addWeapon(Weapon::createWeapon(CL_TURRET));
199      playable->addWeapon(Weapon::createWeapon(CL_AIMING_TURRET));
200      playable->addWeapon(Weapon::createWeapon(CL_CANNON));
201      playable->addWeapon(Weapon::createWeapon(CL_TARGETING_TURRET));
202      PRINTF(2)("ADDING WEAPONS FINISHED\n");
203    }
204  }
205}
206
207/**
208 * @brief subscribe to all events the controllable needs
209 * @param player the player that shall controll this Playable
210 * @returns false on error true otherwise.
211 */
212bool Playable::setPlayer(Player* player)
213{
214  // if we already have a Player inside do nothing
215  if (this->currentPlayer != NULL && player != NULL)
216  {
217    return false;
218  }
219
220  // eject the Player if player == NULL
221  if (this->currentPlayer != NULL && player == NULL)
222  {
223    PRINTF(4)("Player gets ejected\n");
224
225    // unsubscibe all events.
226    EventHandler* evh = EventHandler::getInstance();
227    std::vector<int>::iterator ev;
228    for (ev = this->events.begin(); ev != events.end(); ev++)
229      evh->unsubscribe( ES_GAME, (*ev));
230
231    // leave the entity
232    this->leave();
233
234    // eject the current Player.
235    Player* ejectPlayer = this->currentPlayer;
236    this->currentPlayer = NULL;
237    // eject the Player.
238    ejectPlayer->setPlayable(NULL);
239
240    return true;
241  }
242
243  // get the new Player inside
244  if (this->currentPlayer == NULL && player != NULL)
245  {
246    PRINTF(4)("New Player gets inside\n");
247    this->currentPlayer = player;
248    if (this->currentPlayer->getPlayable() != this)
249      this->currentPlayer->setPlayable(this);
250
251    /*EventHandler*/
252    EventHandler* evh = EventHandler::getInstance();
253    std::vector<int>::iterator ev;
254    for (ev = this->events.begin(); ev != events.end(); ev++)
255      evh->subscribe(player, ES_GAME, (*ev));
256
257    this->enter();
258    return true;
259  }
260
261  return false;
262}
263
264/**
265 * @brief attaches the current Camera to this Playable
266 *
267 * this function can be derived, so that any Playable can make the attachment differently.
268 */
269void Playable::attachCamera()
270{
271  State::getCameraNode()->setParentSoft(this);
272  State::getCameraTargetNode()->setParentSoft(this);
273
274}
275
276/**
277 * @brief detaches the Camera
278 * @see void Playable::attachCamera()
279 */
280void  Playable::detachCamera()
281{}
282
283
284/**
285 * @brief sets the CameraMode.
286 * @param cameraMode: the Mode to switch to.
287 */
288void Playable::setCameraMode(unsigned int cameraMode)
289{
290  State::getCamera()->setViewMode((Camera::ViewMode)cameraMode);
291}
292
293
294/**
295 * @brief sets the Playmode
296 * @param playmode the Playmode
297 * @returns true on success, false otherwise
298 */
299bool Playable::setPlaymode(Playable::Playmode playmode)
300{
301  if (!this->playmodeSupported(playmode))
302    return false;
303  else
304  {
305    this->enterPlaymode(playmode);
306    this->playmode = playmode;
307    return true;
308  }
309}
310
311/**
312 * @brief This function look, that the Playable rotates to the given rotation.
313 * @param angle the Angle around
314 * @param dirX directionX
315 * @param dirY directionY
316 * @param dirZ directionZ
317 * @param speed how fast to turn there.
318 */
319void Playable::setPlayDirection(float angle, float dirX, float dirY, float dirZ, float speed)
320{
321  this->setPlayDirection(Quaternion(angle, Vector(dirX, dirY, dirZ)), speed);
322}
323
324/**
325 * @brief all Playable will enter the Playmode Differently, say here how to do it.
326 * @param playmode the Playmode to enter.
327 *
328 * In this function all the actions that are required to enter the Playmode are described.
329 * e.g: camera, rotation, wait cycle and so on...
330 *
331 * on enter of this function the playmode is still the old playmode.
332 */
333void Playable::enterPlaymode(Playable::Playmode playmode)
334{
335  switch(playmode)
336  {
337    default:
338      this->attachCamera();
339      break;
340    case Playable::Horizontal:
341      this->setCameraMode(Camera::ViewTop);
342      break;
343    case Playable::Vertical:
344      this->setCameraMode(Camera::ViewLeft);
345      break;
346    case Playable::FromBehind:
347      this->setCameraMode(Camera::ViewBehind);
348      break;
349  }
350}
351/**
352 * @brief helps us colliding Playables
353 * @param entity the Entity to collide
354 * @param location where the collision occured.
355 */
356void Playable::collidesWith(WorldEntity* entity, const Vector& location)
357{
358  if (entity == collider)
359    return;
360  collider = entity;
361
362  if ( entity->isA(CL_PROJECTILE) && ( !State::isOnline() || SharedNetworkData::getInstance()->isGameServer() ) )
363  {
364    this->decreaseHealth(entity->getHealth() *(float)rand()/(float)RAND_MAX);
365    // EXTREME HACK
366    if (this->getHealth() <= 0.0f)
367    {
368      this->die();
369    }
370  }
371}
372
373
374void Playable::respawn()
375{
376  PRINTF(0)("Playable respawn\n");
377  // only if this is the spaceship of the player
378  if( this == State::getPlayer()->getPlayable())
379    State::getGameRules()->onPlayerSpawn();
380
381
382  if( this->getOwner() % 2 == 0)
383  {
384    //     this->toList(OM_GROUP_00);
385    this->setAbsCoor(213.37, 57.71, -47.98);
386    this->setAbsDir(0, 0, 1, 0);
387  }
388  else
389  { // red team
390    //     this->toList(OM_GROUP_01);
391    this->setAbsCoor(-314.450, 40.701, 83.554);
392    this->setAbsDir(1.0, -0.015, -0.012, 0.011);
393  }
394  this->reset();
395  this->bDead = false;
396}
397
398
399
400void Playable::die()
401{
402  Explosion::explode(dynamic_cast<PNode*>(this), Vector(1.0f, 1.0f, 1.0f));
403
404
405  if( !this->bDead)
406  {
407    PRINTF(0)("Playable dies\n");
408    // only if this is the spaceship of the player
409    if (State::isOnline())
410    {
411      if( this == State::getPlayer()->getPlayable())
412        State::getGameRules()->onPlayerDeath();
413
414      //     this->toList(OM_GROUP_05);
415      //HACK: moves the entity to an unknown place far far away: in the future, GameRules will look for that
416      this->setAbsCoor(-2000.0, -2000.0, -2000.0);
417
418      //explosion hack
419
420    }
421    this->bDead = true;
422  }
423}
424
425
426
427
428
429/**
430 * @brief add an event to the event list of events this Playable can capture
431 * @param eventType the Type of event to add
432 */
433void Playable::registerEvent(int eventType)
434{
435  this->events.push_back(eventType);
436
437  if (this->currentPlayer != NULL)
438    EventHandler::getInstance()->subscribe(this->currentPlayer, ES_GAME, eventType);
439}
440
441/**
442 * @brief remove an event to the event list this Playable can capture.
443 * @param event the event to unregister.
444 */
445void Playable::unregisterEvent(int eventType)
446{
447  std::vector<int>::iterator rmEvent = std::find(this->events.begin(), this->events.end(), eventType);
448  this->events.erase(rmEvent);
449
450  if (this->currentPlayer != NULL)
451    EventHandler::getInstance()->unsubscribe(ES_GAME, eventType);
452}
453
454/**
455 * @brief ticks a Playable
456 * @param dt: the passed time since the last Tick
457 */
458void Playable::tick(float dt)
459{
460  this->weaponMan.tick(dt);
461  if (this->bFire)
462    weaponMan.fire();
463}
464
465
466/**
467 * @brief processes Playable events.
468 * @param event the Captured Event.
469 */
470void Playable::process(const Event &event)
471{
472  if( event.type == KeyMapper::PEV_FIRE1)
473    this->bFire = event.bPressed;
474  else if( event.type == KeyMapper::PEV_NEXT_WEAPON && event.bPressed)
475  {
476    this->nextWeaponConfig();
477  }
478  else if ( event.type == KeyMapper::PEV_PREVIOUS_WEAPON && event.bPressed)
479    this->previousWeaponConfig();
480}
481
482
483
484/**
485 * @brief converts a string into a Playable::Playmode.
486 * @param playmode the string naming the Playable::Playmode to convert.
487 * @returns the Playable::Playmode converted from playmode.
488 */
489Playable::Playmode Playable::stringToPlaymode(const std::string& playmode)
490{
491  if (playmode == "Vertical")
492    return Playable::Vertical;
493  if (playmode == "Horizontal")
494    return Playable::Horizontal;
495  if (playmode == "FromBehind")
496    return Playable::FromBehind;
497  if (playmode == "Full3D")
498    return Playable::Full3D;
499
500  return Playable::Full3D;
501}
502
503
504/**
505 * @brief converts a playmode into a string.
506 * @param playmode the Playable::Playmode to convert.
507 * @returns the String.
508 */
509const char* Playable::playmodeToString(Playable::Playmode playmode)
510{
511  switch(playmode)
512  {
513    case Playable::Vertical:
514      return "Vertical";
515    case Playable::Horizontal:
516      return "Horizontal";
517    case Playable::FromBehind:
518      return "FromBehind";
519    case Playable::Full3D:
520      return "Full3D";
521
522    default:
523      return "Full3D";
524  }
525
526}
Note: See TracBrowser for help on using the repository browser.