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}