Exemple #1
0
        public static void GetTouchableRegions(Thing thing, Map map, List <Region> outRegions, bool allowAdjacentEvenIfCantTouch = false)
        {
            outRegions.Clear();
            CellRect cellRect  = thing.OccupiedRect();
            CellRect cellRect2 = cellRect;

            if (RegionListersUpdater.CanRegisterInAdjacentRegions(thing))
            {
                cellRect2 = cellRect2.ExpandedBy(1);
            }
            CellRect.CellRectIterator iterator = cellRect2.GetIterator();
            while (!iterator.Done())
            {
                IntVec3 current = iterator.Current;
                if (current.InBounds(map))
                {
                    Region validRegionAt_NoRebuild = map.regionGrid.GetValidRegionAt_NoRebuild(current);
                    if (validRegionAt_NoRebuild != null && validRegionAt_NoRebuild.type.Passable() && !outRegions.Contains(validRegionAt_NoRebuild))
                    {
                        if (cellRect.Contains(current))
                        {
                            outRegions.Add(validRegionAt_NoRebuild);
                        }
                        else if (allowAdjacentEvenIfCantTouch || ReachabilityImmediate.CanReachImmediate(current, thing, map, PathEndMode.Touch, null))
                        {
                            outRegions.Add(validRegionAt_NoRebuild);
                        }
                    }
                }
                iterator.MoveNext();
            }
        }
Exemple #2
0
        public bool TryFindShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine)
        {
            if (targ.HasThing && targ.Thing.Map != caster.Map)
            {
                resultingLine = default(ShootLine);
                return(false);
            }
            if (verbProps.IsMeleeAttack || verbProps.range <= 1.42f)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(ReachabilityImmediate.CanReachImmediate(root, targ, caster.Map, PathEndMode.Touch, null));
            }
            CellRect cellRect = targ.HasThing ? targ.Thing.OccupiedRect() : CellRect.SingleCell(targ.Cell);
            float    num      = verbProps.EffectiveMinRange(targ, caster);
            float    num2     = cellRect.ClosestDistSquaredTo(root);

            if (num2 > verbProps.range * verbProps.range || num2 < num * num)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(false);
            }
            if (!verbProps.requireLineOfSight)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(true);
            }
            IntVec3 goodDest;

            if (CasterIsPawn)
            {
                if (CanHitFromCellIgnoringRange(root, targ, out goodDest))
                {
                    resultingLine = new ShootLine(root, goodDest);
                    return(true);
                }
                ShootLeanUtility.LeanShootingSourcesFromTo(root, cellRect.ClosestCellTo(root), caster.Map, tempLeanShootSources);
                for (int i = 0; i < tempLeanShootSources.Count; i++)
                {
                    IntVec3 intVec = tempLeanShootSources[i];
                    if (CanHitFromCellIgnoringRange(intVec, targ, out goodDest))
                    {
                        resultingLine = new ShootLine(intVec, goodDest);
                        return(true);
                    }
                }
            }
            else
            {
                foreach (IntVec3 item in caster.OccupiedRect())
                {
                    if (CanHitFromCellIgnoringRange(item, targ, out goodDest))
                    {
                        resultingLine = new ShootLine(item, goodDest);
                        return(true);
                    }
                }
            }
            resultingLine = new ShootLine(root, targ.Cell);
            return(false);
        }
        public static void GetTouchableRegions(Thing thing, Map map, List <Region> outRegions, bool allowAdjacentEvenIfCantTouch = false)
        {
            outRegions.Clear();
            CellRect cellRect  = thing.OccupiedRect();
            CellRect cellRect2 = cellRect;

            if (CanRegisterInAdjacentRegions(thing))
            {
                cellRect2 = cellRect2.ExpandedBy(1);
            }
            foreach (IntVec3 item in cellRect2)
            {
                if (item.InBounds(map))
                {
                    Region validRegionAt_NoRebuild = map.regionGrid.GetValidRegionAt_NoRebuild(item);
                    if (validRegionAt_NoRebuild != null && validRegionAt_NoRebuild.type.Passable() && !outRegions.Contains(validRegionAt_NoRebuild))
                    {
                        if (cellRect.Contains(item))
                        {
                            outRegions.Add(validRegionAt_NoRebuild);
                        }
                        else if (allowAdjacentEvenIfCantTouch || ReachabilityImmediate.CanReachImmediate(item, thing, map, PathEndMode.Touch, null))
                        {
                            outRegions.Add(validRegionAt_NoRebuild);
                        }
                    }
                }
            }
        }
 public static bool CanReachImmediate(this Pawn pawn, LocalTargetInfo target, PathEndMode peMode)
 {
     if (!pawn.Spawned)
     {
         return(false);
     }
     return(ReachabilityImmediate.CanReachImmediate(pawn.Position, target, pawn.Map, peMode, pawn));
 }
 internal bool <> m__1(IntVec3 c)
 {
     if (ReachabilityImmediate.CanReachImmediate(c, this.dest, this.$this.map, this.peMode, this.traverseParams.pawn))
     {
         this.foundCell = c;
         return(true);
     }
     return(false);
 }
            internal bool <> m__1(IntVec3 c)
            {
                bool result;

                if (ReachabilityImmediate.CanReachImmediate(c, this.dest, this.$this.map, this.peMode, this.traverseParams.pawn))
                {
                    this.foundCell = c;
                    result         = true;
                }
                else
                {
                    result = false;
                }
                return(result);
            }
Exemple #7
0
        public bool CanReach(IntVec3 start, LocalTargetInfo dest, PathEndMode peMode, TraverseParms traverseParams)
        {
            if (this.working)
            {
                Log.ErrorOnce("Called CanReach() while working. This should never happen. Suppressing further errors.", 7312233, false);
                return(false);
            }
            if (traverseParams.pawn != null)
            {
                if (!traverseParams.pawn.Spawned)
                {
                    return(false);
                }
                if (traverseParams.pawn.Map != this.map)
                {
                    Log.Error(string.Concat(new object[]
                    {
                        "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=",
                        traverseParams.pawn,
                        " pawn.Map=",
                        traverseParams.pawn.Map,
                        " map=",
                        this.map
                    }), false);
                    return(false);
                }
            }
            if (ReachabilityImmediate.CanReachImmediate(start, dest, this.map, peMode, traverseParams.pawn))
            {
                return(true);
            }
            if (!dest.IsValid)
            {
                return(false);
            }
            if (dest.HasThing && dest.Thing.Map != this.map)
            {
                return(false);
            }
            if (!start.InBounds(this.map) || !dest.Cell.InBounds(this.map))
            {
                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))
                {
                    return(true);
                }
            }
            if (traverseParams.mode == TraverseMode.PassAllDestroyableThings)
            {
                TraverseParms traverseParams2 = traverseParams;
                traverseParams2.mode = TraverseMode.PassDoors;
                if (this.CanReach(start, dest, peMode, traverseParams2))
                {
                    return(true);
                }
            }
            dest         = (LocalTargetInfo)GenPath.ResolvePathMode(traverseParams.pawn, dest.ToTargetInfo(this.map), ref peMode);
            this.working = true;
            bool result;

            try
            {
                this.pathGrid      = this.map.pathGrid;
                this.regionGrid    = this.map.regionGrid;
                this.reachedIndex += 1u;
                this.destRegions.Clear();
                if (peMode == PathEndMode.OnCell)
                {
                    Region region = dest.Cell.GetRegion(this.map, RegionType.Set_Passable);
                    if (region != null && region.Allows(traverseParams, true))
                    {
                        this.destRegions.Add(region);
                    }
                }
                else if (peMode == PathEndMode.Touch)
                {
                    TouchPathEndModeUtility.AddAllowedAdjacentRegions(dest, traverseParams, this.map, this.destRegions);
                }
                if (this.destRegions.Count == 0 && traverseParams.mode != TraverseMode.PassAllDestroyableThings && traverseParams.mode != TraverseMode.PassAllDestroyableThingsNotWater)
                {
                    this.FinalizeCheck();
                    result = false;
                }
                else
                {
                    this.destRegions.RemoveDuplicates <Region>();
                    this.openQueue.Clear();
                    this.numRegionsOpened = 0;
                    this.DetermineStartRegions(start);
                    if (this.openQueue.Count == 0 && traverseParams.mode != TraverseMode.PassAllDestroyableThings && traverseParams.mode != TraverseMode.PassAllDestroyableThingsNotWater)
                    {
                        this.FinalizeCheck();
                        result = false;
                    }
                    else
                    {
                        if (this.startingRegions.Any <Region>() && this.destRegions.Any <Region>() && this.CanUseCache(traverseParams.mode))
                        {
                            BoolUnknown cachedResult = this.GetCachedResult(traverseParams);
                            if (cachedResult == BoolUnknown.True)
                            {
                                this.FinalizeCheck();
                                result = true;
                                return(result);
                            }
                            if (cachedResult == BoolUnknown.False)
                            {
                                this.FinalizeCheck();
                                result = false;
                                return(result);
                            }
                            if (cachedResult != BoolUnknown.Unknown)
                            {
                            }
                        }
                        if (traverseParams.mode == TraverseMode.PassAllDestroyableThings || traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater || traverseParams.mode == TraverseMode.NoPassClosedDoorsOrWater)
                        {
                            bool flag = this.CheckCellBasedReachability(start, dest, peMode, traverseParams);
                            this.FinalizeCheck();
                            result = flag;
                        }
                        else
                        {
                            bool flag2 = this.CheckRegionBasedReachability(traverseParams);
                            this.FinalizeCheck();
                            result = flag2;
                        }
                    }
                }
            }
            finally
            {
                this.working = false;
            }
            return(result);
        }
