Bazaar developer reference

CvPlayer::canConstruct(BuildingTypes, bool, bool, bool, CvString *) const

Defined in
CvPlayer.cpp, line 7957
Class
CvPlayer
Hook name
CivHooks::CvPlayer_canConstruct
Lua events
GameEvents.PlayerCanConstruct

Hooks

static bool BeforeCvPlayer_canConstruct(const CvPlayer* self, BuildingTypes eBuilding, bool bContinue, bool bTestVisible, bool bIgnoreCost, CvString* toolTipSink, bool& result);static void AfterCvPlayer_canConstruct(const CvPlayer* self, BuildingTypes eBuilding, bool bContinue, bool bTestVisible, bool bIgnoreCost, CvString* toolTipSink, bool& result);static bool ReplaceCvPlayer_canConstruct(bool (*original)(const CvPlayer*, BuildingTypes, bool, bool, bool, CvString*), const CvPlayer* self, BuildingTypes eBuilding, bool bContinue, bool bTestVisible, bool bIgnoreCost, CvString* toolTipSink);CivRegisterBefore<CivHooks::CvPlayer_canConstruct>(host, &BeforeCvPlayer_canConstruct);CivRegisterAfter<CivHooks::CvPlayer_canConstruct>(host, &AfterCvPlayer_canConstruct);CivRegisterReplace<CivHooks::CvPlayer_canConstruct>(host, &ReplaceCvPlayer_canConstruct);

Code

