TreasureLoader.cpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2004-2005 The Pentagram Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 #include "pent_include.h"
00020 #include "TreasureLoader.h"
00021 
00022 #include "ConfigFileManager.h"
00023 #include "util.h"
00024 
00025 TreasureLoader::TreasureLoader()
00026 {
00027 
00028 }
00029 
00030 TreasureLoader::~TreasureLoader()
00031 {
00032 
00033 }
00034 
00035 void TreasureLoader::loadDefaults()
00036 {
00037         ConfigFileManager* config = ConfigFileManager::get_instance();
00038         std::map<Pentagram::istring,std::string> lootkeyvals;
00039 
00040         // load default treasure types
00041         lootkeyvals = config->listKeyValues("game/treasure");
00042         std::map<Pentagram::istring,std::string>::iterator defaultiter;
00043         for (defaultiter = lootkeyvals.begin();
00044                  defaultiter != lootkeyvals.end(); ++defaultiter)
00045         {
00046                 TreasureInfo ti;
00047                 bool ok = internalParse(defaultiter->second, ti, true);
00048                 if (ok) {
00049                         defaultTreasure[defaultiter->first] = ti;
00050                 } else {
00051                         perr << "Failed to parse treasure type '" << defaultiter->first
00052                                  << "': " << defaultiter->second << std::endl;
00053                 }
00054         }
00055 
00056 }
00057 
00058 bool TreasureLoader::parse(std::string desc,
00059                                                    std::vector<TreasureInfo>& treasure)
00060 {
00061         treasure.clear();
00062 
00063         std::vector<std::string> tr;
00064         Pentagram::SplitString(desc, ';', tr);
00065 
00066         TreasureInfo ti;
00067         for (unsigned int i = 0; i < tr.size(); ++i) {
00068 //              pout << "parse: item=" << tr[i] << std::endl;
00069                 if (internalParse(tr[i], ti, false)) {
00070                         treasure.push_back(ti);
00071                 } else {
00072                         return false;
00073                 }               
00074         }
00075 
00076         return true;
00077 }
00078 
00079 bool TreasureLoader::internalParse(std::string desc, TreasureInfo& ti,
00080                                                                    bool loadingDefault)
00081 {
00082         ti.special = "";
00083         ti.chance = 1;
00084         ti.map = 0;
00085         ti.shapes.clear();
00086         ti.frames.clear();
00087         ti.mincount = ti.maxcount = 1;
00088 
00089         bool loadedDefault = false;
00090 
00091         std::vector<std::pair<std::string, std::string> > kv;
00092         Pentagram::SplitStringKV(desc, ' ', kv);
00093 
00094         for (unsigned int i = 0; i < kv.size(); ++i) {
00095                 std::string key = kv[i].first;
00096                 std::string val = kv[i].second;
00097 //              pout << "internalParse: key=" << key << " val=" << val << std::endl;
00098 
00099                 if (key == "shape") {
00100                         if (!parseUInt32Vector(val, ti.shapes))
00101                                 return false;
00102                 } else if (key == "frame") {
00103                         if (!parseUInt32Vector(val, ti.frames))
00104                                 return false;
00105                 } else if (key == "count") {
00106                         if (!parseUIntRange(val, ti.mincount, ti.maxcount)) {
00107                                 int x;
00108                                 if (!parseInt(val, x))
00109                                         return false;
00110                                 ti.mincount = ti.maxcount = x;
00111                         }
00112                 } else if (key == "chance") {
00113                         if (!parseDouble(val, ti.chance))
00114                                 return false;
00115                 } else if (key == "map") {
00116                         if (val.size() > 1 && val[0] == '!')
00117                                 val[0] = '-'; // HACK: invert map for 'not this map'
00118                         if (!parseInt(val, ti.map))
00119                                 return false;
00120                 } else if (key == "special" && loadingDefault) {
00121                         ti.special = val;
00122                 } else if (key == "type" && !loadingDefault) {
00123                         if (loadedDefault)
00124                                 return false;
00125                         std::map<Pentagram::istring, TreasureInfo>::iterator iter;
00126                         iter = defaultTreasure.find(val);
00127                         if (iter != defaultTreasure.end())
00128                                 ti = iter->second;
00129                         else
00130                                 return false;
00131                         loadedDefault = true;
00132                 } else if (key == "mult" && !loadingDefault) {
00133                         if (!loadedDefault) return false;
00134                         unsigned int minmult, maxmult;
00135                         if (!parseUIntRange(val, minmult, maxmult)) {
00136                                 int x;
00137                                 if (!parseInt(val, x))
00138                                         return false;
00139                                 minmult = maxmult = x;
00140                         }
00141                         ti.mincount *= minmult;
00142                         ti.maxcount *= maxmult;
00143                 } else {
00144                         return false;
00145                 }
00146         }
00147 
00148         return true;
00149 }
00150 
00151 bool TreasureLoader::parseUInt32Vector(std::string val,
00152                                                                            std::vector<uint32>& vec)
00153 {
00154         vec.clear();
00155 
00156         std::string::size_type pos;
00157         while (!val.empty()) {
00158                 pos = val.find(',');
00159                 std::string item = val.substr(0, pos);
00160 
00161                 std::string::size_type itempos = val.find('-');
00162                 if (itempos != std::string::npos) {
00163                         unsigned int min, max;
00164                         if (!parseUIntRange(item, min, max))
00165                                 return false;
00166                         for (unsigned int i = min; i <= max; ++i)
00167                                 vec.push_back(i);
00168                 } else {
00169                         int x;
00170                         if (!parseInt(item, x))
00171                                 return false;
00172                         vec.push_back(x);
00173                 }
00174                 
00175                 if (pos != std::string::npos) pos++;
00176                 val.erase(0, pos);
00177         }
00178 
00179         return true;
00180 }
00181 
00182 bool TreasureLoader::parseUIntRange(std::string val,
00183                                                                    unsigned int& min, unsigned int& max)
00184 {
00185         std::string::size_type pos = val.find('-');
00186         if (pos == 0 || pos == std::string::npos || pos+1 >= val.size())
00187                 return false;
00188         int t1, t2;
00189         bool ok = true;
00190         ok &= parseInt(val.substr(0, pos), t1);
00191         ok &= parseInt(val.substr(pos+1), t2);
00192         if (ok) {
00193                 min = t1;
00194                 max = t2;
00195         }
00196         return ok;
00197 }
00198 
00199 bool TreasureLoader::parseDouble(std::string val, double& d)
00200 {
00201         // TODO: error checking
00202         d = std::strtod(val.c_str(), 0);
00203         return true;
00204 }
00205 
00206 bool TreasureLoader::parseInt(std::string val, int& i)
00207 {
00208         // TODO: error checking
00209         i = std::strtol(val.c_str(), 0, 0);
00210         return true;
00211 }

Generated on Fri Jul 27 22:27:45 2007 for pentagram by  doxygen 1.4.7