Exemple #8
0
        private bool CheckCellBasedReachability(IntVec3 start, LocalTargetInfo dest, PathEndMode peMode, TraverseParms traverseParams)
        {
            IntVec3 foundCell = IntVec3.Invalid;

            Region[]    directRegionGrid = this.regionGrid.DirectGrid;
            PathGrid    pathGrid         = this.map.pathGrid;
            CellIndices cellIndices      = this.map.cellIndices;

            this.map.floodFiller.FloodFill(start, delegate(IntVec3 c)
            {
                int num = cellIndices.CellToIndex(c);
                if ((traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater || traverseParams.mode == TraverseMode.NoPassClosedDoorsOrWater) && c.GetTerrain(this.map).IsWater)
                {
                    return(false);
                }
                if (traverseParams.mode == TraverseMode.PassAllDestroyableThings || traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater)
                {
                    if (!pathGrid.WalkableFast(num))
                    {
                        Building edifice = c.GetEdifice(this.map);
                        if (edifice == null || !PathFinder.IsDestroyable(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(num))
                    {
                        return(false);
                    }
                }
                Region region = directRegionGrid[num];
                return(region == null || region.Allows(traverseParams, false));
            }, delegate(IntVec3 c)
            {
                if (ReachabilityImmediate.CanReachImmediate(c, dest, this.map, peMode, traverseParams.pawn))
                {
                    foundCell = c;
                    return(true);
                }
                return(false);
            }, 2147483647, false, null);
            if (foundCell.IsValid)
            {
                if (this.CanUseCache(traverseParams.mode))
                {
                    Region validRegionAt = this.regionGrid.GetValidRegionAt(foundCell);
                    if (validRegionAt != null)
                    {
                        for (int i = 0; i < this.startingRegions.Count; i++)
                        {
                            this.cache.AddCachedResult(this.startingRegions[i].Room, validRegionAt.Room, traverseParams, true);
                        }
                    }
                }
                return(true);
            }
            if (this.CanUseCache(traverseParams.mode))
            {
                for (int j = 0; j < this.startingRegions.Count; j++)
                {
                    for (int k = 0; k < this.destRegions.Count; k++)
                    {
                        this.cache.AddCachedResult(this.startingRegions[j].Room, this.destRegions[k].Room, traverseParams, false);
                    }
                }
            }
            return(false);
        }
        public static IntVec3 InteractionCellWhenAt(ThingDef def, IntVec3 center, Rot4 rot, Map map)
        {
            if (def.hasInteractionCell)
            {
                IntVec3 b = def.interactionCellOffset.RotatedBy(rot);
                return(center + b);
            }
            if (def.Size.x == 1 && def.Size.z == 1)
            {
                for (int i = 0; i < 8; i++)
                {
                    IntVec3 intVec = center + GenAdj.AdjacentCells[i];
                    if (intVec.Standable(map) && intVec.GetDoor(map) == null && ReachabilityImmediate.CanReachImmediate(intVec, center, map, PathEndMode.Touch, null))
                    {
                        return(intVec);
                    }
                }
                for (int j = 0; j < 8; j++)
                {
                    IntVec3 intVec2 = center + GenAdj.AdjacentCells[j];
                    if (intVec2.Standable(map) && ReachabilityImmediate.CanReachImmediate(intVec2, center, map, PathEndMode.Touch, null))
                    {
                        return(intVec2);
                    }
                }
                for (int k = 0; k < 8; k++)
                {
                    IntVec3 intVec3 = center + GenAdj.AdjacentCells[k];
                    if (intVec3.Walkable(map) && ReachabilityImmediate.CanReachImmediate(intVec3, center, map, PathEndMode.Touch, null))
                    {
                        return(intVec3);
                    }
                }
                return(center);
            }
            List <IntVec3> list = GenAdjFast.AdjacentCells8Way(center, rot, def.size);
            CellRect       rect = GenAdj.OccupiedRect(center, rot, def.size);

            for (int l = 0; l < list.Count; l++)
            {
                if (list[l].Standable(map) && list[l].GetDoor(map) == null && ReachabilityImmediate.CanReachImmediate(list[l], rect, map, PathEndMode.Touch, null))
                {
                    return(list[l]);
                }
            }
            for (int m = 0; m < list.Count; m++)
            {
                if (list[m].Standable(map) && ReachabilityImmediate.CanReachImmediate(list[m], rect, map, PathEndMode.Touch, null))
                {
                    return(list[m]);
                }
            }
            for (int n = 0; n < list.Count; n++)
            {
                if (list[n].Walkable(map) && ReachabilityImmediate.CanReachImmediate(list[n], rect, map, PathEndMode.Touch, null))
                {
                    return(list[n]);
                }
            }
            return(center);
        }
        public bool TryFindShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine)
        {
            if (targ.HasThing && targ.Thing.Map != this.caster.Map)
            {
                resultingLine = default(ShootLine);
                return(false);
            }
            if (this.verbProps.IsMeleeAttack || this.verbProps.range <= 1.42f)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(ReachabilityImmediate.CanReachImmediate(root, targ, this.caster.Map, PathEndMode.Touch, null));
            }
            CellRect cellRect = (!targ.HasThing) ? CellRect.SingleCell(targ.Cell) : targ.Thing.OccupiedRect();
            float    num      = this.verbProps.EffectiveMinRange(targ, this.caster);
            float    num2     = cellRect.ClosestDistSquaredTo(root);

            if (num2 > this.verbProps.range * this.verbProps.range || num2 < num * num)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(false);
            }
            if (!this.verbProps.requireLineOfSight)
            {
                resultingLine = new ShootLine(root, targ.Cell);
                return(true);
            }
            if (this.CasterIsPawn)
            {
                IntVec3 dest;
                if (this.CanHitFromCellIgnoringRange(root, targ, out dest))
                {
                    resultingLine = new ShootLine(root, dest);
                    return(true);
                }
                ShootLeanUtility.LeanShootingSourcesFromTo(root, cellRect.ClosestCellTo(root), this.caster.Map, Verb.tempLeanShootSources);
                for (int i = 0; i < Verb.tempLeanShootSources.Count; i++)
                {
                    IntVec3 intVec = Verb.tempLeanShootSources[i];
                    if (this.CanHitFromCellIgnoringRange(intVec, targ, out dest))
                    {
                        resultingLine = new ShootLine(intVec, dest);
                        return(true);
                    }
                }
            }
            else
            {
                CellRect.CellRectIterator iterator = this.caster.OccupiedRect().GetIterator();
                while (!iterator.Done())
                {
                    IntVec3 intVec2 = iterator.Current;
                    IntVec3 dest;
                    if (this.CanHitFromCellIgnoringRange(intVec2, targ, out dest))
                    {
                        resultingLine = new ShootLine(intVec2, dest);
                        return(true);
                    }
                    iterator.MoveNext();
                }
            }
            resultingLine = new ShootLine(root, targ.Cell);
            return(false);
        }
