How do the World Improvements work?

To make it only occur once set <bUnique> to 1

Setting <bPermanent> to 1 may be a good idea too.

I'm not really sure what determines if an improvement will be placed, but it seems that any improvement I add will be randomly placed on the terrains found in <TerrainMakesValids>
 
The real work is all done in CVMapGenerator.cpp. First an addition to CvMapGenerator::addGameElements() where the bolded part is the only part that applies to adding unique improvements:

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_LAIRS))
    {
        addImprovements();
    }
[b]    if (!GC.getGameINLINE().isOption(GAMEOPTION_NO_UNIQUE_IMPROVEMENTS))
    {
        addUniqueImprovements();
    }[/b]
    if (GC.getGameINLINE().isOption(GAMEOPTION_BARBARIAN_WORLD))
    {
        for (int iI = 0; iI < MAX_PLAYERS; iI++)
        {
            if (GET_PLAYER((PlayerTypes)iI).isAlive() && iI != BARBARIAN_PLAYER)
            {
                GC.getGameINLINE().foundBarbarianCity();
            }
        }
    }
//FfH: End Add

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

Then the addition of the addUniqueImprovements() function that it calls:

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());
                        }
                    }
                }
			}
        }
    }
}

Basically it goes through each of the unique improvements, and if it finds one it has a chance equal to the IMPROVEMENT_UNIQUE_CHANCE definition of spawning that unique improvement somewhere on the map.

Incidently you wouldnt need the last part of that function that spawns defined units on unique features unless you want barb units to start on them as we have in FfH.

Hopefully that helps.
 
That helps some, but I'm still having a bit of trouble reading python script.

I'm not surprised - that's C++ :D

(it's handled in the DLL)


---

That aside - there are probably simple ways to implement the same thing in Python - it's just not as neat. Rough method;

1. Define some improvements in XML and make sure they're unbuildable.
2. Add code to "OnGameStart" in Python to find a valid place to put the improvements and then create one;

Code:
pPlot.setImprovementType(gc.getInfoTypeForString('IMPROVEMENT_GRAND_CANYON'))

The code for the first part very much depends on where you want the improvements to appear...
 
Back
Top Bottom