Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: simple useless stuff

File size: 8.5 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
19#include "weapons/weapon_manager.h"
20#include "event_handler.h"
21#include "player.h"
22#include "state.h"
23#include "util/loading/load_param.h"
24
25#include "world_entities/projectiles/projectile.h"
26
27#include "power_ups/weapon_power_up.h"
28#include "power_ups/param_power_up.h"
29
30#include "game_rules.h"
31
32#include "dot_emitter.h"
33#include "sprite_particles.h"
34
35#include "shared_network_data.h"
36
37#include "effects/explosion.h"
38
39
40Playable::Playable()
41  : weaponMan(this)
42{
43  this->setClassID(CL_PLAYABLE, "Playable");
44  PRINTF(4)("PLAYABLE INIT\n");
45
46  this->toList(OM_GROUP_01);
47
48  // the reference to the Current Player is NULL, because we dont have one at the beginning.
49  this->currentPlayer = NULL;
50
51  this->bFire = false;
52  this->oldFlags = 0;
53
54  this->setSynchronized(true);
55
56  this->score = 0;
57  this->oldScore = 0;
58
59  this->bDead = false;
60}
61
62
63
64Playable::~Playable()
65{
66  // THE DERIVED CLASS MUST UNSUBSCRIBE THE PLAYER THROUGH
67  // this->setPlayer(NULL);
68  // IN ITS DESTRUCTOR.
69  assert(this->currentPlayer == NULL);
70}
71
72
73void Playable::loadParams(const TiXmlElement* root)
74{
75  WorldEntity::loadParams(root);
76
77  LoadParam(root, "abs-dir", this, Playable, setStartDirection);
78}
79
80void Playable::addWeapon(Weapon* weapon, int configID, int slotID)
81{
82  this->weaponMan.addWeapon(weapon, configID, slotID);
83
84  this->weaponConfigChanged();
85}
86
87
88void Playable::removeWeapon(Weapon* weapon)
89{
90  this->weaponMan.removeWeapon(weapon);
91
92    this->weaponConfigChanged();
93}
94
95
96void Playable::nextWeaponConfig()
97{
98  this->weaponMan.nextWeaponConfig();
99    this->weaponConfigChanged();
100}
101
102
103void Playable::previousWeaponConfig()
104{
105  this->weaponMan.previousWeaponConfig();
106    this->weaponConfigChanged();
107}
108
109
110void Playable::weaponConfigChanged()
111{
112  if (this->currentPlayer != NULL)
113    this->currentPlayer->weaponConfigChanged();
114}
115
116/**
117 * @brief sets the CameraMode.
118 * @param cameraMode: the Mode to switch to.
119 */
120void Playable::setCameraMode(unsigned int cameraMode)
121{
122
123}
124
125
126/**
127 * @brief helps us colliding Playables
128 */
129void Playable::collidesWith(WorldEntity* entity, const Vector& location)
130{
131  if (entity == collider)
132    return;
133  collider = entity;
134
135  if ( entity->isA(CL_PROJECTILE) && ( !State::isOnline() || SharedNetworkData::getInstance()->isGameServer() ) )
136  {
137    this->decreaseHealth(entity->getHealth() *(float)rand()/(float)RAND_MAX);
138    // EXTREME HACK
139    if (this->getHealth() <= 0.0f)
140    {
141      this->die();
142    }
143  }
144}
145
146
147void Playable::respawn()
148{
149  PRINTF(0)("Playable respawn\n");
150  // only if this is the spaceship of the player
151  if( this == State::getPlayer()->getPlayable())
152    State::getGameRules()->onPlayerSpawn();
153
154
155  if( this->getOwner() % 2 == 0)
156  {
157//     this->toList(OM_GROUP_00);
158    this->setAbsCoor(213.37, 57.71, -47.98);
159    this->setAbsDir(0, 0, 1, 0);
160  }
161  else
162  { // red team
163//     this->toList(OM_GROUP_01);
164    this->setAbsCoor(-314.450, 40.701, 83.554);
165    this->setAbsDir(1.0, -0.015, -0.012, 0.011);
166  }
167  this->reset();
168  this->bDead = false;
169}
170
171
172
173void Playable::die()
174{
175  Explosion::explode(dynamic_cast<PNode*>(this), Vector(1.0f, 1.0f, 1.0f));
176
177
178  if( !this->bDead)
179  {
180    PRINTF(0)("Playable dies\n");
181  // only if this is the spaceship of the player
182    if (State::isOnline())
183    {
184      if( this == State::getPlayer()->getPlayable())
185        State::getGameRules()->onPlayerDeath();
186
187//     this->toList(OM_GROUP_05);
188  //HACK: moves the entity to an unknown place far far away: in the future, GameRules will look for that
189      this->setAbsCoor(-2000.0, -2000.0, -2000.0);
190
191  //explosion hack
192
193    }
194    this->bDead = true;
195  }
196}
197
198
199/**
200 * subscribe to all events the controllable needs
201 * @param player the player that shall controll this Playable
202 */
203bool Playable::setPlayer(Player* player)
204{
205  // if we already have a Player inside do nothing
206  if (this->currentPlayer != NULL && player != NULL)
207  {
208    return false;
209  }
210
211  // eject the Player if player == NULL
212  if (this->currentPlayer != NULL && player == NULL)
213  {
214    PRINTF(4)("Player gets ejected\n");
215
216    // unsubscibe all events.
217    EventHandler* evh = EventHandler::getInstance();
218    std::list<int>::iterator ev;
219    for (ev = this->events.begin(); ev != events.end(); ev++)
220      evh->unsubscribe( ES_GAME, (*ev));
221
222    // leave the entity
223    this->leave();
224
225    // eject the current Player.
226    Player* ejectPlayer = this->currentPlayer;
227    this->currentPlayer = NULL;
228    // eject the Player.
229    ejectPlayer->setPlayable(NULL);
230
231    return true;
232  }
233
234  // get the new Player inside
235  if (this->currentPlayer == NULL && player != NULL)
236  {
237    PRINTF(4)("New Player gets inside\n");
238    this->currentPlayer = player;
239    if (this->currentPlayer->getPlayable() != this)
240      this->currentPlayer->setPlayable(this);
241
242    /*EventHandler*/
243    EventHandler* evh = EventHandler::getInstance();
244    std::list<int>::iterator ev;
245    for (ev = this->events.begin(); ev != events.end(); ev++)
246      evh->subscribe(player, ES_GAME, (*ev));
247
248    this->enter();
249    return true;
250  }
251
252  return false;
253}
254
255
256bool Playable::pickup(PowerUp* powerUp)
257{
258  if(powerUp->isA(CL_WEAPON_POWER_UP)) {
259    return dynamic_cast<WeaponPowerUp*>(powerUp)->process(&this->getWeaponManager());
260  }
261  else if(powerUp->isA(CL_PARAM_POWER_UP)) {
262    ParamPowerUp* ppu = dynamic_cast<ParamPowerUp*>(powerUp);
263    switch(ppu->getType()) {
264      case POWERUP_PARAM_HEALTH:
265        this->increaseHealth(ppu->getValue());
266        return true;
267      case POWERUP_PARAM_MAX_HEALTH:
268        this->increaseHealthMax(ppu->getValue());
269        return true;
270    }
271  }
272  return false;
273}
274
275/**
276 * add an event to the event list of events this Playable can capture
277 * @param eventType the Type of event to add
278 */
279void Playable::registerEvent(int eventType)
280{
281  this->events.push_back(eventType);
282
283  if (this->currentPlayer != NULL)
284    EventHandler::getInstance()->subscribe(this->currentPlayer, ES_GAME, eventType);
285}
286
287/**
288 * remove an event to the event list this Playable can capture.
289 * @param event the event to unregister.
290 */
291void Playable::unregisterEvent(int eventType)
292{
293  this->events.remove(eventType);
294
295  if (this->currentPlayer != NULL)
296    EventHandler::getInstance()->unsubscribe(ES_GAME, eventType);
297}
298
299/**
300 * @brief ticks a Playable
301 * @param dt: the passed time since the last Tick
302 */
303void Playable::tick(float dt)
304{
305  this->weaponMan.tick(dt);
306  if (this->bFire)
307    weaponMan.fire();
308}
309
310
311/**
312 * @brief processes Playable events.
313 * @param event the Captured Event.
314 */
315void Playable::process(const Event &event)
316{
317  if( event.type == KeyMapper::PEV_FIRE1)
318    this->bFire = event.bPressed;
319  else if( event.type == KeyMapper::PEV_NEXT_WEAPON && event.bPressed)
320  {
321    this->nextWeaponConfig();
322  }
323  else if ( event.type == KeyMapper::PEV_PREVIOUS_WEAPON && event.bPressed)
324    this->previousWeaponConfig();
325}
326
327
328
329void  Playable::attachCamera()
330{
331  State::getCameraNode()->setParentSoft(this);
332  State::getCameraTargetNode()->setParentSoft(this);
333
334}
335
336
337
338
339void  Playable::detachCamera()
340{
341}
342
343#define DATA_FLAGS    1
344#define DATA_SCORE    2
345
346#define FLAGS_bFire   1
347
348int Playable::writeSync( const byte * data, int length, int sender )
349{
350  SYNCHELP_READ_BEGIN();
351
352  byte b;
353  SYNCHELP_READ_BYTE( b, NWT_PL_B );
354
355  byte flags;
356
357  if ( b == DATA_FLAGS )
358  {
359    SYNCHELP_READ_BYTE( flags, NWT_PL_FLAGS );
360
361    bFire = (flags & FLAGS_bFire) != 0;
362
363    return SYNCHELP_READ_N;
364  }
365
366  if ( b == DATA_SCORE )
367  {
368    int newScore;
369    SYNCHELP_READ_BYTE( newScore, NWT_PL_SCORE );
370    setScore( newScore );
371
372    return SYNCHELP_READ_N;
373  }
374
375  return SYNCHELP_READ_N;
376}
377
378int Playable::readSync( byte * data, int maxLength )
379{
380  SYNCHELP_WRITE_BEGIN();
381
382  if ( score != oldScore && isServer() )
383  {
384    SYNCHELP_WRITE_BYTE( DATA_SCORE, NWT_PL_B);
385    SYNCHELP_WRITE_INT( score, NWT_PL_SCORE );
386    oldScore = score;
387
388    return SYNCHELP_WRITE_N;
389  }
390
391  byte flags = 0;
392
393  if ( bFire )
394    flags |= FLAGS_bFire;
395
396
397  SYNCHELP_WRITE_BYTE( DATA_FLAGS, NWT_PL_B);
398  SYNCHELP_WRITE_BYTE( flags, NWT_PL_FLAGS );
399  oldFlags = flags;
400
401
402  return SYNCHELP_WRITE_N;
403}
404
405bool Playable::needsReadSync( )
406{
407  if ( score != oldScore && isServer() )
408    return true;
409
410  byte flags = 0;
411
412  if ( bFire )
413    flags |= FLAGS_bFire;
414
415  return flags!=oldFlags;
416}
Note: See TracBrowser for help on using the repository browser.