View Full Version : RefuseAttitudeThresholds not working ???


DanF5771
Jul 04, 2008, 03:50 AM
AI seems to refuse trades for Bonuses and Civics with a DENIAL_ATTITUDE although it should definitely trade according to the leader's XML thresholds.
I'm not really C++ savvy, but I think the problem is somehow connected to the method
AttitudeTypes CvPlayerAI::AI_getAttitude(PlayerTypes ePlayer, bool bForced).
This seems to return ATTITUDE_CAUTIOUS even though I was FRIENDLY in various tests.

This method is e.g. called in
DenialTypes CvPlayerAI::AI_bonusTrade(BonusTypes eBonus, PlayerTypes ePlayer) const

After changing
eAttitude = AI_getAttitude(ePlayer);
to
eAttitude = GET_TEAM(getTeam()).AI_getAttitude( GET_PLAYER(ePlayer).getTeam() );
which retrieves the Team Attitude the trades work fine!

This might cause a multitude of problems throughout the whole game, whenever the PlayerAI's attitude is taken into consideration.

What is / Where am I wrong here???

DanF5771
Jul 04, 2008, 06:13 AM
Related to the above problem is the following:

An AI will always redline all Civics in trade screen with a DENIAL_FAVORITE_CIVIC when they are currently running their favorite civic.

Proposal for a solution in
DenialTypes CvPlayerAI::AI_civicTrade(CivicTypes eCivic, PlayerTypes ePlayer) const

Change
if (GC.getLeaderHeadInfo(getPersonalityType()).getFav oriteCivic() != NO_CIVIC)
{
if (isCivic((CivicTypes)(GC.getLeaderHeadInfo(getPers onalityType()).getFavoriteCivic())))
{
return DENIAL_FAVORITE_CIVIC;
}
}

to something like
CivicTypes eFavoriteCivic = (CivicTypes)GC.getLeaderHeadInfo(getPersonalityTyp e()).getFavoriteCivic();
if (eFavoriteCivic != NO_CIVIC)
{
int iCivicCategory = GC.getCivicInfo(eFavoriteCivic).getCivicOptionType ();

if ((isCivic(eFavoriteCivic)) && (GC.getCivicInfo(eCivic).getCivicOptionType() == iCivicCategory))
{
return DENIAL_FAVORITE_CIVIC;
}
}

Together with the Attitude fix this will lead to trade screens like this:
http://i294.photobucket.com/albums/mm105/DanF5771/Justin.jpg

Justinian is FRIENDLY with me and currently running his favorite civic Theocracy, so he will:
1. trade me strategic resources (Iron)
2. not deny switching to Vassalage and Caste System
3. deny switching to Decentralization, because that's an inferior civic
4. deny switching to Pacifism because he won't switch out of his favorite civic Theocracy

Solver
Jul 04, 2008, 03:57 PM
Related to the above problem is the following:

An AI will always redline all Civics in trade screen with a DENIAL_FAVORITE_CIVIC when they are currently running their favorite civic.


I'm afraid that's by design.

DanF5771
Jul 05, 2008, 02:35 AM
Aaah, a reply, and from Solver himself!

But I'm sorry, I just can't follow the idea behind such a design.
Should running the favorite civic protect an AI from demands to switch civics in the other civic categories?
It regularly frustrates me to see all civics redlined in the trade screen, as this rule poses a major restraint on the human player's possibilities to influence the diplomatic situation in the game.

So I get the feeling that this rule "goes against everything good game design stands for!". ;)

And it can be "corrected" with just 2 lines of code...

What do other players think about this subject???
Plus, has anybody reproduced the problems of my first post about the trade denials due to allegedly too low attitude???
Why can there be a difference between player's attitude and team's attitude anyway when the teams consist only of the respective players???

77alex77
Jul 05, 2008, 05:58 AM
[...] Should running the favorite civic protect an AI from demands to switch civics in the other civic categories? [...]

I agree. The protection should only apply to the category of the favorite civic, IMO.

