public static List <IntVec3> AdjacentCells8Way(IntVec3 thingCenter, Rot4 thingRot, IntVec2 thingSize)
        {
            if (thingSize.x == 1 && thingSize.z == 1)
            {
                return(GenAdjFast.AdjacentCells8Way(thingCenter));
            }
            if (GenAdjFast.working)
            {
                throw new InvalidOperationException("GenAdjFast is already working.");
            }
            GenAdjFast.resultList.Clear();
            GenAdjFast.working = true;
            GenAdj.AdjustForRotation(ref thingCenter, ref thingSize, thingRot);
            int     num  = thingCenter.x - (thingSize.x - 1) / 2 - 1;
            int     num2 = num + thingSize.x + 1;
            int     num3 = thingCenter.z - (thingSize.z - 1) / 2 - 1;
            int     num4 = num3 + thingSize.z + 1;
            IntVec3 item = new IntVec3(num - 1, 0, num3);

            do
            {
                item.x++;
                GenAdjFast.resultList.Add(item);
            }while (item.x < num2);
            do
            {
                item.z++;
                GenAdjFast.resultList.Add(item);
            }while (item.z < num4);
            do
            {
                item.x--;
                GenAdjFast.resultList.Add(item);
            }while (item.x > num);
            do
            {
                item.z--;
                GenAdjFast.resultList.Add(item);
            }while (item.z > num3 + 1);
            GenAdjFast.working = false;
            return(GenAdjFast.resultList);
        }
Beispiel #2
0
        public static IEnumerable <IntVec3> CellsAdjacent8WayAndInside(this Thing thing)
        {
            IntVec3 center   = thing.Position;
            IntVec2 size     = thing.def.size;
            Rot4    rotation = thing.Rotation;

            GenAdj.AdjustForRotation(ref center, ref size, rotation);
            int minX = center.x - (size.x - 1) / 2 - 1;
            int minZ = center.z - (size.z - 1) / 2 - 1;
            int maxX = minX + size.x + 1;
            int maxZ = minZ + size.z + 1;

            for (int i = minX; i <= maxX; i++)
            {
                for (int j = minZ; j <= maxZ; j++)
                {
                    yield return(new IntVec3(i, 0, j));
                }
            }
        }
Beispiel #3
0
 public static void CheckMoveItemsAside(IntVec3 thingPos, Rot4 thingRot, ThingDef thingDef, Map map)
 {
     if (thingDef.surfaceType == SurfaceType.None && thingDef.passability != 0)
     {
         CellRect occupiedRect = GenAdj.OccupiedRect(thingPos, thingRot, thingDef.Size);
         foreach (IntVec3 item in occupiedRect)
         {
             foreach (Thing item2 in item.GetThingList(map).ToList())
             {
                 if (item2.def.category == ThingCategory.Item)
                 {
                     item2.DeSpawn();
                     if (!GenPlace.TryPlaceThing(item2, item, map, ThingPlaceMode.Near, null, (IntVec3 x) => !occupiedRect.Contains(x)))
                     {
                         item2.Destroy();
                     }
                 }
             }
         }
     }
 }
        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();
                }
                return((!avoidColonists || !SkyfallerUtility.CanPossiblyFallOnColonist(skyfaller, x, map)) && (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, -1));
            }
            return(CellFinderLoose.TryFindRandomNotEdgeCellWith(minDistToEdge, validator, map, out cell));
        }
Beispiel #5
0
        public static IEnumerable <IntVec3> CellsOccupiedBy(Thing t)
        {
            if (t.def.size.x == 1 && t.def.size.z == 1)
            {
                yield return(t.Position);

                /*Error: Unable to find new state assignment for yield return*/;
            }
            using (IEnumerator <IntVec3> enumerator = GenAdj.CellsOccupiedBy(t.Position, t.Rotation, t.def.size).GetEnumerator())
            {
                if (enumerator.MoveNext())
                {
                    IntVec3 c = enumerator.Current;
                    yield return(c);

                    /*Error: Unable to find new state assignment for yield return*/;
                }
            }
            yield break;
IL_013d:
            /*Error near IL_013e: Unexpected return in MoveNext()*/;
        }
