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}