Maniac
Apolyton Sage
I recently had a look at the CvPlayerAI::AI_doEnemyUnitData() function, which led me to spot room for some improvements, and more importantly led me to spot the values it creates don't have any effect on AI behaviour. It's supposed to be used to build useful unitai_counter/reserve/paradrop units, but as point 3 shows, this doesn't work.
1) First small thing I noticed is line 20261 "else if (pLoopUnit->getOwnerINLINE() != getID())". Wouldn't it be better to change that to "else if (pLoopUnit->getTeam() != getTeam())"? Not much point in calculating the best counter unit for your allies' military.
2) At the end of the function there's this code:
If a rival player has at least one unit of a certain unitcombattype, the value for m_aiUnitCombatWeights will already be over 25. And most/all the time the values for m_aiUnitCombatWeights will be in the hundreds if not thousands. So in effect this code simply adds 2500 to all unitcombatweights. Is this intended??
3) m_aiUnitCombatWeights and m_aiUnitClassWeights are used for the following functions:
Note the values are divided by 100!
These values are used in CvPlayerAI::AI_unitValue(...).
Consider the following snipper of code:
Or more specifically this as an example:
iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getUnitCombatModifier(iI) * AI_getUnitCombatWeight((UnitCombatTypes)iI)) / 10000);
Assume GC.getUnitInfo(eUnit).getUnitCombatModifier(iI) is 100 and AI_getUnitCombatWeight((UnitCombatTypes)iI) is 250. That still only results in an insignificant 25000 / 10000 = 2. I'm assuming the code writer forgot that the m_aiUnitCombatWeights value gets divided by 100 already, and as a consequence that in the example line of code the divisor should only be 100.
1) First small thing I noticed is line 20261 "else if (pLoopUnit->getOwnerINLINE() != getID())". Wouldn't it be better to change that to "else if (pLoopUnit->getTeam() != getTeam())"? Not much point in calculating the best counter unit for your allies' military.
2) At the end of the function there's this code:
Code:
for (iI = 0; iI < GC.getNumUnitCombatInfos(); iI++)
{
if (m_aiUnitCombatWeights[iI] > 25)
{
m_aiUnitCombatWeights[iI] += 2500;
}
else if (m_aiUnitCombatWeights[iI] > 0)
{
m_aiUnitCombatWeights[iI] += 1000;
}
}
If a rival player has at least one unit of a certain unitcombattype, the value for m_aiUnitCombatWeights will already be over 25. And most/all the time the values for m_aiUnitCombatWeights will be in the hundreds if not thousands. So in effect this code simply adds 2500 to all unitcombatweights. Is this intended??
3) m_aiUnitCombatWeights and m_aiUnitClassWeights are used for the following functions:
Code:
int CvPlayerAI::AI_getUnitClassWeight(UnitClassTypes eUnitClass) const
{
return m_aiUnitClassWeights[eUnitClass] / 100;
}
int CvPlayerAI::AI_getUnitCombatWeight(UnitCombatTypes eUnitCombat) const
{
return m_aiUnitCombatWeights[eUnitCombat] / 100;
}
Note the values are divided by 100!
These values are used in CvPlayerAI::AI_unitValue(...).
Consider the following snipper of code:
Code:
case UNITAI_COUNTER:
iValue += (iCombatValue / 2);
for (iI = 0; iI < GC.getNumUnitClassInfos(); iI++)
{
iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getUnitClassAttackModifier(iI) * AI_getUnitClassWeight((UnitClassTypes)iI)) / 7500);
iValue += ((iCombatValue * (GC.getUnitInfo(eUnit).getTargetUnitClass(iI) ? 50 : 0)) / 100);
}
for (iI = 0; iI < GC.getNumUnitCombatInfos(); iI++)
{
// int iCombatModifier = GC.getUnitInfo(eUnit).getUnitCombatModifier(iI);
// iCombatModifier = (iCombatModifier < 40) ? iCombatModifier : (40 + (iCombatModifier - 40) / 2);
// iValue += ((iCombatValue * iCombatModifier) / 100);
iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getUnitCombatModifier(iI) * AI_getUnitCombatWeight((UnitCombatTypes)iI)) / 10000);
iValue += ((iCombatValue * (GC.getUnitInfo(eUnit).getTargetUnitCombat(iI) ? 50 : 0)) / 100);
}
Or more specifically this as an example:
iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getUnitCombatModifier(iI) * AI_getUnitCombatWeight((UnitCombatTypes)iI)) / 10000);
Assume GC.getUnitInfo(eUnit).getUnitCombatModifier(iI) is 100 and AI_getUnitCombatWeight((UnitCombatTypes)iI) is 250. That still only results in an insignificant 25000 / 10000 = 2. I'm assuming the code writer forgot that the m_aiUnitCombatWeights value gets divided by 100 already, and as a consequence that in the example line of code the divisor should only be 100.