private MoveResult MoveSplitItem(Item item, BaseOven oven, int totalSlots) { var container = oven.inventory; int invalidItemsCount = container.itemList.Count(slotItem => !IsSlotCompatible(slotItem, oven, item.info)); int numOreSlots = Math.Min(container.capacity - invalidItemsCount, totalSlots); int totalMoved = 0; int totalAmount = Math.Min(item.amount + container.itemList.Where(slotItem => slotItem.info == item.info).Take(numOreSlots).Sum(slotItem => slotItem.amount), item.info.stackable * numOreSlots); if (numOreSlots <= 0) { return(MoveResult.NotEnoughSlots); } //Puts("---------------------------"); int totalStackSize = Math.Min(totalAmount / numOreSlots, item.info.stackable); int remaining = totalAmount - totalAmount / numOreSlots * numOreSlots; List <int> addedSlots = new List <int>(); //Puts("total: {0}, remaining: {1}, totalStackSize: {2}", totalAmount, remaining, totalStackSize); List <OvenSlot> ovenSlots = new List <OvenSlot>(); for (int i = 0; i < numOreSlots; ++i) { Item existingItem; var slot = FindMatchingSlotIndex(container, out existingItem, item.info, addedSlots); if (slot == -1) // full { return(MoveResult.NotEnoughSlots); } addedSlots.Add(slot); var ovenSlot = new OvenSlot { Position = existingItem?.position, Index = slot, Item = existingItem }; int currentAmount = existingItem?.amount ?? 0; int missingAmount = totalStackSize - currentAmount + (i < remaining ? 1 : 0); ovenSlot.DeltaAmount = missingAmount; //Puts("[{0}] current: {1}, delta: {2}, total: {3}", slot, currentAmount, ovenSlot.DeltaAmount, currentAmount + missingAmount); if (currentAmount + missingAmount <= 0) { continue; } ovenSlots.Add(ovenSlot); } foreach (var slot in ovenSlots) { if (slot.Item == null) { var newItem = ItemManager.Create(item.info, slot.DeltaAmount, item.skin); slot.Item = newItem; newItem.MoveToContainer(container, slot.Position ?? slot.Index); } else { slot.Item.amount += slot.DeltaAmount; } totalMoved += slot.DeltaAmount; } container.MarkDirty(); if (totalMoved >= item.amount) { item.Remove(); item.GetRootContainer()?.MarkDirty(); return(MoveResult.Ok); } else { item.amount -= totalMoved; item.GetRootContainer()?.MarkDirty(); return(MoveResult.SlotsFilled); } }
private object CanMoveItem(Item item, PlayerInventory playerLoot, uint targetContainer, int targetSlot) { Func <object> splitFunc = () => { using (TimeWarning.New("FurnaceSplitter.CanMoveItem", 0.005f)) { var player = Extensions.GetBaseEntity(playerLoot.loot); var container = playerLoot.FindContainer(targetContainer); var originalContainer = item.GetRootContainer(); if (player == null || !GetEnabled(player)) { return(null); } var playerOptions = allPlayerOptions[player.userID]; if (container == null || container == item.GetRootContainer()) { return(null); } var oven = container.entityOwner as BaseOven; var cookable = item.info.GetComponent <ItemModCookable>(); if (oven == null || cookable == null) { return(null); } int totalSlots = 2 + (oven.allowByproductCreation ? 1 : 0); if (playerOptions.TotalStacks.ContainsKey(oven.ShortPrefabName)) { totalSlots = playerOptions.TotalStacks[oven.ShortPrefabName]; } float workTemperature = Extensions.GetWorkTemperature(oven); if (cookable.lowTemp > workTemperature || cookable.highTemp < workTemperature) { return(null); } int invalidItemsCount = container.itemList.Count(slotItem => !IsSlotCompatible(slotItem, oven, item.info)); int numOreSlots = Math.Min(container.capacity - invalidItemsCount, totalSlots); int totalMoved = 0; int totalAmount = Math.Min(item.amount + container.itemList.Where(slotItem => slotItem.info == item.info).Take(numOreSlots).Sum(slotItem => slotItem.amount), item.info.stackable * numOreSlots); if (numOreSlots <= 0) { return(true); } //Puts("---------------------------"); int totalStackSize = Math.Min(totalAmount / numOreSlots, item.info.stackable); int remaining = totalAmount - (totalAmount / numOreSlots) * numOreSlots; List <int> addedSlots = new List <int>(); //Puts("total: {0}, remaining: {1}, totalStackSize: {2}", totalAmount, remaining, totalStackSize); List <OvenSlot> ovenSlots = new List <OvenSlot>(); for (int i = 0; i < numOreSlots; ++i) { Item existingItem; var slot = FindMatchingSlotIndex(container, out existingItem, item.info, addedSlots); if (slot == -1) // full { return(true); } addedSlots.Add(slot); var ovenSlot = new OvenSlot { Position = existingItem?.position, Index = slot, Item = existingItem }; int currentAmount = existingItem?.amount ?? 0; int missingAmount = totalStackSize - currentAmount + (i < remaining ? 1 : 0); ovenSlot.DeltaAmount = missingAmount; //Puts("[{0}] current: {1}, delta: {2}, total: {3}", slot, currentAmount, ovenSlot.DeltaAmount, currentAmount + missingAmount); if (currentAmount + missingAmount <= 0) { continue; } ovenSlots.Add(ovenSlot); } foreach (var slot in ovenSlots) { if (slot.Item == null) { var newItem = ItemManager.Create(item.info, slot.DeltaAmount, item.skin); slot.Item = newItem; newItem.MoveToContainer(container, slot.Position ?? slot.Index); } else { slot.Item.amount += slot.DeltaAmount; } totalMoved += slot.DeltaAmount; } if (totalMoved >= item.amount) { item.Remove(); } else { item.amount -= totalMoved; } container.MarkDirty(); originalContainer.MarkDirty(); return(true); } }; object returnValue = splitFunc(); { var container = playerLoot.FindContainer(targetContainer); var oven = container?.entityOwner as BaseOven ?? item.GetRootContainer().entityOwner as BaseOven; if (oven != null && compatibleOvens.Contains(oven.ShortPrefabName)) { queuedUiUpdates.Push(oven); } } return(returnValue); }