示例#1
0
 public static ICostSymbol CreateEntry(
     ISymbol containingSymbol,
     CostNode item,
     DiagnosticBag diagnostics)
 {
     return(new CostSymbol(containingSymbol, item, diagnostics));
 }
    public static void AddCost(Cost cost, Entity entity)
    {
        CostNode node = new CostNode(cost, entity, TimeController.TimeInMinutes + 60);
        costs.Enqueue(node, node.TimeInMinutes);

        // also add to cost per hour
        costPerHour += cost.costPerHour;
    }
    public static void AddCost(Cost cost, Entity entity)
    {
        CostNode node = new CostNode(cost, entity, TimeController.TimeInMinutes + 60);

        costs.Enqueue(node, node.TimeInMinutes);

        // also add to cost per hour
        costPerHour += cost.costPerHour;
    }
示例#4
0
 private void DebugDrawRichData()
 {
     if (DebugViewSettings.drawPaths)
     {
         while (this.openList.Count > 0)
         {
             CostNode costNode = this.openList.Pop();
             int      index    = costNode.index;
             IntVec3  c        = new IntVec3(index % this.mapSizeX, 0, index / this.mapSizeX);
             this.map.debugDrawer.FlashCell(c, 0f, "open", 50);
         }
     }
 }
    /*
     *	Update costs by going through costs items, retrieving minPriority (lowest time)
     *	and checking if that time has arrived yet.
     *	If so, dequeue, subtract hourly cost, and put back in queue
     */
    void UpdateCost()
    {
        if (costs.Count > 0)
        {
            if (costs.First.TimeInMinutes <= TimeController.TimeInMinutes)
            {
                // dequeue and subtract cost
                CostNode costNode = costs.Dequeue();
                money -= costNode.CostPerHour;

                // reset time in minutes for next hour and enqueue
                costNode.TimeInMinutes = TimeController.TimeInMinutes + 60;
                costs.Enqueue(costNode, costNode.TimeInMinutes);
            }
        }
    }
示例#6
0
        public void FloodPathsWithCost(List <int> startTiles, Func <int, int, int> costFunc, Func <int, bool> impassable = null, Func <int, float, bool> terminator = null)
        {
            if (startTiles.Count < 1 || startTiles.Contains(-1))
            {
                Log.Error("Tried to FindPath with invalid start tiles", false);
                return;
            }
            World      world = Find.World;
            WorldGrid  grid  = world.grid;
            List <int> tileIDToNeighbors_offsets = grid.tileIDToNeighbors_offsets;
            List <int> tileIDToNeighbors_values  = grid.tileIDToNeighbors_values;

            if (impassable == null)
            {
                impassable = ((int tid) => world.Impassable(tid));
            }
            statusOpenValue   += 2;
            statusClosedValue += 2;
            if (statusClosedValue >= 65435)
            {
                ResetStatuses();
            }
            openList.Clear();
            using (List <int> .Enumerator enumerator = startTiles.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    int num = enumerator.Current;
                    calcGrid[num].knownCost    = 0;
                    calcGrid[num].costNodeCost = 0;
                    calcGrid[num].parentTile   = num;
                    calcGrid[num].status       = statusOpenValue;
                    openList.Push(new CostNode(num, 0));
                }
                goto IL_2F2;
            }
IL_127:
            CostNode costNode = openList.Pop();

            if (costNode.cost == calcGrid[costNode.tile].costNodeCost)
            {
                int tile = costNode.tile;
                if (calcGrid[tile].status != statusClosedValue)
                {
                    int num2 = (tile + 1 < tileIDToNeighbors_offsets.Count) ? tileIDToNeighbors_offsets[tile + 1] : tileIDToNeighbors_values.Count;
                    for (int i = tileIDToNeighbors_offsets[tile]; i < num2; i++)
                    {
                        int num3 = tileIDToNeighbors_values[i];
                        if (calcGrid[num3].status != statusClosedValue && !impassable(num3))
                        {
                            int    num4   = costFunc(tile, num3) + calcGrid[tile].knownCost;
                            ushort status = calcGrid[num3].status;
                            if ((status != statusClosedValue && status != statusOpenValue) || calcGrid[num3].knownCost > num4)
                            {
                                int num5 = num4;
                                calcGrid[num3].parentTile   = tile;
                                calcGrid[num3].knownCost    = num4;
                                calcGrid[num3].status       = this.statusOpenValue;
                                calcGrid[num3].costNodeCost = num5;
                                openList.Push(new CostNode(num3, num5));
                            }
                        }
                    }
                    calcGrid[tile].status = statusClosedValue;
                    if (terminator != null && terminator(tile, (float)calcGrid[tile].costNodeCost))
                    {
                        return;
                    }
                }
            }
IL_2F2:
            if (openList.Count > 0)
            {
                goto IL_127;
            }
        }
示例#7
0
        public WorldPath FindPath(int startTile, int destTile, Caravan caravan, Func <float, bool> terminator = null)
        {
            if (startTile < 0)
            {
                Log.Error("Tried to FindPath with invalid start tile " + startTile + ", caravan= " + caravan);
                return(WorldPath.NotFound);
            }
            if (destTile < 0)
            {
                Log.Error("Tried to FindPath with invalid dest tile " + destTile + ", caravan= " + caravan);
                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?.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 (true)
            {
                if (openList.Count <= 0)
                {
                    Log.Warning(caravan + " pathing from " + startTile + " to " + destTile + " ran out of tiles to process.");
                    return(WorldPath.NotFound);
                }
                CostNode costNode = openList.Pop();
                if (costNode.cost != calcGrid[costNode.tile].costNodeCost)
                {
                    continue;
                }
                int tile = costNode.tile;
                if (calcGrid[tile].status == statusClosedValue)
                {
                    continue;
                }
                if (tile == destTile)
                {
                    return(FinalizedPath(tile));
                }
                if (num > 500000)
                {
                    Log.Warning(caravan + " pathing from " + startTile + " to " + destTile + " hit search limit of " + 500000 + " 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 || world.Impassable(num5))
                    {
                        continue;
                    }
                    int    num6   = (int)((float)num2 * movementDifficulty[num5] * grid.GetRoadMovementDifficultyMultiplier(tile, num5)) + 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(calcGrid[tile].costNodeCost))
                {
                    break;
                }
            }
            return(WorldPath.NotFound);
        }
示例#8
0
        public (PawnPath path, bool found) FindVehiclePath(IntVec3 start, LocalTargetInfo dest, TraverseParms traverseParms, CancellationToken token, PathEndMode peMode = PathEndMode.OnCell, bool waterPathing = false)
        {
            if (report)
            {
                Debug.Message($"{VehicleHarmony.LogLabel} MainPath for {traverseParms.pawn.LabelShort} - ThreadId: [{Thread.CurrentThread.ManagedThreadId}] TaskId: [{Task.CurrentId}]");
            }

            postCalculatedCells.Clear();
            VehicleMapping VehicleMapping = map.GetCachedMapComponent <VehicleMapping>();

            if (DebugSettings.pathThroughWalls)
            {
                traverseParms.mode = TraverseMode.PassAllDestroyableThings;
            }
            VehiclePawn pawn = traverseParms.pawn as VehiclePawn;

            if (!pawn.IsBoat() && waterPathing)
            {
                Log.Error($"Set to waterPathing but {pawn.LabelShort} is not registered as a Boat. Self Correcting...");
                waterPathing = false;
            }
            if (!(pawn is null) && pawn.Map != map)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to FindVehiclePath for pawn which is spawned in another map. Their map PathFinder should  have been used, not this one. " +
                    "pawn=", pawn,
                    " pawn.Map=", pawn.Map,
                    " map=", map
                }));
                return(PawnPath.NotFound, false);
            }
            if (!start.IsValid)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to FindShipPath with invalid start ",
                    start,
                    ", pawn=", pawn
                }));
                return(PawnPath.NotFound, false);
            }
            if (!dest.IsValid)
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to FindPath with invalid dest ",
                    dest,
                    ", pawn= ",
                    pawn
                }));
                return(PawnPath.NotFound, false);
            }
            if (traverseParms.mode == TraverseMode.ByPawn)
            {
                if (waterPathing)
                {
                    if (!ShipReachabilityUtility.CanReachShip(pawn, dest, peMode, Danger.Deadly, false, traverseParms.mode))
                    {
                        return(PawnPath.NotFound, false);
                    }
                }
                else
                {
                    if (!ReachabilityUtility.CanReach(pawn, dest, peMode, Danger.Deadly, false, traverseParms.mode))
                    {
                        return(PawnPath.NotFound, false);
                    }
                }
            }
            else
            {
                if (waterPathing)
                {
                    if (!VehicleMapping.VehicleReachability.CanReachShip(start, dest, peMode, traverseParms))
                    {
                        return(PawnPath.NotFound, false);
                    }
                }
                else
                {
                    if (!map.reachability.CanReach(start, dest, peMode, traverseParms))
                    {
                        return(PawnPath.NotFound, false);
                    }
                }
            }
            cellIndices = map.cellIndices;

            VehiclePathGrid  = VehicleMapping.VehiclePathGrid;
            pathGrid         = map.pathGrid;
            this.edificeGrid = map.edificeGrid.InnerArray;
            blueprintGrid    = map.blueprintGrid.InnerArray;
            int      x        = dest.Cell.x;
            int      z        = dest.Cell.z;
            int      num      = cellIndices.CellToIndex(start);
            int      num2     = cellIndices.CellToIndex(dest.Cell);
            ByteGrid byteGrid = (pawn is null) ? null : pawn.GetAvoidGrid(true);
            bool     flag     = traverseParms.mode == TraverseMode.PassAllDestroyableThings || traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater;
            bool     flag2    = traverseParms.mode != TraverseMode.NoPassClosedDoorsOrWater && traverseParms.mode != TraverseMode.PassAllDestroyableThingsNotWater;
            bool     flag3    = !flag;
            CellRect cellRect = CalculateDestinationRect(dest, peMode);
            bool     flag4    = cellRect.Width == 1 && cellRect.Height == 1;

            int[]        boatsArray   = VehiclePathGrid.pathGrid;
            int[]        vehicleArray = pathGrid.pathGrid;
            TerrainDef[] topGrid      = map.terrainGrid.topGrid;
            EdificeGrid  edificeGrid  = map.edificeGrid;
            int          num3         = 0;
            int          num4         = 0;
            Area         allowedArea  = GetAllowedArea(pawn);
            bool         flag5        = !(pawn is null) && PawnUtility.ShouldCollideWithPawns(pawn);
            bool         flag6        = true && DebugViewSettings.drawPaths;
            bool         flag7        = !flag && !(VehicleGridsUtility.GetRegion(start, map, RegionType.Set_Passable) is null) && flag2;
            bool         flag8        = !flag || !flag3;
            bool         flag9        = false;
            bool         flag10       = !(pawn is null) && pawn.Drafted;
            bool         flag11       = !(pawn is null) && !(pawn is null);

            int   num5  = (!flag11) ? NodesToOpenBeforeRegionbasedPathing_NonShip : NodesToOpenBeforeRegionBasedPathing_Ship;
            int   num6  = 0;
            int   num7  = 0;
            float num8  = DetermineHeuristicStrength(pawn, start, dest);
            int   num9  = !(pawn is null) ? pawn.TicksPerMoveCardinal : DefaultMoveTicksCardinal;
            int   num10 = !(pawn is null) ? pawn.TicksPerMoveDiagonal : DefaultMoveTicksDiagonal;

            CalculateAndAddDisallowedCorners(traverseParms, peMode, cellRect);
            InitStatusesAndPushStartNode(ref num, start);
            Rot8 rot        = pawn.FullRotation;
            int  iterations = 0;

            for (;;)
            {
                if (token.IsCancellationRequested)
                {
                    return(PawnPath.NotFound, false);
                }

                iterations++;
                if (openList.Count <= 0)
                {
                    break;
                }
                num6 += openList.Count;
                num7++;
                CostNode costNode = openList.Pop();
                num = costNode.index;
                if (costNode.cost == calcGrid[num].costNodeCost && calcGrid[num].status != statusClosedValue)
                {
                    IntVec3 c        = cellIndices.IndexToCell(num);
                    IntVec3 prevCell = c;
                    int     x2       = c.x;
                    int     z2       = c.z;
                    if (flag6)
                    {
                        DebugFlash(c, calcGrid[num].knownCost / 1500f, calcGrid[num].knownCost.ToString());
                    }
                    if (flag4)
                    {
                        if (num == num2)
                        {
                            goto Block_32;
                        }
                    }
                    else if (cellRect.Contains(c) && !disallowedCornerIndices.Contains(num))
                    {
                        goto Block_32;
                    }
                    if (num3 > SearchLimit)
                    {
                        goto Block_33;
                    }

                    List <IntVec3> fullRectCells = CellRect.CenteredOn(c, pawn.def.size.x, pawn.def.size.z).Where(cl2 => cl2 != c).ToList();

                    for (int i = 0; i < 8; i++)
                    {
                        uint num11 = (uint)(x2 + Directions[i]);                           //x
                        uint num12 = (uint)(z2 + Directions[i + 8]);                       //y

                        if (num11 < ((ulong)mapSizeX) && num12 < (ulong)(mapSizeZ))
                        {
                            int num13 = (int)num11;
                            int num14 = (int)num12;
                            int num15 = cellIndices.CellToIndex(num13, num14);

                            IntVec3 cellToCheck = cellIndices.IndexToCell(num15);
                            if (VehicleMod.settings.main.fullVehiclePathing && pawn.LocationRestrictedBySize(cellToCheck))
                            {
                                goto EndPathing;
                            }

                            if (calcGrid[num15].status != statusClosedValue || flag9)
                            {
                                int  num16  = 0;
                                bool flag12 = false;                                 //Extra cost for traversing water

                                if (flag2 || !new IntVec3(num13, 0, num14).GetTerrain(map).HasTag("Water"))
                                {
                                    if (waterPathing)
                                    {
                                        if (!pawn.DrivableFast(num15))
                                        {
                                            if (!flag)
                                            {
                                                if (flag6)
                                                {
                                                    DebugFlash(new IntVec3(num13, 0, num14), 0.22f, "walk");
                                                }
                                                goto EndPathing;
                                            }

                                            num16 += 70;
                                            Building building = edificeGrid[num15];
                                            if (building is null)
                                            {
                                                goto EndPathing;
                                            }
                                            if (!IsDestroyable(building))
                                            {
                                                goto EndPathing;
                                            }
                                            num16 += (int)(building.HitPoints * 0.2f);
                                        }
                                    }
                                    else
                                    {
                                        if (!pawn.DrivableFast(num15))
                                        {
                                            if (!flag)
                                            {
                                                if (flag6)
                                                {
                                                    DebugFlash(new IntVec3(num13, 0, num14), 0.22f, "walk");
                                                }
                                                goto EndPathing;
                                            }
                                            flag12 = true;
                                            num16 += 70;
                                            Building building = edificeGrid[num15];
                                            if (building is null)
                                            {
                                                goto EndPathing;
                                            }
                                            if (!IsDestroyable(building))
                                            {
                                                goto EndPathing;
                                            }
                                            num16 += (int)(building.HitPoints * 0.2f);
                                        }
                                    }

                                    if (i > 3)
                                    {
                                        switch (i)
                                        {
                                        case 4:
                                            if (BlocksDiagonalMovement(pawn, num - mapSizeX))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2, 0, z2 - 1), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            if (BlocksDiagonalMovement(pawn, num + 1))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2 + 1, 0, z2), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            break;

                                        case 5:
                                            if (BlocksDiagonalMovement(pawn, num + mapSizeX))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2, 0, z2 + 1), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            if (BlocksDiagonalMovement(pawn, num + 1))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2 + 1, 0, z2), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            break;

                                        case 6:
                                            if (BlocksDiagonalMovement(pawn, num + mapSizeX))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2, 0, z2 + 1), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            if (BlocksDiagonalMovement(pawn, num - 1))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2 - 1, 0, z2), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            break;

                                        case 7:
                                            if (BlocksDiagonalMovement(pawn, num - mapSizeX))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2, 0, z2 - 1), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            if (BlocksDiagonalMovement(pawn, num - 1))
                                            {
                                                if (flag8)
                                                {
                                                    if (flag6)
                                                    {
                                                        DebugFlash(new IntVec3(x2 - 1, 0, z2), 0.9f, "ships");
                                                    }
                                                    goto EndPathing;
                                                }
                                                num16 += 70;
                                            }
                                            break;
                                        }
                                    }
                                    int num17 = (i <= 3) ? num9 : num10;
                                    num17 += num16;
                                    //if (Rot8.DirectionFromCells(prevCell, cellToCheck) != rot)
                                    //{
                                    //    Log.Message("Additional Cost");
                                    //    num17 += ChangeDirectionAdditionalCost;
                                    //}
                                    if (!flag12 && !waterPathing)
                                    {
                                        //Extra Terrain costs
                                        if (pawn.VehicleDef.properties.customTerrainCosts?.NotNullAndAny() ?? false)
                                        {
                                            TerrainDef currentTerrain = map.terrainGrid.TerrainAt(num15);
                                            if (pawn.VehicleDef.properties.customTerrainCosts.ContainsKey(currentTerrain))
                                            {
                                                int customCost = pawn.VehicleDef.properties.customTerrainCosts[currentTerrain];
                                                if (customCost < 0)
                                                {
                                                    goto EndPathing;
                                                }
                                                num17 += customCost;
                                            }
                                            else
                                            {
                                                num17 += vehicleArray[num15];
                                            }
                                        }
                                        else
                                        {
                                            num17 += vehicleArray[num15];
                                        }
                                        num17 += flag10 ? topGrid[num15].extraDraftedPerceivedPathCost : topGrid[num15].extraNonDraftedPerceivedPathCost;
                                    }
                                    if (byteGrid != null)
                                    {
                                        num17 += (byteGrid[num15] * 8);
                                    }
                                    //Allowed area cost?
                                    if (flag5 && MultithreadHelper.AnyVehicleBlockingPathAt(new IntVec3(num13, 0, num14), pawn, false, false, true) != null)
                                    {
                                        num17 += Cost_PawnCollision;
                                    }
                                    Building building2 = edificeGrid[num15];
                                    if (!(building2 is null))
                                    {
                                        //Building Costs Here
                                    }
                                    if (blueprintGrid[num15] != null)
                                    {
                                        List <Blueprint> list = new List <Blueprint>(blueprintGrid[num15]);
                                        if (!list.NullOrEmpty())
                                        {
                                            int num18 = 0;
                                            foreach (Blueprint bp in list)
                                            {
                                                num18 = Mathf.Max(num18, GetBlueprintCost(bp, pawn));
                                            }
                                            if (num18 == int.MaxValue)
                                            {
                                                goto EndPathing;
                                            }
                                            num17 += num18;
                                        }
                                    }

                                    int    num19  = num17 + calcGrid[num].knownCost;
                                    ushort status = calcGrid[num15].status;

                                    //if(pawn.Props.useFullHitboxPathing)
                                    //{
                                    //    foreach(IntVec3 fullRect in fullRectCells)
                                    //    {
                                    //        if(fullRect != cellToCheck)
                                    //        {
                                    //            num19 += calcGrid[cellIndices.CellToIndex(fullRect)].knownCost;
                                    //            Log.Message($"Cell: {fullRect} Cost: {num19}");
                                    //            if(postCalculatedCells.ContainsKey(fullRect))
                                    //            {
                                    //                postCalculatedCells[fullRect] = num19;
                                    //            }
                                    //            else
                                    //            {
                                    //                postCalculatedCells.Add(fullRect, num19);
                                    //            }
                                    //        }
                                    //    }
                                    //}

                                    //Only generate path costs for linear non-reverse pathing check
                                    if (report)
                                    {
                                        if (postCalculatedCells.ContainsKey(cellToCheck))
                                        {
                                            postCalculatedCells[cellToCheck] = num19;
                                        }
                                        else
                                        {
                                            postCalculatedCells.Add(cellToCheck, num19);
                                        }
                                    }

                                    if (waterPathing && !map.terrainGrid.TerrainAt(num15).IsWater)
                                    {
                                        num19 += 10000;
                                    }
                                    if (status == statusClosedValue || status == statusOpenValue)
                                    {
                                        int num20 = 0;
                                        if (status == statusClosedValue)
                                        {
                                            num20 = num9;
                                        }
                                        if (calcGrid[num15].knownCost <= num19 + num20)
                                        {
                                            goto EndPathing;
                                        }
                                    }
                                    if (flag9)
                                    {
                                        calcGrid[num15].heuristicCost = waterPathing ? Mathf.RoundToInt(regionCostCalculatorSea.GetPathCostFromDestToRegion(num15) *
                                                                                                        RegionheuristicWeighByNodesOpened.Evaluate(num4)) : Mathf.RoundToInt(regionCostCalculatorLand.GetPathCostFromDestToRegion(num15) *
                                                                                                                                                                             RegionheuristicWeighByNodesOpened.Evaluate(num4));
                                        if (calcGrid[num15].heuristicCost < 0)
                                        {
                                            Log.ErrorOnce(string.Concat(new object[]
                                            {
                                                "Heuristic cost overflow for vehicle ", pawn.ToStringSafe <Pawn>(),
                                                " pathing from ", start,
                                                " to ", dest, "."
                                            }), pawn.GetHashCode() ^ 193840009);
                                            calcGrid[num15].heuristicCost = 0;
                                        }
                                    }
                                    else if (status != statusClosedValue && status != statusOpenValue)
                                    {
                                        int dx    = Math.Abs(num13 - x);
                                        int dz    = Math.Abs(num14 - z);
                                        int num21 = GenMath.OctileDistance(dx, dz, num9, num10);
                                        calcGrid[num15].heuristicCost = Mathf.RoundToInt((float)num21 * num8);
                                    }
                                    int num22 = num19 + calcGrid[num15].heuristicCost;
                                    if (num22 < 0)
                                    {
                                        Log.ErrorOnce(string.Concat(new object[]
                                        {
                                            "Node cost overflow for ship ", pawn.ToStringSafe <Pawn>(),
                                            " pathing from ", start,
                                            " to ", dest, "."
                                        }), pawn.GetHashCode() ^ 87865822);
                                        num22 = 0;
                                    }
                                    calcGrid[num15].parentIndex  = num;
                                    calcGrid[num15].knownCost    = num19;
                                    calcGrid[num15].status       = statusOpenValue;
                                    calcGrid[num15].costNodeCost = num22;
                                    num4++;
                                    rot = Rot8.DirectionFromCells(prevCell, cellToCheck);
                                    openList.Push(new CostNode(num15, num22));
                                }
                            }
                        }
                        EndPathing :;
                    }
                    num3++;
                    calcGrid[num].status = statusClosedValue;
                    if (num4 >= num5 && flag7 && !flag9)
                    {
                        flag9 = true;
                        if (waterPathing)
                        {
                            regionCostCalculatorSea.Init(cellRect, traverseParms, num9, num10, byteGrid, allowedArea, flag10, disallowedCornerIndices);
                        }
                        else
                        {
                            regionCostCalculatorLand.Init(cellRect, traverseParms, num9, num10, byteGrid, allowedArea, flag10, disallowedCornerIndices);
                        }

                        InitStatusesAndPushStartNode(ref num, start);
                        num4 = 0;
                        num3 = 0;
                    }
                }
            }
            string text  = ((pawn is null) || pawn.CurJob is null) ? "null" : pawn.CurJob.ToString();
            string text2 = ((pawn is null) || pawn.Faction is null) ? "null" : pawn.Faction.ToString();

            if (report)
            {
                Log.Warning(string.Concat(new object[]
                {
                    "ship pawn: ", pawn, " pathing from ", start,
                    " to ", dest, " ran out of cells to process.\nJob:", text,
                    "\nFaction: ", text2,
                    "\niterations: ", iterations
                }));
            }
            DebugDrawRichData();
            return(PawnPath.NotFound, false);

Block_32:
            PawnPath result = PawnPath.NotFound;

            if (report)
            {
                result = FinalizedPath(num, flag9);
            }
            DebugDrawPathCost();
            return(result, true);

Block_33:
            Log.Warning(string.Concat(new object[]
            {
                "Ship ", pawn, " pathing from ", start,
                " to ", dest, " hit search limit of ", SearchLimit, " cells."
            }));
            DebugDrawRichData();
            return(PawnPath.NotFound, false);
        }
        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);
        }
示例#10
0
        public void FloodPathsWithCost(List <int> startTiles, Func <int, int, int> costFunc, Func <int, bool> impassable = null, Func <int, float, bool> terminator = null)
        {
            if (startTiles.Count < 1 || startTiles.Contains(-1))
            {
                Log.Error("Tried to FindPath with invalid start tiles");
                return;
            }
            World      world = Find.World;
            WorldGrid  grid  = world.grid;
            List <int> tileIDToNeighbors_offsets = grid.tileIDToNeighbors_offsets;
            List <int> tileIDToNeighbors_values  = grid.tileIDToNeighbors_values;

            if (impassable == null)
            {
                impassable = ((int tid) => world.Impassable(tid));
            }
            statusOpenValue   += 2;
            statusClosedValue += 2;
            if (statusClosedValue >= 65435)
            {
                ResetStatuses();
            }
            openList.Clear();
            foreach (int startTile in startTiles)
            {
                calcGrid[startTile].knownCost    = 0;
                calcGrid[startTile].costNodeCost = 0;
                calcGrid[startTile].parentTile   = startTile;
                calcGrid[startTile].status       = statusOpenValue;
                openList.Push(new CostNode(startTile, 0));
            }
            while (openList.Count > 0)
            {
                CostNode costNode = openList.Pop();
                if (costNode.cost != calcGrid[costNode.tile].costNodeCost)
                {
                    continue;
                }
                int tile = costNode.tile;
                if (calcGrid[tile].status == statusClosedValue)
                {
                    continue;
                }
                int num = (tile + 1 < tileIDToNeighbors_offsets.Count) ? tileIDToNeighbors_offsets[tile + 1] : tileIDToNeighbors_values.Count;
                for (int i = tileIDToNeighbors_offsets[tile]; i < num; i++)
                {
                    int num2 = tileIDToNeighbors_values[i];
                    if (calcGrid[num2].status != statusClosedValue && !impassable(num2))
                    {
                        int    num3   = costFunc(tile, num2) + calcGrid[tile].knownCost;
                        ushort status = calcGrid[num2].status;
                        if ((status != statusClosedValue && status != statusOpenValue) || calcGrid[num2].knownCost > num3)
                        {
                            int num4 = num3;
                            calcGrid[num2].parentTile   = tile;
                            calcGrid[num2].knownCost    = num3;
                            calcGrid[num2].status       = statusOpenValue;
                            calcGrid[num2].costNodeCost = num4;
                            openList.Push(new CostNode(num2, num4));
                        }
                    }
                }
                calcGrid[tile].status = statusClosedValue;
                if (terminator != null && terminator(tile, calcGrid[tile].costNodeCost))
                {
                    break;
                }
            }
        }
