Bazaar developer reference

CvGame::SpawnArchaeologySitesHistorically()

Defined in
CvGame.cpp, line 11613
Class
CvGame
Hook name
CivHooks::CvGame_SpawnArchaeologySitesHistorically

Hooks

static bool BeforeCvGame_SpawnArchaeologySitesHistorically(CvGame* self);static void AfterCvGame_SpawnArchaeologySitesHistorically(CvGame* self);static void ReplaceCvGame_SpawnArchaeologySitesHistorically(void (*original)(CvGame*), CvGame* self);CivRegisterBefore<CivHooks::CvGame_SpawnArchaeologySitesHistorically>(host, &BeforeCvGame_SpawnArchaeologySitesHistorically);CivRegisterAfter<CivHooks::CvGame_SpawnArchaeologySitesHistorically>(host, &AfterCvGame_SpawnArchaeologySitesHistorically);CivRegisterReplace<CivHooks::CvGame_SpawnArchaeologySitesHistorically>(host, &ReplaceCvGame_SpawnArchaeologySitesHistorically);

Code

11613void CvGame::SpawnArchaeologySitesHistorically()11614{11615	CvMap& theMap = GC.getMap();11616	const int iGridWidth = theMap.getGridWidth();1161711618	// we should now have a map of the dig sites11619	// turn this map into set of RESOURCE_ARTIFACTS11620	const ResourceTypes eArtifactResourceType = static_cast<ResourceTypes>(GC.getARTIFACT_RESOURCE());11621	const ResourceTypes eHiddenArtifactResourceType = static_cast<ResourceTypes>(GC.getHIDDEN_ARTIFACT_RESOURCE());1162211623	const size_t aRandomArtifactsCount = 7;11624	GreatWorkArtifactClass aRandomArtifacts[aRandomArtifactsCount] = { 11625		CvTypes::getARTIFACT_ANCIENT_RUIN(), 11626		CvTypes::getARTIFACT_ANCIENT_RUIN(), 11627		CvTypes::getARTIFACT_RAZED_CITY(), 11628		CvTypes::getARTIFACT_BARBARIAN_CAMP(), 11629		CvTypes::getARTIFACT_BARBARIAN_CAMP(), 11630		CvTypes::getARTIFACT_BATTLE_MELEE(), 11631		CvTypes::getARTIFACT_BATTLE_RANGED() 11632	};1163311634	// find how many dig sites we need to create11635	const int iNumMajorCivs = countMajorCivsEverAlive();11636	const int iMinDigSites = GC.getMIN_DIG_SITES_PER_MAJOR_CIV() * iNumMajorCivs; //todo: parameterize this11637	const int iMaxDigSites = GC.getMAX_DIG_SITES_PER_MAJOR_CIV() * iNumMajorCivs; //todo: parameterize this11638	const int iIdealNumDigSites = iMinDigSites + getJonRandNum((iMaxDigSites - iMinDigSites) / 2, "Num dig sites") + getJonRandNum((iMaxDigSites - iMinDigSites) / 2, "Num dig sites");1163911640	// find the highest era any player has gotten to11641	EraTypes eHighestEra = NO_ERA;11642	PlayerTypes eLoopPlayer;11643	for(int iPlayerLoop = 0; iPlayerLoop < MAX_MAJOR_CIVS; iPlayerLoop++)11644	{11645		eLoopPlayer = (PlayerTypes) iPlayerLoop;1164611647		// Player not ever alive11648		if(!GET_PLAYER(eLoopPlayer).isEverAlive())11649			continue;1165011651		if (GET_PLAYER(eLoopPlayer).GetCurrentEra() > eHighestEra)11652		{11653			eHighestEra = GET_PLAYER(eLoopPlayer).GetCurrentEra();11654		}11655	}1165611657	CvWeightedVector<int, 64, true> eEraWeights;11658	eEraWeights.clear();11659	int iMaxEraWeight = 0;11660	for (int i=0; i < static_cast<int>(eHighestEra); i++)11661	{11662		int iWeight = static_cast<int>(eHighestEra) - i;11663		eEraWeights.push_back(i,iWeight);11664		iMaxEraWeight += iWeight;11665	}1166611667	RandomNumberDelegate fcn;11668	fcn = MakeDelegate(this, &CvGame::getJonRandNum);1166911670	// find out how many dig sites we have now11671	int iHowManyChosenDigSites = 0;1167211673	// fill the historical buffer with the archaeological data11674	FFastVector<CvArchaeologyData, true, c_eCiv5GameplayDLL, 0> historicalDigSites;11675	FFastVector<CvArchaeologyData, true, c_eCiv5GameplayDLL, 0> scratchDigSites;11676	int iGridSize = theMap.numPlots();11677	CvAssertMsg(iGridSize > 0, "iGridSize is zero");11678	historicalDigSites.resize(iGridSize);11679	scratchDigSites.resize(iGridSize);11680	for (int i = 0; i < iGridSize; i++)11681	{11682		scratchDigSites[i].m_eArtifactType = NO_GREAT_WORK_ARTIFACT_CLASS;11683		scratchDigSites[i].m_eEra = NO_ERA;11684		scratchDigSites[i].m_ePlayer1 = NO_PLAYER;11685		scratchDigSites[i].m_ePlayer2 = NO_PLAYER;1168611687		CvPlot* pPlot = theMap.plotByIndexUnchecked(i);11688		const ResourceTypes eResource = pPlot->getResourceType();1168911690		if (pPlot->isWater() || pPlot->isImpassable())11691		{11692			historicalDigSites[i].m_eArtifactType = NO_GREAT_WORK_ARTIFACT_CLASS;11693			historicalDigSites[i].m_eEra = NO_ERA;11694			historicalDigSites[i].m_ePlayer1 = NO_PLAYER;11695			historicalDigSites[i].m_ePlayer2 = NO_PLAYER;1169611697			//Cannot be an antiquity site if we cannot generate an artifact.11698			if(eResource == eArtifactResourceType || eResource == eHiddenArtifactResourceType)11699			{11700				pPlot->setResourceType(NO_RESOURCE, 0, true);11701			}11702		}11703		else11704		{11705			//If this plot is already marked as an antiquity site, ensure it's populated.11706			if(eResource == eArtifactResourceType || eResource == eHiddenArtifactResourceType)11707			{11708				if(pPlot->GetArchaeologicalRecord().m_eArtifactType == NO_GREAT_WORK_ARTIFACT_CLASS)11709				{11710					// pick an era before this one			11711					EraTypes eEra = static_cast<EraTypes>(eEraWeights.ChooseByWeight(&fcn, "Choosing an era by weight"));11712					eEra = eEra > static_cast<EraTypes>(0) ? eEra : static_cast<EraTypes>(0);1171311714					// pick a type of artifact11715					GreatWorkArtifactClass eArtifact = aRandomArtifacts[getJonRandNum(aRandomArtifactsCount, "Artifact type for non-historical dig site")];1171611717					PopulateDigSite(*pPlot, eEra, eArtifact);1171811719					//Record in scratch space for weights.11720					scratchDigSites[i] = pPlot->GetArchaeologicalRecord();11721				}1172211723				iHowManyChosenDigSites++;11724			}1172511726			historicalDigSites[i] = pPlot->GetArchaeologicalRecord();11727		}11728	}1172911730	// calculate initial weights11731	FFastVector<int, true, c_eCiv5GameplayDLL, 0> digSiteWeights;11732	digSiteWeights.resize(iGridSize);11733	for (int i = 0; i < iGridSize; i++)11734	{11735		digSiteWeights[i] = 0;11736	}11737	CalculateDigSiteWeights(iGridSize, historicalDigSites, scratchDigSites, digSiteWeights);1173811739	// build a weight vector11740	static CvWeightedVector<int, 128*80, true> aDigSiteWeights; // size of a HUGE world11741	aDigSiteWeights.resize(iGridSize);1174211743	vector<GreatWorkType> aWorksWriting;11744	Database::Connection* db = GC.GetGameDatabase();11745	if(db != NULL)11746	{11747		Database::Results kQuery;11748		if(db->Execute(kQuery, "SELECT ID from GreatWorks WHERE ArchaeologyOnly = '1'"))11749		{11750			while(kQuery.Step())11751			{11752				const GreatWorkType eWork = static_cast<GreatWorkType>(kQuery.GetInt(0));11753				aWorksWriting.push_back(eWork);11754			}11755		}11756	}1175711758	int iApproxNumHiddenSites = iIdealNumDigSites * GC.getPERCENT_SITES_HIDDEN() / 100;11759	int iNumDesiredWritingSites = iApproxNumHiddenSites * GC.getPERCENT_HIDDEN_SITES_WRITING() / 100;11760	int iNumWritingSites = min((int)aWorksWriting.size(), iNumDesiredWritingSites);1176111762	// while we are not in the proper range of number of dig sites11763	while (iHowManyChosenDigSites < iIdealNumDigSites)11764	{11765		// populate a weight vector11766		aDigSiteWeights.clear();11767		for (int i = 0; i < iGridSize; i++)11768		{11769			if (digSiteWeights[i] > 0)11770			{11771				aDigSiteWeights.push_back(i, digSiteWeights[i]);11772			}11773		}1177411775		// sort the weight vector11776		aDigSiteWeights.SortItems();1177711778		// add the best dig site11779		int iBestSite = aDigSiteWeights.GetElement(0);11780		CvPlot* pPlot = theMap.plotByIndexUnchecked(iBestSite);1178111782		// Hidden site?11783		bool bHiddenSite = GC.getGame().getJonRandNum(100, "Hidden antiquity site roll") < GC.getPERCENT_SITES_HIDDEN();11784		if (bHiddenSite)11785		{11786			pPlot->setResourceType(eHiddenArtifactResourceType, 1);11787		}11788		else11789		{11790			pPlot->setResourceType(eArtifactResourceType, 1);11791		}1179211793		// if this is not a historical dig site11794		if (scratchDigSites[iBestSite].m_eArtifactType == NO_GREAT_WORK_ARTIFACT_CLASS)11795		{11796			// fake the historical data11797			// pick an era before this one			11798			EraTypes eEra = static_cast<EraTypes>(eEraWeights.ChooseByWeight(&fcn, "Choosing an era by weight"));11799			eEra = eEra > static_cast<EraTypes>(0) ? eEra : static_cast<EraTypes>(0);1180011801			// pick a type of artifact11802			GreatWorkArtifactClass eArtifact;11803			eArtifact = aRandomArtifacts[getJonRandNum(aRandomArtifactsCount, "Artifact type for non-historical dig site")];1180411805			PopulateDigSite(*pPlot, eEra, eArtifact);11806		}1180711808		// If this is a hidden slot getting a writing, override a few things11809		if (bHiddenSite && iNumWritingSites > 0)11810		{11811			// First change the type11812			pPlot->SetArtifactType(CvTypes::getARTIFACT_WRITING());1181311814			// Then get a writing and set it11815			int iIndex = getJonRandNum(aWorksWriting.size(), "");11816			GreatWorkType eWrittenGreatWork = aWorksWriting[iIndex];11817			pPlot->SetArtifactGreatWork((GreatWorkType)eWrittenGreatWork);1181811819			// Erase that writing from future consideration11820			vector<GreatWorkType>::const_iterator it;11821			it = std::find (aWorksWriting.begin(), aWorksWriting.end(), eWrittenGreatWork);11822			aWorksWriting.erase(it);1182311824			// One less writing to give out11825			iNumWritingSites--;11826		}1182711828		scratchDigSites[iBestSite] = pPlot->GetArchaeologicalRecord();1182911830		iHowManyChosenDigSites++;1183111832		// recalculate weights near the chosen dig site (the rest of the world should still be fine)11833		const int iRange = 3;11834		int iPlotX = iBestSite % iGridWidth;11835		int iPlotY = iBestSite / iGridWidth;11836		for (int iDX = -iRange; iDX <= iRange; iDX++)11837		{11838			for (int iDY = -iRange; iDY <= iRange; iDY++)11839			{11840				CvPlot* pLoopPlot = plotXYWithRangeCheck(iPlotX, iPlotY, iDX, iDY, iRange);11841				if (pLoopPlot)11842				{11843					int iIndex = pLoopPlot->GetPlotIndex();11844					digSiteWeights[iIndex] = CalculateDigSiteWeight(iIndex, historicalDigSites, scratchDigSites);				11845				}11846			}11847		}11848	}11849}

Calls

Called by