예제 #1
0
        public static Thing Spawn(Thing thing, IntVec3 loc, Map map, Rot4 rot, WipeMode wipeMode = WipeMode.Vanish, bool respawningAfterLoad = false)
        {
            if (thing.Spawned)
            {
                Log.Error("Tried to spawn " + thing.ToStringSafe <Thing>() + " but it's already spawned.");
                return(thing);
            }

            if (map == null)
            {
                Log.Error("Tried to spawn " + thing.ToStringSafe <Thing>() + " in a null map.", false);
                return(null);
            }

            if (!loc.InBounds(map))
            {
                Log.Error("Tried to spawn " + thing.ToStringSafe <Thing>() + " out of bounds at " + loc + ".", false);
                return(null);
            }

            var occupiedRect = GenAdj.OccupiedRect(loc, rot, thing.def.Size);

            if (!occupiedRect.InBounds(map))
            {
                Log.Error("Tried to spawn " + thing.ToStringSafe <Thing>() + " out of bounds at " + loc + " (out of bounds because size is " + thing.def.Size + ").", false);
                return(null);
            }

            if (thing.def.randomizeRotationOnSpawn)
            {
                rot = Rot4.Random;
            }

            switch (wipeMode)
            {
            case WipeMode.Vanish:
                GenSpawn.WipeExistingThings(loc, rot, thing.def, map, DestroyMode.Vanish);
                break;

            case WipeMode.FullRefund:
                GenSpawn.WipeAndRefundExistingThings(loc, rot, thing.def, map);
                break;
            }

            if (thing.holdingOwner != null)
            {
                thing.holdingOwner.Remove(thing);
            }

            thing.Position = loc;
            thing.Rotation = rot;
            thing.SpawnSetup(map, respawningAfterLoad);

            if (
                thing.Spawned &&
                thing.stackCount == 0
                )
            {
                Log.Error("Spawned thing with 0 stackCount: " + thing, false);
                thing.Destroy(DestroyMode.Vanish);
                return(null);
            }

            if (thing.def.passability == Traversability.Impassable)
            {
                foreach (var cell in occupiedRect)
                {
                    foreach (var existingThing in cell.GetThingList(map).ToList <Thing>())
                    {
                        if (existingThing != thing)
                        {
                            (existingThing as Pawn)?.pather.TryRecoverFromUnwalkablePosition(false);
                        }
                    }
                }
            }

            return(thing);
        }
예제 #2
0
        public static bool Spawn(ref Thing __result,
                                 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);
                __result = (Thing)null;
                return(false);
            }
            if (!loc.InBounds(map))
            {
                Log.Error("Tried to spawn " + newThing.ToStringSafe <Thing>() + " out of bounds at " + (object)loc + ".", false);
                __result = (Thing)null;
                return(false);
            }
            if (null != newThing)
            {
                if (null != newThing.def)
                {
                    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 <Thing>() + " out of bounds at " + (object)loc + " (out of bounds because size is " + (object)newThing.def.Size + ").", false);
                        __result = (Thing)null;
                        return(false);
                    }
                    if (newThing.Spawned)
                    {
                        Log.Error("Tried to spawn " + (object)newThing + " but it's already spawned.", false);
                        __result = newThing;
                        return(false);
                    }
                    switch (wipeMode)
                    {
                    case WipeMode.Vanish:
                        GenSpawn.WipeExistingThings(loc, rot, (BuildableDef)newThing.def, map, DestroyMode.Vanish);
                        break;

                    case WipeMode.FullRefund:
                        GenSpawn.WipeAndRefundExistingThings(loc, rot, (BuildableDef)newThing.def, map);
                        break;

                    case WipeMode.VanishOrMoveAside:
                        GenSpawn.CheckMoveItemsAside(loc, rot, newThing.def, map);
                        GenSpawn.WipeExistingThings(loc, rot, (BuildableDef)newThing.def, map, DestroyMode.Vanish);
                        break;
                    }
                    if (newThing.def.category == ThingCategory.Item)
                    {
                        foreach (IntVec3 intVec3 in occupiedRect)
                        {
                            foreach (Thing thing in intVec3.GetThingList(map).ToList <Thing>())
                            {
                                if (thing != newThing && thing.def.category == ThingCategory.Item)
                                {
                                    thing.DeSpawn(DestroyMode.Vanish);
                                    if (!GenPlace.TryPlaceThing(thing, intVec3, map, ThingPlaceMode.Near, (Action <Thing, int>)null, (Predicate <IntVec3>)(x => !occupiedRect.Contains(x)), new Rot4()))
                                    {
                                        thing.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: " + (object)newThing, false);
                        newThing.Destroy(DestroyMode.Vanish);
                        __result = (Thing)null;
                        return(false);
                    }
                    if (newThing.def.passability == Traversability.Impassable)
                    {
                        foreach (IntVec3 c in occupiedRect)
                        {
                            foreach (Thing thing in c.GetThingList(map).ToList <Thing>())
                            {
                                if (thing != newThing && thing is Pawn pawn)
                                {
                                    pawn.pather.TryRecoverFromUnwalkablePosition(false);
                                }
                            }
                        }
                    }
                }
            }
            __result = newThing;
            return(false);
        }