示例#11
0
        public PawnPath FindPath(IntVec3 start, LocalTargetInfo dest, TraverseParms traverseParms, PathEndMode peMode = PathEndMode.OnCell)
        {
            if (DebugSettings.pathThroughWalls)
            {
                traverseParms.mode = TraverseMode.PassAllDestroyableThings;
            }
            Pawn pawn = traverseParms.pawn;

            if (pawn != null && pawn.Map != this.map)
            {
                Log.Error("Tried to FindPath for pawn which is spawned in another map. His map PathFinder should have been used, not this one. pawn=" + pawn + " pawn.Map=" + pawn.Map + " map=" + this.map);
                return(PawnPath.NotFound);
            }
            if (!start.IsValid)
            {
                Log.Error("Tried to FindPath with invalid start " + start + ", pawn= " + pawn);
                return(PawnPath.NotFound);
            }
            if (!dest.IsValid)
            {
                Log.Error("Tried to FindPath with invalid dest " + dest + ", pawn= " + pawn);
                return(PawnPath.NotFound);
            }
            if (traverseParms.mode == TraverseMode.ByPawn)
            {
                if (!pawn.CanReach(dest, peMode, Danger.Deadly, traverseParms.canBash, traverseParms.mode))
                {
                    return(PawnPath.NotFound);
                }
            }
            else if (!this.map.reachability.CanReach(start, dest, peMode, traverseParms))
            {
                return(PawnPath.NotFound);
            }
            this.PfProfilerBeginSample("FindPath for " + pawn + " from " + start + " to " + dest + ((!dest.HasThing) ? string.Empty : (" at " + dest.Cell)));
            this.cellIndices = this.map.cellIndices;
            this.pathGrid    = this.map.pathGrid;
            this.edificeGrid = this.map.edificeGrid.InnerArray;
            IntVec3  cell     = dest.Cell;
            int      x        = cell.x;
            IntVec3  cell2    = dest.Cell;
            int      z        = cell2.z;
            int      num      = this.cellIndices.CellToIndex(start);
            int      num2     = this.cellIndices.CellToIndex(dest.Cell);
            ByteGrid byteGrid = (pawn == null) ? null : pawn.GetAvoidGrid();
            bool     flag     = traverseParms.mode == TraverseMode.PassAllDestroyableThings;
            bool     flag2    = traverseParms.mode != TraverseMode.NoPassClosedDoorsOrWater && traverseParms.mode != TraverseMode.PassAllDestroyableThingsNotWater;
            bool     flag3    = !flag;
            CellRect cellRect = this.CalculateDestinationRect(dest, peMode);
            bool     flag4    = cellRect.Width == 1 && cellRect.Height == 1;

            int[]       array       = this.map.pathGrid.pathGrid;
            EdificeGrid edificeGrid = this.map.edificeGrid;
            int         num3        = 0;
            int         num4        = 0;
            Area        allowedArea = this.GetAllowedArea(pawn);
            bool        flag5       = pawn != null && PawnUtility.ShouldCollideWithPawns(pawn);
            bool        flag6       = true && DebugViewSettings.drawPaths;
            bool        flag7       = !flag && start.GetRegion(this.map, RegionType.Set_Passable) != null;
            bool        flag8       = !flag || !flag3;
            bool        flag9       = false;
            int         num5        = 0;
            int         num6        = 0;
            float       num7        = this.DetermineHeuristicStrength(pawn, start, dest);
            int         num8;
            int         num9;

            if (pawn != null)
            {
                num8 = pawn.TicksPerMoveCardinal;
                num9 = pawn.TicksPerMoveDiagonal;
            }
            else
            {
                num8 = 13;
                num9 = 18;
            }
            this.CalculateAndAddDisallowedCorners(traverseParms, peMode, cellRect);
            this.InitStatusesAndPushStartNode(ref num, start);
            while (true)
            {
                this.PfProfilerBeginSample("Open cell");
                if (this.openList.Count <= 0)
                {
                    string text  = (pawn == null || pawn.CurJob == null) ? "null" : pawn.CurJob.ToString();
                    string text2 = (pawn == null || pawn.Faction == null) ? "null" : pawn.Faction.ToString();
                    Log.Warning(pawn + " pathing from " + start + " to " + dest + " ran out of cells to process.\nJob:" + text + "\nFaction: " + text2);
                    this.DebugDrawRichData();
                    this.PfProfilerEndSample();
                    return(PawnPath.NotFound);
                }
                num5 += this.openList.Count;
                num6++;
                CostNode costNode = this.openList.Pop();
                num = costNode.index;
                if (costNode.cost != this.calcGrid[num].costNodeCost)
                {
                    this.PfProfilerEndSample();
                    continue;
                }
                if (this.calcGrid[num].status == this.statusClosedValue)
                {
                    this.PfProfilerEndSample();
                    continue;
                }
                IntVec3 c  = this.cellIndices.IndexToCell(num);
                int     x2 = c.x;
                int     z2 = c.z;
                if (flag6)
                {
                    this.DebugFlash(c, (float)((float)this.calcGrid[num].knownCost / 1500.0), this.calcGrid[num].knownCost.ToString());
                }
                if (flag4)
                {
                    if (num == num2)
                    {
                        this.PfProfilerEndSample();
                        PawnPath result = this.FinalizedPath(num);
                        this.PfProfilerEndSample();
                        return(result);
                    }
                }
                else if (cellRect.Contains(c) && !this.disallowedCornerIndices.Contains(num))
                {
                    this.PfProfilerEndSample();
                    PawnPath result2 = this.FinalizedPath(num);
                    this.PfProfilerEndSample();
                    return(result2);
                }
                if (num3 <= 160000)
                {
                    this.PfProfilerEndSample();
                    this.PfProfilerBeginSample("Neighbor consideration");
                    for (int i = 0; i < 8; i++)
                    {
                        uint num10 = (uint)(x2 + PathFinder.Directions[i]);
                        uint num11 = (uint)(z2 + PathFinder.Directions[i + 8]);
                        int  num12;
                        int  num13;
                        int  num14;
                        bool flag10;
                        int  num15;
                        if (num10 < this.mapSizeX && num11 < this.mapSizeZ)
                        {
                            num12 = (int)num10;
                            num13 = (int)num11;
                            num14 = this.cellIndices.CellToIndex(num12, num13);
                            if (this.calcGrid[num14].status == this.statusClosedValue && !flag9)
                            {
                                continue;
                            }
                            num15  = 0;
                            flag10 = false;
                            if (!flag2 && new IntVec3(num12, 0, num13).GetTerrain(this.map).HasTag("Water"))
                            {
                                continue;
                            }
                            if (!this.pathGrid.WalkableFast(num14))
                            {
                                if (!flag)
                                {
                                    if (flag6)
                                    {
                                        this.DebugFlash(new IntVec3(num12, 0, num13), 0.22f, "walk");
                                    }
                                }
                                else
                                {
                                    flag10 = true;
                                    num15 += 70;
                                    Building building = edificeGrid[num14];
                                    if (building != null && PathFinder.IsDestroyable(building))
                                    {
                                        num15 += (int)((float)building.HitPoints * 0.10999999940395355);
                                        goto IL_0749;
                                    }
                                }
                                continue;
                            }
                            goto IL_0749;
                        }
                        continue;
IL_092b:
                        if (this.BlocksDiagonalMovement(num - this.mapSizeX))
                        {
                            if (flag8)
                            {
                                if (flag6)
                                {
                                    this.DebugFlash(new IntVec3(x2, 0, z2 - 1), 0.9f, "corn");
                                }
                                continue;
                            }
                            num15 += 70;
                        }
                        if (this.BlocksDiagonalMovement(num - 1))
                        {
                            if (flag8)
                            {
                                if (flag6)
                                {
                                    this.DebugFlash(new IntVec3(x2 - 1, 0, z2), 0.9f, "corn");
                                }
                                continue;
                            }
                            num15 += 70;
                        }
                        goto IL_09bf;
IL_0b0e:
                        ushort status;
                        if (status != this.statusClosedValue && status != this.statusOpenValue)
                        {
                            if (flag9)
                            {
                                this.calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)this.regionCostCalculator.GetPathCostFromDestToRegion(num14) * PathFinder.RegionHeuristicWeightByNodesOpened.Evaluate((float)num4));
                            }
                            else
                            {
                                int dx    = Math.Abs(num12 - x);
                                int dz    = Math.Abs(num13 - z);
                                int num16 = GenMath.OctileDistance(dx, dz, num8, num9);
                                this.calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)num16 * num7);
                            }
                        }
                        int num17;
                        int num18 = num17 + this.calcGrid[num14].heuristicCost;
                        this.calcGrid[num14].parentIndex  = num;
                        this.calcGrid[num14].knownCost    = num17;
                        this.calcGrid[num14].status       = this.statusOpenValue;
                        this.calcGrid[num14].costNodeCost = num18;
                        num4++;
                        this.openList.Push(new CostNode(num14, num18));
                        continue;
IL_0803:
                        if (this.BlocksDiagonalMovement(num + this.mapSizeX))
                        {
                            if (flag8)
                            {
                                if (flag6)
                                {
                                    this.DebugFlash(new IntVec3(x2, 0, z2 + 1), 0.9f, "corn");
                                }
                                continue;
                            }
                            num15 += 70;
                        }
                        if (this.BlocksDiagonalMovement(num + 1))
                        {
                            if (flag8)
                            {
                                if (flag6)
                                {
                                    this.DebugFlash(new IntVec3(x2 + 1, 0, z2), 0.9f, "corn");
                                }
                                continue;
                            }
                            num15 += 70;
                        }
                        goto IL_09bf;
IL_09bf:
                        int num19 = (i <= 3) ? num8 : num9;
                        num19    += num15;
                        if (!flag10)
                        {
                            num19 += array[num14];
                        }
                        if (byteGrid != null)
                        {
                            num19 += byteGrid[num14] * 8;
                        }
                        if (allowedArea != null && !allowedArea[num14])
                        {
                            num19 += 600;
                        }
                        if (flag5 && PawnUtility.AnyPawnBlockingPathAt(new IntVec3(num12, 0, num13), pawn, false, false))
                        {
                            num19 += 175;
                        }
                        Building building2 = this.edificeGrid[num14];
                        if (building2 != null)
                        {
                            this.PfProfilerBeginSample("Edifices");
                            int buildingCost = PathFinder.GetBuildingCost(building2, traverseParms, pawn);
                            if (buildingCost == 2147483647)
                            {
                                this.PfProfilerEndSample();
                                continue;
                            }
                            num19 += buildingCost;
                            this.PfProfilerEndSample();
                        }
                        num17  = num19 + this.calcGrid[num].knownCost;
                        status = this.calcGrid[num14].status;
                        if (status != this.statusClosedValue && status != this.statusOpenValue)
                        {
                            goto IL_0b0e;
                        }
                        int num20 = 0;
                        if (status == this.statusClosedValue)
                        {
                            num20 = num8;
                        }
                        if (this.calcGrid[num14].knownCost > num17 + num20)
                        {
                            goto IL_0b0e;
                        }
                        continue;
IL_0897:
                        if (this.BlocksDiagonalMovement(num + this.mapSizeX))
                        {
                            if (flag8)
                            {
                                if (flag6)
                                {
                                    this.DebugFlash(new IntVec3(x2, 0, z2 + 1), 0.9f, "corn");
                                }
                                continue;
                            }
                            num15 += 70;
                        }
                        if (this.BlocksDiagonalMovement(num - 1))
                        {
                            if (flag8)
                            {
                                if (flag6)
                                {
                                    this.DebugFlash(new IntVec3(x2 - 1, 0, z2), 0.9f, "corn");
                                }
                                continue;
                            }
                            num15 += 70;
                        }
                        goto IL_09bf;
IL_0749:
                        switch (i)
                        {
                        case 4:
                            break;

                        case 5:
                            goto IL_0803;

                        case 6:
                            goto IL_0897;

                        case 7:
                            goto IL_092b;

                        default:
                            goto IL_09bf;
                        }
                        if (this.BlocksDiagonalMovement(num - this.mapSizeX))
                        {
                            if (flag8)
                            {
                                if (flag6)
                                {
                                    this.DebugFlash(new IntVec3(x2, 0, z2 - 1), 0.9f, "corn");
                                }
                                continue;
                            }
                            num15 += 70;
                        }
                        if (this.BlocksDiagonalMovement(num + 1))
                        {
                            if (flag8)
                            {
                                if (flag6)
                                {
                                    this.DebugFlash(new IntVec3(x2 + 1, 0, z2), 0.9f, "corn");
                                }
                                continue;
                            }
                            num15 += 70;
                        }
                        goto IL_09bf;
                    }
                    this.PfProfilerEndSample();
                    num3++;
                    this.calcGrid[num].status = this.statusClosedValue;
                    if (num4 >= 2000 && flag7 && !flag9)
                    {
                        flag9 = true;
                        this.regionCostCalculator.Init(cellRect, traverseParms, num8, num9, byteGrid, allowedArea, this.disallowedCornerIndices);
                        this.InitStatusesAndPushStartNode(ref num, start);
                        num4 = 0;
                        num3 = 0;
                    }
                    continue;
                }
                break;
            }
            Log.Warning(pawn + " pathing from " + start + " to " + dest + " hit search limit of " + 160000 + " cells.");
            this.DebugDrawRichData();
            this.PfProfilerEndSample();
            return(PawnPath.NotFound);
        }
