In semi-isolation game https://forums.civfanatics.com/threads/nobles-club-366-justinian-i-of-byzantium.692846/ I'm in a situation AI refuses to trade techs because WDWTSTTTJY.
Seems if AI knows only you - it is a degenerate case. I find little info about WDWTSTTTJY and its implications.
Other threads pointed to the function
DLL source code, as pointed in some threads, is in the function:
I've got the case of WDWTSTTTJY, in a game I have only 1 AI on the land (espionage allocation supports the idea, as I haven't spoiled the game via WorldBuilder yet), so
Seems
One AI is a degenerate case, if you want trading - you need to befriend AI, so if you identified semi-isolation you please AI from the beginning... or you won't get +10 relations fast enough (before Astronomy).
Isolation with 2 AIs is less detrimental,
Isolation with 3 AIs even less punishing -
Thus in semi-isolation trade you first fight with WDWTSTTTJY and only then you hit WFYABTA, so breaking isolation has one additional reason (besides overseas large AI cluster trade feast, you miss).
Seems if AI knows only you - it is a degenerate case. I find little info about WDWTSTTTJY and its implications.
Other threads pointed to the function
CvTeamAI::AI_techTrade
. It mentions following reasons:Civ4/Assets/XML/Text/CIV4GameTextInfos.xml
Civ4/Assets/XML/Text/CIV4GameText_Misc1.xml
XML:
<Tag>TXT_KEY_DENIAL_NO_GAIN</Tag>
<English>"We would have nothing to gain."</English>
<Tag>TXT_KEY_DENIAL_WORST_ENEMY</Tag>
<English>"We will never trade with you, our worst enemy!!!"</English>
<Tag>TXT_KEY_DENIAL_ATTITUDE</Tag>
<English>"We just don't like you enough."</English>
<Tag>TXT_KEY_DENIAL_TECH_WHORE</Tag>
<English>"We fear you are becoming too advanced."</English>
<Tag>TXT_KEY_DENIAL_TECH_MONOPOLY</Tag>
<English>"We don't want to start trading away this technology just yet."</English>
<Tag>TXT_KEY_DENIAL_MYSTERY</Tag>
<English>"We have our reasons."</English>
<Tag>TXT_KEY_DENIAL_VICTORY</Tag>
<English>"We'd rather win the game, thank you very much..."</English>
DLL source code, as pointed in some threads, is in the function:
Spoiler Code for CvTeamAI::AI_techTrade() :
C++:
DenialTypes CvTeamAI::AI_techTrade(TechTypes eTech, TeamTypes eTeam) const
{
PROFILE_FUNC();
AttitudeTypes eAttitude;
int iNoTechTradeThreshold;
int iTechTradeKnownPercent;
int iKnownCount;
int iPossibleKnownCount;
int iI, iJ;
FAssertMsg(eTeam != getID(), "shouldn't call this function on ourselves");
if (GC.getGameINLINE().isOption(GAMEOPTION_NO_TECH_BROKERING))
{
CvTeam& kTeam = GET_TEAM(eTeam);
if (!kTeam.isHasTech(eTech))
{
if (!kTeam.isHuman())
{
if (2 * kTeam.getResearchProgress(eTech) > kTeam.getResearchCost(eTech))
{
return DENIAL_NO_GAIN;
}
}
}
}
if (isHuman())
{
return NO_DENIAL;
}
if (isVassal(eTeam))
{
return NO_DENIAL;
}
if (isAtWar(eTeam))
{
return NO_DENIAL;
}
if (AI_getWorstEnemy() == eTeam)
{
return DENIAL_WORST_ENEMY;
}
eAttitude = AI_getAttitude(eTeam);
for (iI = 0; iI < MAX_PLAYERS; iI++)
{
if (GET_PLAYER((PlayerTypes)iI).isAlive())
{
if (GET_PLAYER((PlayerTypes)iI).getTeam() == getID())
{
if (eAttitude <= GC.getLeaderHeadInfo(GET_PLAYER((PlayerTypes)iI).getPersonalityType()).getTechRefuseAttitudeThreshold())
{
return DENIAL_ATTITUDE;
}
}
}
}
if (eAttitude < ATTITUDE_FRIENDLY)
{
if ((GC.getGameINLINE().getTeamRank(getID()) < (GC.getGameINLINE().countCivTeamsEverAlive() / 2)) ||
(GC.getGameINLINE().getTeamRank(eTeam) < (GC.getGameINLINE().countCivTeamsEverAlive() / 2)))
{
iNoTechTradeThreshold = AI_noTechTradeThreshold();
iNoTechTradeThreshold *= std::max(0, (GC.getHandicapInfo(GET_TEAM(eTeam).getHandicapType()).getNoTechTradeModifier() + 100));
iNoTechTradeThreshold /= 100;
if (AI_getMemoryCount(eTeam, MEMORY_RECEIVED_TECH_FROM_ANY) > iNoTechTradeThreshold)
{
return DENIAL_TECH_WHORE;
}
}
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;
}
}
for (iI = 0; iI < GC.getNumUnitInfos(); iI++)
{
if (isTechRequiredForUnit(eTech, ((UnitTypes)iI)))
{
if (isWorldUnitClass((UnitClassTypes)(GC.getUnitInfo((UnitTypes)iI).getUnitClassType())))
{
if (getUnitClassMaking((UnitClassTypes)(GC.getUnitInfo((UnitTypes)iI).getUnitClassType())) > 0)
{
return DENIAL_MYSTERY;
}
}
}
}
for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
{
if (isTechRequiredForBuilding(eTech, ((BuildingTypes)iI)))
{
if (isWorldWonderClass((BuildingClassTypes)(GC.getBuildingInfo((BuildingTypes)iI).getBuildingClassType())))
{
if (getBuildingClassMaking((BuildingClassTypes)(GC.getBuildingInfo((BuildingTypes)iI).getBuildingClassType())) > 0)
{
return DENIAL_MYSTERY;
}
}
}
}
for (iI = 0; iI < GC.getNumProjectInfos(); iI++)
{
if (GC.getProjectInfo((ProjectTypes)iI).getTechPrereq() == eTech)
{
if (isWorldProject((ProjectTypes)iI))
{
if (getProjectMaking((ProjectTypes)iI) > 0)
{
return DENIAL_MYSTERY;
}
}
for (iJ = 0; iJ < GC.getNumVictoryInfos(); iJ++)
{
if (GC.getGameINLINE().isVictoryValid((VictoryTypes)iJ))
{
if (GC.getProjectInfo((ProjectTypes)iI).getVictoryThreshold((VictoryTypes)iJ))
{
return DENIAL_VICTORY;
}
}
}
}
}
return NO_DENIAL;
}
I've got the case of WDWTSTTTJY, in a game I have only 1 AI on the land (espionage allocation supports the idea, as I haven't spoiled the game via WorldBuilder yet), so
DENIAL_TECH_MONOPOLY
was took place, because iPossibleKnownCount
is zero, AI_techTradeKnownPercent()
should be 30% for the leader, and AI_getTechMonopolyValue(eTech, eTeam)
is non-zero (because all techs open mil units or non-religion buildings or wonders), so iTechTradeKnownPercent > 0
is true ((Seems
AI_getTechMonopolyValue
will be zero for few techs, like Alpha, Monotheism, Monarchy, Liberalism, Replaceable Parts (what else are with only religion buildings, no-wonders, no-warriors?).One AI is a degenerate case, if you want trading - you need to befriend AI, so if you identified semi-isolation you please AI from the beginning... or you won't get +10 relations fast enough (before Astronomy).
Isolation with 2 AIs is less detrimental,
iPossibleKnownCount
is 1, so we need to overcome condition ((iKnownCount * 100) / iPossibleKnownCount) < iTechTradeKnownPercent
= (iKnownCount * 100) < iTechTradeKnownPercent
, in other words both AIs should know tech as the condition is for 100% knowledge.Isolation with 3 AIs even less punishing -
iPossibleKnownCount
is 2, so the threshold is 50%, which is it for half of the AIs, so if a tech is known by 2 of 3 AIs we won't hit WDWTSTTTJY for many leaders (with 15/20/30/40/50% threshold).Thus in semi-isolation trade you first fight with WDWTSTTTJY and only then you hit WFYABTA, so breaking isolation has one additional reason (besides overseas large AI cluster trade feast, you miss).
Last edited: