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); }
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(); } }