예제 #1
0
        public static bool TryFindRandomSpawnCellForPawnNear(IntVec3 root, Map map, out IntVec3 result, int firstTryWithRadius = 4)
        {
            if (root.Standable(map) && root.GetFirstPawn(map) == null)
            {
                result = root;
                return(true);
            }
            bool rootFogged = root.Fogged(map);
            int  num        = firstTryWithRadius;

            for (int i = 0; i < 3; i++)
            {
                if (TryFindRandomReachableCellNear(root, map, num, TraverseParms.For(TraverseMode.NoPassClosedDoors), (IntVec3 c) => c.Standable(map) && (rootFogged || !c.Fogged(map)) && c.GetFirstPawn(map) == null, null, out result))
                {
                    return(true);
                }
                num *= 2;
            }
            num = firstTryWithRadius + 1;
            while (true)
            {
                if (TryRandomClosewalkCellNear(root, map, num, out result))
                {
                    return(true);
                }
                if (num > map.Size.x / 2 && num > map.Size.z / 2)
                {
                    break;
                }
                num *= 2;
            }
            result = root;
            return(false);
        }
예제 #2
0
 protected virtual bool CanScatterAt(IntVec3 loc, Map map)
 {
     if (this.extraNoBuildEdgeDist > 0 && loc.CloseToEdge(map, this.extraNoBuildEdgeDist + 10))
     {
         return(false);
     }
     if (this.minEdgeDist > 0 && loc.CloseToEdge(map, this.minEdgeDist))
     {
         return(false);
     }
     if (this.NearUsedSpot(loc, this.minSpacing))
     {
         return(false);
     }
     if ((map.Center - loc).LengthHorizontalSquared < this.minDistToPlayerStart * this.minDistToPlayerStart)
     {
         return(false);
     }
     if (this.spotMustBeStandable && !loc.Standable(map))
     {
         return(false);
     }
     if (this.validators != null)
     {
         for (int i = 0; i < this.validators.Count; i++)
         {
             if (!this.validators[i].Allows(loc, map))
             {
                 return(false);
             }
         }
     }
     return(true);
 }
예제 #3
0
 private bool CanHitCellFromCellIgnoringRange(IntVec3 sourceSq, IntVec3 targetLoc, bool includeCorners = false)
 {
     if (this.verbProps.mustCastOnOpenGround)
     {
         if (!targetLoc.Standable(this.caster.Map) || this.caster.Map.thingGrid.CellContains(targetLoc, ThingCategory.Pawn))
         {
             return(false);
         }
     }
     if (this.verbProps.requireLineOfSight)
     {
         if (!includeCorners)
         {
             if (!GenSight.LineOfSight(sourceSq, targetLoc, this.caster.Map, true, null, 0, 0))
             {
                 return(false);
             }
         }
         else if (!GenSight.LineOfSightToEdges(sourceSq, targetLoc, this.caster.Map, true, null))
         {
             return(false);
         }
     }
     return(true);
 }
예제 #4
0
        public static bool TryFindSkyfallerCell(ThingDef skyfaller, Map map, out IntVec3 cell, int minDistToEdge = 10, IntVec3 nearLoc = default(IntVec3), int nearLocMaxDist = -1, bool allowRoofedCells = true, bool allowCellsWithItems = false, bool allowCellsWithBuildings = false, bool colonyReachable = false, bool avoidColonistsIfExplosive = true, bool alwaysAvoidColonists = false, Predicate <IntVec3> extraValidator = null)
        {
            bool avoidColonists           = (avoidColonistsIfExplosive && skyfaller.skyfaller.CausesExplosion) || alwaysAvoidColonists;
            Predicate <IntVec3> validator = delegate(IntVec3 x)
            {
                CellRect.CellRectIterator iterator = GenAdj.OccupiedRect(x, Rot4.North, skyfaller.size).GetIterator();
                while (!iterator.Done())
                {
                    IntVec3 current = iterator.Current;
                    if (!current.InBounds(map) || current.Fogged(map) || !current.Standable(map) || (current.Roofed(map) && current.GetRoof(map).isThickRoof))
                    {
                        return(false);
                    }
                    if (!allowRoofedCells && current.Roofed(map))
                    {
                        return(false);
                    }
                    if (!allowCellsWithItems && current.GetFirstItem(map) != null)
                    {
                        return(false);
                    }
                    if (!allowCellsWithBuildings && current.GetFirstBuilding(map) != null)
                    {
                        return(false);
                    }
                    if (current.GetFirstSkyfaller(map) != null)
                    {
                        return(false);
                    }
                    iterator.MoveNext();
                }
                if (avoidColonists && SkyfallerUtility.CanPossiblyFallOnColonist(skyfaller, x, map))
                {
                    return(false);
                }
                if (minDistToEdge > 0 && x.DistanceToEdge(map) < minDistToEdge)
                {
                    return(false);
                }
                if (colonyReachable && !map.reachability.CanReachColony(x))
                {
                    return(false);
                }
                if (extraValidator != null && !extraValidator(x))
                {
                    return(false);
                }
                return(true);
            };

            if (nearLocMaxDist > 0)
            {
                return(CellFinder.TryFindRandomCellNear(nearLoc, map, nearLocMaxDist, validator, out cell));
            }
            return(TryFindRandomNotEdgeCellWith(minDistToEdge, validator, map, out cell));
        }
