예제 #1
0
        private static BoolUnknown GetCachedResult(Reachability __instance, TraverseParms traverseParams, List <Region> startingRegionsParams, List <Region> destRegionsParams)
        {
            bool flag = false;
            ReachabilityCache cache = cacheFieldRef(__instance);

            for (int i = 0; i < startingRegionsParams.Count; i++)
            {
                for (int j = 0; j < destRegionsParams.Count; j++)
                {
                    if (destRegionsParams[j] == startingRegionsParams[i])
                    {
                        return(BoolUnknown.True);
                    }

                    switch (cache.CachedResultFor(startingRegionsParams[i].Room, destRegionsParams[j].Room, traverseParams))
                    {
                    case BoolUnknown.True:
                        return(BoolUnknown.True);

                    case BoolUnknown.Unknown:
                        flag = true;
                        break;
                    }
                }
            }

            if (!flag)
            {
                return(BoolUnknown.False);
            }

            return(BoolUnknown.Unknown);
        }
예제 #2
0
        public static bool ClearFor(ReachabilityCache __instance, Pawn p)
        {
            List <CachedEntry2> tmpCachedEntries = getTmpCachedEntries();

            tmpCachedEntries.Clear();
            Dictionary <CachedEntry2, bool> cacheDict = getCacheDict(__instance);

            foreach (KeyValuePair <CachedEntry2, bool> item in cacheDict)
            {
                if (item.Key.TraverseParms.pawn == p)
                {
                    tmpCachedEntries.Add(item.Key);
                }
            }

            for (int i = 0; i < tmpCachedEntries.Count; i++)
            {
                lock (cacheDict)
                {
                    cacheDict.Remove(tmpCachedEntries[i]);
                }
            }

            //tmpCachedEntries.Clear();
            return(false);
        }
        public static bool CachedResultFor(ReachabilityCache __instance, ref BoolUnknown __result, District A, District B, TraverseParms traverseParams)
#endif
        {
            if (A == null || B == null)
            {
                return(false);
            }
            Dictionary <ReachabilityCache.CachedEntry, bool> cacheDict = getCacheDict(__instance);

            lock (cacheDict)
            {
                if (cacheDict.TryGetValue(new ReachabilityCache.CachedEntry(A.ID, B.ID, traverseParams), out bool value))
                {
                    if (!value)
                    {
                        __result = BoolUnknown.False;
                        return(false);
                    }
                    __result = BoolUnknown.True;
                    return(false);
                }
            }
            __result = BoolUnknown.Unknown;
            return(false);
        }
예제 #4
0
        public static bool ClearForHostile(ReachabilityCache __instance, Thing hostileTo)
        {
            if (tmpCachedEntries == null)
            {
                tmpCachedEntries = new List <CachedEntry2>();
            }
            else
            {
                tmpCachedEntries.Clear();
            }
            cacheDict = getCacheDict(__instance);

            foreach (KeyValuePair <CachedEntry2, bool> item in cacheDict)
            {
                pawn = item.Key.TraverseParms.pawn;
                if (pawn != null && pawn.HostileTo(hostileTo))
                {
                    tmpCachedEntries.Add(item.Key);
                }
            }
            for (int i = 0; i < tmpCachedEntries.Count; i++)
            {
                cacheDict.Remove(tmpCachedEntries[i]);
            }

            //tmpCachedEntries.Clear();
            return(false);
        }
예제 #5
0
        public static bool ClearForHostile(ReachabilityCache __instance, Thing hostileTo)
        {
            List <CachedEntry2> tmpCachedEntries = getTmpCachedEntries();

            tmpCachedEntries.Clear();
            Dictionary <CachedEntry2, bool> cacheDict = getCacheDict(__instance);

            lock (cacheDict)
            {
                foreach (KeyValuePair <CachedEntry2, bool> item in cacheDict)
                {
                    Pawn pawn = item.Key.TraverseParms.pawn;
                    if (pawn != null && pawn.HostileTo(hostileTo))
                    {
                        tmpCachedEntries.Add(item.Key);
                    }
                }
            }
            for (int i = 0; i < tmpCachedEntries.Count; i++)
            {
                lock (cacheDict)
                {
                    cacheDict.Remove(tmpCachedEntries[i]);
                }
            }

            //tmpCachedEntries.Clear();
            return(false);
        }