7957bool CvPlayer::canConstruct(BuildingTypes eBuilding, bool bContinue, bool bTestVisible, bool bIgnoreCost, CvString* toolTipSink) const7958{7959	CvBuildingEntry* pkBuildingInfo = GC.getBuildingInfo(eBuilding);7960	if(pkBuildingInfo == NULL)7961		return false;79627963	// Don't allow a city to consider an espionage building if they are playing a non-espionage game7964	if(GC.getGame().isOption(GAMEOPTION_NO_ESPIONAGE) && pkBuildingInfo->IsEspionage())7965	{7966		return false;7967	}79687969	CvBuildingEntry& pBuildingInfo = *pkBuildingInfo;79707971	int iI;7972	CvTeam& currentTeam = GET_TEAM(getTeam());79737974	const BuildingClassTypes eBuildingClass = ((BuildingClassTypes)(pBuildingInfo.GetBuildingClassType()));7975	const CvBuildingClassInfo& kBuildingClass = pkBuildingInfo->GetBuildingClassInfo();79767977	// Checks to make sure civilization doesn't have an override that prevents construction of this building7978	if(getCivilizationInfo().getCivilizationBuildings(eBuildingClass) != eBuilding)7979	{7980		return false;7981	}79827983	if(!bIgnoreCost)7984	{7985		if(pBuildingInfo.GetProductionCost() == -1)7986		{7987			return false;7988		}7989	}79907991	PolicyBranchTypes eBranch = (PolicyBranchTypes)pBuildingInfo.GetPolicyBranchType();7992	if (eBranch != NO_POLICY_BRANCH_TYPE)7993	{7994		if (!GetPlayerPolicies()->IsPolicyBranchUnlocked(eBranch))7995		{7996			return false;7997		}7998	}79998000	if(!(currentTeam.GetTeamTechs()->HasTech((TechTypes)(pBuildingInfo.GetPrereqAndTech()))))8001	{8002		return false;8003	}80048005	for(iI = 0; iI < GC.getNUM_BUILDING_AND_TECH_PREREQS(); iI++)8006	{8007		if(pBuildingInfo.GetPrereqAndTechs(iI) != NO_TECH)8008		{8009			if(!(currentTeam.GetTeamTechs()->HasTech((TechTypes)(pBuildingInfo.GetPrereqAndTechs(iI)))))8010			{8011				return false;8012			}8013		}8014	}80158016	if(currentTeam.isObsoleteBuilding(eBuilding))8017	{8018		return false;8019	}80208021	// Building upgrade to another type8022	BuildingClassTypes eReplacementBuildingClass = (BuildingClassTypes) pBuildingInfo.GetReplacementBuildingClass();80238024	if(eReplacementBuildingClass != NO_BUILDINGCLASS)8025	{8026		BuildingTypes eUpgradeBuilding = ((BuildingTypes)(getCivilizationInfo().getCivilizationBuildings(eReplacementBuildingClass)));80278028		if(canConstruct(eUpgradeBuilding))8029		{8030			return false;8031		}8032	}80338034	if(pBuildingInfo.GetVictoryPrereq() != NO_VICTORY)8035	{8036		if(!(GC.getGame().isVictoryValid((VictoryTypes)(pBuildingInfo.GetVictoryPrereq()))))8037		{8038			return false;8039		}80408041		if(isMinorCiv())8042		{8043			return false;8044		}80458046		if(currentTeam.getVictoryCountdown((VictoryTypes)pBuildingInfo.GetVictoryPrereq()) >= 0)8047		{8048			return false;8049		}8050	}80518052	if(pBuildingInfo.GetMaxStartEra() != NO_ERA)8053	{8054		if(GC.getGame().getStartEra() > pBuildingInfo.GetMaxStartEra())8055		{8056			return false;8057		}8058	}80598060	if(GC.getGame().isBuildingClassMaxedOut(eBuildingClass))8061	{8062		return false;8063	}80648065	if(currentTeam.isBuildingClassMaxedOut(eBuildingClass))8066	{8067		return false;8068	}80698070	if(isBuildingClassMaxedOut(eBuildingClass))8071	{8072		return false;8073	}80748075	///////////////////////////////////////////////////////////////////////////////////8076	// Everything above this is what is checked to see if Building shows up in the list of construction items8077	///////////////////////////////////////////////////////////////////////////////////80788079	if(!bTestVisible)8080	{8081		// Num buildings in the empire... uhhh, how is this different from the very last check in this function? (JON: It doesn't appear to be used, but I can't say for sure :)8082		CvCivilizationInfo& civilizationInfo = getCivilizationInfo();8083		int numBuildingClassInfos = GC.getNumBuildingClassInfos();80848085		for(iI = 0; iI < numBuildingClassInfos; iI++)8086		{8087			CvBuildingClassInfo* pkBuildingClassInfo = GC.getBuildingClassInfo((BuildingClassTypes)iI);8088			if(!pkBuildingClassInfo)8089			{8090				continue;8091			}80928093			BuildingTypes ePrereqBuilding = (BuildingTypes)civilizationInfo.getCivilizationBuildings(iI);80948095			if(NO_BUILDING != ePrereqBuilding && currentTeam.isObsoleteBuilding(ePrereqBuilding))8096			{8097				CvBuildingEntry* pkPrereqBuilding = GC.getBuildingInfo(ePrereqBuilding);8098				if(pkPrereqBuilding)8099				{8100					int iNumHave = getBuildingClassCount((BuildingClassTypes)iI);81018102					int iNumNeeded = getBuildingClassPrereqBuilding(eBuilding, (BuildingClassTypes)iI, 0);81038104					if(iNumHave < iNumNeeded)8105					{8106						GC.getGame().BuildCannotPerformActionHelpText(toolTipSink, "TXT_KEY_NO_ACTION_BUILDING_COUNT_NEEDED", pkPrereqBuilding->GetTextKey(), "", iNumNeeded - iNumHave);81078108						if(toolTipSink == NULL)8109							return false;8110					}8111				}8112			}8113		}81148115		// Resource Requirements8116		for(int iResourceLoop = 0; iResourceLoop < GC.getNumResourceInfos(); iResourceLoop++)8117		{8118			const ResourceTypes eResource = static_cast<ResourceTypes>(iResourceLoop);8119			CvResourceInfo* pkResource = GC.getResourceInfo(eResource);8120			if(pkResource)8121			{8122				int iNumResource = pBuildingInfo.GetResourceQuantityRequirement(eResource);8123				if(iNumResource > 0)8124				{8125					if(bContinue)8126						iNumResource = 0;81278128					if(getNumResourceAvailable(eResource) < iNumResource)8129					{8130						GC.getGame().BuildCannotPerformActionHelpText(toolTipSink, "TXT_KEY_NO_ACTION_BUILDING_LACKS_RESOURCES", pkResource->GetIconString(), pkResource->GetTextKey(), iNumResource);8131						if(toolTipSink == NULL)8132							return false;8133					}8134				}8135			}8136		}81378138		if(GC.getGame().isBuildingClassMaxedOut(eBuildingClass, (currentTeam.getBuildingClassMaking(eBuildingClass) + ((bContinue) ? -1 : 0))))8139		{8140			GC.getGame().BuildCannotPerformActionHelpText(toolTipSink, "TXT_KEY_NO_ACTION_GAME_COUNT_MAX", "", "", kBuildingClass.getMaxGlobalInstances());8141			if(toolTipSink == NULL)8142				return false;8143		}81448145		if(currentTeam.isBuildingClassMaxedOut(eBuildingClass, (currentTeam.getBuildingClassMaking(eBuildingClass) + ((bContinue) ? -1 : 0))))8146		{8147			GC.getGame().BuildCannotPerformActionHelpText(toolTipSink, "TXT_KEY_NO_ACTION_TEAM_COUNT_MAX", "", "", kBuildingClass.getMaxTeamInstances());8148			if(toolTipSink == NULL)8149				return false;8150		}81518152		if(isBuildingClassMaxedOut(eBuildingClass, (getBuildingClassMaking(eBuildingClass) + ((bContinue) ? -1 : 0))))8153		{8154			GC.getGame().BuildCannotPerformActionHelpText(toolTipSink, "TXT_KEY_NO_ACTION_PLAYER_COUNT_MAX", "", "", kBuildingClass.getMaxPlayerInstances());8155			if(toolTipSink == NULL)8156				return false;8157		}81588159		if(getNumCities() < pBuildingInfo.GetNumCitiesPrereq())8160		{8161			return false;8162		}81638164		if(getHighestUnitLevel() < pBuildingInfo.GetUnitLevelPrereq())8165		{8166			return false;8167		}81688169		// How does this differ from the check above?8170		BuildingTypes ePrereqBuilding;8171		int iNumNeeded;8172		for(iI = 0; iI < numBuildingClassInfos; iI++)8173		{8174			iNumNeeded = getBuildingClassPrereqBuilding(eBuilding, ((BuildingClassTypes)iI), bContinue);8175			//int iNumHave = getBuildingClassCount((BuildingClassTypes)iI);8176			ePrereqBuilding = (BuildingTypes) civilizationInfo.getCivilizationBuildings(iI);8177			if(NO_BUILDING != ePrereqBuilding)8178			{8179				CvBuildingEntry* pkPrereqBuilding = GC.getBuildingInfo(ePrereqBuilding);8180				if(pkPrereqBuilding)8181				{8182					int iNumHave = 0;8183					const CvCity* pLoopCity = NULL;8184					int iLoop;8185					for(pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))8186					{8187						if(pLoopCity && !pLoopCity->IsPuppet() && pLoopCity->GetCityBuildings()->GetNumBuilding(ePrereqBuilding) > 0)8188						{8189							iNumHave++;8190						}8191					}81928193					if(iNumHave < iNumNeeded)8194					{8195						ePrereqBuilding = (BuildingTypes) civilizationInfo.getCivilizationBuildings(iI);81968197						GC.getGame().BuildCannotPerformActionHelpText(toolTipSink, "TXT_KEY_NO_ACTION_BUILDING_COUNT_NEEDED", pkPrereqBuilding->GetTextKey(), "", iNumNeeded - iNumHave);81988199						if(toolTipSink == NULL)8200							return false;82018202						// If we have less than 5 to go, list what cities need them8203						int iNonPuppetCities = getNumCities() - GetNumPuppetCities();8204						if(iNumNeeded == iNonPuppetCities && iNumNeeded - iNumHave < 5)8205						{8206							(*toolTipSink) += "[NEWLINE]";82078208							for(pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))8209							{8210								if(pLoopCity && !pLoopCity->IsPuppet() && pLoopCity->GetCityBuildings()->GetNumBuilding(ePrereqBuilding) == 0)8211								{8212									(*toolTipSink) += pLoopCity->getName();8213									(*toolTipSink) += " ";8214								}8215							}8216						}8217					}8218				}8219			}8220		}8221	}82228223	ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();8224	if(pkScriptSystem)8225	{8226		CvLuaArgsHandle args;8227		args->Push(GetID());8228		args->Push(eBuilding);82298230		// Attempt to execute the game events.8231		// Will return false if there are no registered listeners.8232		bool bResult = false;8233		if(LuaSupport::CallTestAll(pkScriptSystem, "PlayerCanConstruct", args.get(), bResult))8234		{8235			// Check the result.8236			if(bResult == false)8237			{8238				return false;8239			}8240		}8241	}82428243	return true;8244}

Calls

Called by