예제 #5
0
        public static bool TryFindSkyfallerCell(ThingDef skyfaller, Map map, out IntVec3 cell, int minDistToEdge = 10, IntVec3 nearLoc = default(IntVec3), int nearLocMaxDist = -1, bool allowRoofedCells = true, bool allowCellsWithItems = false, bool allowCellsWithBuildings = false, bool colonyReachable = false, bool avoidColonistsIfExplosive = true, bool alwaysAvoidColonists = false, Predicate <IntVec3> extraValidator = null)
        {
            bool avoidColonists           = (avoidColonistsIfExplosive && skyfaller.skyfaller.CausesExplosion) || alwaysAvoidColonists;
            Predicate <IntVec3> validator = delegate(IntVec3 x)
            {
                CellRect.CellRectIterator iterator = GenAdj.OccupiedRect(x, Rot4.North, skyfaller.size).GetIterator();
                while (!iterator.Done())
                {
                    IntVec3 c = iterator.Current;
                    bool    result2;
                    if (!c.InBounds(map) || c.Fogged(map) || !c.Standable(map) || (c.Roofed(map) && c.GetRoof(map).isThickRoof))
                    {
                        result2 = false;
                    }
                    else if (!allowRoofedCells && c.Roofed(map))
                    {
                        result2 = false;
                    }
                    else if (!allowCellsWithItems && c.GetFirstItem(map) != null)
                    {
                        result2 = false;
                    }
                    else if (!allowCellsWithBuildings && c.GetFirstBuilding(map) != null)
                    {
                        result2 = false;
                    }
                    else
                    {
                        if (c.GetFirstSkyfaller(map) == null)
                        {
                            iterator.MoveNext();
                            continue;
                        }
                        result2 = false;
                    }
                    return(result2);
                }
                return((!avoidColonists || !SkyfallerUtility.CanPossiblyFallOnColonist(skyfaller, x, map)) && (minDistToEdge <= 0 || x.DistanceToEdge(map) >= minDistToEdge) && (!colonyReachable || map.reachability.CanReachColony(x)) && (extraValidator == null || extraValidator(x)));
            };
            bool result;

            if (nearLocMaxDist > 0)
            {
                result = CellFinder.TryFindRandomCellNear(nearLoc, map, nearLocMaxDist, validator, out cell, -1);
            }
            else
            {
                result = CellFinderLoose.TryFindRandomNotEdgeCellWith(minDistToEdge, validator, map, out cell);
            }
            return(result);
        }
예제 #6
0
        public static bool CanFleeToLocation(Pawn pawn, IntVec3 location)
        {
            if (!location.Standable(pawn.Map))
            {
                return(false);
            }
            if (!pawn.Map.pawnDestinationReservationManager.CanReserve(location, pawn, false))
            {
                return(false);
            }
            Region region = location.GetRegion(pawn.Map, RegionType.Set_Passable);

            return(region.type != RegionType.Portal && pawn.CanReach(location, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn));
        }
