Thunderbrd
C2C War Dog
Part IV
Spoiler :
Code:
m_iTempBuildPriority--;
if ((getDomainFreeExperience(DOMAIN_LAND) == 0) && (getYieldRate(YIELD_PRODUCTION) > 4))
{
if (AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, (kPlayer.getCurrentEra() > 1) ? 0 : 7, 33))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses special BUILDINGFOCUS_EXPERIENCE 1", getName().GetCString());
return;
}
}
m_iTempBuildPriority--;
// Koshling - increased priority for economic builds, especially in early game and allowed
// wonders in if they appear best
if (AI_chooseBuilding(iEconomyFlags | BUILDINGFOCUS_WONDEROK, 20, 0, kPlayer.getCurrentEra() == 0 ? 100 : 50))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose iEconomyFlags (Koshling)", getName().GetCString());
return;
}
m_iTempBuildPriority--;
//TB Build Mod (Moved up in priority)
#ifdef C2C_BUILD
if (!bAlwaysPeace )
{
PROFILE("AI_chooseProduction.NotAlwaysPeace");
if (AI_chooseBuilding(BUILDINGFOCUS_DEFENSE, 20, 0, bDanger ? -1 : 3*getPopulation()))
{
return;
}
if (AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, 20, 0, (bDanger ? 10 : 4)*std::min(9,getPopulation())))
{
return;
}
}
#endif
//TB Build Mod end
m_iTempBuildPriority--;
// Koshling in early game moved optional non-wartime attack unit builds below economy
// don't build frivolous things if this is an important city unless we at war
if (!bInhibitUnits && (!bImportantCity || bLandWar || bAssault) && kPlayer.getCurrentEra() == 0)
{
if (bPrimaryArea)
{
if (kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK) == 0)
{
if (AI_chooseUnit("primary area attack", UNITAI_ATTACK))
{
return;
}
}
}
}
m_iTempBuildPriority--;
// Koshling - next section moved from quite a bit earlier to avoid not-needed-yet worker builds
// before we have checked basic economy builds
//do a check for one tile island type thing?
//this can be overridden by "wait and grow more"
if (!bInhibitUnits && !bDanger && (iExistingWorkers == 0) && (isCapital() || (iNeededWorkers > 0) || (iNeededSeaWorkers > iExistingSeaWorkers)))
{
if( !(bDefenseWar && iWarSuccessRatio < -30) && !(kPlayer.AI_isDoStrategy(AI_STRATEGY_TURTLE)) )
{
if ((AI_countNumBonuses(NO_BONUS, /*bIncludeOurs*/ true, /*bIncludeNeutral*/ true, -1, /*bLand*/ true, /*bWater*/ false) > 0) ||
(isCapital() && (getPopulation() > 3) && iNumCitiesInArea > 1))
{
if (!bChooseWorker && AI_chooseUnit("optional worker", UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
if (iNeededSeaWorkers > iExistingSeaWorkers)
{
if (AI_chooseUnit("optional sea worker", UNITAI_WORKER_SEA))
{
return;
}
}
}
}
m_iTempBuildPriority--;
int iMaxUnitSpending = (bAggressiveAI ? 6 : 3) + iBuildUnitProb / 3;
if( kPlayer.AI_isDoVictoryStrategy(AI_VICTORY_CONQUEST4) )
{
iMaxUnitSpending += 7;
}
else if( kPlayer.AI_isDoVictoryStrategy(AI_VICTORY_CONQUEST3) || kPlayer.AI_isDoVictoryStrategy(AI_VICTORY_DOMINATION3) )
{
iMaxUnitSpending += 3;
}
else if( kPlayer.AI_isDoVictoryStrategy(AI_VICTORY_CONQUEST1) )
{
iMaxUnitSpending += 1;
}
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);
}
}
int iCarriers = kPlayer.AI_totalUnitAIs(UNITAI_CARRIER_SEA);
//Afforess moved AI Aircraft logic up, Aircraft >> Sea transports
UnitTypeWeightArray airUnitTypes;
int iAircraftNeed = 0;
int iAircraftHave = 0;
UnitTypes eBestAttackAircraft = NO_UNIT;
UnitTypes eBestMissile = NO_UNIT;
if (!bInhibitUnits && iUnitCostPercentage < (iMaxUnitSpending + 4) && (!bImportantCity || bDefenseWar) )
{
if( bLandWar || bAssault || (iFreeAirExperience > 0) || (getCitySorenRandNum(3, "AI train air") == 0) )
{
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_totalUnitAIs(UNITAI_ATTACK_AIR) + kPlayer.AI_totalUnitAIs(UNITAI_DEFENSE_AIR) + kPlayer.AI_totalUnitAIs(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, bAssault ? 60 : 40));
}
airUnitTypes.push_back(std::make_pair(UNITAI_ICBM, 20));
if (iAircraftHave * 2 < iAircraftNeed)
{
if (AI_chooseLeastRepresentedUnit("need airforce", airUnitTypes))
{
return;
}
}
// Additional check for air defenses
int iFightersHave = kPlayer.AI_totalUnitAIs(UNITAI_DEFENSE_AIR);
if( 3*iFightersHave < iAircraftNeed )
{
if (AI_chooseUnit("need air defense", UNITAI_DEFENSE_AIR))
{
return;
}
}
}
}
}
m_iTempBuildPriority--;
// Revamped logic for production for invasions
if (!bInhibitUnits && iUnitCostPercentage < (iMaxUnitSpending + 10))
{
bool bBuildAssault = bAssault;
CvArea* pAssaultWaterArea = NULL;
if (NULL != pWaterArea)
{
// Coastal city extra logic
pAssaultWaterArea = pWaterArea;
// If on offensive and can't reach enemy cities from here, act like using AREAAI_ASSAULT
if( (pAssaultWaterArea != NULL) && !bBuildAssault )
{
if( (GET_TEAM(getTeam()).getAnyWarPlanCount(true) > 0) )
{
if( (pArea->getAreaAIType(getTeam()) != AREAAI_DEFENSIVE) )
{
// BBAI TODO: faster to switch to checking path for some selection group?
if( !(plot()->isHasPathToEnemyCity(getTeam())) )
{
bBuildAssault = true;
}
}
}
}
}
if( bBuildAssault )
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses build assault", getName().GetCString());
UnitTypes eBestAssaultUnit = NO_UNIT;
if (NULL != pAssaultWaterArea)
{
kPlayer.AI_bestCityUnitAIValue(UNITAI_ASSAULT_SEA, this, &eBestAssaultUnit);
}
else
{
kPlayer.AI_bestCityUnitAIValue(UNITAI_ASSAULT_SEA, NULL, &eBestAssaultUnit);
}
int iBestSeaAssaultCapacity = 0;
if (eBestAssaultUnit != NO_UNIT)
{
iBestSeaAssaultCapacity = GC.getUnitInfo(eBestAssaultUnit).getCargoSpace();
}
int iAreaAttackCityUnits = kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK_CITY);
int iUnitsToTransport = iAreaAttackCityUnits;
iUnitsToTransport += kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK);
iUnitsToTransport += kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_COUNTER)/2;
int iLocalTransports = kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ASSAULT_SEA);
int iTransportsAtSea = 0;
if (NULL != pAssaultWaterArea)
{
iTransportsAtSea = kPlayer.AI_totalAreaUnitAIs(pAssaultWaterArea, UNITAI_ASSAULT_SEA);
}
else
{
iTransportsAtSea = kPlayer.AI_totalUnitAIs(UNITAI_ASSAULT_SEA)/2;
}
//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...
int iTransports = iLocalTransports + (bPrimaryArea ? iTransportsAtSea : iTransportsAtSea/4);
int iTransportCapacity = iBestSeaAssaultCapacity*(iTransports);
if (NULL != pAssaultWaterArea)
{
int iEscorts = kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ESCORT_SEA);
iEscorts += kPlayer.AI_totalAreaUnitAIs(pAssaultWaterArea, UNITAI_ESCORT_SEA);
int iTransportViability = kPlayer.AI_calculateUnitAIViability(UNITAI_ASSAULT_SEA, DOMAIN_SEA);
int iDesiredEscorts = ((1 + 2 * iTransports) / 3);
if( iTransportViability > 95 )
{
// Transports are stronger than escorts (usually Galleons and Caravels)
iDesiredEscorts /= 3;
}
if ((iEscorts < iDesiredEscorts))
{
if ( AI_chooseBuilding(BUILDINGFOCUS_DOMAINSEA, 12) )
{
return;
}
if (AI_chooseUnit("sea escort", UNITAI_ESCORT_SEA, (iEscorts < iDesiredEscorts/3) ? -1 : 50))
{
return;
}
}
UnitTypes eBestAttackSeaUnit = NO_UNIT;
kPlayer.AI_bestCityUnitAIValue(UNITAI_ATTACK_SEA, this, &eBestAttackSeaUnit);
if (eBestAttackSeaUnit != NO_UNIT)
{
int iDivisor = 2;
if (GC.getUnitInfo(eBestAttackSeaUnit).getBombardRate() == 0)
{
iDivisor = 5;
}
int iAttackSea = kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK_SEA);
iAttackSea += kPlayer.AI_totalAreaUnitAIs(pAssaultWaterArea, UNITAI_ATTACK_SEA);
if ((iAttackSea < ((1 + 2 * iTransports) / iDivisor)))
{
if ( AI_chooseBuilding(BUILDINGFOCUS_DOMAINSEA, 12) )
{
return;
}
if (AI_chooseUnit("sea attack", UNITAI_ATTACK_SEA, (iUnitCostPercentage < iMaxUnitSpending) ? 50 : 20))
{
return;
}
}
}
if (iUnitsToTransport > iTransportCapacity)
{
if ((iUnitCostPercentage < iMaxUnitSpending) || (iUnitsToTransport > 2*iTransportCapacity))
{
if ( AI_chooseBuilding(BUILDINGFOCUS_DOMAINSEA, 12) )
{
return;
}
if (AI_chooseUnit("sea assault", UNITAI_ASSAULT_SEA))
{
return;
}
}
}
}
if (iUnitCostPercentage < iMaxUnitSpending)
{
if (NULL != pAssaultWaterArea)
{
if (!bFinancialTrouble && iCarriers < (kPlayer.AI_totalUnitAIs(UNITAI_ASSAULT_SEA) / 4))
{
// Reduce chances of starting if city has low production
if ( iProductionRank > (kPlayer.getNumCities() / 3) && getCitySorenRandNum(100, "AI train carrier") < 30 )
{
if ( AI_chooseBuilding(BUILDINGFOCUS_DOMAINSEA, 12) )
{
return;
}
if (AI_chooseUnit("need carrier", UNITAI_CARRIER_SEA) )
{
return;
}
}
}
}
}
// Consider building more land units to invade with
int iTrainInvaderChance = iBuildUnitProb + 10;
iTrainInvaderChance += (bAggressiveAI ? 15 : 0);
iTrainInvaderChance /= (bAssaultAssist ? 2 : 1);
iTrainInvaderChance /= (bImportantCity ? 2 : 1);
iTrainInvaderChance /= (bGetBetterUnits ? 2 : 1);
iUnitsToTransport *= 9;
iUnitsToTransport /= 10;
if( (iUnitsToTransport > iTransportCapacity) && (iUnitsToTransport > (bAssaultAssist ? 2 : 4)*iBestSeaAssaultCapacity) )
{
// Already have enough
iTrainInvaderChance /= 2;
}
else if( iUnitsToTransport < (iLocalTransports*iBestSeaAssaultCapacity) )
{
iTrainInvaderChance += 15;
}
if( getPopulation() < 4 )
{
// Let small cities build themselves up first
iTrainInvaderChance /= (5 - getPopulation());
}
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));
if( kPlayer.AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ) )
{
invaderTypes.push_back(std::make_pair(UNITAI_PARADROP, 20));
}
if( !bImportantCity && (iUnitsToTransport >= (iLocalTransports*iBestSeaAssaultCapacity)) )
{
// Have time to build barracks first
if (AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, 20))
{
return;
}
}
if (AI_chooseLeastRepresentedUnit("invader units", invaderTypes, iTrainInvaderChance))
{
return;
}
if (iUnitCostPercentage < (iMaxUnitSpending))
{
int iMissileCarriers = kPlayer.AI_totalUnitAIs(UNITAI_MISSILE_CARRIER_SEA);
if (!bFinancialTrouble && iMissileCarriers > 0 && !bImportantCity)
{
if( (iProductionRank <= ((kPlayer.getNumCities() / 2) + 1)) )
{
UnitTypes eBestMissileCarrierUnit = NO_UNIT;
kPlayer.AI_bestCityUnitAIValue(UNITAI_MISSILE_CARRIER_SEA, NULL, &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))))
{
// Don't always build missiles, more likely if really low
if (AI_chooseUnit("need missiles", UNITAI_MISSILE_AIR, (kPlayer.AI_totalUnitAIs(UNITAI_MISSILE_AIR) < iMissileCarrierAirNeeded/2) ? 50 : 20))
{
return;
}
}
}
}
}
}
}
}
m_iTempBuildPriority--;
// Check for whether to produce planes to fill carriers
if ( !bInhibitUnits && (bLandWar || bAssault) && iUnitCostPercentage < (iMaxUnitSpending))
{
if (iCarriers > 0 && !bImportantCity)
{
UnitTypes eBestCarrierUnit = NO_UNIT;
kPlayer.AI_bestCityUnitAIValue(UNITAI_CARRIER_SEA, NULL, &eBestCarrierUnit);
if (eBestCarrierUnit != NO_UNIT)
{
FAssert(GC.getUnitInfo(eBestCarrierUnit).getDomainCargo() == DOMAIN_AIR);
int iCarrierAirNeeded = iCarriers * GC.getUnitInfo(eBestCarrierUnit).getCargoSpace();
// Reduce chances if city gives no air experience
if (kPlayer.AI_totalUnitAIs(UNITAI_CARRIER_AIR) < iCarrierAirNeeded)
{
if (AI_chooseUnit("need planes for carriers", UNITAI_CARRIER_AIR, (iFreeAirExperience > 0) ? -1 : 35))
{
return;
}
}
}
}
}
m_iTempBuildPriority--;
//Afforess reduced 12 -> 6, since AI rarely reaches this logic, Added exemption for MAD players
int chance = !GC.getGameINLINE().isOption(GAMEOPTION_RUTHLESS_AI) ? 6 : 3;
if (!bInhibitUnits && !bAlwaysPeace && (kPlayer.AI_isDoStrategy(AI_STRATEGY_OWABWNW) || kPlayer.isEnabledMAD() || (getCitySorenRandNum(chance, "AI consider Nuke") == 0)))
{
if( !bFinancialTrouble )
{
int iTotalNukes = kPlayer.AI_totalUnitAIs(UNITAI_ICBM);
int iNukesWanted = 1 + 2 * std::min(kPlayer.getNumCities(), GC.getGame().getNumCities() - kPlayer.getNumCities());
//Afforess rolling randoms twice makes getting nukes much harder
if ((iTotalNukes < iNukesWanted)/* && (getCitySorenRandNum(100, "AI train nuke MWAHAHAH") < (90 - (80 * iTotalNukes) / iNukesWanted))*/)
{
//Reordered, because nukes are more valuable than carriers
if (AI_chooseUnit("ICBM (2)", UNITAI_ICBM))
{
return;
}
if ((pWaterArea != NULL))
{
if (AI_chooseUnit("need missile carrier", UNITAI_MISSILE_CARRIER_SEA, 50))
{
return;
}
}
}
}
}
m_iTempBuildPriority--;
// Assault case now completely handled above
if (/*!bUnitExempt && */!bInhibitUnits && !bAssault && (!bImportantCity || bDefenseWar) && (iUnitCostPercentage < iMaxUnitSpending))
{
if (!bFinancialTrouble && (bLandWar || (kPlayer.AI_isDoStrategy(AI_STRATEGY_DAGGER) && !bGetBetterUnits)))
{
int iTrainInvaderChance = iBuildUnitProb + 10;
if (bAggressiveAI)
{
iTrainInvaderChance += 15;
}
if( bGetBetterUnits )
{
iTrainInvaderChance /= 2;
}
else if ((pArea->getAreaAIType(getTeam()) == AREAAI_MASSING) || (pArea->getAreaAIType(getTeam()) == AREAAI_ASSAULT_MASSING))
{
iTrainInvaderChance = (100 - ((100 - iTrainInvaderChance) / (bCrushStrategy ? 6 : 3)));
}
if (AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, 20, 0, bDefenseWar ? 10 : 30))
{
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("invader units (2)", invaderTypes, iTrainInvaderChance))
{
return;
}
}
}
m_iTempBuildPriority--;
if (!bInhibitUnits && (pWaterArea != NULL) && !bDefenseWar && !bAssault)
{
if( !bFinancialTrouble )
{
// Force civs with foreign colonies to build a few assault transports to defend the colonies
if( kPlayer.AI_totalUnitAIs(UNITAI_ASSAULT_SEA) < (kPlayer.getNumCities() - iNumCapitalAreaCities)/3 )
{
if (AI_chooseUnit("colony defense assault ships", UNITAI_ASSAULT_SEA))
{
return;
}
}
if (kPlayer.AI_calculateUnitAIViability(UNITAI_SETTLER_SEA, DOMAIN_SEA) < 61)
{
// Force civs to build escorts for settler_sea units
if( kPlayer.AI_totalUnitAIs(UNITAI_SETTLER_SEA) > kPlayer.AI_getNumAIUnits(UNITAI_RESERVE_SEA) )
{
if (AI_chooseUnit("sea settler escorts", UNITAI_RESERVE_SEA))
{
return;
}
}
}
}
}
m_iTempBuildPriority--;
//Arr. Don't build pirates in financial trouble, as they'll be disbanded with high probability
if (!bInhibitUnits && (pWaterArea != NULL) && !bLandWar && !bAssault && !bFinancialTrouble/* && !bUnitExempt*/) //k-mod
{
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 (AI_chooseUnit("pirates", UNITAI_PIRATE_SEA, iWaterPercent / (1 + iPirateCount)))
{
return;
}
}
}
}
m_iTempBuildPriority--;
if (!bInhibitUnits && !bLandWar && !bFinancialTrouble)
{
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("sea spy", UNITAI_SPY_SEA))
{
return;
}
}
}
}
}
m_iTempBuildPriority--;
if (!bInhibitUnits && iBestSpreadUnitValue > ((iSpreadUnitThreshold * 40) / 100))
{
if (AI_chooseUnit(eBestSpreadUnit, UNITAI_MISSIONARY))
{
return;
}
}
m_iTempBuildPriority--;
if (!bInhibitUnits && (iTotalFloatingDefenders < iNeededFloatingDefenders && (!bFinancialTrouble || bLandWar)))
{
if (AI_chooseLeastRepresentedUnit("floating defenders", floatingDefenderTypes, 50))
{
return;
}
}
m_iTempBuildPriority--;
// Koshling - protect against broken AI counts, which is known to happen occasionally
int iNumSpies = std::max(0,kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_SPY));
int iNeededSpies = iNumCitiesInArea / 3;
iNeededSpies += isCapital() ? 1 : 0;
// K-Mod
if (kPlayer.AI_isDoStrategy(AI_STRATEGY_BIG_ESPIONAGE))
{
iNeededSpies *= 2;
}
if (!bInhibitUnits && iNumSpies < iNeededSpies)
{
//if (AI_chooseUnit("spy", UNITAI_SPY, 5 + 50 / (1 + iNumSpies)))
if (AI_chooseUnit("spy", UNITAI_SPY, 30 * iNeededSpies / (3 * iNumSpies + iNeededSpies)))
{
return;
}
}
if (!bInhibitUnits && bLandWar && !bDanger)
{
if (iNumSettlers < iMaxSettlers)
{
if (!bFinancialTrouble)
{
if (iAreaBestFoundValue > iMinFoundValue)
{
if (AI_chooseUnit("optional settlers", UNITAI_SETTLE))
{
return;
}
}
}
}
}
m_iTempBuildPriority--;
if (!isHuman() &&
(iProductionRank <= ((kPlayer.getNumCities() > 8) ? 3 : 2))
&& (getPopulation() > 3))
{
/************************************************************************************************/
/* Afforess Start 06/30/10 */
/* */
/* */
/************************************************************************************************/
/*
int iWonderRand = 8 + getCitySorenRandNum(GC.getLeaderHeadInfo(getPersonalityType()).getWonderConstructRand(), "Wonder Construction Rand");
*/
int iWonderRand = 8 + getCitySorenRandNum(GET_PLAYER(getOwnerINLINE()).getWonderConstructRand(), "Wonder Construction Rand");
/************************************************************************************************/
/* Afforess END */
/************************************************************************************************/
// 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 = getCitySorenRandNum(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))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses oppurtunistic wonder build 3", getName().GetCString());
return;
}
}
}
m_iTempBuildPriority--;
if (!bInhibitUnits && iUnitCostPercentage < iMaxUnitSpending + 4 && !bFinancialTrouble)
{
if ((iAircraftHave * 2 >= iAircraftNeed) && (iAircraftHave < iAircraftNeed))
{
int iOdds = 33;
if( iFreeAirExperience > 0 || (iProductionRank <= (1 + kPlayer.getNumCities()/2)) )
{
iOdds = -1;
}
if (AI_chooseLeastRepresentedUnit("air units", airUnitTypes, iOdds))
{
return;
}
}
}
m_iTempBuildPriority--;
if (!bLandWar)
{
if ((iCulturePressure > 90) || kPlayer.AI_isDoVictoryStrategy(AI_VICTORY_CULTURE2))
{
if (!isHuman() || AI_isEmphasizeCommerce(COMMERCE_CULTURE))
{
if (AI_chooseBuilding(BUILDINGFOCUS_CULTURE, 20))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses cultural pressure/cultural victory 3", getName().GetCString());
return;
}
}
}
if (!bInhibitUnits && pWaterArea != NULL && bFinancialTrouble)
{
if (kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_MISSIONARY) > 0)
{
if (kPlayer.AI_totalWaterAreaUnitAIs(pWaterArea, UNITAI_MISSIONARY_SEA) == 0)
{
if (AI_chooseUnit("sea missionary", UNITAI_MISSIONARY_SEA))
{
return;
}
}
}
}
}
m_iTempBuildPriority--;
if (!isHuman() || AI_isEmphasizeCommerce(COMMERCE_CULTURE))
{
if (getCommerceRateTimes100(COMMERCE_CULTURE) == 0)
{
if (AI_chooseBuilding(BUILDINGFOCUS_CULTURE, 30))
{
return;
}
}
}
//TB Build Mod (Move up in priority so this takes place before building for invasions)
#ifndef C2C_BUILD
if (!bAlwaysPeace )
{
if (!bDanger)
{
if (AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, 20, 0, 3*getPopulation()))
{
return;
}
}
if (AI_chooseBuilding(BUILDINGFOCUS_DEFENSE, 20, 0, bDanger ? -1 : 3*getPopulation()))
{
return;
}
if (bDanger)
{
if (AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, 20, 0, 2*getPopulation()))
{
return;
}
}
}
//TB Build Mod (Remove unnecessary elements)
if (AI_chooseBuilding(BUILDINGFOCUS_PRODUCTION, 20, 4))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose BUILDINGFOCUS_PRODUCTION 2", getName().GetCString());
return;
}
#endif
m_iTempBuildPriority--;
//20 means 5g or ~2 happiness...
if (AI_chooseBuilding(iEconomyFlags, 15, (20*iEcononmyFlagsThreasholdWeighting)/100))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose iEconomyFlags 2", getName().GetCString());
return;
}
m_iTempBuildPriority--;
if (!bLandWar)
{
if (AI_chooseBuilding(iEconomyFlags, 40, (8*iEcononmyFlagsThreasholdWeighting)/100))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose iEconomyFlags 3", getName().GetCString());
return;
}
if (!isHuman() || AI_isEmphasizeCommerce(COMMERCE_CULTURE))
{
if (iCulturePressure > 50)
{
if (AI_chooseBuilding(BUILDINGFOCUS_CULTURE, 60))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose cultural pressure 2", getName().GetCString());
return;
}
}
}
if (!bInhibitUnits && pWaterArea != NULL)
{
if (bPrimaryArea)
{
if (kPlayer.AI_totalWaterAreaUnitAIs(pWaterArea, UNITAI_EXPLORE_SEA) < std::min(1, kPlayer.AI_neededExplorers(pWaterArea)))
{
if (AI_chooseUnit("explore sea", UNITAI_EXPLORE_SEA))
{
return;
}
}
}
}
if (!isHuman() || AI_isEmphasizeYield(YIELD_PRODUCTION))
{
if (getBaseYieldRate(YIELD_PRODUCTION) >= 8)
{
if (AI_chooseBuilding(BUILDINGFOCUS_PRODUCTION, 80))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose BUILDINGFOCUS_PRODUCTION 3", getName().GetCString());
return;
}
}
}
}
m_iTempBuildPriority--;
// If there are no city counter units in the vicinity best create 1
if (!bInhibitUnits && plot()->plotCount(PUF_isUnitAIType, UNITAI_CITY_COUNTER, -1, NULL, getOwnerINLINE(), NO_TEAM, NULL, -1, -1, 2) == 0)
{
if (AI_chooseUnit("city counter units needed locally", UNITAI_CITY_COUNTER))
{
return;
}
}
m_iTempBuildPriority--;
// If there are no pillage counter units in the vicinity best create 1
if (!bInhibitUnits && plot()->plotCount(PUF_isUnitAIType, UNITAI_PILLAGE_COUNTER, -1, NULL, getOwnerINLINE(), NO_TEAM, NULL, -1, -1, 2) == 0)
{
if (AI_chooseUnit("pillage counter units needed locally", UNITAI_PILLAGE_COUNTER))
{
return;
}
}
m_iTempBuildPriority--;
// we do a similar check lower, in the landwar case
if (!bLandWar && bFinancialTrouble)
{
if (!isHuman() || AI_isEmphasizeCommerce(COMMERCE_GOLD))
{
if (AI_chooseBuilding(BUILDINGFOCUS_GOLD))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose financial trouble gold", getName().GetCString());
return;
}
}
}
m_iTempBuildPriority--;
// low priority property control (bad property > 5% through op range - choose unit to deal if possible)
if ( AI_choosePropertyControlUnit( 5 ) )
{
return;
}
m_iTempBuildPriority--;
if ( AI_chooseHealerUnit() )
{
return;
}
m_iTempBuildPriority--;
bChooseUnit = false;
if (!bInhibitUnits && iUnitCostPercentage < iMaxUnitSpending + 5)
{
if ((bLandWar) ||
((kPlayer.getNumCities() <= 3) && (GC.getGameINLINE().getElapsedGameTurns() < 60)) ||
(getCitySorenRandNum(100, "AI Build Unit Production") < AI_buildUnitProb()) ||
(isHuman() && (getGameTurnFounded() == GC.getGameINLINE().getGameTurn())))
{
if (AI_chooseUnit("optional units"))
{
return;
}
bChooseUnit = true;
}
}
m_iTempBuildPriority--;
// BBAI TODO: Temporary for testing
//if( getOwnerINLINE()%2 == 1 )
//{
// Only cities with reasonable production
if (!isHuman() && (iProductionRank <= ((kPlayer.getNumCities() > 8) ? 3 : 2))
&& (getPopulation() > 3))
{
if (AI_chooseProject())
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose project 2", getName().GetCString());
return;
}
}
//}