My personal thread: Clarification of certain game mechanics

ah interesting...didn't came to mind that the game would manipulate yields based on production, but you probably are on the right track...will look into it evening with netbeans to have some syntax highlighting and better formatting.

Are you trying to make some personal mod? I would suggest to put special clause that the changes are exclusive to the human player. We don't know how it could affect the AI because both the human and the AI uses that function.

And yes, most of the coding is based on values evaluation and ordering them in terms of priorities. Better to modify there, thus globally, than trying to understand the whole process. It's like a mini-XML conversion inside the SDK, except you have to compile then.

EDIT: Something like that I think:
Code:
if (isHuman) {
Your personal new valuing system
}
else{
if (isProductionProcess() && !bWorkerOptimization)
	{
		for (int iJ = 0; iJ < NUM_COMMERCE_TYPES; iJ++)
		{
			aiCommerceYieldsTimes100[iJ] += GC.getProcessInfo(getProductionProcess()).getProductionToCommerceModifier(iJ) * aiYields[YIELD_PRODUCTION];
		}

		aiYields[YIELD_PRODUCTION] = 0;
          }
	}
 
Are you trying to make some personal mod? I would suggest to put special clause that the changes are exclusive to the human player. We don't know how it could affect the AI because both the human and the AI uses that function.

And yes, most of the coding is based on values evaluation and ordering them in terms of priorities. Better to modify there, thus globally, than trying to understand the whole process. It's like a mini-XML conversion inside the SDK, except you have to compile then.

well not really... but my playstyle would fit to have better citizen manager when building wealth.
I totally hate MMing each city each turn and generally just turn on citizen manager and close eyes when turning wealth in cities on :-).

Sooo if I get into something neat, I could try to modify BULL dll if I find some tool with which to build it lol :-). But I heard that Visual Studio basic version is for free, so hopefully I will have some limited success if I happen to get there.
Netbeans proved to be not that very good for linking DLL's with cygwin when I did in work (even if in theory it should work).
 
Does BAT/BUG/BULL/BUFFY require the cygwin UNIX interface and tools to work? Is that the reason you mentioned cygwin? Or some other reason? Just curious.

Sun Tzu Wu
 
Does BAT/BUG/BULL/BUFFY require the cygwin UNIX interface and tools to work? Is that the reason you mentioned cygwin? Or some other reason? Just curious.

Sun Tzu Wu

netbeans itself is java platform, for compiling c/c++ code it requires cygwin c++ compiler, you can link it through some menus.

what I read about BULL it is compiled with visual studio and thus should not use any of the cygwin platform, what can use otoh is MFC or other standard libraries included in visual studio.

