void CvGame::createBarbarianCities() {
CvPlot* pLoopPlot;
CvPlot* pBestPlot;
long lResult;
int iTargetCities;
int iValue;
int iBestValue;
int iI;
if (getMaxCityElimination() > 0) {
return;
}
if (isOption(GAMEOPTION_NO_BARBARIANS)) {
[COLOR="Red"]// No barbarians enabled, no cities spawning...[/COLOR]
return;
}
lResult = 0;
gDLL->getPythonIFace()->callFunction(PYGameModule, "createBarbarianCities", NULL, &lResult);
[COLOR="Red"]// Not sure what this is... perhaps if Python spawns a city, we don't do it in C++ ? [/COLOR]
if (lResult == 1) {
return;
}
if (GC.getEraInfo(getCurrentEra()).isNoBarbCities()) {
[COLOR="Red"]// Late enough era -> No barbarians spawned. This should be in some XML which era is specified in
Civ4EraInfos.xml (this wasn't available on the wiki[/COLOR]
return;
}
if (GC.getHandicapInfo(getHandicapType()).getUnownedTilesPerBarbarianCity() <= 0) {
[COLOR="Red"]// From quite extensive diving, I have concluded that a plot (the code name for what we usually call "tile"),
is "Owned" if it is either a city, OR is under the cultural influence of a city.
A continent with many creative players, will have far less unowned tiles early. [/COLOR]
return;
}
if (getNumCivCities() < (countCivPlayersAlive() * 2)) {
[COLOR="Red"]// Worth to notice that this is map-wide, most other things look at the continens.[/COLOR]
return;
}
if (getElapsedGameTurns() < (((GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationTurnsElapsed() * GC.getGameSpeedInfo(getGameSpeedType()).getBarbPercent()) / 100) / std::max(getStartEra() + 1, 1))) { [COLOR="Red"]// This is turn 40 on noble, turn 15 on deity.[/COLOR]
return;
}
if (getSorenRandNum(100, "Barb City Creation") >= GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationProb()) {
[COLOR="Red"]//the cityCreationProb is 6 on noble and 8 on deity.
And this is probably the reason why barb cities are so irregular.[/COLOR]
return;
}
iBestValue = 0;
pBestPlot = NULL;
int iTargetCitiesMultiplier = 100;
{
int iTargetBarbCities = (getNumCivCities() * 5 * GC.getHandicapInfo(getHandicapType()).getBarbarianCityCreationProb()) / 100;
[COLOR="Red"]// getBarbarianCityProb is 8 on deity. so if we are playing with 6 AIs
(7 player total. And all AIs settle their first city, there would be 13 * 5 * 8 / 100 = 1.95 [/COLOR]
int iBarbCities = GET_PLAYER(BARBARIAN_PLAYER).getNumCities();
if (iBarbCities < iTargetBarbCities) {
iTargetCitiesMultiplier += (300 * (iTargetBarbCities - iBarbCities)) / iTargetBarbCities;
[COLOR="Red"] with one barb city: 300 * (1.95 - 1) / 1.95 = 146[/COLOR]
}
if (isOption(GAMEOPTION_RAGING_BARBARIANS)) {
iTargetCitiesMultiplier *= 3;
iTargetCitiesMultiplier /= 2;
}
}
for (iI = 0; iI < GC.getMapINLINE().numPlotsINLINE(); iI++) {
pLoopPlot = GC.getMapINLINE().plotByIndexINLINE(iI);
if (!(pLoopPlot->isWater())) {
if (!(pLoopPlot->isVisibleToCivTeam())) {
iTargetCities = pLoopPlot->area()->getNumUnownedTiles();
[COLOR="Red"]//If we have a small island of 20 tiles, with one barb city
spawned in the middle of it, we would have a iTargetCities of 20 - 9 = 11 here.[/COLOR]
if (pLoopPlot->area()->getNumCities() == pLoopPlot->area()->getCitiesPerPlayer(BARBARIAN_PLAYER)) {
iTargetCities *= 3;
[COLOR="Red"]// Since there was only barb cities on this island, the number would get trippled.. 11 * 3 = 33.[/COLOR]
}
int iUnownedTilesThreshold = GC.getHandicapInfo(getHandicapType()).getUnownedTilesPerBarbarianCity(); [COLOR="Red"]// This is defined in Civ4HandicapInfo.xml, defined as 130 on noble and as 80 on deity.[/COLOR]
if (pLoopPlot->area()->getNumTiles() < (iUnownedTilesThreshold / 3)) {
[COLOR="Red"]// If 33 < (60 / 3) no... 33 is not less than 20. This would not be done in our example. [/COLOR]
iTargetCities *= iTargetCitiesMultiplier;
iTargetCities /= 100;
}
iTargetCities /= std::max(1, iUnownedTilesThreshold);
if (pLoopPlot->area()->getCitiesPerPlayer(BARBARIAN_PLAYER) < iTargetCities) {
iValue = GET_PLAYER(BARBARIAN_PLAYER).AI_foundValue(pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE(), GC.getDefineINT("MIN_BARBARIAN_CITY_STARTING_DISTANCE"));
[COLOR="Red"] // The code in AI_foundValue was 400 lines of total mystery.
It takes most of the factors under consideration though, much like human players. [/COLOR]
if (iTargetCitiesMultiplier > 100) {
iValue *= pLoopPlot->area()->getNumOwnedTiles();
}
iValue += (100 + getSorenRandNum(50, "Barb City Found"));
iValue /= 100;
if (iValue > iBestValue) {
[COLOR="Red"] // This will just weight all possible city locations against each other, keeping the best one in mind at each iteration. [/COLOR]
iBestValue = iValue;
pBestPlot = pLoopPlot;
}
}
}
}
}
if (pBestPlot != NULL) { [COLOR="Red"]
GET_PLAYER(BARBARIAN_PLAYER).found(pBestPlot->getX_INLINE(), pBestPlot->getY_INLINE());
}
}