src/map/maps_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  * Maps list
00020  *****************************************************************************/
00021 
00022 #include "maps_list.h"
00023 #include "map.h"
00024 #include "../game/config.h"
00025 #include "../tool/debug.h"
00026 #include "../tool/file_tools.h"
00027 #include "../tool/i18n.h"
00028 #include <iostream>
00029 #if !defined(WIN32) || defined(__MINGW32__)
00030 #include <dirent.h>
00031 #include <sys/stat.h>
00032 #endif
00033 
00034 InfoMap::InfoMap ()
00035 {
00036   is_data_loaded = false;
00037   nb_mine = 0;
00038   nb_barrel = 0;
00039   wind.nb_sprite = 0;
00040   wind.need_flip = false;
00041 }
00042 
00043 bool InfoMap::Init (const std::string &map_name,
00044                     const std::string &directory)
00045 {
00046   std::string nomfich;
00047 
00048   m_directory = directory;
00049 
00050   res_profile = NULL;
00051   is_data_loaded = false;
00052 
00053   try
00054   {
00055     nomfich = m_directory+"config.xml";
00056 
00057     // Load resources
00058     if (!IsFileExist(nomfich))
00059       return false;
00060     res_profile = resource_manager.LoadXMLProfile( nomfich, true),
00061     // Load preview
00062     preview = resource_manager.LoadImage( res_profile, "preview");
00063     // Load other informations
00064     XmlReader doc;
00065     if (!doc.Load(nomfich)) return false;
00066     if (!ProcessXmlData(doc.GetRoot())) return false;
00067   }
00068   catch (const xmlpp::exception &e)
00069   {
00070     std::cout << std::endl
00071               << Format(_("XML error during loading map '%s' :"), map_name.c_str())
00072               << std::endl
00073               << e.what() << std::endl;
00074     return false;
00075   }
00076 
00077   MSG_DEBUG("map.load", "Map loaded: %s", map_name.c_str());
00078 
00079   return true;
00080 }
00081 
00082 bool InfoMap::ProcessXmlData(xmlpp::Element *xml)
00083 {
00084   // Read author informations
00085   xmlpp::Element *author = XmlReader::GetMarker(xml, "author");
00086   if (author != NULL) {
00087     std::string
00088       a_name,
00089       a_nickname,
00090       a_country,
00091       a_email;
00092 
00093     XmlReader::ReadString(author, "name", a_name);
00094     XmlReader::ReadString(author, "nickname", a_nickname);
00095     if (!XmlReader::ReadString(author, "country", a_country))
00096       a_country = "?";
00097     if (!XmlReader::ReadString(author, "email", a_email))
00098       a_email = "?";
00099 
00100     if (!a_nickname.empty())
00101       author_info = Format
00102           (_("%s <%s> aka %s from %s"),
00103            a_name.c_str(),
00104            a_email.c_str(),
00105            a_nickname.c_str(),
00106            a_country.c_str());
00107     else
00108       author_info = Format
00109           (_("%s <%s> from %s"),
00110            a_name.c_str(),
00111            a_email.c_str(),
00112            a_country.c_str());
00113   }
00114 
00115   XmlReader::ReadString(xml, "name", name);
00116   XmlReader::ReadBool(xml, "water", use_water);
00117   XmlReader::ReadUint(xml, "nb_mine", nb_mine);
00118   XmlReader::ReadUint(xml, "nb_barrel", nb_barrel);
00119   XmlReader::ReadBool(xml, "is_open", is_opened);
00120 
00121   xmlpp::Element *xmlwind = XmlReader::GetMarker(xml, "wind");
00122   if (xmlwind != NULL)
00123   {
00124     XmlReader::ReadUint(xmlwind, "nbr_sprite", wind.nb_sprite);
00125     XmlReader::ReadBool(xmlwind, "need_flip", wind.need_flip);
00126 
00127     if (wind.nb_sprite > MAX_WIND_OBJECTS)
00128       wind.nb_sprite = MAX_WIND_OBJECTS ;
00129   } else {
00130     wind.nb_sprite = 0;
00131   }
00132   wind.default_nb_sprite = wind.nb_sprite;
00133 
00134   return true;
00135 }
00136 
00137 void InfoMap::LoadData()
00138 {
00139   if (is_data_loaded)
00140     return;
00141   is_data_loaded = true;
00142 
00143   MSG_DEBUG("map.load", "Map data loaded: %s", name.c_str());
00144 
00145   img_ground = resource_manager.LoadImage(res_profile, "map");
00146   img_sky = resource_manager.LoadImage(res_profile,"sky");
00147 }
00148 
00149 void InfoMap::FreeData()
00150 {
00151   img_sky.Free();
00152   img_ground.Free();
00153   is_data_loaded = false;
00154 }
00155 
00156 Surface InfoMap::ReadImgGround()
00157 {
00158   LoadData();
00159   return img_ground;
00160 }
00161 
00162 Surface InfoMap::ReadImgSky()
00163 {
00164   LoadData();
00165   return img_sky;
00166 }
00167 
00168 MapsList* MapsList::singleton = NULL;
00169 
00170 MapsList* MapsList::GetInstance()
00171 {
00172   if (singleton == NULL) {
00173     singleton = new MapsList();
00174   }
00175 
00176   return singleton;
00177 }
00178 
00179 MapsList::MapsList()
00180 {
00181   lst.clear() ;
00182 
00183   std::cout << "o " << _("Load maps:");
00184   terrain_actif = -1;
00185 
00186   Config * config = Config::GetInstance();
00187   std::string dirname = config->GetDataDir() + PATH_SEPARATOR + "map" + PATH_SEPARATOR;
00188 #if !defined(WIN32) || defined(__MINGW32__)
00189   DIR *dir = opendir(dirname.c_str());
00190   struct dirent *file;
00191   if (dir != NULL) {
00192     while ((file = readdir(dir)) != NULL)
00193           LoadOneMap (dirname, file->d_name);
00194     closedir (dir);
00195   } else {
00196     Error (Format(_("Unable to open maps directory (%s)!"),
00197                    dirname.c_str()));
00198   }
00199 #else
00200   std::string pattern = dirname + "*.*";
00201   WIN32_FIND_DATA file;
00202   HANDLE file_search;
00203   file_search=FindFirstFile(pattern.c_str(),&file);
00204   if(file_search != INVALID_HANDLE_VALUE)
00205   {
00206     while (FindNextFile(file_search,&file))
00207         {
00208           if(file.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
00209             LoadOneMap(dirname,file.cFileName);
00210         }
00211   } else {
00212     Error (Format(_("Unable to open maps directory (%s)!"),
00213                    dirname.c_str()));
00214   }
00215   FindClose(file_search);
00216 #endif
00217 
00218 #if !defined(WIN32) || defined(__MINGW32__)
00219   // Load personal maps
00220   dirname = config->GetPersonalDir() + PATH_SEPARATOR + "map";
00221   dir = opendir(dirname.c_str());
00222   if (dir != NULL) {
00223     while ((file = readdir(dir)) != NULL)
00224       LoadOneMap (dirname, file->d_name);
00225     closedir (dir);
00226   }
00227 #endif
00228   std::cout << std::endl << std::endl;
00229 
00230   // On a au moins une carte ?
00231   if (lst.size() < 1)
00232     Error(_("You need at least one valid map !"));
00233 
00234   std::sort(lst.begin(), lst.end(), compareMaps);
00235 }
00236 
00237 void MapsList::LoadOneMap (const std::string &dir, const std::string &file)
00238 {
00239   std::string fullname = dir+file;
00240 
00241 #if !defined(WIN32) || defined(__MINGW32__)
00242   struct stat stat_file;
00243   if (file[0] == '.') return;
00244   if (stat(fullname.c_str(), &stat_file) != 0) return;
00245   if (!S_ISDIR(stat_file.st_mode)) return;
00246 #endif
00247 
00248   InfoMap nv_terrain;
00249   bool ok = nv_terrain.Init (file, fullname + PATH_SEPARATOR);
00250   if (!ok) return;
00251 
00252   std::cout << (lst.empty()?" ":", ") << file;
00253   std::cout.flush();
00254   lst.push_back(nv_terrain);
00255 }
00256 
00257 int MapsList::FindMapById (const std::string &id)
00258 {
00259   iterator
00260     terrain=lst.begin(),
00261     fin_terrain=lst.end();
00262   uint i=0;
00263   for (; i < lst.size(); ++i)
00264     if (lst[i].ReadName() == id)
00265       return i;
00266   return -1;
00267 }
00268 
00269 void MapsList::SelectMapByName (const std::string &nom)
00270 {
00271   int index = FindMapById (nom);
00272 
00273   if (index == -1){
00274     index = 0;
00275     std::cout << Format(_("! Map %s not found :-("), nom.c_str()) << std::endl;
00276   }
00277   SelectMapByIndex (index);
00278 }
00279 
00280 void MapsList::SelectMapByIndex (uint index)
00281 {
00282   assert (index < lst.size());
00283   if (terrain_actif == (int)index)
00284     return;
00285 
00286   terrain_actif = index;
00287 }
00288 
00289 int MapsList::GetActiveMapIndex ()
00290 {
00291   return terrain_actif;
00292 }
00293 
00294 InfoMap& MapsList::ActiveMap()
00295 {
00296   assert (0 <= terrain_actif);
00297   return lst.at(terrain_actif);
00298 }
00299 
00300 InfoMap& ActiveMap()
00301 {
00302   return MapsList::GetInstance()->ActiveMap();
00303 }
00304 
00305 bool compareMaps(const InfoMap& a, const InfoMap& b)
00306 {
00307   return a.ReadName() < b.ReadName();
00308 }
00309 

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