Beispiel #6
0
        public static IEnumerable <IntVec3> CellsAdjacentAlongEdge(IntVec3 thingCent, Rot4 thingRot, IntVec2 thingSize, LinkDirections dir)
        {
            GenAdj.AdjustForRotation(ref thingCent, ref thingSize, thingRot);
            int minX = thingCent.x - (thingSize.x - 1) / 2 - 1;
            int minZ = thingCent.z - (thingSize.z - 1) / 2 - 1;
            int maxX = minX + thingSize.x + 1;
            int maxZ = minZ + thingSize.z + 1;

            if (dir == LinkDirections.Down)
            {
                for (int x = minX; x <= maxX; x++)
                {
                    yield return(new IntVec3(x, thingCent.y, minZ - 1));
                }
            }
            if (dir == LinkDirections.Up)
            {
                for (int x2 = minX; x2 <= maxX; x2++)
                {
                    yield return(new IntVec3(x2, thingCent.y, maxZ + 1));
                }
            }
            if (dir == LinkDirections.Left)
            {
                for (int z = minZ; z <= maxZ; z++)
                {
                    yield return(new IntVec3(minX - 1, thingCent.y, z));
                }
            }
            if (dir == LinkDirections.Right)
            {
                for (int z2 = minZ; z2 <= maxZ; z2++)
                {
                    yield return(new IntVec3(maxX + 1, thingCent.y, z2));
                }
            }
        }
Beispiel #7
0
 public static bool IsAdjacentToCardinalOrInside(this Thing t1, Thing t2)
 {
     return(GenAdj.IsAdjacentToCardinalOrInside(t1.OccupiedRect(), t2.OccupiedRect()));
 }
Beispiel #8
0
        private static PlaceSpotQuality PlaceSpotQualityAt(IntVec3 c, Rot4 rot, Map map, Thing thing, IntVec3 center, bool allowStacking, Predicate <IntVec3> extraValidator = null)
        {
            if (!c.InBounds(map) || !c.Walkable(map))
            {
                return(PlaceSpotQuality.Unusable);
            }
            if (!GenAdj.OccupiedRect(c, rot, thing.def.Size).InBounds(map))
            {
                return(PlaceSpotQuality.Unusable);
            }
            if (extraValidator != null && !extraValidator(c))
            {
                return(PlaceSpotQuality.Unusable);
            }
            List <Thing> list = map.thingGrid.ThingsListAt(c);

            for (int i = 0; i < list.Count; i++)
            {
                Thing thing2 = list[i];
                if (thing.def.saveCompressible && thing2.def.saveCompressible)
                {
                    return(PlaceSpotQuality.Unusable);
                }
                if (thing.def.category == ThingCategory.Item && thing2.def.category == ThingCategory.Item && (!thing2.CanStackWith(thing) || thing2.stackCount >= thing.def.stackLimit))
                {
                    return(PlaceSpotQuality.Unusable);
                }
            }
            if (thing is Building)
            {
                foreach (IntVec3 item in GenAdj.OccupiedRect(c, rot, thing.def.size))
                {
                    Building edifice = item.GetEdifice(map);
                    if (edifice != null && GenSpawn.SpawningWipes(thing.def, edifice.def))
                    {
                        return(PlaceSpotQuality.Awful);
                    }
                }
            }
            if (c.GetRoom(map) != center.GetRoom(map))
            {
                if (!map.reachability.CanReach(center, c, PathEndMode.OnCell, TraverseMode.PassDoors, Danger.Deadly))
                {
                    return(PlaceSpotQuality.Awful);
                }
                return(PlaceSpotQuality.Bad);
            }
            if (allowStacking)
            {
                for (int j = 0; j < list.Count; j++)
                {
                    Thing thing3 = list[j];
                    if (thing3.def.category == ThingCategory.Item && thing3.CanStackWith(thing) && thing3.stackCount < thing.def.stackLimit)
                    {
                        return(PlaceSpotQuality.Perfect);
                    }
                }
            }
            bool             flag             = (thing as Pawn)?.Downed ?? false;
            PlaceSpotQuality placeSpotQuality = PlaceSpotQuality.Perfect;

            for (int k = 0; k < list.Count; k++)
            {
                Thing thing4 = list[k];
                if (thing4.def.IsDoor)
                {
                    return(PlaceSpotQuality.Bad);
                }
                if (thing4 is Building_WorkTable)
                {
                    return(PlaceSpotQuality.Bad);
                }
                Pawn pawn = thing4 as Pawn;
                if (pawn != null)
                {
                    if (pawn.Downed | flag)
                    {
                        return(PlaceSpotQuality.Bad);
                    }
                    if ((int)placeSpotQuality > 3)
                    {
                        placeSpotQuality = PlaceSpotQuality.Okay;
                    }
                }
                if (thing4.def.category == ThingCategory.Plant && thing4.def.selectable && (int)placeSpotQuality > 3)
                {
                    placeSpotQuality = PlaceSpotQuality.Okay;
                }
            }
            return(placeSpotQuality);
        }
