World Improvements?

cfkane

Emperor
Joined
Feb 7, 2006
Messages
1,196
In Fall from Heaven II there are certain natural landmarks that give special bonuses: "world improvements".

I'm having trouble figuring out how it was programmed. How can I create an improvement generated at the start of the game, by the computer, that only occurs once on the map?
 
It requires a little SDk programming the way we implmented it (you could also do it through python in the game start function if you wanted but the theroy is the same).

First we intercept in CvMapGenerator::addGameElements:

Code:
void CvMapGenerator::addGameElements()
{
	addRivers();
	gDLL->logMemState("CvMapGen after add rivers");

	addLakes();
	gDLL->logMemState("CvMapGen after add lakes");

	addFeatures();
	gDLL->logMemState("CvMapGen after add features");

	addBonuses();
	gDLL->logMemState("CvMapGen after add bonuses");

	addGoodies();
	gDLL->logMemState("CvMapGen after add goodies");

//FfH Improvements: Added by Kael 08/07/2007
    if (!GC.getGameINLINE().isOption(GAMEOPTION_NO_UNIQUE_IMPROVEMENTS))
    {
        addUniqueImprovements();
    }
//FfH: End Add

	// Call for Python to make map modifications after it's been generated
	afterGeneration();
}

Then we add a new function in CvMapGenerator to actually pass out the functions. It just cycles through each improvement looking for ones that have been tagged as unique, then applies a chance set in xml of creatign each one. If it has the chance it looks through the plots for a valid one to place the improvement at.

Code:
void CvMapGenerator::addUniqueImprovements()
{
	CvPlot* pPlot;
    int iBestValue = 0;
    int iValue = 0;
    int iChance = GC.getDefineINT("IMPROVEMENT_UNIQUE_CHANCE") + GC.getWorldInfo(GC.getMapINLINE().getWorldSize()).getUniqueFeatureChance();
	CvPlot* pBestPlot = NULL;
    for (int iI = 0; iI < GC.getNumImprovementInfos(); iI++)
    {
        if (GC.getImprovementInfo((ImprovementTypes)iI).isUnique())
        {
            iBestValue = 0;
            pBestPlot = NULL;
			if (GC.getGameINLINE().getMapRandNum(100, "Unique Improvements") < iChance)
			{
                for (int iJ = 0; iJ < GC.getMapINLINE().numPlotsINLINE(); iJ++)
                {
                    pPlot = GC.getMapINLINE().plotByIndexINLINE(iJ);
                    FAssert(pPlot != NULL);
                    if (pPlot->canHaveImprovement((ImprovementTypes)iI))
                    {
                        if (pPlot->getBonusType(NO_TEAM) == NO_BONUS)
                        {
                            iValue = GC.getGameINLINE().getMapRandNum(10000, "Unique Improvements");
                            if (iValue > iBestValue)
                            {
                                iBestValue = iValue;
                                pBestPlot = pPlot;
                            }
                        }
                    }
                }
                if (pBestPlot != NULL)
                {
                    pBestPlot->setImprovementType((ImprovementTypes)iI);
                    if (GC.getImprovementInfo((ImprovementTypes)iI).getSpawnUnitType() != NO_UNIT)
                    {
                      	if (!GC.getGameINLINE().isOption(GAMEOPTION_NO_BARBARIANS))
                        {
                            GET_PLAYER(BARBARIAN_PLAYER).initUnit(((UnitTypes)GC.getImprovementInfo((ImprovementTypes)iI).getSpawnUnitType()), pBestPlot->getX(), pBestPlot->getY());
                        }
                    }
                }
			}
        }
    }
}

Its not horribly complex, but it will require some SDK knowledge to hook up.
 
If you know the bonus name you want, and you know you want only one of it, you can create a relatively simple python script. It doesn't require SDK. It doesn't require understanding the map scripts, although those are the best place to look for sample code. Think out some simple conditions for where the resource may occur. Probably, not on oceans or peaks. Possibly, not in jungles. Then you can write a loop which generates a random location, tests for your conditions, and repeats until it finds a valid location. Then you can use the python call setBonusType on the plot. This would happen in the onGameStart event.
 
Back
Top Bottom