1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

My personal thread: Clarification of certain game mechanics

Discussion in 'Civ4 - Strategy & Tips' started by Manco Capac, Jun 16, 2012.

  1. 2metraninja

    2metraninja Defender of Nabaxica

    Joined:
    Sep 19, 2007
    Messages:
    5,663
    Location:
    Plovdiv, BG
    The trick/bug/cheat where culture is put in to hammers on culture border pop is indeed negligible, but the trick/bug/cheat which I am mentioning can be exploited heavily - each and every turn hammers can be put in to production and in money/beakers.
     
  2. Manco Capac

    Manco Capac Friday,13 June,I Collapse

    Joined:
    Mar 1, 2010
    Messages:
    8,051
    Oh, that a good recalling of CivIII building wealth in all cities while building normal stuff.

    Yeah, keep it to yourself, that's better.
     
  3. Manco Capac

    Manco Capac Friday,13 June,I Collapse

    Joined:
    Mar 1, 2010
    Messages:
    8,051
    SYNOPSIS​


    "We demand emancipation!" is the raging shrieks of the population for being under a Labor class civic that they deem unjust, oppressing or simply backward.
    It increases the unhappiness level by several unhappiness points according to the following paramaters (ordered from the most direct to the most generalized one):
    1. A base number: I compared Warlords and BTS; I saw no difference in coding. Some people ranted BTS increased emancipation unhappiness along BTS, but that seems to be an unfounded rant. I don't know if Vanilla version have publicized the code...
    2. Number of AI's still alive : indeed more AI's mean smaller incrementation of unhappiness per AI; more AI does not eqal to higher over unhappiness.
    3. Number of cities per AI under Emancipation: that is some kind of weigh that small nations have less impact than large scaled empires.
    4. Population in human player cities: Bigger populations mean more rabbid citizens overall.

    MATHEMATICAL APPROACH​


    Consider a base number called iCivicPercentAnger=400.
    That is defined in CIV4CivicInfos.xml.

    In CvPlayer, we find the function that increases the percentage of unhappiness according to number of AI's under Emancipation over all possible AI's STILL ALIVE and that is weighted with their city counts.

    %CivicAnger = 400*(Number of cities under Emancipation)/(Total Number of Cities in the world)

    "Number of cities under Emancipation" is simply each AI under Emancipation and their weigh is their city counts.
    "Total Number of Cities in the world" seems a pretty special parameter because it doesn't exclude barbarian cities in the count. Count them all if possible. And yes, that is possible to see barbarian cities during renaissance, especially if you play a Terra mapscript.

    Now, to get the exact integer of unhappiness: Let it be named iUnhappiness.

    iUnhappiness = [(%CivicAnger * (CityPopulation + Extra) )/ PERCENT_ANGER_DIVISOR]

    CityPopulation is a common factor that affects many types of anger like motherland unhappiness, No military police anger, etc. That is why I consider that factor not proper to Emancipation, but a global factor in unhappiness.
    PERCENT_ANGER_DIVISOR is some sort of constant defined in GlobalDefines.XML. Do not see beyond the fact it is worth 1000. That's it. :dunno:
    Extra: I still need to define what it is. It can be some sort of additional parameter left for modders.
    EDIT: Ok, I think I got the idea of what is that Extra parameter while browsing the code again. It seems to have to do with stacked unhappiness like from conscription, whipping, defying resolutions and stacking unhappy citizens.
    Given the generality of that second formula for diverse forms of unhappiness, there is no extra for emancipation unhappiness.



    SOURCE CODE​


    Spoiler :

    In CvPlayer.cpp
    Code:
    int CvPlayer::getCivicPercentAnger(CivicTypes eCivic, bool bIgnore) const
    {
    	int iCount;
    	int iPossibleCount;
    	int iI;
    
    	if (GC.getCivicInfo(eCivic).getCivicPercentAnger() == 0)
    	{
    		return 0;
    	}
    
    	if (!bIgnore && (getCivics((CivicOptionTypes)(GC.getCivicInfo(eCivic).getCivicOptionType())) == eCivic))
    	{
    		return 0;
    	}
    
    	iCount = 0;
    	iPossibleCount = 0;
    
    	for (iI = 0; iI < MAX_CIV_PLAYERS; iI++)
    	{
    		if (GET_PLAYER((PlayerTypes)iI).isAlive())
    		{
    			if (GET_PLAYER((PlayerTypes)iI).getTeam() != getTeam())
    			{
    				if (GET_PLAYER((PlayerTypes)iI).getCivics((CivicOptionTypes)(GC.getCivicInfo(eCivic).getCivicOptionType())) == eCivic)
    				{
    					iCount += GET_PLAYER((PlayerTypes)iI).getNumCities();
    				}
    
    				iPossibleCount += GET_PLAYER((PlayerTypes)iI).getNumCities();
    			}
    		}
    	}
    
    	if (iPossibleCount == 0)
    	{
    		return 0;
    	}
    
    	return ((GC.getCivicInfo(eCivic).getCivicPercentAnger() * iCount) / iPossibleCount);
    }
    
    In CvCity.cpp
    Code:
    int CvCity::unhappyLevel(int iExtra) const
    {
    	int iAngerPercent;
    	int iUnhappiness;
    	int iI;
    
    	iUnhappiness = 0;
    
    	if (!isNoUnhappiness())
    	{
    		iAngerPercent = 0;
    
    		for (iI = 0; iI < GC.getNumCivicInfos(); iI++)
    		{
    			iAngerPercent += GET_PLAYER(getOwnerINLINE()).getCivicPercentAnger((CivicTypes)iI);
    		}
    
    		iUnhappiness = ((iAngerPercent * (getPopulation() + iExtra)) / GC.getPERCENT_ANGER_DIVISOR());
    
    		iUnhappiness -= std::min(0, getLargestCityHappiness());
    		iUnhappiness -= std::min(0, getMilitaryHappiness());
    		iUnhappiness -= std::min(0, getCurrentStateReligionHappiness());
    		iUnhappiness -= std::min(0, getBuildingBadHappiness());
    		iUnhappiness -= std::min(0, getExtraBuildingBadHappiness());
    		iUnhappiness -= std::min(0, getFeatureBadHappiness());
    		iUnhappiness -= std::min(0, getBonusBadHappiness());
    		iUnhappiness -= std::min(0, getReligionBadHappiness());
    		iUnhappiness -= std::min(0, getCommerceHappiness());
    		iUnhappiness -= std::min(0, area()->getBuildingHappiness(getOwnerINLINE()));
    		iUnhappiness -= std::min(0, GET_PLAYER(getOwnerINLINE()).getBuildingHappiness());
    		iUnhappiness -= std::min(0, (getExtraHappiness() + GET_PLAYER(getOwnerINLINE()).getExtraHappiness()));
    		iUnhappiness -= std::min(0, GC.getHandicapInfo(getHandicapType()).getHappyBonus());
    		iUnhappiness += std::max(0, getVassalUnhappiness());
    		iUnhappiness += std::max(0, getEspionageHappinessCounter());
    	}
    
    	return std::max(0, iUnhappiness);
    }
    In globalDefines.xml
    Code:
    <Define>
    		<DefineName>PERCENT_ANGER_DIVISOR</DefineName>
    		<iDefineIntVal>1000</iDefineIntVal>
    	</Define>
    In CIV4CivicInfos.xml
    Code:
    <CivicInfo>
    			<CivicOptionType>CIVICOPTION_LABOR</CivicOptionType>
    			<Type>CIVIC_EMANCIPATION</Type>
    			<Description>TXT_KEY_CIVIC_EMANCIPATION</Description>
    			<Civilopedia>TXT_KEY_CIVIC_EMANCIPATION_PEDIA</Civilopedia>
    			<Strategy>TXT_KEY_CIVIC_EMANCIPATION_STRATEGY</Strategy>
    			<Button>,Art/Interface/Buttons/Civics/Emancipation.dds,Art/Interface/Buttons/Civics_Civilizations_Religions_Atlas.dds,6,1</Button>
    			<TechPrereq>TECH_DEMOCRACY</TechPrereq>
    			<iAnarchyLength>1</iAnarchyLength>
    			<Upkeep>UPKEEP_LOW</Upkeep>
    			<iAIWeight>0</iAIWeight>
    			<iGreatPeopleRateModifier>0</iGreatPeopleRateModifier>
    			<iStateReligionGreatPeopleRateModifier>0</iStateReligionGreatPeopleRateModifier>
    			<iDistanceMaintenanceModifier>0</iDistanceMaintenanceModifier>
    			<iNumCitiesMaintenanceModifier>0</iNumCitiesMaintenanceModifier>
    			<iExtraHealth>0</iExtraHealth>
    			<iFreeExperience>0</iFreeExperience>
    			<iWorkerSpeedModifier>0</iWorkerSpeedModifier>
    			<iImprovementUpgradeRateModifier>100</iImprovementUpgradeRateModifier>
    			<iMilitaryProductionModifier>0</iMilitaryProductionModifier>
    			<iBaseFreeUnits>0</iBaseFreeUnits>
    			<iBaseFreeMilitaryUnits>0</iBaseFreeMilitaryUnits>
    			<iFreeUnitsPopulationPercent>0</iFreeUnitsPopulationPercent>
    			<iFreeMilitaryUnitsPopulationPercent>0</iFreeMilitaryUnitsPopulationPercent>
    			<iGoldPerUnit>0</iGoldPerUnit>
    			<iGoldPerMilitaryUnit>0</iGoldPerMilitaryUnit>
    			<iHappyPerMilitaryUnit>0</iHappyPerMilitaryUnit>
    			<bMilitaryFoodProduction>0</bMilitaryFoodProduction>
    			<iMaxConscript>0</iMaxConscript>
    			<bNoUnhealthyPopulation>0</bNoUnhealthyPopulation>
    			<bBuildingOnlyHealthy>0</bBuildingOnlyHealthy>
    			<iLargestCityHappiness>0</iLargestCityHappiness>
    			<iWarWearinessModifier>0</iWarWearinessModifier>
    			<iFreeSpecialist>0</iFreeSpecialist>
    			<iTradeRoutes>0</iTradeRoutes>
    			<bNoForeignTrade>0</bNoForeignTrade>
    			<iCivicPercentAnger>400</iCivicPercentAnger>
    			<bStateReligion>0</bStateReligion>
    			<bNoNonStateReligionSpread>0</bNoNonStateReligionSpread>
    			<iStateReligionHappiness>0</iStateReligionHappiness>
    			<iNonStateReligionHappiness>0</iNonStateReligionHappiness>
    			<iStateReligionUnitProductionModifier>0</iStateReligionUnitProductionModifier>
    			<iStateReligionBuildingProductionModifier>0</iStateReligionBuildingProductionModifier>
    			<iStateReligionFreeExperience>0</iStateReligionFreeExperience>
    			<YieldModifiers/>
    			<CapitalYieldModifiers/>
    			<TradeYieldModifiers/>
    			<CommerceModifiers/>
    			<CapitalCommerceModifiers/>
    			<SpecialistExtraCommerces/>
    			<Hurrys/>
    			<SpecialBuildingNotRequireds/>
    			<SpecialistValids/>
    			<BuildingHappinessChanges/>
    			<FeatureHappinessChanges/>
    			<ImprovementYieldChanges/>
    			<WeLoveTheKing/>
    		</CivicInfo>
     
  4. Manco Capac

    Manco Capac Friday,13 June,I Collapse

    Joined:
    Mar 1, 2010
    Messages:
    8,051
    Finally, I got the mother lode. I finally resolved that matter by myself. :)

    SYNOPSIS

    As many people already deduced well, here are the factors that goad some AI's to be generous:

    1. Every AI out of 52 has an attitude theshold. That is :<NoGiveHelpAttitudeThreshold>ATTITUDE_CAUTIOUS</NoGiveHelpAttitudeThreshold> . According to the code, the AI has to be PLEASED (or >CAUTIOUS) to be in the mood for generosity.
    2. Position in the scoreboard is indeed again an indicator. Your position (or team position) has to be a rank lower than the half alive civs number. It has nothing to do with being the dead last!
    3. The contact for the gift is indeed randomized and is leader dependant: CONTACT_GIVE_HELP is the magical number that rules the contact for freebee. For instance, if CONTACT_GIVE_HELP=50 and the RNG gives 0 (out of 0 to 49 of values), the contact is made. Indeed, bigger is CONTACT_GIVE_HELP, less frequent are the contacts for gifts. Most are either 50 to 100. Some are at 250, 500 and 1000. BUT there is one noticeable unfriendly one with CONTACT_GIVE_HELP=10000. GUESS WHO?
    4. What kind of tech can we get for free? Sadly, that is completely randomized. No prediction can be done. Can we get any techs from what the donor got? Nope. That is because a check is done before the tech roulette: it checks if that tech is tradable and checks possible denials (e.g. WDWTSTA, WFYABTA, We have our reasons, etc.). Don't expect super nice gifts that outrage AI reasoning in refusing such techs in normal trading!
    5. Did you know there was an equivalent for resources?!

    URBAN LEGENDS TO SHOOT DOWN

    • Being the last dead person is not a necessary condition.
    • Differences in number of techs between you and AI has nothing to do with it. So beelining or not doesn't change directly the odd of freebee techs. What makes more common is the fact of beelining makes the player to ignore some filler techs.
    • Receiving a gift is not without consequences. Yes, you don't get any Worst Enemy negmods, but you get one more tech in the count of WFYABTA. Think twice accepting the poison gift like Archery that may forbid you later to tech trade fission!


    SOURCE CODE

    Spoiler :


    In CvPlayerAI.cpp:
    Code:
    if (GET_PLAYER((PlayerTypes)iI).getTeam() != getTeam() && GET_TEAM(GET_PLAYER((PlayerTypes)iI).getTeam()).isVassal(getTeam()))
    							{
    								iBestValue = 0;
    								eBestGiveTech = NO_TECH;
    
    								for (iJ = 0; iJ < GC.getNumTechInfos(); iJ++)
    								{
    									if (GET_TEAM(getTeam()).AI_techTrade((TechTypes)iJ, GET_PLAYER((PlayerTypes)iI).getTeam()) == NO_DENIAL)
    									{
    										setTradeItem(&item, TRADE_TECHNOLOGIES, iJ);
    
    										if (canTradeItem(((PlayerTypes)iI), item, true))
    										{
    											iValue = (1 + GC.getGameINLINE().getSorenRandNum(10000, "AI Vassal Tech gift"));
    
    											if (iValue > iBestValue)
    											{
    												iBestValue = iValue;
    												eBestGiveTech = ((TechTypes)iJ);
    											}
    										}
    									}
    								}
    In CvPlayer.cpp:
    Code:
    bool CvPlayer::canTradeItem(PlayerTypes eWhoTo, TradeData item, bool bTestDenial) const
    {
    	CvCity *pOurCapitalCity;
    
    	if (bTestDenial)
    	{
    		if (getTradeDenial(eWhoTo, item) != NO_DENIAL)
    		{
    			return false;
    		}
    	}
    CIV4LeaderHeadInfos.xml:
    Code:
    <ContactType>CONTACT_GIVE_HELP</ContactType>
    
    CIV4LeaderHeadInfos.xml -> Toku	:				<iContactRand>10000</iContactRand>
    Code:
    <NoGiveHelpAttitudeThreshold>ATTITUDE_CAUTIOUS</NoGiveHelpAttitudeThreshold>
    In CvTeam.cpp :
    Code:
    int CvTeam::getAssets() const
    {
    	int iCount;
    	int iI;
    
    	iCount = 0;
    
    	for (iI = 0; iI < MAX_PLAYERS; iI++)
    	{
    		if (GET_PLAYER((PlayerTypes)iI).isAlive())
    		{
    			if (GET_PLAYER((PlayerTypes)iI).getTeam() == getID())
    			{
    				iCount += GET_PLAYER((PlayerTypes)iI).getAssets();
    			}
    		}
    	}
    
    	return iCount;
    }
    
     
  5. ben-jammin

    ben-jammin Chieftain

    Joined:
    Jan 12, 2011
    Messages:
    1,436
    Highest contact_give_help has got to be our old friend Toku.
     
  6. Sun Tzu Wu

    Sun Tzu Wu Chieftain Supporter

    Joined:
    Mar 26, 2007
    Messages:
    7,920
    Tachy,

    Please avoid using the Lime (Lime) font, because it has poor contrast on both normal background and QUOTE/SPOILER background. As a result of poor contrast, it is almost as hard to read as the Yellow font.

    Sun Tzu Wu
     
  7. Smilingrogue

    Smilingrogue Raging Barbarian

    Joined:
    Jan 4, 2012
    Messages:
    528
    Location:
    On a trade mission
    I have a question about a game mechanic, that I hope is ok to ask here. I found this in SGOTM 11 Plastic Ducks' thread regarding peace vassaling Saladin on another continent:
    In a recent Noble's Club on an Archipelago map, I capitulated an AI after kicking it off my mainland via war. It immediately capitulated along with its colony. But by kicking it off the large land mass we shared together, didn't I fail the 'land target' requirement? My power rating was only twice the AI's.

    So, will the mechanics I quoted from that SGOTM not apply during war capitulations? And also, will an AI capitulate to a Civ across the oceans if it meets the power requirements even if neither Civ has Astronomy? I had a situation where I was beating up a Civ on Hemispheres with Shaka on the other continent, no one had Astro and I was really worried about my target throwing himself at Shaka to save itself. Was that fear justified?

    Thanks for your time and really love the info you are gathering here, Tachywaxon! :)
     
  8. coanda

    coanda Chieftain

    Joined:
    May 12, 2009
    Messages:
    1,601
    http://forums.civfanatics.com/showthread.php?p=10739358#post10739358
    A pretty thorough coverage of the code dealing with AI surrender trades.

    War capitulations have different standards than peacevassaling. What really matters is war success and relative power (plus you must reduce them to <50% of your pop or land).
     
  9. Smilingrogue

    Smilingrogue Raging Barbarian

    Joined:
    Jan 4, 2012
    Messages:
    528
    Location:
    On a trade mission
    @ Coanda

    Thanks a lot for that link. That's a lot of excellent info and answers a lot of things I wondered about the mechanic.

    What about war capitulations? Are they weighted in anyway towards AIs being more willing to cap to other AIs vs. the player like tech-trades? For instance, AIs always seem to have an easier time capitulating some one like Sitting Bull as opposed to me. I always seem to need to burn half his empire to ashes first. On the other hand, I actually saw Brennus cap SB at tech parity after just taking one city. Mao capped to Frederick in a recent game with neither side even inflicting casualties. (I was between the two AIs and didn't see troops move through my borders.)
     
  10. Manco Capac

    Manco Capac Friday,13 June,I Collapse

    Joined:
    Mar 1, 2010
    Messages:
    8,051
    No problem about asking in-game mechanics here. It's all about it.

    SB has an increased resilience against losses and thus capitulate harder.
    I don't think it's weighted towards the AI. It's weighted towards who has done the most damages in a dogpiling war.
     
  11. Zx Zero Zx

    Zx Zero Zx Chieftain

    Joined:
    Apr 23, 2009
    Messages:
    2,145
    Location:
    Minnesota
    You also need to remember that Capping IS RNG based. You can have a everything in a war, killed their stack, took 6 cites, and if the AI rolls a lets cap to the AI who hasn't done anything, or even moved units roll they will give in to them, and not you.
     
  12. Doshin

    Doshin jolly yellow giant

    Joined:
    Apr 24, 2003
    Messages:
    4,470
    Location:
    Terra
    Dear Tachywaxon,

    I have a vague question with limited practical application for a real game. So I thought you might be able to answer :D

    How does the AI determine the limit at which to accede to a request ("Could you spare X for a friend?"), and does this differ from the formula used to determine the point at which it should give in to a demand?

    My gut feeling is that certain demands succeed where a polite request will fail, at least when you have become powerful enough. For example, it often seems very difficult to successfully request a mid-/late-game technology from an ally, whereas it is entirely possible to bully one of your vassals into giving the same technology away.

    In a similar vein, does the AI alter it's opinion regarding the generosity of a gift as the game progresses? 30 gold in 2000 BC is much more valuable than 30 gold in 2000 AD. But it often seems that you can beg Meditation in 2000 BC, whereas you have no chance of getting (e.g.) Medicine in 2000 AD.

    Many thanks for indulging me.
     
  13. Manco Capac

    Manco Capac Friday,13 June,I Collapse

    Joined:
    Mar 1, 2010
    Messages:
    8,051
    Phew, I feared it was some hard question I can't take.
    Right now, I'm working vassal refusal to give in resources after the first demand. Sure is hard to find the exact mechanics. Found the interface button mechanics for instance but can't actually see what pushes the AI to cancel the vassal deal.

    Let me see for that thing.
    I'm leaning towards CvPlayerAI::AI_considerDeal() thingy.
     
  14. Manco Capac

    Manco Capac Friday,13 June,I Collapse

    Joined:
    Mar 1, 2010
    Messages:
    8,051
    In fact, I'm a bit tight of time now. I'll use instead the POWAAA of bookmarking: This!

    I'll return of that subject if something wasn't answered.
     
  15. Manco Capac

    Manco Capac Friday,13 June,I Collapse

    Joined:
    Mar 1, 2010
    Messages:
    8,051
    Oh my! I can't believe I did not see that. :eek:
    Yay! :rotfl::w00t::bounce:
    I got the answer right under my nose and I didn't see that.

    Interesting how it is tied to Doshin's question.
    Ah, the satisfaction of another mystery solved.
     
  16. Sun Tzu Wu

    Sun Tzu Wu Chieftain Supporter

    Joined:
    Mar 26, 2007
    Messages:
    7,920
    The link Tachywaxon provided answers both your questions. It is also the source I will use to answer your questions. EDIT: I believe there may be another article that better explains this topic, but I'm pressed for time to look for it right now. I realize now that I'm using additional info from that article to answer your questions.

    It doesn't matter whether the player begs (target AI is Pleased or higher) or demands (target AI is Cautious or lower) something from an AI regarding success of the beg/demand. On the other hand, the Demand will suffer a Diplomacy hit whereas the Beg never does, thus it is better to beg if one cares about diplomacy.

    The maximum size of a successful beg/demand is bounded by a linear function which is a limit on the sum of all begs/demands made. The referenced article describes this function better than I can. If no begs/demands have been made versus a particular AI, that AI will accommodate a significantly larger beg/demand than an AI that has agreed to one or more begs/demands already. The size of technologies increases faster than a linear function, so only small technologies in early Eras and obsolete technologies in later Eras can ever be successfully begged/demanded. In practice, it is much easier to beg/demand a linearly increasing amount of Wealth than a Technology or a Technology that has been nearly completely researched. I have done both quite successfully in my games.

    Sun Tzu Wu
     
  17. Manco Capac

    Manco Capac Friday,13 June,I Collapse

    Joined:
    Mar 1, 2010
    Messages:
    8,051
    Oedali's article was the strongest to my knowledge. Anyways, I have the code on access if I want see it on a deeper perspective.
     
  18. Sun Tzu Wu

    Sun Tzu Wu Chieftain Supporter

    Joined:
    Mar 26, 2007
    Messages:
    7,920
    I agree. I had to reread his article in full to convince myself. Only another code perusal may shed more light on this topic.

    Sun Tzu Wu
     
  19. Doshin

    Doshin jolly yellow giant

    Joined:
    Apr 24, 2003
    Messages:
    4,470
    Location:
    Terra
    Thanks both. I'm a little pushed for time now, but a brief skim read has already taught me something (no distinction exists between Pleased or Friendly attitudes in terms of beg success).
     
  20. Manco Capac

    Manco Capac Friday,13 June,I Collapse

    Joined:
    Mar 1, 2010
    Messages:
    8,051
    In XML serie of <tag>values</tag> (CIV4LeaderHeadInfos.xml), there is indeed a location for how many techs trigger a particular attitude modifier called TXT_KEY_MEMORY_TRADED_TECH_TO_US ("You have shared your technological discoveries with us.").

    In Civ4 game, there are two types of attitude: those who are eternal and those affected by some decay process.
    The second category has two values: decay odd and some attitude indicator (which is finally processed in the SDK, that is C++/header files in CvGameCoreDLL folder).

    In CIV4LeaderHeadInfos:

    Decay:

    Spoiler :
    Code:
    <MemoryDecay>
    					<MemoryType>MEMORY_TRADED_TECH_TO_US</MemoryType>
    					<iMemoryRand>100</iMemoryRand>
    				</MemoryDecay>


    Attitude Indicator:

    Spoiler :
    Code:
    <MemoryAttitudePercent>
    					<MemoryType>MEMORY_TRADED_TECH_TO_US</MemoryType>
    					<iMemoryAttitudePercent>5,10,15</iMemoryAttitudePercent>
    				</MemoryAttitudePercent>


    All leaders have same memory capacity; no one forgets faster than others.
    But some leaders are more sensitive to other player propensity (and I said player, because AI-AI works too; not human exclusive) to freely share their discoveries.

    Here's the list:

    Spoiler :
    Code:
    LEADERS     <iMemoryAttitudePercent>
    
    ALEXANDER 	10             
    ASOKA       	 5              
    AUGUSTUS	        10
    BISMARCK   	 5
    BOUDICA     	15
    BRENNUS    	10
    CATHERINE  	15
    CHARLEMAGNE	10
    CHURCHILL  	10
    CYRUS        	10
    DARIUS       	10
    DE_GAULLE  	10
    ELIZABETH  	15
    ROOSEVELT  	10
    FREDERICK  	15
    GANDHI      	5
    GENGHIS_KHAN 	10
    GILGAMESH  	15
    HAMMURABI 	10
    HANNIBAL   	15
    HATSHEPSUT	10
    HUAYNA_CAPAC	10
    ISABELLA    	5
    JOAO          	15
    JULIUS_CAESAR 	10
    JUSTINIAN  	15
    KUBLAI_KHAN	15
    LINCOLN     	15
    LOUIS_XIV  	10
    MANSA_MUSA	20
    MAO_ZEDONG	5
    MEHMED     	10
    MONTEZUMA    	15
    NAPOLEON  	10
    PACAL        	10
    PERICLES    	10
    PETER        	20
    QIN_SHI_HUANG	10
    RAGNAR      	5
    RAMESSES   	10
    SALADIN     	10
    SHAKA        	5
    SITTING_BULL	5
    STALIN       	5
    SULEIMAN    	5
    SURYAVARMAN	5
    TOKUGAWA   	5
    VICTORIA	        5
    WANGKON   	5
    WASHINGTON	5
    WILLEM      	5
    ZARA_YAQOB	5
    


    Now how to process those numbers in an actual number of received techs (point of view of the tech receiver).

    In CvPlayerAI.cpp:

    Spoiler :
    Code:
    int CvPlayerAI::AI_getAttitudeVal(PlayerTypes ePlayer, bool bForced) const
    {
    	PROFILE_FUNC();
    
    	int iRankDifference;
    	int iAttitude;
    	int iI;
    
    	FAssertMsg(ePlayer != getID(), "shouldn't call this function on ourselves");
    
    	if (bForced)
    	{
    		if (getTeam() == GET_PLAYER(ePlayer).getTeam() || (GET_TEAM(getTeam()).isVassal(GET_PLAYER(ePlayer).getTeam()) && !GET_TEAM(getTeam()).isCapitulated()))
    		{
    			return 100;
    		}
    
    		if (isBarbarian() || GET_PLAYER(ePlayer).isBarbarian())
    		{
    			return -100;
    		}
    	}
    
    	iAttitude = GC.getLeaderHeadInfo(getPersonalityType()).getBaseAttitude();
    
    	iAttitude += GC.getHandicapInfo(GET_PLAYER(ePlayer).getHandicapType()).getAttitudeChange();
    
    //	if (GC.getGameINLINE().isOption(GAMEOPTION_AGGRESSIVE_AI))
    //	{
    //		if (GET_PLAYER(ePlayer).isHuman())
    //		{
    //			iAttitude -= 2;
    //		}
    //	}
    
    	if (!(GET_PLAYER(ePlayer).isHuman()))
    	{
    		iAttitude += (4 - abs(AI_getPeaceWeight() - GET_PLAYER(ePlayer).AI_getPeaceWeight()));
    		iAttitude += std::min(GC.getLeaderHeadInfo(getPersonalityType()).getWarmongerRespect(), GC.getLeaderHeadInfo(GET_PLAYER(ePlayer).getPersonalityType()).getWarmongerRespect());
    	}
    
    	iAttitude -= std::max(0, (GET_TEAM(GET_PLAYER(ePlayer).getTeam()).getNumMembers() - GET_TEAM(getTeam()).getNumMembers()));
    
    	iRankDifference = (GC.getGameINLINE().getPlayerRank(getID()) - GC.getGameINLINE().getPlayerRank(ePlayer));
    
    	if (iRankDifference > 0)
    	{
    		iAttitude += ((GC.getLeaderHeadInfo(getPersonalityType()).getWorseRankDifferenceAttitudeChange() * iRankDifference) / (GC.getGameINLINE().countCivPlayersEverAlive() + 1));
    	}
    	else
    	{
    		iAttitude += ((GC.getLeaderHeadInfo(getPersonalityType()).getBetterRankDifferenceAttitudeChange() * -(iRankDifference)) / (GC.getGameINLINE().countCivPlayersEverAlive() + 1));
    	}
    
    	if ((GC.getGameINLINE().getPlayerRank(getID()) >= (GC.getGameINLINE().countCivPlayersEverAlive() / 2)) &&
    		  (GC.getGameINLINE().getPlayerRank(ePlayer) >= (GC.getGameINLINE().countCivPlayersEverAlive() / 2)))
    	{
    		iAttitude++;
    	}
    
    	if (GET_TEAM(GET_PLAYER(ePlayer).getTeam()).AI_getWarSuccess(getTeam()) > GET_TEAM(getTeam()).AI_getWarSuccess(GET_PLAYER(ePlayer).getTeam()))
    	{
    		iAttitude += GC.getLeaderHeadInfo(getPersonalityType()).getLostWarAttitudeChange();
    	}
    
    	iAttitude += AI_getCloseBordersAttitude(ePlayer);
    	iAttitude += AI_getWarAttitude(ePlayer);
    	iAttitude += AI_getPeaceAttitude(ePlayer);
    	iAttitude += AI_getSameReligionAttitude(ePlayer);
    	iAttitude += AI_getDifferentReligionAttitude(ePlayer);
    	iAttitude += AI_getBonusTradeAttitude(ePlayer);
    	iAttitude += AI_getOpenBordersAttitude(ePlayer);
    	iAttitude += AI_getDefensivePactAttitude(ePlayer);
    	iAttitude += AI_getRivalDefensivePactAttitude(ePlayer);
    	iAttitude += AI_getRivalVassalAttitude(ePlayer);
    	iAttitude += AI_getShareWarAttitude(ePlayer);
    	iAttitude += AI_getFavoriteCivicAttitude(ePlayer);
    	iAttitude += AI_getTradeAttitude(ePlayer);
    	iAttitude += AI_getRivalTradeAttitude(ePlayer);
    
    	for (iI = 0; iI < NUM_MEMORY_TYPES; iI++)
    	{
    		iAttitude += AI_getMemoryAttitude(ePlayer, ((MemoryTypes)iI));
    	}
    
    	iAttitude += AI_getColonyAttitude(ePlayer);
    	iAttitude += AI_getAttitudeExtra(ePlayer);
    
    	return range(iAttitude, -100, 100);
    }


    The very part that interests us is:

    Code:
    for (iI = 0; iI < NUM_MEMORY_TYPES; iI++)
    	{
    		iAttitude += AI_getMemoryAttitude(ePlayer, ((MemoryTypes)iI));
    	}
    Basically making some enumeration of memory types, and #26 is the concerned one.

    Becomes
    Code:
    iAttitude += AI_getMemoryAttitude(TechReceiver, ((MEMORY_TRADED_TECH_TO_US)26));
    And bit farther in CvPlayerAI...

    we have our definition for AI_getMemoryAttitude:

    Code:
    int CvPlayerAI::AI_getMemoryAttitude(PlayerTypes ePlayer, MemoryTypes eMemory) const
    {
    	return ((AI_getMemoryCount(ePlayer, eMemory) * GC.getLeaderHeadInfo(getPersonalityType()).getMemoryAttitudePercent(eMemory)) / 100);
    }
    Basically that in understandable formula:

    iAttitude= [#TechsReceived*<iMemoryAttitudePercent> / 100]

    [] meaning you have to round down after the calculus.

    For instance, for Cathy, let's take instances of 7, 14 and 20 given techs.

    7 techs:
    iAttitude = [7*15/100] = [1.05]=1
    14 techs:
    iAttitude = [14*15/100] = [2.1]=2
    20 techs:
    iAttitude = [20*15/100] = [3]=3

    And that is why for those with <iMemoryAttitudePercent> as 15, for getting diplo modifiers up to +3, it goes 7,7,6 techs.

    Important thing to remember, those with <iMemoryAttitudePercent> as 5 need 20 techs for +1, those with <iMemoryAttitudePercent> as 10 need 10 techs +1 modifier and those with <iMemoryAttitudePercent> as 15 need 7,7,6 techs for +1,+2,+3 modifier.

    Trivia

    • Interestingly, I was thinking that was better in CvTeamAI.cpp because tech trading is a matter of teams more of individuals. Now come the thought, if you trade a tech to a team, the other partner automatically receives the tech. Does it have a tech count for both or just the leader you traded/gave the tech? Food for thought.
    • The decay process is defined in CvPlayerAI::AI_doCounter() ; nothing particular but basic Soren Johnson's RNG that rolls a number from 0 to 100 (for 101 possible values?). If rolling 0, then the count decreases by one. That RNG is processed each turn. And it is worth for each leader as roughly 1% per turn of Alzheimer.
    • Most code parts are trifles. Mostly for me. ;)
     

Share This Page