Index: trunk/src/util/multiplayer_team_deathmatch.cc
===================================================================
--- trunk/src/util/multiplayer_team_deathmatch.cc	(revision 8717)
+++ trunk/src/util/multiplayer_team_deathmatch.cc	(revision 8802)
@@ -45,4 +45,6 @@
 
 #include "shell_command.h"
+
+#include "spawning_point.h"
 
 
@@ -70,9 +72,6 @@
 
   this->box = NULL;
-
-  this->deathScreen = new ImagePlane();
-  this->deathScreen->setSize(State::getResX()/4.0, State::getResY()/4.0);
-  this->deathScreen->setAbsCoor2D(State::getResX()/2.0f, State::getResY()/2.0f);
-  this->deathScreen->setVisibility(false);
+  this->table = NULL;
+  this->statsBox = NULL;
 
   this->localPlayer = State::getPlayer();
@@ -83,5 +82,8 @@
   subscribeEvent( ES_GAME, SDLK_o );
   subscribeEvent( ES_GAME, SDLK_TAB );
-
+  subscribeEvent( ES_GAME, SDLK_F1 );
+  subscribeEvent( ES_MENU, SDLK_F1 );
+  subscribeEvent( ES_MENU, KeyMapper::PEV_FIRE1 );
+  
   this->notifier = new OrxGui::GLGuiNotifier();
   this->notifier->show();
