Hooks
static bool BeforeCvCityCitizens_IsAIWantSpecialistRightNow(CvCityCitizens* self, bool& result);static void AfterCvCityCitizens_IsAIWantSpecialistRightNow(CvCityCitizens* self, bool& result);static bool ReplaceCvCityCitizens_IsAIWantSpecialistRightNow(bool (*original)(CvCityCitizens*), CvCityCitizens* self);CivRegisterBefore<CivHooks::CvCityCitizens_IsAIWantSpecialistRightNow>(host, &BeforeCvCityCitizens_IsAIWantSpecialistRightNow);CivRegisterAfter<CivHooks::CvCityCitizens_IsAIWantSpecialistRightNow>(host, &AfterCvCityCitizens_IsAIWantSpecialistRightNow);CivRegisterReplace<CivHooks::CvCityCitizens_IsAIWantSpecialistRightNow>(host, &ReplaceCvCityCitizens_IsAIWantSpecialistRightNow);
Code
661/// Does the AI want a Specialist?662bool CvCityCitizens::IsAIWantSpecialistRightNow()663{664 int iWeight = 100;665666 // If the City is Size 1 or 2 then we probably don't want Specialists667 if(m_pCity->getPopulation() < 3)668 {669 iWeight /= 2;670 }671672 int iFoodPerTurn = m_pCity->getYieldRate(YIELD_FOOD, false);673 int iFoodEatenPerTurn = m_pCity->foodConsumption();674 int iSurplusFood = iFoodPerTurn - iFoodEatenPerTurn;675676 CityAIFocusTypes eFocusType = GetFocusType();677678 // Don't want specialists until we've met our food needs679 if(iSurplusFood < 0)680 {681 return false;682 }683 else if(IsAvoidGrowth() && (eFocusType == NO_CITY_AI_FOCUS_TYPE || eFocusType == CITY_AI_FOCUS_TYPE_GREAT_PEOPLE))684 {685 iWeight *= 2;686 }687 else if(iSurplusFood <= 2)688 {689 iWeight /= 2;690 }691 else if(iSurplusFood > 2)692 {693 if(eFocusType == NO_CITY_AI_FOCUS_TYPE || eFocusType == CITY_AI_FOCUS_TYPE_GREAT_PEOPLE || eFocusType == CITY_AI_FOCUS_TYPE_PROD_GROWTH)694 {695 iWeight *= 100 + (20 * (iSurplusFood - 4));696 iWeight /= 100;697 }698 }699700 // If we're deficient in Production then we're less likely to want Specialists701 if(m_pCity->GetCityStrategyAI()->IsYieldDeficient(YIELD_PRODUCTION))702 {703 iWeight *= 50;704 iWeight /= 100;705 }706 // if we've got some slackers in town (since they provide Production)707 else if(GetNumDefaultSpecialists() > 0 && eFocusType != CITY_AI_FOCUS_TYPE_PRODUCTION && eFocusType != CITY_AI_FOCUS_TYPE_PROD_GROWTH)708 {709 iWeight *= 150;710 iWeight /= 100;711 }712713 // Someone told this AI it should be focused on something that is usually gotten from specialists714 if(eFocusType == CITY_AI_FOCUS_TYPE_GREAT_PEOPLE)715 {716 // Loop through all Buildings717 BuildingTypes eBuilding;718 for(int iBuildingLoop = 0; iBuildingLoop < GC.getNumBuildingInfos(); iBuildingLoop++)719 {720 eBuilding = (BuildingTypes) iBuildingLoop;721722 // Have this Building in the City?723 if(m_pCity->GetCityBuildings()->GetNumBuilding(eBuilding) > 0)724 {725 // Can't add more than the max726 if(IsCanAddSpecialistToBuilding(eBuilding))727 {728 iWeight *= 3;729 break;730 }731 }732 }733 }734 else if(eFocusType == CITY_AI_FOCUS_TYPE_CULTURE)735 {736 // Loop through all Buildings737 for(int iBuildingLoop = 0; iBuildingLoop < GC.getNumBuildingInfos(); iBuildingLoop++)738 {739 const BuildingTypes eBuilding = static_cast<BuildingTypes>(iBuildingLoop);740 CvBuildingEntry* pkBuildingInfo = GC.getBuildingInfo(eBuilding);741 if(pkBuildingInfo)742 {743 // Have this Building in the City?744 if(m_pCity->GetCityBuildings()->GetNumBuilding(eBuilding) > 0)745 {746 // Can't add more than the max747 if(IsCanAddSpecialistToBuilding(eBuilding))748 {749 const SpecialistTypes eSpecialist = (SpecialistTypes) pkBuildingInfo->GetSpecialistType();750 CvSpecialistInfo* pSpecialistInfo = GC.getSpecialistInfo(eSpecialist);751 if(pSpecialistInfo && pSpecialistInfo->getCulturePerTurn() > 0)752 {753 iWeight *= 3;754 break;755 }756 }757 }758 }759 }760 }761 else if(eFocusType == CITY_AI_FOCUS_TYPE_SCIENCE)762 {763 // Loop through all Buildings764 BuildingTypes eBuilding;765 for(int iBuildingLoop = 0; iBuildingLoop < GC.getNumBuildingInfos(); iBuildingLoop++)766 {767 eBuilding = (BuildingTypes) iBuildingLoop;768769 // Have this Building in the City?770 if(m_pCity->GetCityBuildings()->GetNumBuilding(eBuilding) > 0)771 {772 // Can't add more than the max773 if(IsCanAddSpecialistToBuilding(eBuilding))774 {775 SpecialistTypes eSpecialist = (SpecialistTypes) GC.getBuildingInfo(eBuilding)->GetSpecialistType();776 CvSpecialistInfo* pSpecialistInfo = GC.getSpecialistInfo(eSpecialist);777 if(pSpecialistInfo && pSpecialistInfo->getYieldChange(YIELD_SCIENCE) > 0)778 {779 iWeight *= 3;780 }781782 if(GetPlayer()->getSpecialistExtraYield(YIELD_SCIENCE) > 0)783 {784 iWeight *= 3;785 }786787 if(GetPlayer()->GetPlayerTraits()->GetSpecialistYieldChange(eSpecialist, YIELD_SCIENCE) > 0)788 {789 iWeight *= 3;790 }791 792#if defined(MOD_API_UNIFIED_YIELDS)793 if(GetPlayer()->getSpecialistYieldChange(eSpecialist, YIELD_SCIENCE) > 0)794 {795 iWeight *= 3;796 }797798 ReligionTypes eMajority = m_pCity->GetCityReligions()->GetReligiousMajority();799 if(eMajority >= RELIGION_PANTHEON)800 {801 const CvReligion* pReligion = GC.getGame().GetGameReligions()->GetReligion(eMajority, m_pCity->getOwner());802 if(pReligion)803 {804 int iReligionChange = pReligion->m_Beliefs.GetSpecialistYieldChange(eSpecialist, YIELD_SCIENCE);805 BeliefTypes eSecondaryPantheon = m_pCity->GetCityReligions()->GetSecondaryReligionPantheonBelief();806 if (eSecondaryPantheon != NO_BELIEF)807 {808 iReligionChange += GC.GetGameBeliefs()->GetEntry(eSecondaryPantheon)->GetSpecialistYieldChange(eSpecialist, YIELD_SCIENCE);809 }810811 if(iReligionChange > 0)812 {813 iWeight *= 3;814 }815 }816 }817#endif818 }819 }820 }821 }822 else if(eFocusType == CITY_AI_FOCUS_TYPE_PRODUCTION)823 {824 // Loop through all Buildings825 for(int iBuildingLoop = 0; iBuildingLoop < GC.getNumBuildingInfos(); iBuildingLoop++)826 {827 const BuildingTypes eBuilding = static_cast<BuildingTypes>(iBuildingLoop);828 CvBuildingEntry* pkBuildingInfo = GC.getBuildingInfo(eBuilding);829 if(pkBuildingInfo)830 {831 // Have this Building in the City?832 if(m_pCity->GetCityBuildings()->GetNumBuilding(eBuilding) > 0)833 {834 // Can't add more than the max835 if(IsCanAddSpecialistToBuilding(eBuilding))836 {837 SpecialistTypes eSpecialist = (SpecialistTypes) pkBuildingInfo->GetSpecialistType();838 CvSpecialistInfo* pSpecialistInfo = GC.getSpecialistInfo(eSpecialist);839 if(NULL != pSpecialistInfo && pSpecialistInfo->getYieldChange(YIELD_PRODUCTION) > 0)840 {841 iWeight *= 150;842 iWeight /= 100;843 }844845 if(GetPlayer()->getSpecialistExtraYield(YIELD_PRODUCTION) > 0)846 {847 iWeight *= 2;848 }849850 if(GetPlayer()->GetPlayerTraits()->GetSpecialistYieldChange(eSpecialist, YIELD_PRODUCTION) > 0)851 {852 iWeight *= 2;853 }854855#if defined(MOD_API_UNIFIED_YIELDS)856 if(GetPlayer()->getSpecialistYieldChange(eSpecialist, YIELD_PRODUCTION) > 0)857 {858 iWeight *= 2;859 }860861 ReligionTypes eMajority = m_pCity->GetCityReligions()->GetReligiousMajority();862 if(eMajority >= RELIGION_PANTHEON)863 {864 const CvReligion* pReligion = GC.getGame().GetGameReligions()->GetReligion(eMajority, m_pCity->getOwner());865 if(pReligion)866 {867 int iReligionChange = pReligion->m_Beliefs.GetSpecialistYieldChange(eSpecialist, YIELD_PRODUCTION);868 BeliefTypes eSecondaryPantheon = m_pCity->GetCityReligions()->GetSecondaryReligionPantheonBelief();869 if (eSecondaryPantheon != NO_BELIEF)870 {871 iReligionChange += GC.GetGameBeliefs()->GetEntry(eSecondaryPantheon)->GetSpecialistYieldChange(eSpecialist, YIELD_PRODUCTION);872 }873874 if(iReligionChange > 0)875 {876 iWeight *= 2;877 }878 }879 }880#endif881 }882 }883 }884 }885 }886 else if(eFocusType == CITY_AI_FOCUS_TYPE_GOLD)887 {888 // Loop through all Buildings889 BuildingTypes eBuilding;890 for(int iBuildingLoop = 0; iBuildingLoop < GC.getNumBuildingInfos(); iBuildingLoop++)891 {892 eBuilding = (BuildingTypes) iBuildingLoop;893894 // Have this Building in the City?895 if(m_pCity->GetCityBuildings()->GetNumBuilding(eBuilding) > 0)896 {897 // Can't add more than the max898 if(IsCanAddSpecialistToBuilding(eBuilding))899 {900 SpecialistTypes eSpecialist = (SpecialistTypes) GC.getBuildingInfo(eBuilding)->GetSpecialistType();901 CvSpecialistInfo* pSpecialistInfo = GC.getSpecialistInfo(eSpecialist);902 if(pSpecialistInfo && pSpecialistInfo->getYieldChange(YIELD_GOLD) > 0)903 {904 iWeight *= 150;905 iWeight /= 100;906 break;907 }908 }909 }910 }911 }912 else if(eFocusType == CITY_AI_FOCUS_TYPE_FOOD)913 {914 iWeight *= 50;915 iWeight /= 100;916 }917 else if(eFocusType == CITY_AI_FOCUS_TYPE_PROD_GROWTH)918 {919 // Loop through all Buildings920 for(int iBuildingLoop = 0; iBuildingLoop < GC.getNumBuildingInfos(); iBuildingLoop++)921 {922 const BuildingTypes eBuilding = static_cast<BuildingTypes>(iBuildingLoop);923 CvBuildingEntry* pkBuildingInfo = GC.getBuildingInfo(eBuilding);924 if(pkBuildingInfo)925 {926 // Have this Building in the City?927 if(m_pCity->GetCityBuildings()->GetNumBuilding(eBuilding) > 0)928 {929 // Can't add more than the max930 if(IsCanAddSpecialistToBuilding(eBuilding))931 {932 SpecialistTypes eSpecialist = (SpecialistTypes) pkBuildingInfo->GetSpecialistType();933 CvSpecialistInfo* pSpecialistInfo = GC.getSpecialistInfo(eSpecialist);934 if(pSpecialistInfo && pSpecialistInfo->getYieldChange(YIELD_PRODUCTION) > 0)935 {936 iWeight *= 150;937 iWeight /= 100;938 break;939 }940 }941 }942 }943 }944 }945 else if(eFocusType == CITY_AI_FOCUS_TYPE_GOLD_GROWTH)946 {947 // Loop through all Buildings948 for(int iBuildingLoop = 0; iBuildingLoop < GC.getNumBuildingInfos(); iBuildingLoop++)949 {950 const BuildingTypes eBuilding = static_cast<BuildingTypes>(iBuildingLoop);951 CvBuildingEntry* pkBuildingInfo = GC.getBuildingInfo(eBuilding);952 if(pkBuildingInfo)953 {954 // Have this Building in the City?955 if(m_pCity->GetCityBuildings()->GetNumBuilding(eBuilding) > 0)956 {957 // Can't add more than the max958 if(IsCanAddSpecialistToBuilding(eBuilding))959 {960 SpecialistTypes eSpecialist = (SpecialistTypes) pkBuildingInfo->GetSpecialistType();961 CvSpecialistInfo* pSpecialistInfo = GC.getSpecialistInfo(eSpecialist);962 if(pSpecialistInfo && pSpecialistInfo->getYieldChange(YIELD_GOLD) > 0)963 {964 iWeight *= 150;965 iWeight /= 100;966 }967968 if(GetPlayer()->getSpecialistExtraYield(YIELD_GOLD) > 0)969 {970 iWeight *= 2;971 }972973 if(GetPlayer()->GetPlayerTraits()->GetSpecialistYieldChange(eSpecialist, YIELD_GOLD) > 0)974 {975 iWeight *= 2;976 }977978#if defined(MOD_API_UNIFIED_YIELDS)979 if(GetPlayer()->getSpecialistYieldChange(eSpecialist, YIELD_GOLD) > 0)980 {981 iWeight *= 2;982 }983984 ReligionTypes eMajority = m_pCity->GetCityReligions()->GetReligiousMajority();985 if(eMajority >= RELIGION_PANTHEON)986 {987 const CvReligion* pReligion = GC.getGame().GetGameReligions()->GetReligion(eMajority, m_pCity->getOwner());988 if(pReligion)989 {990 int iReligionChange = pReligion->m_Beliefs.GetSpecialistYieldChange(eSpecialist, YIELD_GOLD);991 BeliefTypes eSecondaryPantheon = m_pCity->GetCityReligions()->GetSecondaryReligionPantheonBelief();992 if (eSecondaryPantheon != NO_BELIEF)993 {994 iReligionChange += GC.GetGameBeliefs()->GetEntry(eSecondaryPantheon)->GetSpecialistYieldChange(eSpecialist, YIELD_GOLD);995 }996997 if(iReligionChange > 0)998 {999 iWeight *= 2;1000 }1001 }1002 }1003#endif1004 }1005 }1006 }1007 }1008 }1009 else if(eFocusType == CITY_AI_FOCUS_TYPE_FAITH)1010 {1011 // Loop through all Buildings1012 for(int iBuildingLoop = 0; iBuildingLoop < GC.getNumBuildingInfos(); iBuildingLoop++)1013 {1014 const BuildingTypes eBuilding = (BuildingTypes) iBuildingLoop;1015 CvBuildingEntry* pkBuildingInfo = GC.getBuildingInfo(eBuilding);1016 if(pkBuildingInfo)1017 {1018 // Have this Building in the City?1019 if(m_pCity->GetCityBuildings()->GetNumBuilding(eBuilding) > 0)1020 {1021 // Can't add more than the max1022 if(IsCanAddSpecialistToBuilding(eBuilding))1023 {1024 const SpecialistTypes eSpecialist = (SpecialistTypes) pkBuildingInfo->GetSpecialistType();1025 CvSpecialistInfo* pSpecialistInfo = GC.getSpecialistInfo(eSpecialist);1026 if(pSpecialistInfo && pSpecialistInfo->getYieldChange(YIELD_FAITH) > 0)1027 {1028 iWeight *= 3;1029 break;1030 }1031 }1032 }1033 }1034 }1035 }10361037 // specialists are cheaper somehow1038 if (m_pCity->GetPlayer()->isHalfSpecialistUnhappiness() || m_pCity->GetPlayer()->isHalfSpecialistFood())1039 {1040 iWeight *= 150;1041 iWeight /= 100;1042 }10431044 // Does the AI want it enough?1045 if(iWeight >= 150)1046 {1047 return true;1048 }10491050 return false;1051}