How is the player benefiting from liberation via conquest being determined?
Ok, for this we turn to CvCity and there into
getLiberationPlayer. This method is used at multiple points in the game, but important for us also to get the player in question. There are three important parts to this method. The first part is uninteresting for us. It only concerns split empires (colony stuff), which we rarely use and the other part in there is that a capitol city can't be liberated to any player, which should be obvious. The next part gets more interesting:
Code:
PlayerTypes eBestPlayer = NO_PLAYER;
int iBestValue = 0;
int iTotalCultureTimes100 = countTotalCultureTimes100();
for (int iPlayer = 0; iPlayer < MAX_CIV_PLAYERS; ++iPlayer)
{
CvPlayer& kLoopPlayer = GET_PLAYER((PlayerTypes)iPlayer);
if (kLoopPlayer.isAlive())
{
if (kLoopPlayer.canReceiveTradeCity())
{
CvCity* pCapital = kLoopPlayer.getCapitalCity();
if (NULL != pCapital)
{
int iCapitalDistance = ::plotDistance(getX_INLINE(), getY_INLINE(), pCapital->getX_INLINE(), pCapital->getY_INLINE());
if (area() != pCapital->area())
{
iCapitalDistance *= 2;
}
int iCultureTimes100 = getCultureTimes100((PlayerTypes)iPlayer);
if (bConquest)
{
if (iPlayer == getOriginalOwner())
{
iCultureTimes100 *= 3;
iCultureTimes100 /= 2;
}
}
if (GET_PLAYER((PlayerTypes)iPlayer).getTeam() == getTeam()
|| GET_TEAM(GET_PLAYER((PlayerTypes)iPlayer).getTeam()).isVassal(getTeam())
|| GET_TEAM(getTeam()).isVassal(GET_PLAYER((PlayerTypes)iPlayer).getTeam()))
{
iCultureTimes100 *= 2;
iCultureTimes100 = (iCultureTimes100 + iTotalCultureTimes100) / 2;
}
int iValue = std::max(100, iCultureTimes100) / std::max(1, iCapitalDistance);
if (iValue > iBestValue)
{
iBestValue = iValue;
eBestPlayer = (PlayerTypes)iPlayer;
}
}
}
}
}
Like so many times before, we go through each player in search for the best player to award liberation too. We start simple by:
- getting the total culture of all players in that city
- checking if the current player is alive
- checking if the current player can receive a city (this is only relevant for One-City-Challenges)
Now here begins the interesting part of the calculations:
- we calculate the distance between the liberated city and the current player's capitol
- if the two cities are in different areas, we multiple the capitalDistance by 2. Note that areas in most cases means different landmasses.
- next we get the culture of the current player in the liberated city
- the next part inside bConquest applies to our case. If the current player is the founder of the city, we multiply their culture by 3 and then divide by 2 again. This is close to multiplying by 1.5, but don't forget it is integer-calculation
- next we check if the current player is in the same team as the conqueror or if both are in a vassal-relationship with each other. If true, we multiply the current players culture by 2. Then we add the total culture in the liberated city and divide this by 2
- Next if the culture is below 100 we set it to 100 and if the capitalDistance is below 1 we set it to 1
- Lastly we divide the calculated culture with the capitalDistance. The player with the highest quotient is the player benefiting from liberation. In case of a tie the player with the lower player ID wins, but this is a very rare edge case.
Let's do some simple examples:
Example A) City has:
200 culture from player A, with CapitalDistance of 3
100 culture from player B, with CapitalDistance of 9
player C is the conqueror. Player A is the original owner.
For player A we have the following calculations:
CapitalDistance = 3
1. Culture = 200
2. Culture = 200 * 3 / 2 = 300, because of original owner
Quotient = 300 / 3 = 100
For player B we have the following calculations:
CapitalDistance = 9
1. Culture = 100
Quotient = 100 / 9 = 11.11 = 11 thanks to integer calculation
A has the bigger quotient and is the liberation player.
Example B) City has:
200 culture from player A, with CapitalDistance of 3
100 culture from player B, with CapitalDistance of 3, but on a different landmass
player C is the conqueror. Player B is the original owner.
For player A we have the following calculations:
CapitalDistance = 3
1. Culture = 200
Quotient = 200 / 3 = 66.66 = 66 thanks to integer calculation
For player B we have the following calculations:
CapitalDistance = 3 * 2 = 6, because of different landmasses
1. Culture = 100
2. Culture = 100 * 3 / 2 = 150, because of original owner
Quotient = 150 / 6 = 25
A has the bigger quotient and is the liberation player even though he is not the original owner
But we are not done yet. Because there is a third part to all this madness:
Code:
if (NO_PLAYER != eBestPlayer)
{
if (getOwnerINLINE() == eBestPlayer)
{
return NO_PLAYER;
}
for (int iPlot = 0; iPlot < NUM_CITY_PLOTS; ++iPlot)
{
CvPlot* pLoopPlot = ::plotCity(getX_INLINE(), getY_INLINE(), iPlot);
if (NULL != pLoopPlot)
{
if (pLoopPlot->isVisibleEnemyUnit(eBestPlayer))
{
return NO_PLAYER;
}
}
}
}
Here we check if the best player is still suitable for liberation. The first part is easy once again. If the best player is the conqueror itself, then we don't need to prompt the liberation popup.
But the next part inside the for loop is interesting. Here we iterate across all the tiles inside the BFC. If any of those tiles contains a visible enemy unit towards the best player, then nobody benfits from liberation and in turn no liberation popup comes up.
Summary
We calculate a quotient for every alive player
- CapitalDistance = Distance between conquered city and player's capital (* 2 if on different landmasses)
- PlayersCityCulture = Culture of that player in the city
If Original Owner, then
- PlayersCityCulture = PlayersCityCulture * 1.5
If same team or vassal relationship with conqueror, then
- PlayersCityCulture = ((PlayersCityCulture * 2) + TotalCultureOfAllPlayersInCity) / 2
If CapitalDistance is < 1, set to 1. If PlayersCityCulture < 100 set to 100
- Quotient = PlayersCityCulture / CapitalDistance
Player with the highest quotient wins.
But there is an extra catch. If there are visible enemy units towards the best player in the cities BFC, then nobody gets liberation.