示例#12
0
        /// <summary>
        /// Find route which contains target node.
        /// </summary>
        /// <param name="targetNode">Node to find.</param>
        /// <returns>NodeRoute.</returns>
        public NodeRoute FindRoute(CostNode targetNode)
        {
            foreach (NodeRoute route in _nodeRoutes)
            {
                foreach (CostNode node in route.CostNodes)
                {
                    if (node == targetNode)
                    {
                        return route;
                    }
                }
            }

            return null;
        }
示例#13
0
        public void FloodPathsWithCost(List <int> startTiles, Func <int, int, int> costFunc, Func <int, bool> impassable = null, Func <int, float, bool> terminator = null)
        {
            if (startTiles.Count < 1 || startTiles.Contains(-1))
            {
                Log.Error("Tried to FindPath with invalid start tiles");
            }
            else
            {
                World      world = Find.World;
                WorldGrid  grid  = world.grid;
                List <int> tileIDToNeighbors_offsets = grid.tileIDToNeighbors_offsets;
                List <int> tileIDToNeighbors_values  = grid.tileIDToNeighbors_values;
                if (impassable == null)
                {
                    impassable = ((int tid) => world.Impassable(tid));
                }
                this.statusOpenValue   += 2;
                this.statusClosedValue += 2;
                if (this.statusClosedValue >= 65435)
                {
                    this.ResetStatuses();
                }
                this.openList.Clear();
                foreach (int startTile in startTiles)
                {
                    this.calcGrid[startTile].knownCost    = 0;
                    this.calcGrid[startTile].costNodeCost = 0;
                    this.calcGrid[startTile].parentTile   = startTile;
                    this.calcGrid[startTile].status       = this.statusOpenValue;
                    this.openList.Push(new CostNode(startTile, 0));
                }
                while (this.openList.Count > 0)
                {
                    CostNode costNode = this.openList.Pop();
                    if (costNode.cost == this.calcGrid[costNode.tile].costNodeCost)
                    {
                        int tile = costNode.tile;
                        if (this.calcGrid[tile].status != this.statusClosedValue)
                        {
                            int num = (tile + 1 >= tileIDToNeighbors_offsets.Count) ? tileIDToNeighbors_values.Count : tileIDToNeighbors_offsets[tile + 1];
                            for (int i = tileIDToNeighbors_offsets[tile]; i < num; i++)
                            {
                                int num2 = tileIDToNeighbors_values[i];
                                int num4;
                                if (this.calcGrid[num2].status != this.statusClosedValue && !impassable(num2))
                                {
                                    int num3 = costFunc(tile, num2);
                                    num4 = num3 + this.calcGrid[tile].knownCost;
                                    ushort status = this.calcGrid[num2].status;
                                    if (status != this.statusClosedValue && status != this.statusOpenValue)
                                    {
                                        goto IL_0282;
                                    }
                                    if (this.calcGrid[num2].knownCost > num4)
                                    {
                                        goto IL_0282;
                                    }
                                }
                                continue;
IL_0282:
                                int num5 = num4;
                                this.calcGrid[num2].parentTile   = tile;
                                this.calcGrid[num2].knownCost    = num4;
                                this.calcGrid[num2].status       = this.statusOpenValue;
                                this.calcGrid[num2].costNodeCost = num5;
                                this.openList.Push(new CostNode(num2, num5));
                            }
                            this.calcGrid[tile].status = this.statusClosedValue;
                            if (terminator != null && terminator(tile, (float)this.calcGrid[tile].costNodeCost))
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }
示例#14
0
        public WorldPath FindPath(int startTile, int destTile, Caravan caravan, Func <float, bool> terminator = null)
        {
            if (startTile < 0)
            {
                Log.Error("Tried to FindPath with invalid start tile " + startTile + ", caravan= " + caravan);
                return(WorldPath.NotFound);
            }
            if (destTile < 0)
            {
                Log.Error("Tried to FindPath with invalid dest tile " + destTile + ", caravan= " + caravan);
                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;

            int[] pathGrid = world.pathGrid.pathGrid;
            int   num      = 0;
            int   num2     = (caravan == null) ? 2500 : caravan.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 CostNode(startTile, 0));
            while (true)
            {
                if (this.openList.Count <= 0)
                {
                    Log.Warning(caravan + " pathing from " + startTile + " to " + destTile + " ran out of tiles to process.");
                    return(WorldPath.NotFound);
                }
                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)((float)this.calcGrid[tile].knownCost / 375000.0), this.calcGrid[tile].knownCost.ToString(), 50);
                        }
                        if (tile == destTile)
                        {
                            return(this.FinalizedPath(tile));
                        }
                        if (num > 500000)
                        {
                            Log.Warning(caravan + " pathing from " + startTile + " to " + destTile + " hit search limit of " + 500000 + " tiles.");
                            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];
                            int    num7;
                            ushort status;
                            if (this.calcGrid[num5].status != this.statusClosedValue && !world.Impassable(num5))
                            {
                                int num6 = num2;
                                num6  += pathGrid[num5];
                                num6   = (int)((float)num6 * grid.GetRoadMovementMultiplierFast(tile, num5));
                                num7   = num6 + this.calcGrid[tile].knownCost;
                                status = this.calcGrid[num5].status;
                                if (status != this.statusClosedValue && status != this.statusOpenValue)
                                {
                                    goto IL_041e;
                                }
                                if (this.calcGrid[num5].knownCost > num7)
                                {
                                    goto IL_041e;
                                }
                            }
                            continue;
IL_041e:
                            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)((float)num2 * num8 * (float)num3 * 0.5));
                            }
                            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 CostNode(num5, num9));
                        }
                        num++;
                        this.calcGrid[tile].status = this.statusClosedValue;
                        if (terminator != null && terminator((float)this.calcGrid[tile].costNodeCost))
                        {
                            break;
                        }
                    }
                }
            }
            return(WorldPath.NotFound);
        }