Roland Johansen
Jul 05, 2008, 06:16 AM
It seems logical that a civilisation is unwilling to switch out of its favourite civic. That's a part of their programmed personality. It seems extremely odd that whether an AI is using its favourite civic or not has an effect on its willingness to change its civic choices in unrelated civic categories. I must say that I personally had not noticed this before because I rarely try to influence the AI's civic choices. The odd exception is when they're using the theocracy civic and I want to spread a religion to their cities (without the missionary gifting trick).

Solver, are you sure that its a designers choice that whether an AI is using its favourite civic or not has an effect on its willingness to change its civic choices in unrelated civic categories?:confused:
If so, could you try and explain the reasoning behind that choice? It seems rather odd...

Solver
Jul 05, 2008, 08:13 AM
I'm not sure. I believe that it just shows that the leader is very satisfied with his choice of society and is unwilling to make any changes at all. Of course, I see your point - it would make sense if the refusal applied only to the same civic category. Hmm. At least be glad that "favorite civic" doesn't mean that the AI would always run that civic no matter what ;)

Psyringe
Jul 05, 2008, 10:09 AM
I'm throwing my personal 2 cents in on the same side as DanF5571, 77alex77, and Roland. The change suggested by DanF makes more sense than the game's current behavior.

About the only reason I can see why the designers could have *intended* the game to behave as it currently does, is if DanF's change made it too easy for the player to change AI civics, so the code prevents *any* civic changes if an AI has reached its favorite civic. But even that would be a very crude solution, in this case it'd still be better to apply DanF's change, and then fine-tune the trade value of civic changes.

It just doesn't make sense that I can talk an AI into another *political* system right now, but have no chance to do so any more once he applied his favorite *religious* civic.

Roland Johansen
Jul 05, 2008, 10:16 AM
I'm not sure. I believe that it just shows that the leader is very satisfied with his choice of society and is unwilling to make any changes at all. Of course, I see your point - it would make sense if the refusal applied only to the same civic category. Hmm. At least be glad that "favorite civic" doesn't mean that the AI would always run that civic no matter what ;)

Yes, I'm talking about the refusal to talk about changing civics applying to all of the civic categories instead of just the favourite civic category. That's a bit weird in my opinion. Couldn't that have been a small programming error where the designers intended the refusal to apply to the same civic category but accidentally let it apply to all civic categories? I can imagine that some small communication error between designers and programmers or just a small programming error could lead to such non-intuitive AI behaviour. I find it hard to rationalise the present AI behaviour.

Might I ask: What are your arguments against changing it? I wouldn't mind the present AI behaviour if I could find a good argument to rationalise this behaviour (realism or gameplay based argument).

And yes, I'm happy that AI's don't make (very) stupid choices based on their favourite civic. The game needs some balance between a smart AI and a roleplaying AI. Finding that balance will always be tricky. At present, with the availability of both the normal and the aggressive AI, I think this balance has been quite good for the various types of civ-players.

Psyringe
Jul 05, 2008, 10:39 AM
Plus, has anybody reproduced the problems of my first post about the trade denials due to allegedly too low attitude???
Not yet - could you upload your testbed?

Why can there be a difference between player's attitude and team's attitude anyway when the teams consist only of the respective players???
I don't know, and that's about the only detail that keeps up my skepticism: I don't understand *why* and *how* the change you propose solves the problem.

DanF5771
Jul 05, 2008, 03:42 PM
Not yet - could you upload your testbed?


I just used GatlingGun's attached 1500AD save from the first post of his Unfavorable trade policies thread (http://forums.civfanatics.com/showthread.php?t=281367) (that's where I noticed this problem first) and self-pillaged my Iron to get Justinian's through a trade. But just as GatlingGun's second trade screenshot says, Justinian also redlines his Iron in my game with a DENIAL_ATTITUDE ("We just don't like you enough").