@@ -99,10 +101,10 @@
 MultiplayerTeamDeathmatch::~MultiplayerTeamDeathmatch()
 {
-  if( this->deathScreen)
-    delete this->deathScreen;
-
   unsubscribeEvent( ES_GAME, SDLK_o );
   unsubscribeEvent( ES_GAME, SDLK_TAB );
-
+  unsubscribeEvent( ES_GAME, SDLK_F1 );
+  unsubscribeEvent( ES_MENU, SDLK_F1 );
+  unsubscribeEvent( ES_MENU, KeyMapper::PEV_FIRE1 );
+  
   if ( this->notifier )
   {
@@ -130,7 +132,4 @@
       .describe("sets the maximal kills for winning condition");
 
-  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");
@@ -139,35 +138,4 @@
 
 
-
-void MultiplayerTeamDeathmatch::setDeathScreen(const std::string& imageName)
-{
-  if( this->deathScreen)
-    this->deathScreen->setTexture(imageName);
-}
-
-
-
-/**
- * called when the player enters the game
- * @param player the spawned player
- */
-void MultiplayerTeamDeathmatch::onPlayerSpawn()
-{
-  this->bLocalPlayerDead = false;
-  this->deathScreen->setVisibility(false);
-}
-
-
-/**
- * when the player is killed
- * @param player the killed player
- */
-void MultiplayerTeamDeathmatch::onPlayerDeath()
-{
-  this->bLocalPlayerDead = true;
-  this->deathScreen->setVisibility(true);
-}
-
-
 /**
  * time tick
@@ -176,4 +144,5 @@
 void MultiplayerTeamDeathmatch::tick(float dt)
 {
+  tickStatsTable();
   //on client side hostId is -1 until hanshake finished
   if ( SharedNetworkData::getInstance()->getHostID() < 0 )
@@ -250,5 +219,16 @@
   if ( !SharedNetworkData::getInstance()->isGameServer() )
     return;
-
+    
+  //handle kills
+  for ( std::vector<Kill>::iterator it = this->killList.begin(); it != this->killList.end();  )
+  {
+    std::vector<Kill>::iterator delit = it;
+    
+    onKill( it->getKiller()->getOwner(), it->getVictim()->getOwner() );
+    
+    it++;
+    killList.erase( delit );
+  }
+  
   gameStateTimer -= dt;
   //PRINTF(0)("TICK %f\n", gameStateTimer);
@@ -310,6 +290,5 @@
     if ( teamScore[i] >= maxKills )
     {
-      //team i wins
-      //TODO
+      nextGameState();
     }
   }
@@ -435,5 +414,6 @@
   if ( currentGameState == GAMESTATE_POST_GAME )
   {
-    //TODO end game
+    State::getCurrentStoryEntity()->stop();
+    this->bShowTeamChange = false;
 
     return;
@@ -563,4 +543,16 @@
     if ( event.bPressed )
       this->bShowTeamChange = true;
+  } else if ( event.type == SDLK_F1 )
+  {
+    if ( !this->statsBox && event.bPressed )
+    {
+      PRINTF(0)("show stats\n");
+      this->showStats();
+    }
+    if ( this->statsBox && !this->bLocalPlayerDead && event.bPressed && this->table->rowCount() != 0 && this->table->columnCount() != 0 )
+    {
+      PRINTF(0)("hide stats\n");
+      this->hideStats();
+    }
   }
   else if ( event.type == SDLK_TAB )
@@ -576,4 +568,8 @@
     }
   }
+  else if ( this->bLocalPlayerDead && statsBox && event.type == KeyMapper::PEV_FIRE1 )
+  {
+    this->hideStats();
+  }
 }
 
@@ -623,5 +619,158 @@
 }
 
-
-
-
+/**
+ * show table with frags
+ */
+void MultiplayerTeamDeathmatch::showStats( )
+{
+  EventHandler::getInstance()->pushState( ES_MENU );
+  statsBox = new OrxGui::GLGuiBox();
+  statsBox->setAbsCoor2D( 300, 100 );
+  
+  this->table = new OrxGui::GLGuiTable(0,0);
+
+  statsBox->pack( this->table );
+
+  statsBox->showAll();
+}
+
+/**
+ * hide table with frags
+ */
+void MultiplayerTeamDeathmatch::hideStats( )
+{
+    if ( statsBox )
+    {
+      delete statsBox;
+      statsBox = NULL;
+    }
+      
+    EventHandler::getInstance()->popState();
+}
+
+/**
+ * fill stats table with values
+ */
+void MultiplayerTeamDeathmatch::tickStatsTable( )
+{
+  if ( !this->statsBox )
+    return;
+
+  std::vector<std::string> headers;
+  headers.push_back("Red Team");
+  headers.push_back("");
+  headers.push_back("");
+  headers.push_back("Blue Team");
+  headers.push_back("");
+  this->table->setHeader(headers);
+  
+  std::map<int,std::string> fragsTeam0;
+  std::map<int,std::string> fragsTeam1;
+  
+  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 || stats.getTeamId() == 1 )
+    {
+      if ( stats.getTeamId() == 0 )
+        fragsTeam0[stats.getScore()] = stats.getNickName();
+      else
+        fragsTeam1[stats.getScore()] = stats.getNickName();
+    }
+  }
+  
+  char st[10];
+  int i = 0;
+  
+  
+  i = 2;
+  for ( std::map<int,std::string>::const_iterator it = fragsTeam0.begin(); it != fragsTeam0.end(); it++ )
+  {
+    this->table->setEntry( 0, i, it->second );
+    snprintf( st, 10, "%d", it->first );
+    this->table->setEntry( 1, i, st );
+    this->table->setEntry( 2, i, "" );
+    i++;
+  }
+  
+  i = 2;
+  for ( std::map<int,std::string>::const_iterator it = fragsTeam1.begin(); it != fragsTeam1.end(); it++ )
+  {
+    this->table->setEntry( 3, i, it->second );
+    snprintf( st, 10, "%d", it->first );
+    this->table->setEntry( 4, i, st );
+    i++;
+  }
+}
+
+/**
+ * this function is called when a player kills another one or himself
+ * @param killedUserId 
+ * @param userId 
+ */
+void MultiplayerTeamDeathmatch::onKill( int killedUserId, int userId )
+{
+  assert( PlayerStats::getStats( killedUserId ) );
+  assert( PlayerStats::getStats( userId ) );
+  
+  PlayerStats & killedStats = *PlayerStats::getStats( killedUserId );
+  PlayerStats & stats = *PlayerStats::getStats( userId );
+  
+  if ( killedUserId != userId )
+    stats.setScore( stats.getScore() + 1 );
+  else
+    stats.setScore( stats.getScore() - 1 );
+  
+  if ( killedUserId == SharedNetworkData::getInstance()->getHostID() )
+  {
+    this->bLocalPlayerDead = true;
+    this->showStats();
+  }
+  
+  const std::list<BaseObject*> * list = ClassList::getList( CL_SPAWNING_POINT );
+  
+  assert( list );
+  
+  std::vector<SpawningPoint*> spList;
+  
+  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
+  {
+    SpawningPoint * sp = dynamic_cast<SpawningPoint*>(*it);
+    
+    if ( sp->getTeamId() < 0 || sp->getTeamId() == killedStats.getTeamId() )
+      spList.push_back( sp );
+  }
+ 
+  int n = spList.size()*rand();
+  
+  spList[n]->pushEntity( killedStats.getPlayable(), 3 );
+}
+
+/**
+ * this function is called on player respawn
+ * @param userId 
+ */
+void MultiplayerTeamDeathmatch::onRespawn( int userId )
+{
+  if ( userId == SharedNetworkData::getInstance()->getHostID() )
+  {
+    this->bLocalPlayerDead = false;
+    this->hideStats();
+  }
+}
+
+/**
+ * this function is called on player respawn
+ * @param we 
+ */
+void MultiplayerTeamDeathmatch::registerSpawn( WorldEntity * we )
+{
+  onRespawn( we->getOwner() );
+}
+
