PHP-Code:
void CvCityAI::AI_chooseProduction()
{
PROFILE_FUNC();
CvArea* pWaterArea;
UnitTypes eProductionUnit;
bool bWasFoodProduction;
bool bHasMetHuman;
bool bLandWar;
bool bAssault;
bool bDefenseWar;
bool bPrimaryArea;
bool bFinancialTrouble;
bool bDanger;
bool bChooseUnit;
int iProductionRank;
int iCulturePressure;
bDanger = AI_isDanger();
CvPlayerAI& kPlayer = GET_PLAYER(getOwnerINLINE());
if (isProduction())
{
if (getProduction() > 0)
{
if ((getProductionUnitAI() == UNITAI_SETTLE) && kPlayer.AI_isFinancialTrouble())
{
}
//if we are killing our growth to train this, then finish it.
else if (!bDanger && isFoodProduction())
{
if ((area()->getAreaAIType(getTeam()) != AREAAI_DEFENSIVE))
{
return;
}
}
// if less than 3 turns left, keep building current item
else if (getProductionTurnsLeft() <= 3)
{
return;
}
// if building a combat unit, and we have no defenders, keep building it
eProductionUnit = getProductionUnit();
if (eProductionUnit != NO_UNIT)
{
if (plot()->getNumDefenders(getOwnerINLINE()) == 0)
{
if (GC.getUnitInfo(eProductionUnit).getCombat() > 0)
{
return;
}
}
}
// if we are building a wonder, do not cancel, keep building it (if no danger)
BuildingTypes eProductionBuilding = getProductionBuilding();
if (!bDanger && eProductionBuilding != NO_BUILDING &&
isLimitedWonderClass((BuildingClassTypes) GC.getBuildingInfo(eProductionBuilding).getBuildingClassType()))
{
return;
}
}
clearOrderQueue();
}
if (GET_PLAYER(getOwner()).isAnarchy())
{
return;
}
// only clear the dirty bit if we actually do a check, multiple items might be queued
AI_setChooseProductionDirty(false);
// allow python to handle it
CyCity* pyCity = new CyCity(this);
CyArgsList argsList;
argsList.add(gDLL->getPythonIFace()->makePythonObject(pyCity)); // pass in city class
long lResult=0;
gDLL->getPythonIFace()->callFunction(PYGameModule, "AI_chooseProduction", argsList.makeFunctionArgs(), &lResult);
delete pyCity; // python fxn must not hold on to this pointer
if (lResult == 1)
{
return;
}
if (isHuman() && isProductionAutomated())
{
AI_buildGovernorChooseProduction();
return;
}
CvArea* pArea = area();
pWaterArea = waterArea();
bool bMaybeWaterArea = false;
if (pWaterArea != NULL)
{
bMaybeWaterArea = true;
if (!GET_TEAM(getTeam()).AI_isWaterAreaRelevant(pWaterArea))
{
pWaterArea = NULL;
}
}
bWasFoodProduction = isFoodProduction();
bHasMetHuman = GET_TEAM(getTeam()).hasMetHuman();
bLandWar = ((pArea->getAreaAIType(getTeam()) == AREAAI_OFFENSIVE) || (pArea->getAreaAIType(getTeam()) == AREAAI_DEFENSIVE) || (pArea->getAreaAIType(getTeam()) == AREAAI_MASSING));
bDefenseWar = (pArea->getAreaAIType(getTeam()) == AREAAI_DEFENSIVE);
bool bAssaultAssist = (pArea->getAreaAIType(getTeam()) == AREAAI_ASSAULT_ASSIST);
bAssault = bAssaultAssist || (pArea->getAreaAIType(getTeam()) == AREAAI_ASSAULT) || (pArea->getAreaAIType(getTeam()) == AREAAI_ASSAULT_MASSING);
bPrimaryArea = kPlayer.AI_isPrimaryArea(pArea);
bFinancialTrouble = kPlayer.AI_isFinancialTrouble();
iCulturePressure = AI_calculateCulturePressure();
int iNumCitiesInArea = pArea->getCitiesPerPlayer(getOwnerINLINE());
bool bImportantCity = false; //be very careful about setting this.
bool bBigCultureCity = false;
int iCultureRateRank = findCommerceRateRank(COMMERCE_CULTURE);
int iCulturalVictoryNumCultureCities = GC.getGameINLINE().culturalVictoryNumCultureCities();
bool bGetBetterUnits = kPlayer.AI_isDoStrategy(AI_STRATEGY_GET_BETTER_UNITS);
bool bAggressiveAI = GC.getGameINLINE().isOption(GAMEOPTION_AGGRESSIVE_AI);
bool bAlwaysPeace = GC.getGameINLINE().isOption(GAMEOPTION_ALWAYS_PEACE);
int iUnitCostPercentage = (kPlayer.calculateUnitCost() * 100) / std::max(1, kPlayer.calculatePreInflatedCosts());
int iWaterPercent = AI_calculateWaterWorldPercent();
int iBuildUnitProb = AI_buildUnitProb();
int iExistingWorkers = kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_WORKER);
int iNeededWorkers = kPlayer.AI_neededWorkers(pArea);
int iNeededSeaWorkers = (pWaterArea == NULL) ? 0 : AI_neededSeaWorkers();
int iTargetCulturePerTurn = AI_calculateTargetCulturePerTurn();
int iAreaBestFoundValue;
int iNumAreaCitySites = kPlayer.AI_getNumAreaCitySites(getArea(), iAreaBestFoundValue);
int iWaterAreaBestFoundValue = 0;
int iNumWaterAreaCitySites = (pWaterArea == NULL) ? 0 : kPlayer.AI_getNumAdjacentAreaCitySites(pWaterArea->getID(), getArea(), iWaterAreaBestFoundValue);
int iNumSettlers = kPlayer.AI_totalUnitAIs(UNITAI_SETTLE);
bool bIsCapitalArea = false;
int iNumCapitalAreaCities = 0;
if (kPlayer.getCapitalCity() != NULL)
{
iNumCapitalAreaCities = kPlayer.getCapitalCity()->area()->getCitiesPerPlayer(getOwnerINLINE());
if (getArea() == kPlayer.getCapitalCity()->getArea())
{
bIsCapitalArea = true;
}
}
int iMaxSettlers = 0;
if (!bFinancialTrouble)
{
iMaxSettlers= std::min((kPlayer.getNumCities() + 1) / 2, iNumAreaCitySites + iNumWaterAreaCitySites);
if (bLandWar || bAssault)
{
iMaxSettlers = (iMaxSettlers + 2) / 3;
}
}
bool bChooseWorker = false;
int iEconomyFlags = 0;
iEconomyFlags |= BUILDINGFOCUS_PRODUCTION;
iEconomyFlags |= BUILDINGFOCUS_GOLD;
iEconomyFlags |= BUILDINGFOCUS_RESEARCH;
iEconomyFlags |= BUILDINGFOCUS_MAINTENANCE;
iEconomyFlags |= BUILDINGFOCUS_HAPPY;
iEconomyFlags |= BUILDINGFOCUS_HEALTHY;
if (AI_isEmphasizeGreatPeople())
{
iEconomyFlags |= BUILDINGFOCUS_SPECIALIST;
}
if (!GC.getGameINLINE().isOption(GAMEOPTION_NO_ESPIONAGE))
{
iEconomyFlags |= BUILDINGFOCUS_ESPIONAGE;
}
if (iNumCitiesInArea > 2)
{
if (kPlayer.AI_isDoStrategy(AI_STRATEGY_CULTURE2))
{
if (iCultureRateRank <= iCulturalVictoryNumCultureCities + 1)
{
bBigCultureCity = true;
// if we do not have enough cities, then the highest culture city will not get special attention
if (iCultureRateRank > 1 || (kPlayer.getNumCities() > (iCulturalVictoryNumCultureCities + 1)))
{
if ((((iNumAreaCitySites + iNumWaterAreaCitySites) > 0) && (kPlayer.getNumCities() < 6)) && (GC.getGameINLINE().getSorenRandNum(2, "AI Less Culture More Expand") == 0))
{
bImportantCity = false;
}
else
{
bImportantCity = true;
}
}
}
}
}
iProductionRank = findYieldRateRank(YIELD_PRODUCTION);
clearOrderQueue();
if (bWasFoodProduction)
{
AI_assignWorkingPlots();
}
// if we need to pop borders, then do that immediately if we have drama and can do it
if ((iTargetCulturePerTurn > 0) && (getCultureLevel() <= (CultureLevelTypes) 1))
{
if (AI_chooseProcess(COMMERCE_CULTURE))
{
return;
}
}
// if we just captured this city, dont build a unit first
if (isOccupation())
{
// pick granary or lighthouse, any duration
if (AI_chooseBuilding(BUILDINGFOCUS_FOOD))
{
return;
}
// try picking forge, etc, any duration
if (AI_chooseBuilding(BUILDINGFOCUS_PRODUCTION))
{
return;
}
// just pick any building, any duration
if (AI_chooseBuilding())
{
return;
}
}
if (plot()->getNumDefenders(getOwnerINLINE()) == 0) // XXX check for other team's units?
{
if (AI_chooseUnit(UNITAI_CITY_DEFENSE))
{
return;
}
if (AI_chooseUnit(UNITAI_CITY_COUNTER))
{
return;
}
if (AI_chooseUnit(UNITAI_CITY_SPECIAL))
{
return;
}
if (AI_chooseUnit(UNITAI_ATTACK))
{
return;
}
}
if (isBarbarian())
{
if (!AI_isDefended(plot()->plotCount(PUF_isUnitAIType, UNITAI_ATTACK, -1, getOwnerINLINE()))) // XXX check for other team's units?
{
if (AI_chooseDefender())
{
return;
}
if (AI_chooseUnit(UNITAI_ATTACK))
{
return;
}
}
if (!bDanger && (iNeededWorkers > 0) && (AI_getWorkersNeeded() > 0) && (AI_getWorkersHave() == 0))
{
if (AI_chooseUnit(UNITAI_WORKER))
{
return;
}
}
if (!bDanger && (iNeededSeaWorkers > 0))
{
if (AI_chooseUnit(UNITAI_WORKER_SEA))
{
return;
}
}
bChooseUnit = false;
if (GC.getGameINLINE().getSorenRandNum(100, "AI Build Unit Production") > AI_buildUnitProb())
{
int iBarbarianFlags = 0;
iBarbarianFlags |= BUILDINGFOCUS_FOOD;
iBarbarianFlags |= BUILDINGFOCUS_PRODUCTION;
iBarbarianFlags |= BUILDINGFOCUS_EXPERIENCE;
if (AI_chooseBuilding(iBarbarianFlags))
{
return;
}
if (AI_chooseBuilding())
{
return;
}
}
if (plot()->plotCount(PUF_isUnitAIType, UNITAI_ASSAULT_SEA, -1, getOwnerINLINE()) > 0)
{
if (AI_chooseUnit(UNITAI_ATTACK_CITY))
{
return;
}
}
if ((pWaterArea != NULL) && (iWaterPercent > 30))
{
if (GC.getGameINLINE().getSorenRandNum(2, "AI Coast Raiders!") == 0)
{
if (kPlayer.AI_getNumAIUnits(UNITAI_ASSAULT_SEA) <= (1 + kPlayer.getNumCities() / 2))
{
if (AI_chooseUnit(UNITAI_ASSAULT_SEA))
{
return;
}
}
}
if (GC.getGameINLINE().getSorenRandNum(110, "AI arrrr!") < (iWaterPercent + 10))
{
if (kPlayer.AI_getNumAIUnits(UNITAI_PIRATE_SEA) <= kPlayer.getNumCities())
{
if (AI_chooseUnit(UNITAI_PIRATE_SEA))
{
return;
}
}
if (kPlayer.AI_totalAreaUnitAIs(pWaterArea, UNITAI_ATTACK_SEA) < iNumCitiesInArea)
{
if (AI_chooseUnit(UNITAI_ATTACK_SEA))
{
return;
}
}
}
}
if (AI_chooseUnit())
{
return;
}
return;
}
if (((iTargetCulturePerTurn > 0) || (getPopulation() > 5)) && (getCommerceRate(COMMERCE_CULTURE) == 0))
{
if (AI_chooseBuilding(BUILDINGFOCUS_CULTURE, 30))
{
return;
}
}
if ((iExistingWorkers == 0) && (!bDanger) && ((AI_getWorkersNeeded() > 0) || ((isCapital() && (GC.getGame().getElapsedGameTurns() < ((30 * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent()) / 100))))))
{
int iLandBonuses = AI_countNumBonuses(NO_BONUS, /*bIncludeOurs*/ true, /*bIncludeNeutral*/ true, -1, /*bLand*/ true, /*bWater*/ false);
if ((iLandBonuses > 1) || (getPopulation() > 3))
{
if (!bChooseWorker && AI_chooseUnit(UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
if ((iNeededSeaWorkers > 0) && (getPopulation() < 3))
{
if (AI_chooseUnit(UNITAI_WORKER_SEA))
{
return;
}
}
if ((iLandBonuses == 1) || (AI_getWorkersNeeded() > 0))
{
if (!bChooseWorker && AI_chooseUnit(UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
}
int iPercentOfDomination = 0;
int iOurPopPercent = 100 * GET_TEAM(getTeam()).getTotalPopulation() / std::max(1, GC.getGameINLINE().getTotalPopulation());
for (int iI = 0; iI < GC.getNumVictoryInfos(); iI++)
{
if (GC.getVictoryInfo((VictoryTypes)iI).getPopulationPercentLead() > 0)
{
iPercentOfDomination = 100 * iOurPopPercent / std::max(1, GC.getGameINLINE().getAdjustedPopulationPercent((VictoryTypes)iI));
}
}
if (iPercentOfDomination >= 90)
{
if ((goodHealth() - badHealth(true, 0)) < 1)
{
if (AI_chooseBuilding(BUILDINGFOCUS_HEALTHY))
{
return;
}
}
}
if (bDanger && kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK) < 2)
{
if (AI_chooseUnit(UNITAI_ATTACK))
{
return;
}
}
if (bMaybeWaterArea)
{
if (kPlayer.AI_getNumTrainAIUnits(UNITAI_ATTACK_SEA) + kPlayer.AI_getNumTrainAIUnits(UNITAI_PIRATE_SEA) + kPlayer.AI_getNumTrainAIUnits(UNITAI_RESERVE_SEA) < 3)
{
if ((bMaybeWaterArea && kPlayer.AI_getWaterDanger(plot(), 4) > 0)
|| (pWaterArea != NULL && bPrimaryArea && kPlayer.AI_countNumAreaHostileUnits(pWaterArea, true, false, false, false) > 0))
{
if (AI_chooseUnit(UNITAI_ATTACK_SEA))
{
return;
}
if (AI_chooseUnit(UNITAI_PIRATE_SEA))
{
return;
}
if (AI_chooseUnit(UNITAI_RESERVE_SEA))
{
return;
}
}
}
if (NULL != pWaterArea)
{
if (iAreaBestFoundValue == 0 || iWaterAreaBestFoundValue > iAreaBestFoundValue
|| (iWaterPercent > 60 && GC.getGameINLINE().getSorenRandNum(4, "AI Train Early Sea Explore or Settler") == 0))
{
if (kPlayer.AI_totalWaterAreaUnitAIs(pWaterArea, UNITAI_EXPLORE_SEA) == 0)
{
if (AI_chooseUnit(UNITAI_EXPLORE_SEA))
{
return;
}
}
if (kPlayer.AI_totalWaterAreaUnitAIs(pWaterArea, UNITAI_SETTLER_SEA) == 0)
{
if (AI_chooseUnit(UNITAI_SETTLER_SEA))
{
return;
}
}
}
}
}
if ((getDomainFreeExperience(DOMAIN_LAND) == 0) && (getYieldRate(YIELD_PRODUCTION) > 4))
{
if (AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, (kPlayer.getCurrentEra() > 1) ? 0 : 7, 33))
{
return;
}
}
int iPlotSettlerCount = (iNumSettlers == 0) ? 0 : plot()->plotCount(PUF_isUnitAIType, UNITAI_SETTLE, -1, getOwnerINLINE());
int iPlotCityDefenderCount = plot()->plotCount(PUF_isUnitAIType, UNITAI_CITY_DEFENSE, -1, getOwnerINLINE());
//minimal defense.
if (iPlotCityDefenderCount <= iPlotSettlerCount)
{
if (AI_chooseUnit(UNITAI_CITY_DEFENSE))
{
return;
}
}
if (!bPrimaryArea)
{
if (AI_chooseBuilding(BUILDINGFOCUS_FOOD, 60, 10))
{
return;
}
}
if (!bDanger && ((kPlayer.getCurrentEra() > (GC.getGame().getStartEra() + iProductionRank / 2))) || (kPlayer.getCurrentEra() > (GC.getNumEraInfos() / 2)))
{
if (AI_chooseBuilding(BUILDINGFOCUS_PRODUCTION, 20, 15))
{
return;
}
if ((iExistingWorkers < ((iNeededWorkers + 1) / 2)))
{
if (!bChooseWorker && AI_chooseUnit(UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
}
bool bCrushStrategy = kPlayer.AI_isDoStrategy(AI_STRATEGY_CRUSH);
int iNeededFloatingDefenders = (isBarbarian() || bCrushStrategy) ? 0 : kPlayer.AI_getTotalFloatingDefendersNeeded(pArea);
int iTotalFloatingDefenders = (isBarbarian() ? 0 : kPlayer.AI_getTotalFloatingDefenders(pArea));
UnitTypeWeightArray floatingDefenderTypes;
floatingDefenderTypes.push_back(std::make_pair(UNITAI_CITY_DEFENSE, 125));
floatingDefenderTypes.push_back(std::make_pair(UNITAI_CITY_COUNTER, 100));
//floatingDefenderTypes.push_back(std::make_pair(UNITAI_CITY_SPECIAL, 0));
floatingDefenderTypes.push_back(std::make_pair(UNITAI_RESERVE, 100));
floatingDefenderTypes.push_back(std::make_pair(UNITAI_COLLATERAL, 100));
if (iTotalFloatingDefenders < ((iNeededFloatingDefenders + 1) / (bGetBetterUnits ? 3 : 2)))
{
if (AI_chooseLeastRepresentedUnit(floatingDefenderTypes))
{
return;
}
}
if (!(iExistingWorkers == 0))
{
if (!bDanger && (iExistingWorkers < ((iNeededWorkers + 1) / 2)))
{
if (!bChooseWorker && AI_chooseUnit(UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
}
//do a check for one tile island type thing?
//this can be overridden by "wait and grow more"
if (bDanger && (iExistingWorkers == 0) && (isCapital() || (iNeededWorkers > 0) || (iNeededSeaWorkers > 0)))
{
if ((AI_countNumBonuses(NO_BONUS, /*bIncludeOurs*/ true, /*bIncludeNeutral*/ true, -1, /*bLand*/ true, /*bWater*/ false) > 0) ||
(isCapital() && (getPopulation() > 3)))
{
if (!bChooseWorker && AI_chooseUnit(UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
if (iNeededSeaWorkers > 0)
{
if (AI_chooseUnit(UNITAI_WORKER_SEA))
{
return;
}
}
}
if (pWaterArea != NULL)
{
if (iNeededSeaWorkers > 0)
{
if (kPlayer.AI_totalWaterAreaUnitAIs(pWaterArea, UNITAI_WORKER_SEA) < iNeededSeaWorkers)
{
if (AI_chooseUnit(UNITAI_WORKER_SEA))
{
return;
}
}
}
}
if (!bLandWar && !bAssault && (iTargetCulturePerTurn > getCommerceRate(COMMERCE_CULTURE)))
{
if (GC.getGameINLINE().getSorenRandNum(bAggressiveAI ? 3 : 2, "AI Culture Build") == 0)
{
if (AI_chooseBuilding(BUILDINGFOCUS_CULTURE, bAggressiveAI ? 10 : 20))
{
return;
}
}
}
int iMinFoundValue = kPlayer.AI_getMinFoundValue();
if (bDanger)
{
iMinFoundValue *= 3;
iMinFoundValue /= 2;
}
if (!bGetBetterUnits && (bIsCapitalArea) && (iAreaBestFoundValue < (iMinFoundValue * 2)))
{
//Building an early city hunting stack.
int iAttackCityCount = kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK);
if (iAttackCityCount > 0)
{
if (iAttackCityCount < (3 + iBuildUnitProb / 10))
{
if (AI_chooseUnit(UNITAI_ATTACK))
{
return;
}
}
}
else
{
int iStartAttackStackRand = 0;
if (pArea->getCitiesPerPlayer(BARBARIAN_PLAYER))
{
iStartAttackStackRand += 15;
}
if ((pArea->getNumCities() - iNumCitiesInArea) > 0)
{
iStartAttackStackRand += iBuildUnitProb / 2;
}
if (GC.getGame().getSorenRandNum(100, "AI start city attack stack") <= iStartAttackStackRand)
{
if (AI_chooseUnit(UNITAI_ATTACK))
{
return;
}
}
}
}
//oppurunistic wonder build (1)
if (!bDanger && (!hasActiveWorldWonder()) && (kPlayer.getNumCities() <= 3))
{
int iWonderTime = GC.getGameINLINE().getSorenRandNum(GC.getLeaderHeadInfo(getPersonalityType()).getWonderConstructRand(), "Wonder Construction Rand");
iWonderTime /= 5;
iWonderTime += 7;
if (AI_chooseBuilding(BUILDINGFOCUS_WORLDWONDER, iWonderTime))
{
return;
}
}
if (!bDanger && !bIsCapitalArea && area()->getCitiesPerPlayer(getOwnerINLINE()) > iNumCapitalAreaCities)
{
if (AI_chooseBuilding(BUILDINGFOCUS_CAPITAL, 15))
{
return;
}
}
if (AI_chooseBuilding(BUILDINGFOCUS_FOOD, isCapital() ? 5 : 30, 30))
{
return;
}
int iSpreadUnitThreshold = 1000;
iSpreadUnitThreshold += bLandWar ? 1000 : 0;
UnitTypes eBestSpreadUnit = NO_UNIT;
int iBestSpreadUnitValue = -1;
{
int iSpreadUnitRoll = (100 - iBuildUnitProb) / 3;
iSpreadUnitRoll += bLandWar ? 0 : 10;
if (AI_bestSpreadUnit(true, true, iSpreadUnitRoll, &eBestSpreadUnit, &iBestSpreadUnitValue))
{
if (iBestSpreadUnitValue > iSpreadUnitThreshold)
{
if (AI_chooseUnit(eBestSpreadUnit, UNITAI_MISSIONARY))
{
return;
}
FAssertMsg(false, "AI_bestSpreadUnit should provide a valid unit when it returns true");
}
}
}
if (!bDanger && (iProductionRank <= ((kPlayer.getNumCities() / 5) + 1)))
{
if (AI_chooseProject())
{
return;
}
}
//minimal defense.
if (plot()->plotCount(PUF_isUnitAIType, UNITAI_CITY_DEFENSE, -1, getOwnerINLINE()) < (AI_minDefenders() + iPlotSettlerCount))
{
if (AI_chooseUnit(UNITAI_CITY_DEFENSE))
{
return;
}
}
if ((iAreaBestFoundValue > iMinFoundValue) || (iWaterAreaBestFoundValue > iMinFoundValue))
{
if (pWaterArea != NULL)
{
int iTotalCities = kPlayer.getNumCities();
int iSettlerSeaNeeded = std::min(iNumWaterAreaCitySites, ((iTotalCities + 4) / 8) + 1);
if (kPlayer.getCapitalCity() != NULL)
{
int iOverSeasColonies = iTotalCities - kPlayer.getCapitalCity()->area()->getCitiesPerPlayer(getOwnerINLINE());;
int iLoop = 2;
int iExtras = 0;
while (iOverSeasColonies >= iLoop)
{
iExtras++;
iLoop += iLoop + 2;
}
iSettlerSeaNeeded += std::min(kPlayer.AI_totalUnitAIs(UNITAI_WORKER) / 4, iExtras);
}
if (bAssault)
{
iSettlerSeaNeeded = std::min(1, iSettlerSeaNeeded);
}
if (kPlayer.AI_totalWaterAreaUnitAIs(pWaterArea, UNITAI_SETTLER_SEA) < iSettlerSeaNeeded)
{
if (AI_chooseUnit(UNITAI_SETTLER_SEA))
{
return;
}
}
}
if (iPlotSettlerCount == 0)
{
if ((iNumSettlers < iMaxSettlers) && (!bLandWar || (GC.getGameINLINE().getSorenRandNum(2, "AI War Settler") == 0)))
{
if (iPlotCityDefenderCount == 1)
{
if (AI_chooseUnit(UNITAI_CITY_DEFENSE))
{
return;
}
}
else if (AI_chooseUnit(UNITAI_SETTLE))
{
return;
}
}
}
}
//this is needed to build the cathedrals quickly
//also very good for giving cultural cities first dibs on wonders
if (bImportantCity && (iCultureRateRank <= iCulturalVictoryNumCultureCities))
{
if (iCultureRateRank == iCulturalVictoryNumCultureCities)
{
if (AI_chooseBuilding(BUILDINGFOCUS_BIGCULTURE | BUILDINGFOCUS_CULTURE | BUILDINGFOCUS_WONDEROK, 40))
{
return;
}
}
else if (GC.getGameINLINE().getSorenRandNum(((iCultureRateRank == 1) ? 4 : 1) + iCulturalVictoryNumCultureCities * 2 , "AI Build up Culture") < iCultureRateRank)
{
if (AI_chooseBuilding(BUILDINGFOCUS_BIGCULTURE | BUILDINGFOCUS_CULTURE | BUILDINGFOCUS_WONDEROK, 40))
{
return;
}
}
}
// don't build frivolous things if this is an important city unless we at war
if (!bImportantCity || bLandWar || bAssault)
{
if (bPrimaryArea)
{
if (kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK) == 0)
{
if (AI_chooseUnit(UNITAI_ATTACK))
{
return;
}
}
}
if (!bLandWar && !bDanger)
{
if (kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_EXPLORE) < (kPlayer.AI_neededExplorers(pArea)))
{
if (AI_chooseUnit(UNITAI_EXPLORE))
{
return;
}
}
}
if (bDefenseWar)
{
if (GC.getGameINLINE().getSorenRandNum(100, "AI Train Defensive Unit (Panic)") > (bGetBetterUnits ? 60 : 40))
{
UnitTypeWeightArray panicDefenderTypes;
panicDefenderTypes.push_back(std::make_pair(UNITAI_RESERVE, 100));
panicDefenderTypes.push_back(std::make_pair(UNITAI_COUNTER, 100));
panicDefenderTypes.push_back(std::make_pair(UNITAI_COLLATERAL, 100));
panicDefenderTypes.push_back(std::make_pair(UNITAI_ATTACK, 100));
if (AI_chooseLeastRepresentedUnit(panicDefenderTypes))
{
return;
}
}
}
}
if (AI_chooseBuilding(BUILDINGFOCUS_FOOD, 60, 10))
{
return;
}
//oppurunistic wonder build
if (!bDanger && (!hasActiveWorldWonder() || (kPlayer.getNumCities() > 3)))
{
int iWonderTime = GC.getGameINLINE().getSorenRandNum(GC.getLeaderHeadInfo(getPersonalityType()).getWonderConstructRand(), "Wonder Construction Rand");
iWonderTime /= 5;
iWonderTime += 8;
if (AI_chooseBuilding(BUILDINGFOCUS_WORLDWONDER, iWonderTime))
{
return;
}
}
if (iNeededWorkers < iExistingWorkers)
{
if ((AI_getWorkersNeeded() > 0) && (AI_getWorkersHave() == 0))
{
if (!bChooseWorker && AI_chooseUnit(UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
}
//essential economic builds
if (AI_chooseBuilding(iEconomyFlags, 10, 25))
{
return;
}
if (iBestSpreadUnitValue > ((iSpreadUnitThreshold * 60) / 100))
{
if (AI_chooseUnit(eBestSpreadUnit, UNITAI_MISSIONARY))
{
return;
}
FAssertMsg(false, "AI_bestSpreadUnit should provide a valid unit when it returns true");
}
int iMaxUnitSpending = (bAggressiveAI ? 7 : 3) + iBuildUnitProb / 3;
if (bAlwaysPeace)
{
iMaxUnitSpending = -10;
}
else if (kPlayer.AI_isDoStrategy(AI_STRATEGY_FINAL_WAR))
{
iMaxUnitSpending = 5 + iMaxUnitSpending + (100 - iMaxUnitSpending) / 2;
}
else
{
iMaxUnitSpending += bDefenseWar ? 4 : 0;
switch (pArea->getAreaAIType(getTeam()))
{
case AREAAI_OFFENSIVE:
iMaxUnitSpending += 5;
break;
case AREAAI_DEFENSIVE:
iMaxUnitSpending += 10;
break;
case AREAAI_MASSING:
iMaxUnitSpending += 25;
break;
case AREAAI_ASSAULT:
iMaxUnitSpending += 8;
break;
case AREAAI_ASSAULT_MASSING:
iMaxUnitSpending += 16;
break;
case AREAAI_ASSAULT_ASSIST:
iMaxUnitSpending += 6;
break;
case AREAAI_NEUTRAL:
break;
default:
FAssert(false);
}
}
if (iUnitCostPercentage < (iMaxUnitSpending + 10))
{
int iBestSeaAssaultCapacity = 0;
if (NULL != pWaterArea && (bAssault))
{
UnitTypes eBestAssaultUnit = NO_UNIT;
kPlayer.AI_bestCityUnitAIValue(UNITAI_ASSAULT_SEA, this, &eBestAssaultUnit);
if (eBestAssaultUnit != NO_UNIT)
{
iBestSeaAssaultCapacity = GC.getUnitInfo(eBestAssaultUnit).getCargoSpace();
}
int iUnitsToTransport = kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK_CITY);
iUnitsToTransport += kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK);
iUnitsToTransport += kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_COUNTER);
int iTransports = kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ASSAULT_SEA);
iTransports += kPlayer.AI_totalAreaUnitAIs(pWaterArea, UNITAI_ASSAULT_SEA);
int iEscorts = kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ESCORT_SEA);
iEscorts += kPlayer.AI_totalAreaUnitAIs(pWaterArea, UNITAI_ESCORT_SEA);
//The way of calculating numbers is a bit fuzzy since the ships
//can make return trips. When massing for a war it'll train enough
//ships to move it's entire army. Once the war is underway it'll stop
//training so many ships on the assumption that those out at sea
//will return...
if ((iEscorts < ((1 + 2 * iTransports) / 3)) && (GC.getGame().getSorenRandNum(2, "AI train escort sea") == 0))
{
if (AI_chooseUnit(UNITAI_ESCORT_SEA))
{
AI_chooseBuilding(BUILDINGFOCUS_DOMAINSEA);
return;
}
}
UnitTypes eBestAttackSeaUnit = NO_UNIT;
kPlayer.AI_bestCityUnitAIValue(UNITAI_ATTACK_SEA, this, &eBestAttackSeaUnit);
if (eBestAttackSeaUnit != NO_UNIT)
{
if (GC.getUnitInfo(eBestAttackSeaUnit).getBombardRate() > 0)
{
int iAttackSea = kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK_SEA);
iAttackSea += kPlayer.AI_totalAreaUnitAIs(pWaterArea, UNITAI_ATTACK_SEA);
if ((iAttackSea < ((1 + 2 * iTransports) / 2)) && (GC.getGame().getSorenRandNum(2, "AI train attack sea") == 0))
{
if (AI_chooseUnit(UNITAI_ATTACK_SEA))
{
AI_chooseBuilding(BUILDINGFOCUS_DOMAINSEA);
return;
}
}
}
}
if (iUnitsToTransport > (iTransports * iBestSeaAssaultCapacity))
{
if (AI_chooseUnit(UNITAI_ASSAULT_SEA))
{
AI_chooseBuilding(BUILDINGFOCUS_DOMAINSEA);
return;
}
}
int iCarriers = kPlayer.AI_totalUnitAIs(UNITAI_CARRIER_SEA);
if (iCarriers > 0)
{
UnitTypes eBestCarrierUnit = NO_UNIT;
kPlayer.AI_bestCityUnitAIValue(UNITAI_CARRIER_SEA, this, &eBestCarrierUnit);
if (eBestCarrierUnit != NO_UNIT)
{
FAssert(GC.getUnitInfo(eBestCarrierUnit).getDomainCargo() == DOMAIN_AIR);
int iCarrierAirNeeded = iCarriers * GC.getUnitInfo(eBestCarrierUnit).getCargoSpace();
if (kPlayer.AI_totalUnitAIs(UNITAI_CARRIER_AIR) < iCarrierAirNeeded)
{
if (AI_chooseUnit(UNITAI_CARRIER_AIR))
{
return;
}
}
}
}
if (iCarriers < (kPlayer.AI_totalUnitAIs(UNITAI_ASSAULT_SEA) / 4))
{
if (AI_chooseUnit(UNITAI_CARRIER_SEA))
{
return;
}
}
int iMissileCarriers = kPlayer.AI_totalUnitAIs(UNITAI_MISSILE_CARRIER_SEA);
if (iMissileCarriers > 0)
{
UnitTypes eBestMissileCarrierUnit = NO_UNIT;
kPlayer.AI_bestCityUnitAIValue(UNITAI_MISSILE_CARRIER_SEA, this, &eBestMissileCarrierUnit);
if (eBestMissileCarrierUnit != NO_UNIT)
{
FAssert(GC.getUnitInfo(eBestMissileCarrierUnit).getDomainCargo() == DOMAIN_AIR);
int iMissileCarrierAirNeeded = iMissileCarriers * GC.getUnitInfo(eBestMissileCarrierUnit).getCargoSpace();
if ((kPlayer.AI_totalUnitAIs(UNITAI_MISSILE_AIR) < iMissileCarrierAirNeeded) ||
(bPrimaryArea && (kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_MISSILE_CARRIER_SEA) * GC.getUnitInfo(eBestMissileCarrierUnit).getCargoSpace() < kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_MISSILE_AIR))))
{
if (AI_chooseUnit(UNITAI_MISSILE_AIR))
{
return;
}
}
}
}
}
}
UnitTypeWeightArray airUnitTypes;
int iAircraftNeed = 0;
int iAircraftHave = 0;
UnitTypes eBestAttackAircraft = NO_UNIT;
UnitTypes eBestMissile = NO_UNIT;
if (iUnitCostPercentage < (iMaxUnitSpending + 4))
{
int iBestAirValue = kPlayer.AI_bestCityUnitAIValue(UNITAI_ATTACK_AIR, this, &eBestAttackAircraft);
int iBestMissileValue = kPlayer.AI_bestCityUnitAIValue(UNITAI_MISSILE_AIR, this, &eBestMissile);
if ((iBestAirValue + iBestMissileValue) > 0)
{
iAircraftHave = kPlayer.AI_getNumAIUnits(UNITAI_ATTACK_AIR) + kPlayer.AI_getNumAIUnits(UNITAI_DEFENSE_AIR) + kPlayer.AI_getNumAIUnits(UNITAI_MISSILE_AIR);
if (NO_UNIT != eBestAttackAircraft)
{
iAircraftNeed = (2 + kPlayer.getNumCities() * (3 * GC.getUnitInfo(eBestAttackAircraft).getAirCombat())) / (2 * std::max(1, GC.getGame().getBestLandUnitCombat()));
int iBestDefenseValue = kPlayer.AI_bestCityUnitAIValue(UNITAI_DEFENSE_AIR, this);
if ((iBestDefenseValue > 0) && (iBestAirValue > iBestDefenseValue))
{
iAircraftNeed *= 3;
iAircraftNeed /= 2;
}
}
if (iBestMissileValue > 0)
{
iAircraftNeed = std::max(iAircraftNeed, 1 + kPlayer.getNumCities() / 2);
}
bool bAirBlitz = kPlayer.AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ);
bool bLandBlitz = kPlayer.AI_isDoStrategy(AI_STRATEGY_LAND_BLITZ);
if (bAirBlitz)
{
iAircraftNeed *= 3;
iAircraftNeed /= 2;
}
else if (bLandBlitz)
{
iAircraftNeed /= 2;
iAircraftNeed += 1;
}
airUnitTypes.push_back(std::make_pair(UNITAI_ATTACK_AIR, bAirBlitz ? 125 : 80));
airUnitTypes.push_back(std::make_pair(UNITAI_DEFENSE_AIR, bLandBlitz ? 100 : 100));
if (iBestMissileValue > 0)
{
airUnitTypes.push_back(std::make_pair(UNITAI_MISSILE_AIR, 50));
}
airUnitTypes.push_back(std::make_pair(UNITAI_ICBM, 20));
if (iAircraftHave * 2 < iAircraftNeed)
{
if (AI_chooseLeastRepresentedUnit(airUnitTypes))
{
return;
}
}
}
}
if (!bAlwaysPeace && !(bLandWar || bAssault) && (kPlayer.AI_isDoStrategy(AI_STRATEGY_OWABWNW) || (GC.getGame().getSorenRandNum(12, "AI consider Nuke") == 0)))
{
int iTotalNukes = kPlayer.AI_totalUnitAIs(UNITAI_ICBM);
int iNukesWanted = 1 + 2 * std::min(kPlayer.getNumCities(), GC.getGame().getNumCities() - kPlayer.getNumCities());
if ((iTotalNukes < iNukesWanted) && (GC.getGame().getSorenRandNum(100, "AI train nuke MWAHAHAH") < (90 - (80 * iTotalNukes) / iNukesWanted)))
{
if ((pWaterArea != NULL) && (GC.getGame().getSorenRandNum(4, "AI train nuke carrier")))
{
if (AI_chooseUnit(UNITAI_MISSILE_CARRIER_SEA))
{
return;
}
}
if (AI_chooseUnit(UNITAI_ICBM))
{
return;
}
}
}
if ((!bImportantCity || bDefenseWar) && (iUnitCostPercentage < iMaxUnitSpending))
{
if (!bFinancialTrouble && !bGetBetterUnits && (bLandWar || ((bAssault || kPlayer.AI_isDoStrategy(AI_STRATEGY_DAGGER)) && !bAssaultAssist)))
{
int iTrainInvaderChance = iBuildUnitProb + 10;
if (bAggressiveAI)
{
iTrainInvaderChance += 15;
}
if ((pArea->getAreaAIType(getTeam()) == AREAAI_MASSING) || (pArea->getAreaAIType(getTeam()) == AREAAI_ASSAULT_MASSING))
{
iTrainInvaderChance = (100 - ((100 - iTrainInvaderChance) / (bCrushStrategy ? 6 : 3)));
}
if (GC.getGameINLINE().getSorenRandNum(100, "AI Dagger Offense Unit") < iTrainInvaderChance )
{
{
if (AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, 20))
{
return;
}
UnitTypeWeightArray invaderTypes;
invaderTypes.push_back(std::make_pair(UNITAI_ATTACK_CITY, 100));
invaderTypes.push_back(std::make_pair(UNITAI_COUNTER, 50));
invaderTypes.push_back(std::make_pair(UNITAI_ATTACK, 40));
invaderTypes.push_back(std::make_pair(UNITAI_PARADROP, (kPlayer.AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ) ? 30 : 20) / (bAssault ? 2 : 1)));
if (!bAssault)
{
if (kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_PILLAGE) <= ((iNumCitiesInArea + 1) / 2))
{
invaderTypes.push_back(std::make_pair(UNITAI_PILLAGE, 30));
}
}
if (AI_chooseLeastRepresentedUnit(invaderTypes))
{
return;
}
}
}
}
}
//Arr.
if ((pWaterArea != NULL) && !bLandWar && !bAssault)
{
int iPirateCount = kPlayer.AI_totalWaterAreaUnitAIs(pWaterArea, UNITAI_PIRATE_SEA);
int iNeededPirates = (1 + (pWaterArea->getNumTiles() / std::max(1, 200 - iBuildUnitProb)));
iNeededPirates *= (20 + iWaterPercent);
iNeededPirates /= 100;
if (kPlayer.isNoForeignTrade())
{
iNeededPirates *= 3;
iNeededPirates /= 2;
}
if (kPlayer.AI_totalWaterAreaUnitAIs(pWaterArea, UNITAI_PIRATE_SEA) < iNeededPirates)
{
if (kPlayer.AI_calculateUnitAIViability(UNITAI_PIRATE_SEA, DOMAIN_SEA) > 49)
{
if (GC.getGameINLINE().getSorenRandNum(100, "AI train pirate") < (iWaterPercent / (1 + iPirateCount)))
{
if (AI_chooseUnit(UNITAI_PIRATE_SEA))
{
return;
}
}
}
}
}
if (!bLandWar)
{
if ((pWaterArea != NULL) && (iWaterPercent > 40))
{
if (kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_SPY) > 0)
{
if (kPlayer.AI_totalWaterAreaUnitAIs(pWaterArea, UNITAI_SPY_SEA) == 0)
{
if (AI_chooseUnit(UNITAI_SPY_SEA))
{
return;
}
}
}
}
}
if (iBestSpreadUnitValue > ((iSpreadUnitThreshold * 40) / 100))
{
if (AI_chooseUnit(eBestSpreadUnit, UNITAI_MISSIONARY))
{
return;
}
FAssertMsg(false, "AI_bestSpreadUnit should provide a valid unit when it returns true");
}
if (iTotalFloatingDefenders < iNeededFloatingDefenders)
{
if (GC.getGameINLINE().getSorenRandNum(100, "AI Build Floating Defender") < 50)
{
if (AI_chooseLeastRepresentedUnit(floatingDefenderTypes))
{
return;
}
}
}
int iNumSpies = (kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_SPY));
int iNeededSpies = iNumCitiesInArea / 3;
iNeededSpies += isCapital() ? 1 : 0;
if (iNumSpies < iNeededSpies)
{
if (GC.getGameINLINE().getSorenRandNum(100, "AI Train Spy") < 5 + 50 / (1 + iNumSpies))
{
if (AI_chooseUnit(UNITAI_SPY))
{
return;
}
}
}
if (bLandWar)
{
if (iNumSettlers < iMaxSettlers)
{
if (!bFinancialTrouble)
{
if (iAreaBestFoundValue > iMinFoundValue)
{
if (AI_chooseUnit(UNITAI_SETTLE))
{
return;
}
}
}
}
}
if ((iProductionRank <= ((kPlayer.getNumCities() > 8) ? 3 : 2))
&& (getPopulation() > 3))
{
int iWonderRand = 8 + GC.getGameINLINE().getSorenRandNum(GC.getLeaderHeadInfo(getPersonalityType()).getWonderConstructRand(), "Wonder Construction Rand");
// increase chance of going for an early wonder
if (GC.getGameINLINE().getElapsedGameTurns() < (100 * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getConstructPercent() / 100) && iNumCitiesInArea > 1)
{
iWonderRand *= 35;
iWonderRand /= 100;
}
else if (iNumCitiesInArea >= 3)
{
iWonderRand *= 30;
iWonderRand /= 100;
}
else
{
iWonderRand *= 25;
iWonderRand /= 100;
}
if (bAggressiveAI)
{
iWonderRand *= 2;
iWonderRand /= 3;
}
int iWonderRoll = GC.getGameINLINE().getSorenRandNum(100, "Wonder Build Rand");
if (iProductionRank == 1)
{
iWonderRoll /= 2;
}
if (iWonderRoll < iWonderRand)
{
int iWonderMaxTurns = 20 + ((iWonderRand - iWonderRoll) * 2);
if (bLandWar)
{
iWonderMaxTurns /= 2;
}
if (AI_chooseBuilding(BUILDINGFOCUS_WORLDWONDER, iWonderMaxTurns))
{
return;
}
}
}
if (iUnitCostPercentage < iMaxUnitSpending + 4)
{
if ((iAircraftHave * 2 >= iAircraftNeed) && (iAircraftHave < iAircraftNeed))
{
if (AI_chooseLeastRepresentedUnit(airUnitTypes))
{
return;
}
}
}
if (!bLandWar)
{
if ((iCulturePressure > 90) || kPlayer.AI_isDoStrategy(AI_STRATEGY_CULTURE2))
{
if (AI_chooseBuilding(BUILDINGFOCUS_CULTURE, 20))
{
return;
}
}
if (pWaterArea != NULL)
{
if (kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_MISSIONARY) > 0)
{
if (kPlayer.AI_totalWaterAreaUnitAIs(pWaterArea, UNITAI_MISSIONARY_SEA) == 0)
{
if (AI_chooseUnit(UNITAI_MISSIONARY_SEA))
{
return;
}
}
}
}
}
if (getCommerceRateTimes100(COMMERCE_CULTURE) == 0)
{
if (AI_chooseBuilding(BUILDINGFOCUS_CULTURE, 30))
{
return;
}
}
// if (getPopulation() > 6)
// {
// if (!AI_isAirDefended())
// {
// if (AI_chooseUnit(UNITAI_DEFENSE_AIR))
// {
// return;
// }
// }
// }
if (!bAlwaysPeace && (bDanger || (GC.getGameINLINE().getSorenRandNum(30, "AI Build Defense") < getPopulation())))
{
if (!bDanger)
{
if (AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, 20))
{
return;
}
}
if (AI_chooseBuilding(BUILDINGFOCUS_DEFENSE, 20))
{
return;
}
if (bDanger)
{
if (AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, 20))
{
return;
}
}
}
if (AI_chooseBuilding(BUILDINGFOCUS_PRODUCTION, 20, 4))
{
return;
}
//20 means 5g or ~2 happiness...
if (AI_chooseBuilding(iEconomyFlags, 15, 20))
{
return;
}
if (!bLandWar)
{
if (AI_chooseBuilding(iEconomyFlags, 40, 8))
{
return;
}
if (iCulturePressure > 50)
{
if (AI_chooseBuilding(BUILDINGFOCUS_CULTURE, 60))
{
return;
}
}
if (pWaterArea != NULL)
{
if (bPrimaryArea)
{
if (kPlayer.AI_totalWaterAreaUnitAIs(pWaterArea, UNITAI_EXPLORE_SEA) < std::min(1, kPlayer.AI_neededExplorers(pWaterArea)))
{
if (AI_chooseUnit(UNITAI_EXPLORE_SEA))
{
return;
}
}
}
}
if (getBaseYieldRate(YIELD_PRODUCTION) >= 8)
{
if (AI_chooseBuilding(BUILDINGFOCUS_PRODUCTION, 80))
{
return;
}
}
}
if (plot()->plotCheck(PUF_isUnitAIType, UNITAI_CITY_COUNTER, -1, getOwnerINLINE()) == NULL)
{
if (AI_chooseUnit(UNITAI_CITY_COUNTER))
{
return;
}
}
// we do a similar check lower, in the landwar case
if (!bLandWar && bFinancialTrouble)
{
if (AI_chooseBuilding(BUILDINGFOCUS_GOLD))
{
return;
}
}
bChooseUnit = false;
if (iUnitCostPercentage < iMaxUnitSpending + 5)
{
if ((bLandWar) ||
((kPlayer.getNumCities() <= 3) && (GC.getGameINLINE().getElapsedGameTurns() < 60)) ||
(GC.getGameINLINE().getSorenRandNum(100, "AI Build Unit Production") < AI_buildUnitProb()) ||
(isHuman() && (getGameTurnFounded() == GC.getGameINLINE().getGameTurn())))
{
if (AI_chooseUnit())
{
return;
}
bChooseUnit = true;
}
}
if (AI_chooseProject())
{
return;
}
if (AI_chooseBuilding())
{
return;
}
if (!bChooseUnit && !bFinancialTrouble && kPlayer.AI_isDoStrategy(AI_STRATEGY_FINAL_WAR))
{
if (AI_chooseUnit())
{
return;
}
}
if (AI_chooseProcess())
{
return;
}
}
Der erste Funktionsaufruf AI_isDanger() bedeutet