Hooks
static bool BeforeCvStartPositioner_AddCivToRegion(CvStartPositioner* self, int iPlayerIndex, CvStartRegion region, bool bRelaxFoodReq, bool& result);static void AfterCvStartPositioner_AddCivToRegion(CvStartPositioner* self, int iPlayerIndex, CvStartRegion region, bool bRelaxFoodReq, bool& result);static bool ReplaceCvStartPositioner_AddCivToRegion(bool (*original)(CvStartPositioner*, int, CvStartRegion, bool), CvStartPositioner* self, int iPlayerIndex, CvStartRegion region, bool bRelaxFoodReq);// CivHooks.h gives this hook point no types, so nothing checks these hooks' parameters.host->RegisterHook(host->pluginIndex, CivHooks::CvStartPositioner_AddCivToRegion::ID, CIV_HOOK_BEFORE, (void*)&BeforeCvStartPositioner_AddCivToRegion);host->RegisterHook(host->pluginIndex, CivHooks::CvStartPositioner_AddCivToRegion::ID, CIV_HOOK_AFTER, (void*)&AfterCvStartPositioner_AddCivToRegion);host->RegisterHook(host->pluginIndex, CivHooks::CvStartPositioner_AddCivToRegion::ID, CIV_HOOK_REPLACE, (void*)&ReplaceCvStartPositioner_AddCivToRegion);
Code
616/// Pick a start position for a civ within a specific region617bool CvStartPositioner::AddCivToRegion(int iPlayerIndex, CvStartRegion region, bool bRelaxFoodReq)618{619 CvString strString;620 int uiBestFoundValue = 0;621 int uiPlotFoundValue;622 CvPlot* pBestPlot = NULL;623 CvPlot* pLoopPlot = NULL;624 int iMinorFoodReq = GC.getMINOR_CIV_FOOD_REQUIREMENT();625 int iMajorFoodReq = GC.getMAJOR_CIV_FOOD_REQUIREMENT();626 bool bIsMinorCiv = GET_PLAYER((PlayerTypes)iPlayerIndex).isMinorCiv();627 TeamTypes eTeam = GET_PLAYER((PlayerTypes)iPlayerIndex).getTeam();628 int iPercentOfBest = GC.getMIN_START_FOUND_VALUE_AS_PERCENT_OF_BEST();629630 MinorCivTypes eMinorCivType = NO_MINORCIV;631 if(bIsMinorCiv)632 {633 eMinorCivType =GET_PLAYER((PlayerTypes) iPlayerIndex).GetMinorCivAI()->GetMinorCivType();634 }635636 bool bDebugMap = GC.getMap().getWorldSize() == WORLDSIZE_DEBUG;637638 // ***** Debug *****639 if(bDebugMap)640 {641 iMinorFoodReq = 0;642 iMajorFoodReq = 0;643 }644645 // Find best found value in region646 for(int iRow = region.m_Boundaries.m_iSouthEdge; iRow <= region.m_Boundaries.m_iNorthEdge; iRow++)647 {648 for(int iCol = region.m_Boundaries.m_iWestEdge; iCol <= region.m_Boundaries.m_iEastEdge; iCol++)649 {650 pLoopPlot = GC.getMap().plot(iCol, iRow);651652 // Make sure it actually *is* in region653 if(pLoopPlot && pLoopPlot->getArea() == region.m_iAreaID)654 {655 // Check food requirement656 if((bRelaxFoodReq && MeetsFoodRequirement(pLoopPlot, eTeam, iMinorFoodReq))657 || (bIsMinorCiv && MeetsFoodRequirement(pLoopPlot, eTeam, iMinorFoodReq))658 || MeetsFoodRequirement(pLoopPlot, eTeam, iMajorFoodReq))659 {660 // Retrieve from player 1's found value slot661 // (Normally shouldn't be using a hard-coded player reference, but here in the pre-game initialization it is safe to do so.662 // Allows us to reuse this data storage instead of jamming even more data into the CvPlot class that will never be used at run-time).663 uiPlotFoundValue = pLoopPlot->getFoundValue((PlayerTypes)1);664665 // If we're a Maritime Minor Civ then decrease the value of non-coastal starts666 if(bIsMinorCiv)667 {668 if(GC.getMinorCivInfo(eMinorCivType)->GetMinorCivTrait() == MINOR_CIV_TRAIT_MARITIME)669 {670 if(!pLoopPlot->isCoastalLand(GC.getLAKE_MAX_AREA_SIZE()))671 {672 uiPlotFoundValue /= 2;673 }674 }675 }676677 // Above the minimum found value?678 if(bDebugMap || ((int)uiPlotFoundValue > (int)m_iBestFoundValueOnMap * iPercentOfBest / 100))679 {680 // Check distance681 if(!TooCloseToAnotherCiv(pLoopPlot))682 {683 // Best so far?684 if(bDebugMap || uiPlotFoundValue > uiBestFoundValue)685 {686 uiBestFoundValue = uiPlotFoundValue;687 pBestPlot = pLoopPlot;688 }689 }690 }691 }692 }693 }694 }695696 if(pBestPlot != NULL)697 {698 GET_PLAYER((PlayerTypes)iPlayerIndex).setStartingPlot(pBestPlot);699 strString.Format("Adding player, id = %d, plot x = %d, y = %d, fertility = %u",700 iPlayerIndex, pBestPlot->getX(), pBestPlot->getY(), uiBestFoundValue);701 LogStartPositionMessage(strString);702 return true;703 }704 else705 {706 return false;707 }708}