Hooks
static bool BeforeCvBuilderTaskingAI_EvaluateBuilder(CvBuilderTaskingAI* self, CvUnit* pUnit, BuilderDirective* paDirectives, UINT uaDirectives, bool bOnlyKeepBest, bool bOnlyEvaluateWorkersPlot, bool bLimit, bool& result);static void AfterCvBuilderTaskingAI_EvaluateBuilder(CvBuilderTaskingAI* self, CvUnit* pUnit, BuilderDirective* paDirectives, UINT uaDirectives, bool bOnlyKeepBest, bool bOnlyEvaluateWorkersPlot, bool bLimit, bool& result);static bool ReplaceCvBuilderTaskingAI_EvaluateBuilder(bool (*original)(CvBuilderTaskingAI*, CvUnit*, BuilderDirective*, UINT, bool, bool, bool), CvBuilderTaskingAI* self, CvUnit* pUnit, BuilderDirective* paDirectives, UINT uaDirectives, bool bOnlyKeepBest, bool bOnlyEvaluateWorkersPlot, bool bLimit);CivRegisterBefore<CivHooks::CvBuilderTaskingAI_EvaluateBuilder>(host, &BeforeCvBuilderTaskingAI_EvaluateBuilder);CivRegisterAfter<CivHooks::CvBuilderTaskingAI_EvaluateBuilder>(host, &AfterCvBuilderTaskingAI_EvaluateBuilder);CivRegisterReplace<CivHooks::CvBuilderTaskingAI_EvaluateBuilder>(host, &ReplaceCvBuilderTaskingAI_EvaluateBuilder);
Code
646/// Use the flavor settings to determine what the worker should do647#if defined(MOD_UNITS_LOCAL_WORKERS) || defined(MOD_AI_SECONDARY_WORKERS)648bool CvBuilderTaskingAI::EvaluateBuilder(CvUnit* pUnit, BuilderDirective* paDirectives, UINT uaDirectives, bool bOnlyKeepBest, bool bOnlyEvaluateWorkersPlot, bool bLimit)649#else650bool CvBuilderTaskingAI::EvaluateBuilder(CvUnit* pUnit, BuilderDirective* paDirectives, UINT uaDirectives, bool bOnlyKeepBest, bool bOnlyEvaluateWorkersPlot)651#endif652{653 // number of cities has changed mid-turn, so we need to re-evaluate what workers should do654 if(m_pPlayer->getNumCities() != m_iNumCities)655 {656 Update();657 }658659 CvAssertMsg(uaDirectives > 0, "Need more than one directive");660661 for(uint ui = 0; ui < uaDirectives; ui++)662 {663 paDirectives[ui].m_eDirective = BuilderDirective::NUM_DIRECTIVES;664 }665666 m_aDirectives.clear();667668 // check for no brainer bail-outs669 // if the builder is already building something670 if(pUnit->getBuildType() != NO_BUILD)671 {672 paDirectives[0].m_eDirective = BuilderDirective::BUILD_IMPROVEMENT;673 paDirectives[0].m_eBuild = pUnit->getBuildType();674 paDirectives[0].m_sX = pUnit->getX();675 paDirectives[0].m_sY = pUnit->getY();676 //inDirective.m_sGoldCost = 0;677 paDirectives[0].m_sMoveTurnsAway = 0;678 return true;679 }680681 m_aiPlots.clear();682 if(bOnlyEvaluateWorkersPlot)683 {684 // can't build on plots others own685 PlayerTypes eOwner = pUnit->plot()->getOwner();686 if(eOwner == m_pPlayer->GetID())687 {688 m_aiPlots.push_back(pUnit->plot()->GetPlotIndex());689 }690 }691 else692 {693 m_aiPlots = m_pPlayer->GetPlots();694 }695696 // go through all the plots the player has under their control697 for(uint uiPlotIndex = 0; uiPlotIndex < m_aiPlots.size(); uiPlotIndex++)698 {699 // when we encounter the first plot that is invalid, the rest of the list will be invalid700 if(m_aiPlots[uiPlotIndex] == -1)701 {702 if(m_bLogging)703 {704 CvString strLog = "end of plot list";705 LogInfo(strLog, m_pPlayer);706 }707 break;708 }709710 CvPlot* pPlot = GC.getMap().plotByIndex(m_aiPlots[uiPlotIndex]);711712 if(!ShouldBuilderConsiderPlot(pUnit, pPlot))713 {714 continue;715 }716717 // distance weight718 // find how many turns the plot is away719#if defined(MOD_UNITS_LOCAL_WORKERS) || defined(MOD_AI_SECONDARY_WORKERS)720 int iMoveTurnsAway = FindTurnsAway(pUnit, pPlot, bLimit);721#else722 int iMoveTurnsAway = FindTurnsAway(pUnit, pPlot);723#endif724 if(iMoveTurnsAway < 0)725 {726 if(m_bLogging)727 {728 CvString strLog;729 strLog.Format("unitx: %d unity: %d, plotx: %d ploty: %d, can't find path", pUnit->getX(), pUnit->getY(), pPlot->getX(), pPlot->getY());730 LogInfo(strLog, m_pPlayer);731 }732733 continue;734 }735736 UpdateCurrentPlotYields(pPlot);737738 //AddRepairDirectives(pUnit, pPlot, iMoveTurnsAway);739 AddRouteDirectives(pUnit, pPlot, iMoveTurnsAway);740 AddImprovingResourcesDirectives(pUnit, pPlot, iMoveTurnsAway);741 AddImprovingPlotsDirectives(pUnit, pPlot, iMoveTurnsAway);742 AddChopDirectives(pUnit, pPlot, iMoveTurnsAway);743 AddScrubFalloutDirectives(pUnit, pPlot, iMoveTurnsAway);744 // only AIs have permission to remove roads745 if(!m_pPlayer->isHuman())746 {747 //AddRemoveUselessRoadDirectives(pUnit, pPlot, iMoveTurnsAway);748 }749 }750751 // we need to evaluate the tiles outside of our territory to build roads752 for(uint ui = 0; ui < m_aiNonTerritoryPlots.size(); ui++)753 {754 //FAssertMsg(!m_pPlayer->isMinorCiv(), "MinorCivs should have no nonterritory plots");755 CvPlot* pPlot = GC.getMap().plotByIndex(m_aiNonTerritoryPlots[ui]);756 CvAssertMsg(pPlot != NULL, "Plot should not be NULL");757 if(!pPlot)758 continue;759760 if(bOnlyEvaluateWorkersPlot)761 {762 if(pPlot != pUnit->plot())763 {764 continue;765 }766 }767768 if(!ShouldBuilderConsiderPlot(pUnit, pPlot))769 {770 continue;771 }772773 // distance weight774 // find how many turns the plot is away775#if defined(MOD_UNITS_LOCAL_WORKERS) || defined(MOD_AI_SECONDARY_WORKERS)776 int iMoveTurnsAway = FindTurnsAway(pUnit, pPlot, bLimit);777#else778 int iMoveTurnsAway = FindTurnsAway(pUnit, pPlot);779#endif780 if(iMoveTurnsAway < 0)781 {782 if(m_bLogging)783 {784 CvString strLog;785 strLog.Format("unitx: %d unity: %d, plotx: %d ploty: %d, Evaluating out of territory plot, can't find path", pUnit->getX(), pUnit->getY(), pPlot->getX(), pPlot->getY());786 LogInfo(strLog, m_pPlayer);787 }788789 continue;790 }791792 if(m_bLogging)793 {794 CvString strLog;795 strLog.Format("x: %d y: %d, Evaluating out of territory plot", pPlot->getX(), pPlot->getY());796 LogInfo(strLog, m_pPlayer);797 }798799 //AddRepairDirectives(pUnit, pPlot, iMoveTurnsAway);800 AddRouteDirectives(pUnit, pPlot, iMoveTurnsAway);801 }802803 m_aDirectives.StableSortItems();804805 int iBestWeight = 0;806807 int iAssignIndex = 0;808 for(int i = 0; i < m_aDirectives.size(); i++)809 {810 // If this target was far away, we only estimated the time to get there. We need to be sure we have a real path there811 CvPlot* pTarget = GC.getMap().plot(m_aDirectives.GetElement(i).m_sX, m_aDirectives.GetElement(i).m_sY);812 CvAssertMsg(pTarget != NULL, "Not expecting the target to be NULL");813 if(!pTarget)814 continue;815816#if 0 // KWG: We are now always doing a raw estimate when gathering the directives817 int iPlotDistance = plotDistance(pUnit->getX(), pUnit->getY(), pTarget->getX(), pTarget->getY());818 if(iPlotDistance >= GC.getAI_HOMELAND_ESTIMATE_TURNS_DISTANCE())819#endif820 {821 if(TurnsToReachTarget(pUnit, pTarget) == MAX_INT)822 {823 // No path, need to pick a new directive824 continue;825 }826 }827828 if(iBestWeight == 0)829 {830 iBestWeight = m_aDirectives.GetWeight(i);831 }832833 if(bOnlyKeepBest)834 {835 int iWeight = m_aDirectives.GetWeight(i);836 if(iWeight < iBestWeight * 3 / 4)837 {838 break;839 }840 }841842 BuilderDirective directive = m_aDirectives.GetElement(i);843 paDirectives[iAssignIndex] = directive;844 iAssignIndex++;845846 // if we shouldn't copy over any more directives, then break847 if(iAssignIndex >= (int)uaDirectives)848 {849 break;850 }851 }852853 if(m_bLogging)854 {855 if(m_aDirectives.size() > 0)856 {857 //LogFlavors(NO_FLAVOR);858 }859860 LogDirectives(pUnit);861 }862863 //if (m_aDirectives.size() > 0 && iAssignIndex > 0)864 if(iAssignIndex > 0)865 {866 if(m_bLogging)867 {868 LogDirective(paDirectives[0], pUnit, -1, true /*bChosen*/);869 }870 return true;871 }872873 return false;874}