use of mekanism.common.inventory.container.SelectedWindowData in project Mekanism by mekanism.
the class QIOServerCraftingTransferHandler method transferItems.
private void transferItems(Byte2ObjectMap<List<SingularHashedItemSource>> sources) {
SelectedWindowData windowData = craftingWindow.getWindowData();
// Extract items that will be put into the crafting window
Byte2ObjectMap<ItemStack> targetContents = new Byte2ObjectArrayMap<>(sources.size());
for (Byte2ObjectMap.Entry<List<SingularHashedItemSource>> entry : sources.byte2ObjectEntrySet()) {
for (SingularHashedItemSource source : entry.getValue()) {
byte slot = source.getSlot();
ItemStack stack;
if (slot == -1) {
UUID qioSource = source.getQioSource();
// Neither the source nor the frequency can be null here as we validated that during simulation
HashedItem storedItem = frequency.getTypeByUUID(qioSource);
if (storedItem == null) {
bail(targetContents, "Received transfer request from: {}, for: {}, could not find stored item with UUID: {}. " + "This likely means that more of it was requested than is stored.", player, recipeID, qioSource);
return;
}
stack = frequency.removeByType(storedItem, source.getUsed());
if (stack.isEmpty()) {
bail(targetContents, "Received transfer request from: {}, for: {}, but could not extract item: {} with nbt: {} from the QIO.", player, recipeID, storedItem.getStack().getItem(), storedItem.getStack().getTag());
return;
} else if (stack.getCount() < source.getUsed()) {
Mekanism.logger.warn("Received transfer request from: {}, for: {}, but was unable to extract the expected amount: {} of item: {} " + "with nbt: {} from the QIO. This should not be possible as it should have been caught during simulation. Attempting " + "to continue anyways with the actual extracted amount of {}.", player, recipeID, source.getUsed(), storedItem.getStack().getItem(), storedItem.getStack().getTag(), stack.getCount());
}
} else {
int actualSlot;
String slotType;
if (slot < 9) {
// Crafting Window
actualSlot = slot;
slotType = "crafting window";
stack = craftingWindow.getInputSlot(slot).extractItem(source.getUsed(), Action.EXECUTE, AutomationType.MANUAL);
} else if (slot < 9 + PlayerInventory.getSelectionSize()) {
// Hotbar
actualSlot = slot - 9;
slotType = "hotbar";
stack = hotBarSlots.get(actualSlot).remove(source.getUsed());
} else {
// Main inventory
actualSlot = slot - 9 - PlayerInventory.getSelectionSize();
slotType = "main inventory";
stack = mainInventorySlots.get(actualSlot).remove(source.getUsed());
}
if (stack.isEmpty()) {
bail(targetContents, "Received transfer request from: {}, for: {}, could not extract item from {} slot: {}. " + "This likely means that more of it was requested than is stored.", player, recipeID, slotType, actualSlot);
return;
} else if (stack.getCount() < source.getUsed()) {
Mekanism.logger.warn("Received transfer request from: {}, for: {}, but was unable to extract the expected amount: {} from {} slot: {}. " + "This should not be possible as it should have been caught during simulation. Attempting to continue anyways with the " + "actual extracted amount of {}.", player, recipeID, source.getUsed(), slotType, actualSlot, stack.getCount());
}
}
byte targetSlot = entry.getByteKey();
if (targetContents.containsKey(targetSlot)) {
ItemStack existing = targetContents.get(targetSlot);
if (ItemHandlerHelper.canItemStacksStack(existing, stack)) {
int needed = existing.getMaxStackSize() - existing.getCount();
if (stack.getCount() <= needed) {
existing.grow(stack.getCount());
} else {
existing.grow(needed);
// Note: We can safely modify the stack as all our ways of extracting return a new stack
stack.shrink(needed);
Mekanism.logger.warn("Received transfer request from: {}, for: {}, but contents could not fully fit into target slot: {}. " + "This should not be able to happen, returning excess stack, and attempting to continue.", player, recipeID, targetSlot);
returnItem(stack, windowData);
}
} else {
Mekanism.logger.warn("Received transfer request from: {}, for: {}, but contents could not stack into target slot: {}. " + "This should not be able to happen, returning extra stack, and attempting to continue.", player, recipeID, targetSlot);
returnItem(stack, windowData);
}
} else {
// Note: We can safely modify the stack as all our ways of extracting return a new stack
targetContents.put(targetSlot, stack);
}
}
}
// Extract what items are still in the window
Byte2ObjectMap<ItemStack> remainingCraftingGridContents = new Byte2ObjectArrayMap<>(9);
for (byte slot = 0; slot < 9; slot++) {
CraftingWindowInventorySlot inputSlot = craftingWindow.getInputSlot(slot);
if (!inputSlot.isEmpty()) {
ItemStack stack = inputSlot.extractItem(inputSlot.getCount(), Action.EXECUTE, AutomationType.MANUAL);
if (!stack.isEmpty()) {
remainingCraftingGridContents.put(slot, stack);
} else {
bail(targetContents, remainingCraftingGridContents, "Received transfer request from: {}, for: {}, but failed to remove items from crafting " + "input slot: {}. This should not be possible as it should have been caught by an earlier check.", player, recipeID, slot);
return;
}
}
}
// Insert items for the crafting window into it
for (ObjectIterator<Byte2ObjectMap.Entry<ItemStack>> iter = targetContents.byte2ObjectEntrySet().iterator(); iter.hasNext(); ) {
Byte2ObjectMap.Entry<ItemStack> entry = iter.next();
byte targetSlot = entry.getByteKey();
CraftingWindowInventorySlot inputSlot = craftingWindow.getInputSlot(targetSlot);
ItemStack remainder = inputSlot.insertItem(entry.getValue(), Action.EXECUTE, AutomationType.MANUAL);
if (remainder.isEmpty()) {
// If it was fully inserted, remove the entry from what we have left to deal with
iter.remove();
} else {
// otherwise, update the stack for what is remaining and also print a warning as this should have been caught earlier,
// as we then will handle any remaining contents at the end (though we shouldn't have any)
// Note: We need to use put, as entry#setValue is not supported in fastutil maps
targetContents.put(targetSlot, remainder);
Mekanism.logger.warn("Received transfer request from: {}, for: {}, but was unable to fully insert it into the {} crafting input slot. " + "This should not be possible as it should have been caught during simulation. Attempting to continue anyways.", player, recipeID, targetSlot);
}
}
// Put the items that were in the crafting window in the player's inventory
for (Byte2ObjectMap.Entry<ItemStack> entry : remainingCraftingGridContents.byte2ObjectEntrySet()) {
// Insert into player's inventory
ItemStack stack = returnItemToInventory(entry.getValue(), windowData);
if (!stack.isEmpty()) {
// If we couldn't insert it all, try recombining with the slots they were in the crafting window
// (only if the type matches though)
CraftingWindowInventorySlot inputSlot = craftingWindow.getInputSlot(entry.getByteKey());
if (ItemHandlerHelper.canItemStacksStack(inputSlot.getStack(), stack)) {
stack = inputSlot.insertItem(stack, Action.EXECUTE, AutomationType.MANUAL);
}
if (!stack.isEmpty()) {
// If we couldn't insert it, then try to put the remaining items in the frequency
if (frequency != null) {
stack = frequency.addItem(stack);
}
if (!stack.isEmpty()) {
// If we couldn't insert it all, either because there was no frequency or it didn't have room for it all
// drop it as the player, and print a warning as ideally we should never have been able to get to this
// point as our simulation should have marked it as invalid
// Note: In theory we should never get to this point due to having accurate simulations ahead of time
player.drop(stack, false);
Mekanism.logger.warn("Received transfer request from: {}, for: {}, and was unable to fit all contents that were in the crafting window " + "into the player's inventory/QIO system; dropping items by player.", player, recipeID);
}
}
}
}
if (!targetContents.isEmpty()) {
// If we have any contents we wanted to move remaining try to return them, in theory
// this should never happen but in case it does make sure we don't void any items
bail(targetContents, "Received transfer request from: {}, for: {}, but ended up with {} items that could not be transferred into " + "the proper crafting grid slot. This should not be possible as it should have been caught during simulation.", player, recipeID, targetContents.size());
}
}
use of mekanism.common.inventory.container.SelectedWindowData in project Mekanism by mekanism.
the class QIOServerCraftingTransferHandler method bail.
/**
* Bails out if something went horribly wrong and didn't get caught by simulations, and send the various items back to the inventory.
*/
private void bail(Byte2ObjectMap<ItemStack> targetContents, Byte2ObjectMap<ItemStack> remainingCraftingGridContents, String format, Object... args) {
Mekanism.logger.warn(format, args);
SelectedWindowData windowData = craftingWindow.getWindowData();
for (ItemStack stack : targetContents.values()) {
// We don't attempt to try and return the contents being moved to the crafting inventory to their original slots
// as we don't keep track of that data and in theory unless something goes majorly wrong we should never end
// up bailing anyways
// TODO: Eventually we may want to try and make it first try to return to the same slots it came from but it doesn't matter that much
returnItem(stack, windowData);
}
// Put the items that were in the crafting window in the player's inventory
for (Byte2ObjectMap.Entry<ItemStack> entry : remainingCraftingGridContents.byte2ObjectEntrySet()) {
ItemStack stack = entry.getValue();
CraftingWindowInventorySlot inputSlot = craftingWindow.getInputSlot(entry.getByteKey());
if (ItemHandlerHelper.canItemStacksStack(inputSlot.getStack(), stack)) {
stack = inputSlot.insertItem(stack, Action.EXECUTE, AutomationType.MANUAL);
if (stack.isEmpty()) {
continue;
}
}
returnItem(stack, windowData);
}
}
use of mekanism.common.inventory.container.SelectedWindowData in project Mekanism by mekanism.
the class PacketWindowSelect method decode.
public static PacketWindowSelect decode(PacketBuffer buffer) {
byte extraData = buffer.readByte();
if (extraData == -1) {
return new PacketWindowSelect(null);
}
WindowType windowType = buffer.readEnum(WindowType.class);
return new PacketWindowSelect(windowType == WindowType.UNSPECIFIED ? SelectedWindowData.UNSPECIFIED : new SelectedWindowData(windowType, extraData));
}
Aggregations