00001
00002
00003
00004
00005
00006 #include <string>
00007 #include <boost/shared_ptr.hpp>
00008 #include "SDL.h"
00009 #include "GLee.h"
00010 #include "Player.h"
00011 #include "Cargo.h"
00012 #include "Product.h"
00013 #include "Log.h"
00014 #include "tinyxml.h"
00015 #include "CityManager.h"
00016 #include "CityEconomy.h"
00017 #include "Economy.h"
00018
00019 using namespace std;
00020 using boost::shared_ptr;
00021
00022 Economy *Economy::s_economy = NULL;
00023
00024 Economy::Economy(const char* filename) {
00025 TiXmlNode* Products;
00026 TiXmlNode* ForProducts;
00027 TiXmlElement* Prod;
00028 TiXmlText* data;
00029 string prodName;
00030 int Id;
00031 int DefaultValue;
00032
00033
00034 doc.LoadFile( filename );
00035 if (doc.Error()) {
00036 Log::s_log->Message("Error: Could not open Economy File.\n");
00037 exit(-1);
00038 }
00039
00040 Products = doc.FirstChild("CandC")->FirstChild("Products");
00041
00042 for(ForProducts = Products->FirstChildElement("Name");
00043 ForProducts;
00044 ForProducts = ForProducts->NextSibling("Name")) {
00045
00046 if (ForProducts == NULL) throw -1;
00047 Prod = ForProducts->ToElement();
00048 if (Prod == NULL) throw -2;
00049 if (Prod->QueryIntAttribute("id", &Id) != TIXML_SUCCESS)
00050 throw string("Could not parse Product ID");
00051 if (Prod->QueryIntAttribute("default", &DefaultValue) != TIXML_SUCCESS)
00052 throw string("Could not parse Product Default Value");
00053 data = Prod->FirstChild()->ToText();
00054 prodName = data->Value();
00055
00056 ProdList.push_back(prodName);
00057 ProductDefaults.push_back(DefaultValue);
00058 }
00059
00060 num_steps = 0;
00061 }
00062
00063 Economy::~Economy() {
00064 map<string, CityEconomy*>::iterator i;
00065
00066 for (i = CityList.begin();
00067 i != CityList.end();
00068 i++)
00069 delete i->second;
00070
00071 CityList.clear();
00072
00073 }
00074
00075 bool Economy::CreateEconomy() {
00076 if (s_economy != NULL) {
00077 Log::s_log->Message("Warning: Multiple calls to CreateEcon()");
00078 return false;
00079 }
00080
00081 s_economy = new Economy("data/Product.xml");
00082
00083 return true;
00084 }
00085
00086 void Economy::DestroyEconomy() {
00087 if (s_economy == NULL) {
00088 Log::s_log->Message("Warning: Call to DestroyEconomy with NULL Econ");
00089 return;
00090 }
00091 delete s_economy;
00092 s_economy = NULL;
00093 }
00094
00095 void Economy::Step() {
00096 UpdateEconomy();
00097 }
00098
00099 void Economy::UpdateEconomy() {
00100 map<string, CityEconomy*>::iterator i;
00101
00102 for (i = CityList.begin();
00103 i != CityList.end();
00104 i++)
00105 i->second->UpdateEconomy(num_steps);
00106
00107 num_steps = 0;
00108 }
00109
00110 void Economy::Print() {
00111 map<string, CityEconomy*>::iterator i;
00112
00113 for (i = CityList.begin();
00114 i != CityList.end();
00115 i++)
00116 i->second->Print();
00117 }
00118
00119 vector<Product*> Economy::ParseCityProducts(TiXmlElement* CityElement) {
00120 int Consumption;
00121 int Production;
00122 int Id;
00123 TiXmlElement* ProductNode;
00124 Product* ProductHolder;
00125 vector<Product*> Result;
00126
00127 for (ProductNode = CityElement->FirstChildElement("Product");
00128 ProductNode;
00129 ProductNode = ProductNode->NextSibling("Product")->ToElement()) {
00130 if (ProductNode->QueryIntAttribute("id", &Id) != TIXML_SUCCESS) {
00131 Log::s_log->Message("Could not parse Product ID");
00132 throw 0;
00133 }
00134 if (ProductNode->QueryIntAttribute("consumption", &Consumption) != TIXML_SUCCESS) {
00135 Log::s_log->Message("Could not parse Product Consumption");
00136 throw 1;
00137 }
00138 if (ProductNode->QueryIntAttribute("production", &Production) != TIXML_SUCCESS) {
00139 Log::s_log->Message("Could not parse Product Production");
00140 throw 2;
00141 }
00142
00143 ProductHolder = new Product(Id, Consumption, Production);
00144 Result.push_back(ProductHolder);
00145 }
00146 return Result;
00147 }
00148
00149 CityEconomy* Economy::CreateCity(const char* CityName){
00150 TiXmlNode* City;
00151 TiXmlElement* CityElement;
00152 vector<Product*> ProductList;
00153 CityEconomy* tempCE;
00154 string name;
00155 string cityName;
00156 int size;
00157
00158 EconomyNode = doc.FirstChild("CandC")->FirstChild("Economy");
00159
00160 for(City = EconomyNode->FirstChildElement("City");
00161 City;
00162 City = City->NextSibling("City")) {
00163
00164 if (City == NULL) throw -1;
00165 CityElement = City->ToElement();
00166
00167 cityName = CityElement->Attribute("name");
00168 size = atoi(CityElement->Attribute("size"));
00169 if (cityName == CityName) {
00170 ProductList = ParseCityProducts(CityElement);
00171 tempCE = new CityEconomy(cityName.c_str(), ProductList, size);
00172
00173 CityList[tempCE->GetCityName()] = tempCE;
00174
00175 ProductList.clear();
00176 break;
00177 }
00178
00179 }
00180 return tempCE;
00181 }
00182
00183 bool Economy::CheckCities(CityManager* tempManager) {
00184 map<string, CityEconomy*>::iterator i;
00185
00186 for (i = CityList.begin();
00187 i != CityList.end();
00188 i++) {
00189 if (!tempManager->CheckCity(i->second->GetCityName().c_str()))
00190 return false;
00191 }
00192
00193 return true;
00194 }
00195
00196 int Economy::ProductCount() {
00197 return (int)ProdList.size();
00198 }
00199
00200 void Economy::BuyProduct(int ProdID, float price) {
00201 shared_ptr<Cargo> playerCargo = Player::player->GetCargo();
00202
00203 try {
00204
00205 if ((Player::player->gold < price) || (playerCargo->GetAvailQty() <= 0)) return;
00206
00207 playerCargo->AddQty(ProdID, 1);
00208 Player::player->gold -= (int) price;
00209 } catch (const char *e) {
00210 Log::s_log->Message(e);
00211 }
00212 }
00213
00214 void Economy::SellProduct(int ProdID, float price) {
00215 shared_ptr<Cargo> playerCargo = Player::player->GetCargo();
00216
00217 try {
00218 if (playerCargo->GetQty(ProdID) <= 0) return;
00219
00220 playerCargo->AddQty(ProdID, -1);
00221 Player::player->gold += (int) price;
00222 } catch (const char *e) {
00223 Log::s_log->Message(e);
00224 }
00225 }
00226
00227 int Economy::FindID(string Name) {
00228 unsigned int i;
00229
00230 for(i = 0; i < ProdList.size(); i++) {
00231 if (ProdList[i] == Name) return (int)i;
00232 }
00233
00234 return -1;
00235 }