In the spirit of the similar thread with Python code samples, here's a thread to post examples of C++ code for others to learn from/use. It will work best if everybody can refrain from posting broken code or requests in this thread.
(Although the python thread is over here, I thought this board was a better location, hopefully the moderators agree)
Anyway, I'll start it off with a relatively easy example:
In CvPlot.cpp, a replacement for the CvPlot::doImprovement() method:
What it does:
The biggest change is the this code limits resource discovery to terrain types allowed for that bonus. In other words, if Iron is set to only appear on deserts you will never discover iron in a mine that you build on a grassland hill. The second change is that it allows the discovery of health resources (if enabled in the XML) but limits them so that you can only discover a resource that you already have access to, including from trades. Neither change will alter the way the XML data is handled or allow players to discover a resource that isn't allowed in your XML files.
If you look in CIV4ImprovementInfos.xml at the mine improvement you will see several lines like:
The iDiscoverRand value tells the game that a mine with no bonus has a chance (1 in iDiscoverRand) of discovering this bonus resource. The allowable terrain types are defined in CIV4BonusInfos.xml and used for resource placement during map generation.
Use:
In my mod I use this code to allow corn & wheat to spread to other farms in your civ, but only if you already have it. The only XML change required was altering the iDiscoverRand value for corn and wheat in the farm. It can easily be adapted (with no code changes) to do the same with animals provided you allow pastures to be built on a tile that doesn't already have the animal bonus.
(Although the python thread is over here, I thought this board was a better location, hopefully the moderators agree)
Anyway, I'll start it off with a relatively easy example:
In CvPlot.cpp, a replacement for the CvPlot::doImprovement() method:
Code:
void CvPlot::doImprovement()
{
PROFILE_FUNC();
CvCity* pCity;
CvWString szBuffer;
int iI;
FAssert(isBeingWorked() && isOwned());
if (getImprovementType() != NO_IMPROVEMENT)
{
if (getBonusType() == NO_BONUS)
{
FAssertMsg((0 < GC.getNumBonusInfos()), "GC.getNumBonusInfos() is not greater than zero but an array is being allocated in CvPlot::doImprovement");
for (iI = 0; iI < GC.getNumBonusInfos(); ++iI)
{
// ----- World Piece Begin -----
/*Seven05: Here we're going to make a slight change to the chance of discovering bonuses on
improved plots. What we want is to limit food resources so they will only appear if the civ
already has that resource. And 'fix' it so resources can only be discovered on the appropriate
terrain.*/
if (GET_TEAM(getTeam()).isHasTech((TechTypes)(GC.getBonusInfo((BonusTypes) iI).getTechReveal())) &&
GC.getBonusInfo((BonusTypes) iI).isTerrain((unsigned int) getTerrainType()))
{ // If this bonus type is allowed on this terrain and we have the tech needed
if (GC.getImprovementInfo(getImprovementType()).getImprovementBonusDiscoverRand(iI) > 0)
{ // If this bonus can be 'discovered'
if (GC.getGameINLINE().getSorenRandNum(GC.getImprovementInfo(getImprovementType()).getImprovementBonusDiscoverRand(iI), "Bonus Discovery") == 0)
{
if(GC.getBonusInfo((BonusTypes) iI).getHealth() > 0)
{ // This next check should only happen with food resources
if(GET_PLAYER(getOwner()).hasBonus((BonusTypes) iI))
{ // If we have this one already
setBonusType((BonusTypes) iI);
}
else
{ // We don't have this one yet, bail out
break;
}
}
else
{ // Non-health bonuses can be discovered without having one already
setBonusType((BonusTypes)iI);
}
// ----- World Piece End -----
pCity = GC.getMapINLINE().findCity(getX_INLINE(), getY_INLINE(), getOwnerINLINE(), NO_TEAM, false);
if (pCity != NULL)
{
szBuffer = gDLL->getText("TXT_KEY_MISC_DISCOVERED_NEW_RESOURCE", GC.getBonusInfo((BonusTypes) iI).getTextKeyWide(), pCity->getNameKey());
gDLL->getInterfaceIFace()->addMessage(getOwnerINLINE(), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_DISCOVERBONUS", MESSAGE_TYPE_MINOR_EVENT, GC.getBonusInfo((BonusTypes) iI).getButton(), (ColorTypes)GC.getInfoTypeForString("COLOR_WHITE"), getX_INLINE(), getY_INLINE(), true, true);
}
break;
}
}
}
}
}
}
doImprovementUpgrade();
}
What it does:
The biggest change is the this code limits resource discovery to terrain types allowed for that bonus. In other words, if Iron is set to only appear on deserts you will never discover iron in a mine that you build on a grassland hill. The second change is that it allows the discovery of health resources (if enabled in the XML) but limits them so that you can only discover a resource that you already have access to, including from trades. Neither change will alter the way the XML data is handled or allow players to discover a resource that isn't allowed in your XML files.
If you look in CIV4ImprovementInfos.xml at the mine improvement you will see several lines like:
Code:
<BonusTypeStruct>
<BonusType>BONUS_ALUMINUM</BonusType>
<bBonusMakesValid>1</bBonusMakesValid>
<bBonusTrade>1</bBonusTrade>
<iDiscoverRand>10000</iDiscoverRand>
<YieldChanges>
<iYieldChange>0</iYieldChange>
<iYieldChange>1</iYieldChange>
<iYieldChange>1</iYieldChange>
</YieldChanges>
</BonusTypeStruct>
Use:
In my mod I use this code to allow corn & wheat to spread to other farms in your civ, but only if you already have it. The only XML change required was altering the iDiscoverRand value for corn and wheat in the farm. It can easily be adapted (with no code changes) to do the same with animals provided you allow pastures to be built on a tile that doesn't already have the animal bonus.