示例#15
0
        public PawnPath FindPath(IntVec3 start, LocalTargetInfo dest, TraverseParms traverseParms, PathEndMode peMode = PathEndMode.OnCell)
        {
            if (DebugSettings.pathThroughWalls)
            {
                traverseParms.mode = TraverseMode.PassAllDestroyableThings;
            }
            Pawn pawn = traverseParms.pawn;

            if (pawn != null && pawn.Map != map)
            {
                Log.Error(string.Concat("Tried to FindPath for pawn which is spawned in another map. His map PathFinder should have been used, not this one. pawn=", pawn, " pawn.Map=", pawn.Map, " map=", map));
                return(PawnPath.NotFound);
            }
            if (!start.IsValid)
            {
                Log.Error(string.Concat("Tried to FindPath with invalid start ", start, ", pawn= ", pawn));
                return(PawnPath.NotFound);
            }
            if (!dest.IsValid)
            {
                Log.Error(string.Concat("Tried to FindPath with invalid dest ", dest, ", pawn= ", pawn));
                return(PawnPath.NotFound);
            }
            if (traverseParms.mode == TraverseMode.ByPawn)
            {
                if (!pawn.CanReach(dest, peMode, Danger.Deadly, traverseParms.canBash, traverseParms.mode))
                {
                    return(PawnPath.NotFound);
                }
            }
            else if (!map.reachability.CanReach(start, dest, peMode, traverseParms))
            {
                return(PawnPath.NotFound);
            }
            PfProfilerBeginSample(string.Concat("FindPath for ", pawn, " from ", start, " to ", dest, dest.HasThing ? (" at " + dest.Cell) : ""));
            cellIndices      = map.cellIndices;
            pathGrid         = map.pathGrid;
            this.edificeGrid = map.edificeGrid.InnerArray;
            blueprintGrid    = map.blueprintGrid.InnerArray;
            int      x        = dest.Cell.x;
            int      z        = dest.Cell.z;
            int      curIndex = cellIndices.CellToIndex(start);
            int      num      = cellIndices.CellToIndex(dest.Cell);
            ByteGrid byteGrid = pawn?.GetAvoidGrid();
            bool     flag     = traverseParms.mode == TraverseMode.PassAllDestroyableThings || traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater;
            bool     flag2    = traverseParms.mode != TraverseMode.NoPassClosedDoorsOrWater && traverseParms.mode != TraverseMode.PassAllDestroyableThingsNotWater;
            bool     flag3    = !flag;
            CellRect cellRect = CalculateDestinationRect(dest, peMode);
            bool     flag4    = cellRect.Width == 1 && cellRect.Height == 1;

            int[]        array       = map.pathGrid.pathGrid;
            TerrainDef[] topGrid     = map.terrainGrid.topGrid;
            EdificeGrid  edificeGrid = map.edificeGrid;
            int          num2        = 0;
            int          num3        = 0;
            Area         allowedArea = GetAllowedArea(pawn);
            bool         flag5       = pawn != null && PawnUtility.ShouldCollideWithPawns(pawn);
            bool         flag6       = !flag && start.GetRegion(map) != null && flag2;
            bool         flag7       = !flag || !flag3;
            bool         flag8       = false;
            bool         flag9       = pawn?.Drafted ?? false;
            int          num4        = ((pawn?.IsColonist ?? false) ? 100000 : 2000);
            int          num5        = 0;
            int          num6        = 0;
            float        num7        = DetermineHeuristicStrength(pawn, start, dest);
            int          num8;
            int          num9;

            if (pawn != null)
            {
                num8 = pawn.TicksPerMoveCardinal;
                num9 = pawn.TicksPerMoveDiagonal;
            }
            else
            {
                num8 = 13;
                num9 = 18;
            }
            CalculateAndAddDisallowedCorners(traverseParms, peMode, cellRect);
            InitStatusesAndPushStartNode(ref curIndex, start);
            while (true)
            {
                PfProfilerBeginSample("Open cell");
                if (openList.Count <= 0)
                {
                    string text  = ((pawn != null && pawn.CurJob != null) ? pawn.CurJob.ToString() : "null");
                    string text2 = ((pawn != null && pawn.Faction != null) ? pawn.Faction.ToString() : "null");
                    Log.Warning(string.Concat(pawn, " pathing from ", start, " to ", dest, " ran out of cells to process.\nJob:", text, "\nFaction: ", text2));
                    DebugDrawRichData();
                    PfProfilerEndSample();
                    PfProfilerEndSample();
                    return(PawnPath.NotFound);
                }
                num5 += openList.Count;
                num6++;
                CostNode costNode = openList.Pop();
                curIndex = costNode.index;
                if (costNode.cost != calcGrid[curIndex].costNodeCost)
                {
                    PfProfilerEndSample();
                    continue;
                }
                if (calcGrid[curIndex].status == statusClosedValue)
                {
                    PfProfilerEndSample();
                    continue;
                }
                IntVec3 c  = cellIndices.IndexToCell(curIndex);
                int     x2 = c.x;
                int     z2 = c.z;
                if (flag4)
                {
                    if (curIndex == num)
                    {
                        PfProfilerEndSample();
                        PawnPath result = FinalizedPath(curIndex, flag8);
                        PfProfilerEndSample();
                        return(result);
                    }
                }
                else if (cellRect.Contains(c) && !disallowedCornerIndices.Contains(curIndex))
                {
                    PfProfilerEndSample();
                    PawnPath result2 = FinalizedPath(curIndex, flag8);
                    PfProfilerEndSample();
                    return(result2);
                }
                if (num2 > 160000)
                {
                    break;
                }
                PfProfilerEndSample();
                PfProfilerBeginSample("Neighbor consideration");
                for (int i = 0; i < 8; i++)
                {
                    uint num10 = (uint)(x2 + Directions[i]);
                    uint num11 = (uint)(z2 + Directions[i + 8]);
                    if (num10 >= mapSizeX || num11 >= mapSizeZ)
                    {
                        continue;
                    }
                    int num12 = (int)num10;
                    int num13 = (int)num11;
                    int num14 = cellIndices.CellToIndex(num12, num13);
                    if (calcGrid[num14].status == statusClosedValue && !flag8)
                    {
                        continue;
                    }
                    int  num15  = 0;
                    bool flag10 = false;
                    if (!flag2 && new IntVec3(num12, 0, num13).GetTerrain(map).HasTag("Water"))
                    {
                        continue;
                    }
                    if (!pathGrid.WalkableFast(num14))
                    {
                        if (!flag)
                        {
                            continue;
                        }
                        flag10 = true;
                        num15 += 70;
                        Building building = edificeGrid[num14];
                        if (building == null || !IsDestroyable(building))
                        {
                            continue;
                        }
                        num15 += (int)((float)building.HitPoints * 0.2f);
                    }
                    switch (i)
                    {
                    case 4:
                        if (BlocksDiagonalMovement(curIndex - mapSizeX))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        if (BlocksDiagonalMovement(curIndex + 1))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        break;

                    case 5:
                        if (BlocksDiagonalMovement(curIndex + mapSizeX))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        if (BlocksDiagonalMovement(curIndex + 1))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        break;

                    case 6:
                        if (BlocksDiagonalMovement(curIndex + mapSizeX))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        if (BlocksDiagonalMovement(curIndex - 1))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        break;

                    case 7:
                        if (BlocksDiagonalMovement(curIndex - mapSizeX))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        if (BlocksDiagonalMovement(curIndex - 1))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        break;
                    }
                    int num16 = ((i > 3) ? num9 : num8);
                    num16 += num15;
                    if (!flag10)
                    {
                        num16 += array[num14];
                        num16  = ((!flag9) ? (num16 + topGrid[num14].extraNonDraftedPerceivedPathCost) : (num16 + topGrid[num14].extraDraftedPerceivedPathCost));
                    }
                    if (byteGrid != null)
                    {
                        num16 += byteGrid[num14] * 8;
                    }
                    if (allowedArea != null && !allowedArea[num14])
                    {
                        num16 += 600;
                    }
                    if (flag5 && PawnUtility.AnyPawnBlockingPathAt(new IntVec3(num12, 0, num13), pawn, actAsIfHadCollideWithPawnsJob: false, collideOnlyWithStandingPawns: false, forPathFinder: true))
                    {
                        num16 += 175;
                    }
                    Building building2 = this.edificeGrid[num14];
                    if (building2 != null)
                    {
                        PfProfilerBeginSample("Edifices");
                        int buildingCost = GetBuildingCost(building2, traverseParms, pawn);
                        if (buildingCost == int.MaxValue)
                        {
                            PfProfilerEndSample();
                            continue;
                        }
                        num16 += buildingCost;
                        PfProfilerEndSample();
                    }
                    List <Blueprint> list = blueprintGrid[num14];
                    if (list != null)
                    {
                        PfProfilerBeginSample("Blueprints");
                        int num17 = 0;
                        for (int j = 0; j < list.Count; j++)
                        {
                            num17 = Mathf.Max(num17, GetBlueprintCost(list[j], pawn));
                        }
                        if (num17 == int.MaxValue)
                        {
                            PfProfilerEndSample();
                            continue;
                        }
                        num16 += num17;
                        PfProfilerEndSample();
                    }
                    int    num18  = num16 + calcGrid[curIndex].knownCost;
                    ushort status = calcGrid[num14].status;
                    if (status == statusClosedValue || status == statusOpenValue)
                    {
                        int num19 = 0;
                        if (status == statusClosedValue)
                        {
                            num19 = num8;
                        }
                        if (calcGrid[num14].knownCost <= num18 + num19)
                        {
                            continue;
                        }
                    }
                    if (flag8)
                    {
                        calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)regionCostCalculator.GetPathCostFromDestToRegion(num14) * RegionHeuristicWeightByNodesOpened.Evaluate(num3));
                        if (calcGrid[num14].heuristicCost < 0)
                        {
                            Log.ErrorOnce(string.Concat("Heuristic cost overflow for ", pawn.ToStringSafe(), " pathing from ", start, " to ", dest, "."), pawn.GetHashCode() ^ 0xB8DC389);
                            calcGrid[num14].heuristicCost = 0;
                        }
                    }
                    else if (status != statusClosedValue && status != statusOpenValue)
                    {
                        int dx    = Math.Abs(num12 - x);
                        int dz    = Math.Abs(num13 - z);
                        int num20 = GenMath.OctileDistance(dx, dz, num8, num9);
                        calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)num20 * num7);
                    }
                    int num21 = num18 + calcGrid[num14].heuristicCost;
                    if (num21 < 0)
                    {
                        Log.ErrorOnce(string.Concat("Node cost overflow for ", pawn.ToStringSafe(), " pathing from ", start, " to ", dest, "."), pawn.GetHashCode() ^ 0x53CB9DE);
                        num21 = 0;
                    }
                    calcGrid[num14].parentIndex  = curIndex;
                    calcGrid[num14].knownCost    = num18;
                    calcGrid[num14].status       = statusOpenValue;
                    calcGrid[num14].costNodeCost = num21;
                    num3++;
                    openList.Push(new CostNode(num14, num21));
                }
                PfProfilerEndSample();
                num2++;
                calcGrid[curIndex].status = statusClosedValue;
                if (num3 >= num4 && flag6 && !flag8)
                {
                    flag8 = true;
                    regionCostCalculator.Init(cellRect, traverseParms, num8, num9, byteGrid, allowedArea, flag9, disallowedCornerIndices);
                    InitStatusesAndPushStartNode(ref curIndex, start);
                    num3 = 0;
                    num2 = 0;
                }
            }
            Log.Warning(string.Concat(pawn, " pathing from ", start, " to ", dest, " hit search limit of ", 160000, " cells."));
            DebugDrawRichData();
            PfProfilerEndSample();
            PfProfilerEndSample();
            return(PawnPath.NotFound);
        }
示例#16
0
 /// <summary>
 /// Test this cost node is preceding of the given node.
 /// </summary>
 /// <param name="node">Cost node to test with.</param>
 /// <returns>True for yes, otherwise false.</returns>
 internal bool IsPreceed(CostNode node)
 {
     return this.CostNode.WaveUnit.SampleOffset
         + this.CostNode.WaveUnit.SampleLength
         == node.WaveUnit.SampleOffset;
 }
示例#17
0
        /// <summary>
        /// Find a NodeRoute which is shown and includes the cost node.
        /// </summary>
        /// <param name="costNode">Cost noe to find route on.</param>
        /// <returns>Found node route.</returns>
        public NodeRoute FindRoute(CostNode costNode)
        {
            if (Utterance == null || Utterance.Viterbi == null)
            {
                return null;
            }

            foreach (NodeRoute route in Utterance.Viterbi.NodeRoutes)
            {
                if (route.Visible
                    && route.CostNodes.Contains(costNode))
                {
                    return route;
                }
            }

            return null;
        }
示例#18
0
        private static CostNode ParseCostNode(string line)
        {
            CostNode node = new CostNode();

            string[] items = line.Split(new char[] { ' ' },
                StringSplitOptions.RemoveEmptyEntries);
            System.Diagnostics.Debug.Assert(items.Length == 14 || items.Length == 5 || items.Length == 3);
            node.Index = int.Parse(items[1], CultureInfo.InvariantCulture);

            node.WaveUnit = ParseWaveUnitForViterbi(items);
            if (items.Length > 3)
            {
                node.TargetCost = float.Parse(items[items.Length - 2], CultureInfo.InvariantCulture);
                node.RouteCost = float.Parse(items[items.Length - 1], CultureInfo.InvariantCulture);
            }

            return node;
        }
