Fimbulvetr
Emperor
Even at warning level 4 I get nothing when compiling this part of code I wrote, which simply tries to improve valuation of siege units for UNITAI_ATTACK_CITY, taking into account how many siege units the player already has and how big the rest of the offensive army is.. so what am I doing wrong here? It's crashing so often I have to assume it crashes always when a siege unit is already in an AI's army and it's thinking about building another one. (not really sure though)
CvPlayerAI.cpp (based on ideas from Better BTS AI)
edit: nvm, it suddenly works after a few changes that as far as I can see shouldn't really change anything. mysterious ..
CvPlayerAI.cpp (based on ideas from Better BTS AI)
Spoiler :
Code:
case UNITAI_ATTACK_CITY:
[COLOR="Green"]// Effect army composition to have more collateral/bombard units[/COLOR]
iFastMoverMultiplier = AI_isDoStrategy(AI_STRATEGY_FASTMOVERS) ? 4 : 1;
iTempValue = ((iCombatValue * iCombatValue) / 75) + (iCombatValue / 2);
iValue += iTempValue;
if (GC.getUnitInfo(eUnit).isNoDefensiveBonus())
{
iValue -= iTempValue / 2;
}
if (GC.getUnitInfo(eUnit).getDropRange() > 0)
{
iValue -= iTempValue / 2;
}
if (GC.getUnitInfo(eUnit).isFirstStrikeImmune())
{
iValue += (iTempValue * 8) / 100;
}
iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getCityAttackModifier()) / 75);
[COLOR="Green"]/* Collateral Damage valuation moved to bombard part
iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getCollateralDamage()) / 400);
*/[/COLOR]
iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getMoves() * iFastMoverMultiplier) / 4);
iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getWithdrawalProbability()) / 100);
[COLOR="Green"]/*
if (!AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ))
{
*/[/COLOR]
if (GC.getUnitInfo(eUnit).getBombardRate() > 0 || GC.getUnitInfo(eUnit).getCollateralDamageMaxUnits() > 0)
{
[COLOR="Green"] /* original code
int iBombardValue = GC.getUnitInfo(eUnit).getBombardRate() * 4;
*/[/COLOR]
int iBombardValue = GC.getUnitInfo(eUnit).getBombardRate() * (GC.getUnitInfo(eUnit).isIgnoreBuildingDefense() ? 3 : 2);
[COLOR="Green"]// Army composition needs to scale with army size, bombard unit potency[/COLOR]
[COLOR="Green"]//modified AI_calculateTotalBombard(DOMAIN_LAND) code[/COLOR]
int iI;
int iTotalBombard = 0;
int iSiegeUnits = 0;
int iSiegeImmune = 0;
int iTotalSiegeMaxUnits = 0;
for (iI = 0; iI < GC.getNumUnitClassInfos(); iI++)
{
UnitTypes eLoopUnit = ((UnitTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(iI)));
if (eLoopUnit != NO_UNIT)
{
if (GC.getUnitInfo(eLoopUnit).getDomainType() == DOMAIN_LAND)
{
int iBombardRate = GC.getUnitInfo(eLoopUnit).getBombardRate();
if (iBombardRate > 0)
{
iTotalBombard += (iBombardRate * getUnitClassCount((UnitClassTypes)iI) * (GC.getUnitInfo(eUnit).isIgnoreBuildingDefense() ? 3 : 2)) / 2;
}
int iBombRate = GC.getUnitInfo(eLoopUnit).getBombRate();
if (iBombRate > 0)
{
iTotalBombard += iBombRate * getUnitClassCount((UnitClassTypes)iI);
}
if (GC.getUnitInfo(eLoopUnit).getCollateralDamageMaxUnits() != 0 && GC.getUnitInfo(eLoopUnit).getCollateralDamage() != 0)
{
iTotalSiegeMaxUnits += GC.getUnitInfo(eLoopUnit).getCollateralDamageMaxUnits() * getUnitClassCount((UnitClassTypes)iI);
iSiegeUnits += getUnitClassCount((UnitClassTypes)iI);
}
else if (GC.getUnitInfo(eLoopUnit).getUnitCombatCollateralImmune(GC.getUnitInfo(eUnit).getUnitCombatType()))
{
iSiegeImmune+= getUnitClassCount((UnitClassTypes)iI);
}
}
}
}
int iNumOffensiveUnits = AI_totalUnitAIs(UNITAI_ATTACK_CITY) + AI_totalUnitAIs(UNITAI_ATTACK) + AI_totalUnitAIs(UNITAI_COUNTER)/2;
int iNumDefensiveUnits = AI_totalUnitAIs(UNITAI_CITY_DEFENSE) + AI_totalUnitAIs(UNITAI_RESERVE) + AI_totalUnitAIs(UNITAI_CITY_COUNTER)/2 + AI_totalUnitAIs(UNITAI_COLLATERAL)/2;
iSiegeUnits += (iSiegeImmune*iNumOffensiveUnits)/(iNumOffensiveUnits+iNumDefensiveUnits);
int iMAX_HIT_POINTS = GC.getDefineINT("MAX_HIT_POINTS");
int iCollateralDamageMaxUnitsWeight = (100 * (iNumOffensiveUnits - iSiegeUnits)) / std::max(1,iTotalSiegeMaxUnits);
iCollateralDamageMaxUnitsWeight = std::min(100, iCollateralDamageMaxUnitsWeight);
[COLOR="Green"]//to decrease value further for units with low damage limits:[/COLOR]
int iCollateralDamageLimitWeight = 100*iMAX_HIT_POINTS - std::max(0, ((iMAX_HIT_POINTS - GC.getUnitInfo(eUnit).getCollateralDamageLimit()) * (100 - iCollateralDamageMaxUnitsWeight)));
iCollateralDamageLimitWeight /= iMAX_HIT_POINTS;
int iCollateralValue = iCombatValue * GC.getUnitInfo(eUnit).getCollateralDamage() * GC.getDefineINT("COLLATERAL_COMBAT_DAMAGE");
iCollateralValue /= 100;
iCollateralValue *= std::max(100, (GC.getUnitInfo(eUnit).getCollateralDamageMaxUnits() * iCollateralDamageMaxUnitsWeight * iCollateralDamageMaxUnitsWeight) / 100);
iCollateralValue /= 100;
iCollateralValue *= iCollateralDamageLimitWeight;
iCollateralValue /= 100;
iCollateralValue /= iMAX_HIT_POINTS;
iValue += iCollateralValue;
[COLOR="Green"]//int iTotalBombardValue = 4 * iTotalBombard;[/COLOR]
int iNumBombardUnits = 2 * iTotalBombard / iBombardValue;
int iAIDesiredBombardFraction = std::max( 5, /*default: 10*/ GC.getDefineINT("BBAI_BOMBARD_ATTACK_STACK_FRACTION"));
int iActualBombardFraction = (100*iNumBombardUnits)/std::max(1, iNumOffensiveUnits);
int iTempBombardValue = 0;
if (iTotalBombard < 200) //still less than 200 bombard points
{
iTempBombardValue = iBombardValue * (500 - 2*iTotalBombard);
iTempBombardValue /= 100;
[COLOR="Green"]//iTempBombardValue is at most (5 * iBombardValue)[/COLOR]
}
if (iActualBombardFraction < iAIDesiredBombardFraction)
{
iBombardValue *= iAIDesiredBombardFraction + 3 * (iAIDesiredBombardFraction - iActualBombardFraction);
iBombardValue /= iAIDesiredBombardFraction;
[COLOR="Green"]//new iBombardValue is at most (4 * old iBombardValue)[/COLOR]
}
else
{
iBombardValue *= iAIDesiredBombardFraction;
iBombardValue /= range(iActualBombardFraction,1,99);
}
if (iTempBombardValue > iBombardValue)
{
iBombardValue = iTempBombardValue;
}
if (!AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ))
{
iValue += iBombardValue;
}
}
[COLOR="Green"]/*
}
*/[/COLOR]
break;
edit: nvm, it suddenly works after a few changes that as far as I can see shouldn't really change anything. mysterious ..
Spoiler :
Code:
case UNITAI_ATTACK_CITY:
[COLOR="Green"]// Effect army composition to have more collateral/bombard units[/COLOR]
iFastMoverMultiplier = AI_isDoStrategy(AI_STRATEGY_FASTMOVERS) ? 4 : 1;
iTempValue = ((iCombatValue * iCombatValue) / 75) + (iCombatValue / 2);
iValue += iTempValue;
if (GC.getUnitInfo(eUnit).isNoDefensiveBonus())
{
iValue -= iTempValue / 2;
}
if (GC.getUnitInfo(eUnit).getDropRange() > 0)
{
iValue -= iTempValue / 2;
}
if (GC.getUnitInfo(eUnit).isFirstStrikeImmune())
{
iValue += (iTempValue * 8) / 100;
}
iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getCityAttackModifier()) / 75);
[COLOR="Green"]/* Collateral Damage valuation moved to bombard part
iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getCollateralDamage()) / 400);
*/[/COLOR]
iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getMoves() * iFastMoverMultiplier) / 4);
iValue += ((iCombatValue * GC.getUnitInfo(eUnit).getWithdrawalProbability()) / 100);
[COLOR="Green"]/*
if (!AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ))
{
*/[/COLOR]
if (GC.getUnitInfo(eUnit).getBombardRate() > 0 || (GC.getUnitInfo(eUnit).getCollateralDamageMaxUnits() > 0 && GC.getUnitInfo(eUnit).getCollateralDamage() > 0))
{
[COLOR="Green"]// Army composition needs to scale with army size, bombard unit potency[/COLOR]
[COLOR="Green"]//modified AI_calculateTotalBombard(DOMAIN_LAND) code[/COLOR]
int iII;
int iTotalBombard = 0;
int iSiegeUnits = 0;
int iSiegeImmune = 0;
int iTotalSiegeMaxUnits = 0;
for (iII = 0; iII < GC.getNumUnitClassInfos(); iII++)
{
UnitTypes eLoopUnit = ((UnitTypes)(GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(iII)));
if (eLoopUnit != NO_UNIT)
{
if (GC.getUnitInfo(eLoopUnit).getDomainType() == DOMAIN_LAND)
{
int iClassCount = getUnitClassCount((UnitClassTypes)iII);
int iBombardRate = GC.getUnitInfo(eLoopUnit).getBombardRate();
if (iBombardRate > 0)
{
iTotalBombard += ((iBombardRate * iClassCount * ((GC.getUnitInfo(eLoopUnit).isIgnoreBuildingDefense()) ? 3 : 2)) / 2);
}
int iBombRate = GC.getUnitInfo(eLoopUnit).getBombRate();
if (iBombRate > 0)
{
iTotalBombard += iBombRate * iClassCount;
}
int iCollateralDamageMaxUnits = GC.getUnitInfo(eLoopUnit).getCollateralDamageMaxUnits();
if (iCollateralDamageMaxUnits > 0 && GC.getUnitInfo(eLoopUnit).getCollateralDamage() > 0)
{
iTotalSiegeMaxUnits += iCollateralDamageMaxUnits * iClassCount;
iSiegeUnits += iClassCount;
}
else if (GC.getUnitInfo(eLoopUnit).getUnitCombatCollateralImmune((UnitCombatTypes)GC.getUnitInfo(eUnit).getUnitCombatType()))
{
iSiegeImmune+= iClassCount;
}
}
}
}
int iNumOffensiveUnits = AI_totalUnitAIs(UNITAI_ATTACK_CITY) + AI_totalUnitAIs(UNITAI_ATTACK) + AI_totalUnitAIs(UNITAI_COUNTER)/2;
int iNumDefensiveUnits = AI_totalUnitAIs(UNITAI_CITY_DEFENSE) + AI_totalUnitAIs(UNITAI_RESERVE) + AI_totalUnitAIs(UNITAI_CITY_COUNTER)/2 + AI_totalUnitAIs(UNITAI_COLLATERAL)/2;
iSiegeUnits += (iSiegeImmune*iNumOffensiveUnits)/(iNumOffensiveUnits+iNumDefensiveUnits);
int iMAX_HIT_POINTS = GC.getDefineINT("MAX_HIT_POINTS");
int iCollateralDamageMaxUnitsWeight = (100 * (iNumOffensiveUnits - iSiegeUnits)) / std::max(1,iTotalSiegeMaxUnits);
iCollateralDamageMaxUnitsWeight = std::min(100, iCollateralDamageMaxUnitsWeight);
[COLOR="Green"]//to decrease value further for units with low damage limits:[/COLOR]
int iCollateralDamageLimitWeight = 100*iMAX_HIT_POINTS - std::max(0, ((iMAX_HIT_POINTS - GC.getUnitInfo(eUnit).getCollateralDamageLimit()) * (100 - iCollateralDamageMaxUnitsWeight)));
iCollateralDamageLimitWeight /= iMAX_HIT_POINTS;
int iCollateralValue = iCombatValue * GC.getUnitInfo(eUnit).getCollateralDamage() * GC.getDefineINT("COLLATERAL_COMBAT_DAMAGE");
iCollateralValue /= 100;
iCollateralValue *= std::max(100, ((GC.getUnitInfo(eUnit).getCollateralDamageMaxUnits() * iCollateralDamageMaxUnitsWeight * iCollateralDamageMaxUnitsWeight) / 100));
iCollateralValue /= 100;
iCollateralValue *= iCollateralDamageLimitWeight;
iCollateralValue /= 100;
iCollateralValue /= iMAX_HIT_POINTS;
iValue += iCollateralValue;
if (!AI_isDoStrategy(AI_STRATEGY_AIR_BLITZ) && GC.getUnitInfo(eUnit).getBombardRate() > 0)
{
[COLOR="Green"] /* original code
int iBombardValue = GC.getUnitInfo(eUnit).getBombardRate() * 4;
*/[/COLOR]
int iBombardValue = GC.getUnitInfo(eUnit).getBombardRate() * ((GC.getUnitInfo(eUnit).isIgnoreBuildingDefense()) ? 3 : 2);
[COLOR="Green"]//int iTotalBombardValue = 4 * iTotalBombard;[/COLOR]
[COLOR="Green"]//int iNumBombardUnits = 2 * iTotalBombard / iBombardValue;[/COLOR]
int iAIDesiredBombardFraction = std::max( 5, GC.getDefineINT("BBAI_BOMBARD_ATTACK_STACK_FRACTION")); /*default: 10*/
int iActualBombardFraction = (100 * 2 * iTotalBombard)/(iBombardValue * std::max(1, iNumOffensiveUnits));
iActualBombardFraction = std::min(100, iActualBombardFraction);
int iTempBombardValue = 0;
if (iTotalBombard < 200) //still less than 200 bombard points
{
iTempBombardValue = (iBombardValue * (700 - 3*iTotalBombard));
iTempBombardValue /= 100;
[COLOR="Green"]//iTempBombardValue is at most (7 * iBombardValue)[/COLOR]
}
if (iActualBombardFraction < iAIDesiredBombardFraction)
{
iBombardValue *= (iAIDesiredBombardFraction + 4 * (iAIDesiredBombardFraction - iActualBombardFraction));
iBombardValue /= iAIDesiredBombardFraction;
[COLOR="Green"]//new iBombardValue is at most (5 * old iBombardValue)[/COLOR]
}
else
{
iBombardValue *= iAIDesiredBombardFraction;
iBombardValue /= std::max(1, iActualBombardFraction);
}
if (iTempBombardValue > iBombardValue)
{
iBombardValue = iTempBombardValue;
}
iValue += iBombardValue;
}
}
[COLOR="Green"]/*
}
*/[/COLOR]
break;