Okay, I have a lead on how to interpret the iTechTradeKnownPercent values.
Here's some relevant code from {Your Civ4 directory}\Beyond the Sword\CvGameCoreDLL\CvTeamAI.cpp, in particular from the DenialTypes function:
Code:
iKnownCount = 0;
iPossibleKnownCount = 0;
for (iI = 0; iI < MAX_CIV_TEAMS; iI++)
{
if (GET_TEAM((TeamTypes)iI).isAlive())
{
if ((iI != getID()) && (iI != eTeam))
{
if (isHasMet((TeamTypes)iI))
{
if (GET_TEAM((TeamTypes)iI).isHasTech(eTech))
{
iKnownCount++;
}
iPossibleKnownCount++;
}
}
}
}
iTechTradeKnownPercent = AI_techTradeKnownPercent();
iTechTradeKnownPercent *= std::max(0, (GC.getHandicapInfo(GET_TEAM(eTeam).getHandicapType()).getTechTradeKnownModifier() + 100));
iTechTradeKnownPercent /= 100;
iTechTradeKnownPercent *= AI_getTechMonopolyValue(eTech, eTeam);
iTechTradeKnownPercent /= 100;
if ((iPossibleKnownCount > 0) ? (((iKnownCount * 100) / iPossibleKnownCount) < iTechTradeKnownPercent) : (iTechTradeKnownPercent > 0))
{
return DENIAL_TECH_MONOPOLY;
}
iKnownCount and iPossibleKnownCount look at all players that the AI whom we are talking to (let's say that we are talking to Vicky) knows, excluding the AI that we are talking to (so, excluding Vicky) and the player that is talking to said AI (so, excluding us).
iKnownCount specifically looks at those players which Vicky knows and that know the tech (minus Vicky and us)
iPossibleKnownCount specifically looks at those players which Vicky knows (minus Vicky and us)
MAX_CIV_TEAMS means that every team will be checked, with each pass through the for loop using the "iI" counter variable
isAlive() makes sure that we're only counting players that are alive, so presumably, if an AI learned Feudalism and then we killed off that AI, it would be a good thing, as other AIs wouldn't be able to use the dead AI's knowledge of Feudalism to make that tech easier to trade around amongst each other.
getID() seems to be the AI itself. So, if we are talking to Vicky, then getID() refers to Vicky. In this case, we see that "iI" ensures that it is not Vicky.
eTeam seems to be the player that is being spoken to. So, if we are the one talking to Vicky, then eTeam refers to us. Again, we see that "iI" ensures that it is not us.
isHasMet is probably exactly what it says... only count players that the AI that we are talking to, such as Vicky, actually knows. One factor that we can't be sure about here is whether or not Vicky (or Cathy or whomever we want to trade with) actually knows the AI that we do not know. I am going to say that it is a good bet that Cathy knows that Unknown AI, since she got Hinduism spread to her, but that's not a guarantee. Still, that other AI does have Hinduism, so there is even a small chance that this other AI also has learned Monotheism. In fact, since Vicky seems willing to trade with us while only knowing Ragnar, it is probably almost certain that she knows the Unknown AI (if I can finish wading through this formula we should be able to know for certain if I am right here).
isHasTech is probably exactly what it says, too... which is: Does the player, which is not the player that we are talking to (not Vicky) and not the player doing the talking (not us) have knowledge of the tech? If yes, both iKnownCount and iPossibleKnownCount are incremented. If no, iKnownCount does not change but iPossibleKnownCount is incremented.
AI_techTradeKnownPercent() seems to simply return the iTechTradeKnownPercent value... for a team of players, it grabs the average value of the team members, but with only 1 player per team, that's the same as grabbing the AI's iTechTradeKnownPercent value.
std:max means get the maximum value out of all of the values being compared
The values being compared for the maximum value are 0 (zero) and another number.
Part of that other number grabs a Handicap value from the CIV4HandicapInfo.xml file, specifically the iTechTradeKnownModifier value. This value is 100 for Settler difficulty level, 50 for Chieftain, 25 for Warlord, and 0 for Noble and above. Since we're on Emperor difficulty, that means that getTechTradeKnownModifier() returns 0 for us. Since each other AIs play on Noble difficulty level, getTechTradeKnownModifier() also returns 0 for them. The other part of that number is that 100 gets added to it. 0 + 100 = 100, pretty simple, right?
So, all that happens in these two lines:
Code:
iTechTradeKnownPercent *= std::max(0, (GC.getHandicapInfo(GET_TEAM(eTeam).getHandicapType()).getTechTradeKnownModifier() + 100));
iTechTradeKnownPercent /= 100;
is that the iTechTradeKnownPercent value gets multiplied by 100 and then divided by 100... i.e. the result does not change except when a player is playing on a really easy difficulty level. Here's one of the many reasons why when we played XOTM games where the AIs were set to Settler-level difficulty by editing the World Builder file that it was extremely hard to compete with them (I remember one such game where NO ONE won it).
Anyway, it is nice to know that the other AIs will be treated equally as us in terms of the use of the iTechTradeKnownPercent values.
getTechMonopolyValue is one beast of a function. I'll spoiler it here:
The heart of that funciton seems to rely on getAnyWarPlanCount, which is a function that is found in the CvTeam.cpp file. The player that gets passed to the getAnyWarPlanCount function is us, or whichever player is trying to get the tech in trade. Here is the function:
Code:
int CvTeam::getAnyWarPlanCount(bool bIgnoreMinors) const
{
int iCount;
int iI;
iCount = 0;
for (iI = 0; iI < MAX_CIV_TEAMS; iI++)
{
if (GET_TEAM((TeamTypes)iI).isAlive())
{
if (!bIgnoreMinors || !(GET_TEAM((TeamTypes)iI).isMinorCiv()))
{
if (AI_getWarPlan((TeamTypes)iI) != NO_WARPLAN)
{
FAssert(iI != getID());
iCount++;
}
}
}
}
FAssert(iCount >= getAtWarCount(bIgnoreMinors));
return iCount;
}
Okay, I'm starting to get overwhelmed here.
We could just make an assumption that the human player can't have a "war plan," which might or might not be the right kind of assumption to make. Another possible assumption could be that since no AI currently has their hands full and since no player is at war with any other player, then no "war plan" exists.
Whatever. The point seems to be that a war plan could increase the iValue value in the AI_getTechMonopolyValue function.
Then it looks like the AI_getTechMonopolyValue function factors in units, buildings, Wonders, and Projects that are unlocked by the tech in question.
I'm a bit lost at this point, though, in the intricacies of AI_getTechMonopolyValue function and I'm just going to ignore it for now. What it seems to boil down to is that different things unlocked by a tech could affect the default willingness of an AI to trade a tech, but I could be wrong.
Anyway, continuing on, we have this little bit:
Code:
if ((iPossibleKnownCount > 0) ? (((iKnownCount * 100) / iPossibleKnownCount) < iTechTradeKnownPercent) : (iTechTradeKnownPercent > 0))
{
return DENIAL_TECH_MONOPOLY;
}
If iPossibleKnownCount were 0, meaning that the AI that you are trying to trade with (Vicky) doesn't know anyone other than you, then we'd use the bit after the colon:
(iTechTradeKnownPercent > 0)
Ignoring the effect of the AI_getTechMonopolyValue function, since I'm still not sure how to figure it out, I believe what we are seeing here is that "if you're not trying to trade with Mansa, then an isolated AI will return "true," and if "true" is returned, then then you will get a DENIAL_TECH_MONOPOLY (i.e. you can't get the tech).
But, since we know that Vicky knows at least Ragnar, (iTechTradeKnownPercent > 0) IS true, so we need to look at whether or not the following code returns true or false, with a "true" value being a denial to trade the tech due to it being treated as a monopoly tech:
Code:
((iKnownCount * 100) / iPossibleKnownCount) < iTechTradeKnownPercent)
So, again, ignoring the effect of the AI_getTechMonopolyValue function, and assuming that Vicky only knows Ragnar, then Iron Working would be:
((1 * 100 / 1) < 30) = (100 < 30) which returns false, so she would trade with us
Similarly, ignoring the effect of the AI_getTechMonopolyValue function, and assuming that Vicky only knows Ragnar, then Polytheism would be:
((0 * 100 / 1) < 30) = (0 < 30) which returns true, so she would refuse to trade with us
Therefore, either the AI_getTechMonopolyValue function is really important, or maybe she knows the Unknown AI. Let's see what numbers we would get if she knew the Unknown AI:
((1 * 100 / 2) < 30) = (50 < 30) which returns false, so she would trade with us
Actually, if we think about it, the AI_getTechMonopolyValue function does not appear to return negative values, and therefore, as long as it is not returning a value of "0" (which I am not even sure if it would be possible to return), then any value that it returns (even if it is less than 100 but as long as it is greater than 0) would leave iTechTradeKnownPercent as a positive value. As such, in our case above with only Vicky knowing Ragnar when looking at Polytheism, we'd still have (0 < {a number bigger than zero}), which would return true... but that would mean that Polytheism is not tradeable.
Therefore, assuming that the AI_getTechMonopolyValue function is not returning a value of "0" for Polytheism (which may never happen but even if it does it seems unlikely to happen since Polytheism unlocks a Wonder), then we can safely conclude that
Vicky knows the Unknown AI.
So, again ignoring the AI_getTechMonopolyValue function, what sorts of numbers would we see for, say, Vicky knowing Metal Casting and Code of Laws?
Well, for either Metal Casting or Code of Laws:
Let's say that she just knows Ragnar + the Unknown AI:
((1 * 100 / 2) < 30) = (50 < 30) returns false, so it looks like she would be willing to trade around either tech
Let's say that she meets one more AI that is not Willem (and therefore knows another AI that does not know either of these techs):
((1 * 100 / 3) < 30) = (33.33 < 30) still returns false, so it looks like she would still be willing to trade around either tech
Of course, if she meets 2 more AIs that are not Willem, we'd see:
((1 * 100 / 4) < 30) = (25 < 30) which returns true, so then she'd say that not enough other players know the tech
If Vicky meets everyone, then she'd hang onto Code of Laws if only she and we had it, but what about Metal Casting, where Willem would also know it?
((2 * 100 / 5) < 30) = (40 < 30) which returns false, so she would be willing to trade Metal Casting around to anyone
As for Willem, he currently knows Isabella, Ragnar, Cathy, and us (as well as possible the Unknown AI).
Assuming that he does not know the Unknown AI, and if we don't trade Metal Casting to Vicky, will he be willing to trade around Metal Casting?
((1 * 100 / 3) < 15) = (33.33 < 15) which returns false, so he would be willing to trade Metal Casting around to anyone
Now, Vicky has a reasonably high chance of self-teching Metal Casting, as that tech is listed with a "35" value for her (incidentally, she has a value of "10" for Machinery).
So, if Vicky, who we know (unless the AI_getTechMonopolyValue function can return a value of 0 for Polytheism, which I highly doubt) knows both Ragnar and the Unknown AI, ends up meeting Willem without meeting anyone else, decides to start researching Metal Casting, then she could feasibly get sufficient Flasks invested in Metal Casting in order for that tech to "equal" Code of Law's value, and thus she could trade away Code of Laws <-> the rest of Metal Casting with Willem. Of course, if she meets a different AI before she meets Willem and then meets Willem, this danger doesn't exist, but it is a potential danger.
Vicky has chance of going after Machinery, so who knows, she might tech it for us?
Willem values Machinery at a value of 18, and that value is much higher than his Priesthood (5) and Monarchy (10) values.
If they both learned Machinery, then we could certainly get Machinery in trade.
So, yes, since there is a risk that if Willem were to meet Vicky and no other AI were to meet Vicky that they could swap Code of Laws and Metal Casting,
it's probably better to give Metal Casting to Vicky than Code of Laws.