示例#19
0
        /// <summary>
        /// Save information of one unit into log file.
        /// </summary>
        /// <param name="writer">Stream writer to save the information.</param>
        /// <param name="index">Index of the unit to save.</param>
        /// <param name="expectedUnit">Expected unit from front-end.</param>
        /// <param name="selectedNode">Selected node through unit selection.</param>
        /// <returns>Next unit index.</returns>
        private static int SaveUnit(StreamWriter writer, int index,
            TtsUnit expectedUnit, CostNode selectedNode)
        {
            writer.Write(index.ToString(CultureInfo.InvariantCulture) + " ");
            ++index;
            writer.Write(index.ToString(CultureInfo.InvariantCulture) + " ");
            writer.Write(expectedUnit.MetaUnit.Id.ToString(CultureInfo.InvariantCulture) + " ");
            writer.Write(selectedNode.WaveUnit.SampleOffset.ToString(CultureInfo.InvariantCulture) + " ");
            writer.Write(selectedNode.WaveUnit.SampleLength.ToString(CultureInfo.InvariantCulture) + " ");

            TtsUnitFeature selFea = selectedNode.WaveUnit.Features;
            if (selFea != null)
            {
                StringBuilder builder = new StringBuilder();

                builder.AppendFormat(CultureInfo.InvariantCulture,
                    "{0}/ {1} ",
                    (int)selFea.PosInSentence, (int)expectedUnit.Feature.PosInSentence);
                builder.AppendFormat(CultureInfo.InvariantCulture,
                    "{0}/{1} ",
                    (int)selFea.PosInWord, (int)expectedUnit.Feature.PosInWord);
                builder.AppendFormat(CultureInfo.InvariantCulture,
                    "{0}/{1} ",
                    (int)selFea.PosInSyllable, (int)expectedUnit.Feature.PosInSyllable);

                builder.AppendFormat(CultureInfo.InvariantCulture,
                    "{0}/{1} ",
                    (int)selFea.LeftContextPhone, (int)expectedUnit.Feature.LeftContextPhone);
                builder.AppendFormat(CultureInfo.InvariantCulture,
                    "{0}/{1} ",
                    (int)selFea.RightContextPhone, (int)expectedUnit.Feature.RightContextPhone);

                builder.AppendFormat(CultureInfo.InvariantCulture,
                    "{0}/{1} ",
                    (int)selFea.LeftContextTone, (int)expectedUnit.Feature.LeftContextTone);
                builder.AppendFormat(CultureInfo.InvariantCulture,
                    "{0}/{1} ",
                    (int)selFea.RightContextTone, (int)expectedUnit.Feature.RightContextTone);

                builder.AppendFormat(CultureInfo.InvariantCulture,
                    "{0}/ {1} ",
                    (int)selFea.TtsStress, (int)expectedUnit.Feature.TtsStress);
                builder.AppendFormat(CultureInfo.InvariantCulture,
                    "{0}/{1} ",
                    (int)selFea.TtsEmphasis, (int)expectedUnit.Feature.TtsEmphasis);

                builder.AppendFormat(CultureInfo.InvariantCulture,
                    "{0}/{1} ",
                    (int)selFea.TtsWordTone, (int)expectedUnit.Feature.TtsWordTone);

                writer.Write(builder.ToString());
            }

            writer.Write("\r\n");
            return index;
        }
