General about withdrawal:
Withdrawal due to promotions works on offense and on defense - ok but differs from BTS AFAIK.
Withdrawal from iWithdrawlProbDefensive works only on defense - as intended obviously.
Withdrawal from <iWithdrawalProb>20</iWithdrawalProb> only works on offense.
Is this intentional? At least the displayed stats are misleading: The unit help does not distinct between iWithdrawalProb and withdrawal from promotions.
It just adds the 2 values and displays them. Which made sense in BTS (no defensive withdrawal based on looking into the respective cpp) but not in FFH2.
Example: Privateer with 3 promos has 70% withdraw on offense and 50% on defense. The help simply says 70%. I never even knew there was a difference before looking at this stuff in detail.
--
There is supposed to be a cap at 90%. The method to ensure the cap is questionable and does only work partially:
Code:
if (promotionInfo.getWithdrawalChange() > 0)
{
if (promotionInfo.getWithdrawalChange() + m_pUnitInfo->getWithdrawalProbability() + getExtraWithdrawal() > GC.getDefineINT("MAX_WITHDRAWAL_PROBABILITY"))
{
return false;
}
}
Means to breach the cap:
a) Cast "fair winds" spell.
b) Mutation and getting 'Light' promotion.
c) Probably upgrading a unit (not tested).
d) The 10% from 'Advanced Tactics' are not considered (not tested).
There are weird problems due to the questionable method:
a) Have to wait for 'fair winds' to turn off before picking withdrawal promotion.
b) Can mutate/upgrade after picking withdrawal promotion but not before.
c) It can also be advantageous to have less withdrawal (as having more may make it impossible to pick the next withdrawal promotion).
d) The method only considers offensive withdrawal but the promotions function for defensive withdrawal also. Which means defensive withdrawal is unfairly restricted due to having offensive withdrawal.
Any reason for not changing the code so that the maximum is actually ensured and all the weirdness due to the questionable code goes away?
Like - in combination with removing the questionable code: (not tested, cannot compile DLL)
Code:
int CvUnit::withdrawalProbability() const
{
if (getDomainType() == DOMAIN_LAND && plot()->isWater())
{
return 0;
}
//FfH: Added by Kael 04/06/2009
if (getImmobileTimer() > 0)
{
return 0;
}
//FfH: End Add
// Advanced Tactics - all units have an inherent 10% withdrawal chance
int iWithDrawalBonus = 0;
if (GC.getGameINLINE().isOption(GAMEOPTION_ADVANCED_TACTICS))
{
if ((getDuration() == 0) && !m_pUnitInfo->isObject())
{
iWithDrawalBonus += 10;
}
}
[B] const int prior_code_withdraw = std::max(0, (m_pUnitInfo->getWithdrawalProbability() + getExtraWithdrawal() + iWithDrawalBonus));
// possibly too slow to read this here like that - may have to 'cache' the constant somewhere
// or simply use static but I do not know if that is acceptable/workable in civ 4 code
const int max_withdraw = GC.getDefineINT("MAX_WITHDRAWAL_PROBABILITY"));
return std::min(max_withdraw, prior_code_withdraw);[/B]
}
And maybe also getWithdrawlProbDefensive() but AFAIK only Loki can and does (intentionally) exceed the cap and I do not know if the current behaviour (see question above) is intended.