I had some troubles in work when making JNI for some our application with cygwin c++ compiler (not sure now what was the problem exactly, but I think it isn't that important)
 
@vranasm

I've looked at the code section I gave you earlier and I am more assured that's the one that deals of plots config that gives best value.

Through testing, I have noticed it is depending on the situation and there are thresholds like between a mined grass hill and a flat grass forest, while building wealth, the grass flat forest wins. But if I get a 1 :food: 4 :hammers: , then the flat grass forest is no longer the winner.

At the beginning of the code, we could simplify the the values between those three outputs (:food: = (#Food*15)-1, :hammers:=15 and :commerce:=7), but especially for the food section, there is a big panoply of conditions based on the circumstance in which the city is like being in slavery for instance, and then when evaluating the food value to be added to hammers and commerce ones, it is chosen between a flat out simple food value ( :food: = (#Food*15)-1) or the food value from that combination of circumstances.

Not to mention all other conditions I haven't looked at yet.

To be sure for the human player to maximize and let hammers win while building wealth,

Code:
if (isHuman) {

if (isProductionProcess() && !bWorkerOptimization)
	{
		for (int iJ = 0; iJ < NUM_COMMERCE_TYPES; iJ++)
		{
			aiCommerceYieldsTimes100[iJ] += [COLOR="Red"]1000 * aiYields[YIELD_PRODUCTION][/COLOR];
		}

		aiYields[YIELD_PRODUCTION] = 0;
          }

}
else{
if (isProductionProcess() && !bWorkerOptimization)
	{
		for (int iJ = 0; iJ < NUM_COMMERCE_TYPES; iJ++)
		{
			aiCommerceYieldsTimes100[iJ] += GC.getProcessInfo(getProductionProcess()).getProductionToCommerceModifier(iJ) * aiYields[YIELD_PRODUCTION];
		}

		aiYields[YIELD_PRODUCTION] = 0;
          }
	}

I'm sure at that point, then hammers would win.
Also, not sure if I need to use the macro getPlayer...I don't think so...it is usually used in a one-sided mechanics perspective like trading or attitude. Anyways...
 
Can I ask something about some game mechanic I don't understand completely?
There is some nice thing in game that you can ask for some gold from other Civ.. Usually AI must be pleased or friendly towards me (or I will see "we demand" text instead).. But its possible to get this working also with cautios AI?
Just want to learn something more for better gameplay.. I know that I can't get anything for free for some time.. but than again can.. What is important to know here to get this time shorter.. Should I trade something so Ai gets better attitude to me (not checked if that "trade relationship +bonus" change after I ask for gold).. does same religion somehow decrease this time? it is different time for different game speed or its "magical number"?
Hope I desribe clear enough what I want to know.. And thanks for great info.. :)
 
Can I ask something about some game mechanic I don't understand completely?
There is some nice thing in game that you can ask for some gold from other Civ.. Usually AI must be pleased or friendly towards me (or I will see "we demand" text instead).. But its possible to get this working also with cautios AI?
Just want to learn something more for better gameplay.. I know that I can't get anything for free for some time.. but than again can.. What is important to know here to get this time shorter.. Should I trade something so Ai gets better attitude to me (not checked if that "trade relationship +bonus" change after I ask for gold).. does same religion somehow decrease this time? it is different time for different game speed or its "magical number"?
Hope I desribe clear enough what I want to know.. And thanks for great info.. :)

Yeah, I know you're talking about demands and beggings from AI's. This mechanics annoys people because it seems random, but it is in fact a mechanics similar to try to get the exit of a pokemon game's dark cave without light.

Since that was covered nicely before I was born on CivFanatics, no need to reenact the code translation...see HERE.

To point out most practical important mechanics:

PLEASED or FRIENDLY is the same. Be more generous to the AI won't make the AI more generous to you.
Between CAUTIOUS and PLEASED, it is basically the same begging mechanics, but we call it demand given it incurs a diplo hit.
Don't abuse demands because a hidden counter will explode. After the AI favors you with his/her grace, there is a period of cooldown, which is random, that is the AI doesn't give more surprises while having given one recently unless he forgets it.
The forget rate is 1 chance out of 20 each turn. By 25 turns, you get decent chances he forgot. If you abuse the 5% memory abuses, then the demand counter will explode and when (s)he'll forget, not all demands will be forgotten, but one at a time. If you attempted 20 times, well, you may forget about demands for the rest of the game. It must ideally done at a rate of 25 turns.

Now, the magnitude:
Of course, usually, the beggings are lump sums.
How to determine how much I can ask before (s)he thinks it's too much.

Well, for the first demand ever, it's the points are 50+#turnSinceMet.
If you met the AI's for 20 turns, then you got 70 begging points.

Then this value is inflated by a default x2 and a further x3 if you are sharing 8 tiles or more with that AI (land target). So asking an AI on the other continent is harder unless you put a culturally crushed city of yours there.

At last, there is a power comparison (vassals power ignored) between you nations, but if you think you got similar powers (or better), then just ignore this for simplification.

Next demands, the free 50 is no longer, because you spent you begging points. It is simply #turnSinceMet with the two multipliers.

Now how gold is valued by the AI? Well, I already talked about it in the OP, but I'll make a reminder here:
It's 2 begging points for 1 gold. So if you want 50 gold, you need 100 begging points.

BUT, there are moments the AI feels financial pressure and demands 3 begging points for 1 gold (they value more gold because well financial pressure).
So for 50 gold, it's 150 begging points. How to determine the AI is under financial stress, just like the link explained, just ask a counter proposal of whatever you want and if the AI gives a gold proposal in numbers finishing with 3,6 or 9, thus it is financial crisis.

At last, an example of the begging magnitude:

You meet the AI for 25 turns:

Begging points=50+25=75
You are sharing borders and assume you have similar powers
Begging points=75*2*3=450

You check a counter proposal trrade and the AI gives you smallest increment of gold with 5 gold like 45 gold plus a tech. Not under financial stress, thus 1 gold=2 begging point.

Therefore, you can beg 225 gold (well, 220 because you can't set 225 manually).
Perhaps, just put 200 gold if you are unsure of your power (not enough EP on the AI).

BTW, to know the number of turns between the meeting AI and now, just put small notes on the map with ALT+S about the turn of meeting, then a simple substraction should do the job.

Good luck. Then it is a matter of experience.
 
@Vran: C++ and Visual C++ can basically be considered as two different programming languages which is why a normal C++ compiler will fail. Visual C++ relies on the same coding mechanisms as C++ but makes extensive use of .NET entities. You don't need Visual Studio to compile Visual C++ code. Any Visual C++ compiler will do. The best free editor / compiler is probably Microsoft's Visual C++ express. (Not as great as VS but nice for home use if you don't want to invest in a professional tool.)
 
^^^ This is simply wrong. ^^^

There is an optional flag (/CLR) that you can give to the VC++ compiler which will enable language extensions for use in the .NET environment. Without the flag, VC++ compiles standard C++ code. With care, the same code will compile in VC++ and gc++. I have done this many times.
 
^^^ This is simply wrong. ^^^

There is an optional flag (/CLR) that you can give to the VC++ compiler which will enable language extensions for use in the .NET environment. Without the flag, VC++ compiles standard C++ code. With care, the same code will compile in VC++ and gc++. I have done this many times.
Well, I didn't say that you can't compile normal C++ code with VS. I said a normal C++ compiler will not compile .NET entities for you which is something Vran wanted to do.
 
MFC is not .NET code; it is written in standard C++. It does not use any .NET extensions and, in fact, does not access .NET in any way. Instead it is written to the Win32 API. The source to MFC comes with VS.

In theory, you should be able to compile it using a gc++ compiler. In practice, it is likely that there are enough differences in the gc++ and VC++ Windows header files that this could be quite a challenging task.

I agree with you that the best solution is to use VS Express.
 
Relative power affects the success of tribute demands, but it has no effect on the begging/tribute amount. Your last post (the example) seemed to imply that relative power does affect the amount that can be successfully begged.

Sun Tzu Wu
 
well while we derail a bit the thread... i have no clue what you talk about :-D

I just needed to call SetWindowsHookEx from java :-) after experimenting a bit i changed the options in Visual studio so the DLL is standalone and needs only standard windows dll's (making it from somewhat robust 80kB bastard with need for 6MB another DLL's into nice helpful 30kB DLL :-)). The same can't be said about cygwin and what is worse...it didn't even work since it didn't send the callbacks to java as i needed.

