Index: trunk/src/util/multiplayer_team_deathmatch.cc
===================================================================
--- trunk/src/util/multiplayer_team_deathmatch.cc	(revision 7954)
+++ trunk/src/util/multiplayer_team_deathmatch.cc	(revision 8068)
@@ -15,4 +15,6 @@
 #define DEBUG_MODULE_GAME_RULES
 
+#include <map>
+
 #include "multiplayer_team_deathmatch.h"
 
@@ -34,4 +36,6 @@
 #include "space_ships/space_ship.h"
 
+#include "network_game_manager.h"
+
 
 using namespace std;
@@ -45,5 +49,5 @@
  */
 MultiplayerTeamDeathmatch::MultiplayerTeamDeathmatch(const TiXmlElement* root)
-  : GameRules(root)
+  : NetworkGameRules(root)
 {
   this->setClassID(CL_MULTIPLAYER_TEAM_DEATHMATCH, "MultiplayerTeamDeathmatch");
@@ -52,4 +56,7 @@
   this->deathTimeout = 10.0f;     // 5 seconds
   this->timeout = 0.0f;
+  this->numTeams = 2;
+  this->currentGameState = GAMESTATE_PRE_GAME;
+  this->gameStateTimer = 10.0f;
 
   this->deathScreen = new ImagePlane();
@@ -87,4 +94,7 @@
   LoadParam(root, "death-screen-image", this, MultiplayerTeamDeathmatch, setDeathScreen)
       .describe("sets the death screen image");
+  
+  LoadParam(root, "num-teams", this, MultiplayerTeamDeathmatch, setNumTeams)
+      .describe("sets number of teams");
 
 }