But he should not do this, because according to the XML he must allow to trade strategic resources if he is better than CAUTIOUS with me (for what price is another question).
In the save I have an attitude value of +11 with him that can be increased to +15 by gifting techs. But no matter how high/low the values are, if the diplo screen tells me he is FRIENDLY with me, then this must be his one current attitude towards me referring all aspects of the game and there must not be any other deviating internal and invisible attitudes created by hidden modifiers. (btw to get down to CAUTIOUS which would be necessary for his denial response the hidden modifiers would need to be at least -13!).

So my first guess was that this might have something to do with the fix of the multiple corporation resources bug (Iron = Mining Inc.) To test this I gave Justinian 2 Ivory via WB and asked for them, but no, DENIAL_ATTITUDE for that too. Then I tested combinations of happy and health resources and various leaders and attitude thresholds which all let me assume that the leaders always treat me as if they were CAUTIOUS towards me when trading for bonuses, civics and religions.

Inspecting the SDK I figured that these are the cases when the denial is a function of the AI player's attitude towards the human player whereas other trades such as for maps or techs ask for the attitude of the AI player's team towards the team of the human player -- and these trades work fine!

So I modified the code for the bonus trade to ask for team attitude and bingo - I can get Justinian's Iron!

I have absolutely no idea why AttitudeTypes CvPlayerAI::AI_getAttitude(PlayerTypes ePlayer, bool bForced) always returns ATTITUDE_CAUTIOUS even though this method appears to be called during the calculation of the team's attitude.
(overloading, python interaction ????)

If anybody wants to test, I attache the modified dll. Note that this is version 19 of Solver's patch, but it also includes my corrected variant of the Collateral Damage calculation (Drill2-4 don't render unit CD immune), the free preserve induced growth of forests over roads/railroads and modified global warming (Recycling Centers and Environmentalism reduce it). I'm not really C++ savvy and don't know if this modification might lead to other problems, but I think for tests it works fine.

JujuLautre
Jul 05, 2008, 08:34 PM
At least be glad that "favorite civic" doesn't mean that the AI would always run that civic no matter what ;)

Wasn't it the case in vanilla and warlords? :P

oedali
Jul 09, 2008, 11:56 AM
DanF5771 definitely has a point here. I agree that this is a bug and had been noticing it in my games before but had not looked into it carefully until now. In my current game the AI is not trading ivory to me even though he is friendly (and I don't have any vassals), giving the same denial message "we just don't like you enough". On the other hand, another AI did trade me luxury resources even when he was annoyed but he wasn't supposed to (because Montezuma needs to be cautious to trade that resource as defined in the xml). The fact that the player attitudes function returns 'cautious' regardless of what must be the culprit here. I can post a save if necessary.

If people are convinced that this is a bug about the incorrect/buggy attitude function (i.e. the player attitude instead of the team attitude) being used for resource trades and civic changes, could it please be fixed in the unofficial patch? I like DanF5771's solution by using the team attitude for everything since that function seems to be working correctly.

DanF5771
Jul 11, 2008, 07:55 AM
Ok, I think I have further encircled the problem of the erroneous determination of an AI's attitude toward other players.
The problem occurs when attempting to trade resources, civics, religions. The respective methods are:

DenialTypes CvPlayerAI::AI_bonusTrade(BonusTypes eBonus, PlayerTypes ePlayer) const
DenialTypes CvPlayerAI::AI_civicTrade(CivicTypes eCivic, PlayerTypes ePlayer) const
DenialTypes CvPlayerAI::AI_religionTrade(ReligionTypes eReligion, PlayerTypes ePlayer) const

Within these methods the attitude toward ePlayer is checked via

eAttitude = AI_getAttitude(ePlayer);

which is supposed to call

AttitudeTypes CvPlayerAI::AI_getAttitude(PlayerTypes ePlayer, bool bForced)

However this is not a const method, so instead the following static method is called directly

// static
AttitudeTypes CvPlayerAI::AI_getAttitude(int iAttitudeVal)

with the ePlayers's ID passed as the int iAttitudeVal argument!
Since the human player always has the ID=0

eAttitude = AI_getAttitude(ePlayer);

always returns ATTITUDE_CAUTIOUS.

I tested this by letting the intended method

AttitudeTypes CvPlayerAI::AI_getAttitude(PlayerTypes ePlayer, bool bForced)

always return ATTITUDE_FURIOUS and playing a WB-scenario with 10 AIs as the 10th AI (Pacal II).
The ID=10 gives me a virtual ATTITUDE_FRIENDLY during those trades, which lets everybody trade everything.

Furious Ragnar wants to give me Gems:
http://i294.photobucket.com/albums/mm105/DanF5771/AttitudeTest.jpg

This is a clear programming bug and should definitely be fixed. As I'm a C++noob I can only suggest something like

eAttitude = (GET_PLAYER((PlayerTypes)getID())).AI_getAttitude( ePlayer);


so there is no need to ask for team attitude as proposed above. There might be a better way--I'd like to leave this to the experts.

77alex77
Jul 12, 2008, 05:44 AM
Hi DanF5771,

thank you for all your efforts to investigate this bug.
I never noticed it, but it has definitely a tremendous impact on gameplay.
I hope that this can be fixed soon.
I also think that it would be great, if this "we-wont-change-our-civics-as-we-run-our-favorit-civic-thing" could be fixed. In my opinion this is a bug too.

DanF5771
Jul 12, 2008, 06:02 AM
I also think that it would be great, if this "we-wont-change-our-civics-as-we-run-our-favorit-civic-thing" could be fixed. In my opinion this is a bug too.

Thanks 77alex77 for agreeing/support. Apparently we are a minority and others don't bother too much.

The favorite-civic thing is easy to fix with the small code changes proposed above, you can see Justinian is willing to adopt Vassalage and Caste System. It's just up to Solver to implement or not (maybe in a better way, because I'm just a C++noob), so I'd love to hear opinions from other players.

