00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00042 if (!types_.loadTankTypes(context)) return false;
00043
00044
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
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
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
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
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
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
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
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
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 }