Code
1190void CvHomelandAI::PlotOpportunisticSettlementMoves()1191{1192 const char* szCiv = m_pPlayer->getCivilizationTypeKey();11931194 int iMinHappiness = gCustomMods.getCivOption(szCiv, "SECONDARY_SETTLERS_MIN_HAPPINESS", 5);1195 int iMinTurnsSinceLastCity = gCustomMods.getCivOption(szCiv, "SECONDARY_SETTLERS_MIN_TURNS_SINCE_LAST_CITY", 10);1196 int iMinRevealedTilesThisLandmass = gCustomMods.getCivOption(szCiv, "SECONDARY_SETTLERS_MIN_REVEALED_TILES", 10);1197 int iMaxDistance = gCustomMods.getCivOption(szCiv, "SECONDARY_SETTLERS_MAX_DISTANCE", 10);1198 int iMaxPlotsToConsider = gCustomMods.getCivOption(szCiv, "SECONDARY_SETTLERS_MAX_PLOTS_CONSIDER", 3);1199 int iMaxSettleDistance = gCustomMods.getCivOption(szCiv, "SECONDARY_SETTLERS_MAX_SETTLE_DISTANCE", 1);1200 int iMaxTravelDistance = gCustomMods.getCivOption(szCiv, "SECONDARY_SETTLERS_MAX_TRAVEL_DISTANCE", 3);12011202 int iCapitalX = m_pPlayer->getCapitalCity()->getX();1203 int iCapitalY = m_pPlayer->getCapitalCity()->getY();12041205 CvUnit* pLoopUnit;12061207 if (m_pPlayer->GetHappiness() <= iMinHappiness) {1208 return;1209 }1210 1211 if (m_pPlayer->GetTurnsSinceSettledLastCity() <= iMinTurnsSinceLastCity) {1212 return;1213 }1214 1215 int iLoop;1216 for (pLoopUnit = m_pPlayer->firstUnit(&iLoop); pLoopUnit != NULL; pLoopUnit = m_pPlayer->nextUnit(&iLoop)) {1217 if (!pLoopUnit->IsCombatUnit() && pLoopUnit->isFound()) {1218 return;1219 }1220 }1221 1222 // Make a list of all combat units that are on a landmass of a suitable size and could found a city at their current plot1223 MoveUnitsArray PossibleSettlerUnits;1224 for (list<int>::iterator it = m_CurrentTurnUnits.begin(); it != m_CurrentTurnUnits.end(); ++it) {1225 UnitHandle pUnit = m_pPlayer->getUnit(*it);1226 if (pUnit) {1227 if (pUnit->IsCombatUnit() && GC.getMap().getArea(pUnit->getArea())->getNumRevealedTiles(m_pPlayer->getTeam()) > iMinRevealedTilesThisLandmass && pUnit->canFound(pUnit->plot())) {1228 CvHomelandUnit unit;1229 unit.SetID(pUnit->GetID());1230 unit.SetAuxIntData(plotDistance(pUnit->getX(), pUnit->getY(), iCapitalX, iCapitalY));1231 PossibleSettlerUnits.push_back(unit);1232 }1233 }1234 }1235 1236 // Sort them by proximity to the capital1237 std::stable_sort(PossibleSettlerUnits.begin(), PossibleSettlerUnits.end(), HomelandAIHelpers::CvHomelandUnitAuxIntSort);1238 1239 if (PossibleSettlerUnits.size() > 0) {1240 // CUSTOMLOG("%i possible units for opportunistic settlement", PossibleSettlerUnits.size());1241 CvMap& kMap = GC.getMap();1242 TeamTypes eUnitTeam = m_pPlayer->getTeam();12431244 FStaticVector< CvHomelandUnit, 64, true, c_eCiv5GameplayDLL >::iterator settlerUnitIt;1245 for (settlerUnitIt = PossibleSettlerUnits.begin(); settlerUnitIt != PossibleSettlerUnits.end(); ++settlerUnitIt) {1246 UnitHandle pUnit = m_pPlayer->getUnit(settlerUnitIt->GetID());1247 int iArea = pUnit->getArea();1248 int iUnitX = pUnit->getX();1249 int iUnitY = pUnit->getY();1250 // CUSTOMLOG(" ... for unit at (%i, %i)", iUnitX, iUnitY);12511252 // Find the best locations on the landmass (within X tiles of the unit)1253 WeightedFoundPlotVector aBestPlots;1254 aBestPlots.reserve((iMaxDistance+1) * 2);12551256 for (int iPlotX = iUnitX-iMaxDistance; iPlotX != iUnitX+iMaxDistance; iPlotX++) {1257 for (int iPlotY = iUnitY-iMaxDistance; iPlotY != iUnitY+iMaxDistance; iPlotY++) {1258 CvPlot* pPlot = kMap.plot(iPlotX, iPlotY);1259 if (!pPlot) continue;1260 if (pPlot->getArea() != iArea) continue;1261 if (!pPlot->isRevealed(eUnitTeam)) continue;1262 if (!m_pPlayer->canFound(iPlotX, iPlotY)) continue;12631264 aBestPlots.push_back(pPlot, m_pPlayer->AI_foundValue(iPlotX, iPlotY, -1, false));1265 }1266 }12671268 if (aBestPlots.size() > 0) {1269 int iMaxPlots = std::min(iMaxPlotsToConsider, aBestPlots.size());1270 // CUSTOMLOG(" ... found %i possible plots, considering the first %i", aBestPlots.size(), iMaxPlots);12711272 aBestPlots.SortItems();12731274 // For the first N locations, can the unit reach it in less than one turn (ie move to the plot and found the city as one turn)1275 for (int i = 0; i < iMaxPlots; ++i ) {1276 int iPathTurns;1277 CvPlot* pFoundPlot = aBestPlots.GetElement(i);1278 // CUSTOMLOG(" ... possible city plot at (%i, %i)", pFoundPlot->getX(), pFoundPlot->getY());1279 bool bCanFindPath = pUnit->GeneratePath(pFoundPlot, MOVE_TERRITORY_NO_UNEXPLORED, true, &iPathTurns);12801281 if (bCanFindPath) {1282 // CUSTOMLOG(" ... is %i moves away", iPathTurns)1283 1284 if (iPathTurns <= iMaxSettleDistance) {1285 // CUSTOMLOG(" ... here comes the city!")1286 // If so, move to the plot, found the city and bail out of this method1287 pUnit->setXY(pFoundPlot->getX(), pFoundPlot->getY());1288 pUnit->PushMission(CvTypes::getMISSION_FOUND());1289 UnitProcessed(pUnit->GetID());1290 return;1291 } else if (iPathTurns <= iMaxTravelDistance) {1292 // CUSTOMLOG(" ... moving towards the city site!")1293 pUnit->PushMission(CvTypes::getMISSION_MOVE_TO(), pFoundPlot->getX(), pFoundPlot->getY());1294 UnitProcessed(pUnit->GetID());1295 }1296 }1297 }1298 }1299 }1300 }1301}