biggest drawback of cygwin is it doesn't have usefull IDE for debugging and netbeans doesn't integrate it well enough to debug things there.

in the Mods subforum here I read somewhere that for compiling the CvGameCoreDLL.dll you need visual studio (if I remember right), so I guess these guys know what they talk about (that should be hopefully helpful to STW since he originally asked about my experimantation)
 
well while we derail a bit the thread... i have no clue what you talk about :-D

I just needed to call SetWindowsHookEx from java :-) after experimenting a bit i changed the options in Visual studio so the DLL is standalone and needs only standard windows dll's (making it from somewhat robust 80kB bastard with need for 6MB another DLL's into nice helpful 30kB DLL :-)). The same can't be said about cygwin and what is worse...it didn't even work since it didn't send the callbacks to java as i needed.

biggest drawback of cygwin is it doesn't have usefull IDE for debugging and netbeans doesn't integrate it well enough to debug things there.

in the Mods subforum here I read somewhere that for compiling the CvGameCoreDLL.dll you need visual studio (if I remember right), so I guess these guys know what they talk about (that should be hopefully helpful to STW since he originally asked about my experimantation)

Sorry, Vran. I was under the impression that you needed .NET support for a mod. If you only want to access the Windows API you don't really need .NET at all. Abegweit is right in saying that even a normal c++ compiler would theoretically be able to do it, but writing the makefile could be a real pain. Have you tried either of the VS express tools? (They come with the same compiler as the corresponding VS version does.)
 
