Esempio n. 1
0
        public static PathDataLog LoadFromFile(string filename)
        {
            var pathData = new PathDataLog();

            try
            {
                Scribe.InitLoading(filename);
                ScribeMetaHeaderUtility.LoadGameDataHeader(ScribeMetaHeaderUtility.ScribeHeaderMode.Map, false);
                Scribe.EnterNode("PathData");
                pathData.ExposeData();
                Scribe.ExitNode();
            }
            catch (Exception e)
            {
                Log.Error("Exception while loading: " + e);
            }
            finally
            {
                // done loading
                Scribe.FinalizeLoading();
                Scribe.mode = LoadSaveMode.Inactive;
            }

            return(pathData);
        }
Esempio n. 2
0
        public static void SaveFromPathCall(Map map, IntVec3 startVec, LocalTargetInfo dest, TraverseParms traverseParms, PathEndMode peMode)
        {
            CellRect destinationRect;

            if (dest.HasThing && peMode != PathEndMode.OnCell)
            {
                destinationRect = dest.Thing.OccupiedRect();
            }
            else
            {
                destinationRect = CellRect.SingleCell(dest.Cell);
            }

            var dumper = new PathDataLog
            {
                mapSize         = map.Size,
                start           = startVec,
                dest            = destinationRect,
                peMode          = peMode,
                tpMode          = traverseParms.mode,
                tpMaxDanger     = traverseParms.maxDanger,
                tpCanBash       = traverseParms.canBash,
                tpMoveCardinal  = traverseParms.pawn?.TicksPerMoveCardinal ?? -1,
                tpMoveDiagonal  = traverseParms.pawn?.TicksPerMoveDiagonal ?? -1,
                pathGrid        = map.pathGrid.pathGrid,
                fakeEdificeGrid = new ByteGrid(map),
                avoidGrid       = traverseParms.pawn?.GetAvoidGrid(),
                allowedArea     = traverseParms.pawn?.playerSettings?.AreaRestrictionInPawnCurrentMap
            };

            foreach (var cell in map.AllCells)
            {
                var rb    = cell.GetRegionBarrier(map);
                int value = Edifice_None;
                if (rb != null)
                {
                    var door = rb as Building_Door;
                    if (door != null)
                    {
                        switch (traverseParms.mode)
                        {
                        case TraverseMode.ByPawn:
                            if (!traverseParms.canBash && door.IsForbiddenToPass(traverseParms.pawn))
                            {
                                value = Edifice_NonTraversableDoor;
                            }
                            else if (!door.FreePassage)
                            {
                                value = door.PawnCanOpen(traverseParms.pawn) ? door.TicksToOpenNow : Edifice_NonTraversableDoor;
                            }
                            else
                            {
                                value = 0;
                            }
                            break;

                        case TraverseMode.NoPassClosedDoors:
                            value = !door.FreePassage ? Edifice_NonTraversableDoor : 0;
                            break;
                        }
                    }
                    else if ((rb as Building)?.PathFindCostFor(traverseParms.pawn) > 0)
                    {
                        value = Edifice_KnownArmedTrap;
                    }
                    else
                    {
                        value = Edifice_Impassible;
                    }
                }
                dumper.fakeEdificeGrid[cell] = (byte)value;
            }

            var savePath = Path.Combine(GenFilePaths.DevOutputFolderPath, $"{traverseParms.pawn} - {Find.TickManager.TicksAbs}");

            if (File.Exists(savePath + ".xml"))
            {
                savePath = savePath + " ";
                int saveNum = 1;
                while (File.Exists(savePath + saveNum + ".xml"))
                {
                    saveNum++;
                }
                savePath = savePath + saveNum;
            }
            try
            {
                SaveGame(savePath);
                try
                {
                    Scribe.InitWriting(savePath + ".xml", "PathDataLog");
                }
                catch (Exception ex)
                {
                    GenUI.ErrorDialog("Stuff went wrong " + ex);
                    throw;
                }
                ScribeMetaHeaderUtility.WriteMetaHeader();

                Scribe_Deep.LookDeep(ref dumper, "PathData");
            }
            catch (Exception ex2)
            {
                Log.Error("Exception while saving: " + ex2);
            }
            finally
            {
                Scribe.FinalizeWriting();
            }
        }
        //Wrapper function to run extra testing/logging code.
        public PawnPath FindPath(IntVec3 start, LocalTargetInfo dest, TraverseParms traverseParms, PathEndMode peMode = PathEndMode.OnCell)
        {
#if DEBUG
            if (traverseParms.pawn != null)
            {
                Log.Message($"Pathfinding times for pawn {traverseParms.pawn}, mode: {traverseParms.mode}\n Move speed: {traverseParms.pawn.TicksPerMoveCardinal}, {traverseParms.pawn.TicksPerMoveDiagonal}");
            }
            disableDebugFlash = true;             //disable debug flash during timing tests
            var      sw          = new Stopwatch();
            PawnPath temp        = null;
            var      vanillaCost = float.MaxValue - 1000;
            diagonalPerceivedCostWeight = 1.0f;
            sw.Start();
            temp = FindPathInner(start, dest, traverseParms, peMode, HeuristicMode.Vanilla);
            sw.Stop();
            Log.Message("~~ Vanilla ~~ " + sw.ElapsedTicks + " ticks, " + debug_openCellsPopped + " open cells popped, " + temp.TotalCost + " path cost!");
            vanillaCost = temp.TotalCost;
            temp.Dispose();

            //sw.Reset();
            //sw.Start();
            //temp = FindPathInner(start, dest, traverseParms, peMode, HeuristicMode.AdmissableOctile);
            //sw.Stop();
            //Log.Message("~~ Admissable Octile ~~ " + sw.ElapsedTicks + " ticks, " + debug_openCellsPopped + " open cells popped, " + temp.TotalCost + " path cost!");
            //var optimal = temp.TotalCost;
            //temp.Dispose();

            try
            {
                diagonalPerceivedCostWeight = diagonalCostWeightSetting;
                sw.Reset();
                sw.Start();
                temp = FindPathInner(start, dest, traverseParms, peMode, HeuristicMode.Better);
                sw.Stop();
                Log.Message("~~ Better ~~ " + sw.ElapsedTicks + " ticks, " + debug_openCellsPopped + " open cells popped, " + temp.TotalCost + " path cost!  (" /*+ sw.ElapsedMilliseconds*/ + "ms)");
            }
            catch
            {
                if (Current.ProgramState == ProgramState.Playing)
                {
                    PathDataLog.SaveFromPathCall(this.map, start, dest, traverseParms, peMode);
                }
            }
            //var sb = new StringBuilder();
            //foreach (var pathmax in new [] {false, true})
            //{
            //	pathmaxEnabled = pathmax;
            //	foreach (var weight in new[] {false, true})
            //	{
            //		weightEnabled = weight;
            //		sw.Reset();
            //		sw.Start();
            //		temp = FindPathInner(start, dest, traverseParms, peMode);
            //		sw.Stop();
            //		sb.AppendLine($"pathmax: {pathmax}, weight: {weight}, pops: {debug_openCellsPopped}, pathcost: {temp.TotalCost}, elapsed: {sw.ElapsedTicks}");
            //		temp.Dispose();
            //	}
            //}
            //Log.Message(sb.ToString());

            //Log.Message("\t Distance Map Pops: " + RegionLinkDijkstra.nodes_popped);
            //Log.Message("\t Total open cells added: " + debug_totalOpenListCount);
            //Log.Message("\t Closed cells reopened: " + closedCellsReopened);
            //Log.Message($"\t Total Heuristic Estimate {debug_totalHeuristicCostEstimate}, off by {((temp.TotalCost / debug_totalHeuristicCostEstimate) - 1.0f).ToStringPercent()}");

            temp?.Dispose();
            disableDebugFlash = false;
#endif
#if PFPROFILE
            if (!hasRunOnce)
            {
                disableDebugFlash = true;
                var jitRun = FindPathInner(start, dest, traverseParms, peMode, HeuristicMode.Better);
                jitRun.Dispose();
                hasRunOnce        = true;
                disableDebugFlash = false;
            }
            sws.Clear();
#endif
            var result = FindPathInner(start, dest, traverseParms, peMode, HeuristicMode.Better);

#if PFPROFILE
            var profsb = new StringBuilder();
            foreach (var pfsw in sws)
            {
                profsb.AppendLine("SW " + pfsw.Key + ": " + pfsw.Value.ElapsedTicks.ToString("##,#") + " ticks.");
            }
            Log.Message(profsb.ToString());
#endif
#if DEBUG
            if (Current.ProgramState == ProgramState.Playing)
            {
                if (debug_openCellsPopped > 2500 || (vanillaCost + 100) < result.TotalCost || result == PawnPath.NotFound)
                {
                    PathDataLog.SaveFromPathCall(this.map, start, dest, traverseParms, peMode);
                }
            }
#endif
            return(result);
        }