Esempio n. 1
0
 private static bool PlaceThingInSlotGroup(this IPRF_Building placer, Thing t,
                                           SlotGroup slotGroup, IntVec3 cell, Map map)
 {
     if (placer?.OutputToEntireStockpile == true)
     {
         return(PlaceThingAnywhereInSlotGroup(placer, t, slotGroup, cell));
     }
     // Head off a lot of potential calculation:
     // TODO: Deal properly with underground conveyors (need options to allow
     //       player to decide how that works.
     if (placer.ObeysStorageFilters && !slotGroup.parent.Accepts(t))
     {
         return(false);
     }
     if (CallNoStorageBlockersIn(cell, map, t))
     {
         Debug.Message(Debug.Flag.PlaceThing, "Found NoStorageBlockersIn(" + cell + ", map, " + t + ") - Placing");
         bool wasSpawned = t.Spawned;
         if (wasSpawned)
         {
             t.DeSpawn();
         }
         if (!GenPlace.TryPlaceThing(t, cell, map, ThingPlaceMode.Direct))
         {
             // This happens if some was absorbed, but not the whole stack
             Debug.Message(Debug.Flag.PlaceThing, "  some was absorbed, but still have " + t.stackCount);
             // as above, should be safe
             if (wasSpawned)
             {
                 GenPlace.TryPlaceThing(t, t.Position, map, ThingPlaceMode.Near);
             }
             placer.EffectOnPlaceThing(t);
             return(false);
         }
         placer.EffectOnPlaceThing(t);
         if (placer.ForbidOnPlacing(t))
         {
             t.SetForbidden(true, false);
         }
         return(true);
     }
     Debug.Message(Debug.Flag.PlaceThing, "There were StorageBlockersIn(" + cell + ", map, " + t + ") - cannot place");
     return(false);
 }
Esempio n. 2
0
 private static bool PlaceThingNextBuilding(this IPRF_Building placer,
                                            IPRF_Building nextBuilding, Thing t,
                                            IntVec3 cell, Map map)
 {
     if (nextBuilding.AcceptsThing(t, placer))
     {
         placer.EffectOnPlaceThing(t);
         return(true);
     }
     return(false);
 }
Esempio n. 3
0
        /// <summary>
        /// Some PRF Buildings are Magic, and can move stuff anywhere into a slotGroup
        ///   (or, you know, they pile stuff up until it falls, or use a machine
        ///    arm to move things, etc)
        /// </summary>
        /// <returns><c>true</c>, if thing was placed somewhere; <c>false</c> otherwise.</returns>
        /// <param name="placer">IPRF Buidling placing.</param>
        /// <param name="t">thing to place.</param>
        /// <param name="slotGroup">SlotGroup.</param>
        /// <param name="cell">optional first cell</param>
        public static bool PlaceThingAnywhereInSlotGroup(this IPRF_Building placer, Thing t,
                                                         SlotGroup slotGroup, IntVec3?cell = null)
        {
            // Should we even be putting anything here?
            if (placer.ObeysStorageFilters && !slotGroup.parent.Accepts(t))
            {
                return(false);
            }
            Map map = placer.Map;

            // Go through slotGroup, starting with cell if given
            // TODO: go thru slotgroup in order of increasing distance from cell?
            foreach (var c in (cell != null ? ((new[] { (IntVec3)cell }).Concat(slotGroup.CellsList.Where(x => x != cell)))
                                          : slotGroup.CellsList))
            {
                if (CallNoStorageBlockersIn(c, map, t))
                {
                    Debug.Message(Debug.Flag.PlaceThing, "Found NoStorageBlockersIn(" + cell + ", map, " + t + ") - Placing");
                    if (t.Spawned)
                    {
                        t.DeSpawn();
                    }
                    if (!GenPlace.TryPlaceThing(t, c, map, ThingPlaceMode.Direct))
                    {
                        // This happens if some was absorbed, but not the whole stack
                        //  We should continue on, to see if we can place everything
                        Debug.Message(Debug.Flag.PlaceThing, "  some was absorbed, still have " + t.stackCount);
                        continue;
                    }
                    placer.EffectOnPlaceThing(t);
                    if (placer.ForbidOnPlacing(t))
                    {
                        t.SetForbidden(true, false);
                    }
                    return(true);
                }
            }
            Debug.Message(Debug.Flag.PlaceThing, "There were StorageBlockersIn every cell of "
                          + slotGroup.parent + " - cannot place" + t);
            return(false);
        }
