result_type operator() (const ResourceInfo::BaseNode& node) { info.rawHappy = node.baseHappy; for (size_t i = 0, count = node.buildingNodes.size(); i < count; ++i) { (*this)(node.buildingNodes[i]); } CityIter iter(CvPlayerAI::getPlayer(playerType_)); CvCity* pLoopCity; // how many citizens are made happy now if we had the resource, how many would be happy if we had the requisite buildings, // and how many more could be made happy with the buildings we have. // E.g. suppose we have 1 unhappy citizen in a city, with a forge - and we analyse gold - this would give: // actualHappy = 1, potentialHappy = 0, unusedHappy = 1, but if the city had no forge, it should give: // actualHappy = 1, potentialHappy = 1, unusedHappy = 0 int actualHappy = 0, potentialHappy = 0, unusedHappy = 0; while (pLoopCity = iter()) { int unhappyCitizens = std::max<int>(0, pLoopCity->unhappyLevel() - pLoopCity->happyLevel()); int baseHappy = std::min<int>(node.baseHappy, unhappyCitizens); // have we got any left? unhappyCitizens = std::max<int>(0, unhappyCitizens - baseHappy); if (unhappyCitizens == 0) { unusedHappy += node.baseHappy - baseHappy; } actualHappy += baseHappy; for (size_t i = 0, count = info.buildingHappy.size(); i < count; ++i) { int buildingCount = pLoopCity->getNumBuilding(info.buildingHappy[i].first); if (buildingCount > 0) { int thisBuildingCount = std::min<int>(buildingCount * info.buildingHappy[i].second, unhappyCitizens); unhappyCitizens = std::max<int>(0, unhappyCitizens - thisBuildingCount); if (unhappyCitizens == 0) { unusedHappy += buildingCount * info.buildingHappy[i].second - thisBuildingCount; } actualHappy += thisBuildingCount; } else // just assumes one building allowed (should use getCITY_MAX_NUM_BUILDINGS(), but this would be wrong if building is limited in some other way, e.g. wonders) { potentialHappy += info.buildingHappy[i].second; } } } info.actualHappy = actualHappy; info.potentialHappy = potentialHappy; info.unusedHappy = unusedHappy; }
result_type operator() (const ResourceInfo::BaseNode& node) { info.rawHealth = node.baseHealth; for (size_t i = 0, count = node.buildingNodes.size(); i < count; ++i) { (*this)(node.buildingNodes[i]); } CityIter iter(CvPlayerAI::getPlayer(playerType_)); CvCity* pLoopCity; int actualHealth = 0, potentialHealth = 0, unusedHealth = 0; while (pLoopCity = iter()) { int unhealthyCitizens = pLoopCity->healthRate(); int baseHealth = std::min<int>(node.baseHealth, unhealthyCitizens); // have we got any left? unhealthyCitizens = std::max<int>(0, unhealthyCitizens - baseHealth); if (unhealthyCitizens == 0) { unusedHealth += node.baseHealth - baseHealth; } actualHealth += baseHealth; for (size_t i = 0, count = info.buildingHealth.size(); i < count; ++i) { int buildingCount = pLoopCity->getNumBuilding(info.buildingHealth[i].first); if (buildingCount > 0) { int thisBuildingCount = std::min<int>(buildingCount * info.buildingHealth[i].second, unhealthyCitizens); unhealthyCitizens = std::max<int>(0, unhealthyCitizens - thisBuildingCount); if (unhealthyCitizens == 0) { unusedHealth += buildingCount * info.buildingHealth[i].second - thisBuildingCount; } actualHealth += thisBuildingCount; } else // just assumes one building allowed { potentialHealth += info.buildingHealth[i].second; } } } info.actualHealth = actualHealth; info.potentialHealth = potentialHealth; info.unusedHealth = unusedHealth; }
bool operator() (const UnitInfo::BaseNode& node) const { #ifdef ALTAI_DEBUG //std::ostream& os = CivLog::getLog(*player_.getCvPlayer())->getStream(); #endif // includes great people if (node.cost < 0) { // do great people if city can produce the right type of great people points from specialists return false; } for (size_t i = 0, count = node.techTypes.size(); i < count; ++i) { // if we don't we have the tech and its depth is deeper than our lookaheadDepth, return false if (!civHelper_->hasTech(node.techTypes[i]) && (lookaheadDepth_ == 0 || pAnalysis_->getTechResearchDepth(node.techTypes[i]) > lookaheadDepth_)) { return false; } } for (size_t i = 0, count = node.nodes.size(); i < count; ++i) { if (!boost::apply_visitor(*this, node.nodes[i])) { return false; } } if (node.specialUnitType != NO_SPECIALUNIT) { if (!gGlobals.getGame().isSpecialUnitValid(node.specialUnitType)) { return false; } } // todo - add religion and any other checks bool passedAreaCheck = node.minAreaSize < 0, passedBonusCheck = ignoreRequiredResources_ || (node.andBonusTypes.empty() && node.orBonusTypes.empty()); bool passedBuildingCheck = node.prereqBuildingType == NO_BUILDING; if (!passedBuildingCheck) { SpecialBuildingTypes specialBuildingType = (SpecialBuildingTypes)gGlobals.getBuildingInfo(node.prereqBuildingType).getSpecialBuildingType(); if (specialBuildingType != NO_SPECIALBUILDING) { passedBuildingCheck = player_.getCivHelper()->getSpecialBuildingNotRequiredCount(specialBuildingType) > 0; } } #ifdef ALTAI_DEBUG //os << "\narea check = " << passedAreaCheck << ", bonus check = " << passedBonusCheck << ", building check = " << passedBuildingCheck; #endif CityIter cityIter(*player_.getCvPlayer()); CvCity* pCity; while (pCity = cityIter()) { if (!passedAreaCheck) { if (node.domainType == DOMAIN_SEA) { if (pCity->isCoastal(node.minAreaSize)) { passedAreaCheck = true; } } else if (node.domainType == DOMAIN_LAND) { if (pCity->area()->getNumTiles() >= node.minAreaSize) { passedAreaCheck = true; } } } if (!passedBonusCheck) { bool foundAllAndBonuses = true, foundOrBonus = node.orBonusTypes.empty(); for (size_t i = 0, count = node.andBonusTypes.size(); i < count; ++i) { if (!pCity->hasBonus(node.andBonusTypes[i])) { foundAllAndBonuses = false; break; } } if (foundAllAndBonuses) { for (size_t i = 0, count = node.orBonusTypes.size(); i < count; ++i) { if (pCity->hasBonus(node.orBonusTypes[i])) { foundOrBonus = true; break; } } if (foundOrBonus) { passedBonusCheck = true; } } } if (!passedBuildingCheck) { passedBuildingCheck = pCity->getNumBuilding(node.prereqBuildingType) > 0; } } return passedAreaCheck && passedBonusCheck && passedBuildingCheck; }