TankModelStore.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <tank/TankModelStore.h>
00022 #include <3dsparse/ModelStore.h>
00023 #include <3dsparse/Model.h>
00024 #include <common/Defines.h>
00025 #include <XML/XMLFile.h>
00026 #include <lang/LangResource.h>
00027 
00028 TankModelStore::TankModelStore()
00029 {
00030         modelCatagories_.insert("All");
00031 }
00032 
00033 TankModelStore::~TankModelStore()
00034 {
00035 
00036 }
00037 
00038 bool TankModelStore::loadTankMeshes(ScorchedContext &context, 
00039         int detailLevel, ProgressCounter *counter)
00040 {
00041         // Load the tank types
00042         if (!types_.loadTankTypes(context)) return false;
00043 
00044         // Load tank definition file
00045         if (counter) counter->setNewOp(LANG_RESOURCE("LOADING_TANKS", "Loading tanks"));
00046         XMLFile file;
00047         if (!file.readFile(S3D::getDataFile("data/tanks.xml")))
00048         {
00049                 S3D::dialogMessage("Scorched Models", S3D::formatStringBuffer(
00050                                           "Failed to parse tanks.xml\n%s", 
00051                                           file.getParserError()));
00052                 return false;
00053         }
00054 
00055         // Check file exists
00056         if (!file.getRootNode())
00057         {
00058                 S3D::dialogMessage("Scorched Models",
00059                                         "Failed to find tank definition file \"data/tanks.xml\"");
00060                 return false;           
00061         }
00062 
00063         // Itterate all of the tanks in the file
00064         int count = 0;
00065         std::vector<TankModel *> randomModels, lowModels, midModels, highModels;
00066     std::list<XMLNode *>::iterator childrenItor;
00067         std::list<XMLNode *> &children = file.getRootNode()->getChildren();
00068     for (childrenItor = children.begin();
00069         childrenItor != children.end();
00070         childrenItor++, count++)
00071     {
00072                 if (counter) counter->
00073                         setNewPercentage(float(count) / float(children.size()) * 100.0f);
00074                 // Parse the tank entry
00075         XMLNode *currentNode = (*childrenItor);
00076                 if (stricmp(currentNode->getName(), "tank"))
00077                 {
00078                         return currentNode->returnError("Failed to tank node");
00079                 }
00080 
00081                 TankModel *tankModel = new TankModel();
00082                 if (!tankModel->initFromXML(context, currentNode))
00083                 {
00084                         return currentNode->returnError("Failed to parse tank node");;
00085                 }
00086 
00087                 // Add models depending on the number of triangles in each model
00088                 Model *model = ModelStore::instance()->loadModel(
00089                         tankModel->getTankModelID());
00090                 if (strcmp(tankModel->getName(), "Random") == 0)
00091                 {
00092                         randomModels.push_back(tankModel);
00093                 }
00094                 else 
00095                 {
00096                         int triangles = model->getNumberTriangles();
00097                         if (triangles <= 250) lowModels.push_back(tankModel);
00098                         else if (triangles <= 500) midModels.push_back(tankModel);
00099                         else highModels.push_back(tankModel);
00100                 }
00101         }
00102 
00103         // Add tanks dependant on the set detail level
00104         if (detailLevel >= 2) addModels(highModels);
00105         if (detailLevel >= 1) addModels(midModels);
00106         if (detailLevel >= 0) addModels(lowModels);
00107         if (models_.empty()) addModels(midModels);
00108         if (models_.empty()) addModels(highModels);
00109         addModels(randomModels);
00110 
00111         // Remove any models we don't use
00112         killModels(randomModels);
00113         killModels(lowModels);
00114         killModels(midModels);
00115         killModels(highModels);
00116 
00117         return true;
00118 }
00119 
00120 void TankModelStore::addModels(std::vector<TankModel *> &src)
00121 {
00122         while (!src.empty())
00123         {
00124                 TankModel *tankModel = src.back();
00125                 src.pop_back();
00126 
00127                 // Add catagories to list of all catagories
00128                 std::set<std::string> &catagories = tankModel->getCatagories();
00129                 std::set<std::string>::iterator catitor;
00130                 for (catitor = catagories.begin();
00131                         catitor != catagories.end();
00132                         catitor++)
00133                 {
00134                         modelCatagories_.insert((*catitor).c_str());
00135                 }
00136 
00137                 models_.push_back(tankModel);
00138         }
00139 }
00140 
00141 void TankModelStore::killModels(std::vector<TankModel *> &src)
00142 {
00143         while (!src.empty())
00144         {
00145                 TankModel *tankModel = src.back();
00146                 src.pop_back();
00147                 delete tankModel;
00148         }
00149 }
00150 
00151 TankModel *TankModelStore::getRandomModel(int team, bool ai)
00152 {
00153         std::vector<TankModel *> models;
00154         std::vector<TankModel *>::iterator itor;
00155         for (itor = models_.begin();
00156                 itor != models_.end();
00157                 itor++)
00158         {
00159                 TankModel *model = (*itor);
00160                 if (strcmp(model->getName(), "Random") != 0)
00161                 {
00162                         if (model->isOfTeam(team) && 
00163                                 model->isOfAi(ai)) models.push_back(model);
00164                 }
00165         }
00166 
00167         DIALOG_ASSERT(models.size());
00168         TankModel *model = models[rand() % models.size()];
00169         return model;
00170 }
00171 
00172 TankModel *TankModelStore::getModelByName(const char *name, int team, bool ai)
00173 {
00174         DIALOG_ASSERT(models_.size());
00175 
00176         // A hack to allow the random model
00177         if (strcmp(name, "Random") == 0) return getRandomModel(team, ai);
00178 
00179         std::vector<TankModel *>::iterator itor;
00180         for (itor = models_.begin();
00181                  itor != models_.end();
00182                  itor++)
00183         {
00184                 TankModel *current = (*itor);
00185                 if (0 == strcmp(current->getName(), name) &&
00186                         current->isOfTeam(team) &&
00187                         current->isOfAi(ai))
00188                 {
00189                         return current;
00190                 }
00191         }
00192 
00193         return getRandomModel(team, ai);
00194 }
00195 
00196 TankType *TankModelStore::getTypeByName(const char *name)
00197 {
00198         return types_.getType(name);
00199 }

Generated on Mon Feb 16 15:14:51 2009 for Scorched3D by  doxygen 1.5.3