As a French person I feel like it's my duty to explain strikes to you. - AdrienIer

Create an account  

 
Curious Civplayer - Mysteries of the DLL

Another small request Charriu - what does iSoundtrackSpace in EraInfos do?
"I know that Kilpatrick is a hell of a damned fool, but I want just that sort of man to command my cavalry on this expedition."
- William Tecumseh Sherman

Reply

Nothing. The value is accessable from the python code, but there as well as in the DLL it is not used. Of course it could be used in the part of the code to which I have no access. But I doubt that. My reasoning is that in the few lines of code that give access to this iSoundtrackSpace they do make sure that this variable never gets to be 0 or lower. This suggest that there might be an error if it's 0 or lower. So I forced the code to throw out these numbers and the game does not crash. Therefore I presume the value is not used anywhere else. By the way this value is present since before the Warlords expansion.

Just curious but why did you want to know this and how did you stumble upon this?
Mods: RtR    CtH

Pitboss: PB39, PB40PB52, PB59 Useful Collections: Pickmethods, Mapmaking, Curious Civplayer

Buy me a coffee
Reply

How is trade mission gold calculated?

This will be a short one. For the actual code look into CvUnit and there into getTradeGold:

Code:
(m_pUnitInfo->getBaseTrade() + (m_pUnitInfo->getTradeMultiplier() * ((pCapitalCity != NULL) ? pCity->calculateTradeProfit(pCapitalCity) : 0)));

For the Great Merchants these values are as follows:

getBaseTrade = 500
getTradeMultiplier = 200
calculateTradeProfit(pCapitalCity) = the total trade commerce the city would get if it had a trade connection to your capitol.

After this the value gets multiplied with (iUnitTradePercent / 100) from GameSpeedInfo.xml, which for Normal is 100. We can summarize the whole formula to this:

(500 + (200 * Cities trade commerce towards your capitol)) * (iUnitTradePercent / 100)

This of course also means that everything that improves trade is counted towards the trade mission, for example ToA, harbors, being on different continents, etc.
Mods: RtR    CtH

Pitboss: PB39, PB40PB52, PB59 Useful Collections: Pickmethods, Mapmaking, Curious Civplayer

Buy me a coffee
Reply

(February 21st, 2021, 08:11)Charriu Wrote: Just curious but why did you want to know this and how did you stumble upon this?

I have a mod I play with my friends, and they like to have a custom soundtrack of all their favorite songs, and while I was editing erainfos, i stumbled upon in, and noticed it decreased in value from the classcial to the future era, but was 0 in the ancient era.
"I know that Kilpatrick is a hell of a damned fool, but I want just that sort of man to command my cavalry on this expedition."
- William Tecumseh Sherman

Reply

(February 21st, 2021, 08:27)Charriu Wrote: calculateTradeProfit(pCapitalCity) = the total trade commerce the city would get if it had a trade connection to your capitol.

So I need the % modifiers not in my capital but rather in the target city? So I should not build the ToA on my own in the cap, but rather send my GM to somebody else's ToA city?
Reply

- Yes, the % modifiers in the city that receives the Trade Mission aka the target city is relevant.
- Building ToA in your cap doesn't do anything for your Trade Missions.
- Yes sending the GM to somebody else's ToA city can be better, but for example a city on a different island does get the same modifier as ToA. So you can't say send it to ToA is best.
Mods: RtR    CtH

Pitboss: PB39, PB40PB52, PB59 Useful Collections: Pickmethods, Mapmaking, Curious Civplayer

Buy me a coffee
Reply

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:

  1. we calculate the distance between the liberated city and the current player's capitol
  2. if the two cities are in different areas, we multiple the capitalDistance by 2. Note that areas in most cases means different landmasses.
  3. next we get the culture of the current player in the liberated city
  4. 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
  5. 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
  6. Next if the culture is below 100 we set it to 100 and if the capitalDistance is below 1 we set it to 1
  7. 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.
Mods: RtR    CtH

Pitboss: PB39, PB40PB52, PB59 Useful Collections: Pickmethods, Mapmaking, Curious Civplayer

Buy me a coffee
Reply

So this

Quote:A) NumCities > 2*NumPlayersAlive:
Barbs will enter your territory if they can pillage an improvement on their next turn [...]
Barbs will enter your territory if they can attack a city on the same turn [...]
B) NumCities > 3*NumPlayersAlive:
The restrictions for the missions are lifted to
pillage on the 3rd turn
attack city on the second turn

from DanF5771 on civfanatics has been quoted a lot.

Is this information actually correct?
If so do roads count as an improvement for barbs to pillage under A)?
Reply

(April 1st, 2021, 04:03)civac2 Wrote: So this

Quote:A) NumCities > 2*NumPlayersAlive:
Barbs will enter your territory if they can pillage an improvement on their next turn [...]
Barbs will enter your territory if they can attack a city on the same turn [...]
B) NumCities > 3*NumPlayersAlive:
The restrictions for the missions are lifted to
pillage on the 3rd turn
attack city on the second turn

from DanF5771 on civfanatics has been quoted a lot.

Is this information actually correct?
If so do roads count as an improvement for barbs to pillage under A)?
From experience, they do pillage roads.
Reply

I've put it on my todo list and will check it.
Mods: RtR    CtH

Pitboss: PB39, PB40PB52, PB59 Useful Collections: Pickmethods, Mapmaking, Curious Civplayer

Buy me a coffee
Reply



Forum Jump: