UnitCombatFreeExperience(UnitCombatTypes

Chazcon

Prince
Joined
Feb 16, 2006
Messages
476
Location
Left Coast
This bit is causing me some grief, I throw the first assert with an eIndex of -1 which means the unit has no UNITCOMBAT type. This will throw in both release and debug.

I have modified the unitcombat types and made changes to CIV4EventInfos.xml, CIV4PromotionInfos.xml, CIV4UnitCombatInfos.xml, and CIV4UnitIfos.xml. Also verified that all UNITCOMBAT_ types in CIV4BuildingInfos.xml are correct.

I also listed all unitcombat types in PyHelpers.py and CvAdvisorUtils.py for kicks.

All units have a correct <Combat>UNITCOMBAT_*</Combat> type or <Combat>NONE</Combat>.

Code:
int CvCity::getUnitCombatFreeExperience(UnitCombatTypes eIndex) const
{
	FAssertMsg(eIndex >= 0, "eIndex expected to be >= 0");
	FAssertMsg(eIndex < GC.getNumUnitCombatInfos(), "eIndex expected to be < GC.getNumUnitCombatInfos()");
	return m_paiUnitCombatFreeExperience[eIndex];
}
 
Could do with some context around this. Most places where this function is called are wrapped with either a for loop through the CombatInfos or an explicit check for NO_UNITCOMBAT.

When is this happening? Is it in the city screen, at the end of a turn when you have finished training a unit? What is the call stack when you are debugging it?
 
Away from comp right now, but this is happening when an AI unit is trained, it's doing a free experience check from a building as far as I can tell.

UnitCombatTypes are enumerated or 'loaded' at startup from CIV4UnitCombatInfos.xml correct? And then in a function such as this the individual unit UnitCombatType is checked against that list for a match. If the unit has a <Combat> flag of NONE it would enumerate to UnitCombatType = -1 correct? But some unit DO have 'no' UnitCombatType such as Settlers, Workers, Executives and Missionaries. So why would it assert on one of those units?

Been out of town, will provide more info when get in front of my home comp with a cup of joe this weekend... modern life...
 
Either don't call the function if the unit has no unit combat, or add a check at the start of the function and immediately return 0 if the value passed was -1 (instead of doing the assert).

Not doing the "return m_paiUnitCombatFreeExperience[eIndex];" when eIndex is -1 is very important since an index of -1 is not valid, but it will do it anyway and either return whatever junk is present in memory at the address one int size immediately before the start of the array (which could be anything) or it will crash (due to it being invalid or unreadable).
 
SOLVED: Typo in code, in Python, I changed the UnitCombatTypes for my mod and I had missed changing '_Gunpowder" to "_Gun" in one reference...

Relevant files were CvAdvisorUtils.py and PyHelpers.py.
 
Top Bottom