Dear Tachywaxon,

I have another question that is probably as obtuse as it is abstruse. If you ever discover the answer (and no problem if you don't...) I would be much obliged.

Under what circumstances does a successful gold/tech/resource beg NOT lead an AI to stop plotting war against the player?

An example:

A) No beg.

Spoiler :
ScreenShot2013-01-28at51707AM_zps937d9d1c.jpg


ScreenShot2013-01-28at51727AM_zpsb6aa4490.jpg


B) Beg.

Spoiler :
ScreenShot2013-01-28at51752AM_zps8a2fa6b9.jpg


ScreenShot2013-01-28at51809AM_zps437c017a.jpg


ScreenShot2013-01-28at51842AM_zps75b850f5.jpg


ScreenShot2013-01-28at51909AM_zps697d26ae.jpg

This hasn't happened to me for a while.

Save attached, for what it's worth. Many thanks!
 

Attachments

I've only ever seen 1 beg make the AI change his DoW target. The normal behaviour is simply to instill a 10t temporary peace after which the AI will start the war as it had initially planned.

I suspect it might have to do with the AI's finances but I could never find out.
 
Usually the AI simply stops plotting altogether, though. They can start to plot on the player again after the ten turns are up, of course, provided that relations allow. But it is very unusual, in my experience at least, for a 10T temporary peace to be just that: a 10T temporary peace.
 
Agreed. The beg simply delays the plotted DoW for up to 10t. If one is (cautiously) tracking the AI's SoD toward one's border, it may help to wait until its within 1t of entering one's border to beg, thus delaying the DoW exactly 10t (maximizing the DoW delaying effect of the beg). Use the extra time to prepare a defense or offense to decimate the AI's SoD.

I'm not sure, but the AI may reevaluate its planned DoW based on relative Power plus maybe other considerations and "change its mind" about the planned DoW. Someone would need to check the code to be sure.

Sun Tzu Wu
 
I am closing in to answering your question, Doshin.

Just preparing some raw stuff here.

Indeed, it is found in CvTeamAI.cpp file given war in its full generality is matter of teams...

Basically, AI_calculateAreaAIType() and AI_doWar() are the main cast of the drama.

The first i