@@ -128,4 +138,22 @@
 void MultiplayerTeamDeathmatch::tick(float dt)
 {
+  if ( !SharedNetworkData::getInstance()->isGameServer() )
+    return;
+  
+  gameStateTimer -= dt;
+  PRINTF(0)("TICK %f\n", gameStateTimer);
+  
+  if ( currentGameState != GAMESTATE_GAME && gameStateTimer < 0 )
+    nextGameState();
+  
+  this->currentGameState = NetworkGameManager::getInstance()->getGameState();
+  
+  if ( currentGameState == GAMESTATE_GAME )
+  {
+    handleTeamChanges();
+  }
+  
+  this->calculateTeamScore();
+  
   this->checkGameRules();
 
@@ -164,95 +192,180 @@
 void MultiplayerTeamDeathmatch::checkGameRules()
 {
-
-  Vector big_left(-201, 0, 0);
-  float rBig = 176.0f;
-  Vector big_right(177, 0, 0);
-  Vector small_left(10, 0, 0);
-  Vector small_middle(0, 0, 0);
-  Vector small_right(-10, 0, 0);
-  float rSmall = 90.0f;
-
-
+  if ( !SharedNetworkData::getInstance()->isGameServer() )
+    return;
+  
   // check for max killing count
-  if( this->teamAKills >= this->maxKills)
-  {
-    // team A winns
-  }
-  else if( this->teamBKills >= this->maxKills)
-  {
-    // team B winns
-  }
-
-
-  if ( SharedNetworkData::getInstance()->isGameServer() )
-  {
-    float offsetx = 500.0f;
-    float offsety = 323.0f;
-    float offsetz = 200.0f;
-
-    offsetz += 10;
-
-    Terrain * terrain = dynamic_cast<Terrain*>(*(ClassList::getList( CL_TERRAIN )->begin()));
-    const std::list<BaseObject*> * list = ClassList::getList( CL_SPACE_SHIP );
-    for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++)
-    {
-      SpaceShip * ss = dynamic_cast<SpaceShip*>(*it);
-      float terrx = ss->getAbsCoor().x + offsetx;
-      float terry = ss->getAbsCoor().z + offsetz;
-      float terrz = ss->getAbsCoor().y + offsety;
-      if ( terrz < terrain->getHeight( terrx, terry ) && ss->getAbsCoor().x > -1000 )
+  for ( int i = 0; i<numTeams; i++ )
+  {
+    if ( teamScore[i] >= maxKills )
+    {
+      //team i wins
+      //TODO
+    }
+  }
+}
+
+/**
+ * find group for new player
+ * @return group id
+ */
+int MultiplayerTeamDeathmatch::getTeamForNewUser( )
+{
+  return TEAM_NOTEAM;
+}
+
+ClassID MultiplayerTeamDeathmatch::getPlayableClassId( int team )
+{
+  return CL_SPECTATOR;
+}
+
+std::string MultiplayerTeamDeathmatch::getPlayableModelFileName( int team, ClassID classId )
+{
+  return "";
+}
+
+/**
+ * calculate team score
+ */
+void MultiplayerTeamDeathmatch::calculateTeamScore( )
+{
+  teamScore.clear();
+  
+  for ( int i = 0; i<numTeams; i++ )
+    teamScore[i] = 0;
+  
+    
+  const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYER_STATS );
+  
+  if ( !list )
+    return;
+  
+  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
+  {
+    PlayerStats & stats = *dynamic_cast<PlayerStats*>(*it);
+
+    if ( stats.getTeamId() >= 0 )
+    {
+      teamScore[stats.getTeamId()] += stats.getScore();
+    }
+  }
+}
+
+/**
+ * get team for player who choose to join random team
+ * @return smallest team
+ */
+int MultiplayerTeamDeathmatch::getRandomTeam( )
+{
+  std::map<int,int> playersInTeam;
+  
+  for ( int i = 0; i<numTeams; i++ )
+    playersInTeam[i] = 0;
+  
+  const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYER_STATS );
+  
+  if ( !list )
+    return 0;
+  
+  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
+  {
+    PlayerStats & stats = *dynamic_cast<PlayerStats*>(*it);
+
+    if ( stats.getTeamId() >= 0 )
+    {
+      playersInTeam[stats.getTeamId()]++;
+    }
+  }
+  
+  
+  int minPlayers = 0xFFFF;
+  int minTeam = -1;
+  
+  for ( int i = 0; i<numTeams; i++ )
+  {
+    if ( playersInTeam[i] < minPlayers )
+    {
+      minTeam = i;
+      minPlayers = playersInTeam[i];
+    }
+  }
+  
+  assert( minTeam != -1 );
+  
+  return minTeam;
+}
+
+void MultiplayerTeamDeathmatch::nextGameState( )
+{
+  if ( currentGameState == GAMESTATE_PRE_GAME )
+  {
+    NetworkGameManager::getInstance()->setGameState( GAMESTATE_GAME );
+    
+    return;
+  }
+  
+  if ( currentGameState == GAMESTATE_GAME )
+  {
+    NetworkGameManager::getInstance()->setGameState( GAMESTATE_POST_GAME );
+    
+    return;
+  }
+  
+  if ( currentGameState == GAMESTATE_POST_GAME )
+  {
+    //TODO end game
+    
+    return;
+  }
+}
+
+void MultiplayerTeamDeathmatch::handleTeamChanges( )
+{
+  const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYER_STATS );
+  
+  if ( !list )
+    return;
+  
+  //first server players with choices
+  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
+  {
+    PlayerStats & stats = *dynamic_cast<PlayerStats*>(*it);
+
+    if ( stats.getTeamId() != stats.getPreferedTeamId() )
+    {
+      if ( stats.getPreferedTeamId() == TEAM_SPECTATOR || ( stats.getPreferedTeamId() <= 0 && stats.getPreferedTeamId() < numTeams ) )
       {
-        //TODO handle this
+        teamChange( stats.getUserId() );
       }
-
-
-      float dist = (dynamic_cast<Playable*>(*it)->getAbsCoor() - big_left).len();
-      if( (dynamic_cast<Playable*>(*it)->getAbsCoor() - big_left).len() > rBig &&
-           (dynamic_cast<Playable*>(*it)->getAbsCoor() - big_right).len() > rBig &&
-           (dynamic_cast<Playable*>(*it)->getAbsCoor() - small_left).len() > rSmall &&
-           (dynamic_cast<Playable*>(*it)->getAbsCoor() - small_middle).len() > rSmall &&
-           (dynamic_cast<Playable*>(*it)->getAbsCoor() - small_right).len() > rSmall
-           && ss->getAbsCoor().x > -1000)
+    }
+  }
+  
+  //now serve player who want join a random team
+  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
+  {
+    PlayerStats & stats = *dynamic_cast<PlayerStats*>(*it);
+
+    if ( stats.getTeamId() != stats.getPreferedTeamId() )
+    {
+      if ( stats.getPreferedTeamId() == TEAM_RANDOM )
       {
-        PRINTF(0)("KILLLLLLLL\n");
-
-        if((*it)->isA(CL_SPACE_SHIP))
-        {
-          //TODO handle this
-        }
+        stats.setPreferedTeamId( getTeamForNewUser() );
+        teamChange( stats.getUserId() );
       }
     }
   }
-
-
-#if 0
-  std::list<BaseObject*>::const_iterator it;
-  const std::list<BaseObject*>* list = ClassList::getList(CL_PLAYABLE);
-
-  if( SharedNetworkData::getInstance()->isGameServer())
-  {
-    for(it = list->begin(); it != list->end(); it++)
-    {
-      float dist = (dynamic_cast<Playable*>(*it)->getAbsCoor() - big_left).len();
-      if( (dynamic_cast<Playable*>(*it)->getAbsCoor() - big_left).len() > rBig &&
-           (dynamic_cast<Playable*>(*it)->getAbsCoor() - big_right).len() > rBig &&
-           (dynamic_cast<Playable*>(*it)->getAbsCoor() - small_left).len() > rSmall &&
-           (dynamic_cast<Playable*>(*it)->getAbsCoor() - small_middle).len() > rSmall &&
-           (dynamic_cast<Playable*>(*it)->getAbsCoor() - small_right).len() > rSmall)
-      {
-        PRINTF(0)("KILLLLLLLL\n");
-
-        if((*it)->isA(CL_SPACE_SHIP))
-          dynamic_cast<SpaceShip*>(*it)->doCollideNetwork(116369220.33434f);
-      }
-    }
-  }
-#endif
-
-}
-
-
-
-
-
-
+}
+
+void MultiplayerTeamDeathmatch::teamChange( int userId )
+{
+  assert( PlayerStats::getStats( userId ) );
+  PlayerStats & stats = *(PlayerStats::getStats( userId ));
+  
+  assert(false);
+}
+
+
+
+
+
+
