diff --git a/CvGameCoreDLLUtil/include/CvEnums.h b/CvGameCoreDLLUtil/include/CvEnums.h index 6500f1ba0f..bb711f9f10 100644 --- a/CvGameCoreDLLUtil/include/CvEnums.h +++ b/CvGameCoreDLLUtil/include/CvEnums.h @@ -3782,7 +3782,8 @@ enum CLOSED_ENUM RoutePurpose PURPOSE_CONNECT_CAPITAL = 1, PURPOSE_SHORTCUT = 2, - PURPOSE_STRATEGIC = 4 + PURPOSE_STRATEGIC = 4, + PURPOSE_MANUAL = 8 }; enum CLOSED_ENUM RoutePlanTypes diff --git a/CvGameCoreDLL_Expansion2/CvAStar.cpp b/CvGameCoreDLL_Expansion2/CvAStar.cpp index e7aeff79ff..84a1ce6ee4 100644 --- a/CvGameCoreDLL_Expansion2/CvAStar.cpp +++ b/CvGameCoreDLL_Expansion2/CvAStar.cpp @@ -2388,6 +2388,7 @@ int BuildRouteValid(const CvAStarNode* parent, const CvAStarNode* node, const SP PlayerTypes ePlayer = data.ePlayer; CvPlayer& kPlayer = GET_PLAYER(ePlayer); bool bThisPlayerIsMinor = kPlayer.isMinorCiv(); + bool bIsManual = data.eRoutePurpose == PURPOSE_MANUAL; //can we build it? RouteTypes eRoute = data.eRoute; @@ -2404,7 +2405,7 @@ int BuildRouteValid(const CvAStarNode* parent, const CvAStarNode* node, const SP if(!pNewPlot->isValidMovePlot(ePlayer) && (!pNewPlot->isMountain() || !kPlayer.IsWorkersIgnoreImpassable())) return FALSE; - if (pNewPlot->GetPlannedRouteState(ePlayer) == ROAD_PLANNING_EXCLUDE && !pNewPlot->isCity()) + if (!bIsManual && pNewPlot->GetPlannedRouteState(ePlayer) == ROAD_PLANNING_EXCLUDE && !pNewPlot->isCity()) return FALSE; PlayerTypes ePlotOwnerPlayer = pNewPlot->getOwner(); @@ -2430,14 +2431,17 @@ int BuildRouteValid(const CvAStarNode* parent, const CvAStarNode* node, const SP } if ((ePlotOwnerPlayer == NO_PLAYER || ePlotOwnerPlayer == ePlayer) && kPlayer.GetSameRouteBenefitFromTrait(pNewPlot, eRoute)) - return true; + return TRUE; //if the plot and its parent are both too far from our borders, don't build here - if (!kPlayer.IsPlotSafeForRoute(pNewPlot, true /*bIncludeAdjacent*/)) + if (!bIsManual) { - CvPlot* pFromPlot = GC.getMap().plotUnchecked(parent->m_iX, parent->m_iY); - if (!kPlayer.IsPlotSafeForRoute(pFromPlot, true /*bIncludeAdjacent*/)) - return FALSE; + if (!kPlayer.IsPlotSafeForRoute(pNewPlot, true /*bIncludeAdjacent*/)) + { + CvPlot* pFromPlot = GC.getMap().plotUnchecked(parent->m_iX, parent->m_iY); + if (!kPlayer.IsPlotSafeForRoute(pFromPlot, true /*bIncludeAdjacent*/)) + return FALSE; + } } return TRUE; diff --git a/CvGameCoreDLL_Expansion2/CvBuilderTaskingAI.cpp b/CvGameCoreDLL_Expansion2/CvBuilderTaskingAI.cpp index c12dcc3922..0addc273f9 100644 --- a/CvGameCoreDLL_Expansion2/CvBuilderTaskingAI.cpp +++ b/CvGameCoreDLL_Expansion2/CvBuilderTaskingAI.cpp @@ -1972,7 +1972,7 @@ vector> CvBuilderTaskingAI::GetImprovementDire } if (pPlot->GetPlannedRouteState(m_pPlayer->GetID()) == ROAD_PLANNING_PRIORITY_CONSTRUCTION) { - AddRouteOrRepairDirective(aDirectives, pPlot, eBestRoute, 1000, NO_ROUTE_PURPOSE); + AddRouteOrRepairDirective(aDirectives, pPlot, eBestRoute, 1000, PURPOSE_MANUAL); } } diff --git a/CvGameCoreDLL_Expansion2/CvCityStrategyAI.cpp b/CvGameCoreDLL_Expansion2/CvCityStrategyAI.cpp index 0859edb2ba..f1fbfb8a1e 100644 --- a/CvGameCoreDLL_Expansion2/CvCityStrategyAI.cpp +++ b/CvGameCoreDLL_Expansion2/CvCityStrategyAI.cpp @@ -2764,7 +2764,7 @@ bool CityStrategyAIHelpers::IsTestCityStrategy_PocketCity(CvCity* pCity) } //could we build a route? - SPathFinderUserData data(pCity->getOwner(), PT_BUILD_ROUTE, NO_BUILD, ROUTE_ANY, NO_ROUTE_PURPOSE, true); + SPathFinderUserData data(pCity->getOwner(), PT_BUILD_ROUTE, NO_BUILD, ROUTE_ANY, PURPOSE_CONNECT_CAPITAL, true); return !GC.GetStepFinder().DoesPathExist(pCapitalCity->getX(), pCapitalCity->getY(), pCity->getX(), pCity->getY(), data); } #endif diff --git a/CvGameCoreDLL_Expansion2/CvUnit.cpp b/CvGameCoreDLL_Expansion2/CvUnit.cpp index f31b403881..182f5112e5 100644 --- a/CvGameCoreDLL_Expansion2/CvUnit.cpp +++ b/CvGameCoreDLL_Expansion2/CvUnit.cpp @@ -13411,7 +13411,7 @@ bool CvUnit::canBuild(const CvPlot* pPlot, BuildTypes eBuild, bool bTestVisible, if(pLoopUnit && pLoopUnit != this) { - if(pLoopUnit->IsWork() && pLoopUnit->getBuildType() != NO_BUILD) + if(pLoopUnit->IsWork() && pLoopUnit->IsWorking()) { return false; } @@ -15619,6 +15619,13 @@ BuildTypes CvUnit::getBuildType() const return NO_BUILD; } +// ---------------------------------------------------------------------------- +bool CvUnit::IsWorking() const +{ + VALIDATE_OBJECT + const MissionData* pkMissionNode = HeadMissionData(); + return pkMissionNode && (pkMissionNode->eMissionType == CvTypes::getMISSION_ROUTE_TO() || pkMissionNode->eMissionType == CvTypes::getMISSION_BUILD()); +} // -------------------------------------------------------------------------------- int CvUnit::workRate(bool bMax, BuildTypes /*eBuild*/) const @@ -29520,7 +29527,7 @@ bool CvUnit::UnitRoadTo(int iX, int iY, int iFlags) //ok apparently we both can move and need to move //do not use the path cache here, the step finder tells us where to put the route - SPathFinderUserData data(getOwner(), PT_BUILD_ROUTE, ePlayerBestRouteBuild, ePlayerBestRoute, NO_ROUTE_PURPOSE, false); + SPathFinderUserData data(getOwner(), PT_BUILD_ROUTE, ePlayerBestRouteBuild, ePlayerBestRoute, PURPOSE_MANUAL, false); SPath path = GC.GetStepFinder().GetPath(getX(), getY(), iX, iY, data); //index zero is the current plot! diff --git a/CvGameCoreDLL_Expansion2/CvUnit.h b/CvGameCoreDLL_Expansion2/CvUnit.h index 00b9b421fa..6787305d0c 100644 --- a/CvGameCoreDLL_Expansion2/CvUnit.h +++ b/CvGameCoreDLL_Expansion2/CvUnit.h @@ -651,6 +651,7 @@ class CvUnit bool canBuildRoute() const; BuildTypes getBuildType() const; + bool IsWorking() const; int workRate(bool bMax, BuildTypes eBuild = NO_BUILD) const; bool isNoBadGoodies() const;