Page 1 of 1
AI Constants questions
Posted: Mon Mar 24, 2008 9:09 pm
by wwhitman
Hi all. I've been actively modding the game since I got it, and I think giving us players the ability to mod through text files is one of the best decisions the designers made. I have logged dozens of tweaks to unit and building costs, terrain def and move values, gun power and range, weapon availability, camp reinforcement rates, etc., and to see those changes affect the game is a thrill. I've re-started my first campaign three separate times (so far...) because I wanted to go back and re-play the early turns with different rules in place.
But, I've hit a roadblock. Playing as the Confederate States, I can't figure out how to make the Union AI stop attacking me when his troops are outnumbered or suffering from low disposition. I'm betting this is something I can influence using the following three values in the ACWConstants.txt file:
AI Ideal Odds
AI Refuse Odds
AI Reluctance Scale
....but I don't know which way to move the numbers, how sensitive they are, and what else might (unintentionally) be thrown out of whack. I'm not asking for any state secrets, I just want to keep Rosecrans from leading 20,000 troops against 30,000 troops that just whipped him the prior turn. Is there a level to set these numbers that will cause the AI to wait a few turns and build up before seeking battle?
RE: AI Constants questions
Posted: Thu Apr 17, 2008 9:14 am
by Conny D
Strange theres no response here since other questions are picked up instantly. I also think the ai should in some way be forbidden to lead single divisions against whole armies, what it does at times.
RE: AI Constants questions
Posted: Thu Apr 17, 2008 2:20 pm
by ericbabe
The AI is forbidden from moving divisions into provinces with ungarrisoned enemy units, but it does break this rule from time to time for reasons that aren't easy to explain pertaining to the way the AI engine is structured. I have considered making the rule that uncontainered brigades simple fail to move into any province containing ungarrisoned enemy units.
Here's the core of the target-evaluation routine that explains the use of these parameters. This is only called for certain military groups, not lone divisions. The "power" of a group is determined by most all the relevant factors, including disposition, weapon, etc.
int TAI::a3_Get_Value_Of_Target_To_Piece(TAITarget *pT, GAMEPIECE pPiece)
{
if (pPiece->GetPlayerId()!=AIPlayer ||
pPiece->GetContainer() ||
!pPiece->IsMilitary())
return 0;
int value = 0;
float attackPower = (float) a4_Calc_Piece_Power(pPiece)+(3*pT->maxPowerCanDeploy/4);
if (AIPlayer==CSA) // V1.9.10 csa more cautious on the attack
attackPower = (float) a4_Calc_Piece_Power(pPiece)+(pT->maxPowerCanDeploy/5);
float defendPower = (float) pT->enemyPower-(pT->powerDeployed);
float idealOdds = (float) AI_IdealOddsx100/100.0f; //1.6f;
float refuseOdds = (float) AI_RefuseOddsx100/100.0f; //.7f;
int distance = a4_Can_Piece_Reach_Target(pPiece, pT->hProv);
if (distance==0)
return 0;
// MAKE SURE TARGET IS IN THE SAME THEATER AS THIS PIECE
TProvince* pPieceProv = PTGame->Prov(pPiece->GetProvince());
TProvince* pTargProv = PTGame->Prov(pT->hProv);
if (pTargProv->AIReluctance[AIPlayer])
{
defendPower *= (1.0f + (float) pTargProv->AIReluctance[AIPlayer]*AI_ReluctanceScalex100/100.0f);
}
// DON'T ENTER THEATER -1 PROVINCES WITH BIG FORCES
if (pPieceProv && pTargProv &&
pTargProv->Theater==-1 &&
attackPower>10000)
{
return 0;
}
// CSA player doesn't like to invade
if (pPiece->GetPlayerId()==CSA)
{
if (pTargProv->hVeryOriginalNation!=CSA && bCSADontInvadeThisTurn)
return 0;
}
// USA player doesn't want to invade V1.10.6
if (pPiece->GetPlayerId()==USA)
{
if (pTargProv->hVeryOriginalNation!=USA && bUSADontInvadeThisTurn)
return 0;
}
// WON'T INVADE IF NOT ADJACENT
if (!PTGame->Info_CalcIsProvinceAdjacentToPlayer(pT->hProv, pPiece->GetPlayerId()))
return 0;
// check power of defender
if (defendPower)
{
float attackRatio = attackPower / defendPower;
if (attackRatio > 2.0f*idealOdds) // V1.9.1 don't value overkill
{
value = pT->value/2; // V1.9.8
}
else if (attackRatio > idealOdds)
{
value = (int) (idealOdds*pT->value);
}
else if (attackRatio < refuseOdds)
{
value = 0;
}
else
{
value = (int) (attackRatio*pT->value);
}
}
else
value = pT->value;
// value of targets in home terr worth more
if (PTGame->PTProvMap->location(pT->hProv)->GetPlayerId()==AIPlayer)
value *= 2;
// value of mississippi river
switch(pT->hProv)
{
case 235:
case 201:
case 199:
case 204:
case 206:
case 207:
case 208:
case 209:
value *= 3;
break;
}
// V1.9.1 theaters now scale value
if (pPieceProv && pTargProv &&
pTargProv->Theater>0 &&
pPieceProv->Theater>0 &&
pPieceProv->Theater!=pTargProv->Theater)
{
value = value*AI_OutOfTheaterMultiplierOnValuex100;
value /= 100;
if (distance>4) // V1.9.11
value = 0;
}
// V1.9.5 AI lock some milgroups to particular theaters
if (strcmp(pPiece->GetName(), "Army_Potomac_Left")==0 ||
strcmp(pPiece->GetName(), "Army_Potomac_Center")==0 ||
strcmp(pPiece->GetName(), "Army_Potomac_Right")==0 ||
strcmp(pPiece->GetName(), "Dept._N._Virginia")==0 ||
strcmp(pPiece->GetName(), "Dist._of_the_Potomac")==0 ||
strcmp(pPiece->GetName(), "Valley_District")==0 ||
strcmp(pPiece->GetName(), "Dept_of_NE_Virginia")==0 ||
strcmp(pPiece->GetName(), "Army_of_the_Potomac")==0 ||
strcmp(pPiece->GetName(), "Army_of_the_Peninsula")==0 ||
strcmp(pPiece->GetName(), "Aquia_District")==0)
{
if (pTargProv->Theater!=5)
value = 0;
}
// V1.9.1 does destination have enemy siegeworks?
GAMEPIECE pEnemySiege = PTGame->Info_FindEnemy_UnitType_Here(pT->hProv, AIPlayer, TMasterPiece::siegeworks);
if (pEnemySiege)
{
value *= AI_EnemySiegex100;
value /= 100;
}
// value decreases by distance
switch(distance)
{
case 1: value *= AI_ValueDistance0; break;
case 2: value *= AI_ValueDistance1; break;
case 3: value *= AI_ValueDistance2; break;
case 4: value *= AI_ValueDistance3; break;
case 5: value *= AI_ValueDistance4; break;
case 6: value *= AI_ValueDistance5; break;
case 7: value *= AI_ValueDistance6; break;
case 8: value *= AI_ValueDistance7; break;
case 9: value *= AI_ValueDistance8; break;
case 10: value *= AI_ValueDistance9; break;
default: value *= AI_ValueDistanceGr9; break;
}
return value;
}
RE: AI Constants questions
Posted: Fri May 02, 2008 12:43 pm
by morganbj
Gee, that might have been a little more than you wanted ...