Beispiel #9
0
        public static IntVec3 FindNoWipeSpawnLocNear(IntVec3 near, Map map, ThingDef thingToSpawn, Rot4 rot, int maxDist = 2, Predicate <IntVec3> extraValidator = null)
        {
            int     num    = GenRadial.NumCellsInRadius((float)maxDist);
            IntVec3 intVec = IntVec3.Invalid;
            float   num2   = 0f;

            for (int i = 0; i < num; i++)
            {
                IntVec3 intVec2 = near + GenRadial.RadialPattern[i];
                if (intVec2.InBounds(map))
                {
                    CellRect cellRect = GenAdj.OccupiedRect(intVec2, rot, thingToSpawn.size);
                    if (cellRect.InBounds(map))
                    {
                        if (GenSight.LineOfSight(near, intVec2, map, true, null, 0, 0))
                        {
                            if (extraValidator == null || extraValidator(intVec2))
                            {
                                if (thingToSpawn.category != ThingCategory.Building || GenConstruct.CanBuildOnTerrain(thingToSpawn, intVec2, map, rot, null))
                                {
                                    bool flag  = false;
                                    bool flag2 = false;
                                    CellFinder.tmpUniqueWipedThings.Clear();
                                    CellRect.CellRectIterator iterator = cellRect.GetIterator();
                                    while (!iterator.Done())
                                    {
                                        if (iterator.Current.Impassable(map))
                                        {
                                            flag2 = true;
                                        }
                                        List <Thing> thingList = iterator.Current.GetThingList(map);
                                        for (int j = 0; j < thingList.Count; j++)
                                        {
                                            if (thingList[j] is Pawn)
                                            {
                                                flag = true;
                                            }
                                            else if (GenSpawn.SpawningWipes(thingToSpawn, thingList[j].def) && !CellFinder.tmpUniqueWipedThings.Contains(thingList[j]))
                                            {
                                                CellFinder.tmpUniqueWipedThings.Add(thingList[j]);
                                            }
                                        }
                                        iterator.MoveNext();
                                    }
                                    if (flag && thingToSpawn.passability == Traversability.Impassable)
                                    {
                                        CellFinder.tmpUniqueWipedThings.Clear();
                                    }
                                    else if (flag2 && thingToSpawn.category == ThingCategory.Item)
                                    {
                                        CellFinder.tmpUniqueWipedThings.Clear();
                                    }
                                    else
                                    {
                                        float num3 = 0f;
                                        for (int k = 0; k < CellFinder.tmpUniqueWipedThings.Count; k++)
                                        {
                                            if (CellFinder.tmpUniqueWipedThings[k].def.category == ThingCategory.Building && !CellFinder.tmpUniqueWipedThings[k].def.costList.NullOrEmpty <ThingDefCountClass>() && CellFinder.tmpUniqueWipedThings[k].def.costStuffCount == 0)
                                            {
                                                List <ThingDefCountClass> list = CellFinder.tmpUniqueWipedThings[k].CostListAdjusted();
                                                for (int l = 0; l < list.Count; l++)
                                                {
                                                    num3 += list[l].thingDef.GetStatValueAbstract(StatDefOf.MarketValue, null) * (float)list[l].count * (float)CellFinder.tmpUniqueWipedThings[k].stackCount;
                                                }
                                            }
                                            else
                                            {
                                                num3 += CellFinder.tmpUniqueWipedThings[k].MarketValue * (float)CellFinder.tmpUniqueWipedThings[k].stackCount;
                                            }
                                            if (CellFinder.tmpUniqueWipedThings[k].def.category == ThingCategory.Building || CellFinder.tmpUniqueWipedThings[k].def.category == ThingCategory.Item)
                                            {
                                                num3 = Mathf.Max(num3, 0.001f);
                                            }
                                        }
                                        CellFinder.tmpUniqueWipedThings.Clear();
                                        if (!intVec.IsValid || num3 < num2)
                                        {
                                            if (num3 == 0f)
                                            {
                                                return(intVec2);
                                            }
                                            intVec = intVec2;
                                            num2   = num3;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return((!intVec.IsValid) ? near : intVec);
        }
 private bool IsRotationValid(IntVec3 loc, Rot4 rot, Map map)
 {
     return(GenAdj.OccupiedRect(loc, rot, this.thingDef.size).InBounds(map) && !GenSpawn.WouldWipeAnythingWith(loc, rot, this.thingDef, map, (Thing x) => x.def == this.thingDef || (x.def.category != ThingCategory.Plant && x.def.category != ThingCategory.Filth)));
 }
Beispiel #11
0
 public static CellRect OccupiedRect(IntVec3 center, Rot4 rot, IntVec2 size)
 {
     GenAdj.AdjustForRotation(ref center, ref size, rot);
     return(new CellRect(center.x - (size.x - 1) / 2, center.z - (size.z - 1) / 2, size.x, size.z));
 }
Beispiel #12
0
 public static CellRect OccupiedRect(this Thing t)
 {
     return(GenAdj.OccupiedRect(t.Position, t.Rotation, t.def.size));
 }
Beispiel #13
0
        public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish)
        {
            var map = Map;     // before DeSpawn!

            base.DeSpawn(mode);

            if (def.IsEdifice())
            {
                map.edificeGrid.DeRegister(this);
            }

            if (mode != DestroyMode.WillReplace)
            {
                if (def.MakeFog)
                {
                    map.fogGrid.Notify_FogBlockerRemoved(Position);
                }

                if (def.holdsRoof)
                {
                    RoofCollapseCellsFinder.Notify_RoofHolderDespawned(this, map);
                }

                if (def.IsSmoothable)
                {
                    SmoothSurfaceDesignatorUtility.Notify_BuildingDespawned(this, map);
                }
            }

            if (sustainerAmbient != null)
            {
                sustainerAmbient.End();
            }

            CellRect occRect = GenAdj.OccupiedRect(this);

            for (int z = occRect.minZ; z <= occRect.maxZ; z++)
            {
                for (int x = occRect.minX; x <= occRect.maxX; x++)
                {
                    IntVec3 c = new IntVec3(x, 0, z);

                    MapMeshFlag changeType = MapMeshFlag.Buildings;

                    if (def.coversFloor)
                    {
                        changeType |= MapMeshFlag.Terrain;
                    }

                    if (def.Fillage == FillCategory.Full)
                    {
                        changeType |= MapMeshFlag.Roofs;
                        changeType |= MapMeshFlag.Snow;
                    }

                    map.mapDrawer.MapMeshDirty(c, changeType);

                    map.glowGrid.MarkGlowGridDirty(c);
                }
            }

            map.listerBuildings.Remove(this);
            map.listerBuildingsRepairable.Notify_BuildingDeSpawned(this);

            if (def.building.leaveTerrain != null && Current.ProgramState == ProgramState.Playing && canChangeTerrainOnDestroyed)
            {
                for (var cri = GenAdj.OccupiedRect(this).GetIterator(); !cri.Done(); cri.MoveNext())
                {
                    map.terrainGrid.SetTerrain(cri.Current, def.building.leaveTerrain);
                }
            }

            //Mining, planning, etc
            map.designationManager.Notify_BuildingDespawned(this);

            if (!this.CanBeSeenOver())
            {
                map.exitMapGrid.Notify_LOSBlockerDespawned();
            }

            if (def.building.hasFuelingPort)
            {
                var fuelingPortCell = FuelingPortUtility.GetFuelingPortCell(Position, Rotation);
                var launchable      = FuelingPortUtility.LaunchableAt(fuelingPortCell, map);

                if (launchable != null)
                {
                    launchable.Notify_FuelingPortSourceDeSpawned();
                }
            }

            //Must go after removing from buildings list
            map.avoidGrid.Notify_BuildingDespawned(this);
        }
Beispiel #14
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);
        }
Beispiel #15
0
        public static Thing Spawn(Thing newThing, IntVec3 loc, Map map, Rot4 rot, WipeMode wipeMode = WipeMode.Vanish, bool respawningAfterLoad = false)
        {
            if (map == null)
            {
                Log.Error("Tried to spawn " + newThing.ToStringSafe <Thing>() + " in a null map.", false);
                return(null);
            }
            if (!loc.InBounds(map))
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to spawn ",
                    newThing.ToStringSafe <Thing>(),
                    " out of bounds at ",
                    loc,
                    "."
                }), false);
                return(null);
            }
            if (newThing.def.randomizeRotationOnSpawn)
            {
                rot = Rot4.Random;
            }
            CellRect occupiedRect = GenAdj.OccupiedRect(loc, rot, newThing.def.Size);

            if (!occupiedRect.InBounds(map))
            {
                Log.Error(string.Concat(new object[]
                {
                    "Tried to spawn ",
                    newThing.ToStringSafe <Thing>(),
                    " out of bounds at ",
                    loc,
                    " (out of bounds because size is ",
                    newThing.def.Size,
                    ")."
                }), false);
                return(null);
            }
            if (newThing.Spawned)
            {
                Log.Error("Tried to spawn " + newThing + " but it's already spawned.", false);
                return(newThing);
            }
            if (wipeMode == WipeMode.Vanish)
            {
                GenSpawn.WipeExistingThings(loc, rot, newThing.def, map, DestroyMode.Vanish);
            }
            else if (wipeMode == WipeMode.FullRefund)
            {
                GenSpawn.WipeAndRefundExistingThings(loc, rot, newThing.def, map);
            }
            if (newThing.def.category == ThingCategory.Item)
            {
                foreach (IntVec3 current in occupiedRect)
                {
                    foreach (Thing current2 in current.GetThingList(map).ToList <Thing>())
                    {
                        if (current2 != newThing)
                        {
                            if (current2.def.category == ThingCategory.Item)
                            {
                                current2.DeSpawn(DestroyMode.Vanish);
                                if (!GenPlace.TryPlaceThing(current2, current, map, ThingPlaceMode.Near, null, (IntVec3 x) => !occupiedRect.Contains(x)))
                                {
                                    current2.Destroy(DestroyMode.Vanish);
                                }
                            }
                        }
                    }
                }
            }
            newThing.Rotation = rot;
            newThing.Position = loc;
            if (newThing.holdingOwner != null)
            {
                newThing.holdingOwner.Remove(newThing);
            }
            newThing.SpawnSetup(map, respawningAfterLoad);
            if (newThing.Spawned && newThing.stackCount == 0)
            {
                Log.Error("Spawned thing with 0 stackCount: " + newThing, false);
                newThing.Destroy(DestroyMode.Vanish);
                return(null);
            }
            if (newThing.def.passability == Traversability.Impassable)
            {
                foreach (IntVec3 current3 in occupiedRect)
                {
                    foreach (Thing current4 in current3.GetThingList(map).ToList <Thing>())
                    {
                        if (current4 != newThing)
                        {
                            Pawn pawn = current4 as Pawn;
                            if (pawn != null)
                            {
                                pawn.pather.TryRecoverFromUnwalkablePosition(false);
                            }
                        }
                    }
                }
            }
            return(newThing);
        }
Beispiel #16
0
 public static bool TryFindRandomAdjacentCell8WayWithRoomGroup(Thing t, out IntVec3 result)
 {
     return(GenAdj.TryFindRandomAdjacentCell8WayWithRoomGroup(t.Position, t.Rotation, t.def.size, t.Map, out result));
 }
Beispiel #17
0
        public static Thing Spawn(Thing newThing, IntVec3 loc, Map map, Rot4 rot, WipeMode wipeMode = WipeMode.Vanish, bool respawningAfterLoad = false)
        {
            if (map == null)
            {
                Log.Error("Tried to spawn " + newThing.ToStringSafe() + " in a null map.");
                return(null);
            }
            if (!loc.InBounds(map))
            {
                Log.Error("Tried to spawn " + newThing.ToStringSafe() + " out of bounds at " + loc + ".");
                return(null);
            }
            if (newThing.def.randomizeRotationOnSpawn)
            {
                rot = Rot4.Random;
            }
            CellRect occupiedRect = GenAdj.OccupiedRect(loc, rot, newThing.def.Size);

            if (!occupiedRect.InBounds(map))
            {
                Log.Error("Tried to spawn " + newThing.ToStringSafe() + " out of bounds at " + loc + " (out of bounds because size is " + newThing.def.Size + ").");
                return(null);
            }
            if (newThing.Spawned)
            {
                Log.Error("Tried to spawn " + newThing + " but it's already spawned.");
                return(newThing);
            }
            switch (wipeMode)
            {
            case WipeMode.Vanish:
                WipeExistingThings(loc, rot, newThing.def, map, DestroyMode.Vanish);
                break;

            case WipeMode.FullRefund:
                WipeAndRefundExistingThings(loc, rot, newThing.def, map);
                break;
            }
            if (newThing.def.category == ThingCategory.Item)
            {
                foreach (IntVec3 item in occupiedRect)
                {
                    foreach (Thing item2 in item.GetThingList(map).ToList())
                    {
                        if (item2 != newThing && item2.def.category == ThingCategory.Item)
                        {
                            item2.DeSpawn();
                            if (!GenPlace.TryPlaceThing(item2, item, map, ThingPlaceMode.Near, null, (IntVec3 x) => !occupiedRect.Contains(x)))
                            {
                                item2.Destroy();
                            }
                        }
                    }
                }
            }
            newThing.Rotation = rot;
            newThing.Position = loc;
            if (newThing.holdingOwner != null)
            {
                newThing.holdingOwner.Remove(newThing);
            }
            newThing.SpawnSetup(map, respawningAfterLoad);
            if (newThing.Spawned && newThing.stackCount == 0)
            {
                Log.Error("Spawned thing with 0 stackCount: " + newThing);
                newThing.Destroy();
                return(null);
            }
            if (newThing.def.passability == Traversability.Impassable)
            {
                foreach (IntVec3 item3 in occupiedRect)
                {
                    foreach (Thing item4 in item3.GetThingList(map).ToList())
                    {
                        if (item4 != newThing)
                        {
                            (item4 as Pawn)?.pather.TryRecoverFromUnwalkablePosition(error: false);
                        }
                    }
                }
                return(newThing);
            }
            return(newThing);
        }
Beispiel #18
0
 public static IEnumerable <IntVec3> CellsAdjacentCardinal(Thing t)
 {
     return(GenAdj.CellsAdjacentCardinal(t.Position, t.Rotation, t.def.size));
 }
Beispiel #19
0
 public static bool WouldWipeAnythingWith(IntVec3 thingPos, Rot4 thingRot, BuildableDef thingDef, Map map, Predicate <Thing> predicate)
 {
     return(GenSpawn.WouldWipeAnythingWith(GenAdj.OccupiedRect(thingPos, thingRot, thingDef.Size), thingDef, map, predicate));
 }
Beispiel #20
0
 public static bool AdjacentTo8WayOrInside(this Thing a, Thing b)
 {
     return(GenAdj.AdjacentTo8WayOrInside(a.OccupiedRect(), b.OccupiedRect()));
 }
Beispiel #21
0
        public static IntVec3 FindNoWipeSpawnLocNear(IntVec3 near, Map map, ThingDef thingToSpawn, Rot4 rot, int maxDist = 2, Predicate <IntVec3> extraValidator = null)
        {
            int     num    = GenRadial.NumCellsInRadius(maxDist);
            IntVec3 result = IntVec3.Invalid;
            float   num2   = 0f;

            for (int i = 0; i < num; i++)
            {
                IntVec3 intVec = near + GenRadial.RadialPattern[i];
                if (!intVec.InBounds(map))
                {
                    continue;
                }
                CellRect cellRect = GenAdj.OccupiedRect(intVec, rot, thingToSpawn.size);
                if (!cellRect.InBounds(map) || !GenSight.LineOfSight(near, intVec, map, skipFirstCell: true) || (extraValidator != null && !extraValidator(intVec)) || (thingToSpawn.category == ThingCategory.Building && !GenConstruct.CanBuildOnTerrain(thingToSpawn, intVec, map, rot)))
                {
                    continue;
                }
                bool flag  = false;
                bool flag2 = false;
                tmpUniqueWipedThings.Clear();
                foreach (IntVec3 item in cellRect)
                {
                    if (item.Impassable(map))
                    {
                        flag2 = true;
                    }
                    List <Thing> thingList = item.GetThingList(map);
                    for (int j = 0; j < thingList.Count; j++)
                    {
                        if (thingList[j] is Pawn)
                        {
                            flag = true;
                        }
                        else if (GenSpawn.SpawningWipes(thingToSpawn, thingList[j].def) && !tmpUniqueWipedThings.Contains(thingList[j]))
                        {
                            tmpUniqueWipedThings.Add(thingList[j]);
                        }
                    }
                }
                if (flag && thingToSpawn.passability == Traversability.Impassable)
                {
                    tmpUniqueWipedThings.Clear();
                    continue;
                }
                if (flag2 && thingToSpawn.category == ThingCategory.Item)
                {
                    tmpUniqueWipedThings.Clear();
                    continue;
                }
                float num3 = 0f;
                for (int k = 0; k < tmpUniqueWipedThings.Count; k++)
                {
                    if (tmpUniqueWipedThings[k].def.category == ThingCategory.Building && !tmpUniqueWipedThings[k].def.costList.NullOrEmpty() && tmpUniqueWipedThings[k].def.costStuffCount == 0)
                    {
                        List <ThingDefCountClass> list = tmpUniqueWipedThings[k].CostListAdjusted();
                        for (int l = 0; l < list.Count; l++)
                        {
                            num3 += list[l].thingDef.GetStatValueAbstract(StatDefOf.MarketValue) * (float)list[l].count * (float)tmpUniqueWipedThings[k].stackCount;
                        }
                    }
                    else
                    {
                        num3 += tmpUniqueWipedThings[k].MarketValue * (float)tmpUniqueWipedThings[k].stackCount;
                    }
                    if (tmpUniqueWipedThings[k].def.category == ThingCategory.Building || tmpUniqueWipedThings[k].def.category == ThingCategory.Item)
                    {
                        num3 = Mathf.Max(num3, 0.001f);
                    }
                }
                tmpUniqueWipedThings.Clear();
                if (!result.IsValid || num3 < num2)
                {
                    if (num3 == 0f)
                    {
                        return(intVec);
                    }
                    result = intVec;
                    num2   = num3;
                }
            }
            if (!result.IsValid)
            {
                return(near);
            }
            return(result);
        }
Beispiel #22
0
 public static bool IsInside(this IntVec3 root, Thing t)
 {
     return(GenAdj.IsInside(root, t.Position, t.Rotation, t.def.size));
 }