예제 #6
0
 public static Dictionary <CachedEntry2, bool> getCacheDict(ReachabilityCache __instance)
 {
     if (!cacheDictDict.TryGetValue(__instance, out Dictionary <CachedEntry2, bool> cacheDict))
     {
         cacheDict = new Dictionary <CachedEntry2, bool>();
         cacheDictDict[__instance] = cacheDict;
     }
     return(cacheDict);
 }
예제 #7
0
        public static bool Clear(ReachabilityCache __instance)
        {
            Dictionary <CachedEntry2, bool> cacheDict = getCacheDict(__instance);

            lock (cacheDict)
            {
                cacheDict.Clear();
            }
            return(false);
        }
예제 #8
0
        private static bool CheckRegionBasedReachability(Reachability __instance, TraverseParms traverseParams, Queue <Region> openQueueParam,
                                                         HashSet <Region> regionsReached, List <Region> startingRegionsParam, List <Region> destRegionsParam)
        {
            ReachabilityCache cache = __instance.cache;

            while (openQueueParam.Count > 0)
            {
                Region region = openQueueParam.Dequeue();
                for (int i = 0; i < region.links.Count; i++)
                {
                    RegionLink regionLink = region.links[i];
                    for (int j = 0; j < 2; j++)
                    {
                        Region region2 = regionLink.regions[j];
                        if (region2 == null || regionsReached.Contains(region2) || !region2.type.Passable() || !region2.Allows(traverseParams, isDestination: false))
                        {
                            continue;
                        }

                        if (destRegionsParam.Contains(region2))
                        {
                            for (int k = 0; k < startingRegionsParam.Count; k++)
                            {
#if RW12
                                cache.AddCachedResult(startingRegionsParam[k].Room, region2.Room, traverseParams, reachable: true);
#endif
#if RW13
                                cache.AddCachedResult(startingRegionsParam[k].District, region2.District, traverseParams, reachable: true);
#endif
                            }

                            return(true);
                        }
                        QueueNewOpenRegion(region2, openQueueParam, regionsReached);
                    }
                }
            }

            for (int l = 0; l < startingRegionsParam.Count; l++)
            {
                for (int m = 0; m < destRegionsParam.Count; m++)
                {
#if RW12
                    cache.AddCachedResult(startingRegionsParam[l].Room, destRegionsParam[m].Room, traverseParams, reachable: false);
#endif
#if RW13
                    cache.AddCachedResult(startingRegionsParam[l].District, destRegionsParam[m].District, traverseParams, reachable: false);
#endif
                }
            }
            return(false);
        }
예제 #9
0
        public static bool AddCachedResult(ReachabilityCache __instance, Room A, Room B, TraverseParms traverseParams, bool reachable)
        {
            CachedEntry2 key = new CachedEntry2(A.ID, B.ID, traverseParams);
            Dictionary <CachedEntry2, bool> cacheDict = getCacheDict(__instance);

            if (!cacheDict.ContainsKey(key))
            {
                lock (cacheDict)
                {
                    cacheDict.Add(key, reachable);
                }
            }
            return(false);
        }
예제 #10
0
        public static bool CachedResultFor(ReachabilityCache __instance, ref BoolUnknown __result, Room A, Room B, TraverseParms traverseParams)
        {
            cacheDict = getCacheDict(__instance);

            if (cacheDict.TryGetValue(new CachedEntry2(A.ID, B.ID, traverseParams), out bool value))
            {
                if (!value)
                {
                    __result = BoolUnknown.False;
                    return(false);
                }
                __result = BoolUnknown.True;
                return(false);
            }
            __result = BoolUnknown.Unknown;
            return(false);
        }
        public static bool AddCachedResult(ReachabilityCache __instance, District A, District B, TraverseParms traverseParams, bool reachable)
#endif
        {
            if (A == null || B == null)
            {
                return(false);
            }
            ReachabilityCache.CachedEntry key = new ReachabilityCache.CachedEntry(A.ID, B.ID, traverseParams);
            Dictionary <ReachabilityCache.CachedEntry, bool> cacheDict = getCacheDict(__instance);

            if (!cacheDict.ContainsKey(key))
            {
                lock (cacheDict)
                {
                    if (!cacheDict.ContainsKey(key))
                    {
                        cacheDict.Add(key, reachable);
                    }
                }
            }
            return(false);
        }
 public static bool CachedResultFor(ReachabilityCache __instance, ref BoolUnknown __result, Room A, Room B, TraverseParms traverseParams)
 public static bool AddCachedResult(ReachabilityCache __instance, Room A, Room B, TraverseParms traverseParams, bool reachable)
예제 #14
0
 public static bool Clear(ReachabilityCache __instance)
 {
     cacheDict = getCacheDict(__instance);
     cacheDict.Clear();
     return(false);
 }
예제 #15
0
 public static bool get_Count(ReachabilityCache __instance, ref int __result)
 {
     __result = getCacheDict(__instance).Count;
     return(false);
 }
예제 #16
0
        private static BoolUnknown GetCachedResult2(TraverseParms traverseParams, List <Region> this_startingRegions, List <Region> this_destRegions, ReachabilityCache this_cache)
        {
            bool flag = false;

            for (int index1 = 0; index1 < this_startingRegions.Count; ++index1)
            {
                for (int index2 = 0; index2 < this_destRegions.Count; ++index2)
                {
                    Region tsr1 = this_startingRegions[index1];
                    Region tdr2 = this_destRegions[index2];
                    if (tdr2 == tsr1)
                    {
                        return(BoolUnknown.True);
                    }
                    Room tsr1r = tsr1.Room;
                    Room tdr2r = tdr2.Room;
                    if (null != tsr1r && null != tdr2r)
                    {
                        switch (this_cache.CachedResultFor(tsr1r, tdr2r, traverseParams))
                        {
                        case BoolUnknown.True:
                            return(BoolUnknown.True);

                        case BoolUnknown.Unknown:
                            flag = true;
                            break;
                        }
                    }
                }
            }
            return(!flag ? BoolUnknown.False : BoolUnknown.Unknown);
        }
예제 #17
0
        private static bool CheckCellBasedReachability(
            IntVec3 start,
            LocalTargetInfo dest,
            PathEndMode peMode,
            TraverseParms traverseParams, RegionGrid regionGrid, Reachability __instance, List <Region> this_startingRegions,
            ReachabilityCache this_cache, List <Region> this_destRegions)
        {
            IntVec3 foundCell = IntVec3.Invalid;

            Region[]    directRegionGrid = regionGrid.DirectGrid;
            PathGrid    pathGrid         = map(__instance).pathGrid;
            CellIndices cellIndices      = map(__instance).cellIndices;

            map(__instance).floodFiller.FloodFill(start, (Predicate <IntVec3>)(c =>
            {
                int index = cellIndices.CellToIndex(c);
                if ((traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater || traverseParams.mode == TraverseMode.NoPassClosedDoorsOrWater) &&
                    c.GetTerrain(map(__instance)).IsWater)
                {
                    return(false);
                }
                if (traverseParams.mode == TraverseMode.PassAllDestroyableThings || traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater)
                {
                    if (!pathGrid.WalkableFast(index))
                    {
                        Building edifice = c.GetEdifice(map(__instance));
                        if (edifice == null || !PathFinder.IsDestroyable((Thing)edifice))
                        {
                            return(false);
                        }
                    }
                }
                else if (traverseParams.mode != TraverseMode.NoPassClosedDoorsOrWater)
                {
                    Log.ErrorOnce("Do not use this method for non-cell based modes!", 938476762, false);
                    if (!pathGrid.WalkableFast(index))
                    {
                        return(false);
                    }
                }
                Region region = directRegionGrid[index];
                return(region == null || region.Allows(traverseParams, false));
            }), (Func <IntVec3, bool>)(c =>
            {
                if (!ReachabilityImmediate.CanReachImmediate(c, dest, map(__instance), peMode, traverseParams.pawn))
                {
                    return(false);
                }
                foundCell = c;
                return(true);
            }), int.MaxValue, false, (IEnumerable <IntVec3>)null);
            if (foundCell.IsValid)
            {
                if (CanUseCache(traverseParams.mode))
                {
                    Region validRegionAt = regionGrid.GetValidRegionAt(foundCell);
                    if (validRegionAt != null)
                    {
                        for (int index = 0; index < this_startingRegions.Count; ++index)
                        {
                            this_cache.AddCachedResult(this_startingRegions[index].Room, validRegionAt.Room, traverseParams, true);
                        }
                    }
                }
                return(true);
            }
            if (CanUseCache(traverseParams.mode))
            {
                for (int index1 = 0; index1 < this_startingRegions.Count; ++index1)
                {
                    for (int index2 = 0; index2 < this_destRegions.Count; ++index2)
                    {
                        this_cache.AddCachedResult(this_startingRegions[index1].Room, this_destRegions[index2].Room, traverseParams, false);
                    }
                }
            }
            return(false);
        }
예제 #18
0
 private static bool CheckRegionBasedReachability(TraverseParms traverseParams, Queue <Region> this_openQueue, uint this_reachedIndex,
                                                  List <Region> this_destRegions, List <Region> this_startingRegions, ReachabilityCache this_cache, ref int this_numRegionsOpened, HashSet <Region> regionsReached)
 {
     while (this_openQueue.Count > 0)
     {
         Region region1 = this_openQueue.Dequeue();
         for (int index1 = 0; index1 < region1.links.Count; ++index1)
         {
             RegionLink link = region1.links[index1];
             for (int index2 = 0; index2 < 2; ++index2)
             {
                 Region region2 = link.regions[index2];
                 if (region2 != null && !regionsReached.Contains(region2) && region2.type.Passable() && region2.Allows(traverseParams, false))
                 {
                     if (this_destRegions.Contains(region2))
                     {
                         for (int index3 = 0; index3 < this_startingRegions.Count; ++index3)
                         {
                             Region regionA = this_startingRegions[index3];
                             Room   roomA   = null;
                             if (regionA != null)
                             {
                                 roomA = regionA.Room;
                                 this_cache.AddCachedResult(roomA, region2.Room, traverseParams, true);
                             }
                         }
                         return(true);
                     }
                     QueueNewOpenRegion(region2,
                                        this_reachedIndex, this_openQueue, ref this_numRegionsOpened, regionsReached
                                        );
                 }
             }
         }
     }
     for (int index1 = 0; index1 < this_startingRegions.Count; ++index1)
     {
         for (int index2 = 0; index2 < this_destRegions.Count; ++index2)
         {
             this_cache.AddCachedResult(this_startingRegions[index1].Room, this_destRegions[index2].Room, traverseParams, false);
         }
     }
     return(false);
 }
