public Region TryGenerateRegionFrom(IntVec3 root)
        {
            RegionType expectedRegionType = root.GetExpectedRegionType(this.map);

            if (expectedRegionType == RegionType.None)
            {
                return(null);
            }
            if (this.working)
            {
                Log.Error("Trying to generate a new region but we are currently generating one. Nested calls are not allowed.");
                return(null);
            }
            this.working = true;
            try
            {
                this.regionGrid  = this.map.regionGrid;
                this.newReg      = Region.MakeNewUnfilled(root, this.map);
                this.newReg.type = expectedRegionType;
                if (this.newReg.type == RegionType.Portal)
                {
                    this.newReg.portal = root.GetDoor(this.map);
                }
                this.FloodFillAndAddCells(root);
                this.CreateLinks();
                this.RegisterThingsInRegionListers();
                return(this.newReg);
            }
            finally
            {
                this.working = false;
            }
        }
        public static RegionType GetExpectedRegionType(this IntVec3 c, Map map)
        {
            RegionType result;

            if (!c.InBounds(map))
            {
                result = RegionType.None;
            }
            else if (c.GetDoor(map) != null)
            {
                result = RegionType.Portal;
            }
            else if (c.Walkable(map))
            {
                result = RegionType.Normal;
            }
            else
            {
                List <Thing> thingList = c.GetThingList(map);
                for (int i = 0; i < thingList.Count; i++)
                {
                    if (thingList[i].def.Fillage == FillCategory.Full)
                    {
                        return(RegionType.None);
                    }
                }
                result = RegionType.ImpassableFreeAirExchange;
            }
            return(result);
        }
Beispiel #3
0
        public static bool TryFindBestPawnStandCell(Pawn forPawn, out IntVec3 cell, bool cellByCell = false)
        {
            cell = IntVec3.Invalid;
            int   num    = -1;
            float radius = 10f;

            while (true)
            {
                tmpDistances.Clear();
                tmpParents.Clear();
                Dijkstra <IntVec3> .Run(forPawn.Position, (IntVec3 x) => GetAdjacentCardinalCellsForBestStandCell(x, radius, forPawn), delegate(IntVec3 from, IntVec3 to)
                {
                    float num4 = 1f;
                    if (from.x != to.x && from.z != to.z)
                    {
                        num4 = 1.41421354f;
                    }
                    if (!to.Standable(forPawn.Map))
                    {
                        num4 += 3f;
                    }
                    if (PawnUtility.AnyPawnBlockingPathAt(to, forPawn))
                    {
                        num4 = ((to.GetThingList(forPawn.Map).Find((Thing x) => x is Pawn && x.HostileTo(forPawn)) == null) ? (num4 + 15f) : (num4 + 40f));
                    }
                    Building_Door building_Door = to.GetEdifice(forPawn.Map) as Building_Door;
                    if (building_Door != null && !building_Door.FreePassage)
                    {
                        num4 = ((!building_Door.PawnCanOpen(forPawn)) ? (num4 + 50f) : (num4 + 6f));
                    }
                    return(num4);
                }, tmpDistances, tmpParents);

                if (tmpDistances.Count == num)
                {
                    return(false);
                }
                float num2 = 0f;
                foreach (KeyValuePair <IntVec3, float> tmpDistance in tmpDistances)
                {
                    if ((!cell.IsValid || !(tmpDistance.Value >= num2)) && tmpDistance.Key.Walkable(forPawn.Map) && !PawnUtility.AnyPawnBlockingPathAt(tmpDistance.Key, forPawn))
                    {
                        Building_Door door = tmpDistance.Key.GetDoor(forPawn.Map);
                        if (door == null || door.FreePassage)
                        {
                            cell = tmpDistance.Key;
                            num2 = tmpDistance.Value;
                        }
                    }
                }
                if (cell.IsValid)
                {
                    if (!cellByCell)
                    {
                        return(true);
                    }
                    IntVec3 intVec = cell;
                    int     num3   = 0;
                    while (intVec.IsValid && intVec != forPawn.Position)
                    {
                        num3++;
                        if (num3 >= 10000)
                        {
                            Log.Error("Too many iterations.");
                            break;
                        }
                        if (intVec.Walkable(forPawn.Map))
                        {
                            Building_Door door2 = intVec.GetDoor(forPawn.Map);
                            if (door2 == null || door2.FreePassage)
                            {
                                cell = intVec;
                            }
                        }
                        intVec = tmpParents[intVec];
                    }
                    return(true);
                }
                if (radius > (float)forPawn.Map.Size.x && radius > (float)forPawn.Map.Size.z)
                {
                    break;
                }
                radius *= 2f;
                num     = tmpDistances.Count;
            }
            return(false);
        }
Beispiel #4
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);
        }