Spoiler :
AreaAITypes CvTeamAI::AI_calculateAreaAIType(CvArea* pArea, bool bPreparingTotal) const
{
PROFILE_FUNC();

bool bRecentAttack;
bool bTargets;
bool bChosenTargets;
bool bDeclaredTargets;
int iOffensiveThreshold;
int iAreaCities;
int iI;

if (!(pArea->isWater()))
{
if (isBarbarian())
{
if ((pArea->getNumCities() - pArea->getCitiesPerPlayer(BARBARIAN_PLAYER)) == 0)
{
return AREAAI_ASSAULT;
}
if ((countNumAIUnitsByArea(pArea, UNITAI_ATTACK) + countNumAIUnitsByArea(pArea, UNITAI_ATTACK_CITY) + countNumAIUnitsByArea(pArea, UNITAI_PILLAGE) + countNumAIUnitsByArea(pArea, UNITAI_ATTACK_AIR)) > (((AI_countMilitaryWeight(pArea) * 20) / 100) + 1))
{
return AREAAI_OFFENSIVE; // XXX does this ever happen?
}

return AREAAI_MASSING;
}

bRecentAttack = false;
bTargets = false;
bChosenTargets = false;
bDeclaredTargets = false;

bool bAssault = false;
bool bPreparingAssault = false;

if (bPreparingTotal)
{
iOffensiveThreshold = 25;
}
else
{
iOffensiveThreshold = 20;
}

iAreaCities = countNumCitiesByArea(pArea);

for (iI = 0; iI < MAX_CIV_TEAMS; iI++)
{
if (GET_TEAM((TeamTypes)iI).isAlive())
{
if (AI_getWarPlan((TeamTypes)iI) != NO_WARPLAN)
{
FAssert(((TeamTypes)iI) != getID());
FAssert(isHasMet((TeamTypes)iI) || GC.getGameINLINE().isOption(GAMEOPTION_ALWAYS_WAR));

if (AI_getWarPlan((TeamTypes)iI) == WARPLAN_ATTACKED_RECENT)
{
FAssert(isAtWar((TeamTypes)iI));
bRecentAttack = true;
}

if ((GET_TEAM((TeamTypes)iI).countNumCitiesByArea(pArea) > 0) || (GET_TEAM((TeamTypes)iI).countNumUnitsByArea(pArea) > 4))
{
bTargets = true;

if (AI_isChosenWar((TeamTypes)iI))
{
bChosenTargets = true;

if ((isAtWar((TeamTypes)iI)) ? (AI_getAtWarCounter((TeamTypes)iI) < 10) : AI_isSneakAttackReady((TeamTypes)iI))
{
bDeclaredTargets = true;
}
}
}
else
{
bAssault = true;
if (AI_isSneakAttackPreparing((TeamTypes)iI))
{
bPreparingAssault = true;
}
}
}
}
}

if (bDeclaredTargets)
{
return AREAAI_OFFENSIVE;
}

if (bTargets)
{
if ((countNumAIUnitsByArea(pArea, UNITAI_ATTACK) + countNumAIUnitsByArea(pArea, UNITAI_ATTACK_CITY) + countNumAIUnitsByArea(pArea, UNITAI_PILLAGE) + countNumAIUnitsByArea(pArea, UNITAI_ATTACK_AIR)) > (((AI_countMilitaryWeight(pArea) * iOffensiveThreshold) / 100) + 1))
{
return AREAAI_OFFENSIVE;
}
}

if (bTargets)
{
for (int iPlayer = 0; iPlayer < MAX_CIV_PLAYERS; iPlayer++)
{
CvPlayerAI& kPlayer = GET_PLAYER((PlayerTypes)iI);
if (kPlayer.isAlive())
{
if (kPlayer.getTeam() == getID())
{
if (kPlayer.AI_isDoStrategy(AI_STRATEGY_DAGGER) || kPlayer.AI_isDoStrategy(AI_STRATEGY_FINAL_WAR))
{
if (pArea->getCitiesPerPlayer((PlayerTypes)iPlayer) > 0)
{
return AREAAI_MASSING;
}
}
}
}
}
if (bRecentAttack)
{
int iPower = countPowerByArea(pArea);
int iEnemyPower = countEnemyPowerByArea(pArea);
if (iPower > iEnemyPower)
{
return AREAAI_MASSING;
}
return AREAAI_DEFENSIVE;
}
}

if (iAreaCities > 0)
{
if (countEnemyDangerByArea(pArea) > iAreaCities)
{
return AREAAI_DEFENSIVE;
}
}

if (bChosenTargets)
{
return AREAAI_MASSING;
}

if (bTargets)
{
if (iAreaCities > (getNumMembers() * 3))
{
if (GC.getGameINLINE().isOption(GAMEOPTION_AGGRESSIVE_AI) || GC.getGameINLINE().isOption(GAMEOPTION_ALWAYS_WAR) || (countPowerByArea(pArea) > ((countEnemyPowerByArea(pArea) * 3) / 2)))
{
return AREAAI_MASSING;
}
}
return AREAAI_DEFENSIVE;
}
else
{
if (bAssault)
{
if (AI_isPrimaryArea(pArea))
{
if (bPreparingAssault)
{
return AREAAI_ASSAULT_MASSING;
}
}
else if (countNumCitiesByArea(pArea) > 0)
{
return AREAAI_ASSAULT_ASSIST;
}

return AREAAI_ASSAULT;
}
}
}

return AREAAI_NEUTRAL;
}


