private static void DetermineCaravanTravelTimeFromFaction(Faction faction, Map playerMap) { try { int radius = 60; int playerBase = playerMap.Tile; WorldGrid grid = Find.World.grid; List <Settlement> bases = Find.WorldObjects.SettlementBases.FindAll((settlementBase) => settlementBase.Faction.Name == faction.Name); int closestFactionBase = 0; int ticksToArrive = int.MaxValue; bases.ForEach((fBase) => { if (grid.ApproxDistanceInTiles(playerBase, fBase.Tile) < radius) { int ticks = CaravanArrivalTimeEstimator.EstimatedTicksToArrive( fBase.Tile, playerBase, Find.WorldPathFinder.FindPath(fBase.Tile, playerBase, null), 0f, CaravanTicksPerMoveUtility.DefaultTicksPerMove, GenTicks.TicksAbs ); if (ticks < ticksToArrive) { ticksToArrive = ticks; closestFactionBase = fBase.Tile; } } }); if (closestFactionBase == 0) { Log.Error("Couldn't find faction base within " + radius.ToString() + " tiles"); // Fallback travel time 3.5 days factionTravelTime.Add(faction, Mathf.FloorToInt(3.5f * fullDayInTicks)); return; } factionTravelTime.Add(faction, ticksToArrive); } catch { Log.Error("Error calculating dist to nearest settlement for " + faction.Name + ". Defaulting travel time to 3.5 days"); factionTravelTime.Add(faction, Mathf.FloorToInt(3.5f * fullDayInTicks)); } }
public void searchForSettlements(int startTile, ref List <SettlementInfo> settlementsSearched) { var timer = System.Diagnostics.Stopwatch.StartNew(); WorldGrid worldGrid = Find.WorldGrid; foreach (Settlement s in Find.WorldObjects.Settlements) { if (worldGrid.ApproxDistanceInTiles(startTile, s.Tile) <= maxNeighbourDistance) { int distance = CaravanArrivalTimeEstimator.EstimatedTicksToArrive(startTile, s.Tile, null); if (distance <= maxTicksToNeighbour) { settlementsSearched.Add(new SettlementInfo(s, distance)); } } } timer.Stop(); RoadsOfTheRim.DebugLog("Time spent searching for settlements : " + timer.ElapsedMilliseconds + "ms"); }
public WorldPath FindPath(int startTile, int destTile, VehicleCaravan caravan, Func <float, bool> terminator = null) { if (startTile < 0) { Log.Error(string.Concat(new object[] { "Tried to FindPath with invalid start tile ", startTile, ", caravan= ", caravan })); return(WorldPath.NotFound); } if (destTile < 0) { Log.Error(string.Concat(new object[] { "Tried to FindPath with invalid dest tile ", destTile, ", caravan= ", caravan })); return(WorldPath.NotFound); } if (!WorldVehicleReachability.Instance.CanReach(caravan, destTile)) { return(WorldPath.NotFound); } World world = Find.World; WorldGrid grid = world.grid; List <int> tileIDToNeighbors_offsets = grid.tileIDToNeighbors_offsets; List <int> tileIDToNeighbors_values = grid.tileIDToNeighbors_values; Vector3 normalized = grid.GetTileCenter(destTile).normalized; Dictionary <VehicleDef, float[]> movementDifficulty = WorldVehiclePathGrid.Instance.movementDifficulty; int num = 0; int num2 = (caravan != null) ? caravan.TicksPerMove : 3300; int num3 = CalculateHeuristicStrength(startTile, destTile); statusOpenValue += 2; statusClosedValue += 2; if (statusClosedValue >= 65435) { ResetStatuses(); } calcGrid[startTile].knownCost = 0; calcGrid[startTile].heuristicCost = 0; calcGrid[startTile].costNodeCost = 0; calcGrid[startTile].parentTile = startTile; calcGrid[startTile].status = statusOpenValue; openList.Clear(); openList.Push(new CostNode(startTile, 0)); while (openList.Count > 0) { CostNode costNode = openList.Pop(); if (costNode.cost == calcGrid[costNode.tile].costNodeCost) { int tile = costNode.tile; if (calcGrid[tile].status != statusClosedValue) { if (tile == destTile) { return(FinalizedPath(tile)); } if (num > SearchLimit) { Log.Warning(string.Concat(new object[] { caravan, " pathing from ", startTile, " to ", destTile, " hit search limit of ", SearchLimit, " tiles." })); return(WorldPath.NotFound); } int num4 = (tile + 1 < tileIDToNeighbors_offsets.Count) ? tileIDToNeighbors_offsets[tile + 1] : tileIDToNeighbors_values.Count; for (int i = tileIDToNeighbors_offsets[tile]; i < num4; i++) { int num5 = tileIDToNeighbors_values[i]; if (calcGrid[num5].status != statusClosedValue && caravan.UniqueVehicleDefsInCaravan().All(v => WorldVehiclePathGrid.Instance.Passable(num5, v)) && (!caravan.HasBoat() || !(Find.World.CoastDirectionAt(num5).IsValid&& num5 != destTile))) { float highestTerrainCost = caravan.UniqueVehicleDefsInCaravan().Max(v => movementDifficulty[v][num5]); int num6 = (int)(num2 * highestTerrainCost * VehicleCaravan_PathFollower.GetRoadMovementDifficultyMultiplier(caravan, tile, num5, null)) + calcGrid[tile].knownCost; ushort status = calcGrid[num5].status; if ((status != statusClosedValue && status != statusOpenValue) || calcGrid[num5].knownCost > num6) { Vector3 tileCenter = grid.GetTileCenter(num5); if (status != statusClosedValue && status != statusOpenValue) { float num7 = grid.ApproxDistanceInTiles(GenMath.SphericalDistance(tileCenter.normalized, normalized)); calcGrid[num5].heuristicCost = Mathf.RoundToInt(num2 * num7 * num3 * BestRoadDiscount); } int num8 = num6 + calcGrid[num5].heuristicCost; calcGrid[num5].parentTile = tile; calcGrid[num5].knownCost = num6; calcGrid[num5].status = statusOpenValue; calcGrid[num5].costNodeCost = num8; openList.Push(new CostNode(num5, num8)); } } } num++; calcGrid[tile].status = statusClosedValue; if (terminator != null && terminator(calcGrid[tile].costNodeCost)) { return(WorldPath.NotFound); } } } } Log.Warning(string.Concat(new object[] { caravan, " pathing from ", startTile, " to ", destTile, " ran out of tiles to process." })); return(WorldPath.NotFound); }
private static void CacheAccessibleThings(int nearTile) { if (nearTile == cachedAccessibleThingsForTile && RealTime.frameCount == cachedAccessibleThingsForFrame) { return; } cachedAccessibleThings.Clear(); cachedPossiblyAccessibleThings.Clear(); cachedMakeableItemDefs.Clear(); WorldGrid worldGrid = Find.WorldGrid; List <Map> maps = Find.Maps; for (int i = 0; i < maps.Count; i++) { if (!(worldGrid.ApproxDistanceInTiles(nearTile, maps[i].Tile) > 5f)) { ThingOwnerUtility.GetAllThingsRecursively(maps[i], tmpThings, allowUnreal: false); cachedAccessibleThings.AddRange(tmpThings); } } List <Caravan> caravans = Find.WorldObjects.Caravans; for (int j = 0; j < caravans.Count; j++) { if (caravans[j].IsPlayerControlled && !(worldGrid.ApproxDistanceInTiles(nearTile, caravans[j].Tile) > 5f)) { ThingOwnerUtility.GetAllThingsRecursively(caravans[j], tmpThings, allowUnreal: false); cachedAccessibleThings.AddRange(tmpThings); } } for (int k = 0; k < cachedAccessibleThings.Count; k++) { Thing thing = cachedAccessibleThings[k]; cachedPossiblyAccessibleThings.Add(new ThingDefCount(thing.def, thing.stackCount)); if (GenLeaving.CanBuildingLeaveResources(thing, DestroyMode.Deconstruct)) { List <ThingDefCountClass> list = thing.CostListAdjusted(); for (int l = 0; l < list.Count; l++) { int num = Mathf.RoundToInt((float)list[l].count * thing.def.resourcesFractionWhenDeconstructed); if (num > 0) { cachedPossiblyAccessibleThings.Add(new ThingDefCount(list[l].thingDef, num)); cachedMakeableItemDefs.Add(list[l].thingDef); } } } Plant plant = thing as Plant; if (plant != null && (plant.HarvestableNow || plant.HarvestableSoon)) { int num2 = Mathf.RoundToInt(plant.def.plant.harvestYield * Find.Storyteller.difficultyValues.cropYieldFactor); if (num2 > 0) { cachedPossiblyAccessibleThings.Add(new ThingDefCount(plant.def.plant.harvestedThingDef, num2)); cachedMakeableItemDefs.Add(plant.def.plant.harvestedThingDef); } } if (!thing.def.butcherProducts.NullOrEmpty()) { for (int m = 0; m < thing.def.butcherProducts.Count; m++) { cachedPossiblyAccessibleThings.Add(thing.def.butcherProducts[m]); cachedMakeableItemDefs.Add(thing.def.butcherProducts[m].thingDef); } } Pawn pawn = thing as Pawn; if (pawn != null) { if (pawn.RaceProps.meatDef != null) { int num3 = Mathf.RoundToInt(pawn.GetStatValue(StatDefOf.MeatAmount)); if (num3 > 0) { cachedPossiblyAccessibleThings.Add(new ThingDefCount(pawn.RaceProps.meatDef, num3)); cachedMakeableItemDefs.Add(pawn.RaceProps.meatDef); } } if (pawn.RaceProps.leatherDef != null) { int num4 = GenMath.RoundRandom(pawn.GetStatValue(StatDefOf.LeatherAmount)); if (num4 > 0) { cachedPossiblyAccessibleThings.Add(new ThingDefCount(pawn.RaceProps.leatherDef, num4)); cachedMakeableItemDefs.Add(pawn.RaceProps.leatherDef); } } if (!pawn.RaceProps.Humanlike) { PawnKindLifeStage curKindLifeStage = pawn.ageTracker.CurKindLifeStage; if (curKindLifeStage.butcherBodyPart != null) { cachedPossiblyAccessibleThings.Add(new ThingDefCount(curKindLifeStage.butcherBodyPart.thing, 1)); cachedMakeableItemDefs.Add(curKindLifeStage.butcherBodyPart.thing); } } } if (thing.def.smeltable) { List <ThingDefCountClass> list2 = thing.CostListAdjusted(); for (int n = 0; n < list2.Count; n++) { if (!list2[n].thingDef.intricate) { int num5 = Mathf.RoundToInt((float)list2[n].count * 0.25f); if (num5 > 0) { cachedPossiblyAccessibleThings.Add(new ThingDefCount(list2[n].thingDef, num5)); cachedMakeableItemDefs.Add(list2[n].thingDef); } } } } if (thing.def.smeltable && !thing.def.smeltProducts.NullOrEmpty()) { for (int num6 = 0; num6 < thing.def.smeltProducts.Count; num6++) { cachedPossiblyAccessibleThings.Add(thing.def.smeltProducts[num6]); cachedMakeableItemDefs.Add(thing.def.smeltProducts[num6].thingDef); } } } int num7 = 0; for (int num8 = 0; num8 < cachedAccessibleThings.Count; num8++) { Pawn pawn2 = cachedAccessibleThings[num8] as Pawn; if (pawn2 != null && pawn2.IsFreeColonist && !pawn2.Dead && !pawn2.Downed && pawn2.workSettings.WorkIsActive(WorkTypeDefOf.Crafting)) { num7++; } } if (num7 > 0) { tmpWorkTables.Clear(); for (int num9 = 0; num9 < cachedAccessibleThings.Count; num9++) { Building_WorkTable building_WorkTable = cachedAccessibleThings[num9] as Building_WorkTable; if (building_WorkTable == null || !building_WorkTable.Spawned || !tmpWorkTables.Add(building_WorkTable.def)) { continue; } List <RecipeDef> allRecipes = building_WorkTable.def.AllRecipes; for (int num10 = 0; num10 < allRecipes.Count; num10++) { if (!allRecipes[num10].AvailableNow || !allRecipes[num10].AvailableOnNow(building_WorkTable) || !allRecipes[num10].products.Any() || allRecipes[num10].PotentiallyMissingIngredients(null, building_WorkTable.Map).Any()) { continue; } ThingDef stuffDef = (allRecipes[num10].products[0].thingDef.MadeFromStuff ? GenStuff.DefaultStuffFor(allRecipes[num10].products[0].thingDef) : null); float num11 = allRecipes[num10].WorkAmountTotal(stuffDef); if (num11 <= 0f) { continue; } int num12 = Mathf.FloorToInt((float)(num7 * 60000 * 5) * 0.09f / num11); if (num12 > 0) { for (int num13 = 0; num13 < allRecipes[num10].products.Count; num13++) { cachedPossiblyAccessibleThings.Add(new ThingDefCount(allRecipes[num10].products[num13].thingDef, allRecipes[num10].products[num13].count * num12)); cachedMakeableItemDefs.Add(allRecipes[num10].products[num13].thingDef); } } } } } cachedAccessibleThingsForTile = nearTile; cachedAccessibleThingsForFrame = RealTime.frameCount; }
public WorldPath FindOceanPath(int startTile, int destTile, Caravan caravan, Func <float, bool> terminator = null) { if (startTile < 0) { Log.Error(string.Concat(new object[] { "Tried to FindPath with invalid start tile ", startTile, ", caravan= ", caravan }), false); return(WorldPath.NotFound); } if (destTile < 0) { Log.Error(string.Concat(new object[] { "Tried to FindPath with invalid dest tile ", destTile, ", caravan= ", caravan }), false); return(WorldPath.NotFound); } if (caravan != null) { if (!caravan.CanReach(destTile)) { return(WorldPath.NotFound); } } else if (!Find.WorldReachability.CanReach(startTile, destTile)) { return(WorldPath.NotFound); } World world = Find.World; WorldGrid grid = world.grid; List <int> tileIDToNeighbors_offsets = grid.tileIDToNeighbors_offsets; List <int> tileIDToNeighbors_values = grid.tileIDToNeighbors_values; Vector3 normalized = grid.GetTileCenter(destTile).normalized; float[] movementDifficulty = world.pathGrid.movementDifficulty; int num = 0; int num2 = (caravan != null) ? caravan.TicksPerMove : 3300; int num3 = CalculateHeuristicStrength(startTile, destTile); statusOpenValue += 2; statusClosedValue += 2; if (statusClosedValue >= 65435) { ResetStatuses(); } calcGrid[startTile].knownCost = 0; calcGrid[startTile].heuristicCost = 0; calcGrid[startTile].costNodeCost = 0; calcGrid[startTile].parentTile = startTile; calcGrid[startTile].status = statusOpenValue; openList.Clear(); openList.Push(new CostNode(startTile, 0)); while (openList.Count > 0) { CostNode costNode = openList.Pop(); if (costNode.cost == calcGrid[costNode.tile].costNodeCost) { int tile = costNode.tile; if (calcGrid[tile].status != statusClosedValue) { if (tile == destTile) { return(FinalizedPath(tile)); } if (num > 500000) { Log.Warning(string.Concat(new object[] { caravan, " pathing from ", startTile, " to ", destTile, " hit search limit of ", 500000, " tiles." }), false); return(WorldPath.NotFound); } int num4 = (tile + 1 < tileIDToNeighbors_offsets.Count) ? tileIDToNeighbors_offsets[tile + 1] : tileIDToNeighbors_values.Count; for (int i = tileIDToNeighbors_offsets[tile]; i < num4; i++) { int num5 = tileIDToNeighbors_values[i]; if (calcGrid[num5].status != statusClosedValue && !HelperMethods.ImpassableModified(world, num5, startTile, destTile, caravan)) { int num6 = (int)((float)num2 * movementDifficulty[num5] * grid.GetRoadMovementDifficultyMultiplier(tile, num5, null)) + calcGrid[tile].knownCost; ushort status = calcGrid[num5].status; if ((status != statusClosedValue && status != statusOpenValue) || calcGrid[num5].knownCost > num6) { Vector3 tileCenter = grid.GetTileCenter(num5); if (status != statusClosedValue && status != statusOpenValue) { float num7 = grid.ApproxDistanceInTiles(GenMath.SphericalDistance(tileCenter.normalized, normalized)); calcGrid[num5].heuristicCost = Mathf.RoundToInt((float)num2 * num7 * (float)num3 * 0.5f); } int num8 = num6 + calcGrid[num5].heuristicCost; calcGrid[num5].parentTile = tile; calcGrid[num5].knownCost = num6; calcGrid[num5].status = statusOpenValue; calcGrid[num5].costNodeCost = num8; openList.Push(new CostNode(num5, num8)); } } } num++; calcGrid[tile].status = statusClosedValue; if (terminator != null && terminator((float)calcGrid[tile].costNodeCost)) { return(WorldPath.NotFound); } } } } Log.Warning(string.Concat(new object[] { caravan, " pathing from ", startTile, " to ", destTile, " ran out of tiles to process." }), false); return(WorldPath.NotFound); }
private static void CacheAccessibleThings(int nearTile) { if (nearTile != PlayerItemAccessibilityUtility.cachedAccessibleThingsForTile || RealTime.frameCount != PlayerItemAccessibilityUtility.cachedAccessibleThingsForFrame) { PlayerItemAccessibilityUtility.cachedAccessibleThings.Clear(); PlayerItemAccessibilityUtility.cachedPossiblyAccessibleThings.Clear(); WorldGrid worldGrid = Find.WorldGrid; List <Map> maps = Find.Maps; for (int i = 0; i < maps.Count; i++) { float num = worldGrid.ApproxDistanceInTiles(nearTile, maps[i].Tile); if (num <= 5f) { ThingOwnerUtility.GetAllThingsRecursively(maps[i], PlayerItemAccessibilityUtility.tmpThings, false, null); PlayerItemAccessibilityUtility.cachedAccessibleThings.AddRange(PlayerItemAccessibilityUtility.tmpThings); } } List <Caravan> caravans = Find.WorldObjects.Caravans; for (int j = 0; j < caravans.Count; j++) { if (caravans[j].IsPlayerControlled) { float num2 = worldGrid.ApproxDistanceInTiles(nearTile, caravans[j].Tile); if (num2 <= 5f) { ThingOwnerUtility.GetAllThingsRecursively(caravans[j], PlayerItemAccessibilityUtility.tmpThings, false, null); PlayerItemAccessibilityUtility.cachedAccessibleThings.AddRange(PlayerItemAccessibilityUtility.tmpThings); } } } for (int k = 0; k < PlayerItemAccessibilityUtility.cachedAccessibleThings.Count; k++) { Thing thing = PlayerItemAccessibilityUtility.cachedAccessibleThings[k]; PlayerItemAccessibilityUtility.cachedPossiblyAccessibleThings.Add(new ThingDefCount(thing.def, thing.stackCount)); if (GenLeaving.CanBuildingLeaveResources(thing, DestroyMode.Deconstruct)) { List <ThingDefCountClass> list = thing.CostListAdjusted(); for (int l = 0; l < list.Count; l++) { int num3 = Mathf.RoundToInt((float)list[l].count * thing.def.resourcesFractionWhenDeconstructed); if (num3 > 0) { PlayerItemAccessibilityUtility.cachedPossiblyAccessibleThings.Add(new ThingDefCount(list[l].thingDef, num3)); } } } Plant plant = thing as Plant; if (plant != null) { if (plant.HarvestableNow || plant.HarvestableSoon) { int num4 = Mathf.RoundToInt(plant.def.plant.harvestYield * Find.Storyteller.difficulty.cropYieldFactor); if (num4 > 0) { PlayerItemAccessibilityUtility.cachedPossiblyAccessibleThings.Add(new ThingDefCount(plant.def.plant.harvestedThingDef, num4)); } } } if (!thing.def.butcherProducts.NullOrEmpty <ThingDefCountClass>()) { for (int m = 0; m < thing.def.butcherProducts.Count; m++) { PlayerItemAccessibilityUtility.cachedPossiblyAccessibleThings.Add(thing.def.butcherProducts[m]); } } Pawn pawn = thing as Pawn; if (pawn != null) { if (pawn.RaceProps.meatDef != null) { int num5 = Mathf.RoundToInt(pawn.GetStatValue(StatDefOf.MeatAmount, true)); if (num5 > 0) { PlayerItemAccessibilityUtility.cachedPossiblyAccessibleThings.Add(new ThingDefCount(pawn.RaceProps.meatDef, num5)); } } if (pawn.RaceProps.leatherDef != null) { int num6 = GenMath.RoundRandom(pawn.GetStatValue(StatDefOf.LeatherAmount, true)); if (num6 > 0) { PlayerItemAccessibilityUtility.cachedPossiblyAccessibleThings.Add(new ThingDefCount(pawn.RaceProps.leatherDef, num6)); } } if (!pawn.RaceProps.Humanlike) { PawnKindLifeStage curKindLifeStage = pawn.ageTracker.CurKindLifeStage; if (curKindLifeStage.butcherBodyPart != null) { PlayerItemAccessibilityUtility.cachedPossiblyAccessibleThings.Add(new ThingDefCount(curKindLifeStage.butcherBodyPart.thing, 1)); } } } if (thing.def.smeltable) { List <ThingDefCountClass> list2 = thing.CostListAdjusted(); for (int n = 0; n < list2.Count; n++) { if (!list2[n].thingDef.intricate) { int num7 = Mathf.RoundToInt((float)list2[n].count * 0.25f); if (num7 > 0) { PlayerItemAccessibilityUtility.cachedPossiblyAccessibleThings.Add(new ThingDefCount(list2[n].thingDef, num7)); } } } } if (thing.def.smeltable && !thing.def.smeltProducts.NullOrEmpty <ThingDefCountClass>()) { for (int num8 = 0; num8 < thing.def.smeltProducts.Count; num8++) { PlayerItemAccessibilityUtility.cachedPossiblyAccessibleThings.Add(thing.def.smeltProducts[num8]); } } } int num9 = 0; for (int num10 = 0; num10 < PlayerItemAccessibilityUtility.cachedAccessibleThings.Count; num10++) { Pawn pawn2 = PlayerItemAccessibilityUtility.cachedAccessibleThings[num10] as Pawn; if (pawn2 != null && pawn2.IsFreeColonist && !pawn2.Dead && !pawn2.Downed && pawn2.workSettings.WorkIsActive(WorkTypeDefOf.Crafting)) { num9++; } } if (num9 > 0) { PlayerItemAccessibilityUtility.tmpWorkTables.Clear(); for (int num11 = 0; num11 < PlayerItemAccessibilityUtility.cachedAccessibleThings.Count; num11++) { Building_WorkTable building_WorkTable = PlayerItemAccessibilityUtility.cachedAccessibleThings[num11] as Building_WorkTable; if (building_WorkTable != null && building_WorkTable.Spawned && PlayerItemAccessibilityUtility.tmpWorkTables.Add(building_WorkTable.def)) { List <RecipeDef> allRecipes = building_WorkTable.def.AllRecipes; for (int num12 = 0; num12 < allRecipes.Count; num12++) { if (allRecipes[num12].AvailableNow) { if (allRecipes[num12].products.Any <ThingDefCountClass>()) { if (!allRecipes[num12].PotentiallyMissingIngredients(null, building_WorkTable.Map).Any <ThingDef>()) { ThingDef stuffDef = (!allRecipes[num12].products[0].thingDef.MadeFromStuff) ? null : GenStuff.DefaultStuffFor(allRecipes[num12].products[0].thingDef); float num13 = allRecipes[num12].WorkAmountTotal(stuffDef); if (num13 > 0f) { int num14 = Mathf.FloorToInt((float)(num9 * 60000 * 5) * 0.09f / num13); if (num14 > 0) { for (int num15 = 0; num15 < allRecipes[num12].products.Count; num15++) { PlayerItemAccessibilityUtility.cachedPossiblyAccessibleThings.Add(new ThingDefCount(allRecipes[num12].products[num15].thingDef, allRecipes[num12].products[num15].count * num14)); } } } } } } } } } } PlayerItemAccessibilityUtility.cachedAccessibleThingsForTile = nearTile; PlayerItemAccessibilityUtility.cachedAccessibleThingsForFrame = RealTime.frameCount; } }
public WorldPath FindPath(int startTile, int destTile, object requester, int ticksPerMove = -1, Func <float, bool> terminator = null) { if (startTile < 0) { Log.Error(string.Concat(new object[] { "Tried to FindPath with invalid start tile ", startTile, ", caravan= ", requester.ToString() }), false); return(WorldPath.NotFound); } if (destTile < 0) { Log.Error(string.Concat(new object[] { "Tried to FindPath with invalid dest tile ", destTile, ", caravan= ", requester.ToString() }), false); return(WorldPath.NotFound); } World world = Find.World; WorldGrid grid = world.grid; List <int> tileIDToNeighbors_offsets = grid.tileIDToNeighbors_offsets; List <int> tileIDToNeighbors_values = grid.tileIDToNeighbors_values; Vector3 normalized = grid.GetTileCenter(destTile).normalized; int num = 0; int num2 = (ticksPerMove < 1) ? 3300 : ticksPerMove; int num3 = this.CalculateHeuristicStrength(startTile, destTile); this.statusOpenValue += 2; this.statusClosedValue += 2; if (this.statusClosedValue >= 65435) { this.ResetStatuses(); } this.calcGrid[startTile].knownCost = 0; this.calcGrid[startTile].heuristicCost = 0; this.calcGrid[startTile].costNodeCost = 0; this.calcGrid[startTile].parentTile = startTile; this.calcGrid[startTile].status = this.statusOpenValue; this.openList.Clear(); this.openList.Push(new WorldShipPathFinder.CostNode(startTile, 0)); while (this.openList.Count > 0) { WorldShipPathFinder.CostNode costNode = this.openList.Pop(); if (costNode.cost == this.calcGrid[costNode.tile].costNodeCost) { int tile = costNode.tile; if (this.calcGrid[tile].status != this.statusClosedValue) { if (DebugViewSettings.drawPaths) { Find.WorldDebugDrawer.FlashTile(tile, (float)this.calcGrid[tile].knownCost / 375000f, this.calcGrid[tile].knownCost.ToString(), 50); } if (tile == destTile) { return(this.FinalizedPath(tile)); } if (num > 500000) { Log.Warning(string.Concat(new object[] { requester.ToString(), " pathing from ", startTile, " to ", destTile, " hit search limit of ", 500000, " tiles." }), false); return(WorldPath.NotFound); } int num4 = (tile + 1 >= tileIDToNeighbors_offsets.Count) ? tileIDToNeighbors_values.Count : tileIDToNeighbors_offsets[tile + 1]; for (int i = tileIDToNeighbors_offsets[tile]; i < num4; i++) { int num5 = tileIDToNeighbors_values[i]; if (this.calcGrid[num5].status != this.statusClosedValue) { int num6 = (int)((float)num2);// * movementDifficulty[num5] * grid.GetRoadMovementDifficultyMultiplier(tile, num5, null)); int num7 = num6 + this.calcGrid[tile].knownCost; ushort status = this.calcGrid[num5].status; if ((status != this.statusClosedValue && status != this.statusOpenValue) || this.calcGrid[num5].knownCost > num7) { Vector3 tileCenter = grid.GetTileCenter(num5); if (status != this.statusClosedValue && status != this.statusOpenValue) { float num8 = grid.ApproxDistanceInTiles(GenMath.SphericalDistance(tileCenter.normalized, normalized)); this.calcGrid[num5].heuristicCost = Mathf.RoundToInt((float)num2 * num8 * (float)num3 * 0.5f); } int num9 = num7 + this.calcGrid[num5].heuristicCost; this.calcGrid[num5].parentTile = tile; this.calcGrid[num5].knownCost = num7; this.calcGrid[num5].status = this.statusOpenValue; this.calcGrid[num5].costNodeCost = num9; this.openList.Push(new WorldShipPathFinder.CostNode(num5, num9)); } } } num++; this.calcGrid[tile].status = this.statusClosedValue; if (terminator != null && terminator((float)this.calcGrid[tile].costNodeCost)) { return(WorldPath.NotFound); } } } } Log.Warning(string.Concat(new object[] { requester.ToString(), " pathing from ", startTile, " to ", destTile, " ran out of tiles to process." }), false); return(WorldPath.NotFound); }