Still nothing.... Other mods work normally, but C2C doesn't even start.
but when I try loading C2C game shuts down and nothing happens....
@ TB
I believe the "stack" movement is back, i have like 6 archers in a stack and when i attack, i can only get 1 of them to attack, then it says (2) in the movement area, and i have to DE-select the stack, and attack ONE at a time??
EDIT: Weird, now i went back to the game from minimized desktop, and now the stack is working again, weird?
Hard to say what was happening. Particularly when I don't know what attack options you're playing on. Quick Combat (Offense) and Stack Attack from the vanilla options tab are the two I worked with. You should never use the Bug Stack Attack though.
Bad timing, I'm going to be away from my computer until early february, and I won't have time before I leave.![]()
Perhaps the sea textures in my texture pack works as they should, they are pretty much redone.
Assert Failed
File: CvGlobals.cpp
Line: 5274
SVN-Rev: 8951
Expression: stricmp(szType, "NONE")==0 || strcmp(szType, "")==0
Message: info type 'BUILDING_MING_VASE_WORKSHOP' not found, Current XML file is: modules\My_Mods\Traditions\Work_Ethic_CIV4BuildingInfos.xml
----------------------------------------------------------
it'll be like waiting for the walking dead to come back on tv!
Hehe appreciate that, I'll be around to answer posts at least.Stay in touch with us at least my friend. I'll have lots of work for you when you returnToo bad we're losing you for so long - it'll be like waiting for the walking dead to come back on tv!
Cant stand to watch that show any longer, just like all the other zombie tv shows, it all the same to me, i really stopped watching the walking dead when Lori Grimes stopped being there.
Code:Assert Failed File: CvGlobals.cpp Line: 5274 SVN-Rev: 8951 Expression: stricmp(szType, "NONE")==0 || strcmp(szType, "")==0 Message: info type 'BUILDING_MING_VASE_WORKSHOP' not found, Current XML file is: modules\My_Mods\Traditions\Work_Ethic_CIV4BuildingInfos.xml ----------------------------------------------------------
I realize that. Which is why I need an original CvUnit so I can repair the bug option stack attack as well. The problem is not being 100% sure how it was setup originally when it was working so many years ago.
Joe usually keeps alot of OLD mod and older copies of everything, tell him where to find it and how far back, he Might be able to find a copy??
"Are you SURE you can see into the build settings on all those cities that don't have a selection? If that's it then the problem is much deeper than that because, as you suggested, wealth/research/culture IS the default if there's nothing else to do. However, there are numerous situations where as a player I've found my cities building nothing and wondered how they ended up in that position. If the AI is suffering from this kind of thing then at least we need to program in a catch to determine this every round and ensure SOMETHING is set. Problem is, I'm not sure what's causing it or really where to setup such a check... particularly without causing lots of turn time delays. I can look into it but PLEASE, given the complexity of the problem, I NEED you to absolutely rock solidly confirm that this problem really is happening and provide a test save that shows it."
Yes looks like i can be sure, all other special agents see the production of the other city and if i give oral tradition to the AI then next turn they build directly knowledge inhertiance its visible then directly, so must be idle for sure. Check it and fix it here is the save where i made all civs visible with special agents...
void CvCityAI::AI_chooseProduction()
{
PROFILE_FUNC();
CvArea* pWaterArea;
bool bWasFoodProduction;
bool bLandWar;
bool bAssault;
bool bDefenseWar;
bool bPrimaryArea;
bool bFinancialTrouble;
bool bDanger;
bool bChooseUnit;
bool bInhibitUnits = false;
int iProductionRank;
int iCulturePressure;
m_bRequestedBuilding = false;
m_bRequestedUnit = false;
CvPlayerAI& kPlayer = GET_PLAYER(getOwnerINLINE());
if (kPlayer.isAnarchy())
{
return;
}
bDanger = AI_isDanger();
m_iBuildPriority = CITY_BUILD_PRIORITY_CEILING;
m_iTempBuildPriority = CITY_BUILD_PRIORITY_CEILING;
// only clear the dirty bit if we actually do a check, multiple items might be queued
AI_setChooseProductionDirty(false);
/************************************************************************************************/
/* Afforess Start 04/22/10 */
/* */
/* */
/************************************************************************************************/
if(GC.getUSE_AI_CHOOSE_PRODUCTION_CALLBACK())
{
PYTHON_ACCESS_LOCK_SCOPE
// 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;
PYTHON_CALL_FUNCTION4(__FUNCTION__, PYGameModule, "AI_chooseProduction", argsList.makeFunctionArgs(), &lResult);
delete pyCity; // python fxn must not hold on to this pointer
if (lResult == 1)
{
return;
}
}
if (isHuman() && isProductionAutomated())
{
if (!GET_PLAYER(getOwnerINLINE()).isOption(PLAYEROPTION_MODDER_3))
{
AI_buildGovernorChooseProduction();
return;
}
else
{
for (int iI = 0; iI < NUM_COMMERCE_TYPES; iI++)
{
if (AI_isEmphasizeCommerce((CommerceTypes)iI))
{
bInhibitUnits = true;
}
}
for (int iI = 0; iI < NUM_YIELD_TYPES; iI++)
{
if (AI_isEmphasizeYield((YieldTypes)iI))
{
bInhibitUnits = true;
}
}
}
}
/************************************************************************************************/
/* Afforess END */
/************************************************************************************************/
CvArea* pArea = area();
pWaterArea = waterArea(true);
bool bMaybeWaterArea = false;
bool bWaterDanger = false;
if (pWaterArea != NULL)
{
bMaybeWaterArea = true;
if (!GET_TEAM(getTeam()).AI_isWaterAreaRelevant(pWaterArea))
{
pWaterArea = NULL;
}
bWaterDanger = kPlayer.AI_getWaterDanger(plot(), 4) > 0;
}
bWasFoodProduction = isFoodProduction();
//AIAndy: Not used here at the moment
//bool bHasMetHuman = GET_TEAM(getTeam()).hasMetHuman();
bool bMassing = (pArea->getAreaAIType(getTeam()) == AREAAI_ASSAULT_MASSING);
bLandWar = ((pArea->getAreaAIType(getTeam()) == AREAAI_OFFENSIVE) || (pArea->getAreaAIType(getTeam()) == AREAAI_DEFENSIVE) || bMassing);
bDefenseWar = (pArea->getAreaAIType(getTeam()) == AREAAI_DEFENSIVE);
bool bAssaultAssist = (pArea->getAreaAIType(getTeam()) == AREAAI_ASSAULT_ASSIST);
bAssault = bAssaultAssist || (pArea->getAreaAIType(getTeam()) == AREAAI_ASSAULT) || bMassing;
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();
int iWarSuccessRatio = GET_TEAM(getTeam()).AI_getWarSuccessCapitulationRatio();
int iEnemyPowerPerc = GET_TEAM(getTeam()).AI_getEnemyPowerPercent(true);
int iWarTroubleThreshold = 0;
// Are our best worker units one-shot usage (mostly)?
bool bBestWorkerIsOneShot = false;
//TB OOS Debug: Undefined variable causing an OOS
int iUnitValue = 0;
UnitTypes eBestWorker = AI_bestUnitAI(UNITAI_WORKER, iUnitValue, false, true);
if ( eBestWorker != NO_UNIT )
{
int iNoKillBuildsCount = 0;
int iKillBuildsCount = 0;
for (int iI = 0; iI < GC.getNumBuildInfos(); ++iI)
{
if (GC.getUnitInfo(eBestWorker).getBuilds(iI))
{
if ( GC.getBuildInfo((BuildTypes)iI).isKill() )
{
iKillBuildsCount++;
}
else
{
iNoKillBuildsCount++;
}
}
}
// Empirical ratio needed to distinguish C2C gatherer, but should hopefully
// be a reasonable heuristic should any similar units be added in future
bBestWorkerIsOneShot = (3*iKillBuildsCount >= iNoKillBuildsCount);
}
if( bLandWar && iWarSuccessRatio < 30 )
{
iWarTroubleThreshold = std::max(3,(-iWarSuccessRatio/8));
}
if( !bLandWar && !bAssault && GET_TEAM(getTeam()).isAVassal() )
{
bLandWar = GET_TEAM(getTeam()).isMasterPlanningLandWar(area());
if( !bLandWar )
{
bAssault = GET_TEAM(getTeam()).isMasterPlanningSeaWar(area());
}
}
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);
// Sea worker need independent of whether water area is militarily relevant
int iNeededSeaWorkers = (bMaybeWaterArea) ? AI_neededSeaWorkers() : 0;
int iExistingSeaWorkers = (waterArea(true) != NULL) ? kPlayer.AI_totalWaterAreaUnitAIs(waterArea(true), UNITAI_WORKER_SEA) : 0;
int iTargetCulturePerTurn = AI_calculateTargetCulturePerTurn();
int iAreaBestFoundValue;
int iNumAreaCitySites = kPlayer.AI_getNumAreaCitySites(getArea(), iAreaBestFoundValue);
int iWaterAreaBestFoundValue = 0;
CvArea* pWaterSettlerArea = pWaterArea;
if( pWaterSettlerArea == NULL )
{
pWaterSettlerArea = GC.getMap().findBiggestArea(true);
if( GET_PLAYER(getOwnerINLINE()).AI_totalWaterAreaUnitAIs(pWaterSettlerArea, UNITAI_SETTLER_SEA) == 0 )
{
pWaterSettlerArea = NULL;
}
}
int iNumWaterAreaCitySites = (pWaterSettlerArea == NULL) ? 0 : kPlayer.AI_getNumAdjacentAreaCitySites(pWaterSettlerArea->getID(), getArea(), iWaterAreaBestFoundValue);
int iNumSettlers = kPlayer.AI_totalUnitAIs(UNITAI_SETTLE) + GET_PLAYER(getOwnerINLINE()).getContractBroker().numRequestsOutstanding(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 && GET_PLAYER(getOwnerINLINE()).bestBuildableUnitForAIType(NO_DOMAIN, UNITAI_SETTLE) != NO_UNIT)
{
iMaxSettlers= std::min((kPlayer.getNumCities() + 1) / 2, iNumAreaCitySites + iNumWaterAreaCitySites);
if (bLandWar || bAssault)
{
iMaxSettlers = (iMaxSettlers + 2) / 3;
}
if (kPlayer.getCityLimit() > 0)
{
if ( kPlayer.getCityOverLimitUnhappy() > 0 )
{
// Soft limit. If we already have unhappy cities don't create
// settlers that will increase overall unhappiness as they found
// new cities
if ( kPlayer.AI_getOverallHappyness() < 0 )
{
iMaxSettlers = std::min(iMaxSettlers, std::max(0,kPlayer.getCityLimit() - kPlayer.getNumCities()));
}
}
else
{
// Hard limit - don't stockpile more than 2 settlers
iMaxSettlers = std::min(iMaxSettlers,kPlayer.getCityLimit() - kPlayer.getNumCities() + 2);
}
}
}
/************************************************************************************************/
/* Afforess Start 06/29/10 */
/* */
/* */
/************************************************************************************************/
// AIAndy: Not used here at the moment
//bool bDevelopingCity = isDevelopingCity();
/************************************************************************************************/
/* Afforess END */
/************************************************************************************************/
bool bChooseWorker = false;
int iEconomyFlags = 0;
int iEconomyFlagBits = 0;
if ( !isHuman() || AI_isEmphasizeYield(YIELD_PRODUCTION) )
{
iEconomyFlags |= BUILDINGFOCUS_PRODUCTION;
iEconomyFlagBits++;
}
if ( !isHuman() || AI_isEmphasizeYield(YIELD_COMMERCE) )
{
iEconomyFlags |= BUILDINGFOCUS_GOLD;
iEconomyFlagBits++;
}
if ( !isHuman() || AI_isEmphasizeCommerce(COMMERCE_RESEARCH) )
{
iEconomyFlags |= BUILDINGFOCUS_RESEARCH;
iEconomyFlagBits++;
}
if ( !bInhibitUnits ) // This is actually a proxy for the human owner having set no explicit preferences
{
iEconomyFlags |= BUILDINGFOCUS_MAINTENANCE;
iEconomyFlags |= BUILDINGFOCUS_HAPPY;
iEconomyFlags |= BUILDINGFOCUS_HEALTHY;
iEconomyFlagBits += 3;
}
if (AI_isEmphasizeGreatPeople())
{
iEconomyFlags |= BUILDINGFOCUS_SPECIALIST;
iEconomyFlagBits++;
}
if (!GC.getGameINLINE().isOption(GAMEOPTION_NO_ESPIONAGE))
{
iEconomyFlags |= BUILDINGFOCUS_ESPIONAGE;
iEconomyFlagBits++;
}
// Normalize threholds using this against the number of bits we are including
int iEcononmyFlagsThreasholdWeighting = (100*iEconomyFlagBits)/8;
if (iNumCitiesInArea > 2)
{
if (kPlayer.AI_isDoVictoryStrategy(AI_VICTORY_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)) && (getCitySorenRandNum(2, "AI Less Culture More Expand") == 0))
{
bImportantCity = false;
}
else
{
bImportantCity = true;
}
}
}
}
}
// Free experience for various unit domains
int iFreeLandExperience = getSpecialistFreeExperience() + getDomainFreeExperience(DOMAIN_LAND);
// AIAndy: Not used here at the moment
//int iFreeSeaExperience = getSpecialistFreeExperience() + getDomainFreeExperience(DOMAIN_SEA);
int iFreeAirExperience = getSpecialistFreeExperience() + getDomainFreeExperience(DOMAIN_AIR);
clearOrderQueue();
if (bWasFoodProduction)
{
AI_assignWorkingPlots();
}
iProductionRank = findYieldRateRank(YIELD_PRODUCTION);
// K-Mod, military exemption for commerce cities and underdeveloped cities
//bool bUnitExempt = false;
//if (kPlayer.AI_isDoStrategy(AI_STRATEGY_ECONOMY_FOCUS))
//{
// bUnitExempt = true;
//}
//else if (iProductionRank > kPlayer.getNumCities() / 2)
//{
// bool bBelowMedian = true;
// for (int iI = 0; iI < NUM_COMMERCE_TYPES; iI++)
// {
// // I'd use the total commerce rank, but there currently isn't a cached value of that.
// int iRank = findCommerceRateRank((CommerceTypes)iI);
// if (iRank < iProductionRank)
// {
// bUnitExempt = true;
// break;
// }
// if (iRank < kPlayer.getNumCities() / 2)
// {
// bBelowMedian = false;
// }
// }
// if (bBelowMedian)
// {
// bUnitExempt = true;
// }
//}
////Exemptions (Afforess)
//if (isCapital() || kPlayer.getNumCities() < 3)
//{
// bUnitExempt = false;
//}
// K-Mod end
if( gCityLogLevel >= 3 ) logBBAI(" City %S pop %d considering new production: iProdRank %d, iBuildUnitProb %d", getName().GetCString(), getPopulation(), iProductionRank, iBuildUnitProb);
// -------------------- BBAI Notes -------------------------
// Start special circumstances
// -------------------- BBAI Notes -------------------------
// Barbarian city build priorities
if (isBarbarian())
{
if( gCityLogLevel >= 3 )
{
logBBAI(" Barb city %S - area workers %d (needed %d), local %d (needed %d)", getName().GetCString(), iExistingWorkers, iNeededWorkers, AI_getWorkersHave(), AI_getWorkersNeeded());
}
if (!AI_isDefended(plot()->plotStrength(UNITVALUE_FLAGS_DEFENSIVE, PUF_isUnitAIType, UNITAI_ATTACK, -1, getOwnerINLINE()))) // XXX check for other team's units?
{
if (AI_chooseDefender("barbarian defenders"))
{
return;
}
if (AI_chooseUnit("barbarian lack of defense", UNITAI_ATTACK))
{
return;
}
}
if (!bDanger && (2*iExistingWorkers < iNeededWorkers) && (AI_getWorkersNeeded() > 0) && (AI_getWorkersHave() == 0))
{
if( getPopulation() > 1 || (GC.getGameINLINE().getGameTurn() - getGameTurnAcquired() > (15 * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent())/100) )
{
if (AI_chooseUnit("barbarian worker for established city", UNITAI_WORKER))
{
return;
}
}
}
if (!bDanger && !bWaterDanger && (iNeededSeaWorkers > 0))
{
if (AI_chooseUnit("barbarian navy", UNITAI_WORKER_SEA))
{
return;
}
}
iBuildUnitProb += (3 * iFreeLandExperience);
bool bRepelColonists = false;
if( area()->getNumCities() > area()->getCitiesPerPlayer(BARBARIAN_PLAYER) + 2 )
{
if( area()->getCitiesPerPlayer(BARBARIAN_PLAYER) > area()->getNumCities()/3 )
{
// New world scenario with invading colonists ... fight back!
bRepelColonists = true;
iBuildUnitProb += 8*(area()->getNumCities() - area()->getCitiesPerPlayer(BARBARIAN_PLAYER));
}
}
bChooseUnit = false;
if (!bDanger && getCitySorenRandNum(100, "AI Build Unit Production") > iBuildUnitProb)
{
int iBarbarianFlags = 0;
if( getPopulation() < 4 ) iBarbarianFlags |= BUILDINGFOCUS_FOOD;
iBarbarianFlags |= BUILDINGFOCUS_PRODUCTION;
iBarbarianFlags |= BUILDINGFOCUS_EXPERIENCE;
if( getPopulation() > 3 ) iBarbarianFlags |= BUILDINGFOCUS_DEFENSE;
if (AI_chooseBuilding(iBarbarianFlags, 15))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses barb AI_chooseBuilding with flags and iBuildUnitProb = %d", getName().GetCString(), iBuildUnitProb);
return;
}
if( getCitySorenRandNum(100, "AI Build Unit Production") > iBuildUnitProb)
{
if (AI_chooseBuilding())
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses barb AI_chooseBuilding without flags and iBuildUnitProb = %d", getName().GetCString(), iBuildUnitProb);
return;
}
}
}
if (plot()->plotCount(PUF_isUnitAIType, UNITAI_ASSAULT_SEA, -1, NULL, getOwnerINLINE()) > 0)
{
if (AI_chooseUnit("barbarian choose attack city for transports", UNITAI_ATTACK_CITY))
{
return;
}
}
if (!bDanger && (pWaterArea != NULL) && (iWaterPercent > 30))
{
if (getCitySorenRandNum(3, "AI Coast Raiders!") == 0)
{
if (kPlayer.AI_totalUnitAIs(UNITAI_ASSAULT_SEA) <= (1 + kPlayer.getNumCities() / 2))
{
if (AI_chooseUnit("barbarian transports", UNITAI_ASSAULT_SEA))
{
return;
}
}
}
if (getCitySorenRandNum(110, "AI arrrr!") < (iWaterPercent + 10))
{
if (kPlayer.AI_totalUnitAIs(UNITAI_PIRATE_SEA) <= kPlayer.getNumCities())
{
if (AI_chooseUnit("barbarian pirates", UNITAI_PIRATE_SEA))
{
return;
}
}
if (kPlayer.AI_totalAreaUnitAIs(pWaterArea, UNITAI_ATTACK_SEA) < iNumCitiesInArea)
{
if (AI_chooseUnit("barbarian sea attack", UNITAI_ATTACK_SEA))
{
return;
}
}
}
}
if (getCitySorenRandNum(2, "Barb worker") == 0)
{
if (!bDanger && (iExistingWorkers < iNeededWorkers) && (AI_getWorkersNeeded() > 0) && (AI_getWorkersHave() == 0))
{
if( getPopulation() > 1 )
{
if (AI_chooseUnit("barbarian worker", UNITAI_WORKER))
{
return;
}
}
}
}
UnitTypeWeightArray barbarianTypes;
barbarianTypes.push_back(std::make_pair(UNITAI_ATTACK, 125));
barbarianTypes.push_back(std::make_pair(UNITAI_ATTACK_CITY, (bRepelColonists ? 200 : 100)));
barbarianTypes.push_back(std::make_pair(UNITAI_COUNTER, 100));
barbarianTypes.push_back(std::make_pair(UNITAI_CITY_DEFENSE, 50));
if (AI_chooseLeastRepresentedUnit("barbarian units", barbarianTypes))
{
return;
}
if (AI_chooseUnit("barbarian last resort"))
{
return;
}
return;
}
//TB Build Mod (is considered a poor strategy now) // if we need to pop borders, then do that immediately if we have drama and can do it
#ifndef C2C_BUILD
// 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;
}
}
#endif
/************************************************************************************************/
/* REVOLUTION_MOD 06/11/08 jdog5000 */
/* */
/* */
/************************************************************************************************/
if( kPlayer.isRebel() )
{
UnitTypeWeightArray rebelDefenseTypes;
rebelDefenseTypes.push_back(std::make_pair(UNITAI_CITY_DEFENSE, 100));
rebelDefenseTypes.push_back(std::make_pair(UNITAI_COUNTER, 100));
rebelDefenseTypes.push_back(std::make_pair(UNITAI_COLLATERAL, 100));
rebelDefenseTypes.push_back(std::make_pair(UNITAI_ATTACK, 100));
UnitTypeWeightArray rebelOffenseTypes;
rebelOffenseTypes.push_back(std::make_pair(UNITAI_ATTACK, 125));
rebelOffenseTypes.push_back(std::make_pair(UNITAI_COUNTER, 100));
rebelOffenseTypes.push_back(std::make_pair(UNITAI_ATTACK_CITY, 75));
if( isOccupation() )
{
// Probably just captured ... may be getting defensive units,
// but need to build offense to keep rolling
if( bLandWar || bDanger )
{
if (AI_chooseLeastRepresentedUnit("rebel offense", rebelOffenseTypes))
{
return;
}
}
}
else
{
// City Defense
if (plot()->plotCount(PUF_isUnitAIType, UNITAI_CITY_DEFENSE, -1, NULL, getOwnerINLINE()) < (AI_minDefenders()))
{
if (AI_chooseUnit("rebel city defense", UNITAI_CITY_DEFENSE))
{
return;
}
if (AI_chooseDefender("rebel city defense (non-specific)"))
{
return;
}
}
// Area defense
int iNeededFloatingDefenders = kPlayer.AI_getTotalFloatingDefendersNeeded(pArea);
int iTotalFloatingDefenders = kPlayer.AI_getTotalFloatingDefenders(pArea);
if (iTotalFloatingDefenders < ((iNeededFloatingDefenders + 1) / (2)))
{
if (AI_chooseLeastRepresentedUnit("rebel defense", rebelDefenseTypes))
{
return;
}
}
// Offensive rebel units
if( bDanger || (getCitySorenRandNum(100, "AI Build Unit Production") < AI_buildUnitProb()) )
{
if( (getYieldRate(YIELD_PRODUCTION) > 5) )
{
// Air units
int iBestDefenseValue = kPlayer.AI_bestCityUnitAIValue(UNITAI_DEFENSE_AIR, this);
if( iBestDefenseValue > 0 )
{
UnitTypes eBestAttackAircraft = NO_UNIT;
int iBestAirValue = kPlayer.AI_bestCityUnitAIValue(UNITAI_ATTACK_AIR, this, &eBestAttackAircraft);
int iAircraftHave = kPlayer.AI_getNumAIUnits(UNITAI_ATTACK_AIR) + kPlayer.AI_getNumAIUnits(UNITAI_DEFENSE_AIR) + kPlayer.AI_getNumAIUnits(UNITAI_MISSILE_AIR);
int iAircraftNeed = (2 + kPlayer.getNumCities() * (3 * GC.getUnitInfo(eBestAttackAircraft).getAirCombat())) / (2 * std::max(1, GC.getGame().getBestLandUnitCombat()));
UnitTypeWeightArray airUnitTypes;
airUnitTypes.push_back(std::make_pair(UNITAI_ATTACK_AIR, 60));
airUnitTypes.push_back(std::make_pair(UNITAI_DEFENSE_AIR, 100));
if ((iAircraftHave * 2 < iAircraftNeed) && (getCitySorenRandNum(2, "AI train escort sea") == 0))
{
if (AI_chooseLeastRepresentedUnit("rebel air units", airUnitTypes))
{
return;
}
}
}
}
if( bLandWar || bDanger )
{
if (AI_chooseLeastRepresentedUnit("rebel offense units", rebelOffenseTypes))
{
return;
}
}
if( bAssault )
{
if( pWaterArea != NULL )
{
UnitTypes eBestAssaultUnit = NO_UNIT;
kPlayer.AI_bestCityUnitAIValue(UNITAI_ASSAULT_SEA, this, &eBestAssaultUnit);
int iBestSeaAssaultCapacity = 0;
if (eBestAssaultUnit != NO_UNIT)
{
iBestSeaAssaultCapacity = GC.getUnitInfo(eBestAssaultUnit).getCargoSpace();
}
if( iBestSeaAssaultCapacity > 0 )
{
int iUnitsToTransport = kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK_CITY);
iUnitsToTransport += kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK);
iUnitsToTransport += kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_COUNTER);
int iLocalTransports = kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ASSAULT_SEA);
int iTransportsAtSea = kPlayer.AI_totalAreaUnitAIs(pWaterArea, UNITAI_ASSAULT_SEA);
int iTransports = iLocalTransports + iTransportsAtSea;
int iEscorts = kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ESCORT_SEA);
iEscorts += kPlayer.AI_totalAreaUnitAIs(pWaterArea, UNITAI_ESCORT_SEA);
// Escorts
if ((iEscorts < ((1 + 2 * iTransports) / 3)) && (getCitySorenRandNum(2, "AI train escort sea") == 0))
{
if ( AI_chooseBuilding(BUILDINGFOCUS_DOMAINSEA) )
{
return;
}
if (AI_chooseUnit("rebel sea escorts", UNITAI_ESCORT_SEA))
{
return;
}
}
// Transports
if (iUnitsToTransport > (iTransports * iBestSeaAssaultCapacity))
{
if ( AI_chooseBuilding(BUILDINGFOCUS_DOMAINSEA) )
{
return;
}
if (AI_chooseUnit("rebel sea assault", UNITAI_ASSAULT_SEA))
{
return;
}
}
// Attack troops
if( iUnitsToTransport < ((iLocalTransports + (bPrimaryArea ? iTransportsAtSea/2 : 0))*iBestSeaAssaultCapacity) )
{
if (AI_chooseLeastRepresentedUnit("rebel offensive units", rebelOffenseTypes))
{
return;
}
}
}
}
}
if (AI_chooseUnit("rebel last resort"))
{
return;
}
}
}
// Buildings important for rebels
if ((getPopulation() > 3) && (getCommerceRate(COMMERCE_CULTURE) == 0))
{
if (AI_chooseBuilding(BUILDINGFOCUS_CULTURE, 30))
{
return;
}
}
if( getPopulation() < 8 )
{
if (AI_chooseBuilding(BUILDINGFOCUS_FOOD))
{
return;
}
}
// Happiness? Health?
int iRebelFlags = 0;
iRebelFlags |= BUILDINGFOCUS_CULTURE;
iRebelFlags |= BUILDINGFOCUS_PRODUCTION;
iRebelFlags |= BUILDINGFOCUS_EXPERIENCE;
iRebelFlags |= BUILDINGFOCUS_DEFENSE;
if (AI_chooseBuilding(iRebelFlags))
{
return;
}
//essential economic builds
if (AI_chooseBuilding(iEconomyFlags, 10, (25*iEcononmyFlagsThreasholdWeighting)/100))
{
return;
}
// If nothing special to build, continue to regular logic
}
/************************************************************************************************/
/* REVOLUTION_MOD END */
/************************************************************************************************/
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 (!bInhibitUnits && plot()->getNumDefenders(getOwnerINLINE()) == 0) // XXX check for other team's units?
{
if (AI_chooseUnit("defenseless city", UNITAI_CITY_DEFENSE))
{
return;
}
/********************************************************************************/
/* City Defenders 24.07.2010 Fuyu */
/********************************************************************************/
//Fuyu bIgnoreNotUnitAIs
if (kPlayer.getNumCities() <= 3)
{
CvUnitSelectionCriteria criteria;
criteria.m_bIgnoreNotUnitAIs = true;
if (AI_chooseUnit("defenseless city any unit", UNITAI_CITY_DEFENSE, -1, -1, -1, &criteria))
{
return;
}
}
/********************************************************************************/
/* City Defenders END */
/********************************************************************************/
if (AI_chooseUnit("defenseless city counter units", UNITAI_CITY_COUNTER))
{
return;
}
if (AI_chooseUnit("defenseless city special units", UNITAI_CITY_SPECIAL))
{
return;
}
/********************************************************************************/
/* City Defenders 24.07.2010 Fuyu */
/********************************************************************************/
if (AI_chooseUnit("defenseless city reserve units", UNITAI_RESERVE))
{
return;
}
//Fuyu bIgnoreNotUnitAIs
if (kPlayer.getNumCities() > 3 && iNumCitiesInArea <= 3)
{
CvUnitSelectionCriteria criteria;
criteria.m_bIgnoreNotUnitAIs = true;
if (AI_chooseUnit("defenseless city any unit (low city count area)", UNITAI_CITY_DEFENSE, -1, -1, -1, &criteria))
{
return;
}
}
/********************************************************************************/
/* City Defenders END */
/********************************************************************************/
if (AI_chooseUnit("defenseless city (accept attack units)", UNITAI_ATTACK))
{
return;
}
}
if( kPlayer.isStrike() )
{
// pick granary or lighthouse, any duration
int iStrikeFlags = 0;
iStrikeFlags |= BUILDINGFOCUS_GOLD;
iStrikeFlags |= BUILDINGFOCUS_MAINTENANCE;
if(AI_chooseBuilding(iStrikeFlags))
{
return;
}
// try picking forge, etc, any duration
if (AI_chooseBuilding(BUILDINGFOCUS_PRODUCTION))
{
return;
}
// just pick any building, any duration
if (AI_chooseBuilding())
{
return;
}
}
m_iTempBuildPriority--;
// So what's the right detection of defense which works in early game too?
// Fuyu: The right way is to 1) queue the warriors with UNITAI_CITY_DEFENCE or UNITAI_RESERVE,
// then 2) to detect defenders with plot()->plotCount(PUF_canDefendGroupHead, -1, -1, getOwnerINLINE(), NO_TEAM, PUF_isCityAIType) - compare AI_isDefended()
int iPlotSettlerCount = (iNumSettlers == 0) ? 0 : plot()->plotCount(PUF_isUnitAIType, UNITAI_SETTLE, -1, NULL, getOwnerINLINE());
int iPlotCityDefenderCount = plot()->plotCount(PUF_isUnitAIType, UNITAI_CITY_DEFENSE, -1, NULL, getOwnerINLINE(), NO_TEAM, NULL, -1, -1, 2);
int iPlotOtherCityAICount = plot()->plotCount(PUF_canDefend, -1, -1, NULL, getOwnerINLINE(), NO_TEAM, PUF_isCityAIType, -1, -1, 2);
/********************************************************************************/
/* City Defenders 24.07.2010 Fuyu */
/********************************************************************************/
int iPlotCityDefenderStrength = getGarrisonStrength();
int iPlotOtherCityAIStrength = plot()->plotStrength(UNITVALUE_FLAGS_DEFENSIVE, PUF_canDefend, -1, -1, getOwnerINLINE(), NO_TEAM, PUF_isCityAIType, -1, -1, 2) - iPlotCityDefenderStrength;
if( kPlayer.getCurrentEra() == 0 )
{
// Warriors are blocked from UNITAI_CITY_DEFENSE, in early game this confuses AI city building
if( kPlayer.AI_totalUnitAIs(UNITAI_CITY_DEFENSE) <= kPlayer.getNumCities() + iNumSettlers )
{
if( kPlayer.AI_bestCityUnitAIValue(UNITAI_CITY_DEFENSE, this) == 0 )
{
iPlotCityDefenderStrength += iPlotOtherCityAIStrength;
iPlotOtherCityAIStrength = 0;
if (iPlotCityDefenderStrength == 0)
{
iPlotCityDefenderStrength = plot()->plotStrength(UNITVALUE_FLAGS_DEFENSIVE, PUF_canDefend, -1, -1, getOwnerINLINE(), NO_TEAM, PUF_isDomainType, DOMAIN_LAND, -1, 2);
}
}
}
}
/********************************************************************************/
/* City Defenders END */
/********************************************************************************/
m_iTempBuildPriority--;
// Emergency happyness
int iHappyness = happyLevel() - unhappyLevel(0);
if ( iHappyness < -1 || iHappyness <= -getPopulation()/2 )
{
// More than 2 unhappy citizens (or more than half the population)
if (AI_chooseBuilding(BUILDINGFOCUS_HAPPY, 30, 0, -1, true))
{
return;
}
// Can we build military happyness units? Only do that up to 3 over what we might
// normally consider
if ( GET_PLAYER(getOwner()).getHappyPerMilitaryUnit() > 0 &&
plot()->plotCount(PUF_canDefend) < (AI_minDefenders() + iPlotSettlerCount + 3) )
{
if (AI_chooseUnit("emergency military happyness", UNITAI_CITY_DEFENSE))
{
return;
}
}
}
m_iTempBuildPriority--;
#if 0
//minimal defense.
if (!bInhibitUnits && (iPlotCityDefenderCount <= iPlotSettlerCount || m_requestedEscorts > 0))
{
UnitAITypes bestAIType = (m_requestedEscorts > 0 ? UNITAI_CITY_COUNTER : UNITAI_CITY_DEFENSE);
if( gCityLogLevel >= 2 ) logBBAI(" City %S needs escort for existing settler", getName().GetCString());
if (AI_chooseUnit("settler escort", bestAIType))
{
// BBAI TODO: Does this work right after settler is built???
return;
}
/********************************************************************************/
/* City Defenders 24.07.2010 Fuyu */
/********************************************************************************/
//Fuyu bIgnoreNotUnitAIs
if (iNumCitiesInArea <= 3)
{
if (AI_chooseUnit("settler escort low area count (accept any)", bestAIType, -1, true))
{
// Yes it probably works but it should never happen in the first place
return;
}
}
if (iPlotCityDefenderCount + iPlotOtherCityAICount <= iPlotSettlerCount)
{
if (AI_chooseUnit("settler escort (city defense)", UNITAI_CITY_DEFENSE))
{
return;
}
if (AI_chooseUnit("settler escort (attack)", UNITAI_ATTACK))
{
return;
}
if (AI_chooseUnit("settler escort (city counter)", UNITAI_CITY_COUNTER))
{
return;
}
if (AI_chooseUnit("settler escort (special)", UNITAI_CITY_SPECIAL))
{
return;
}
if (AI_chooseUnit("settler escort (reserve)", UNITAI_RESERVE))
{
return;
}
}
/********************************************************************************/
/* City Defenders END */
/********************************************************************************/
}
#endif
// emergency property control (bad property > 20% through op range - choose unit to deal if possible)
if ( AI_choosePropertyControlUnit( 20 ) )
{
return;
}
m_iTempBuildPriority--;
// Non-emergency, but still urgent happyness
if ( iHappyness < 0 )
{
// More than 2 unhappy citizens (or more than half the population)
if (AI_chooseBuilding(BUILDINGFOCUS_HAPPY, 15, 0, -1, true))
{
return;
}
// Can we build military happyness units? Only do that up to 1 over what we might
// normally consider
if ( GET_PLAYER(getOwner()).getHappyPerMilitaryUnit() > 0 &&
plot()->plotCount(PUF_canDefend) < (AI_minDefenders() + iPlotSettlerCount + 1) )
{
if (AI_chooseUnit("military happyness", UNITAI_CITY_DEFENSE))
{
return;
}
}
}
m_iTempBuildPriority--;
// Really easy production trumps everything
if (AI_chooseBuilding(BUILDINGFOCUS_PRODUCTION, 1))
{
return;
}
m_iTempBuildPriority--;
//Koshling - made having at least 1 hunter a much higher priority
int iNeededExplorers = kPlayer.AI_neededExplorers(pArea);
int iNeededHunters = kPlayer.AI_neededHunters(pArea);
int iExplorerDeficitPercent = (iNeededExplorers == 0) ? 0 : ((iNeededExplorers - kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_EXPLORE))*100)/iNeededExplorers;
int iHunterDeficitPercent = (iNeededHunters == 0) ? 0 : ((iNeededHunters - kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_HUNTER))*100)/iNeededHunters;
if ( iNeededHunters > 0 && iHunterDeficitPercent == 100 )
{
if ( isCapital() )
{
UnitTypes eBestUnit = AI_bestUnitAI(UNITAI_HUNTER, iUnitValue);
if ( eBestUnit != NO_UNIT )
{
int iCost = (GC.getUnitInfo(eBestUnit).getProductionCost() * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent()) / 100;
int perTurnLossesCost = (iCost*area()->getRecentCombatDeathRate(getOwnerINLINE(), UNITAI_HUNTER))/100;
if( gCityLogLevel >= 2 )
{
logBBAI(" City %S evaluating recent hunter deaths - %d per/turn cost vs %d production",
getName().GetCString(),
perTurnLossesCost,
GET_PLAYER(getOwnerINLINE()).calculateTotalYield(YIELD_PRODUCTION));
}
if ( perTurnLossesCost > GET_PLAYER(getOwnerINLINE()).calculateTotalYield(YIELD_PRODUCTION)/4 )
{
if (AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, 30))
{
return;
}
}
}
}
if (AI_chooseUnit("no hunters at all", UNITAI_HUNTER))
{
return;
}
}
/********************************************************************************/
/* RevDCM uncommented Better BUG AI changes 28.10.2010 Fuyu */
/********************************************************************************/
if( !bInhibitUnits && !(bDefenseWar && iWarSuccessRatio < -50) && !bDanger )
{
if ((iExistingWorkers == 0))
{
int iLandBonuses = m_iNumImprovableBonuses;AI_countNumImprovableBonuses(true, kPlayer.getCurrentResearch());
if ((iLandBonuses > 1) || (getPopulation() > 3 && iNeededWorkers > 0))
{
if (!bChooseWorker && AI_chooseUnit("no workers", UNITAI_WORKER, -1, -1, CITY_NO_WORKERS_WORKER_PRIORITY))
{
return;
}
bChooseWorker = true;
}
if (!bWaterDanger && (iNeededSeaWorkers > iExistingSeaWorkers) && (getPopulation() < 3))
{
if (AI_chooseUnit("no sea workers", UNITAI_WORKER_SEA, -1, -1, CITY_NO_WORKERS_WORKER_PRIORITY))
{
return;
}
}
if (iLandBonuses >= 1 && getPopulation() > 1)
{
if (!bChooseWorker && AI_chooseUnit("secondary worker", UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
}
}
/********************************************************************************/
/* RevDCM uncommented Better BUG AI changes 28.10.2010 END */
/********************************************************************************/
int iHealth = goodHealth() - badHealth(true, 0);
int iFoodDiffBase = foodDifference(false, false, true);
// If there is negative health address it if we can do so quickly (relative to the amount of ill health)
// Koshling - don't waste time with this if we have a food excess that is being trimmed by less than 20%
// by the ill health (rounded - so at less than 5 net food we always consider this)
if ( iHealth < 0 && -iHealth > iFoodDiffBase/5 )
{
// Koshling - reduce the time we're prepared to spend on this by the current food excess (if any)
if (AI_chooseBuilding(BUILDINGFOCUS_HEALTHY, std::max(1,-iHealth - std::max(0,iFoodDiffBase)), 0, -1, true))
{
return;
}
}
m_iTempBuildPriority--;
//Koshling - increase priority of hunetrs up to half what we would ideally want
if ( iNeededHunters > 0 && iHunterDeficitPercent > 50 )
{
if ( isCapital() )
{
UnitTypes eBestUnit = AI_bestUnitAI(UNITAI_HUNTER, iUnitValue);
if ( eBestUnit != NO_UNIT )
{
int iCost = (GC.getUnitInfo(eBestUnit).getProductionCost() * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent()) / 100;
int perTurnLossesCost = (iCost*area()->getRecentCombatDeathRate(getOwnerINLINE(), UNITAI_HUNTER))/100;
if( gCityLogLevel >= 2 )
{
logBBAI(" City %S evaluating recent hunter deaths - %d per/turn cost vs %d production",
getName().GetCString(),
perTurnLossesCost,
GET_PLAYER(getOwnerINLINE()).calculateTotalYield(YIELD_PRODUCTION));
}
if ( perTurnLossesCost > GET_PLAYER(getOwnerINLINE()).calculateTotalYield(YIELD_PRODUCTION)/4 )
{
if (AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, 30))
{
return;
}
}
}
}
if (AI_chooseUnit("less than half the required hunters", UNITAI_HUNTER))
{
return;
}
}
m_iTempBuildPriority--;
#ifdef C2C_BUILD
//TB Build Priority Mod Begin
{
PROFILE("AI_chooseProduction.TB_Mod");
int iPriorityCheckFlags = 0;
if (!isHuman())
{
iPriorityCheckFlags |= BUILDINGFOCUS_RESEARCH;
}
if (!isHuman() || AI_isEmphasizeYield(YIELD_PRODUCTION))
{
iPriorityCheckFlags |= BUILDINGFOCUS_PRODUCTION;
}
if (!isHuman() || AI_isEmphasizeYield(YIELD_FOOD))
{
iPriorityCheckFlags |= BUILDINGFOCUS_FOOD;
}
if ( iPriorityCheckFlags != 0 )
{
if (AI_chooseBuilding(iPriorityCheckFlags, 5))
{
return;
}
}
}
//TB Build Priority Mod End
#endif
m_iTempBuildPriority--;
if (((iTargetCulturePerTurn > 0) || (getPopulation() > 5)) && (getCommerceRate(COMMERCE_CULTURE) == 0))
{
if( !(kPlayer.AI_isDoStrategy(AI_STRATEGY_TURTLE)) )
{
if (!isHuman() || AI_isEmphasizeCommerce(COMMERCE_CULTURE))
{
if (AI_chooseBuilding(BUILDINGFOCUS_CULTURE, 30))
{
return;
}
}
}
}
m_iTempBuildPriority--;
if ( m_iTempBuildPriority >= HIGH_PRIORITY_ESCORT_PRIORITY )
{
m_iTempBuildPriority = HIGH_PRIORITY_ESCORT_PRIORITY - 1;
}
// Early game worker logic
if( !bInhibitUnits && isCapital() && (GC.getGame().getElapsedGameTurns() < ((30 * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent()) / 100)))
{
if( !bDanger && !(kPlayer.AI_isDoStrategy(AI_STRATEGY_TURTLE)) )
{
if (!bWaterDanger && (getPopulation() <= 2) && (iNeededSeaWorkers > 0))
{
if (iExistingSeaWorkers == 0)
{
// Build workboat first since it doesn't stop growth
if (AI_chooseUnit("capital with no sea workers", UNITAI_WORKER_SEA))
{
return;
}
}
}
if( iExistingWorkers == 0 && AI_totalBestBuildValue(area()) > 0 /*Fuyu: anything bigger than 0 is ok*/ )
{
if (!bChooseWorker && AI_chooseUnit("capital with no workers", UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
/********************************************************************************/
/* Build more early sea workers Fuyu */
/********************************************************************************/
else
{
if (!bWaterDanger && (getPopulation() <= 4) && (iNeededSeaWorkers > 0) && (happyLevel() - unhappyLevel(1)) > 0)
{
if (iExistingSeaWorkers == 0)
{
if (AI_chooseUnit("capital worker", UNITAI_WORKER_SEA))
{
return;
}
}
}
}
/********************************************************************************/
/* Build more early sea workers END */
/********************************************************************************/
}
}
m_iTempBuildPriority--;
if( !bInhibitUnits && !(bDefenseWar && iWarSuccessRatio < -50) && !bDanger )
{
if ((iExistingWorkers == 0))
{
int iLandBonuses = m_iNumImprovableBonuses;
if ((iLandBonuses > 1) || (getPopulation() > 3 && iNeededWorkers > 0))
{
if (!bChooseWorker && AI_chooseUnit("non capital primary worker", UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
if (!bWaterDanger && (iNeededSeaWorkers > iExistingSeaWorkers) && (getPopulation() < 3))
{
if (AI_chooseUnit("secondary sea worker", UNITAI_WORKER_SEA))
{
return;
}
}
if (iLandBonuses >= 1 && getPopulation() > 1)
{
if (!bChooseWorker && AI_chooseUnit("secondary worker", UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
}
}
m_iTempBuildPriority--;
if ( kPlayer.AI_isDoVictoryStrategy(AI_VICTORY_DOMINATION3) )
{
if (iHealth < 1)
{
if ( AI_chooseBuilding(BUILDINGFOCUS_HEALTHY, 20, 0, (kPlayer.AI_isDoVictoryStrategy(AI_VICTORY_DOMINATION4) ? 50 : 20)) )
{
return;
}
}
}
if( GET_TEAM(getTeam()).isAVassal() && GET_TEAM(getTeam()).isCapitulated() )
{
if( !bLandWar )
{
if (iHealth < 1)
{
if (AI_chooseBuilding(BUILDINGFOCUS_HEALTHY, 30, 0, 3*getPopulation()))
{
return;
}
}
if ((getPopulation() > 3) && (getCommerceRate(COMMERCE_CULTURE) < 5))
{
if (AI_chooseBuilding(BUILDINGFOCUS_CULTURE, 30, 0 + 3*iWarTroubleThreshold, 3*getPopulation()))
{
return;
}
}
}
}
m_iTempBuildPriority--;
// -------------------- BBAI Notes -------------------------
// Minimal attack force, both land and sea
if (bDanger && !bInhibitUnits )
{
int iAttackNeeded = 4;
/********************************************************************************/
/* City Defenders 24.07.2010 Fuyu */
/********************************************************************************/
iAttackNeeded += std::max(0, AI_neededDefenders() - (iPlotCityDefenderCount + iPlotOtherCityAICount));
/********************************************************************************/
/* City Defenders END */
/********************************************************************************/
if( kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK) < iAttackNeeded)
{
if (AI_chooseUnit("minimal attack (danger)", UNITAI_ATTACK))
{
return;
}
}
}
m_iTempBuildPriority--;
if (bMaybeWaterArea && !bInhibitUnits)
{
if( !(bLandWar && iWarSuccessRatio < -30) && !bDanger && !bFinancialTrouble )
{
if (kPlayer.AI_getNumTrainAIUnits(UNITAI_ATTACK_SEA) + kPlayer.AI_getNumTrainAIUnits(UNITAI_PIRATE_SEA) + kPlayer.AI_getNumTrainAIUnits(UNITAI_RESERVE_SEA) < std::min(3,kPlayer.getNumCities()))
{
if ((bMaybeWaterArea && bWaterDanger)
|| (pWaterArea != NULL &&
bPrimaryArea &&
kPlayer.AI_countNumAreaHostileUnits(pWaterArea, true, false, false, false, plot(), 15) > 0) )
{
int iLocalNavy = kPlayer.AI_countNumLocalNavy(plot(),4);
if ( iLocalNavy < 2 ) // If there are a few local appropriate AI units already assume they will deal
{
if (AI_chooseUnit("minimal navy", UNITAI_ATTACK_SEA))
{
return;
}
if (AI_chooseUnit("minimal navy", UNITAI_PIRATE_SEA))
{
return;
}
if (AI_chooseUnit("minimal navy", UNITAI_RESERVE_SEA))
{
return;
}
}
}
}
if (NULL != pWaterArea)
{
int iOdds = -1;
if (iAreaBestFoundValue == 0 || iWaterAreaBestFoundValue > iAreaBestFoundValue)
{
iOdds = 100;
}
else if (iWaterPercent > 60)
{
iOdds = 13;
}
if( iOdds >= 0 )
{
if (kPlayer.AI_totalWaterAreaUnitAIs(pWaterArea, UNITAI_EXPLORE_SEA) == 0)
{
if (AI_chooseUnit("sea explorer", UNITAI_EXPLORE_SEA, iOdds))
{
return;
}
}
// BBAI TODO: Really only want to do this if no good area city sites ... 13% chance on water heavy maps
// of slow start, little benefit
if (kPlayer.AI_totalWaterAreaUnitAIs(pWaterArea, UNITAI_SETTLER_SEA) == 0)
{
if (AI_chooseUnit("settler sea", UNITAI_SETTLER_SEA, iOdds))
{
return;
}
}
}
}
}
}
m_iTempBuildPriority--;
// -------------------- BBAI Notes -------------------------
// Top normal priorities
if (!bPrimaryArea && !bLandWar)
{
if (!isHuman() || AI_isEmphasizeYield(YIELD_FOOD))
{
if (AI_chooseBuilding(BUILDINGFOCUS_FOOD, 60, 10 + 2*iWarTroubleThreshold, isHuman() ? -1 : 50))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose BUILDINGFOCUS_FOOD 1", getName().GetCString());
return;
}
}
}
m_iTempBuildPriority--;
if (!bDanger && ((kPlayer.getCurrentEra() > (GC.getGame().getStartEra() + iProductionRank / 2))) || (kPlayer.getCurrentEra() > (GC.getNumEraInfos() / 2)))
{
if (!isHuman() || AI_isEmphasizeYield(YIELD_PRODUCTION))
{
if (AI_chooseBuilding(BUILDINGFOCUS_PRODUCTION, 20 - iWarTroubleThreshold, 15, ((!isHuman() && (bLandWar || bAssault)) ? 25 : -1)))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose BUILDINGFOCUS_PRODUCTION 1", getName().GetCString());
return;
}
}
if( !bInhibitUnits && !(bDefenseWar && iWarSuccessRatio < -30) )
{
if ((iExistingWorkers < ((iNeededWorkers + 1) / 2)))
{
if( getPopulation() > 3 || (iProductionRank < (kPlayer.getNumCities() + 1) / 2) )
{
if (!bChooseWorker && AI_chooseUnit("no danger workers", UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
}
}
}
m_iTempBuildPriority--;
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 (!bInhibitUnits && iTotalFloatingDefenders < ((iNeededFloatingDefenders + 1) / (bGetBetterUnits ? 3 : 2)))
{
if (/*!bUnitExempt && */AI_chooseLeastRepresentedUnit("floating defender", floatingDefenderTypes))// K-Mod
{
return;
}
}
m_iTempBuildPriority--;
// If losing badly in war, need to build up defenses and counter attack force
if( !bInhibitUnits && bLandWar && (iWarSuccessRatio < -30 || iEnemyPowerPerc > 150) )
{
UnitTypeWeightArray defensiveTypes;
defensiveTypes.push_back(std::make_pair(UNITAI_COUNTER, 100));
defensiveTypes.push_back(std::make_pair(UNITAI_ATTACK, 100));
defensiveTypes.push_back(std::make_pair(UNITAI_RESERVE, 60));
defensiveTypes.push_back(std::make_pair(UNITAI_COLLATERAL, 60));
if ( bDanger || (iTotalFloatingDefenders < (5*iNeededFloatingDefenders)/(bGetBetterUnits ? 6 : 4)))
{
defensiveTypes.push_back(std::make_pair(UNITAI_CITY_DEFENSE, 200));
defensiveTypes.push_back(std::make_pair(UNITAI_CITY_COUNTER, 50));
}
int iOdds = iBuildUnitProb;
if( iWarSuccessRatio < -50 )
{
iOdds += abs(iWarSuccessRatio/3);
}
if( bDanger )
{
iOdds += 10;
}
if (AI_chooseLeastRepresentedUnit("extra defense", defensiveTypes, iOdds))
{
return;
}
}
m_iTempBuildPriority--;
if( !bInhibitUnits && !(bDefenseWar && iWarSuccessRatio < -50) )
{
if (!(iExistingWorkers == 0))
{
if (!bDanger && (iExistingWorkers < ((iNeededWorkers + 1) / 2)))
{
if( getPopulation() > 3 || (iProductionRank < (kPlayer.getNumCities() + 1) / 2) )
{
if (!bChooseWorker && AI_chooseUnit("no danger large city extra worker", UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
}
}
}
#if 0
//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 > 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(UNITAI_WORKER))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose worker 5", getName().GetCString());
return;
}
bChooseWorker = true;
}
if (iNeededSeaWorkers > iExistingSeaWorkers)
{
if (AI_chooseUnit(UNITAI_WORKER_SEA))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose worker sea 2", getName().GetCString());
return;
}
}
}
}
#endif
m_iTempBuildPriority--;
if ( m_iTempBuildPriority >= LOW_PRIORITY_ESCORT_PRIORITY )
{
m_iTempBuildPriority = LOW_PRIORITY_ESCORT_PRIORITY - 1;
}
if( !bInhibitUnits && !(bDefenseWar && iWarSuccessRatio < -30) )
{
if (!bWaterDanger && iNeededSeaWorkers > iExistingSeaWorkers)
{
if (AI_chooseUnit("no danger extra sea worker", UNITAI_WORKER_SEA))
{
return;
}
}
}
//TB Build Mod (Moves below to lower priority)
#ifndef C2C_BUILD
if (!bLandWar && !bAssault && (iTargetCulturePerTurn > getCommerceRate(COMMERCE_CULTURE)))
{
if (AI_chooseBuilding(BUILDINGFOCUS_CULTURE, bAggressiveAI ? 10 : 20, 0, bAggressiveAI ? 33 : 50))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses minimal culture rate", getName().GetCString());
return;
}
}
#endif
//TB Build Mod end
m_iTempBuildPriority--;
int iMinFoundValue = kPlayer.AI_getMinFoundValue();
if (bDanger)
{
iMinFoundValue *= 3;
iMinFoundValue /= 2;
}
// BBAI TODO: Check that this works to produce early rushes on tight maps
if (!bInhibitUnits && !bGetBetterUnits && (bIsCapitalArea) && (iAreaBestFoundValue < (iMinFoundValue * 2)))
{
//Building city hunting stack.
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 1a", getName().GetCString());
return;
}
}
int iStartAttackStackRand = 0;
if (pArea->getCitiesPerPlayer(BARBARIAN_PLAYER) > 0)
{
iStartAttackStackRand += 15;
}
if ((pArea->getNumCities() - iNumCitiesInArea) > 0)
{
iStartAttackStackRand += iBuildUnitProb / 2;
}
if( iStartAttackStackRand > 0 )
{
int iAttackCityCount = kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK_CITY);
int iAttackCount = iAttackCityCount + kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK);
if( (iAttackCount) == 0 )
{
if( !bFinancialTrouble )
{
if (AI_chooseUnit("build attack force", UNITAI_ATTACK, iStartAttackStackRand))
{
return;
}
}
}
else
{
if( (iAttackCount > 1) && (iAttackCityCount == 0) )
{
if (AI_chooseUnit("start city attack stack", UNITAI_ATTACK_CITY))
{
return;
}
}
else if (iAttackCityCount < (3 + iBuildUnitProb / 10))
{
if (AI_chooseUnit("add to city attack stack", UNITAI_ATTACK_CITY))
{
return;
}
}
else if (iAttackCount-iAttackCityCount < (3 + iBuildUnitProb / 10))
{
if (AI_chooseUnit("add to attack stack", UNITAI_ATTACK))
{
return;
}
}
}
}
}
m_iTempBuildPriority--;
//opportunistic wonder build (1)
if (!bDanger && (!hasActiveWorldWonder()) && (kPlayer.getNumCities() <= 3))
{
// For small civ at war, don't build wonders unless winning
if( !bLandWar || (iWarSuccessRatio > 30) )
{
/************************************************************************************************/
/* Afforess Start 06/30/10 */
/* */
/* */
/************************************************************************************************/
/*
int iWonderTime = getCitySorenRandNum(GC.getLeaderHeadInfo(getPersonalityType()).getWonderConstructRand(), "Wonder Construction Rand");
*/
int iWonderTime = getCitySorenRandNum(GET_PLAYER(getOwnerINLINE()).getWonderConstructRand(), "Wonder Construction Rand");
/************************************************************************************************/
/* Afforess END */
/************************************************************************************************/
iWonderTime /= 5;
iWonderTime += 7;
if (AI_chooseBuilding(BUILDINGFOCUS_WORLDWONDER, iWonderTime))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses oppurtunistic wonder build 1", getName().GetCString());
return;
}
}
}
m_iTempBuildPriority--;
if (!bDanger && !bIsCapitalArea && area()->getCitiesPerPlayer(getOwnerINLINE()) > iNumCapitalAreaCities)
{
// BBAI TODO: This check should be done by player, not by city and optimize placement
// If losing badly in war, don't build big things
if( !bLandWar || (iWarSuccessRatio > -30) )
{
if( kPlayer.getCapitalCity() == NULL || area()->getPopulationPerPlayer(getOwnerINLINE()) > kPlayer.getCapitalCity()->area()->getPopulationPerPlayer(getOwnerINLINE()) )
{
if (AI_chooseBuilding(BUILDINGFOCUS_CAPITAL, 15))
{
return;
}
}
}
}
m_iTempBuildPriority--;
if (!isHuman() || AI_isEmphasizeYield(YIELD_FOOD))
{
if (AI_chooseBuilding(BUILDINGFOCUS_FOOD, isCapital() ? 5 : 30, 30))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose BUILDINGFOCUS_FOOD 2", getName().GetCString());
return;
}
}
int iSpreadUnitThreshold = 1000;
if( bLandWar )
{
iSpreadUnitThreshold += 800 - 10*iWarSuccessRatio;
}
iSpreadUnitThreshold += 300*plot()->plotCount(PUF_isUnitAIType, UNITAI_MISSIONARY, -1, NULL, getOwnerINLINE());
UnitTypes eBestSpreadUnit = NO_UNIT;
int iBestSpreadUnitValue = -1;
if( !bInhibitUnits && !bDanger && !(kPlayer.AI_isDoStrategy(AI_STRATEGY_TURTLE)) )
{
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;
}
}
}
}
m_iTempBuildPriority--;
/************************************************************************************************/
/* RevolutionDCM Inquisitions 01/29/10 Afforess */
/* */
/* */
/************************************************************************************************/
if (!bInhibitUnits && AI_trainInquisitor())
{
return;
}
/************************************************************************************************/
/* RevolutionDCM END */
/************************************************************************************************/
if( !isHuman() && !(bLandWar && iWarSuccessRatio < 30) )
{
if (!bDanger && (iProductionRank <= ((kPlayer.getNumCities() / 5) + 1)))
{
// BBAI TODO: Temporary for testing
//if( getOwnerINLINE()%2 == 1 )
//{
if (AI_chooseProject())
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose project 1", getName().GetCString());
return;
}
//}
}
}
m_iTempBuildPriority--;
//minimal defense.
/********************************************************************************/
/* City Defenders 24.07.2010 Fuyu */
/********************************************************************************/
int iPlotSettlerEscortCityDefenseCount = plot()->plotCount(PUF_isUnitAIType, UNITAI_CITY_COUNTER, -1,NULL, getOwnerINLINE()) - (AI_minDefenders()+1);
int iPlotSettlerEscortCounterCount = plot()->plotCount(PUF_isUnitAIType, UNITAI_CITY_COUNTER, -1, NULL, getOwnerINLINE());
int iPlotSettlerEscortCount = iPlotSettlerEscortCityDefenseCount + iPlotSettlerEscortCounterCount;
if (!bInhibitUnits && iPlotSettlerCount > 0 && iPlotSettlerEscortCount < (iPlotSettlerCount * 4))
//if (!bInhibitUnits && iPlotCityDefenderCount + iPlotOtherCityAICount < (AI_minDefenders() + iPlotSettlerCount))
//if (!bUnitExempt && !bInhibitUnits && iPlotCityDefenderStrength + iPlotOtherCityAIStrength < (AI_minDefenseStrength() + iPlotSettlerCount*GET_PLAYER(getOwnerINLINE()).strengthOfBestUnitAI(DOMAIN_LAND, UNITAI_CITY_DEFENSE))) //k-mod
{
if (AI_chooseUnit("min defender", UNITAI_CITY_DEFENSE))
{
return;
}
if (AI_chooseUnit("min defender", UNITAI_CITY_COUNTER))
{
return;
}
if (AI_chooseUnit("min defender", UNITAI_CITY_DEFENSE))
{
return;
}
if (AI_chooseUnit("min defender", UNITAI_CITY_COUNTER))
{
return;
}
if (AI_chooseUnit("min defender", UNITAI_CITY_SPECIAL))
{
return;
}
if (AI_chooseUnit("min defender", UNITAI_RESERVE))
{
return;
}
if (AI_chooseUnit("min defender", UNITAI_ATTACK))
{
return;
}
//Fuyu bIgnoreNotUnitAIs
if (iNumCitiesInArea <= 3)
{
if (AI_chooseUnit("min defender (any unit)", UNITAI_CITY_DEFENSE, -1, 1))
{
return;
}
}
}
/********************************************************************************/
/* City Defenders END */
/********************************************************************************/
m_iTempBuildPriority--;
// Afforess - don't wait until we are in trouble, preventative medicine is best
int iFundedPercent = kPlayer.AI_costAsPercentIncome();
int iSafePercent = kPlayer.AI_safeCostAsPercentIncome();
// if ( bFinancialTrouble )
if (iFundedPercent < iSafePercent - 10)
{
if (AI_chooseBuilding(BUILDINGFOCUS_GOLD, 10))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses financial difficulty resolution", getName().GetCString());
return;
}
}
m_iTempBuildPriority--;
if( !bInhibitUnits && !(bDefenseWar && iWarSuccessRatio < -50) )
{
if ((iAreaBestFoundValue > iMinFoundValue) || (iWaterAreaBestFoundValue > iMinFoundValue))
{
// BBAI TODO: Needs logic to check for early settler builds, settler builds in small cities, whether settler sea exists for water area sites?
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)
{
/********************************************************************************/
/* Build more workers #1.1 Fuyu */
/********************************************************************************/
/* financial trouble: 2/3; */
if (!bDanger && bFinancialTrouble && (iExistingWorkers < ((2*iNeededWorkers) + 2)/3))
{
if ((AI_getWorkersNeeded() > 0) && (AI_getWorkersHave() == 0))
{
if( getPopulation() > 1 || (GC.getGameINLINE().getGameTurn() - getGameTurnAcquired() > (15 * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent())/100) )
{
if (!bChooseWorker && AI_chooseUnit("worker needed", UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
}
}
/********************************************************************************/
/* Build more workers #1.1 END */
/********************************************************************************/
if (AI_chooseUnit("sea settler needed", UNITAI_SETTLER_SEA))
{
return;
}
}
}
if (iPlotSettlerCount == 0)
{
if ((iNumSettlers < iMaxSettlers))
{
if (getCitySorenRandNum(2, "settler training decision") < (bLandWar ? 1 : 2))
{
/********************************************************************************/
/* Build more workers #1.2 Fuyu */
/********************************************************************************/
/* financial trouble: 2/3; */
if (!bDanger && bFinancialTrouble && (iExistingWorkers < ((2*iNeededWorkers) + 2)/3))
{
if ((AI_getWorkersNeeded() > 0) && (AI_getWorkersHave() == 0))
{
if( getPopulation() > 1 || (GC.getGameINLINE().getGameTurn() - getGameTurnAcquired() > (15 * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent())/100) )
{
if (!bChooseWorker && AI_chooseUnit("worker needed 2", UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
}
}
/********************************************************************************/
/* Build more workers #1.2 END */
/********************************************************************************/
/********************************************************************************/
/* City Defenders 24.07.2010 Fuyu */
/********************************************************************************/
if ((kPlayer.getNumMilitaryUnits() <= (kPlayer.getNumCities() + iNumSettlers + 1))
//Fuyu: in the beginning, don't count on other cities to build the escorts
|| (kPlayer.getNumCities() <= 7 && iNumCitiesInArea <= 3 && (plot()->plotCount(PUF_canDefendGroupHead, -1, -1, NULL, getOwnerINLINE(), NO_TEAM, PUF_isCityAIType) <= 1)))
{
if (AI_chooseUnit("extra quick defender", UNITAI_CITY_DEFENSE))
{
return;
}
//Fuyu bIgnoreNotUnitAIs
if (iNumCitiesInArea <= 3)
{
CvUnitSelectionCriteria criteria;
criteria.m_bIgnoreNotUnitAIs = true;
if (AI_chooseUnit("extra quick defender (any unit)", UNITAI_CITY_DEFENSE, -1, -1, -1, &criteria))
{
return;
}
}
if (AI_chooseUnit("extra quick defender", UNITAI_CITY_COUNTER))
{
return;
}
if (AI_chooseUnit("extra quick defender", UNITAI_CITY_SPECIAL))
{
return;
}
if (AI_chooseUnit("extra quick defender", UNITAI_RESERVE))
{
return;
}
}
/********************************************************************************/
/* City Defenders END */
/********************************************************************************/
if (AI_chooseUnit("settler needed", UNITAI_SETTLE) )
{
return;
}
}
}
}
}
}
m_iTempBuildPriority--;
/********************************************************************************/
/* Build more workers #2 Fuyu */
/********************************************************************************/
if( !bInhibitUnits && !(bLandWar && iWarSuccessRatio < 0) && !bDanger && !bBestWorkerIsOneShot) // KOSHLING - don't build frivolous one-shot workers like this
{
/* financial trouble: ---; will grow above happy cap: 2/3; both: 3/4; else 4/7 */
if ( (iExistingWorkers < ((4*iNeededWorkers) + 6)/7)
/* || (bFinancialTrouble && (iExistingWorkers < (((2*iNeededWorkers) + 1)/3))) */
|| (((iExistingWorkers < ((2*iNeededWorkers) + 2)/3) || (bFinancialTrouble && (iExistingWorkers < (((3*iNeededWorkers) + 3)/4))))
&& (((happyLevel() - unhappyLevel()) <= 0) && (foodDifference(false) > 0 || (foodDifference(false) == 0 && happyLevel() - unhappyLevel() < 0)))) )
{
if ((AI_getWorkersNeeded() > 0) && (AI_getWorkersHave() == 0))
{
if( getPopulation() > 2 || (GC.getGameINLINE().getGameTurn() - getGameTurnAcquired() > (15 * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent())/100) )
{
if (!bChooseWorker && AI_chooseUnit("worker for established city", UNITAI_WORKER))
{
return;
// Koshling - the following is not operatiional with the unit tendering system, and I can't quite fuigure out what it was for anyway, so
// deactivated for now
//if (!isFoodProduction() && ((happyLevel() - unhappyLevel()) <= 0)
// && getProductionUnit() != NO_UNIT && getUnitProduction(getProductionUnit()) == 0)
//{
// popOrder(0);
// bChooseWorker = true;
//Already set by chooseUnit but I'm not taking any chances
// if ((getTeam() == GC.getGameINLINE().getActiveTeam()) || GC.getGameINLINE().isDebugMode())
// {
// setInfoDirty(true);
// if (isCitySelected())
// {
// gDLL->getInterfaceIFace()->setDirty(InfoPane_DIRTY_BIT, true );
// gDLL->getInterfaceIFace()->setDirty(SelectionButtons_DIRTY_BIT, true);
// gDLL->getInterfaceIFace()->setDirty(CityScreen_DIRTY_BIT, true);
// gDLL->getInterfaceIFace()->setDirty(PlotListButtons_DIRTY_BIT, true);
// }
// }
//}
//else
//{
// if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose worker 6b", getName().GetCString());
// return;
//}
}
bChooseWorker = !bChooseWorker;
}
}
}
}
/********************************************************************************/
/* Build more workers #2 END */
/********************************************************************************/
m_iTempBuildPriority--;
//this is needed to build the cathedrals quickly
//also very good for giving cultural cities first dibs on wonders
if (!isHuman() || AI_isEmphasizeCommerce(COMMERCE_CULTURE))
{
if (bImportantCity && (iCultureRateRank <= iCulturalVictoryNumCultureCities))
{
if (iCultureRateRank == iCulturalVictoryNumCultureCities)
{
if (AI_chooseBuilding(BUILDINGFOCUS_BIGCULTURE | BUILDINGFOCUS_CULTURE | BUILDINGFOCUS_WONDEROK, 40))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses cultural victory 1", getName().GetCString());
return;
}
}
else if (getCitySorenRandNum(((iCultureRateRank == 1) ? 4 : 1) + iCulturalVictoryNumCultureCities * 2 + (bLandWar ? 5 : 0), "AI Build up Culture") < iCultureRateRank)
{
if (AI_chooseBuilding(BUILDINGFOCUS_BIGCULTURE | BUILDINGFOCUS_CULTURE | BUILDINGFOCUS_WONDEROK, (bLandWar ? 20 : 40)))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses cultural victory 2", getName().GetCString());
return;
}
}
}
}
m_iTempBuildPriority--;
// don't build frivolous things if this is an important city unless we at war
if (!bInhibitUnits && (!bImportantCity || bLandWar || bAssault))
{
// Koshling in early game moved optional non-wartime attack unit builds below economy
if (bPrimaryArea && kPlayer.getCurrentEra() != 0)
{
if (kPlayer.AI_totalAreaUnitAIs(pArea, UNITAI_ATTACK) == 0)
{
if (AI_chooseUnit("optional attack", UNITAI_ATTACK))
{
return;
}
}
}
if ((bMassing || !bLandWar) && !bDanger && !bFinancialTrouble)
{
// Normalize them by the ideally needed numbers (which are not limited by our number of cities and
// reflect the geography only)
iExplorerDeficitPercent *= kPlayer.AI_neededExplorers(pArea, true);
iHunterDeficitPercent *= kPlayer.AI_neededHunters(pArea, true);
if ( iExplorerDeficitPercent >= iHunterDeficitPercent && iExplorerDeficitPercent > 0 )
{
// If we are just pumping out explorer units and having them die fast
// go for EXP giving buildings first
UnitTypes eBestUnit = AI_bestUnitAI(UNITAI_EXPLORE, iUnitValue);
if ( eBestUnit != NO_UNIT )
{
if ( isCapital() )
{
// What is the cost of one of these units?
int iCost = (GC.getUnitInfo(eBestUnit).getProductionCost() * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent()) / 100;
int perTurnLossesCost = (iCost*area()->getRecentCombatDeathRate(getOwnerINLINE(), UNITAI_EXPLORE))/100;
if( gCityLogLevel >= 2 )
{
logBBAI(" City %S evaluating recent explorer deaths - %d per/turn cost vs %d production",
getName().GetCString(),
perTurnLossesCost,
GET_PLAYER(getOwnerINLINE()).calculateTotalYield(YIELD_PRODUCTION));
}
if ( perTurnLossesCost > GET_PLAYER(getOwnerINLINE()).calculateTotalYield(YIELD_PRODUCTION)/6 )
{
if (AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, 30))
{
return;
}
}
}
if (AI_chooseUnit("need explorers", UNITAI_EXPLORE))
{
return;
}
}
}
if (iHunterDeficitPercent > 0)
{
// If we are just pumping out hunting units and having them die fast
// go for EXP giving buildings first
UnitTypes eBestUnit = AI_bestUnitAI(UNITAI_HUNTER, iUnitValue, false);
if ( eBestUnit != NO_UNIT )
{
// What is the cost of one of these units?
int iCost = (GC.getUnitInfo(eBestUnit).getProductionCost() * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent()) / 100;
int perTurnLossesCost = (iCost*area()->getRecentCombatDeathRate(getOwnerINLINE(), UNITAI_HUNTER))/100;
if( gCityLogLevel >= 2 )
{
logBBAI(" City %S evaluating recent hunter deaths - %d per/turn cost vs %d production",
getName().GetCString(),
perTurnLossesCost,
GET_PLAYER(getOwnerINLINE()).calculateTotalYield(YIELD_PRODUCTION));
}
if ( perTurnLossesCost > GET_PLAYER(getOwnerINLINE()).calculateTotalYield(YIELD_PRODUCTION)/6 )
{
if (AI_chooseBuilding(BUILDINGFOCUS_EXPERIENCE, 30))
{
return;
}
}
if (AI_chooseUnit("need hunters", UNITAI_HUNTER))
{
return;
}
}
}
}
if( bDefenseWar || (bLandWar && (iWarSuccessRatio < -30)) )
{
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("panic defender", panicDefenderTypes, (bGetBetterUnits ? 40 : 60) - iWarSuccessRatio/3))
{
return;
}
}
}
m_iTempBuildPriority--;
/************************************************************************************************/
/* Afforess Start 1/22/12 */
/* */
/* Encourage Aggressive AI to stock up on a few nukes */
/************************************************************************************************/
if (!bInhibitUnits && !bAlwaysPeace && (GC.getGameINLINE().isOption(GAMEOPTION_RUTHLESS_AI) || kPlayer.isEnabledMAD() || (getCitySorenRandNum(10, "AI consider Nuke") == 0)))
{
if(!bFinancialTrouble)
{
int iTotalNukes = kPlayer.AI_totalUnitAIs(UNITAI_ICBM);
//keep between 3 to 8 nukes, at least for early considerations
int iNukesNeeded = std::max(3, std::min((GC.getGame().getNumCities() - kPlayer.getNumCities()) / 5, 8));
if (iTotalNukes < iNukesNeeded)
{
//Reordered, because nukes are more valuable than carriers
if (AI_chooseUnit("ICBM", UNITAI_ICBM))
{
return;
}
}
}
}
/************************************************************************************************/
/* Afforess END */
/************************************************************************************************/
m_iTempBuildPriority--;
if (!isHuman() || AI_isEmphasizeYield(YIELD_FOOD))
{
if (AI_chooseBuilding(BUILDINGFOCUS_FOOD, 60, 10, (bLandWar ? 30 : -1)))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose BUILDINGFOCUS_FOOD 3", getName().GetCString());
return;
}
}
m_iTempBuildPriority--;
//opportunistic wonder build
if (!isHuman() && !bDanger && (!hasActiveWorldWonder() || (kPlayer.getNumCities() > 3)))
{
// For civ at war, don't build wonders if losing
if( !bLandWar || (iWarSuccessRatio > -30) )
{
/************************************************************************************************/
/* Afforess Start 06/30/10 */
/* */
/* */
/************************************************************************************************/
/*
int iWonderTime = getCitySorenRandNum(GC.getLeaderHeadInfo(getPersonalityType()).getWonderConstructRand(), "Wonder Construction Rand");
*/
int iWonderTime = getCitySorenRandNum(GET_PLAYER(getOwnerINLINE()).getWonderConstructRand(), "Wonder Construction Rand");
/************************************************************************************************/
/* Afforess END */
/************************************************************************************************/
iWonderTime /= 5;
iWonderTime += 8;
if (AI_chooseBuilding(BUILDINGFOCUS_WORLDWONDER, iWonderTime))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses oppurtunistic wonder build 2", getName().GetCString());
return;
}
}
}
m_iTempBuildPriority--;
if( !bInhibitUnits && !(bLandWar && iWarSuccessRatio < -30) && !bDanger )
{
if (iExistingWorkers < iNeededWorkers )
{
if ((AI_getWorkersNeeded() > 0) && (AI_getWorkersHave() == 0))
{
if( getPopulation() > 1 || (GC.getGameINLINE().getGameTurn() - getGameTurnAcquired() > (15 * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getTrainPercent())/100) )
{
if (!bChooseWorker && AI_chooseUnit("established city needs more workers", UNITAI_WORKER))
{
return;
}
bChooseWorker = true;
}
}
}
}
m_iTempBuildPriority--;
// semi-urgent property control (bad property > 15% through op range - choose unit to deal if possible)
if ( AI_choosePropertyControlUnit( 15 ) )
{
return;
}
m_iTempBuildPriority--;
//essential economic builds
if (AI_chooseBuilding(iEconomyFlags, 10, (iEcononmyFlagsThreasholdWeighting*(25 + iWarTroubleThreshold))/100, (bLandWar && !isHuman() ? 40 : -1)))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S uses choose iEconomyFlags 1", getName().GetCString());
return;
}
m_iTempBuildPriority--;
/************************************************************************************************/
/* Afforess Start 07/28/10 */
/* */
/* */
/************************************************************************************************/
if ((isCapital() || getYieldRate(YIELD_PRODUCTION) > std::min(70, std::max(40, iNumCitiesInArea * 6))) && !bDanger)
{
if (bFinancialTrouble)
{
if (AI_chooseProcess(COMMERCE_GOLD))
{
if( gCityLogLevel >= 2 ) logBBAI(" City %S chooses to build wealth due to financial trouble", getName().GetCString());
return;
}
}
}
m_iTempBuildPriority--;
// normal running property control (bad property > 10% through op range - choose unit to deal if possible)
if ( AI_choosePropertyControlUnit( 10 ) )
{
return;
}
m_iTempBuildPriority--;
/************************************************************************************************/
/* Afforess END */
/************************************************************************************************/
if( !bInhibitUnits && !bDanger )
{
if (iBestSpreadUnitValue > ((iSpreadUnitThreshold * (bLandWar ? 80 : 60)) / 100))
{
if (AI_chooseUnit(eBestSpreadUnit, UNITAI_MISSIONARY))
{
return;
}
}
}