bjam
Jul 12, 2008, 08:47 PM
AI seems to refuse trades for Bonuses and Civics with a DENIAL_ATTITUDE although it should definitely trade according to the leader's XML thresholds.
I'm not really C++ savvy, but I think the problem is somehow connected to the method
AttitudeTypes CvPlayerAI::AI_getAttitude(PlayerTypes ePlayer, bool bForced).
This seems to return ATTITUDE_CAUTIOUS even though I was FRIENDLY in various tests.
<snip>
This might cause a multitude of problems throughout the whole game, whenever the PlayerAI's attitude is taken into consideration.

What is / Where am I wrong here???
If I understand you correctly, for initiating or refusing a trade, an AI will always consider that his attitude toward you (or your team) is 'cautious'. I think this is a bug that should be fixed. The AI should use (as it is doing for everything else) the real attitude toward you (or the average for your team if you have vassal(s)).
Related to the above problem is the following:

An AI will always redline all Civics in trade screen with a DENIAL_FAVORITE_CIVIC when they are currently running their favorite civicI'm afraid that's by design.
On this one too I would tend to agree with you and I think that it could be changed. However, according to Solver, it has been made like this for the civics by design, so this is not a bug but the intended gameplay. That's why I think that a modification wouldn't be a bugfix, but a gameplay change, which is beyond the scope of this patch. Maybe we could have two versions of the patch, with and without this, but I guess it would be a nightmare for Solver to update his patch if he has to take care of more than one version depending of what each one prefer. The multiple version problem is already here for the 50 civs dll, so maybe we shouldn't aggravate it. I don't know what to do about it because I disagree with the gameplay choice, or, more precisely, I don't understand it. :crazyeye:

DanF5771
Jul 13, 2008, 04:52 AM
If I understand you correctly, for initiating or refusing a trade, an AI will always consider that his attitude toward you (or your team) is 'cautious'.

Actually it also affects AI to AI trades: The AIs with 3>=ID<10 will always get a virtual attitude of PLEASED in trades with other AIs and AIs with IDs >=10 will be FRIENDLY and thus never be denied a trade due to the leader's refusal thresholds. :crazyeye:

However, according to Solver, it has been made like this for the civics by design, so this is not a bug but the intended gameplay. That's why I think that a modification wouldn't be a bugfix, but a gameplay change, which is beyond the scope of this patch.

IMHO it is much more likely that this was an oversight of the developers than a true intention for gameplay. The AIs will even deny trades to get them out of the inferior starting civics (Barbarism, ...) with this "That would go against everything we stand for" response in times when they run their favorite civic and haven't decided to switch civics in the other category yet. I don't see the improvement in gameplay that comes with this big restriction of one's possibilities to influence the diplomatic situation in the game.

Roland Johansen
Jul 13, 2008, 06:23 AM
Actually it also affects AI to AI trades: The AIs with 3>=ID<10 will always get a virtual attitude of PLEASED in trades with other AIs and AIs with IDs >=10 will be FRIENDLY and thus never be denied a trade due to the leader's refusal thresholds. :crazyeye:



IMHO it is much more likely that this was an oversight of the developers than a true intention for gameplay. The AIs will even deny trades to get them out of the inferior starting civics (Barbarism, ...) with this "That would go against everything we stand for" response in times when they run their favorite civic and haven't decided to switch civics in the other category yet. I don't see the improvement in gameplay that comes with this big restriction of one's possibilities to influence the diplomatic situation in the game.

DanF, do you know whether these bugs also existed in the official version BTS 3.13?

At any rate, I would advise you to also mention these 2 bugs in the new BetterAI project. The guys who revived that project are trying to improve the AI and it would seem to me that a fixed attitude in some negotiations may harm the AI. It can't get certain resources and can't influence some of the other AI's civics just because the real relations are ignored. That can't be good. Humans can often deal with buggy gameplay better than an AI can.

The guys who are working on that betterAI are also more in the business of modding. While Solver may deem a certain change too far reaching or not following the intentions of the designers, these guys don't care as much about such considerations. They just want to improve the AI. They include the latest version of Solvers unofficial patch in their work and there is some level of cooperation between Solver and the BetterAI team.

Kazper
Jul 13, 2008, 05:31 PM
About the only thing I can contribute here is total and absolute agreement with you that BOTH these things are bugs, and should be fixed.

I sincerely hope this is included in the unofficial patch - or even better in an official one. These both weaken the game tremendously, and the trade bug even also weakens the AI massively by causing arbitrary relations...

jdog5000
Jul 17, 2008, 05:16 PM
Very well done DanF, that's huge both in terms of player-AI relations and just AI-AI relations ... glad you kept searching to find the source!

This will certainly be in the next Better BTS AI release (currently at .21)

Dresden
Aug 10, 2008, 04:37 AM
Another potential trade-denial-related bug has popped up in the topic This is weird; anyone ever see this? (http://forums.civfanatics.com/showthread.php?t=286318)

You can't ask an AI civ to run Emancipation because they will redline it with the message TXT_KEY_DENIAL_ANGER_CIVIC ("We don't want to deal with the unhappiness"). However, that kind of denial message seems like it should come from asking them to switch out of Emancipation, not into it. Here's the very brief bit of CvPlayerAI::AI_civicTrade() that is causing it:
if (getCivicPercentAnger(eCivic) > 0)
{
return DENIAL_ANGER_CIVIC;
}

That would make sense if a positive return value from CvPlayer::getCivicPercentAnger() means that your people will become unhappy if you run the suggested civic. But a positive return value instead means that you will get unhappiness if you aren't running it. Note that you can see the true meaning of this return value by looking at how the same function is used in CvCity::unhappyLevel().

Unfortunately, fixing this properly is a little tricky. The quick and dirty method would be to do something like this:
if (getCivicPercentAnger(getCivics((CivicOptionTypes) (GC.getCivicInfo(eCivic).getCivicOptionType())),tr ue) > 0)
{
return DENIAL_ANGER_CIVIC;
}

That basically says "if switching out of our current civic of the same type as the suggested one can cause unhappiness, deny." So, for example, if the AI is in Emancipation and the human is suggesting Caste System, they'll deny. But if the AI is running Caste System and the human is suggesting Emancipation, they'll consider it. This did work for me in a brief test.

Note that this fix assumes there is a maximum of one civic of each type that can cause unhappiness in other nations. This should work fine in the original game where Emancipation is the only such civic, but wouldn't be so hot if multiple civics have been modified to cause that sort of unhappiness. That'd require a much more complex check where you'd have to try and determine how much civic-related unhappiness you currently have and compare it to how much civic-related unhappiness you'd have if you switched.

jdog5000
Aug 11, 2008, 06:37 PM
Wow, nice catch. Certainly the quick and dirty method you describe seems to be what Firaxis intended here, to make it a little more mod friendly we could do:


if (getCivicPercentAnger(getCivics((CivicOptionTypes) (GC.getCivicInfo(eCivic).getCivicOptionType())),tr ue) > getCivicPercentAnger(eCivic))


How does that sound?

Dresden
Aug 11, 2008, 07:00 PM
That might work, but it would definitely need some testing. Don't know why I didn't think of using that comparison. :)