Those AREAAI_<insert> are basically the trigger of an actual action in constrast of those war plans in AI_doWar. What you are interesting in is AI dropping their war plans for NO_WARPLAN. Indeed, there is one line of code treating that aspect:

Spoiler :
Code:
else if (AI_getWarPlan((TeamTypes)iI) == WARPLAN_PREPARING_TOTAL)
				{
					FAssert(canDeclareWar((TeamTypes)iI));

					if (AI_getWarPlanStateCounter((TeamTypes)iI) > ((10 * iTimeModifier) / 100))
					{
						bAreaValid = true;
						bShareValid = false;

						for(pLoopArea = GC.getMapINLINE().firstArea(&iLoop); pLoopArea != NULL; pLoopArea = GC.getMapINLINE().nextArea(&iLoop))
						{
							if (AI_isPrimaryArea(pLoopArea))
							{
								if (GET_TEAM((TeamTypes)iI).countNumCitiesByArea(pLoopArea) > 0)
								{
									bShareValid = true;

									bOffensiveValid = false;
[COLOR="Purple"][B]
									if (AI_calculateAreaAIType(pLoopArea, true) == AREAAI_OFFENSIVE)
									{
										bOffensiveValid = true;
									}

									if (!bOffensiveValid)
									{
										bAreaValid = false;
									}
								}
							}
						}

						if (bAreaValid || !bShareValid)
						{
							AI_setWarPlan(((TeamTypes)iI), WARPLAN_TOTAL);
						}
						else if (AI_getWarPlanStateCounter((TeamTypes)iI) > ((20 * iTimeModifier) / 100))
						{
							AI_setWarPlan(((TeamTypes)iI), NO_WARPLAN);
						}
					}[/B][/COLOR]
				}

The purple part is the one that triggers AI to abandon their war plans.
It seems tied only with a specific war plan called WARPLAN_PREPARING_TOTAL. Other war plans are not valid for calling off war planning.

If we read all the conditional structures one by one, it gives:

  1. If we are under WHEEOH with WARPLAN_PREPARING_TOTAL flag...
  2. If our (the AI point of view) war planning counter has reached over 10 * iTimeModifier) / 100, which is depending of factors like our powers (if we are the target in its mind), theirs, a base 100 points, a special clause if the AI is super strong like twice target power (usual on deity), it further multiplies the length for war preparation, thus the AI really want the target's head and finally scaled with gamespeed as preparing war is longer/shorter compared to normal speed.
    On normal speed, with similar powers, I think it gives 10 turns for war preparation before starting to roll over some weakling...
  3. If the target is in the primary area...basically land target IIRC. Something like sharing 8 tiles or more with the agressor and being on the same landmass (which can be anything surrounded with waters...even islands). Also, something about the agressor capital. IIRC again.
  4. If the trigger AREAAI_OFFENSIVE is sent from AI_calculateAreaAIType() function. I'll return on this core aspect separatedly.

If those conditions are fulfilled, the the AI sends its stack for a war with purpose to crush its opponent.

If not, then we enters in the case where the AI may ponder leaving its target alone:

Code:
else if (AI_getWarPlanStateCounter((TeamTypes)iI) > ((20 * iTimeModifier) / 100))
						{
							AI_setWarPlan(((TeamTypes)iI), NO_WARPLAN);
						}
Basically, if war count is over twice the last one (e.g. basic 20 turns on normal speed with comparable powers), the AI re-evaluate its war preparation and returns to its peaceful state.

==========================================
==========================================

Now, the most important and core that brings the trigger AREAAI_OFFENSIVE:

Here it is:

