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
Of course you have to know changeculturetimes100, which is basically setculturetimes100, which uses doplotculture
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
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.
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;
}
}
}
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.