DanF5771
Aug 12, 2008, 03:38 AM
Haha, really nice Dresden! The problem is not so much the AI's denial to switch into Emancipation (most of the times they do so automatically, plus the human player would probably want to decrease his own Emancipation unhappiness more often than to increase it for other AIs), but the thus never occurring denial to switch out of it.

jdog5000: shouldn't the comparison be if Anger(CurrentCivic) < Anger(NewCivic) --> denial ?

Dresden
Aug 12, 2008, 04:31 AM
@Dan: you're making the same mistake Firaxis made ;) getCivicPercentAnger() does not tell you how much anger running that civic causes, but how much not running it causes. so jdog's comparison should be okay.

Here's a concrete example:
Assume that a new labor civic called Unions generates small unhappiness in non-users while Emancipation generates large unhappiness in non-users. Thus we get the relationship getCivicPercentAnger(Emancipation) > getCivicPercentAnger(Unions) > 0

jdog's comparison looks like this:
if (getCivicPercentAnger(current) > getCivicPercentAnger(proposed)) then deny.

Thus they would redline a change from Emancipation to Unions but would not redline a change from Unions to Emancipation.

DanF5771
Aug 12, 2008, 05:04 AM
Right! Should have taken a look at the actual code and not just at the clever (:rolleyes:) name of getCivicPercentAnger.
Your Unions example makes it "clear as an unmuddied lake, sir".:goodjob:

Niklas
Aug 16, 2008, 04:49 PM
I agree with Dan too - this is a really serious bug, and I won't willingly play 3.17 until it has been fixed.

And the favorite civic bug is definitely a bug too.

TheMeInTeam
Sep 09, 2008, 03:15 PM
I'm not sure. I believe that it just shows that the leader is very satisfied with his choice of society and is unwilling to make any changes at all. Of course, I see your point - it would make sense if the refusal applied only to the same civic category. Hmm. At least be glad that "favorite civic" doesn't mean that the AI would always run that civic no matter what ;)

I've been running into this problem lately. Your argument in its defense isn't particularly valid, because even in theocracy for example Justinian would still switch from caste system to emancipation. However, it would be impossible to bribe him to do so.

On the flip side, bribes for civic switches make sense. I switch civics just for diplo sometimes, I would DEFINITELY switch civics if it meant a free tech or 500-1k gold depending on how fare in the game I am, especially if spiritual.

There's already a check for "we don't want to deal with the unhappiness" which usually would prevent them from switching out of emancipation or something - something similar may exist for state property and $$$ - haven't tried.

DMOC
Jun 16, 2009, 02:59 PM
Just wondering ... has this been added to the unofficial patch?

jdog5000
Jun 16, 2009, 08:55 PM
I believe it was in prior versions, it's certainly been in BBAI for a while now. Thanks for checking though, I'll add it to the list of BBAI fixes appropriate for a patch.