示例#20
0
        public PawnPath FindPath(IntVec3 start, LocalTargetInfo dest, TraverseParms traverseParms, PathEndMode peMode = PathEndMode.OnCell)
        {
            if (DebugSettings.pathThroughWalls)
            {
                traverseParms.mode = TraverseMode.PassAllDestroyableThings;
            }
            Pawn pawn = traverseParms.pawn;

            if (pawn != null && pawn.Map != map)
            {
                Log.Warning(String.Format("Map object was rebuilt, but new pather was not assigned to new map (new {0}) (old {1})", pawn.Map.uniqueID, map.uniqueID));
                Log.Error("Tried to FindPath for pawn which is spawned in another map. His map PathFinder should have been used, not this one. pawn=" + pawn + " pawn.Map=" + pawn.Map + " map=" + map);
                return(PawnPath.NotFound);
            }
            if (!start.IsValid)
            {
                Log.Error("Tried to FindPath with invalid start " + start + ", pawn= " + pawn);
                return(PawnPath.NotFound);
            }
            if (!dest.IsValid)
            {
                Log.Error("Tried to FindPath with invalid dest " + dest + ", pawn= " + pawn);
                return(PawnPath.NotFound);
            }
            if (traverseParms.mode == TraverseMode.ByPawn)
            {
                if (!pawn.CanReach(dest, peMode, Danger.Deadly, traverseParms.canBash, traverseParms.mode))
                {
                    return(PawnPath.NotFound);
                }
            }
            else if (!map.reachability.CanReach(start, dest, peMode, traverseParms))
            {
                return(PawnPath.NotFound);
            }
            PfProfilerBeginSample("FindPath for " + pawn + " from " + start + " to " + dest + (dest.HasThing ? (" at " + dest.Cell) : ""));
            cellIndices      = map.cellIndices;
            pathGrid         = map.pathGrid;
            this.edificeGrid = map.edificeGrid.InnerArray;
            blueprintGrid    = map.blueprintGrid.InnerArray;
            int      x        = dest.Cell.x;
            int      z        = dest.Cell.z;
            int      curIndex = cellIndices.CellToIndex(start);
            int      num      = cellIndices.CellToIndex(dest.Cell);
            ByteGrid byteGrid = pawn?.GetAvoidGrid();
            bool     flag     = traverseParms.mode == TraverseMode.PassAllDestroyableThings || traverseParms.mode == TraverseMode.PassAllDestroyableThingsNotWater;
            bool     flag2    = traverseParms.mode != TraverseMode.NoPassClosedDoorsOrWater && traverseParms.mode != TraverseMode.PassAllDestroyableThingsNotWater;
            bool     flag3    = !flag;
            CellRect cellRect = CalculateDestinationRect(dest, peMode);
            bool     flag4    = cellRect.Width == 1 && cellRect.Height == 1;

            int[]        array       = map.pathGrid.pathGrid;
            TerrainDef[] topGrid     = map.terrainGrid.topGrid;
            EdificeGrid  edificeGrid = map.edificeGrid;
            int          num2        = 0;
            int          num3        = 0;
            Area         allowedArea = GetAllowedArea(pawn);
            bool         flag5       = pawn != null && PawnUtility.ShouldCollideWithPawns(pawn);
            bool         flag6       = (!flag && start.GetRegion(map) != null) & flag2;
            bool         flag7       = !flag || !flag3;
            bool         flag8       = false;
            bool         flag9       = pawn?.Drafted ?? false;
            int          num4        = (pawn?.IsColonist ?? false) ? 100000 : 2000;
            int          num5        = 0;
            int          num6        = 0;
            float        num7        = DetermineHeuristicStrength(pawn, start, dest);
            // BEGIN CHANGED SECTION
            // In case pawn is null
            int num8 = 13;
            int num9 = 18;
            Dictionary <TerrainDef, int>  pawnTerrainCacheCardinal    = new Dictionary <TerrainDef, int>();
            Dictionary <TerrainDef, int>  pawnTerrainCacheDiagonal    = new Dictionary <TerrainDef, int>();
            Dictionary <TerrainDef, bool> pawnSpecialMovementCache    = new Dictionary <TerrainDef, bool>();
            Dictionary <TerrainDef, bool> pawnImpassibleMovementCache = new Dictionary <TerrainDef, bool>();
            Dictionary <TerrainDef, int>  pawnTerrainMovementCache    = new Dictionary <TerrainDef, int>();

            // END CHANGED SECTION
            CalculateAndAddDisallowedCorners(traverseParms, peMode, cellRect);
            InitStatusesAndPushStartNode(ref curIndex, start);
            while (true)
            {
                PfProfilerBeginSample("Open cell");
                if (openList.Count <= 0)
                {
                    string text  = (pawn != null && pawn.CurJob != null) ? pawn.CurJob.ToString() : "null";
                    string text2 = (pawn != null && pawn.Faction != null) ? pawn.Faction.ToString() : "null";
                    Log.Warning(pawn + " pathing from " + start + " to " + dest + " ran out of cells to process.\nJob:" + text + "\nFaction: " + text2);
                    DebugDrawRichData();
                    PfProfilerEndSample();
                    PfProfilerEndSample();
                    return(PawnPath.NotFound);
                }
                num5 += openList.Count;
                num6++;
                CostNode costNode = openList.Pop();
                curIndex = costNode.index;
                if (costNode.cost != calcGrid[curIndex].costNodeCost)
                {
                    PfProfilerEndSample();
                    continue;
                }
                if (calcGrid[curIndex].status == statusClosedValue)
                {
                    PfProfilerEndSample();
                    continue;
                }
                IntVec3 c  = cellIndices.IndexToCell(curIndex);
                int     x2 = c.x;
                int     z2 = c.z;
                if (flag4)
                {
                    if (curIndex == num)
                    {
                        PfProfilerEndSample();
                        PawnPath result = FinalizedPath(curIndex, flag8);
                        PfProfilerEndSample();
                        return(result);
                    }
                }
                else if (cellRect.Contains(c) && !disallowedCornerIndices.Contains(curIndex))
                {
                    PfProfilerEndSample();
                    PawnPath result2 = FinalizedPath(curIndex, flag8);
                    PfProfilerEndSample();
                    return(result2);
                }
                if (num2 > 160000)
                {
                    break;
                }
                PfProfilerEndSample();
                PfProfilerBeginSample("Neighbor consideration");
                for (int i = 0; i < 8; i++)
                {
                    uint num10 = (uint)(x2 + Directions[i]);
                    uint num11 = (uint)(z2 + Directions[i + 8]);
                    if (num10 >= mapSizeX || num11 >= mapSizeZ)
                    {
                        continue;
                    }
                    int num12 = (int)num10;
                    int num13 = (int)num11;
                    int num14 = cellIndices.CellToIndex(num12, num13);
                    if (calcGrid[num14].status == statusClosedValue && !flag8)
                    {
                        continue;
                    }
                    // BEGIN CHANGED SECTION
                    IntVec3    targetCell    = new IntVec3(num12, 0, num13);
                    TerrainDef targetTerrain = topGrid[num14];
                    if (pawn != null)
                    {
                        // Use cache of terrain movement indicators to avoid a lot of repeated computation
                        if (!pawnImpassibleMovementCache.TryGetValue(targetTerrain, out bool impassible))
                        {
                            impassible = pawn.kindDef.UnreachableTerrainCheck(targetTerrain);
                            pawnImpassibleMovementCache[targetTerrain] = impassible;
                        }
                        if (impassible)
                        {
                            // Skip this cell for pathing calculations
                            calcGrid[num14].status = statusClosedValue;
                            continue;
                        }

                        // Overwrite directional move costs
                        if (!pawnTerrainCacheCardinal.TryGetValue(targetTerrain, out num8))
                        {
                            num8 = pawn.TerrainAwareTicksPerMoveCardinal(targetTerrain);
                            pawnTerrainCacheCardinal[targetTerrain] = num8;
                        }
                        if (!pawnTerrainCacheDiagonal.TryGetValue(targetTerrain, out num9))
                        {
                            num9 = pawn.TerrainAwareTicksPerMoveDiagonal(targetTerrain);
                            pawnTerrainCacheDiagonal[targetTerrain] = num9;
                        }
                    }
                    // END CHANGED SECTION
                    int  num15  = 0;
                    bool flag10 = false;
                    //if (!flag2 && new IntVec3(num12, 0, num13).GetTerrain(map).HasTag("Water"))
                    if (!flag2 && targetTerrain.HasTag("Water"))
                    {
                        continue;
                    }
                    if (!pathGrid.WalkableFast(num14))
                    {
                        if (!flag)
                        {
                            continue;
                        }
                        flag10 = true;
                        num15 += 70;
                        Building building = edificeGrid[num14];
                        if (building == null || !IsDestroyable(building))
                        {
                            continue;
                        }
                        num15 += (int)((float)building.HitPoints * 0.2f);
                    }
                    switch (i)
                    {
                    case 4:
                        if (BlocksDiagonalMovement(curIndex - mapSizeX))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        if (BlocksDiagonalMovement(curIndex + 1))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        break;

                    case 5:
                        if (BlocksDiagonalMovement(curIndex + mapSizeX))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        if (BlocksDiagonalMovement(curIndex + 1))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        break;

                    case 6:
                        if (BlocksDiagonalMovement(curIndex + mapSizeX))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        if (BlocksDiagonalMovement(curIndex - 1))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        break;

                    case 7:
                        if (BlocksDiagonalMovement(curIndex - mapSizeX))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        if (BlocksDiagonalMovement(curIndex - 1))
                        {
                            if (flag7)
                            {
                                continue;
                            }
                            num15 += 70;
                        }
                        break;
                    }
                    int num16 = (i > 3) ? num9 : num8;
                    num16 += num15;
                    if (!flag10)
                    {
                        // BEGIN CHANGED SECTION
                        //num16 += array[num14];
                        //num16 = ((!flag9) ? (num16 + topGrid[num14].extraNonDraftedPerceivedPathCost) : (num16 + topGrid[num14].extraDraftedPerceivedPathCost));
                        if (pawn == null)
                        {
                            num16 += array[num14];
                            if (flag9)
                            {
                                num16 += targetTerrain.extraDraftedPerceivedPathCost;
                            }
                            else
                            {
                                num16 += targetTerrain.extraNonDraftedPerceivedPathCost;
                            }
                        }
                        else
                        {
                            // Use cache of terrain perceived cost instead of fixed pathCost grid to avoid a lot of repeated computation while maintaining accuracy
                            if (!pawnTerrainMovementCache.TryGetValue(targetTerrain, out int terrainMoveCost))
                            {
                                terrainMoveCost = pawn.TerrainMoveCost(targetTerrain);
                                pawnTerrainMovementCache[targetTerrain] = terrainMoveCost;
                            }
                            // This was really really expensive, so we opted to mod this pre-calced value
                            //num16 += pathGrid.TerrainCalculatedCostAt(map, pawn, targetCell, true, IntVec3.Invalid, terrainMoveCost);
                            num16 += pathGrid.ApplyTerrainModToCalculatedCost(targetTerrain, array[num14], terrainMoveCost);
                            // Use cache of terrain movement indicators to avoid a lot of repeated computation
                            if (!pawnSpecialMovementCache.TryGetValue(targetTerrain, out bool specialMovement))
                            {
                                specialMovement = pawn.TerrainMoveStat(targetTerrain) != StatDefOf.MoveSpeed;
                                pawnSpecialMovementCache[targetTerrain] = specialMovement;
                            }
                            // Skip applying the PerceivedPathCost hack if we've got a specialized speed stat for this terrain
                            if (!specialMovement)
                            {
                                if (flag9)
                                {
                                    num16 += targetTerrain.extraDraftedPerceivedPathCost;
                                }
                                else
                                {
                                    num16 += targetTerrain.extraNonDraftedPerceivedPathCost;
                                }
                            }
                        }
                        // END CHANGED SECTION
                    }
                    if (byteGrid != null)
                    {
                        num16 += byteGrid[num14] * 8;
                    }
                    if (allowedArea != null && !allowedArea[num14])
                    {
                        num16 += 600;
                    }
                    //new IntVec3(num12, 0, num13) -> targetCell
                    if (flag5 && PawnUtility.AnyPawnBlockingPathAt(targetCell, pawn, actAsIfHadCollideWithPawnsJob: false, collideOnlyWithStandingPawns: false, forPathFinder: true))
                    {
                        num16 += 175;
                    }
                    Building building2 = this.edificeGrid[num14];
                    if (building2 != null)
                    {
                        PfProfilerBeginSample("Edifices");
                        int buildingCost = GetBuildingCost(building2, traverseParms, pawn);
                        if (buildingCost == int.MaxValue)
                        {
                            PfProfilerEndSample();
                            continue;
                        }
                        num16 += buildingCost;
                        PfProfilerEndSample();
                    }
                    List <Blueprint> list = blueprintGrid[num14];
                    if (list != null)
                    {
                        PfProfilerBeginSample("Blueprints");
                        int num17 = 0;
                        for (int j = 0; j < list.Count; j++)
                        {
                            num17 = Mathf.Max(num17, GetBlueprintCost(list[j], pawn));
                        }
                        if (num17 == int.MaxValue)
                        {
                            PfProfilerEndSample();
                            continue;
                        }
                        num16 += num17;
                        PfProfilerEndSample();
                    }
                    int    num18  = num16 + calcGrid[curIndex].knownCost;
                    ushort status = calcGrid[num14].status;
                    if (status == statusClosedValue || status == statusOpenValue)
                    {
                        int num19 = 0;
                        if (status == statusClosedValue)
                        {
                            num19 = num8;
                        }
                        if (calcGrid[num14].knownCost <= num18 + num19)
                        {
                            continue;
                        }
                    }
                    if (flag8)
                    {
                        calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)regionCostCalculator.GetPathCostFromDestToRegion(num14) * RegionHeuristicWeightByNodesOpened.Evaluate(num3));
                        if (calcGrid[num14].heuristicCost < 0)
                        {
                            Log.ErrorOnce("Heuristic cost overflow for " + pawn.ToStringSafe() + " pathing from " + start + " to " + dest + ".", pawn.GetHashCode() ^ 0xB8DC389);
                            calcGrid[num14].heuristicCost = 0;
                        }
                    }
                    else if (status != statusClosedValue && status != statusOpenValue)
                    {
                        int dx    = Math.Abs(num12 - x);
                        int dz    = Math.Abs(num13 - z);
                        int num20 = GenMath.OctileDistance(dx, dz, num8, num9);
                        calcGrid[num14].heuristicCost = Mathf.RoundToInt((float)num20 * num7);
                    }
                    int num21 = num18 + calcGrid[num14].heuristicCost;
                    if (num21 < 0)
                    {
                        Log.ErrorOnce("Node cost overflow for " + pawn.ToStringSafe() + " pathing from " + start + " to " + dest + ".", pawn.GetHashCode() ^ 0x53CB9DE);
                        num21 = 0;
                    }
                    calcGrid[num14].parentIndex  = curIndex;
                    calcGrid[num14].knownCost    = num18;
                    calcGrid[num14].status       = statusOpenValue;
                    calcGrid[num14].costNodeCost = num21;
                    num3++;
                    openList.Push(new CostNode(num14, num21));
                }
                PfProfilerEndSample();
                num2++;
                calcGrid[curIndex].status = statusClosedValue;
                if (num3 >= num4 && flag6 && !flag8)
                {
                    flag8 = true;
                    regionCostCalculator.Init(cellRect, traverseParms, num8, num9, byteGrid, allowedArea, flag9, disallowedCornerIndices);
                    InitStatusesAndPushStartNode(ref curIndex, start);
                    num3 = 0;
                    num2 = 0;
                }
            }
            Log.Warning(pawn + " pathing from " + start + " to " + dest + " hit search limit of " + 160000 + " cells.");
            DebugDrawRichData();
            PfProfilerEndSample();
            PfProfilerEndSample();
            return(PawnPath.NotFound);
        }
示例#21
0
文件: Binder.cs 项目: BSData/phalanx
 internal ICostTypeSymbol BindCostTypeSymbol(CostNode node, DiagnosticBag diagnostics) =>
 BindSimple <ICostTypeSymbol, ErrorSymbols.ErrorCostTypeSymbol>(
     node, diagnostics, node.TypeId, LookupOptions.CostTypeOnly);