public static float DaysTo(Map map, Func <Faction, bool> factionValidator)
        {
            int tile = map.Tile;
            Func <WorldObject, bool> woValidator = (wo) =>
                                                   (wo is Settlement || wo is Site s && s.parts.Any(part => part.def == SitePartDefOf.Outpost)) &&
                                                   wo.Faction != null && factionValidator(wo.Faction);
            Predicate <int> validator = (int t) => Find.World.worldObjects.ObjectsAt(t).Any(woValidator);

            Predicate <int> waterValidator = (int t) => Find.World.grid[t].WaterCovered;

            //bool factionBase = false, water = false;
            int foundTile;

            if (!TryFindClosestTile(tile, t => !Find.World.Impassable(t), validator, out foundTile))
            {
                TryFindClosestTile(tile, t => !Find.World.Impassable(t) || waterValidator(t), waterValidator, out foundTile);
            }

            Log.Message($"Closest tile to {map} is {foundTile}:{Find.World.grid[foundTile]}");
            WorldPath path = Find.WorldPathFinder.FindPath(tile, foundTile, null);
            float     cost = 0;

            if (path.Found)
            {
                cost = path.TotalCost;
                Log.Message($"Path cost is {cost}");
                path.ReleaseToPool();
            }
            else
            {
                List <int> neighborTiles = new List <int>();
                Find.World.grid.GetTileNeighbors(foundTile, neighborTiles);
                float bestCost = float.MaxValue;
                foreach (int nTile in neighborTiles)
                {
                    Log.Message($"Looking at neighbor tile {nTile}:{Find.World.grid[nTile]}");
                    path = Find.WorldPathFinder.FindPath(tile, nTile, null);
                    if (path.Found)
                    {
                        bestCost = Math.Min(bestCost, path.TotalCost);
                    }
                    Log.Message($"best cost is {bestCost}");
                    path.ReleaseToPool();
                }
                if (bestCost == float.MaxValue)
                {
                    bestCost = 0;                                            //paranoid?
                }
                cost = bestCost + Mod.settings.islandAddedDays * 40000;
                Log.Message($"cost after added island days: {cost}");
            }

            cost /= 40000;              //Cost to days-ish

            float wealth = map.wealthWatcher.WealthTotal;

            return(AddedDays(cost) * WealthReduction(wealth));
        }
 public bool StartPath(int destTile, CaravanArrivalAction arrivalAction, bool repathImmediately = false, bool resetPauseStatus = true)
 {
     caravan.autoJoinable = false;
     if (resetPauseStatus)
     {
         paused = false;
     }
     if (arrivalAction != null && !arrivalAction.StillValid(caravan, destTile))
     {
         return(false);
     }
     if (!IsPassable(caravan.Tile) && !TryRecoverFromUnwalkablePosition())
     {
         return(false);
     }
     if (moving && curPath != null && this.destTile == destTile)
     {
         this.arrivalAction = arrivalAction;
         return(true);
     }
     if (!WorldVehicleReachability.Instance.CanReach(caravan, destTile))
     {
         PatherFailed();
         return(false);
     }
     this.destTile      = destTile;
     this.arrivalAction = arrivalAction;
     caravan.Notify_DestinationOrPauseStatusChanged();
     if (nextTile < 0 || !IsNextTilePassable())
     {
         nextTile         = caravan.Tile;
         nextTileCostLeft = 0f;
         previousTileForDrawingIfInDoubt = -1;
     }
     if (AtDestinationPosition())
     {
         PatherArrived();
         return(true);
     }
     if (curPath != null)
     {
         curPath.ReleaseToPool();
     }
     curPath = null;
     moving  = true;
     if (repathImmediately && TrySetNewPath() && nextTileCostLeft <= 0f && moving)
     {
         TryEnterNextPathTile();
     }
     return(true);
 }
Example #3
0
 public bool StartPath(int destTile, bool repathImmediately = false, bool resetPauseStatus = true)
 {
     if (resetPauseStatus)
     {
         paused = false;
     }
     if (!IsPassable(warObject.Tile) && !TryRecoverFromUnwalkablePosition())
     {
         return(false);
     }
     if (moving && curPath != null && this.destTile == destTile)
     {
         //this.arrivalAction = arrivalAction;
         return(true);
     }
     if (!Utility.WorldReachability.CanReach(warObject.Tile, destTile))
     {
         PatherFailed();
         return(false);
     }
     this.destTile = destTile;
     if (nextTile < 0 || !IsNextTilePassable())
     {
         nextTile         = warObject.Tile;
         nextTileCostLeft = 0f;
         previousTileForDrawingIfInDoubt = -1;
     }
     if (AtDestinationPosition())
     {
         PatherArrived();
         return(true);
     }
     if (curPath != null)
     {
         curPath.ReleaseToPool();
     }
     curPath = null;
     moving  = true;
     if (repathImmediately && TrySetNewPath() && nextTileCostLeft <= 0f && moving)
     {
         TryEnterNextPathTile();
     }
     return(true);
 }
 private void DrawLinksOnWorld(List <Link> linkFinal, List <int> indexToTile)
 {
     foreach (Link item in linkFinal)
     {
         Link       current       = item;
         WorldPath  worldPath     = Find.WorldPathFinder.FindPath(indexToTile[current.indexA], indexToTile[current.indexB], null);
         List <int> nodesReversed = worldPath.NodesReversed;
         RoadDef    roadDef       = (from rd in DefDatabase <RoadDef> .AllDefsListForReading
                                     where !rd.ancientOnly
                                     select rd).RandomElementWithFallback();
         for (int i = 0; i < nodesReversed.Count - 1; i++)
         {
             Find.WorldGrid.OverlayRoad(nodesReversed[i], nodesReversed[i + 1], roadDef);
         }
         worldPath.ReleaseToPool();
     }
 }