using the 3.19 culture bomb and spread culture

vicawoo

Chieftain
Joined
Feb 12, 2007
Messages
3,226
Having learned the secret to reading civilization code and having free time to do so while re-reading the posts on culture during the holidays, I present the secrets of the 3.19 spread culture tile spread and BTS great works, and attempts and limitations of (ab)using it in the second post. To be honest, I hoped there were threads or updated threads that were explicit about this, but that is not the case.

BTS great work
Spoiler cvunit.cpp excerpt :
Code:
bool CvUnit::greatWork()
{
	if (!canGreatWork(plot()))
	{
		return false;
	}

	CvCity* pCity = plot()->getPlotCity();

	if (pCity != NULL)
	{
		pCity->setCultureUpdateTimer(0);
		pCity->setOccupationTimer(0);

		int iCultureToAdd = 100 * getGreatWorkCulture(plot());
		int iNumTurnsApplied = (GC.getDefineINT("GREAT_WORKS_CULTURE_TURNS") * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getUnitGreatWorkPercent()) / 100;

		for (int i = 0; i < iNumTurnsApplied; ++i)
		{
			pCity->changeCultureTimes100(getOwnerINLINE(), iCultureToAdd / iNumTurnsApplied, true, true);
		}

		if (iNumTurnsApplied > 0)
		{
			pCity->changeCultureTimes100(getOwnerINLINE(), iCultureToAdd % iNumTurnsApplied, false, true);
		}
	}

	if (plot()->isActiveVisible(false))
	{
		NotifyEntity(MISSION_GREAT_WORK);
	}

	kill(true);

	return true;
}

Of course you have to know changeculturetimes100, which is basically setculturetimes100, which uses doplotculture
Code:
void CvCity::setCultureTimes100(PlayerTypes eIndex, int iNewValue, bool bPlots, bool bUpdatePlotGroups)
{
	FAssertMsg(eIndex >= 0, "eIndex expected to be >= 0");
	FAssertMsg(eIndex < MAX_PLAYERS, "eIndex expected to be < MAX_PLAYERS");

	if (getCultureTimes100(eIndex) != iNewValue)
	{
		m_aiCulture[eIndex] = iNewValue;
		FAssert(getCultureTimes100(eIndex) >= 0);

		updateCultureLevel(bUpdatePlotGroups);

		if (bPlots)
		{
			doPlotCulture(true, eIndex, 0);
		}
	}
}