Code:
if (bTargets)
		{
			if ((countNumAIUnitsByArea(pArea, UNITAI_ATTACK) + countNumAIUnitsByArea(pArea, UNITAI_ATTACK_CITY) + countNumAIUnitsByArea(pArea, UNITAI_PILLAGE) + countNumAIUnitsByArea(pArea, UNITAI_ATTACK_AIR)) > (((AI_countMilitaryWeight(pArea) * iOffensiveThreshold) / 100) + 1))
			{
				return AREAAI_OFFENSIVE;
			}
		}

If the sum up of agressor units with UNITAI_ATTACK, UNITAI_ATTACK_CITY, UNITAI_PILLAGE and less important early game UNITAI_ATTACK_AIR scripts is over
AI_countMilitaryWeight(pArea) multiplied with a constant worth 25 (which seems a constant equal to 25 for PreparingTotalWar), then, the trigger is sent for beating up some neighbour.

Otherwise...AI_countMilitaryWeight(pArea) for a given area decides why the AI has stopped by his/her own decision to stop thinking war.

Now we enter the final step and the most important of the uselessness of this reply:

Code:
int CvTeamAI::AI_countMilitaryWeight(CvArea* pArea) 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).AI_militaryWeight(pArea);
			}
		}
	}

	return iCount;
}

For the agressor, (s)he wants to know its military weight for a given area and it is:

Code:
int CvPlayerAI::AI_militaryWeight(CvArea* pArea) const
{
	return (pArea->getPopulationPerPlayer(getID()) + pArea->getCitiesPerPlayer(getID()) + 1);
}

Basically population and their city count!
Yes, those AI's reevaluate their plans to crush an enemy based only on their empire stats you simply don't have control upon. The AI must have more units with attack type script than the city/pop tally, otherwise, perhaps she or he feels not comfortable to go at war. Not sure the reason behind this anyways...

BUT, there is a hidden way to play the AI decision in its back by giving more health/happy resources, helping to city growth and thus gambling the AI new short term decision.

Also, AI's personalities play a determining role in calling off war state: their preferred AI unit script. Some AI's have good favored AI unit scripts, but others may have defensive/counter scripts and that certainly don't help them to push a war if they spam counter/defend units instead of sine qua non attack type units.

Final word, what does it have to do with that small begging?
Beggings don't change their mind at all. Easy to prove, have you ever seen their WHEEOH mode dropped instantly after beg...no.
But begging increases their war preparation counter and certainly plays a bit in your favor, but if you got a super attack type unit spammer, it's perhaps useless.
Also, the decision to call off a war decision comes at 20 turns (I repeat, war prep counter is dynamic depending of situation, 10 or 20 turns are just basic references...) after starting WHEOOH, and a forced peace treaty from begging pity is only 10 turns.

Lastly, given deity AI's are much much much more powerful early, count on them to have prolonged WHEOOH!!! :run:

EDIT: Oops, it ended up to be a finished write up after all...:mad:
 
Oh by the way,

that thing:

Code:
if (bTargets)
		{
			if ((countNumAIUnitsByArea(pArea, UNITAI_ATTACK) + countNumAIUnitsByArea(pArea, UNITAI_ATTACK_CITY) + countNumAIUnitsByArea(pArea, UNITAI_PILLAGE) + countNumAIUnitsByArea(pArea, UNITAI_ATTACK_AIR)) > (((AI_countMilitaryWeight(pArea) * iOffensiveThreshold) / 100) + 1))
			{
				return AREAAI_OFFENSIVE;
			}
		}

is also applied to barb team when it decides to invade into nations' culture. It is the same function used.
Seems if they have too many cities for a given landmass (oohhh that makes me remember that deity barb challenge by Kossin where at some point the barbs stop invading poor Churchill) and those cities are furthermore big vertically, it may mean the end of AREAAI_OFFENSIVE period or commonly called the barb invasions.

Of course, barbs cities also diminish the barb unit spawning, so it is a double effect.
 

Attachments

Back
Top Bottom