Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/multi_player_map/src/util/multiplayer_team_deathmatch.cc @ 9024

Last change on this file since 9024 was 9023, checked in by rennerc, 19 years ago

MultiPlayerTeamDeathMatch: use hud notifier instead of own

File size: 19.7 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: Patrick Boenzli
13*/
14
15#define DEBUG_MODULE_GAME_RULES
16
17#include <map>
18
19#include "multiplayer_team_deathmatch.h"
20
21#include "util/loading/load_param.h"
22#include "util/loading/factory.h"
23
24#include "render2D/image_plane.h"
25#include "state.h"
26#include "class_list.h"
27
28#include "player.h"
29#include "playable.h"
30#include "space_ships/space_ship.h"
31
32
33#include "shared_network_data.h"
34#include "terrain.h"
35#include "class_list.h"
36#include "space_ships/space_ship.h"
37
38#include "network_game_manager.h"
39
40#include "event_handler.h"
41
42#include "glgui.h"
43
44#include "story_entity.h"
45
46#include "shell_command.h"
47
48#include "spawning_point.h"
49
50
51using namespace std;
52
53
54CREATE_FACTORY(MultiplayerTeamDeathmatch, CL_MULTIPLAYER_TEAM_DEATHMATCH);
55
56
57/**
58 * constructor
59 */
60MultiplayerTeamDeathmatch::MultiplayerTeamDeathmatch(const TiXmlElement* root)
61  : NetworkGameRules(root)
62{
63  this->setClassID(CL_MULTIPLAYER_TEAM_DEATHMATCH, "MultiplayerTeamDeathmatch");
64
65  this->bLocalPlayerDead = false;
66  this->deathTimeout = 10.0f;     // 5 seconds
67  this->timeout = 0.0f;
68  this->numTeams = 2;
69  this->currentGameState = GAMESTATE_PRE_GAME;
70  this->gameStateTimer = 3.0f;
71  this->bShowTeamChange = false;
72
73  this->box = NULL;
74  this->table = NULL;
75  this->statsBox = NULL;
76
77  this->localPlayer = State::getPlayer();
78
79  if( root != NULL)
80    this->loadParams(root);
81
82  subscribeEvent( ES_GAME, SDLK_o );
83  subscribeEvent( ES_GAME, SDLK_TAB );
84  subscribeEvent( ES_GAME, SDLK_F1 );
85  subscribeEvent( ES_MENU, SDLK_F1 );
86  subscribeEvent( ES_MENU, KeyMapper::PEV_FIRE1 );
87
88  this->input = new OrxGui::GLGuiInputLine();
89  this->input->setAbsCoor2D(180, 5);
90  this->input->connect(SIGNAL(input, enterPushed), this, SLOT(MultiplayerTeamDeathmatch, onInputEnter));
91}
92
93/**
94 * decontsructor
95 */
96MultiplayerTeamDeathmatch::~MultiplayerTeamDeathmatch()
97{
98  unsubscribeEvent( ES_GAME, SDLK_o );
99  unsubscribeEvent( ES_GAME, SDLK_TAB );
100  unsubscribeEvent( ES_GAME, SDLK_F1 );
101  unsubscribeEvent( ES_MENU, SDLK_F1 );
102  unsubscribeEvent( ES_MENU, KeyMapper::PEV_FIRE1 );
103
104  if ( this->input )
105  {
106    delete this->input;
107    this->input = NULL;
108  }
109}
110
111
112
113void MultiplayerTeamDeathmatch::loadParams(const TiXmlElement* root)
114{
115  GameRules::loadParams(root) ;
116
117  LoadParam(root, "death-penalty-timeout", this, MultiplayerTeamDeathmatch, setDeathPenaltyTimeout)
118      .describe("sets the time in seconds a player has to wait for respawn");
119
120  LoadParam(root, "max-kills", this, MultiplayerTeamDeathmatch, setMaxKills)
121      .describe("sets the maximal kills for winning condition");
122
123  LoadParam(root, "num-teams", this, MultiplayerTeamDeathmatch, setNumTeams)
124      .describe("sets number of teams");
125
126}
127
128
129/**
130 * time tick
131 * @param dt time
132 */
133void MultiplayerTeamDeathmatch::tick(float dt)
134{
135  tickStatsTable();
136  //on client side hostId is -1 until hanshake finished
137  if ( SharedNetworkData::getInstance()->getHostID() < 0 )
138    return;
139
140  if ( currentGameState == GAMESTATE_PRE_GAME || currentGameState == GAMESTATE_GAME )
141  {
142    if ( PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() )
143         && box == NULL
144         &&  (PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() )->getPreferedTeamId() == TEAM_NOTEAM
145         || bShowTeamChange )
146
147       )
148    {
149      EventHandler::getInstance()->pushState( ES_MENU );
150
151      OrxGui::GLGuiHandler::getInstance()->activateCursor();
152
153      box = new OrxGui::GLGuiBox();
154      box->setAbsCoor2D( 300, 100 );
155
156      OrxGui::GLGuiPushButton * buttonSpectator = new OrxGui::GLGuiPushButton("Spectator");
157      box->pack( buttonSpectator );
158      buttonSpectator->connect(SIGNAL(buttonSpectator, released), this, SLOT(MultiplayerTeamDeathmatch, onButtonSpectator));
159
160      OrxGui::GLGuiPushButton * buttonRandom = new OrxGui::GLGuiPushButton("Random");
161      box->pack( buttonRandom );
162      buttonRandom->connect(SIGNAL(buttonRandom, released), this, SLOT(MultiplayerTeamDeathmatch, onButtonRandom));
163
164      OrxGui::GLGuiPushButton * buttonTeam0 = new OrxGui::GLGuiPushButton("Blue Team");
165      box->pack( buttonTeam0 );
166      buttonTeam0->connect(SIGNAL(buttonTeam0, released), this, SLOT(MultiplayerTeamDeathmatch, onButtonTeam0));
167
168      OrxGui::GLGuiPushButton * buttonTeam1 = new OrxGui::GLGuiPushButton("Red Team");
169      box->pack( buttonTeam1 );
170      buttonTeam1->connect(SIGNAL(buttonTeam1, released), this, SLOT(MultiplayerTeamDeathmatch, onButtonTeam1));
171
172      if ( bShowTeamChange )
173      {
174        OrxGui::GLGuiPushButton * buttonCancel = new OrxGui::GLGuiPushButton("Cancel");
175        box->pack( buttonCancel );
176        buttonCancel->connect(SIGNAL(buttonCancel, released), this, SLOT(MultiplayerTeamDeathmatch, onButtonCancel));
177      }
178
179      OrxGui::GLGuiPushButton * buttonExit = new OrxGui::GLGuiPushButton("Exit");
180      box->pack( buttonExit );
181      buttonExit->connect(SIGNAL(buttonExit, released), this, SLOT(MultiplayerTeamDeathmatch, onButtonExit));
182
183      box->showAll();
184    }
185  }
186
187  if ( box != NULL
188       && PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() )
189       && PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() )->getPreferedTeamId() != TEAM_NOTEAM
190       && !bShowTeamChange
191     )
192  {
193    delete box;
194    box = NULL;
195
196    OrxGui::GLGuiHandler::getInstance()->deactivateCursor( true );
197
198    EventHandler::getInstance()->popState();
199  }
200
201  if ( box != NULL )
202  {
203    OrxGui::GLGuiHandler::getInstance()->tick( dt );
204  }
205
206  assignPlayable();
207
208  if ( !SharedNetworkData::getInstance()->isGameServer() )
209    return;
210
211  //handle kills
212  while ( this->killList.begin() != this->killList.end() )
213  {
214    onKill( this->killList.begin()->getVictim(), this->killList.begin()->getKiller() );
215    this->killList.erase( this->killList.begin() );
216  }
217 
218
219
220  gameStateTimer -= dt;
221  //PRINTF(0)("TICK %f\n", gameStateTimer);
222
223  if ( currentGameState != GAMESTATE_GAME && gameStateTimer < 0 )
224    nextGameState();
225
226  this->currentGameState = NetworkGameManager::getInstance()->getGameState();
227
228  if ( currentGameState == GAMESTATE_GAME )
229  {
230    handleTeamChanges();
231  }
232
233  this->calculateTeamScore();
234
235  this->checkGameRules();
236
237  // is the local player dead and inactive
238  if( unlikely(this->bLocalPlayerDead))
239  {
240    this->timeout += dt;
241    PRINTF(0)("TICK DEATH: %f of %f\n", this->timeout, this->deathTimeout);
242    // long enough dead?
243    if( this->timeout >= this->deathTimeout)
244    {
245      this->timeout = 0.0f;
246      // respawn
247      PRINTF(0)("RESPAWN\n");
248      (State::getPlayer())->getPlayable()->respawn();
249    }
250  }
251}
252
253
254/**
255 * draws the stuff
256 */
257void MultiplayerTeamDeathmatch::draw()
258{
259  if( unlikely( this->bLocalPlayerDead))
260  {
261
262  }
263}
264
265
266/**
267 * check the game rules for consistency
268 */
269void MultiplayerTeamDeathmatch::checkGameRules()
270{
271  if ( !SharedNetworkData::getInstance()->isGameServer() )
272    return;
273
274  // check for max killing count
275  for ( int i = 0; i<numTeams; i++ )
276  {
277    if ( teamScore[i] >= maxKills )
278    {
279      nextGameState();
280    }
281  }
282}
283
284/**
285 * find group for new player
286 * @return group id
287 */
288int MultiplayerTeamDeathmatch::getTeamForNewUser()
289{
290  return TEAM_NOTEAM;
291}
292
293ClassID MultiplayerTeamDeathmatch::getPlayableClassId( int userId, int team )
294{
295  if ( team == TEAM_NOTEAM || team == TEAM_SPECTATOR )
296    return CL_SPECTATOR;
297
298  if ( team == 0 || team == 1 )
299    return CL_SPACE_SHIP;
300
301  assert( false );
302}
303
304std::string MultiplayerTeamDeathmatch::getPlayableModelFileName( int userId, int team, ClassID classId )
305{
306  if ( team == 0 )
307    return "models/ships/reap_#.obj";
308  else if ( team == 1 )
309    return "models/ships/fighter.obj";
310  else
311    return "";
312}
313
314/**
315 * calculate team score
316 */
317void MultiplayerTeamDeathmatch::calculateTeamScore( )
318{
319  teamScore.clear();
320
321  for ( int i = 0; i<numTeams; i++ )
322    teamScore[i] = 0;
323
324
325  const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYER_STATS );
326
327  if ( !list )
328    return;
329
330  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
331  {
332    PlayerStats & stats = *dynamic_cast<PlayerStats*>(*it);
333
334    if ( stats.getTeamId() >= 0 )
335    {
336      teamScore[stats.getTeamId()] += stats.getScore();
337    }
338  }
339}
340
341/**
342 * get team for player who choose to join random team
343 * @return smallest team
344 */
345int MultiplayerTeamDeathmatch::getRandomTeam( )
346{
347  std::map<int,int> playersInTeam;
348
349  for ( int i = 0; i<numTeams; i++ )
350    playersInTeam[i] = 0;
351
352  const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYER_STATS );
353
354  if ( !list )
355    return 0;
356
357  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
358  {
359    PlayerStats & stats = *dynamic_cast<PlayerStats*>(*it);
360
361    if ( stats.getTeamId() >= 0 )
362    {
363      playersInTeam[stats.getTeamId()]++;
364    }
365  }
366
367
368  int minPlayers = 0xFFFF;
369  int minTeam = -1;
370
371  for ( int i = 0; i<numTeams; i++ )
372  {
373    if ( playersInTeam[i] < minPlayers )
374    {
375      minTeam = i;
376      minPlayers = playersInTeam[i];
377    }
378  }
379
380  assert( minTeam != -1 );
381
382  return minTeam;
383}
384
385void MultiplayerTeamDeathmatch::nextGameState( )
386{
387  if ( currentGameState == GAMESTATE_PRE_GAME )
388  {
389    NetworkGameManager::getInstance()->setGameState( GAMESTATE_GAME );
390
391    return;
392  }
393
394  if ( currentGameState == GAMESTATE_GAME )
395  {
396    NetworkGameManager::getInstance()->setGameState( GAMESTATE_POST_GAME );
397
398    return;
399  }
400
401  if ( currentGameState == GAMESTATE_POST_GAME )
402  {
403    State::getCurrentStoryEntity()->stop();
404    this->bShowTeamChange = false;
405
406    return;
407  }
408}
409
410void MultiplayerTeamDeathmatch::handleTeamChanges( )
411{
412  const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYER_STATS );
413
414  if ( !list )
415    return;
416
417  //first server players with choices
418  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
419  {
420    PlayerStats & stats = *dynamic_cast<PlayerStats*>(*it);
421
422    if ( stats.getTeamId() != stats.getPreferedTeamId() )
423    {
424      if ( stats.getPreferedTeamId() == TEAM_SPECTATOR || ( stats.getPreferedTeamId() >= 0 && stats.getPreferedTeamId() < numTeams ) )
425      {
426        teamChange( stats.getUserId() );
427      }
428    }
429  }
430
431  //now serve player who want join a random team
432  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
433  {
434    PlayerStats & stats = *dynamic_cast<PlayerStats*>(*it);
435
436    if ( stats.getTeamId() != stats.getPreferedTeamId() )
437    {
438      if ( stats.getPreferedTeamId() == TEAM_RANDOM )
439      {
440        stats.setPreferedTeamId( getRandomTeam() );
441        teamChange( stats.getUserId() );
442      }
443    }
444  }
445}
446
447void MultiplayerTeamDeathmatch::teamChange( int userId )
448{
449  assert( PlayerStats::getStats( userId ) );
450  PlayerStats & stats = *(PlayerStats::getStats( userId ));
451
452  stats.setTeamId( stats.getPreferedTeamId() );
453
454  Playable * oldPlayable = stats.getPlayable();
455
456
457  ClassID playableClassId = getPlayableClassId( userId, stats.getPreferedTeamId() );
458  std::string playableModel = getPlayableModelFileName( userId, stats.getPreferedTeamId(), playableClassId );
459
460  BaseObject * bo = Factory::fabricate( playableClassId );
461
462  assert( bo != NULL );
463  assert( bo->isA( CL_PLAYABLE ) );
464
465  Playable & playable = *(dynamic_cast<Playable*>(bo));
466
467  playable.loadModel( playableModel );
468  playable.setOwner( userId );
469  playable.setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
470  playable.setSynchronized( true );
471
472  stats.setTeamId( stats.getPreferedTeamId() );
473  stats.setPlayableClassId( playableClassId );
474  stats.setPlayableUniqueId( playable.getUniqueID() );
475  stats.setModelFileName( playableModel );
476
477  this->respawnPlayable( &playable, stats.getPreferedTeamId(), 0.0f );
478
479  if ( oldPlayable )
480  {
481    //if ( userId == SharedNetworkData::getInstance()->getHostID() )
482    //  State::getPlayer()->setPlayable( NULL );
483    delete oldPlayable;
484  }
485}
486
487void MultiplayerTeamDeathmatch::onButtonExit( )
488{
489  State::getCurrentStoryEntity()->stop();
490  this->bShowTeamChange = false;
491}
492
493void MultiplayerTeamDeathmatch::onButtonRandom( )
494{
495  NetworkGameManager::getInstance()->prefereTeam( TEAM_RANDOM );
496  this->bShowTeamChange = false;
497}
498
499void MultiplayerTeamDeathmatch::onButtonTeam0( )
500{
501  NetworkGameManager::getInstance()->prefereTeam( 0 );
502  this->bShowTeamChange = false;
503}
504
505void MultiplayerTeamDeathmatch::onButtonTeam1( )
506{
507  NetworkGameManager::getInstance()->prefereTeam( 1 );
508  this->bShowTeamChange = false;
509}
510
511void MultiplayerTeamDeathmatch::onButtonSpectator( )
512{
513  NetworkGameManager::getInstance()->prefereTeam( TEAM_SPECTATOR );
514  this->bShowTeamChange = false;
515}
516
517void MultiplayerTeamDeathmatch::assignPlayable( )
518{
519  if ( PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() ) )
520    PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() )->getPlayable();
521}
522
523  /**
524   * function that processes events from the handler
525   * @param event: the event
526   * @todo replace SDLK_o with something from KeyMapper
527   */
528void MultiplayerTeamDeathmatch::process( const Event & event )
529{
530  if ( event.type == SDLK_o )
531  {
532    if ( event.bPressed )
533      this->bShowTeamChange = true;
534  } else if ( event.type == SDLK_F1 )
535  {
536    if ( !this->statsBox && event.bPressed )
537    {
538      PRINTF(0)("show stats\n");
539      this->showStats();
540    }
541    if ( this->statsBox && !this->bLocalPlayerDead && event.bPressed && this->table->rowCount() != 0 && this->table->columnCount() != 0 )
542    {
543      PRINTF(0)("hide stats\n");
544      this->hideStats();
545    }
546  }
547  else if ( event.type == SDLK_TAB )
548  {
549    if ( currentGameState == GAMESTATE_GAME && event.bPressed && !EventHandler::getInstance()->isPressed( SDLK_RALT ) && !EventHandler::getInstance()->isPressed( SDLK_LALT ) )
550    {
551      EventHandler::getInstance()->pushState( ES_MENU );
552      OrxGui::GLGuiHandler::getInstance()->activateCursor();
553      OrxGui::GLGuiHandler::getInstance()->deactivateCursor();
554      input->show();
555      input->giveMouseFocus();
556      input->setText("say ");
557    }
558  }
559  else if ( this->bLocalPlayerDead && statsBox && event.type == KeyMapper::PEV_FIRE1 )
560  {
561    this->hideStats();
562  }
563}
564
565void MultiplayerTeamDeathmatch::onButtonCancel( )
566{
567  this->bShowTeamChange = false;
568}
569
570
571
572/**
573 * this method is called by NetworkGameManger when he recieved a chat message
574 * @param userId senders user id
575 * @param message message string
576 * @param messageType some int
577 */
578void MultiplayerTeamDeathmatch::handleChatMessage( int userId, const std::string & message, int messageType )
579{
580  std::string name = "unknown";
581
582  if ( PlayerStats::getStats( userId ) )
583  {
584    name = PlayerStats::getStats( userId )->getNickName();
585  }
586
587  PRINTF(0)("CHATMESSAGE %s (%d): %s\n", name.c_str(), userId, message.c_str() );
588  State::getPlayer()->getHud().notifyUser(name + ": " + message);
589}
590
591void MultiplayerTeamDeathmatch::onInputEnter( const std::string & text )
592{
593  EventHandler::getInstance()->popState();
594  input->breakMouseFocus();
595  input->hide();
596  input->setText("");
597
598  std::string command = text;
599
600  //HACK insert " in say commands so user doesn't have to type them
601  if ( command.length() >= 4 && command[0] == 's' && command[1] == 'a' && command[2] == 'y' && command[3] == ' ' )
602  {
603    command.insert( 4, "\"" );
604    command = command + "\"";
605  }
606
607  OrxShell::ShellCommand::execute( command );
608}
609
610/**
611 * show table with frags
612 */
613void MultiplayerTeamDeathmatch::showStats( )
614{
615  EventHandler::getInstance()->pushState( ES_MENU );
616  statsBox = new OrxGui::GLGuiBox();
617  statsBox->setAbsCoor2D( 300, 100 );
618
619  this->table = new OrxGui::GLGuiTable(0,0);
620
621  statsBox->pack( this->table );
622
623  statsBox->showAll();
624}
625
626/**
627 * hide table with frags
628 */
629void MultiplayerTeamDeathmatch::hideStats( )
630{
631    if ( statsBox )
632    {
633      delete statsBox;
634      statsBox = NULL;
635    }
636
637    EventHandler::getInstance()->popState();
638}
639
640/**
641 * fill stats table with values
642 */
643void MultiplayerTeamDeathmatch::tickStatsTable( )
644{
645  if ( !this->statsBox )
646    return;
647
648  std::vector<std::string> headers;
649  headers.push_back("Red Team");
650  headers.push_back("");
651  headers.push_back("");
652  headers.push_back("Blue Team");
653  headers.push_back("");
654  this->table->setHeader(headers);
655
656  std::map<int,std::string> fragsTeam0;
657  std::map<int,std::string> fragsTeam1;
658
659  const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYER_STATS );
660
661  if ( !list )
662    return;
663
664  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
665  {
666    PlayerStats & stats = *dynamic_cast<PlayerStats*>(*it);
667
668    if ( stats.getTeamId() == 0 || stats.getTeamId() == 1 )
669    {
670      if ( stats.getTeamId() == 0 )
671        fragsTeam0[stats.getScore()] = stats.getNickName();
672      else
673        fragsTeam1[stats.getScore()] = stats.getNickName();
674    }
675  }
676
677  char st[10];
678  int i = 0;
679
680
681  i = 2;
682  for ( std::map<int,std::string>::const_iterator it = fragsTeam0.begin(); it != fragsTeam0.end(); it++ )
683  {
684    this->table->setEntry( 0, i, it->second );
685    snprintf( st, 10, "%d", it->first );
686    this->table->setEntry( 1, i, st );
687    this->table->setEntry( 2, i, "" );
688    i++;
689  }
690
691  i = 2;
692  for ( std::map<int,std::string>::const_iterator it = fragsTeam1.begin(); it != fragsTeam1.end(); it++ )
693  {
694    this->table->setEntry( 3, i, it->second );
695    snprintf( st, 10, "%d", it->first );
696    this->table->setEntry( 4, i, st );
697    i++;
698  }
699}
700
701/**
702 * this function is called when a player kills another one or himself
703 * @param killedUserId
704 * @param userId
705 */
706void MultiplayerTeamDeathmatch::onKill( WorldEntity * victim, WorldEntity * killer )
707{
708  if ( !victim )
709    return;
710  if ( !killer )
711    return;
712 
713  int killerUserId = killer->getOwner();
714  int victimUserId = victim->getOwner();
715
716  PlayerStats & victimStats = *PlayerStats::getStats( victimUserId );
717  PlayerStats & killerStats = *PlayerStats::getStats( killerUserId );
718 
719  if ( killerStats.getPlayable() != killer || victimStats.getPlayable() != victim )
720    return;
721
722  //check for suicide
723  if ( killerUserId != victimUserId )
724  {
725    //check for teamkill
726    if ( victimStats.getTeamId() != killerStats.getTeamId() )
727    {
728      killerStats.setScore( killerStats.getScore() + 1 );
729    }
730    else
731    {
732      killerStats.setScore( killerStats.getScore() - 1 );
733    }
734  }
735  else
736    killerStats.setScore( killerStats.getScore() - 1 );
737
738  if ( victimUserId == SharedNetworkData::getInstance()->getHostID() )
739  {
740    this->bLocalPlayerDead = true;
741    this->showStats();
742  }
743
744  this->respawnPlayable( victimStats.getPlayable(), victimStats.getTeamId(), 3.0f );
745}
746
747/**
748 * this function is called on player respawn
749 * @param userId
750 */
751void MultiplayerTeamDeathmatch::onRespawn( int userId )
752{
753  if ( userId == SharedNetworkData::getInstance()->getHostID() )
754  {
755    this->bLocalPlayerDead = false;
756    this->hideStats();
757  }
758}
759
760/**
761 * this function is called on player respawn
762 * @param we
763 */
764void MultiplayerTeamDeathmatch::registerSpawn( WorldEntity * we )
765{
766  onRespawn( we->getOwner() );
767}
768
769
770void MultiplayerTeamDeathmatch::respawnPlayable( Playable * playable, int teamId, float delay )
771{
772  const std::list<BaseObject*> * list = ClassList::getList( CL_SPAWNING_POINT );
773
774  assert( list );
775
776  std::vector<SpawningPoint*> spList;
777
778  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
779  {
780    SpawningPoint * sp = dynamic_cast<SpawningPoint*>(*it);
781
782    if ( sp->getTeamId() == teamId )
783      spList.push_back( sp );
784  }
785
786  if ( spList.size() == 0 )
787  {
788    for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
789    {
790      SpawningPoint * sp = dynamic_cast<SpawningPoint*>(*it);
791
792      if ( sp->getTeamId() < 0 )
793        spList.push_back( sp );
794    }
795  }
796
797  assert( spList.size() != 0 );
798
799  int n = (int)((float)spList.size() * (float)rand()/(float)RAND_MAX);
800
801  spList[n]->pushEntity( playable, delay );
802}
803
Note: See TracBrowser for help on using the repository browser.