Code:
void CvCity::doPlotCulture(bool bUpdate, PlayerTypes ePlayer, int iCultureRate)
{
	CvPlot* pLoopPlot;
	int iDX, iDY;
	int iCultureRange;
	CultureLevelTypes eCultureLevel = (CultureLevelTypes)0;

	CyCity* pyCity = new CyCity(this);
	CyArgsList argsList;
	argsList.add(gDLL->getPythonIFace()->makePythonObject(pyCity));	// pass in city class
	argsList.add(bUpdate);
	argsList.add(ePlayer);
	argsList.add(iCultureRate);
	long lResult=0;
	gDLL->getPythonIFace()->callFunction(PYGameModule, "doPlotCulture", argsList.makeFunctionArgs(), &lResult);
	delete pyCity;	// python fxn must not hold on to this pointer 
	if (lResult == 1)
	{
		return;
	}

	FAssert(NO_PLAYER != ePlayer);

	if (getOwnerINLINE() == ePlayer)
	{
		eCultureLevel = getCultureLevel();
	}
	else
	{
		for (int iI = (GC.getNumCultureLevelInfos() - 1); iI > 0; iI--)
		{
			if (getCultureTimes100(ePlayer) >= 100 * GC.getGameINLINE().getCultureThreshold((CultureLevelTypes)iI))
			{
				eCultureLevel = (CultureLevelTypes)iI;
				break;
			}
		}
	}

The nerf is this line
doPlotCulture(true, eIndex, 0)
Instead of adding whatever culture per turn you are producing, you add 0, that third term. For reference, you add the 4000 culture in increments presumably 20 times. Each time you add the culture, you update the city's cultural level, then add plot culture, which for a tile in the ith cultural level is 20*(city culture level-ith cultural level).
It's mostly explained here http://forums.civfanatics.com/showthread.php?t=225927
As people have suspected, it's pretty much the same as the pre-BTS culture bomb on a city producing 0 culture per turn. Everyone says it was a huge nerf, but before you can output 100s of culture per turn it was never great at switching over inner culture rings. The main functional difference is that the tiles in the outer culture ring amass a total of 0 culture from your culture bomb, switching over nothing, whereas before even 5 culture per turn would pump almost 100 tile culture into those areas and have a decent chance of switching over those fringe territories.

Spread culture mission
Spoiler cvplayer.cpp excerpt :
Code:
	if (kMission.getCityInsertCultureCostFactor() > 0)
	{
		if (NULL != pPlot)
		{
			CvCity* pCity = pPlot->getPlotCity();

			if (NULL != pCity)
			{
				szBuffer = gDLL->getText("TXT_KEY_ESPIONAGE_TARGET_CITY_CULTURE_INSERTED", pCity->getNameKey()).GetCString();				

				int iCultureAmount = kMission.getCityInsertCultureAmountFactor() * pCity->countTotalCultureTimes100();
				iCultureAmount /= 10000;
				iCultureAmount = std::max(1, iCultureAmount);
				
				int iNumTurnsApplied = (GC.getDefineINT("GREAT_WORKS_CULTURE_TURNS") * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getUnitGreatWorkPercent()) / 100;

				for (int i = 0; i < iNumTurnsApplied; ++i)
				{
					pCity->changeCulture(getID(), iCultureAmount / iNumTurnsApplied, true, true);
				}

				if (iNumTurnsApplied > 0)
				{
					pCity->changeCulture(getID(), iCultureAmount % iNumTurnsApplied, false, true);
				}

				bSomethingHappened = true;
			}

		}
	}
What it does: multiplies city culture by 5% rounded down, or technically multiplies insertcultureamounterfactor, multiplies by 100, then divides by 10000.
Then it adds that amount to the city culture using the great work mechanic: it adds the culture fraction by fraction in a certain number of "turns". It adds tile culture (but only the 20*(culture border level-distance from city)) during each of those turns. Then it adds any culture leftover from dividing by that number once, without updating the culture.

Or in short, you add 5% to the city plot, and do 20 0 culture tile culture additions.
Explained earlier, tile culture notwithstanding here http://forums.civfanatics.com/showthread.php?t=286229
Since revolt is based on the tile culture of the city, not the city culture itself, you'd have to do possibly hundreds of missions to force a revolt in a well-established city, so you really should conquer these cities after spread culture to a planned level.
 
Using and abusing: (will fill in)

So when can you use a great work to convert a city? If one great artist can force a revolt, that can be a lot cheaper than conquering a city by force.

Revolting the capital with a great work alone is pretty much impossible. First of all, after 50 turns his city tile will be gaining 40+ culture per turn. Even if you drop a city 3 tiles away, it will only be able to induce 17 great work turns of 20 culture per great work turn, initially, and 20 culture per turn afterwards. You do have a good chance of cutting off the tiles on your side, though.
If you use a second great artist, you will surpass the 5000 culture mark, and you will gain 15 great work turns of 40 culture per turn, so if your city produces more culture per turn than him, you will have a shot at converting his capital before his next border pop.

Unfortunately, I doubt one capital is worth two great artists + further investment.

A great work will have a shot at revolting a city with a single border pop, though.

If you can get two or more such cities within 3 tiles of your great work city, it could easily be worth the great work.

---

Spread culture:
it takes 20.5 successful mission to double a cities culture. So 20 missions will give you 50,000 culture on a 50000 culture city, 41 a 25000 culture city. Don't bother waiting for a revolt, save your espionage and just conquer it the old fashioned way (perhaps with a riot).

an idea for stealing a cultural win:
pump espionage of course.
invade a border/coastal city next to the first legendary city. great work (important, you must reach other cities and it will save turns) and great engineer a forbidden/palace/versailles, or just rush buy the palace.
change religions if necessary, spread culture to sufficient level, conquer, repeat.

I'll have to clean this up later
 
Back
Top Bottom