src/team/teams_list.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *  Wormux is a convivial mass murder game.
00003  *  Copyright (C) 2001-2004 Lawrence Azzoug.
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00018  ******************************************************************************
00019  * Team handling
00020  *****************************************************************************/
00021 
00022 #include "teams_list.h"
00023 //-----------------------------------------------------------------------------
00024 #include "../character/body_list.h"
00025 #include "../include/action_handler.h"
00026 #include "../game/config.h"
00027 #include "../tool/file_tools.h"
00028 #include "../tool/i18n.h"
00029 #include "team_energy.h"
00030 #include <algorithm>
00031 #include <iostream>
00032 
00033 #if !defined(WIN32) || defined(__MINGW32__)
00034 #include <dirent.h>
00035 #include <sys/stat.h>
00036 #endif
00037 //-----------------------------------------------------------------------------
00038 TeamsList teams_list;
00039 //-----------------------------------------------------------------------------
00040 //-----------------------------------------------------------------------------
00041 
00042 TeamsList::TeamsList()
00043 {}
00044 
00045 TeamsList::~TeamsList()
00046 {
00047   Clear();
00048   full_list.clear();
00049 }
00050 
00051 //-----------------------------------------------------------------------------
00052 
00053 void TeamsList::NextTeam (bool begin_game)
00054 {
00055   // End of turn for active team
00056   if (begin_game) return;
00057 
00058   // Next team
00059   std::vector<Team*>::iterator it=active_team;
00060   do
00061   {
00062     ++it;
00063     if (it == playing_list.end()) it = playing_list.begin();
00064   } while ((**it).NbAliveCharacter() == 0);
00065   ActionHandler::GetInstance()->NewAction(new Action(Action::ACTION_CHANGE_TEAM, (**it).GetId()));
00066 }
00067 
00068 //-----------------------------------------------------------------------------
00069 
00070 Team& TeamsList::ActiveTeam()
00071 {
00072   assert (active_team != playing_list.end());
00073   return **active_team;
00074 }
00075 
00076 //-----------------------------------------------------------------------------
00077 
00078 void TeamsList::LoadOneTeam(const std::string &dir, const std::string &team)
00079 {
00080   // Skip '.', '..' and hidden files
00081   if (team[0] == '.') return;
00082 
00083 #if !defined(WIN32) || defined(__MINGW32__)
00084   // Is it a directory ?
00085   struct stat stat_file;
00086   std::string filename = dir+team;
00087   if (stat(filename.c_str(), &stat_file) != 0) return;
00088   if (!S_ISDIR(stat_file.st_mode)) return;
00089 #endif
00090 
00091   // Add the team
00092   Team * tmp = Team::CreateTeam (dir, team);
00093   if (tmp != NULL) {
00094     full_list.push_back(*tmp);
00095     std::cout << ((1<full_list.size())?", ":" ") << team;
00096     std::cout.flush();
00097   }
00098 }
00099 
00100 //-----------------------------------------------------------------------------
00101 
00102 void TeamsList::LoadList()
00103 {
00104   playing_list.clear() ;
00105 
00106   std::cout << "o " << _("Load teams:");
00107 
00108   // Load Wormux teams
00109   std::string dirname = Config::GetInstance()->GetDataDir() + PATH_SEPARATOR + "team" + PATH_SEPARATOR;
00110 #if !defined(WIN32) || defined(__MINGW32__)
00111   struct dirent *file;
00112   DIR *dir = opendir(dirname.c_str());
00113   if (dir != NULL) {
00114     while ((file = readdir(dir)) != NULL)  LoadOneTeam (dirname, file->d_name);
00115     closedir (dir);
00116   } else {
00117     Error (Format(_("Cannot open teams directory (%s)!"), dirname.c_str()));
00118   }
00119 #else
00120   std::string pattern = dirname + "*.*";
00121   WIN32_FIND_DATA file;
00122   HANDLE file_search;
00123   file_search=FindFirstFile(pattern.c_str(),&file);
00124   if(file_search != INVALID_HANDLE_VALUE)
00125   {
00126     while (FindNextFile(file_search,&file))
00127     {
00128       if(file.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
00129         LoadOneTeam(dirname,file.cFileName);
00130     }
00131   } else {
00132     Error (Format(_("Cannot open teams directory (%s)!"), dirname.c_str()));
00133   }
00134   FindClose(file_search);
00135 #endif
00136 
00137   // Load personal teams
00138 #if !defined(WIN32) || defined(__MINGW32__)
00139   dirname = Config::GetInstance()->GetPersonalDir() + PATH_SEPARATOR
00140     + "team" + PATH_SEPARATOR;
00141   dir = opendir(dirname.c_str());
00142   if (dir != NULL) {
00143     while ((file = readdir(dir)) != NULL) LoadOneTeam (dirname, file->d_name);
00144     closedir (dir);
00145   }
00146 #endif
00147 
00148   teams_list.full_list.sort(compareTeams);
00149 
00150   // We need at least 2 teams
00151   if (full_list.size() < 2)
00152     Error(_("You need at least two valid teams !"));
00153 
00154   // Default selection
00155   std::list<uint> nv_selection;
00156   nv_selection.push_back (0);
00157   nv_selection.push_back (1);
00158   ChangeSelection (nv_selection);
00159 
00160   std::cout << std::endl;
00161 }
00162 
00163 //-----------------------------------------------------------------------------
00164 
00165 void TeamsList::LoadGamingData(uint how_many_characters)
00166 {
00167   active_team = playing_list.begin();
00168 
00169   iterator it=playing_list.begin(), end=playing_list.end();
00170 
00171   // Load the data of all teams
00172   for (; it != end; ++it) (**it).LoadGamingData(how_many_characters);
00173 }
00174 
00175 //-----------------------------------------------------------------------------
00176 
00177 void TeamsList::UnloadGamingData()
00178 {
00179   body_list.FreeMem();
00180   iterator it=playing_list.begin(), end=playing_list.end();
00181 
00182   // Unload the data of all teams
00183   for (; it != end; ++it) (**it).UnloadGamingData();
00184 }
00185 
00186 //-----------------------------------------------------------------------------
00187 
00188 Team *TeamsList::FindById (const std::string &id, int &pos)
00189 {
00190   full_iterator it=full_list.begin(), fin=full_list.end();
00191   int i=0;
00192   for (; it != fin; ++it, ++i)
00193   {
00194     if (it -> GetId() == id)
00195     {
00196       pos = i;
00197       return &(*it);
00198     }
00199   }
00200   pos = -1;
00201   return NULL;
00202 }
00203 
00204 //-----------------------------------------------------------------------------
00205 
00206 Team *TeamsList::FindByIndex (uint index)
00207 {
00208   full_iterator it=full_list.begin(), fin=full_list.end();
00209   uint i=0;
00210   for (; it != fin; ++it, ++i)
00211   {
00212     if (i == index) return &(*it);
00213   }
00214   assert (false);
00215   return NULL;
00216 }
00217 
00218 //-----------------------------------------------------------------------------
00219 
00220 Team *TeamsList::FindPlayingByIndex (uint index)
00221 {
00222   assert(index < playing_list.size());
00223   return playing_list[index];
00224 }
00225 
00226 //-----------------------------------------------------------------------------
00227 
00228 Team* TeamsList::FindPlayingById(const std::string &id, uint &index)
00229 {
00230   iterator it = playing_list.begin(), end = playing_list.end();
00231   index=0;
00232   for (; it != end; ++it, ++index)
00233   {
00234     if ((*it) -> GetId() == id)
00235       return *it;
00236   }
00237   assert(false);
00238   return NULL;
00239 }
00240 
00241 //-----------------------------------------------------------------------------
00242 
00243 void TeamsList::InitList (const std::list<ConfigTeam> &lst)
00244 {
00245   Clear();
00246   std::list<ConfigTeam>::const_iterator it=lst.begin(), end=lst.end();
00247   for (; it != end; ++it) {
00248     AddTeam (*it, false);
00249   }
00250   active_team = playing_list.begin();
00251 }
00252 
00253 //-----------------------------------------------------------------------------
00254 
00255 void TeamsList::InitEnergy()
00256 {
00257   // Looking at team with the greatest energy
00258   // (in case teams does not have same amount of character)
00259   iterator it=playing_list.begin(), fin=playing_list.end();
00260   uint max = 0;
00261   for (; it != fin; ++it)
00262   {
00263     if( (**it).ReadEnergy() > max)
00264       max = (**it).ReadEnergy();
00265   }
00266 
00267   // Init each team's energy bar
00268   it=playing_list.begin();
00269   uint i = 0;
00270   for (; it != fin; ++it)
00271   {
00272     (**it).InitEnergy (max);
00273     ++i;
00274   }
00275 
00276   // Initial ranking
00277   it=playing_list.begin();
00278   for (; it != fin; ++it)
00279   {
00280     uint rank = 0;
00281     iterator it2=playing_list.begin();
00282     for (; it2 != fin; ++it2)
00283     {
00284       if((it != it2)
00285           && (**it2).ReadEnergy() > (**it).ReadEnergy() )
00286         ++rank;
00287     }
00288     (**it).energy.rank_tmp = rank;
00289   }
00290   it=playing_list.begin();
00291   for (; it != fin; ++it)
00292   {
00293     uint rank = (**it).energy.rank_tmp;
00294     iterator it2=playing_list.begin();
00295     for (it2 = it; it2 != fin; ++it2)
00296     {
00297       if((it != it2)
00298           && (**it2).ReadEnergy() == (**it).ReadEnergy() )
00299         ++rank;
00300     }
00301     (**it).energy.SetRanking(rank);
00302   }
00303 }
00304 
00305 //-----------------------------------------------------------------------------
00306 
00307 void TeamsList::RefreshEnergy()
00308 {
00309   // In the order of the priorit :
00310   // - finish current action
00311   // - change a teams energy
00312   // - change ranking
00313   // - prepare energy bar for next event
00314 
00315   iterator it=playing_list.begin(), fin=playing_list.end();
00316   energy_t status;
00317 
00318   bool waiting = true; // every energy bar are waiting
00319 
00320   for (; it != fin; ++it) {
00321     if( (**it).energy.status != EnergyStatusWait) {
00322       waiting = false;
00323       break;
00324     }
00325   }
00326 
00327   // one of the energy bar is changing ?
00328   if(!waiting) {
00329     status = EnergyStatusOK;
00330 
00331     // change an energy bar value ?
00332     for (it=playing_list.begin(); it != fin; ++it) {
00333       if( (**it).energy.status == EnergyStatusValueChange) {
00334         status = EnergyStatusValueChange;
00335         break;
00336       }
00337     }
00338 
00339     // change a ranking ?
00340     for (it=playing_list.begin(); it != fin; ++it) {
00341       if( (**it).energy.status == EnergyStatusRankChange
00342              && ((**it).energy.IsMoving() || status == EnergyStatusOK)) {
00343         status = EnergyStatusRankChange;
00344         break;
00345       }
00346     }
00347   }
00348   else {
00349     // every energy bar are waiting
00350     // -> set state ready for a new event
00351     status = EnergyStatusOK;
00352   }
00353 
00354   // Setting event to process in every energy bar
00355   if(status != EnergyStatusOK || waiting) {
00356     it=playing_list.begin();
00357     for (; it != fin; ++it) {
00358       (**it).energy.status = status;
00359     }
00360   }
00361 
00362   // Actualisation des valeurs (pas d'actualisation de l'affichage)
00363   for (it=playing_list.begin(); it != fin; ++it) {
00364     (**it).UpdateEnergyBar();
00365     RefreshSort();
00366   }
00367 }
00368 //-----------------------------------------------------------------------------
00369 
00370 void TeamsList::RefreshSort ()
00371 {
00372   iterator it=playing_list.begin(), fin=playing_list.end();
00373   uint rank;
00374 
00375   // Find a ranking without taking acount of the equalities
00376   it=playing_list.begin();
00377   for (; it != fin; ++it)
00378   {
00379     rank = 0;
00380     iterator it2=playing_list.begin();
00381     for (; it2 != fin; ++it2)
00382     {
00383       if((it != it2)
00384           && (**it2).ReadEnergy() > (**it).ReadEnergy() )
00385         ++rank;
00386     }
00387     (**it).energy.rank_tmp = rank;
00388   }
00389 
00390   // Fix equalities
00391   it=playing_list.begin();
00392   for (; it != fin; ++it)
00393   {
00394     rank = (**it).energy.rank_tmp;
00395     iterator it2=playing_list.begin();
00396     for (it2 = it; it2 != fin; ++it2)
00397     {
00398       if((it != it2)
00399           && (**it2).ReadEnergy() == (**it).ReadEnergy() )
00400         ++rank;
00401     }
00402     (**it).energy.NewRanking(rank);
00403   }
00404 }
00405 
00406 //-----------------------------------------------------------------------------
00407 
00408 void TeamsList::ChangeSelection (const std::list<uint>& nv_selection)
00409 {
00410   selection = nv_selection;
00411 
00412   selection_iterator it=selection.begin(), fin=selection.end();
00413   playing_list.clear();
00414   for (; it != fin; ++it) playing_list.push_back (FindByIndex(*it));
00415   active_team = playing_list.begin();
00416 }
00417 
00418 //-----------------------------------------------------------------------------
00419 
00420 bool TeamsList::IsSelected (uint index)
00421 {
00422   selection_iterator pos = std::find (selection.begin(), selection.end(), index);
00423   return pos != selection.end();
00424 }
00425 
00426 void TeamsList::Clear()
00427 {
00428   selection.clear();
00429   playing_list.clear();
00430 }
00431 
00432 //-----------------------------------------------------------------------------
00433 
00434 void TeamsList::AddTeam (const ConfigTeam &the_team_cfg, bool generate_error)
00435 {
00436   int pos;
00437   Team *the_team = FindById (the_team_cfg.id, pos);
00438   if (the_team != NULL) {
00439 
00440     // set the player name and number of characters
00441     the_team->SetPlayerName(the_team_cfg.player_name);
00442     the_team->SetNbCharacters(the_team_cfg.nb_characters);
00443 
00444     selection.push_back (pos);
00445     playing_list.push_back (the_team);
00446 
00447   } else {
00448     std::string msg = Format(_("Can't find team %s!"), the_team_cfg.id.c_str());
00449     if (generate_error)
00450       Error (msg);
00451     else
00452       std::cout << "! " << msg << std::endl;
00453   }
00454   active_team = playing_list.begin();
00455 }
00456 
00457 //-----------------------------------------------------------------------------
00458 
00459 void TeamsList::UpdateTeam (const ConfigTeam &the_team_cfg, bool generate_error)
00460 {
00461   int pos;
00462   Team *the_team = FindById (the_team_cfg.id, pos);
00463   if (the_team != NULL) {
00464 
00465     // set the player name and number of characters
00466     the_team->SetPlayerName(the_team_cfg.player_name);
00467     the_team->SetNbCharacters(the_team_cfg.nb_characters);
00468 
00469   } else {
00470     std::string msg = Format(_("Can't find team %s!"), the_team_cfg.id.c_str());
00471     if (generate_error)
00472       Error (msg);
00473     else
00474       std::cout << "! " << msg << std::endl;
00475   }
00476 }
00477 
00478 //-----------------------------------------------------------------------------
00479 
00480 void TeamsList::DelTeam (const std::string &id)
00481 {
00482   int pos;
00483   Team *equipe = FindById (id, pos);
00484   assert(equipe != NULL);
00485 
00486   selection.erase(find(selection.begin(),selection.end(),(uint)pos));
00487   playing_list.erase(find(playing_list.begin(),playing_list.end(),equipe));
00488 
00489   active_team = playing_list.begin();
00490 }
00491 
00492 //-----------------------------------------------------------------------------
00493 
00494 void TeamsList::SetActive(const std::string &id)
00495 {
00496   iterator
00497       it = playing_list.begin(),
00498   end = playing_list.end();
00499   for (; it != end; ++it)
00500   {
00501     Team &team = **it;
00502     if (team.GetId() == id)
00503     {
00504       active_team = it;
00505       return;
00506     }
00507   }
00508   Error (Format(_("Can't find team %s!"), id.c_str()));
00509 }
00510 
00511 //-----------------------------------------------------------------------------
00512 
00513 Team& ActiveTeam()
00514 {
00515   return teams_list.ActiveTeam();
00516 }
00517 
00518 //-----------------------------------------------------------------------------
00519 
00520 Character& ActiveCharacter()
00521 {
00522   return ActiveTeam().ActiveCharacter();
00523 }
00524 
00525 //-----------------------------------------------------------------------------
00526 
00527 bool compareTeams(const Team& a, const Team& b)
00528 {
00529   return a.GetName() < b.GetName();
00530 }
00531 
00532 //-----------------------------------------------------------------------------

Generated on Mon Jan 1 13:10:59 2007 for Wormux by  doxygen 1.4.7