Merge remote-tracking branch 'upstream/develop' into develop

This commit is contained in:
filux 2014-10-16 21:16:49 +00:00
commit 1724fddb65
11 changed files with 205 additions and 121 deletions

@ -1 +1 @@
Subproject commit 4f05a0177385ce47eb4cfcf5ce6676f59b290d37
Subproject commit b1fc026f227d6947c0bf685d1c705561f2d3909f

View File

@ -202,6 +202,10 @@ GCRYPT_LINKEDLIBNAME='libgcrypt.so.11'
GCRYPT_LIBLOOKUP1=${GCRYPT_LINKEDLIBNAME}
GCRYPT_LIBLOOKUP2='libgcrypt.so.'
TASN_LINKEDLIBNAME='libtasn1.so.3'
TASN_LIBLOOKUP1=${TASN_LINKEDLIBNAME}
TASN_LIBLOOKUP2='libtasn1.so.'
if [ "$OS_TYPE"'_' = 'x86_64_' ]; then
DIRECTFB_LINKEDLIBNAME='libdirectfb-1.2.so.0'
DIRECTFB_LIBLOOKUP1=${DIRECTFB_LINKEDLIBNAME}
@ -279,6 +283,7 @@ findMissingSO "$LDCONFIG" "$GAMEDIR/$LIBDIR/${DL_LINKEDLIBNAME}" "$DL_LIBLOOKUP1
findMissingSO "$LDCONFIG" "$GAMEDIR/$LIBDIR/${VLCCORE_LINKEDLIBNAME}" "$VLCCORE_LIBLOOKUP1" "$VLCCORE_LIBLOOKUP2"
findMissingSO "$LDCONFIG" "$GAMEDIR/$LIBDIR/${VLC_LINKEDLIBNAME}" "$VLC_LIBLOOKUP1" "$VLC_LIBLOOKUP2"
findMissingSO "$LDCONFIG" "$GAMEDIR/$LIBDIR/${GCRYPT_LINKEDLIBNAME}" "$GCRYPT_LIBLOOKUP1" "$GCRYPT_LIBLOOKUP2"
findMissingSO "$LDCONFIG" "$GAMEDIR/$LIBDIR/${TASN_LINKEDLIBNAME}" "$TASN_LIBLOOKUP1" "$TASN_LIBLOOKUP2"
./megaglest $@

View File

@ -5359,7 +5359,8 @@ int glestMain(int argc, char** argv) {
bool startCRCPrecacheThread = config.getBool("PreCacheCRCThread","true");
//printf("### In [%s::%s Line: %d] precache thread enabled = %d SystemFlags::VERBOSE_MODE_ENABLED = %d\n",__FILE__,__FUNCTION__,__LINE__,startCRCPrecacheThread,SystemFlags::VERBOSE_MODE_ENABLED);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] precache thread enabled = %d\n",__FILE__,__FUNCTION__,__LINE__,startCRCPrecacheThread);
if(startCRCPrecacheThread == true) {
if (startCRCPrecacheThread == true
&& GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) {
static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__);
vector<string> techDataPaths = config.getPathListForType(ptTechs);

View File

@ -3341,8 +3341,9 @@ void MenuStateConnectedGame::update() {
GameSettings *gameSettings = clientInterface->getGameSettingsPtr();
//printf("Menu got new settings thisfactionindex = %d startlocation: %d control = %d\n",gameSettings->getThisFactionIndex(),clientInterface->getGameSettings()->getStartLocationIndex(clientInterface->getGameSettings()->getThisFactionIndex()),gameSettings->getFactionControl(clientInterface->getGameSettings()->getThisFactionIndex()));
setupUIFromGameSettings(gameSettings, errorOnMissingData);
if ( difftime((long int)time(NULL),broadcastServerSettingsDelayTimer) >= HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS){
setupUIFromGameSettings(gameSettings, errorOnMissingData);
}
}
// check if we are joining an in progress game
@ -4604,6 +4605,7 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings,
if(getMissingMapFromFTPServerInProgress == false &&
gameSettings->getMap() != "") {
// map
bool missingMap=false;
string mapFile = gameSettings->getMap();
mapFile = formatString(mapFile);
@ -4647,11 +4649,16 @@ void MenuStateConnectedGame::setupUIFromGameSettings(GameSettings *gameSettings,
}
maps.push_back(Lang::getInstance().getString("DataMissing","",true));
mapFile = Lang::getInstance().getString("DataMissing","",true);
missingMap=true;
}
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] listBoxMap.getSelectedItemIndex() = %d, mapFiles.size() = " MG_SIZE_T_SPECIFIER ", maps.size() = " MG_SIZE_T_SPECIFIER ", getCurrentMapFile() [%s] mapFile [%s]\n",
extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,listBoxMap.getSelectedItemIndex(),mapFiles.size(),maps.size(),getCurrentMapFile().c_str(),mapFile.c_str());
if(!missingMap && mapFile!=listBoxMap.getSelectedItem()){
console.addLine("Headless server does not have map, switching to next one");
printf("Headless server doesn't have map '%s'. Setting map '%s' instead.\n",listBoxMap.getSelectedItem().c_str(),mapFile.c_str());
}
listBoxMap.setItems(maps);
listBoxMap.setSelectedItem(mapFile);

