Hooks
static bool BeforeCvCity_canConstruct(const CvCity* self, BuildingTypes eBuilding, bool bContinue, bool bTestVisible, bool bIgnoreCost, bool bWillPurchase, CvString* toolTipSink, bool& result);static void AfterCvCity_canConstruct(const CvCity* self, BuildingTypes eBuilding, bool bContinue, bool bTestVisible, bool bIgnoreCost, bool bWillPurchase, CvString* toolTipSink, bool& result);static bool ReplaceCvCity_canConstruct(bool (*original)(const CvCity*, BuildingTypes, bool, bool, bool, bool, CvString*), const CvCity* self, BuildingTypes eBuilding, bool bContinue, bool bTestVisible, bool bIgnoreCost, bool bWillPurchase, CvString* toolTipSink);CivRegisterBefore<CivHooks::CvCity_canConstruct>(host, &BeforeCvCity_canConstruct);CivRegisterAfter<CivHooks::CvCity_canConstruct>(host, &AfterCvCity_canConstruct);CivRegisterReplace<CivHooks::CvCity_canConstruct>(host, &ReplaceCvCity_canConstruct);
Code
2803#if defined(MOD_API_EXTENSIONS)2804bool CvCity::canConstruct(BuildingTypes eBuilding, bool bContinue, bool bTestVisible, bool bIgnoreCost, bool bWillPurchase, CvString* toolTipSink) const2805#else2806bool CvCity::canConstruct(BuildingTypes eBuilding, bool bContinue, bool bTestVisible, bool bIgnoreCost, CvString* toolTipSink) const2807#endif2808{2809 VALIDATE_OBJECT2810 BuildingTypes ePrereqBuilding;2811 int iI;28122813 if(eBuilding == NO_BUILDING)2814 {2815 return false;2816 }28172818 CvBuildingEntry* pkBuildingInfo = GC.getBuildingInfo(eBuilding);2819 if(pkBuildingInfo == NULL)2820 {2821 return false;2822 }28232824 if(!(GET_PLAYER(getOwner()).canConstruct(eBuilding, bContinue, bTestVisible, bIgnoreCost, toolTipSink)))2825 {2826 return false;2827 }28282829#if defined(MOD_API_EXTENSIONS)2830 if (!bWillPurchase && pkBuildingInfo->IsPurchaseOnly())2831 {2832 return false;2833 }2834#endif28352836 if(m_pCityBuildings->GetNumBuilding(eBuilding) >= GC.getCITY_MAX_NUM_BUILDINGS())2837 {2838 return false;2839 }28402841 if(!isValidBuildingLocation(eBuilding))2842 {2843 return false;2844 }28452846 // Local Resource requirements met?2847 if(!IsBuildingLocalResourceValid(eBuilding, bTestVisible, toolTipSink))2848 {2849 return false;2850 }28512852 // Holy city requirement2853 if (pkBuildingInfo->IsRequiresHolyCity() && !GetCityReligions()->IsHolyCityAnyReligion())2854 {2855 return false;2856 }28572858 CvCivilizationInfo& thisCivInfo = *GC.getCivilizationInfo(getCivilizationType());2859 int iNumBuildingClassInfos = GC.getNumBuildingClassInfos();28602861 // Can't construct a building to reduce occupied unhappiness if the city isn't occupied2862 if(pkBuildingInfo->IsNoOccupiedUnhappiness() && !IsOccupied())2863 return false;28642865 // Does this city have prereq buildings?2866 for(iI = 0; iI < iNumBuildingClassInfos; iI++)2867 {2868 CvBuildingClassInfo* pkBuildingClassInfo = GC.getBuildingClassInfo((BuildingClassTypes)iI);2869 if(!pkBuildingClassInfo)2870 {2871 continue;2872 }28732874 if(pkBuildingInfo->IsBuildingClassNeededInCity(iI))2875 {2876 ePrereqBuilding = ((BuildingTypes)(thisCivInfo.getCivilizationBuildings(iI)));28772878 if(ePrereqBuilding != NO_BUILDING)2879 {2880 if(0 == m_pCityBuildings->GetNumBuilding(ePrereqBuilding) /* && (bContinue || (getFirstBuildingOrder(ePrereqBuilding) == -1))*/)2881 {2882 return false;2883 }2884 }2885 }2886 }28872888 ///////////////////////////////////////////////////////////////////////////////////2889 // Everything above this is what is checked to see if Building shows up in the list of construction items2890 ///////////////////////////////////////////////////////////////////////////////////28912892 const CvBuildingClassInfo& kBuildingClassInfo = pkBuildingInfo->GetBuildingClassInfo();2893 if(!bTestVisible)2894 {2895 if(!bContinue)2896 {2897 if(getFirstBuildingOrder(eBuilding) != -1)2898 {2899 return false;2900 }2901 }29022903 if(!(kBuildingClassInfo.isNoLimit()))2904 {2905 if(isWorldWonderClass(kBuildingClassInfo))2906 {2907 if(isWorldWondersMaxed())2908 {2909 return false;2910 }2911 }2912 else if(isTeamWonderClass(kBuildingClassInfo))2913 {2914 if(isTeamWondersMaxed())2915 {2916 return false;2917 }2918 }2919 else if(isNationalWonderClass(kBuildingClassInfo))2920 {2921 if(isNationalWondersMaxed())2922 {2923 return false;2924 }2925 }2926 else2927 {2928 if(isBuildingsMaxed())2929 {2930 return false;2931 }2932 }2933 }2934 }29352936 // Locked Buildings (Mutually Exclusive Buildings?) - not quite sure how this works2937 for(iI = 0; iI < iNumBuildingClassInfos; iI++)2938 {2939 BuildingClassTypes eLockedBuildingClass = (BuildingClassTypes) pkBuildingInfo->GetLockedBuildingClasses(iI);29402941 if(eLockedBuildingClass != NO_BUILDINGCLASS)2942 {2943 BuildingTypes eLockedBuilding = (BuildingTypes)(thisCivInfo.getCivilizationBuildings(eLockedBuildingClass));29442945 if(eLockedBuilding != NO_BUILDING)2946 {2947 if(m_pCityBuildings->GetNumBuilding(eLockedBuilding) > 0)2948 {2949 return false;2950 }2951 }2952 }2953 }29542955 // Mutually Exclusive Buildings 22956 if(pkBuildingInfo->GetMutuallyExclusiveGroup() != -1)2957 {2958 int iNumBuildingInfos = GC.getNumBuildingInfos();2959 for(iI = 0; iI < iNumBuildingInfos; iI++)2960 {2961 const BuildingTypes eBuildingLoop = static_cast<BuildingTypes>(iI);29622963 CvBuildingEntry* pkLoopBuilding = GC.getBuildingInfo(eBuildingLoop);2964 if(pkLoopBuilding)2965 {2966 // Buildings are in a Mutually Exclusive Group, so only one is allowed2967 if(pkLoopBuilding->GetMutuallyExclusiveGroup() == pkBuildingInfo->GetMutuallyExclusiveGroup())2968 {2969 if(m_pCityBuildings->GetNumBuilding(eBuildingLoop) > 0)2970 {2971 return false;2972 }2973 }2974 }2975 }2976 }297729782979 ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();2980 if(pkScriptSystem)2981 {2982 CvLuaArgsHandle args;2983 args->Push(getOwner());2984 args->Push(GetID());2985 args->Push(eBuilding);29862987 // Attempt to execute the game events.2988 // Will return false if there are no registered listeners.2989 bool bResult = false;2990 if(LuaSupport::CallTestAll(pkScriptSystem, "CityCanConstruct", args.get(), bResult))2991 {2992 // Check the result.2993 if(bResult == false)2994 {2995 return false;2996 }2997 }2998 }29993000 return true;3001}