Exemple #11
0
        public bool CanReach(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);
            }
            if (traverseParams.pawn != null)
            {
                if (!traverseParams.pawn.Spawned)
                {
                    return(false);
                }
                if (traverseParams.pawn.Map != map)
                {
                    Log.Error(string.Concat("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=", traverseParams.pawn, " pawn.Map=", traverseParams.pawn.Map, " map=", map));
                    return(false);
                }
            }
            if (ReachabilityImmediate.CanReachImmediate(start, dest, map, peMode, traverseParams.pawn))
            {
                return(true);
            }
            if (!dest.IsValid)
            {
                return(false);
            }
            if (dest.HasThing && dest.Thing.Map != map)
            {
                return(false);
            }
            if (!start.InBounds(map) || !dest.Cell.InBounds(map))
            {
                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, map);
                if (room != null && room == RegionAndRoomQuery.RoomAtFast(dest.Cell, map))
                {
                    return(true);
                }
            }
            if (traverseParams.mode == TraverseMode.PassAllDestroyableThings)
            {
                TraverseParms traverseParams2 = traverseParams;
                traverseParams2.mode = TraverseMode.PassDoors;
                if (CanReach(start, dest, peMode, traverseParams2))
                {
                    return(true);
                }
            }
            dest    = (LocalTargetInfo)GenPath.ResolvePathMode(traverseParams.pawn, dest.ToTargetInfo(map), ref peMode);
            working = true;
            try
            {
                pathGrid   = map.pathGrid;
                regionGrid = map.regionGrid;
                reachedIndex++;
                destRegions.Clear();
                switch (peMode)
                {
                case PathEndMode.OnCell:
                {
                    Region region = dest.Cell.GetRegion(map);
                    if (region != null && region.Allows(traverseParams, isDestination: true))
                    {
                        destRegions.Add(region);
                    }
                    break;
                }

                case PathEndMode.Touch:
                    TouchPathEndModeUtility.AddAllowedAdjacentRegions(dest, traverseParams, map, destRegions);
                    break;
                }
                if (destRegions.Count == 0 && traverseParams.mode != TraverseMode.PassAllDestroyableThings && traverseParams.mode != TraverseMode.PassAllDestroyableThingsNotWater)
                {
                    FinalizeCheck();
                    return(false);
                }
                destRegions.RemoveDuplicates();
                openQueue.Clear();
                numRegionsOpened = 0;
                DetermineStartRegions(start);
                if (openQueue.Count == 0 && traverseParams.mode != TraverseMode.PassAllDestroyableThings && traverseParams.mode != TraverseMode.PassAllDestroyableThingsNotWater)
                {
                    FinalizeCheck();
                    return(false);
                }
                if (startingRegions.Any() && destRegions.Any() && CanUseCache(traverseParams.mode))
                {
                    switch (GetCachedResult(traverseParams))
                    {
                    case BoolUnknown.True:
                        FinalizeCheck();
                        return(true);

                    case BoolUnknown.False:
                        FinalizeCheck();
                        return(false);
                    }
                }
                if (traverseParams.mode == TraverseMode.PassAllDestroyableThings || traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater || traverseParams.mode == TraverseMode.NoPassClosedDoorsOrWater)
                {
                    bool result = CheckCellBasedReachability(start, dest, peMode, traverseParams);
                    FinalizeCheck();
                    return(result);
                }
                bool result2 = CheckRegionBasedReachability(traverseParams);
                FinalizeCheck();
                return(result2);
            }
            finally
            {
                working = false;
            }
        }
Exemple #12
0
        public static bool CanReachImmediate(IntVec3 start, CellRect rect, Map map, PathEndMode peMode, Pawn pawn)
        {
            IntVec3 c = rect.ClosestCellTo(start);

            return(ReachabilityImmediate.CanReachImmediate(start, c, map, peMode, pawn));
        }