src/CityManager.cpp

Go to the documentation of this file.
00001 /* Crown and Cutlass
00002  * City Manager Class
00003  *
00004  * This class is a vector of cities. It will handle all the
00005  * appropriate actions to take on the cities. (Displaying,
00006  * checking collisions, etc)
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   //WorldEcon = new Economy("data/Product.xml");
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   // Delete the cluster models
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   // Used to determine if the player is sailing towards the city
00063   float angleToCity;
00064   float diffAngles;
00065 
00066   map<string, City*>::iterator i;
00067 
00068   // No sense in checking if the player isn't moving
00069   if (ship->m_speed == 0) return NULL;
00070 
00071   for (i=CityList.begin();
00072        i!=CityList.end();
00073        i++) {
00074     // Check the distance to each city
00075     // Note: This isn't really efficient, but since there aren't many cities
00076     //   it's not really worth doing something fancier.
00077     if (i->second->calcDist(ship->m_x, ship->m_z) < 3) {
00078       // It's in range, now make sure the angle is close
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         // The player is close and headed +-5 degs of city
00087         return i->second;
00088       }
00089     }
00090   }
00091 
00092   // No collision
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       // Get the name of the city
00131       object = node->FirstChild("name")->ToElement();
00132       if (object == NULL) throw 0;
00133       cityString = object->FirstChild()->ToText();
00134       if (cityString == NULL) throw 0;
00135       //cityString = object->ToText();
00136       cityName = cityString->Value();
00137 
00138       // Get the X location
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       // Get the Z location
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       // Get the buildings
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 }

Generated on Mon Jan 8 22:34:12 2007 for CrownandCutlass by  doxygen 1.4.7