예제 #19
0
        public static bool CanReach(Reachability __instance, ref bool __result,
                                    IntVec3 start,
                                    LocalTargetInfo dest,
                                    PathEndMode peMode,
                                    TraverseParms traverseParams)
        {
            /*
             * if (working)
             * {
             *  Log.ErrorOnce("Called CanReach() while working. This should never happen. Suppressing further errors.", 7312233);
             *  return false;
             * }
             */

            Map this_map = map(__instance);

            if (traverseParams.pawn != null)
            {
                if (!traverseParams.pawn.Spawned)
                {
                    __result = false;
                    return(false);
                }
                if (traverseParams.pawn.Map != this_map)
                {
                    Log.Error("Called CanReach() with a pawn spawned not on this map. This means that we can't check his reachability here. Pawn's current map should have been used instead of this one. pawn=" +
                              (object)traverseParams.pawn + " pawn.Map=" + (object)traverseParams.pawn.Map + " map=" + (object)map(__instance), false);
                    __result = false;
                    return(false);
                }
            }
            if (ReachabilityImmediate.CanReachImmediate(start, dest, this_map, peMode, traverseParams.pawn))
            {
                __result = true;
                return(false);
            }
            if (!dest.IsValid || dest.HasThing && dest.Thing.Map != this_map || (!start.InBounds(this_map) || !dest.Cell.InBounds(this_map)))
            {
                __result = false;
                return(false);
            }
            if ((peMode == PathEndMode.OnCell || peMode == PathEndMode.Touch || peMode == PathEndMode.ClosestTouch) && (traverseParams.mode != TraverseMode.NoPassClosedDoorsOrWater && traverseParams.mode != TraverseMode.PassAllDestroyableThingsNotWater))
            {
                Room room = RegionAndRoomQuery.RoomAtFast(start, this_map, RegionType.Set_Passable);
                if (room != null && room == RegionAndRoomQuery.RoomAtFast(dest.Cell, this_map, RegionType.Set_Passable))
                {
                    __result = true;
                    return(false);
                }
            }
            if (traverseParams.mode == TraverseMode.PassAllDestroyableThings)
            {
                TraverseParms traverseParams1 = traverseParams;
                traverseParams1.mode = TraverseMode.PassDoors;
                if (__instance.CanReach(start, dest, peMode, traverseParams1))
                {
                    __result = true;
                    return(false);
                }
            }
            dest = (LocalTargetInfo)GenPath.ResolvePathMode(traverseParams.pawn, dest.ToTargetInfo(this_map), ref peMode);
            //working = true;
            try
            {
                uint this_reachedIndex;                                   //Replaced reachedIndex
                lock (reachedIndexLock)                                   //Added
                {
                    this_reachedIndex   = offsetReachedIndex;             //Added
                    offsetReachedIndex += 100000;                         //Added
                }
                HashSet <Region> regionsReached = new HashSet <Region>(); //Added
                PathGrid         pathGrid       = this_map.pathGrid;      //Replaced pathGrid
                RegionGrid       regionGrid     = this_map.regionGrid;    //Replaced regionGrid
                ++this_reachedIndex;                                      //Replaced reachedIndex

                //this_destRegions.Clear();
                List <Region> this_destRegions = new List <Region>(); //Replaced destRegions
                switch (peMode)
                {
                case PathEndMode.OnCell:
                    Region region = dest.Cell.GetRegion(this_map, RegionType.Set_Passable);
                    if (region != null && region.Allows(traverseParams, true))
                    {
                        this_destRegions.Add(region);
                        break;
                    }
                    break;

                case PathEndMode.Touch:
                    TouchPathEndModeUtility.AddAllowedAdjacentRegions(dest, traverseParams, this_map, this_destRegions);
                    break;
                }
                if (this_destRegions.Count == 0 && traverseParams.mode != TraverseMode.PassAllDestroyableThings && traverseParams.mode != TraverseMode.PassAllDestroyableThingsNotWater)
                {
                    //this.FinalizeCheck();
                    __result = false;
                    return(false);
                }
                this_destRegions.RemoveDuplicates <Region>();
                //this_openQueue.Clear();
                Queue <Region> this_openQueue        = new Queue <Region>(); //Replaced openQueue
                int            this_numRegionsOpened = 0;                    //Replaced numRegionsOpened
                List <Region>  this_startingRegions  = new List <Region>();
                DetermineStartRegions2(__instance, start, this_startingRegions, pathGrid, regionGrid, this_reachedIndex, this_openQueue, ref this_numRegionsOpened, regionsReached);
                if (this_openQueue.Count == 0 && traverseParams.mode != TraverseMode.PassAllDestroyableThings && traverseParams.mode != TraverseMode.PassAllDestroyableThingsNotWater)
                {
                    //this.FinalizeCheck();
                    __result = false;
                    return(false);
                }
                ReachabilityCache this_cache = cache(__instance);
                if (this_startingRegions.Any <Region>() && this_destRegions.Any <Region>() && CanUseCache(traverseParams.mode))
                {
                    switch (GetCachedResult2(traverseParams, this_startingRegions, this_destRegions, this_cache))
                    {
                    case BoolUnknown.True:
                        //this.FinalizeCheck();
                        __result = true;
                        return(false);

                    case BoolUnknown.False:
                        //this.FinalizeCheck();
                        __result = false;
                        return(false);
                    }
                }
                if (traverseParams.mode == TraverseMode.PassAllDestroyableThings || traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater || traverseParams.mode == TraverseMode.NoPassClosedDoorsOrWater)
                {
                    int num = CheckCellBasedReachability(start, dest, peMode, traverseParams,
                                                         regionGrid, __instance, this_startingRegions, this_cache, this_destRegions
                                                         ) ? 1 : 0;
                    //this.FinalizeCheck();
                    __result = num != 0;
                    return(false);
                }
                int num1 = CheckRegionBasedReachability(traverseParams,
                                                        this_openQueue, this_reachedIndex,
                                                        this_destRegions, this_startingRegions, this_cache, ref this_numRegionsOpened, regionsReached
                                                        ) ? 1 : 0;
                //this.FinalizeCheck();
                __result = num1 != 0;
                return(false);
            }
            finally
            {
            }
        }