// ============================================================== // This file is part of Glest (www.glest.org) // // Copyright (C) 2001-2008 Martiņo Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published // by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version // ============================================================== #include "tech_tree.h" #include #include "util.h" #include "resource.h" #include "faction_type.h" #include "logger.h" #include "xml_parser.h" #include "platform_util.h" #include "game_util.h" #include "leak_dumper.h" using namespace Shared::Util; using namespace Shared::Xml; namespace Glest{ namespace Game{ // ===================================================== // class TechTree // ===================================================== void TechTree::loadTech(const vector pathList, const string &techName, set &factions, Checksum* checksum) { for(int idx = 0; idx < pathList.size(); idx++) { string path = pathList[idx] + "/" + techName; if(isdir(path.c_str()) == true) { load(path, factions, checksum); break; } } } void TechTree::load(const string &dir, set &factions, Checksum* checksum) { string str; vector filenames; string name= lastDir(dir); Logger::getInstance().add("TechTree: "+ formatString(name), true); //load resources str= dir+"/resources/*."; try{ findAll(str, filenames); resourceTypes.resize(filenames.size()); for(int i=0; iaddFile(path); xmlTree.load(path); const XmlNode *techTreeNode= xmlTree.getRootNode(); //attack types const XmlNode *attackTypesNode= techTreeNode->getChild("attack-types"); attackTypes.resize(attackTypesNode->getChildCount()); for(int i=0; igetChild("attack-type", i); attackTypes[i].setName(attackTypeNode->getAttribute("name")->getRestrictedValue()); attackTypes[i].setId(i); } //armor types const XmlNode *armorTypesNode= techTreeNode->getChild("armor-types"); armorTypes.resize(armorTypesNode->getChildCount()); for(int i=0; igetChild("armor-type", i); armorTypes[i].setName(armorTypeNode->getAttribute("name")->getRestrictedValue()); armorTypes[i].setId(i); } //damage multipliers damageMultiplierTable.init(attackTypes.size(), armorTypes.size()); const XmlNode *damageMultipliersNode= techTreeNode->getChild("damage-multipliers"); for(int i=0; igetChildCount(); ++i){ const XmlNode *damageMultiplierNode= damageMultipliersNode->getChild("damage-multiplier", i); const AttackType *attackType= getAttackType(damageMultiplierNode->getAttribute("attack")->getRestrictedValue()); const ArmorType *armorType= getArmorType(damageMultiplierNode->getAttribute("armor")->getRestrictedValue()); float multiplier= damageMultiplierNode->getAttribute("value")->getFloatValue(); damageMultiplierTable.setDamageMultiplier(attackType, armorType, multiplier); } } catch(const exception &e){ throw runtime_error("Error loading Tech Tree: "+ dir + "\n" + e.what()); } //load factions str= dir+"/factions/*."; try{ factionTypes.resize(factions.size()); int i=0; for ( set::iterator it = factions.begin(); it != factions.end(); ++it ) { str=dir+"/factions/" + *it; factionTypes[i++].load(str, this, checksum); } } catch(const exception &e){ throw runtime_error("Error loading Faction Types: "+ dir + "\n" + e.what()); } } TechTree::~TechTree(){ Logger::getInstance().add("Tech tree", true); } // ==================== get ==================== const FactionType *TechTree::getType(const string &name) const{ for(int i=0; igetResourceNumber()==i && rt->getClass()==rcTech) return getResourceType(j); } return getFirstTechResourceType(); } const ResourceType *TechTree::getFirstTechResourceType() const{ for(int i=0; igetResourceNumber()==1 && rt->getClass()==rcTech) return getResourceType(i); } throw runtime_error("This tech tree has not tech resources, one at least is required"); } const ResourceType *TechTree::getResourceType(const string &name) const{ for(int i=0; i