Esempio n. 4
0
        // Always use this if you are placing an item.
        /// <summary>
        /// Place a Thing (onto the ground or into a proper receptacle)
        /// Any time ANY PRF building tries to place an item, this is THE way to do it:
        ///   It checks if the space is clear, it checks for conveyor belts, in checks
        ///   for other storage mods (well, Deep Storage, anyway).  It does all the
        ///   things!
        /// </summary>
        /// <returns><c>true</c>, if item was placed, <c>false</c> if it could not.</returns>
        /// <param name="placer">The PRF_Building doing the placing</param>
        /// <param name="t">Thing to place.</param>
        /// <param name="cell">Where to place.</param>
        /// <param name="map">Map.</param>
        /// <param name="forcePlace">If set to <c>true</c>, forces placing. For when
        ///   you absolutely positively have to put it down.</param>
        public static bool PRFTryPlaceThing(this IPRF_Building placer, Thing t, IntVec3 cell, Map map,
                                            bool forcePlace = false)
        {
            if (!cell.InBounds(map))
            {
                Log.Error("PRF Error Attempting to place Thing out of bounds.");
                return(false);
            }

            // Storage:
            SlotGroup slotGroup = cell.GetSlotGroup(map);

            if (slotGroup != null)
            {
                Debug.Warning(Debug.Flag.PlaceThing, "Placing " + t + " in slotGroup: " + slotGroup.parent + " at " + cell);
                if (slotGroup.parent is IPRF_Building)
                {
                    if (placer.PlaceThingNextBuilding((slotGroup.parent as IPRF_Building),
                                                      t, cell, map))
                    {
                        Debug.Message(Debug.Flag.PlaceThing, "  which is owned by PRF " + slotGroup.parent);
                        return(true);
                    }
                    if (forcePlace)
                    {
                        goto ForcePlace;
                    }
                    return(false);
                }
                if (placer.PlaceThingInSlotGroup(t, slotGroup, cell, map))
                {
                    return(true);
                }
                if (forcePlace)
                {
                    goto ForcePlace;
                }
                return(false);
            }
            Debug.Warning(Debug.Flag.PlaceThing, "Place request: " + placer == null ? "NoPlacer" : placer.ToString() + " is trying to place " + t + " at " + cell);
            // Search through all items in cell: see if any will absorb
            //   our thing.  If we find a PRF_Building, stop looking and
            //   try to pass it on.
            bool cellIsImpassible = false;

            foreach (Thing otherThing in map.thingGrid.ThingsListAt(cell))
            {
                if (otherThing.TryAbsorbStack(t, true))
                {
                    Debug.Message(Debug.Flag.PlaceThing, "  absorbed by " + otherThing);
                    placer.EffectOnPlaceThing(otherThing); // I think?
                    return(true);
                }
                if (otherThing.def.passability == Traversability.Impassable)
                {
                    cellIsImpassible = true;
                }
                if (otherThing is IPRF_Building)
                {
                    if (placer.PlaceThingNextBuilding((otherThing as IPRF_Building),
                                                      t, cell, map))
                    {
                        Debug.Message(Debug.Flag.PlaceThing, placer +
                                      " gave " + t + " to " + otherThing);
                        placer.EffectOnPlaceThing(t);
                        return(true);
                    }
                    // Continue loop - may be more than 1 PRF_Building here
                }
            }
            // There is no IPRF Building to take this from us
            if (cellIsImpassible)
            {
                Debug.Message(Debug.Flag.PlaceThing, "  cell is impassable.");
                if (forcePlace)
                {
                    goto ForcePlace;
                }
                return(false);
            }
            // The cell is not impassible! Try to place:
            if (CallNoStorageBlockersIn(cell, map, t))
            {
                Debug.Message(Debug.Flag.PlaceThing, "  placing directly.");
                bool wasSpawned = t.Spawned;
                if (wasSpawned)
                {
                    t.DeSpawn();
                }
                if (!GenPlace.TryPlaceThing(t, cell, map, ThingPlaceMode.Direct))
                {
                    // some of the stack
                    Debug.Message(Debug.Flag.PlaceThing, "  some absorbed, still have " + t.stackCount + " left");
                    // I think this is safe, as it shoudl still have its position?
                    if (wasSpawned)
                    {
                        GenPlace.TryPlaceThing(t, t.Position, map, ThingPlaceMode.Near);
                    }
                    placer.EffectOnPlaceThing(t);
                    if (forcePlace)
                    {
                        goto ForcePlace;
                    }
                    return(false);
                }
                placer.EffectOnPlaceThing(t);
                if (placer.ForbidOnPlacing(t))
                {
                    t.SetForbidden(true, false);
                }
                return(true);
            }
            if (!forcePlace)
            {
                return(false);
            }
ForcePlace:
            Debug.Warning(Debug.Flag.PlaceThing, "  Placement is forced!");
            if (t.Spawned)
            {
                t.DeSpawn();
            }
            GenPlace.TryPlaceThing(t, cell, map, ThingPlaceMode.Near);
            placer.EffectOnPlaceThing(t);
            if (placer.ForbidOnPlacing(t))
            {
                t.SetForbidden(true, false);
            }
            return(true);
        }