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); }
/// <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); }
// 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); }