00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
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] = '-';
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
00202 d = std::strtod(val.c_str(), 0);
00203 return true;
00204 }
00205
00206 bool TreasureLoader::parseInt(std::string val, int& i)
00207 {
00208
00209 i = std::strtol(val.c_str(), 0, 0);
00210 return true;
00211 }