Limiting which cities an auto route transport will go to?

codiac

Chieftain
Joined
Oct 15, 2022
Messages
53
If you have 2 or more cities on the same continent marked to import all goods then your transports happily go all the way across the continent :cry:

I'd like to stop this, but I am not sure which code to change. I'd appreciate some pointers to which functions I'd need to change to get one of the following to work.

  1. A setting to restrict land transports using auto routes to only use roads.
  2. A way to associate an auto route transport to a selected list of cities.
I guess they aren't mutually exclusive and #1 seems simpler, so maybe it's best to start with that.
 
The list of ideas on how to improve trade routes is quite long by now.
  • Classic colo trade routes (so something kind of like OpenTTD)
  • Create lists of colonies and then assign transports to the lists and they will only use the trade routes where both ends are in the list
  • Limited range from current location
  • Limited range from home colony
  • First post here
I likely forgot some proposals. I really want to do the first one at some point, but so far I haven't found time to do so.
 
Heh :)

I thought that since stage coaches are limited to country roads it might be possible to use a similar logic to limit automated transports to roads. A "simple" "quick fix" and a hopefully useful intro to modifying the trade route logic.
 
This seems to do the job, at least in a quick test.

It's missing an option to toggle the behavior; there seems to be several ways top do options and I'm not sure which type would be most appropriate.

Spoiler diff :

Diff:
diff --git a/Project Files/DLLSources/CvUnit.cpp b/Project Files/DLLSources/CvUnit.cpp
index 2764b946..b408995a 100644
--- a/Project Files/DLLSources/CvUnit.cpp   
+++ b/Project Files/DLLSources/CvUnit.cpp   
@@ -3671,6 +3715,30 @@ bool CvUnit::canMoveInto(CvPlot const& kPlot, bool bAttack, bool bDeclareWar, bo
         }
         // R&R, ray, End Logic for Trains
 
+        // Start Automated transports stay on roads
+        if (getUnitInfo().getCargoSpace() >= 1 && getGroup()->getAutomateType() == AUTOMATE_FULL)
+        {
+            // Check if the Plot has road or Ferry Stations or River Ford.
+            if (kPlot.getRouteType() < 0)
+            {
+                const FeatureTypes eFeature = plot()->getFeatureType();
+
+                bool bIsRoadWorthy = kPlot.getTerrainType() == TERRAIN_LARGE_RIVERS &&
+                    (    (eFeature != NO_FEATURE && GC.getFeatureInfo(eFeature).isNoImprovement()) ||
+                        (    kPlot.getImprovementType() != NO_IMPROVEMENT &&
+                            GC.getImprovementInfo(kPlot.getImprovementType()).getTerrainMakesValid(TERRAIN_LARGE_RIVERS) &&
+                            GC.getImprovementInfo(kPlot.getImprovementType()).isOutsideBorders()
+                        )
+                    );
+
+                if (!bIsRoadWorthy)
+                {
+                    return false;
+                }
+            }
+        }
+        // End Automated transports stay on roads
+
         if (kPlot.isWater() && !m_pUnitInfo->isCanMoveAllTerrain())
         {
             if (bIgnoreLoad || plot()->isWater() || !canLoad(&kPlot, false))
 
This seems to do the job, at least in a quick test.

It's missing an option to toggle the behavior; there seems to be several ways top do options and I'm not sure which type would be most appropriate.

Spoiler diff :

Diff:
diff --git a/Project Files/DLLSources/CvUnit.cpp b/Project Files/DLLSources/CvUnit.cpp
index 2764b946..b408995a 100644
--- a/Project Files/DLLSources/CvUnit.cpp   
+++ b/Project Files/DLLSources/CvUnit.cpp   
@@ -3671,6 +3715,30 @@ bool CvUnit::canMoveInto(CvPlot const& kPlot, bool bAttack, bool bDeclareWar, bo
         }
         // R&R, ray, End Logic for Trains
 
+        // Start Automated transports stay on roads
+        if (getUnitInfo().getCargoSpace() >= 1 && getGroup()->getAutomateType() == AUTOMATE_FULL)
+        {
+            // Check if the Plot has road or Ferry Stations or River Ford.
+            if (kPlot.getRouteType() < 0)
+            {
+                const FeatureTypes eFeature = plot()->getFeatureType();
+
+                bool bIsRoadWorthy = kPlot.getTerrainType() == TERRAIN_LARGE_RIVERS &&
+                    (    (eFeature != NO_FEATURE && GC.getFeatureInfo(eFeature).isNoImprovement()) ||
+                        (    kPlot.getImprovementType() != NO_IMPROVEMENT &&
+                            GC.getImprovementInfo(kPlot.getImprovementType()).getTerrainMakesValid(TERRAIN_LARGE_RIVERS) &&
+                            GC.getImprovementInfo(kPlot.getImprovementType()).isOutsideBorders()
+                        )
+                    );
+
+                if (!bIsRoadWorthy)
+                {
+                    return false;
+                }
+            }
+        }
+        // End Automated transports stay on roads
+
         if (kPlot.isWater() && !m_pUnitInfo->isCanMoveAllTerrain())
         {
             if (bIgnoreLoad || plot()->isWater() || !canLoad(&kPlot, false))
I have been thinking about this solution. It has a few flaws, the biggest being it affects the AI, so the AI loses the ability to transport between colonies unless there is a road connection.

I'm thinking I want to revive the plotgroup idea from Medieval Conquest (I made it, so I would be copying myself). Basically it assigns an ID to a route and all routes next to it and next to them and... Eventually all connected routes will have the same ID, meaning if two colonies report the same ID, then they are connected. No pathfinding needed, just a get function, which looks up the ID (an int) for the team in question. This will greatly reduce the CPU load on transport pathfinding and pathfinding is the biggest CPU killer in late game.
 
I have been thinking about this solution. It has a few flaws, the biggest being it affects the AI, so the AI loses the ability to transport between colonies unless there is a road connection.
Aww, I though that AI didn't use `AUTOMATE_FULL`. I'll add `isHuman()` as the first condition.

I'm thinking I want to revive the plotgroup idea from Medieval Conquest (I made it, so I would be copying myself). Basically it assigns an ID to a route and all routes next to it and next to them and... Eventually all connected routes will have the same ID, meaning if two colonies report the same ID, then they are connected. No pathfinding needed, just a get function, which looks up the ID (an int) for the team in question. This will greatly reduce the CPU load on transport pathfinding and pathfinding is the biggest CPU killer in late game.
This sounds interesting.

I don't find the late game processing to be too annoying. I find me having to think about which colony needs what more frustrating. I'm planning a war here people! Surely you can organize your own rum rations and order your own deliveries of stone! :)
 
Top Bottom