Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

trunk: orientation fix

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