src/team/team.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  * A team
00020  *****************************************************************************/
00021 
00022 #include "team.h"
00023 #include "teams_list.h"
00024 #include "../character/body_list.h"
00025 #include "../game/game.h"
00026 #include "../game/game_mode.h"
00027 #include "../game/game_loop.h"
00028 #include "../interface/cursor.h"
00029 #include "../include/constant.h"
00030 #include "../game/config.h"
00031 #include "../map/camera.h"
00032 #include "../map/map.h"
00033 #include "../weapon/weapons_list.h"
00034 #include "../tool/debug.h"
00035 #include "../tool/i18n.h"
00036 #include "../tool/file_tools.h"
00037 #include "../tool/resource_manager.h"
00038 #include "../graphic/sprite.h"
00039 #include "../network/network.h"
00040 #include <sstream>
00041 #include <iostream>
00042 
00043 Team::Team(const std::string& _teams_dir,
00044            const std::string& _id,
00045            const std::string& _name,
00046            const Surface& _flag,
00047            const std::string& _sound_profile)
00048   : energy(this)
00049 {
00050   active_character = characters.end();
00051 
00052   is_camera_saved = false;
00053   active_weapon = Config::GetInstance()->GetWeaponsList()->GetWeapon(Weapon::WEAPON_DYNAMITE);
00054 
00055   m_teams_dir = _teams_dir;
00056   m_id = _id;
00057   m_name = _name;
00058   m_sound_profile = _sound_profile;
00059   m_player_name = "";
00060 
00061   nb_characters = GameMode::GetInstance()->max_characters;
00062 
00063   flag = _flag;
00064 
00065   type_of_player = TEAM_human_local;
00066 }
00067 
00068 Team * Team::CreateTeam (const std::string& teams_dir,
00069                          const std::string& id)
00070 {
00071   std::string nomfich;
00072   try
00073   {
00074     XmlReader doc;
00075 
00076     // Load XML
00077     nomfich = teams_dir+id+PATH_SEPARATOR+ "team.xml";
00078     if (!IsFileExist(nomfich)) return false;
00079     if (!doc.Load(nomfich)) return false;
00080 
00081     // Load name
00082     std::string name;
00083     if (!XmlReader::ReadString(doc.GetRoot(), "name", name)) return NULL;
00084 
00085     // Load flag
00086     Profile *res = resource_manager.LoadXMLProfile( nomfich, true);
00087     Surface flag = resource_manager.LoadImage(res, "flag");
00088     resource_manager.UnLoadXMLProfile(res);
00089 
00090     // Get sound profile
00091     std::string sound_profile;
00092     if (!XmlReader::ReadString(doc.GetRoot(), "sound_profile", sound_profile))
00093       sound_profile = "default";
00094 
00095     return new Team(teams_dir, id, name, flag, sound_profile) ;
00096   }
00097   catch (const xmlpp::exception &e)
00098   {
00099     std::cerr << std::endl
00100         << Format(_("Error loading team %s:"), id.c_str())
00101         << std::endl << e.what() << std::endl;
00102     return NULL;
00103   }
00104 
00105   return NULL;
00106 }
00107 
00108 
00109 bool Team::LoadCharacters(uint howmany)
00110 {
00111   //assert(howmany <= GameMode::GetInstance()->max_characters);
00112   assert (howmany <= 10);
00113 
00114   std::string nomfich;
00115   try
00116   {
00117     XmlReader doc;
00118 
00119     // Load XML
00120     nomfich = m_teams_dir+m_id+PATH_SEPARATOR+ "team.xml";
00121     if (!IsFileExist(nomfich)) return false;
00122     if (!doc.Load(nomfich)) return false;
00123 
00124     // Create the characters
00125     xmlpp::Element *xml = XmlReader::GetMarker(doc.GetRoot(), "team");
00126 
00127     xmlpp::Node::NodeList nodes = xml->get_children("character");
00128     xmlpp::Node::NodeList::iterator it=nodes.begin();
00129 
00130     characters.clear();
00131     active_character = characters.end();
00132     do
00133     {
00134       xmlpp::Element *elem = dynamic_cast<xmlpp::Element*> (*it);
00135       Body* body;
00136       std::string character_name="Soldat Inconnu";
00137       std::string body_name="";
00138       XmlReader::ReadStringAttr(elem, "name", character_name);
00139       XmlReader::ReadStringAttr(elem, "body", body_name);
00140 
00141       if (!(body = body_list.GetBody(body_name)) )
00142       {
00143         std::cerr
00144             << Format(_("Error: can't find the body \"%s\" for the team \"%s\"."),
00145                       body_name.c_str(),
00146                       m_name.c_str())
00147             << std::endl;
00148         return false;
00149       }
00150 
00151       // Create a new character and add him to the team
00152       Character new_character(*this, character_name, body);
00153       characters.push_back(new_character);
00154       active_character = characters.begin(); // we need active_character to be initialized here !!
00155       if (!characters.back().PutRandomly(false, world.dst_min_entre_vers))
00156       {
00157         // We haven't found any place to put the characters!!
00158         if (!characters.back().PutRandomly(false, world.dst_min_entre_vers/2)) {
00159           std::cerr << std::endl;
00160           std::cerr << "Error: " << character_name.c_str() << " will be probably misplaced!" << std::endl;
00161           std::cerr << std::endl;
00162 
00163             // Put it with no space...
00164           characters.back().PutRandomly(false, 0);
00165         }
00166       }
00167       characters.back().Init();
00168 
00169       MSG_DEBUG("team", "Add %s in team %s", character_name.c_str(), m_name.c_str());
00170 
00171         // C'est la fin ?
00172       ++it;
00173     } while (it!=nodes.end() && characters.size() < howmany );
00174 
00175     active_character = characters.begin();
00176 
00177   }
00178   catch (const xmlpp::exception &e)
00179   {
00180     std::cerr << std::endl
00181         << Format(_("Error loading team's data %s:"), m_id.c_str())
00182         << std::endl << e.what() << std::endl;
00183     return false;
00184   }
00185 
00186   return (characters.size() == howmany);
00187 }
00188 
00189 void Team::InitEnergy (uint max)
00190 {
00191   energy.Config(ReadEnergy(), max);
00192 }
00193 
00194 uint Team::ReadEnergy ()
00195 {
00196   uint total_energy = 0;
00197 
00198   iterator it = characters.begin(), end = characters.end();
00199 
00200   for (; it != end; ++it) {
00201     if ( !(*it).IsDead() )
00202       total_energy += (*it).GetEnergy();
00203   }
00204 
00205   return total_energy;
00206 }
00207 
00208 void Team::UpdateEnergyBar ()
00209 {
00210   energy.SetValue(ReadEnergy());
00211 }
00212 
00213 TeamEnergy & Team::GetEnergyBar()
00214 {
00215   return energy;
00216 }
00217 
00218 void Team::SelectCharacter(uint index)
00219 {
00220   assert(index <= characters.size());
00221   ActiveCharacter().StopPlaying();
00222   active_character = characters.begin();
00223   for(uint i = 0; i < index; ++i)
00224     ++active_character;
00225 }
00226 
00227 void Team::NextCharacter()
00228 {
00229   assert (0 < NbAliveCharacter());
00230   ActiveCharacter().StopPlaying();
00231   do
00232   {
00233     ++active_character;
00234     if (active_character == characters.end())
00235       active_character = characters.begin();
00236   } while (ActiveCharacter().IsDead());
00237   ActiveCharacter().StartPlaying();
00238 
00239   if (is_camera_saved) camera.SetXYabs (sauve_camera.x, sauve_camera.y);
00240   camera.FollowObject (&ActiveCharacter(),
00241                           !is_camera_saved, !is_camera_saved,
00242                           true);
00243   MSG_DEBUG("team", "%s (%d, %d)is now the active character",
00244             ActiveCharacter().GetName().c_str(),
00245             ActiveCharacter().GetX(),
00246             ActiveCharacter().GetY());
00247 }
00248 
00249 int Team::NbAliveCharacter() const
00250 {
00251   uint nbr = 0;
00252   const_iterator it= characters.begin(), end=characters.end();
00253 
00254   for (; it!=end; ++it)
00255     if ( !(*it).IsDead() ) nbr++;
00256 
00257   return nbr;
00258 }
00259 
00260 // Prepare a new team turn
00261 void Team::PrepareTurn()
00262 {
00263   // Get a living character if possible
00264   if (ActiveCharacter().IsDead())
00265   {
00266     is_camera_saved = false;
00267     NextCharacter();
00268   }
00269 
00270   if (is_camera_saved) camera.SetXYabs (sauve_camera.x, sauve_camera.y);
00271   camera.FollowObject (&ActiveCharacter(),
00272                           !is_camera_saved, !is_camera_saved,
00273                           true);
00274   CharacterCursor::GetInstance()->FollowActiveCharacter();
00275 
00276   // Active last weapon use if EnoughAmmo
00277   if (AccessWeapon().EnoughAmmo())
00278     AccessWeapon().Select();
00279   else { // try to find another weapon !!
00280     active_weapon = Config::GetInstance()->GetWeaponsList()->GetWeapon(Weapon::WEAPON_BAZOOKA);
00281     AccessWeapon().Select();
00282   }
00283 }
00284 
00285 Character& Team::ActiveCharacter()
00286 {
00287   return (*active_character);
00288 }
00289 
00290 void Team::SetWeapon (Weapon::Weapon_type type)
00291 {
00292   AccessWeapon().Deselect();
00293   active_weapon = Config::GetInstance()->GetWeaponsList()->GetWeapon(type);
00294   AccessWeapon().Select();
00295 }
00296 
00297 int Team::ReadNbAmmos() const
00298 {
00299   return ReadNbAmmos(active_weapon->GetName());
00300 }
00301 
00302 int Team::ReadNbUnits() const
00303 {
00304   return ReadNbUnits( active_weapon->GetName());
00305 }
00306 
00307 int Team::ReadNbAmmos(const std::string &weapon_name) const
00308 {
00309   // Read in the Map
00310   // The same method as in AccesNbAmmos can't be use on const team !
00311   std::map<std::string, int>::const_iterator it =
00312       m_nb_ammos.find( weapon_name );
00313 
00314   if (it !=  m_nb_ammos.end()) return ( it->second ) ;
00315   // We should not be here !
00316   MSG_DEBUG("team", "%s : not found into the ammo map.", weapon_name.c_str());
00317   assert(false);
00318   return 0 ;
00319 }
00320 
00321 int Team::ReadNbUnits(const std::string &weapon_name) const
00322 {
00323   std::map<std::string, int>::const_iterator it =
00324       m_nb_units.find( weapon_name );
00325 
00326   if (it !=  m_nb_units.end()) return ( it->second ) ;
00327   // We should not be here !
00328   MSG_DEBUG("team", "%s : not found into the ammo map.", weapon_name.c_str());
00329   assert(false);
00330   return 0 ;
00331 }
00332 
00333 int& Team::AccessNbAmmos()
00334 {
00335   // if value not initialized, it initialize to 0 and then return 0
00336   return m_nb_ammos[ active_weapon->GetName() ] ;
00337 }
00338 
00339 int& Team::AccessNbUnits()
00340 {
00341   // if value not initialized, it initialize to 0 and then return 0
00342   return m_nb_units[ active_weapon->GetName() ] ;
00343 }
00344 
00345 void Team::ResetNbUnits()
00346 {
00347   m_nb_units[ active_weapon->GetName() ] = active_weapon->ReadInitialNbUnit();
00348 }
00349 
00350 Team::iterator Team::begin() { return characters.begin(); }
00351 Team::iterator Team::end() { return characters.end(); }
00352 
00353 Character* Team::FindByIndex(uint index)
00354 {
00355   assert(index < characters.size());
00356   iterator it= characters.begin(), end=characters.end();
00357 
00358   while(index != 0 && it != characters.end())
00359   {
00360     index--;
00361     it++;
00362   }
00363   return &(*it);
00364 }
00365 
00366 void Team::LoadGamingData(uint howmany)
00367 {
00368   // Reset ammos
00369   m_nb_ammos.clear();
00370   m_nb_units.clear();
00371   std::list<Weapon *> l_weapons_list = Config::GetInstance()->GetWeaponsList()->GetList() ;
00372   std::list<Weapon *>::iterator itw = l_weapons_list.begin(),
00373   end = l_weapons_list.end();
00374 
00375   for (; itw != end ; ++itw) {
00376     m_nb_ammos[ (*itw)->GetName() ] = (*itw)->ReadInitialNbAmmo();
00377     m_nb_units[ (*itw)->GetName() ] = (*itw)->ReadInitialNbUnit();
00378   }
00379 
00380   // Disable non-working weapons in network games
00381   if(network.IsConnected())
00382   {
00383     m_nb_ammos[ Config::GetInstance()->GetWeaponsList()->GetWeapon(Weapon::WEAPON_NINJA_ROPE)->GetName() ] = 0;
00384     m_nb_ammos[ Config::GetInstance()->GetWeaponsList()->GetWeapon(Weapon::WEAPON_AIR_HAMMER)->GetName() ] = 0;
00385     m_nb_ammos[ Config::GetInstance()->GetWeaponsList()->GetWeapon(Weapon::WEAPON_BLOWTORCH)->GetName() ] = 0;
00386     m_nb_ammos[ Config::GetInstance()->GetWeaponsList()->GetWeapon(Weapon::WEAPON_SUBMACHINE_GUN)->GetName() ] = 0;
00387   }
00388 
00389   active_weapon = Config::GetInstance()->GetWeaponsList()->GetWeapon(Weapon::WEAPON_DYNAMITE);
00390   is_camera_saved = false;
00391 
00392   if (howmany == 0)
00393     LoadCharacters(nb_characters);
00394   else
00395     LoadCharacters(howmany);
00396 }
00397 
00398 void Team::UnloadGamingData()
00399 {
00400   // Clear list of characters
00401   characters.clear();
00402 }
00403 
00404 void Team::SetNbCharacters(uint howmany)
00405 {
00406   assert(howmany >= 2 && howmany <= 10);
00407   nb_characters = howmany;
00408 }
00409 
00410 void Team::SetPlayerName(const std::string& _player_name)
00411 {
00412   m_player_name = _player_name;
00413   // energy.SetTeamName(m_player_name+" - "+m_name);
00414 }
00415 
00416 void Team::DrawEnergy(const Point2i& pos)
00417 {
00418   energy.Draw(pos);
00419 }
00420 
00421 void Team::Refresh()
00422 {
00423   energy.Refresh();
00424 }
00425 
00426 Weapon& Team::AccessWeapon() const { return *active_weapon; }
00427 const Weapon& Team::GetWeapon() const { return *active_weapon; }
00428 Weapon::Weapon_type Team::GetWeaponType() const { return GetWeapon().GetType(); }
00429 
00430 bool Team::IsSameAs(const Team& other) const
00431 {
00432   return (strcmp(m_id.c_str(), other.GetId().c_str()) == 0);
00433 }
00434 
00435 bool Team::IsActiveTeam() const
00436 {
00437   return this == &ActiveTeam();
00438 }
00439 
00440 bool Team::IsLocal() const
00441 {
00442   if (type_of_player == TEAM_human_local)
00443     return true;
00444 
00445   return false;
00446 }
00447 
00448 bool Team::IsLocalAI() const
00449 {
00450   if (type_of_player == TEAM_ai_local)
00451     return true;
00452 
00453   return false;
00454 }
00455 
00456 void Team::SetLocal()
00457 {
00458   type_of_player = TEAM_human_local;
00459 }
00460 
00461 void Team::SetLocalAI()
00462 {
00463   type_of_player = TEAM_ai_local;
00464 }
00465 
00466 void Team::SetRemote()
00467 {
00468   type_of_player = TEAM_remote;
00469 }

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