Bazaar developer reference

CvPlot::canBuild(BuildTypes, PlayerTypes, bool, bool) const

Defined in
CvPlot.cpp, line 2464
Class
CvPlot
Hook name
CivHooks::CvPlot_canBuild

Hooks

static bool BeforeCvPlot_canBuild(const CvPlot* self, BuildTypes eBuild, PlayerTypes ePlayer, bool bTestVisible, bool bTestPlotOwner, bool& result);static void AfterCvPlot_canBuild(const CvPlot* self, BuildTypes eBuild, PlayerTypes ePlayer, bool bTestVisible, bool bTestPlotOwner, bool& result);static bool ReplaceCvPlot_canBuild(bool (*original)(const CvPlot*, BuildTypes, PlayerTypes, bool, bool), const CvPlot* self, BuildTypes eBuild, PlayerTypes ePlayer, bool bTestVisible, bool bTestPlotOwner);CivRegisterBefore<CivHooks::CvPlot_canBuild>(host, &BeforeCvPlot_canBuild);CivRegisterAfter<CivHooks::CvPlot_canBuild>(host, &AfterCvPlot_canBuild);CivRegisterReplace<CivHooks::CvPlot_canBuild>(host, &ReplaceCvPlot_canBuild);

Code

2464bool CvPlot::canBuild(BuildTypes eBuild, PlayerTypes ePlayer, bool bTestVisible, bool bTestPlotOwner) const2465{2466	TeamTypes eTeam = GET_PLAYER(ePlayer).getTeam();24672468	ImprovementTypes eImprovement;2469	ImprovementTypes eFinalImprovementType;2470	RouteTypes eRoute;2471	bool bValid;24722473	// Can't build nothing!2474	if(eBuild == NO_BUILD)2475	{2476		return false;2477	}24782479	bValid = false;24802481	// Repairing an Improvement that's been pillaged2482	CvBuildInfo& thisBuildInfo = *GC.getBuildInfo(eBuild);2483	if(thisBuildInfo.isRepair())2484	{2485		if(IsImprovementPillaged() || IsRoutePillaged())2486		{2487			bValid = true;2488		}2489		else2490		{2491			return false;2492		}2493	}24942495	if(thisBuildInfo.IsRemoveRoute())2496	{2497		if(!getPlotCity() && getRouteType() != NO_ROUTE)2498		{2499			if(getOwner() == ePlayer)2500			{2501				bValid = true;2502			}2503			else if(getOwner() == NO_PLAYER && GetPlayerResponsibleForRoute() == ePlayer)2504			{2505				bValid = true;2506			}2507#if defined(MOD_BUGFIX_REMOVE_GHOST_ROUTES)2508			else if(MOD_BUGFIX_REMOVE_GHOST_ROUTES && getOwner() == NO_PLAYER && (GetPlayerResponsibleForRoute() == NO_PLAYER || !GET_PLAYER(GetPlayerResponsibleForRoute()).isAlive()))2509			{2510				bValid = true;2511			}2512#endif2513			else2514			{2515				return false;2516			}2517		}2518		else2519		{2520			return false;2521		}2522	}25232524	eImprovement = ((ImprovementTypes)(thisBuildInfo.getImprovement()));25252526	// Improvement2527	if(eImprovement != NO_IMPROVEMENT)2528	{2529		// Player must be able to build this Improvement2530		if(!canHaveImprovement(eImprovement, eTeam, bTestVisible))2531		{2532			return false;2533		}25342535		// Already an improvement here2536		if(getImprovementType() != NO_IMPROVEMENT)2537		{25382539			if(GC.getImprovementInfo(getImprovementType())->IsPermanent())2540			{2541				return false;2542			}25432544			if(getImprovementType() == eImprovement)2545			{2546				return false;2547			}25482549			eFinalImprovementType = finalImprovementUpgrade(getImprovementType());25502551			if(eFinalImprovementType != NO_IMPROVEMENT)2552			{2553				if(eFinalImprovementType == finalImprovementUpgrade(eImprovement))2554				{2555					if(!IsImprovementPillaged())2556					{2557						return false;2558					}2559				}2560			}2561		}25622563		// Requirements on adjacent plots?2564		if (!bTestVisible)2565		{2566			CvImprovementEntry *pkImprovement = GC.getImprovementInfo(eImprovement);2567			bool bHasLuxuryRequirement = pkImprovement->IsAdjacentLuxury();2568			bool bHasNoAdjacencyRequirement = pkImprovement->IsNoTwoAdjacent();2569			if (pkImprovement && (bHasLuxuryRequirement || bHasNoAdjacencyRequirement))2570			{2571				bool bLuxuryRequirementMet = !bHasLuxuryRequirement;2572				for (int iI = 0; iI < NUM_DIRECTION_TYPES; ++iI)2573				{2574					CvPlot *pAdjacentPlot = plotDirection(getX(), getY(), ((DirectionTypes)iI));2575					if (pAdjacentPlot != NULL)2576					{2577						if (bHasLuxuryRequirement)2578						{2579							ResourceTypes eResource = pAdjacentPlot->getResourceType();2580							if (eResource != NO_RESOURCE)2581							{2582								CvResourceInfo *pkResourceInfo = GC.getResourceInfo(eResource);2583								if (pkResourceInfo && pkResourceInfo->getResourceUsage() == RESOURCEUSAGE_LUXURY)2584								{2585									bLuxuryRequirementMet = true;2586								}2587							}2588						}2589						if (bHasNoAdjacencyRequirement)2590						{2591							ImprovementTypes eAdjacentImprovement =  pAdjacentPlot->getImprovementType();2592							if (eAdjacentImprovement != NO_IMPROVEMENT && eAdjacentImprovement == eImprovement)2593							{2594								return false;2595							}2596							int iBuildProgress = pAdjacentPlot->getBuildProgress(eBuild);2597							if (iBuildProgress > 0)2598							{2599								return false;2600							}2601						}2602					}2603				}2604				if (bHasLuxuryRequirement && !bLuxuryRequirementMet)2605				{2606					return false;2607				}2608			}2609		}26102611		if(!bTestVisible)2612		{2613			if(!GC.getImprovementInfo(eImprovement)->IsIgnoreOwnership())2614			{2615				// Gifts for minors can ignore borders requirements2616				if(bTestPlotOwner)2617				{2618					// Outside Borders - Can be built in or outside our lands, but not in other lands2619					if(GC.getImprovementInfo(eImprovement)->IsOutsideBorders())2620					{2621						if (getTeam() != eTeam && getTeam() != NO_TEAM)2622						{2623							return false;2624						}2625					}2626					// In Adjacent Friendly - Can be built in or adjacent to our lands2627					else if (GC.getImprovementInfo(eImprovement)->IsInAdjacentFriendly())2628					{2629						if (getTeam() != eTeam && !isAdjacentTeam(eTeam, false))2630						{2631							return false;2632						}2633					}2634					// Only City State Territory - Can only be built in City-State territory (not our own lands)2635					else if (GC.getImprovementInfo(eImprovement)->IsOnlyCityStateTerritory())2636					{2637						bool bCityStateTerritory = false;2638						if (isOwned())2639						{2640							if (GET_PLAYER(getOwner()).isMinorCiv())2641							{2642								bCityStateTerritory = true;2643							}2644						}26452646						if (!bCityStateTerritory)2647						{2648							return false;2649						}2650					}2651					else if(getTeam() != eTeam) 2652					{//only buildable in own culture2653						return false;2654					}2655				}2656			}2657		}26582659		bValid = true;2660	}26612662	eRoute = ((RouteTypes)(GC.getBuildInfo(eBuild)->getRoute()));26632664	// Route2665	if(eRoute != NO_ROUTE)2666	{2667		if(getRouteType() != NO_ROUTE)2668		{2669			if (isWater() && !thisBuildInfo.IsWater())2670			{2671				return false;2672			}26732674			CvRouteInfo* pkPlotRoute = GC.getRouteInfo(getRouteType());2675			CvRouteInfo* pkBuildRoute = GC.getRouteInfo(eRoute);2676			if(pkPlotRoute && pkBuildRoute)2677			{2678				// Can't build an older, less useful Route over the top of an existing one2679				if(pkPlotRoute->getValue() >= pkBuildRoute->getValue())2680				{2681					if(!IsRoutePillaged())2682					{2683						return false;2684					}2685				}2686			}2687		}26882689		bValid = true;2690	}26912692	// In general, cannot clear features in the lands of players that aren't on our team or that we're at war with2693	if(getFeatureType() != NO_FEATURE)2694	{2695		if(GC.getBuildInfo(eBuild)->isFeatureRemove(getFeatureType()))2696		{2697			if(bTestPlotOwner)2698			{2699				if(isOwned() && (eTeam != getTeam()) && !atWar(eTeam, getTeam()))2700				{2701					if (eImprovement == NO_IMPROVEMENT)2702					{2703						return false;2704					}27052706					// Some improvements are exceptions2707					if (!GC.getImprovementInfo(eImprovement)->IsIgnoreOwnership() &&2708						!GC.getImprovementInfo(eImprovement)->IsOnlyCityStateTerritory())2709					{2710						return false;2711					}2712				}2713			}27142715			bValid = true;2716		}2717	}27182719	return bValid;2720}

Calls

Called by