00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <string>
00010 #include <vector>
00011 #include <map>
00012 #include <fstream>
00013 #include <iostream>
00014 #include "GLee.h"
00015 #include "SDL.h"
00016 #include "ccmath.h"
00017 #include "City.h"
00018 #include "IEnvironmentObject.h"
00019 #include "Terrain.h"
00020 #include "Ship.h"
00021 #include "Log.h"
00022 #include "Product.h"
00023 #include "Model.h"
00024 #include "BuildingList.h"
00025 #include "Point.h"
00026 #include "tinyxml.h"
00027 #include "CityManager.h"
00028
00029 #define MAX_CITIES 32 // This needs to get bigger probably...
00030
00031 using namespace std;
00032
00033 CityManager::CityManager(Terrain *land) {
00034 LoadCityConfig("data/City.xml", land);
00035
00036
00037
00038 Log::s_log->Message("Cities loaded");
00039 }
00040
00041 CityManager::~CityManager() {
00042 unsigned int i;
00043 map<string, City*>::const_iterator j;
00044
00045 for (j = CityList.begin();
00046 j != CityList.end();
00047 j++)
00048 delete j->second;
00049 CityList.clear();
00050
00051
00052 for (i = 0; i < clusters.size(); i++) {
00053 delete clusters[i];
00054 clusters[i] = NULL;
00055 }
00056 clusters.clear();
00057
00058 Log::s_log->Message("Cities deleted");
00059 }
00060
00061 City* CityManager::CheckCollision(Ship *ship) {
00062
00063 float angleToCity;
00064 float diffAngles;
00065
00066 map<string, City*>::iterator i;
00067
00068
00069 if (ship->m_speed == 0) return NULL;
00070
00071 for (i=CityList.begin();
00072 i!=CityList.end();
00073 i++) {
00074
00075
00076
00077 if (i->second->calcDist(ship->m_x, ship->m_z) < 3) {
00078
00079 angleToCity = i->second->calcAngle(ship->m_x, ship->m_z);
00080
00081 diffAngles = fabs(ship->m_rot - angleToCity);
00082
00083 if (diffAngles > M_PI) diffAngles = 2*M_PI - diffAngles;
00084
00085 if (diffAngles < degreesToRadians(15)) {
00086
00087 return i->second;
00088 }
00089 }
00090 }
00091
00092
00093 return NULL;
00094 }
00095
00096 void CityManager::DisplayCities() {
00097 map<string, City*>::iterator i;
00098
00099 for (i = CityList.begin();
00100 i != CityList.end();
00101 i++)
00102 i->second->DisplayObject();
00103 }
00104
00105 void CityManager::LoadCityConfig(const char *filename, Terrain *land) {
00106 City* TempCity;
00107 TiXmlElement* object;
00108 TiXmlElement* location;
00109 TiXmlElement* buildings;
00110 TiXmlNode* node;
00111 TiXmlNode* cities;
00112 TiXmlDocument doc( filename );
00113 TiXmlText* cityString;
00114 string cityName;
00115 vector<Product*> tempList;
00116 int locX, locZ;
00117 int objNum = 0;
00118 string modelName;
00119 string textureName;
00120 BuildingList *cityBuildings;
00121
00122 doc.LoadFile();
00123 cities = doc.FirstChild("Cities");
00124
00125 ParseClusters(cities->FirstChildElement("Clusters"));
00126
00127 for (node = cities->FirstChild("object"); node; node = node->NextSibling()) {
00128 objNum++;
00129 try {
00130
00131 object = node->FirstChild("name")->ToElement();
00132 if (object == NULL) throw 0;
00133 cityString = object->FirstChild()->ToText();
00134 if (cityString == NULL) throw 0;
00135
00136 cityName = cityString->Value();
00137
00138
00139 location = node->FirstChild("location")->ToElement();
00140 if (location == NULL) throw 1;
00141 object = location->FirstChild("x")->ToElement();
00142 if (object == NULL) throw 1;
00143 cityString = object->FirstChild()->ToText();
00144 if (cityString == NULL) throw 1;
00145 sscanf(cityString->Value(), "%d", &locX);
00146
00147
00148 object = location->FirstChild("z")->ToElement();
00149 if (object == NULL) throw 2;
00150 cityString = object->FirstChild()->ToText();
00151 if (cityString == NULL) throw 2;
00152 sscanf(cityString->Value(), "%d", &locZ);
00153
00154
00155 cityBuildings = new BuildingList();
00156
00157 buildings = node->FirstChildElement("Buildings");
00158 if (buildings == NULL) throw 3;
00159
00160 for (object = buildings->FirstChildElement("Building"); object; object = object->NextSiblingElement("Building")) {
00161 int tModel;
00162 float tX, tY, tZ, tRot;
00163 const char *tStr;
00164
00165 if (object == NULL) throw 4;
00166
00167 tStr = object->Attribute("index");
00168 if (tStr == NULL) throw 5;
00169 if (sscanf(tStr, "%d", &tModel) != 1) throw 5;
00170
00171 tStr = object->Attribute("rotation");
00172 if (tStr == NULL) throw 6;
00173 if (sscanf(tStr, "%f", &tRot) != 1) throw 6;
00174
00175 tStr = object->Attribute("x");
00176 if (tStr == NULL) throw 7;
00177 if (sscanf(tStr, "%f", &tX) != 1) throw 7;
00178
00179 tStr = object->Attribute("y");
00180 if (tStr == NULL) throw 7;
00181 if (sscanf(tStr, "%f", &tY) != 1) throw 7;
00182
00183 tStr = object->Attribute("z");
00184 if (tStr == NULL) throw 7;
00185 if (sscanf(tStr, "%f", &tZ) != 1) throw 7;
00186
00187 cityBuildings->Add(clusters[tModel], new Point(tX, tY, tZ), tRot);
00188 }
00189
00190 TempCity = new City(land, cityName, locX, locZ, cityBuildings);
00191 CityList[cityName] = TempCity;
00192 Keys.push_back(cityName);
00193 } catch(int j) {
00194 switch (j) {
00195 case 0:
00196 Log::s_log->Message("Warning: Problem with Object Name.");
00197 break;
00198 case 1:
00199 Log::s_log->Message("Warning: Problem with Object x Location.");
00200 break;
00201 case 2:
00202 Log::s_log->Message("Warning: Problem with Object y Location.");
00203 break;
00204 case 3:
00205 Log::s_log->Message("Warning: Problem with Object Buildings.");
00206 break;
00207 case 4:
00208 Log::s_log->Message("Warning: Problem with Object Buildings item.");
00209 break;
00210 case 5:
00211 Log::s_log->Message("Warning: Problem with Object Buildings index.");
00212 break;
00213 case 6:
00214 Log::s_log->Message("Warning: Problem with Object Buildings rotation.");
00215 break;
00216 case 7:
00217 Log::s_log->Message("Warning: Problem with Object Buildings x, y, z.");
00218 break;
00219 default:
00220 Log::s_log->Message("Warning: Problem with City Config file.");
00221 break;
00222 }
00223 }
00224 }
00225 }
00226
00227 void CityManager::ParseClusters(TiXmlElement *clustersNode) {
00228 TiXmlElement *node;
00229 TiXmlElement *tempElement;
00230 TiXmlText* tempString;
00231 string file;
00232 string texture;
00233 string scaleStr;
00234 float scale;
00235 Model *model;
00236
00237 if (clustersNode == NULL) {
00238 Log::s_log->Message("Warning: Clusters node NULL");
00239 return;
00240 }
00241
00242 try {
00243 for (node = clustersNode->FirstChildElement("Cluster"); node; node = node->NextSiblingElement("Cluster")) {
00244 tempElement = node->FirstChildElement("Model");
00245 if ((tempElement == NULL) || (tempElement->FirstChild() == NULL)) throw "Model";
00246 tempString = tempElement->FirstChild()->ToText();
00247 if (tempString == NULL) throw "Model2";
00248 file = tempString->Value();
00249
00250 tempElement = node->FirstChildElement("Texture");
00251 if ((tempElement == NULL) || (tempElement->FirstChild() == NULL)) throw "Texture";
00252 tempString = tempElement->FirstChild()->ToText();
00253 if (tempString == NULL) throw "Texture";
00254 texture = tempString->Value();
00255
00256 tempElement = node->FirstChildElement("Scale");
00257 if ((tempElement == NULL) || (tempElement->FirstChild() == NULL)) throw "Scale";
00258 tempString = tempElement->FirstChild()->ToText();
00259 if (tempString == NULL) throw "Scale";
00260 if (sscanf(tempString->Value(), "%f", &scale) != 1) throw "Scale";
00261
00262 model = new Model(texture);
00263 model->loadObj(file.c_str(), scale);
00264
00265 clusters.push_back(model);
00266 }
00267 } catch (const char *e) {
00268 Log::s_log->Message("Warning: Could not parse %s in city clusters", e);
00269 }
00270
00271 Log::s_log->Message("%d clusters loaded", clusters.size());
00272 }
00273
00274 bool CityManager::CheckCity(const char *cityName) {
00275 if (CityList[cityName]) return true;
00276 return false;
00277 }
00278
00279 unsigned int CityManager::NumberCities() {
00280 return CityList.size();
00281 }
00282
00283 City* CityManager::GetCity(const char *cityName) {
00284 return CityList[cityName];
00285 }
00286
00287 City* CityManager::GetCity(int CityIndex) {
00288 return GetCity(Keys[CityIndex].c_str());
00289 }