Single Player bugs and crashes v36 plus (SVN) - After the 24th of October 2015

Status
Not open for further replies.
Still nothing.... Other mods work normally, but C2C doesn't even start.

What have you done differently this time that you didn't do 2 months ago?

And what do you mean by "C2C doesn't even start"?

Do you still have a C2C shortcut?

If you re-installed BtS did you remember to manually patch it to the Official 3.19 patch?

Need details to help, lots of details. ;)

JosEPh :)
 
Well... I came back, so as always I've clicked SVN Update.
After that my shortcut didn't start the game. Because I saw, that there were some conflicts in SVN I've decided to delete contents of Caveman2Cosmos folder and download it again. It didn't help at all.
So next thing I've done was reinstalling Civ4 - Complete version. It is updated to 3.19.

When I try to run shortcut with C2C, my cursor changes to ... "thinking(?)" one and after few seconds everything goes back to normal - nothing happens.

I can run BtS normally, without any problems. I can run other mods from Load a Mod menu, but when I try loading C2C game shuts down and nothing happens....
 
but when I try loading C2C game shuts down and nothing happens....

Again try what i put in the other post, try that like 5 times, BUT you MUST start BtS 1st. And if its stopping after that, you have a BAD install, re-download everything . . if you have a conflict in the SVN, take OUT(delete) the "conflicting" files, and do an update again, keep that going till its ok . .
 
@ 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?
 
@ 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.
 
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.

Yeah never use that, wish we could delete that has never worked anyways . .
I just use what ever the default stuff is on attacks. .
 
So you get the animations and when you click to attack, regardless of how many you have selected you'll attack one at a time right?

There COULD be some further issues lurking with other types of combat resolutions like withdrawal. Now that things are working it could expose more that wasn't right to begin with.
 
Bad timing, I'm going to be away from my computer until early february, and I won't have time before I leave. :sad:
Perhaps the sea textures in my texture pack works as they should, they are pretty much redone.

Stay in touch with us at least my friend. I'll have lots of work for you when you return ;) Too bad we're losing you for so long - it'll be like waiting for the walking dead to come back on tv!
 
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

----------------------------------------------------------
 
it'll be like waiting for the walking dead to come back on tv!

[offtopic]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.
 
[offtopic]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.

lol... losing lori was the best thing they did. Funny how opinions can differ. That said, I don't think she's dead but... this is a little off topic.
 
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

----------------------------------------------------------

Turn off the new mod I made, ie move it from My_Mods into My_Mods(Unloaded) on the SVN. No idea why it is not there as it should have been.

BtW I have always used both Stack Attack options and they worked well until we started to mess with combat.
 
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.
 
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??
 
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??

I got v11, 16, 19, 21, 22 of C2C. The rest can be found on the SVN iirc. I know v27 thru v36 can be. I had more but lost v1 thru 10 to a HD crash couple of years ago.

Plus Rise of Mankind v1.03 , 2.5, 2.71, 2.81, and 2.92.

I may have some early AND on my older Comp too.

JosEPh
 
"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...

Ok, I THINK I've made some headway here. Apparently it's somehow possible for cities to evaluate all the way through all possibilities and come up with no answer for what to set to build so I've built a failsafe mousetrap at the end to make sure that it at least picks a valuable process.

I'm sure there are plenty of places this selection routine could be improved but if you'd like to go through it line by line, be my guest.:
Part I
Spoiler :
Code:
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;
		}
	}

I'm compiling and testing the new 'mousetrap' now.
 
Part II
Spoiler :
Code:
	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;
    		}
 
Part III
Spoiler :
Code:
			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;
			}
		}
	}
 
Status
Not open for further replies.
Back
Top Bottom