예제 #7
0
        public virtual IEnumerable <IntVec3> ExplosionCellsToHit(IntVec3 center, Map map, float radius)
        {
            DamageWorker.openCells.Clear();
            DamageWorker.adjWallCells.Clear();
            int num = GenRadial.NumCellsInRadius(radius);

            for (int i = 0; i < num; i++)
            {
                IntVec3 intVec = center + GenRadial.RadialPattern[i];
                if (intVec.InBounds(map))
                {
                    if (GenSight.LineOfSight(center, intVec, map, true, null, 0, 0))
                    {
                        DamageWorker.openCells.Add(intVec);
                    }
                }
            }
            for (int j = 0; j < DamageWorker.openCells.Count; j++)
            {
                IntVec3 intVec2 = DamageWorker.openCells[j];
                if (intVec2.Walkable(map))
                {
                    for (int k = 0; k < 4; k++)
                    {
                        IntVec3 intVec3 = intVec2 + GenAdj.CardinalDirections[k];
                        if (intVec3.InHorDistOf(center, radius))
                        {
                            if (intVec3.InBounds(map))
                            {
                                if (!intVec3.Standable(map))
                                {
                                    if (intVec3.GetEdifice(map) != null)
                                    {
                                        if (!DamageWorker.openCells.Contains(intVec3) && DamageWorker.adjWallCells.Contains(intVec3))
                                        {
                                            DamageWorker.adjWallCells.Add(intVec3);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(DamageWorker.openCells.Concat(DamageWorker.adjWallCells));
        }
예제 #8
0
 public static bool CanFleeToLocation(Pawn pawn, IntVec3 location)
 {
     if (!location.Standable(pawn.Map))
     {
         return(false);
     }
     if (!pawn.Map.pawnDestinationReservationManager.CanReserve(location, pawn))
     {
         return(false);
     }
     if (location.GetRegion(pawn.Map).type == RegionType.Portal)
     {
         return(false);
     }
     if (!pawn.CanReach(location, PathEndMode.OnCell, Danger.Deadly))
     {
         return(false);
     }
     return(true);
 }
예제 #9
0
        public static bool TryFindRandomSpawnCellForPawnNear(IntVec3 root, Map map, out IntVec3 result, int firstTryWithRadius = 4)
        {
            if (root.Standable(map) && root.GetFirstPawn(map) == null)
            {
                result = root;
                return(true);
            }
            bool rootFogged = root.Fogged(map);
            int  num        = firstTryWithRadius;

            for (int i = 0; i < 3; i++)
            {
                if (CellFinder.TryFindRandomReachableCellNear(root, map, (float)num, TraverseParms.For(TraverseMode.NoPassClosedDoors, Danger.Deadly, false), (Predicate <IntVec3>)((IntVec3 c) => c.Standable(map) && (rootFogged || !c.Fogged(map)) && c.GetFirstPawn(map) == null), (Predicate <Region>)null, out result, 999999))
                {
                    return(true);
                }
                num *= 2;
            }
            num = firstTryWithRadius + 1;
            while (true)
            {
                if (CellFinder.TryRandomClosewalkCellNear(root, map, num, out result, (Predicate <IntVec3>)null))
                {
                    return(true);
                }
                int     num2 = num;
                IntVec3 size = map.Size;
                if (num2 > size.x / 2)
                {
                    int     num3  = num;
                    IntVec3 size2 = map.Size;
                    if (num3 > size2.z / 2)
                    {
                        break;
                    }
                }
                num *= 2;
            }
            result = root;
            return(false);
        }
예제 #10
0
        public static bool TryFindSkyfallerCell(ThingDef skyfaller, Map map, out IntVec3 cell, int minDistToEdge = 10, IntVec3 nearLoc = default(IntVec3), int nearLocMaxDist = -1, bool allowRoofedCells = true, bool allowCellsWithItems = false, bool allowCellsWithBuildings = false, bool colonyReachable = false, Predicate <IntVec3> extraValidator = null)
        {
            Predicate <IntVec3> validator = delegate(IntVec3 x)
            {
                CellRect.CellRectIterator iterator = GenAdj.OccupiedRect(x, Rot4.North, skyfaller.size).GetIterator();
                while (!iterator.Done())
                {
                    IntVec3 current = iterator.Current;
                    if (!current.InBounds(map) || current.Fogged(map) || !current.Standable(map) || (current.Roofed(map) && current.GetRoof(map).isThickRoof))
                    {
                        return(false);
                    }
                    if (!allowRoofedCells && current.Roofed(map))
                    {
                        return(false);
                    }
                    if (!allowCellsWithItems && current.GetFirstItem(map) != null)
                    {
                        return(false);
                    }
                    if (!allowCellsWithBuildings && current.GetFirstBuilding(map) != null)
                    {
                        return(false);
                    }
                    if (current.GetFirstSkyfaller(map) != null)
                    {
                        return(false);
                    }
                    iterator.MoveNext();
                }
                return((minDistToEdge <= 0 || x.DistanceToEdge(map) >= minDistToEdge) && (!colonyReachable || map.reachability.CanReachColony(x)) && (extraValidator == null || extraValidator(x)));
            };

            if (nearLocMaxDist > 0)
            {
                return(CellFinder.TryFindRandomCellNear(nearLoc, map, nearLocMaxDist, validator, out cell));
            }
            return(CellFinderLoose.TryFindRandomNotEdgeCellWith(minDistToEdge, validator, map, out cell));
        }
예제 #11
0
        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);
        }
예제 #12
0
        public virtual IEnumerable <IntVec3> ExplosionCellsToHit(IntVec3 center, Map map, float radius)
        {
            openCells.Clear();
            adjWallCells.Clear();
            int num = GenRadial.NumCellsInRadius(radius);

            for (int i = 0; i < num; i++)
            {
                IntVec3 intVec = center + GenRadial.RadialPattern[i];
                if (intVec.InBounds(map) && GenSight.LineOfSight(center, intVec, map, skipFirstCell: true))
                {
                    openCells.Add(intVec);
                }
            }
            for (int j = 0; j < openCells.Count; j++)
            {
                IntVec3 intVec2 = openCells[j];
                if (intVec2.Walkable(map))
                {
                    for (int k = 0; k < 4; k++)
                    {
                        IntVec3 intVec3 = intVec2 + GenAdj.CardinalDirections[k];
                        if (intVec3.InHorDistOf(center, radius) && intVec3.InBounds(map) && !intVec3.Standable(map) && intVec3.GetEdifice(map) != null && !openCells.Contains(intVec3) && adjWallCells.Contains(intVec3))
                        {
                            adjWallCells.Add(intVec3);
                        }
                    }
                }
            }
            return(openCells.Concat(adjWallCells));
        }