Great tutorial! I'm trying to add some tags to Civ4ImprovementInfos so that improvements can require bonuses to construct, in the same way that railroads require coal. I got a little greedy, and wanted to make multiple bonuses possible, and multiple ways of checking their presence. I added my tags inside the BonusTypeStruct of CivTerrainInfos.xml, as follows:
Code:
<ElementType name="BonusType" content="textOnly"/>
<ElementType name="bBonusMakesValid" content="textOnly" dt:type="boolean"/>
<!--begin adds -->
<!-- The improvement requires that the bonus be available at the actual plot (ie must be on a trade route) -->
<ElementType name="bBonusRequiredAt" content="textOnly" dt:type="boolean"/>
<!-- The improvement requires the bonus be available at an adjacent plot (as for railroads/coal)-->
<ElementType name="bBonusRequiredAdjacent" content="textOnly" dt:type="boolean"/>
<!-- The improvement requires the bonus be available at the nearest city-->
<ElementType name="bBonusRequiredCity" content="textOnly" dt:type="boolean"/>
<!-- The improvement requires the bonus be available in the Capital -->
<ElementType name="bBonusRequiredCapital" content="textOnly" dt:type="boolean"/>
<!-- The improvement requires the resource be somewhere in the civilization -->
<ElementType name="bBonusRequiredAnywhere" content="textOnly" dt:type="boolean"/>
<!-- end adds -->
<ElementType name="bBonusTrade" content="textOnly" dt:type="boolean"/>
<ElementType name="iDiscoverRand" content="textOnly" dt:type="int"/>
<ElementType name="BonusTypeStruct" content="eltOnly">
<element type="BonusType"/>
<element type="bBonusMakesValid"/>
<!-- begin adds -->
<element type="bBonusRequiredAt"/>
<element type="bBonusRequiredAdjacent"/>
<element type="bBonusRequiredCity"/>
<element type="bBonusRequiredCapital"/>
<element type="bBonusRequiredAnywhere"/>
<!-- end adds -->
<element type="bBonusTrade"/>
<element type="iDiscoverRand"/>
<element type="YieldChanges" minOccurs="0" maxOccurs="*"/>
</ElementType>
I then added the new data to CivImprovementInfos.xml. this loaded okay, though after looking at the C++, I see that the data wasn't properly loaded without some changes.
I followed all the rest of the steps, with some changes to the XML read step, because the BonusTypeStruct is read differently (CvXMLLoadUtilitySet.cpp):
Code:
void CvXMLLoadUtility::SetImprovementBonuses(CvImprovementBonusInfo** ppImprovementBonus)
{
....
....
// initialize the boolean list to the correct size and all the booleans to false
InitImprovementBonusList(ppImprovementBonus, GC.getNumBonusInfos());
// set the local pointer to the memory we just allocated
paImprovementBonus = *ppImprovementBonus;
...
...
GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_bBonusMakesValid);
/* additions */
GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_bBonusRequiredAt);
GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_bBonusRequiredAdjacent);
GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_bBonusRequiredCity);
GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_bBonusRequiredCapital);
GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_bBonusRequiredAnywhere);
/* end additions*/
GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_bBonusTrade);
GetNextXmlVal(&paImprovementBonus[iBonusIndex].m_iDiscoverRand);
...
...
}
I also added some lines to initImprovementBonusList, to initialize the new members to false.
It still parses the XML fine, but the program is crashing sometime in the first few turns. I did add some implementation code, but it's all commented out now. I'm guessing that bad memory is being allocated somewhere, but in a codebase this big, I can't begin to figure out where. Any ideas?
Edit: Figured it out, I had null pointers cropping up in certain cases (trying to get the barbarian's capital, for instance).