View File

@ -266,7 +266,7 @@ string AttackCommandType::getDesc(const TotalUpgrade *totalUpgrade, bool transla
//attack distance
str+= lang.getString("AttackDistance",(translatedValue == true ? "" : "english"))+": "+intToStr(attackSkillType->getAttackRange());
if(totalUpgrade->getAttackRange(attackSkillType) != 0) {
str+= "+"+intToStr(totalUpgrade->getAttackRange(attackSkillType) != 0);
str+= "+"+intToStr(totalUpgrade->getAttackRange(attackSkillType));
}
str+="\n";

View File

@ -12,6 +12,7 @@
#include "skill_type.h"
#include <cassert>
#include <iterator>
#include "sound.h"
#include "util.h"
@ -61,34 +62,16 @@ bool AttackBoost::isAffected(const Unit *source, const Unit *dest) const {
else {
// All units are affected (including enemies)
if(targetType == abtAll) {
destUnitMightApply = (boostUnitList.empty() == true);
// Specify which units are affected
for(unsigned int i = 0; i < boostUnitList.size(); ++i) {
const UnitType *ut = boostUnitList[i];
if(dest->getType()->getId() == ut->getId()) {
destUnitMightApply = true;
break;
}
}
destUnitMightApply = (boostUnitList.empty() && tags.empty());
destUnitMightApply = isInUnitListOrTags(dest->getType());
}
// Only same faction units are affected
else if(targetType == abtFaction) {
//if(boostUnitList.empty() == true) {
if(source->getFactionIndex() == dest->getFactionIndex()) {
//destUnitMightApply = true;
destUnitMightApply = (boostUnitList.empty() == true);
// Specify which units are affected
for(unsigned int i = 0; i < boostUnitList.size(); ++i) {
const UnitType *ut = boostUnitList[i];
if(dest->getType()->getId() == ut->getId()) {
destUnitMightApply = true;
break;
}
}
destUnitMightApply = (boostUnitList.empty() && tags.empty());
destUnitMightApply = isInUnitListOrTags(dest->getType());
}
//}
}
@ -97,16 +80,8 @@ bool AttackBoost::isAffected(const Unit *source, const Unit *dest) const {
//if(boostUnitList.empty() == true) {
if(source->isAlly(dest) == true) {
//destUnitMightApply = true;
destUnitMightApply = (boostUnitList.empty() == true);
// Specify which units are affected
for(unsigned int i = 0; i < boostUnitList.size(); ++i) {
const UnitType *ut = boostUnitList[i];
if(dest->getType()->getId() == ut->getId()) {
destUnitMightApply = true;
break;
}
}
destUnitMightApply = (boostUnitList.empty() && tags.empty());
destUnitMightApply = isInUnitListOrTags(dest->getType());
}
//}
}
@ -115,28 +90,13 @@ bool AttackBoost::isAffected(const Unit *source, const Unit *dest) const {
//if(boostUnitList.empty() == true) {
if(source->isAlly(dest) == false) {
//destUnitMightApply = true;
destUnitMightApply = (boostUnitList.empty() == true);
// Specify which units are affected
for(unsigned int i = 0; i < boostUnitList.size(); ++i) {
const UnitType *ut = boostUnitList[i];
if(dest->getType()->getId() == ut->getId()) {
destUnitMightApply = true;
break;
}
}
destUnitMightApply = (boostUnitList.empty() && tags.empty());
destUnitMightApply = isInUnitListOrTags(dest->getType());
}
//}
}
else if(targetType == abtUnitTypes) {
// Specify which units are affected
for(unsigned int i = 0; i < boostUnitList.size(); ++i) {
const UnitType *ut = boostUnitList[i];
if(dest->getType()->getId() == ut->getId()) {
destUnitMightApply = true;
break;
}
}
destUnitMightApply = isInUnitListOrTags(dest->getType());
}
}
@ -151,6 +111,32 @@ bool AttackBoost::isAffected(const Unit *source, const Unit *dest) const {
return result;
}
bool AttackBoost::isInUnitListOrTags(const UnitType *unitType) const {
// Specify which units are affected
std::set<const UnitType*>::iterator it;
for (it = boostUnitList.begin(); it != boostUnitList.end(); ++it) {
const UnitType *boostUnit = *it;
if(unitType->getId() == boostUnit->getId()) {
return true;
}
}
set<string> unitTags = unitType->getTags();
set<string> intersect;
set_intersection(tags.begin(),tags.end(),unitTags.begin(),unitTags.end(),
std::inserter(intersect,intersect.begin()));
if(!intersect.empty()) return true;
// Otherwise no match
return false;
}
string AttackBoost::getTagName(string tag, bool translatedValue) const {
if(translatedValue == false) return tag;
Lang &lang = Lang::getInstance();
return lang.getTechTreeString("TagName_" + tag, tag.c_str());
}
string AttackBoost::getDesc(bool translatedValue) const{
Lang &lang= Lang::getInstance();
string str= "";
@ -190,14 +176,31 @@ string AttackBoost::getDesc(bool translatedValue) const{
str+= lang.getString("AffectedUnitsFromAll") +":\n";
}
if(boostUnitList.empty() == false) {
for(int i=0; i < (int)boostUnitList.size(); ++i){
str+= " "+boostUnitList[i]->getName(translatedValue)+"\n";
}
if(boostUnitList.empty() && tags.empty()) {
str+= lang.getString("All")+"\n";
}
else
{
str+= lang.getString("All")+"\n";
// We want the output to be sorted, so convert the set to a vector and sort that
std::vector<const UnitType*> outputUnits(boostUnitList.begin(), boostUnitList.end());
std::sort(outputUnits.begin(), outputUnits.end(), UnitTypeSorter());
vector<const UnitType*>::iterator unitIter;
for (unitIter = outputUnits.begin(); unitIter != outputUnits.end(); ++unitIter) {
const UnitType *unit = *unitIter;
str+= indent+unit->getName(translatedValue)+"\n";
}
// Do the same for tags
std::vector<string> outputTags(tags.begin(), tags.end());
std::sort(outputTags.begin(), outputTags.end());
vector<string>::iterator tagIter;
for (tagIter = outputTags.begin(); tagIter != outputTags.end(); ++tagIter) {
string tag = *tagIter;
str+= indent + lang.getString("TagDesc", (translatedValue == true ? "" : "english")) +
" " + getTagName(tag,translatedValue) + "\n";
}
}
return str;
@ -222,10 +225,18 @@ void AttackBoost::loadGame(const XmlNode *rootNode, Faction *faction, const Skil
string unitTypeName = node->getAttribute("name")->getValue();
const UnitType *unitType = faction->getType()->getUnitType(unitTypeName);
if(unitType != NULL) {
boostUnitList.push_back(unitType);
boostUnitList.insert(unitType);
}
}
}
if(attackBoostNode->hasChild("tag")) {
vector<XmlNode *> tagNodeList = attackBoostNode->getChildList("tag");
for(unsigned int i = 0; i < tagNodeList.size(); ++i) {
XmlNode *node = tagNodeList[i];
string tagName = node->getAttribute("name")->getValue();
tags.insert(tagName);
}
}
//boostUpgrade.loadGame(attackBoostNode,faction);
boostUpgrade = skillType->getAttackBoost()->boostUpgrade;
@ -252,10 +263,17 @@ void AttackBoost::saveGame(XmlNode *rootNode) const {
// AttackBoostTargetType targetType;
attackBoostNode->addAttribute("targetType",intToStr(targetType), mapTagReplacements);
// vector<const UnitType *> boostUnitList;
for(unsigned int i = 0; i < boostUnitList.size(); ++i) {
const UnitType *ut = boostUnitList[i];
std::set<const UnitType*>::iterator unitIter;
for (unitIter = boostUnitList.begin(); unitIter != boostUnitList.end(); ++unitIter) {
const UnitType *unit = *unitIter;
XmlNode *unitTypeNode = attackBoostNode->addChild("UnitType");
unitTypeNode->addAttribute("name",ut->getName(false), mapTagReplacements);
unitTypeNode->addAttribute("name",unit->getName(false), mapTagReplacements);
}
std::set<string>::iterator tagIter;
for (tagIter = tags.begin(); tagIter != tags.end(); ++tagIter) {
string tag = *tagIter;
XmlNode *unitTypeNode = attackBoostNode->addChild("tag");
unitTypeNode->addAttribute("name", tag, mapTagReplacements);
}
// UpgradeTypeBase boostUpgrade;
boostUpgrade.saveGame(attackBoostNode);
@ -352,38 +370,18 @@ void SkillType::loadAttackBoost(const XmlNode *attackBoostsNode, const XmlNode *
if(targetType == "ally") {
attackBoost.targetType = abtAlly;
for(int i = 0;i < (int)attackBoostNode->getChild("target")->getChildCount();++i) {
const XmlNode *boostUnitNode = attackBoostNode->getChild("target")->getChild("unit-type", i);
attackBoost.boostUnitList.push_back(ft->getUnitType(boostUnitNode->getAttribute("name")->getRestrictedValue()));
}
}
else if(targetType == "foe") {
attackBoost.targetType = abtFoe;
for(int i = 0;i < (int)attackBoostNode->getChild("target")->getChildCount();++i) {
const XmlNode *boostUnitNode = attackBoostNode->getChild("target")->getChild("unit-type", i);
attackBoost.boostUnitList.push_back(ft->getUnitType(boostUnitNode->getAttribute("name")->getRestrictedValue()));
}
}
else if(targetType == "faction") {
attackBoost.targetType = abtFaction;
for(int i = 0;i < (int)attackBoostNode->getChild("target")->getChildCount();++i) {
const XmlNode *boostUnitNode = attackBoostNode->getChild("target")->getChild("unit-type", i);
attackBoost.boostUnitList.push_back(ft->getUnitType(boostUnitNode->getAttribute("name")->getRestrictedValue()));
}
}
else if(targetType == "unit-types") {
attackBoost.targetType = abtUnitTypes;
for(int i = 0;i < (int)attackBoostNode->getChild("target")->getChildCount();++i) {
const XmlNode *boostUnitNode = attackBoostNode->getChild("target")->getChild("unit-type", i);
attackBoost.boostUnitList.push_back(ft->getUnitType(boostUnitNode->getAttribute("name")->getRestrictedValue()));
}
}
else if(targetType == "all") {
attackBoost.targetType = abtAll;
for(int i = 0;i < (int)attackBoostNode->getChild("target")->getChildCount();++i) {
const XmlNode *boostUnitNode = attackBoostNode->getChild("target")->getChild("unit-type", i);
attackBoost.boostUnitList.push_back(ft->getUnitType(boostUnitNode->getAttribute("name")->getRestrictedValue()));
}
}
else {
char szBuf[8096] = "";
@ -391,6 +389,21 @@ void SkillType::loadAttackBoost(const XmlNode *attackBoostsNode, const XmlNode *
throw megaglest_runtime_error(szBuf);
}
// Load the regular targets
const XmlNode *targetNode = attackBoostNode->getChild("target");
vector<XmlNode*> targetNodes = targetNode->getChildList("unit-type");
for(size_t i = 0;i < targetNodes.size(); ++i) {
string unitName = targetNodes.at(i)->getAttribute("name")->getRestrictedValue();
attackBoost.boostUnitList.insert(ft->getUnitType(unitName));
}
// Load tags
vector<XmlNode*> tagNodes = targetNode->getChildList("tag");
for(size_t i = 0;i < tagNodes.size(); ++i) {
string unitName = tagNodes.at(i)->getAttribute("name")->getRestrictedValue();
attackBoost.tags.insert(unitName);
}
attackBoost.boostUpgrade.load(attackBoostNode,attackBoost.name);
if(attackBoostNode->hasChild("particles") == true) {
const XmlNode *particleNode = attackBoostNode->getChild("particles");

View File

@ -30,6 +30,7 @@
#include "projectile_type.h"
#include "upgrade_type.h"
#include "leak_dumper.h"
#include <set>
using Shared::Sound::StaticSound;
using Shared::Xml::XmlNode;
@ -98,7 +99,8 @@ public:
bool allowMultipleBoosts;
int radius;
AttackBoostTargetType targetType;
vector<const UnitType *> boostUnitList;
std::set<const UnitType *> boostUnitList;
std::set<string> tags;
UpgradeTypeBase boostUpgrade;
UnitParticleSystemType *unitParticleSystemTypeForSourceUnit;
@ -109,9 +111,20 @@ public:
bool isAffected(const Unit *source, const Unit *dest) const;
virtual string getDesc(bool translatedValue) const;
string getTagName(string tag, bool translatedValue=false) const;
virtual void saveGame(XmlNode *rootNode) const;
virtual void loadGame(const XmlNode *rootNode, Faction *faction, const SkillType *skillType);
private:
/**
* Checks if a unit is affected by the attack boost by checking if either the UnitType is in
* the #boostUnitList or shares a tag with #tags.
* @param unitType The unit type to check.
* @return True if the unit *might* be affected by the attack boost (still have to check if it's
* in range), false otherwise.
*/
bool isInUnitListOrTags(const UnitType *unitType) const;
};
class AnimationAttributes {

View File

@ -602,7 +602,7 @@ void UnitType::loaddd(int id,const string &dir, const TechTree *techTree,
if(parametersNode->hasChild("resources-death")) {
const XmlNode *deathResourcesNode= parametersNode->getChild("resources-death");
for(int i=0; i < deathResourcesNode->getChildCount(); ++i){
for(size_t i=0; i < deathResourcesNode->getChildCount(); ++i){
const XmlNode *resourceNode= deathResourcesNode->getChild("resource", i);
string name= resourceNode->getAttribute("name")->getRestrictedValue();
@ -656,6 +656,17 @@ void UnitType::loaddd(int id,const string &dir, const TechTree *techTree,
}
}
// Tags
if(parametersNode->hasChild("tags")) {
const XmlNode *tagsNode= parametersNode->getChild("tags");
for(size_t i=0; i < tagsNode->getChildCount(); ++i){
const XmlNode *resourceNode= tagsNode->getChild("tag", i);
string tag= resourceNode->getAttribute("value")->getRestrictedValue();
tags.insert(tag);
}
}
//image
const XmlNode *imageNode= parametersNode->getChild("image");
image= Renderer::getInstance().newTexture2D(rsGame);

View File

@ -193,6 +193,7 @@ private:
StoredResources storedResources;
Levels levels;
LootableResources lootableResources;
std::set<string> tags;
//meeting point
bool meetingPoint;
@ -265,6 +266,7 @@ public:
inline const Resource *getStoredResource(int i) const {return &storedResources[i];}
int getLootableResourceCount() const {return lootableResources.size();}
inline const LootableResource getLootableResource(int i) const {return lootableResources.at(i);}
const set<string> &getTags() const {return tags;}
bool getCellMapCell(int x, int y, CardinalDir facing) const;
inline bool getMeetingPoint() const {return meetingPoint;}
inline bool getCountUnitDeathInStats() const {return countUnitDeathInStats;}
@ -329,6 +331,17 @@ private:
void computeFirstCtOfClass();
};
/**
* Used to sort UnitType. Sorts by *translated* unit name. Sorting is case sensitive and done in
* lexical order.
*/
struct UnitTypeSorter
{
bool operator()( const UnitType *left, const UnitType *right ) const {
return left->getName(true) < right->getName(true);
}
};
}}//end namespace

View File

@ -13,6 +13,7 @@
#include <algorithm>
#include <cassert>
#include <iterator>
#include "unit_type.h"
#include "util.h"
@ -601,18 +602,43 @@ string UpgradeType::getName(bool translatedValue) const {
return lang.getTechTreeString("UpgradeTypeName_" + name,name.c_str());
}
string UpgradeType::getTagName(string tag, bool translatedValue) const {
if(translatedValue == false) return tag;
Lang &lang = Lang::getInstance();
return lang.getTechTreeString("TagName_" + tag, tag.c_str());
}
string UpgradeType::getReqDesc(bool translatedValue) const{
Lang &lang= Lang::getInstance();
string str= ProducibleType::getReqDesc(translatedValue);
string indent=" ";
if(getEffectCount()>0){
if(!effects.empty() || !tags.empty()){
str+= "\n"+ lang.getString("Upgrades",(translatedValue == true ? "" : "english"))+"\n";
}
str+=UpgradeTypeBase::getDesc(translatedValue);
if(getEffectCount()>0){
if(!effects.empty() || !tags.empty()){
str+= lang.getString("AffectedUnits",(translatedValue == true ? "" : "english"))+"\n";
for(int i=0; i<getEffectCount(); ++i){
str+= indent+getEffect(i)->getName(translatedValue)+"\n";
// We want the output to be sorted, so convert the set to a vector and sort that
std::vector<const UnitType*> outputUnits(effects.begin(), effects.end());
std::sort(outputUnits.begin(), outputUnits.end(), UnitTypeSorter());
vector<const UnitType*>::iterator unitIter;
for (unitIter = outputUnits.begin(); unitIter != outputUnits.end(); ++unitIter) {
const UnitType *unit = *unitIter;
str+= indent+unit->getName(translatedValue)+"\n";
}
// Do the same for tags
std::vector<string> outputTags(tags.begin(), tags.end());
std::sort(outputTags.begin(), outputTags.end());
vector<string>::iterator tagIter;
for (tagIter = outputTags.begin(); tagIter != outputTags.end(); ++tagIter) {
string tag = *tagIter;
str+= indent + lang.getString("TagDesc", (translatedValue == true ? "" : "english")) +
" " + getTagName(tag,translatedValue) + "\n";
}
}
return str;
@ -757,29 +783,24 @@ void UpgradeType::load(const string &dir, const TechTree *techTree,
sortedItems.clear();
hasDup = false;
//effects
//effects -- get list of affected units
const XmlNode *effectsNode= upgradeNode->getChild("effects");
for(int i = 0; i < (int)effectsNode->getChildCount(); ++i) {
const XmlNode *unitNode= effectsNode->getChild("unit", i);
vector<XmlNode*> unitNodes= effectsNode->getChildList("unit");
for(size_t i = 0; i < unitNodes.size(); ++i) {
const XmlNode *unitNode= unitNodes.at(i);
string name= unitNode->getAttribute("name")->getRestrictedValue();
if(sortedItems.find(name) != sortedItems.end()) {
hasDup = true;
}
sortedItems[name] = 0;
effects.insert(factionType->getUnitType(name));
}
if(hasDup) {
printf("WARNING, upgrade type [%s] has one or more duplicate effects\n",this->getName().c_str());
//effects -- convert tags into units
vector<XmlNode*> tagNodes= effectsNode->getChildList("tag");
for(size_t i = 0; i < tagNodes.size(); ++i) {
const XmlNode *tagNode= tagNodes.at(i);
string name= tagNode->getAttribute("name")->getRestrictedValue();
tags.insert(name);
}
for(std::map<string,int>::iterator iterMap = sortedItems.begin();
iterMap != sortedItems.end(); ++iterMap) {
effects.push_back(factionType->getUnitType(iterMap->first));
}
sortedItems.clear();
//values
UpgradeTypeBase::load(upgradeNode,name);
}
@ -792,7 +813,15 @@ void UpgradeType::load(const string &dir, const TechTree *techTree,
}
bool UpgradeType::isAffected(const UnitType *unitType) const{
return find(effects.begin(), effects.end(), unitType)!=effects.end();
if(std::find(effects.begin(), effects.end(), unitType)!=effects.end()) return true;
const set<string> unitTags = unitType->getTags();
set<string> intersect;
set_intersection(tags.begin(),tags.end(),unitTags.begin(),unitTags.end(),
std::inserter(intersect,intersect.begin()));
if(!intersect.empty()) return true;
return false;
}
//void UpgradeType::saveGame(XmlNode *rootNode) const {

View File

@ -30,6 +30,7 @@
#include "conversion.h"
#include "xml_parser.h"
#include "leak_dumper.h"
#include <set>
using Shared::Util::Checksum;
using namespace Shared::Util;
@ -266,9 +267,10 @@ public:
class UpgradeType: public UpgradeTypeBase, public ProducibleType {
private:
/**
* List of unit types (the "classes" of units, eg, swordman) that are affected by this upgrade.
*/
vector<const UnitType*> effects;
* Set of unit types (the "classes" of units, eg, swordman) that are affected by this upgrade.
*/
std::set<const UnitType*> effects;
std::set<string> tags;
public:
/**
@ -301,17 +303,7 @@ public:
* appears in the XMLs.
*/
virtual string getName(bool translatedValue=false) const;
/**
* Returns the number of UnitTypes affected by this upgrade.
*/
int getEffectCount() const {return (int)effects.size();}
/**
* Returns a particular unit type affected by this upgrade.
* @param i Index of the unit type in the #effects list.
*/
const UnitType * getEffect(int i) const {return effects[i];}
string getTagName(string tag, bool translatedValue=false) const;
/**
* Determines if a unit is affected by this upgrade.