Closed RecursiveStar closed 4 years ago
nah, didn't touch this. also it seems like the "three negatives" conditions is extremely unlikely to trigger ...
I planted a city right next to Denmark's capital and gave them four units against my zero, and I denounced them, yet they had no war or hostile weight at all.
Denmark had 10 WAR and 10 HOSTILE bias, so this doesn't make sense.
Assuming the logging is working correctly (and I didn't touch it, so it should be), the only potential other culprits are:
////////////////////////////////////
// PEACE TREATY - have we made peace with this player recently? If so, reduce war weight
////////////////////////////////////
if (GetNumWarsFought(ePlayer) > 0)
{
int iPeaceTreatyTurn = GET_TEAM(GetTeam()).GetTurnMadePeaceTreatyWithTeam(eTeam);
if (iPeaceTreatyTurn > -1)
{
int iTurnsSincePeace = GC.getGame().getElapsedGameTurns() - iPeaceTreatyTurn;
int iPeaceDampenerTurns = 20;
if (MOD_BALANCE_CORE_DIFFICULTY)
{
int iPeaceDifficultyMod = GC.getGame().getHandicapInfo().getAIDifficultyBonusBase();
iPeaceDampenerTurns -= iPeaceDifficultyMod;
if (iPeaceDampenerTurns < 11)
iPeaceDampenerTurns = 11;
}
if (iTurnsSincePeace < iPeaceDampenerTurns)
{
viApproachWeights[MAJOR_CIV_APPROACH_WAR] = 0;
viApproachWeights[MAJOR_CIV_APPROACH_HOSTILE] = 0;
}
}
}
This function, which I modified recently to decrease the dampener between peace treaties on higher difficulties. But we hadn't previously been at war anyway.
// We like our vassals (unless they're blocking our path to victory)
else if (GET_TEAM(GET_PLAYER(ePlayer).getTeam()).GetMaster() == GetTeam())
{
if (GET_PLAYER(ePlayer).GetCapitalConqueror() != NO_PLAYER && GET_PLAYER(ePlayer).GetNumCapitalCities() <= 0 && !IsMajorCompetitor(ePlayer))
{
viApproachWeights[MAJOR_CIV_APPROACH_WAR] = 0;
viApproachWeights[MAJOR_CIV_APPROACH_HOSTILE] = 0;
}
}
The AI thinking everyone is their vassal, which is an unlikely explanation.
////////////////////////////////////
// Made a military promise?
////////////////////////////////////
// Don't declare war if we promised that our troops weren't on their borders for war
if (GET_PLAYER(ePlayer).GetDiplomacyAI()->IsPlayerMadeMilitaryPromise(GetPlayer()->GetID()))
{
viApproachWeights[MAJOR_CIV_APPROACH_WAR] = 0;
viApproachWeights[MAJOR_CIV_APPROACH_HOSTILE] = 0;
}
// If we agreed to remove our troops from their borders, destroy weight for war
if (IsPlayerMoveTroopsRequestAccepted(ePlayer))
{
viApproachWeights[MAJOR_CIV_APPROACH_WAR] = 0;
viApproachWeights[MAJOR_CIV_APPROACH_HOSTILE] = 0;
}
It can't be a military promise/move troops request, because neither of us asked for a military promise.
////////////////////////////////////
// On the same team?
////////////////////////////////////
if (GetTeam() == GET_PLAYER(ePlayer).getTeam())
{
viApproachWeights[MAJOR_CIV_APPROACH_WAR] = 0;
viApproachWeights[MAJOR_CIV_APPROACH_HOSTILE] = 0;
viApproachWeights[MAJOR_CIV_APPROACH_DECEPTIVE] = 0;
viApproachWeights[MAJOR_CIV_APPROACH_GUARDED] = 0;
viApproachWeights[MAJOR_CIV_APPROACH_AFRAID] = 0;
viApproachWeights[MAJOR_CIV_APPROACH_NEUTRAL] = 0;
viApproachWeights[MAJOR_CIV_APPROACH_FRIENDLY] = 100;
}
Or the AI somehow thinks we're on the same team.
I'll reinstall and see if that fixes it.
Okay, so I started a game with just Montezuma and Harald Bluetooth, two of the most aggressive AIs, put them right next to each other on Deity difficulty, gave them full visibility of the entire map with IGE, gave them three extra Settlers each and on turn 18, used IGE to make them denounce each other.
Turn 0:
Turn 50 (neither of them has declared war yet):
Mucho no comprehendo. Logs show the WAR and HOSTILE approaches being zeroed out.
They also have FRIENDLY and DECEPTIVE weight, which shouldn't be happening after denouncing each other. Diplo AI Logs.zip
Relevant code is in CvDiplomacyAI::GetBestApproachTowardsMajorCiv...
@ilteroi Also take a look at the questionable AI defensive strategy for Texcoco. :)
i'll take a look in the debugger ... what's wrong with texcoco?
Thanks! And as for Texcoco: I mean, I get that Montezuma's UU is the Jaguar, but wouldn't some ships or ranged units be more effective? He has no ranged units at all. :)
re: spearmen ... production choices are G's domain. you can take a look in CityProductionAI log to see what is going on. maybe they built so many melee units before they even got archery? but i agree it's weird.
ok it seems your first guess was right ... the problem is that HaveCachedAttackTarget() only looks in the cache and doesn't update it. the correct call is FindBestAttackTargetCached()
@ilteroi In the deal AI for third party war there's this code:
bool bTargetLand = GetPlayer()->GetMilitaryAI()->HaveCachedAttackTarget(eWithPlayer, AI_OPERATION_CITY_SNEAK_ATTACK);
bool bTargetSeaPure = GetPlayer()->GetMilitaryAI()->HaveCachedAttackTarget(eWithPlayer, AI_OPERATION_NAVAL_ONLY_CITY_ATTACK);
bool bTargetSea = GetPlayer()->GetMilitaryAI()->HaveCachedAttackTarget(eWithPlayer, AI_OPERATION_NAVAL_INVASION_SNEAKY);
if(!bTargetLand && !bTargetSeaPure && !bTargetSea)
{
CvMilitaryTarget target = GetPlayer()->GetMilitaryAI()->FindBestAttackTargetCached(AI_OPERATION_CITY_SNEAK_ATTACK, eWithPlayer);
if(target.m_pTargetCity != NULL && target.m_pMusterCity != NULL)
{
if(!target.m_bAttackBySea)
{
bTargetLand = true;
}
else
{
bTargetSea = true;
}
}
}
//No target? Abort!
if(!bTargetLand && !bTargetSeaPure && !bTargetSea)
{
return INT_MAX;
}
So I assume the solution is to check for either an updated attack target outright, or to do so if there is no cached target?
thinking about it ... i'm not happy with the way HaveCachedAttackTarget() is being used in general.
there's a performance aspect, but also the split by operation type is awkward ... in the medium term we should improve it.
in the short term i would simply remove that check in GetBestApproachTowardsMajorCiv
Sounds good...well, I'll leave the military targeting to you and fix the short term issue in a pull request. :)
It appears this is actually a longstanding bug making the AI much less aggressive, and it only became evident because I moved the check to a later position in GetBestApproachTowardsMajorCiv.
Would you be able to recompile the DLL again?
i'll release a fixed version soon, don't touch anything in the meantime :)
Sounds good (x2)...I have another pull request to fix a separate issue causing the AI to make an excessive amount of friends (was checking for grand strategy in Ancient Era); mind merging that as well? :)
ok so i simplified those target checks, turns out there were some inadvertent fallthroughs in switch statements as well, should be better now
Thank you! Looking forward to the rebuilt DLL :)
@ilteroi (Also, this was a longstanding bug, can you add the "SLAIN LIKE THE HYDRA" label?)
Hehe, thanks a lot! :)
Last thing: could you push the updated code here? I intend to make further changes once I get community feedback.
Edit: Much appreciated. 😄
1. Mod version (i.e Date - 4/23): Latest (with my hotfix and ilteroi's bugfixes)
2. Mod list (if using Vox Populi only, leave blank): Archaeology Aesthetic Adjustments Calypso's Colored Religious Icons Faster Aircraft Animations Ingame Editor Quick Turns
3. Error description: I played through a game for about 30 turns, trying to deliberately provoke the AI into declaring war early game, yet it wasn't. I looked at the approach logs and I noticed that the WAR and HOSTILE approaches were being set to 0 for every civ with every other civ, which would explain recent AI passivity.
After looking through GetBestApproachTowardsMajorCiv to find the culprit, my suspicion is this:
@ilteroi Did you change anything about attack targets that would impact this?
I'm going to reinstall to see if it's just some kind of installation error.