Bazaar developer reference

CvMap::DoPlaceNaturalWonders()

Defined in
CvMap.cpp, line 1572
Class
CvMap
Hook name
CivHooks::CvMap_DoPlaceNaturalWonders

Hooks

static bool BeforeCvMap_DoPlaceNaturalWonders(CvMap* self);static void AfterCvMap_DoPlaceNaturalWonders(CvMap* self);static void ReplaceCvMap_DoPlaceNaturalWonders(void (*original)(CvMap*), CvMap* self);CivRegisterBefore<CivHooks::CvMap_DoPlaceNaturalWonders>(host, &BeforeCvMap_DoPlaceNaturalWonders);CivRegisterAfter<CivHooks::CvMap_DoPlaceNaturalWonders>(host, &AfterCvMap_DoPlaceNaturalWonders);CivRegisterReplace<CivHooks::CvMap_DoPlaceNaturalWonders>(host, &ReplaceCvMap_DoPlaceNaturalWonders);

Code

1571/// Put Natural Wonders on the map - this could be a LUA script1572void CvMap::DoPlaceNaturalWonders()1573{1574	FeatureTypes eNWFeature = NO_FEATURE;1575	FeatureTypes eFeature;15761577	FeatureTypes featureFuji = NO_FEATURE;1578	FeatureTypes featureEverest = NO_FEATURE;1579	FeatureTypes featureReef = NO_FEATURE;1580	FeatureTypes featureCrater = NO_FEATURE;1581	FeatureTypes featureLake = NO_FEATURE;1582	FeatureTypes featureMesa = NO_FEATURE;1583	FeatureTypes featureVolcano = NO_FEATURE;15841585	int iNumFeatureInfos = GC.getNumFeatureInfos();1586	int nwCount = 0;1587	for(int iFeatureLoop = 0; iFeatureLoop < iNumFeatureInfos; iFeatureLoop++)1588	{1589		eFeature = (FeatureTypes) iFeatureLoop;1590		CvFeatureInfo* feature = GC.getFeatureInfo(eFeature);1591		if(feature && feature->IsNaturalWonder())1592		{1593			eNWFeature = eFeature;15941595			// hackery - this should be more data driven but the engine side isn't15961597			if(strcmp(feature->GetType(), "FEATURE_EVEREST") == 0)1598			{1599				featureEverest = eFeature;1600			}1601			else if(strcmp(feature->GetType(), "FEATURE_CRATER") == 0)1602			{1603				featureCrater = eFeature;1604			}1605			else if(strcmp(feature->GetType(), "FEATURE_TITICACA") == 0)1606			{1607				featureLake = eFeature;1608			}1609			else if(strcmp(feature->GetType(), "FEATURE_FUJI") == 0)1610			{1611				featureFuji = eFeature;1612			}1613			else if(strcmp(feature->GetType(), "FEATURE_MESA") == 0)1614			{1615				featureMesa = eFeature;1616			}1617			else if(strcmp(feature->GetType(), "FEATURE_REEF") == 0)1618			{1619				featureReef = eFeature;1620			}1621			else if(strcmp(feature->GetType(), "FEATURE_VOLCANO") == 0)1622			{1623				featureVolcano = eFeature;1624			}16251626			nwCount++;1627		}1628	}16291630	// No Natural Wonder Feature, abort!1631	if(eNWFeature == NO_FEATURE)1632	{1633		return;1634	}16351636	int iNumNaturalWondersToAdd = getWorldInfo().getNumNaturalWonders();16371638	int iCoastDistance = -1;	// Should be in XML1639	int iAnotherNWDistance = 5;	// Should be in XML16401641	int iCount = 0;16421643	int iPlotRand;1644	CvPlot* pRandPlot;16451646	int iPlotLoopX;1647	int iPlotLoopY;1648	CvPlot* pLoopPlot;16491650	int iNumMapPlots = numPlots();16511652	// Determine the max number of NWs we can have in a single Area1653	CvArea* pLoopArea;1654	int iLoop;1655	int iNumValidAreas = 0;16561657	int iMaxLatitudeForNW = 65;16581659	int iBottomLatitude;16601661	for(pLoopArea = firstArea(&iLoop); pLoopArea != NULL; pLoopArea = nextArea(&iLoop))1662	{1663		if(!pLoopArea->isWater())1664		{1665			if(!pLoopArea->IsMountains())1666			{1667				iBottomLatitude = pLoopArea->GetAreaMinLatitude();16681669				if(iBottomLatitude <= iMaxLatitudeForNW)1670				{1671					iNumValidAreas++;1672				}1673			}1674		}1675	}16761677	int iMaxNWsOneArea = 2;16781679	// If we have more Natural Wonders than we have Areas then we have to handle things differently - more can be placed in one Area than normal1680	if(iNumNaturalWondersToAdd > iNumValidAreas)1681	{1682		iMaxNWsOneArea = iNumNaturalWondersToAdd - iNumValidAreas + 1;1683	}16841685	while(iNumNaturalWondersToAdd > 0 && iCount < 10000)1686	{1687		iCount++;16881689		iPlotRand = GC.getGame().getJonRandNum(iNumMapPlots, "Randomly Placing Natural Wonders");16901691		pRandPlot = plotByIndex(iPlotRand);16921693		// No Water Tiles1694		if(pRandPlot->isWater())1695		{1696			continue;1697		}16981699		// No River Tiles either (don't want them carved up)1700		if(pRandPlot->isRiver())1701		{1702			continue;1703		}17041705		// No Tiles with Resources1706		if(pRandPlot->getResourceType() != NO_RESOURCE)1707		{1708			continue;1709		}17101711		// No Tiles with Improvements (Goody Huts)1712		if(pRandPlot->getImprovementType() != NO_IMPROVEMENT)1713		{1714			continue;1715		}17161717		// Can't have too many NWs in one Area1718		if(getArea(pRandPlot->getArea())->GetNumNaturalWonders() >= iMaxNWsOneArea)1719		{1720			continue;1721		}17221723		// Has to be in the central band of the map.  If the latitude is too extreme we might end up on a islelet surrounded by Ice or something1724		if(pRandPlot->getLatitude() > /*65*/ iMaxLatitudeForNW)1725		{1726			continue;1727		}17281729		// Can't be a starting Plot for ANY player (including Minors)1730		if(pRandPlot->isStartingPlot())1731		{1732			continue;1733		}17341735		bool bValid;17361737		// Does it have to be close to the coast?1738		if(iCoastDistance != -1)1739		{1740			bValid = false;17411742			for(iPlotLoopX = -iCoastDistance; iPlotLoopX <= iCoastDistance; iPlotLoopX++)1743			{1744				for(iPlotLoopY = -iCoastDistance; iPlotLoopY <= iCoastDistance; iPlotLoopY++)1745				{1746					pLoopPlot = plotXYWithRangeCheck(pRandPlot->getX(), pRandPlot->getY(), iPlotLoopX, iPlotLoopY, iCoastDistance);17471748					if(pLoopPlot != NULL)1749					{1750						if(pLoopPlot->isWater())1751						{1752							if(!pLoopPlot->isLake())1753							{1754								// Found a Plot within 2 plots of "the Ocean"1755								bValid = true;1756								break;1757							}1758						}1759					}1760				}17611762				if(bValid)1763				{1764					break;1765				}1766			}17671768			// Plot not within 2 of Ocean1769			if(!bValid)1770			{1771				continue;1772			}1773		}17741775		bValid = true;17761777		// Can't be too close to another Natural Wonder1778		for(iPlotLoopX = -iAnotherNWDistance; iPlotLoopX <= iAnotherNWDistance; iPlotLoopX++)1779		{1780			for(iPlotLoopY = -iAnotherNWDistance; iPlotLoopY <= iAnotherNWDistance; iPlotLoopY++)1781			{1782				pLoopPlot = plotXYWithRangeCheck(pRandPlot->getX(), pRandPlot->getY(), iPlotLoopX, iPlotLoopY, iAnotherNWDistance);17831784				if(pLoopPlot != NULL)1785				{1786					if(pLoopPlot->IsNaturalWonder())1787					{1788						// Found a NW too close1789						bValid = false;1790						break;1791					}1792				}1793			}17941795			if(!bValid)1796			{1797				break;1798			}1799		}18001801		// Natural Wonder too close1802		if(!bValid)1803		{1804			continue;1805		}18061807		// see if we can add the volcano1808		if(featureVolcano != NO_FEATURE)1809		{1810			if(!pRandPlot->isAdjacentToLand())1811			{1812				pRandPlot->setPlotType(PLOT_MOUNTAIN);1813				pRandPlot->setFeatureType(featureVolcano);1814				iNumNaturalWondersToAdd--;1815				featureVolcano = NO_FEATURE;	// Prevent this one from being placed again1816				continue;1817			}1818		}18191820		// see if we can add the reef1821		if(featureReef != NO_FEATURE)1822		{1823			if(!pRandPlot->isMountain() && pRandPlot->isAdjacentToShallowWater())1824			{1825				if(pRandPlot->area()->getNumTiles() == 2)1826				{1827					pRandPlot->setPlotType(PLOT_MOUNTAIN);1828					pRandPlot->setFeatureType(featureReef);1829					for(int iI = 0; iI < NUM_DIRECTION_TYPES; ++iI)1830					{1831						CvPlot* pAdjacentPlot = plotDirection(pRandPlot->getX(), pRandPlot->getY(), ((DirectionTypes)iI));1832						if(pAdjacentPlot != NULL)1833						{1834							if(!(pAdjacentPlot->isWater()))1835							{1836								pAdjacentPlot->setPlotType(PLOT_MOUNTAIN);1837								pAdjacentPlot->setFeatureType(featureReef);1838								break;1839							}1840						}1841					}1842					iNumNaturalWondersToAdd--;1843					featureReef = NO_FEATURE;	// Prevent this one from being placed again1844					continue;1845				}1846			}1847		}18481849		// see if we can add the lake1850		if(featureLake != NO_FEATURE)1851		{1852			if(pRandPlot->isHills())1853			{1854				int iHillCount = 0;1855				// if we have a couple of hills nearby already1856				for(int iI = 0; iI < NUM_DIRECTION_TYPES; ++iI)1857				{1858					CvPlot* pAdjacentPlot = plotDirection(pRandPlot->getX(), pRandPlot->getY(), ((DirectionTypes)iI));1859					if(pAdjacentPlot != NULL)1860					{1861						if((pAdjacentPlot->isHills()))1862						{1863							iHillCount++;1864						}1865					}1866				}1867				if(iHillCount > 2)1868				{1869					// we are stamping the terrain1870					for(int iI = 0; iI < NUM_DIRECTION_TYPES; ++iI)1871					{1872						CvPlot* pAdjacentPlot = plotDirection(pRandPlot->getX(), pRandPlot->getY(), ((DirectionTypes)iI));1873						if(pAdjacentPlot != NULL)1874						{1875							pAdjacentPlot->setPlotType(PLOT_HILLS);1876							pAdjacentPlot->setTerrainType((TerrainTypes)(GC.getLAND_TERRAIN()));1877						}1878					}1879					pRandPlot->setPlotType(PLOT_MOUNTAIN);1880					pRandPlot->setFeatureType(featureLake);1881					iNumNaturalWondersToAdd--;1882					featureLake = NO_FEATURE;	// Prevent this one from being placed again1883					continue;1884				}1885			}1886		}18871888		// see if we can add Everest1889		if(featureEverest != NO_FEATURE)1890		{1891			if(pRandPlot->isMountain() && GC.getGame().getMapRandNum(100, "Natural Wonder") > 75)1892			{1893				// we are stamping the terrain1894				for(int iI = 0; iI < NUM_DIRECTION_TYPES; ++iI)1895				{1896					CvPlot* pAdjacentPlot = plotDirection(pRandPlot->getX(), pRandPlot->getY(), ((DirectionTypes)iI));1897					if(pAdjacentPlot != NULL)1898					{1899						if(iI & 1)1900						{1901							pAdjacentPlot->setPlotType(PLOT_MOUNTAIN);1902						}1903						else1904						{1905							pAdjacentPlot->setPlotType(PLOT_HILLS);1906							pAdjacentPlot->setTerrainType((TerrainTypes)(GC.getLAND_TERRAIN()));1907						}1908					}1909				}1910				pRandPlot->setPlotType(PLOT_MOUNTAIN);1911				pRandPlot->setFeatureType(featureEverest);1912				iNumNaturalWondersToAdd--;1913				featureEverest = NO_FEATURE;	// Prevent this one from being placed again1914				continue;1915			}1916		}19171918		// randomly pick one of the other three - but not if this is a coastal plot, because they look terrible there1919		if(pRandPlot->isCoastalLand())1920		{1921			continue;1922		}19231924		int iDice = GC.getGame().getMapRandNum(100, "Natural Wonder");1925		if(iDice > 66)1926		{1927			if(featureCrater != NO_FEATURE)1928			{1929				pRandPlot->setPlotType(PLOT_MOUNTAIN);1930				pRandPlot->setFeatureType(featureCrater);1931				iNumNaturalWondersToAdd--;1932				featureCrater = NO_FEATURE;	// Prevent this one from being placed again1933				continue;1934			}1935		}1936		else if(iDice > 25)1937		{1938			if(featureFuji != NO_FEATURE)1939			{1940				pRandPlot->setPlotType(PLOT_MOUNTAIN);1941				pRandPlot->setFeatureType(featureFuji);1942				iNumNaturalWondersToAdd--;1943				featureFuji = NO_FEATURE;	// Prevent this one from being placed again1944				continue;1945			}1946		}1947		else1948		{1949			if(featureMesa != NO_FEATURE)1950			{1951				pRandPlot->setPlotType(PLOT_MOUNTAIN);1952				pRandPlot->setFeatureType(featureMesa);1953				iNumNaturalWondersToAdd--;1954				featureMesa = NO_FEATURE;	// Prevent this one from being placed again1955				continue;1956			}1957		}1958	}1959}

Calls

Called by