Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/presentation/src/util/multiplayer_team_deathmatch.cc @ 9135

Last change on this file since 9135 was 9119, checked in by rennerc, 19 years ago

added scling for playables

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