protected bool TrySwapping(int index, Item item, Character user, bool createNetworkEvent, bool swapWholeStack) { if (item?.ParentInventory == null || !slots[index].Any()) { return(false); } //swap to InvSlotType.Any if possible Inventory otherInventory = item.ParentInventory; bool otherIsEquipped = false; int otherIndex = -1; for (int i = 0; i < otherInventory.slots.Length; i++) { if (!otherInventory.slots[i].Contains(item)) { continue; } if (otherInventory is CharacterInventory characterInventory) { if (characterInventory.SlotTypes[i] == InvSlotType.Any) { otherIndex = i; break; } else { otherIsEquipped = true; } } } if (otherIndex == -1) { otherIndex = otherInventory.FindIndex(item); if (otherIndex == -1) { DebugConsole.ThrowError("Something went wrong when trying to swap items between inventory slots: couldn't find the source item from it's inventory.\n" + Environment.StackTrace.CleanupStackTrace()); return(false); } } List <Item> existingItems = new List <Item>(); if (swapWholeStack) { existingItems.AddRange(slots[index].Items); for (int j = 0; j < capacity; j++) { if (existingItems.Any(existingItem => slots[j].Contains(existingItem))) { slots[j].RemoveAllItems(); } } } else { existingItems.Add(slots[index].FirstOrDefault()); slots[index].RemoveItem(existingItems.First()); } List <Item> stackedItems = new List <Item>(); if (swapWholeStack) { for (int j = 0; j < otherInventory.capacity; j++) { if (otherInventory.slots[j].Contains(item)) { stackedItems.AddRange(otherInventory.slots[j].Items); otherInventory.slots[j].RemoveAllItems(); } } } else { stackedItems.Add(item); otherInventory.slots[otherIndex].RemoveItem(item); } bool swapSuccessful = false; if (otherIsEquipped) { swapSuccessful = stackedItems.Distinct().All(stackedItem => TryPutItem(stackedItem, index, false, false, user, createNetworkEvent)) && (existingItems.All(existingItem => otherInventory.TryPutItem(existingItem, otherIndex, false, false, user, createNetworkEvent)) || existingItems.Count == 1 && otherInventory.TryPutItem(existingItems.First(), user, CharacterInventory.anySlot, createNetworkEvent)); } else { swapSuccessful = (existingItems.All(existingItem => otherInventory.TryPutItem(existingItem, otherIndex, false, false, user, createNetworkEvent)) || existingItems.Count == 1 && otherInventory.TryPutItem(existingItems.First(), user, CharacterInventory.anySlot, createNetworkEvent)) && stackedItems.Distinct().All(stackedItem => TryPutItem(stackedItem, index, false, false, user, createNetworkEvent)); } //if the item in the slot can be moved to the slot of the moved item if (swapSuccessful) { System.Diagnostics.Debug.Assert(slots[index].Contains(item), "Something when wrong when swapping items, item is not present in the inventory."); System.Diagnostics.Debug.Assert(otherInventory.Contains(existingItems.FirstOrDefault()), "Something when wrong when swapping items, item is not present in the other inventory."); #if CLIENT if (visualSlots != null) { for (int j = 0; j < capacity; j++) { if (slots[j].Contains(item)) { visualSlots[j].ShowBorderHighlight(GUI.Style.Green, 0.1f, 0.9f); } } for (int j = 0; j < otherInventory.capacity; j++) { if (otherInventory.slots[j].Contains(existingItems.FirstOrDefault())) { otherInventory.visualSlots[j].ShowBorderHighlight(GUI.Style.Green, 0.1f, 0.9f); } } } #endif return(true); } else //swapping the items failed -> move them back to where they were { if (swapWholeStack) { foreach (Item stackedItem in stackedItems) { for (int j = 0; j < capacity; j++) { if (slots[j].Contains(stackedItem)) { slots[j].RemoveItem(stackedItem); } ; } } foreach (Item existingItem in existingItems) { for (int j = 0; j < otherInventory.capacity; j++) { if (otherInventory.slots[j].Contains(existingItem)) { otherInventory.slots[j].RemoveItem(existingItem); } } } } else { for (int j = 0; j < capacity; j++) { if (slots[j].Contains(item)) { slots[j].RemoveAllItems(); } ; } for (int j = 0; j < otherInventory.capacity; j++) { if (otherInventory.slots[j].Contains(existingItems.FirstOrDefault())) { otherInventory.slots[j].RemoveAllItems(); } } } if (otherIsEquipped) { existingItems.ForEach(existingItem => TryPutItem(existingItem, index, false, false, user, createNetworkEvent)); stackedItems.ForEach(stackedItem => otherInventory.TryPutItem(stackedItem, otherIndex, false, false, user, createNetworkEvent)); } else { stackedItems.ForEach(stackedItem => otherInventory.TryPutItem(stackedItem, otherIndex, false, false, user, createNetworkEvent)); existingItems.ForEach(existingItem => TryPutItem(existingItem, index, false, false, user, createNetworkEvent)); } #if CLIENT if (visualSlots != null) { for (int j = 0; j < capacity; j++) { if (slots[j].Contains(existingItems.FirstOrDefault())) { visualSlots[j].ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.9f); } } } #endif return(false); } }
public InventoryPlaceCommand(Inventory inventory, List <Item> items, bool dropped) { Inventory = inventory; Receivers = items.Select(item => new InventorySlotItem(inventory.FindIndex(item), item)).ToList(); wasDropped = dropped; }