public void DropItem([NotNull] Thing item, IntVec3 position, bool forced = false) { var backupSound = item.def.soundDrop; try { item.def.soundDrop = null; if (!_container.Contains(item)) return; Thing droppedItem; if (!_container.TryDrop(item, position, ThingPlaceMode.Direct, out droppedItem) && !forced) { return; } // Might prevent those "has null owner" errors... else if (forced && _container.Contains(item) && !_container.TryDrop(item, position, ThingPlaceMode.Near, out droppedItem)) { _container.Remove(item); item.holder = null; return; } // Play the sound as that isn't handled by the ThingContainer anymore... if (backupSound != null) { backupSound.PlayOneShot(position); } _thingCounter.Remove(item); item.holder = null; if (droppedItem is ThingWithComps) { droppedItem.SetForbidden(false); } if (droppedItem.def.defName.Contains("Chunk") && Find.DesignationManager.DesignationOn(droppedItem, DesignationDefOf.Haul) == null) { // If this is a chunk AND not already haulable ("designated twice" warning) make it haulable Find.DesignationManager.AddDesignation(new Designation(droppedItem, DesignationDefOf.Haul)); } } finally { // Stupid hack to make sure the drop sound is not played all the time item.def.soundDrop = backupSound; } }
public virtual void Unboard(Pawn pawn) { if (storage.Count(x => x is Pawn) <= 0) { return; } if (storage.Contains(pawn)) { pawn.holder = null; pawn.jobs.StopAll(); Thing dummy; storage.TryDrop(pawn, Position, ThingPlaceMode.Near, out dummy); } }
internal static void Remove(this ThingContainer _this, Thing item) { if (!_this.Contains(item)) { return; } if (item.holdingContainer == _this) { item.holdingContainer = null; } List <Thing> innerList = (List <Thing>)innerListFieldInfo.GetValue(_this); // Fetch innerList through reflection innerList.Remove(item); Pawn_InventoryTracker pawn_InventoryTracker = _this.owner as Pawn_InventoryTracker; if (pawn_InventoryTracker != null) { pawn_InventoryTracker.Notify_ItemRemoved(item); } CR_Utility.TryUpdateInventory(_this.owner as Pawn_InventoryTracker); // Item was removed, update inventory }
internal static bool TryAdd(this ThingContainer _this, Thing item, bool canMergeWithExistingStacks = true) { if (item == null) { Log.Warning("Tried to add null item to ThingContainer."); return(false); } if (_this.Contains(item)) { Log.Warning("Tried to add " + item + " to ThingContainer but this item is already here."); return(false); } if (item.stackCount > _this.AvailableStackSpace) { return(_this.TryAdd(item, _this.AvailableStackSpace) > 0); } List <Thing> innerList = (List <Thing>)innerListFieldInfo.GetValue(_this); // Fetch innerList through reflection SlotGroupUtility.Notify_TakingThing(item); if (canMergeWithExistingStacks && item.def.stackLimit > 1) { for (int i = 0; i < innerList.Count; i++) { if (innerList[i].def == item.def) { int num = item.stackCount; if (num > _this.AvailableStackSpace) { num = _this.AvailableStackSpace; } Thing other = item.SplitOff(num); if (!innerList[i].TryAbsorbStack(other, false)) { Log.Error("ThingContainer did TryAbsorbStack " + item + " but could not absorb stack."); } } if (item.Destroyed) { //CR PART!!! CR_Utility.TryUpdateInventory(_this.owner as Pawn_InventoryTracker); // Item has been added, notify CompInventory return(true); } } } int maxStacks = (int)maxStacksFieldInfo.GetValue(_this); // Fetch maxStacks through reflection if (innerList.Count >= maxStacks) { return(false); } if (item.Spawned) { item.DeSpawn(); } if (item.HasAttachment(ThingDefOf.Fire)) { item.GetAttachment(ThingDefOf.Fire).Destroy(DestroyMode.Vanish); } item.holdingContainer = _this; innerList.Add(item); CR_Utility.TryUpdateInventory(_this.owner as Pawn_InventoryTracker); // Item has been added, notify CompInventory return(true); }