use of mekanism.api.inventory.IInventorySlot in project Mekanism by mekanism.
the class TileEntityFactory method sortInventory.
// End methods IComputerTile
private void sortInventory() {
Map<HashedItem, RecipeProcessInfo> processes = new HashMap<>();
List<ProcessInfo> emptyProcesses = new ArrayList<>();
for (ProcessInfo processInfo : processInfoSlots) {
IInventorySlot inputSlot = processInfo.getInputSlot();
if (inputSlot.isEmpty()) {
emptyProcesses.add(processInfo);
} else {
ItemStack inputStack = inputSlot.getStack();
HashedItem item = HashedItem.raw(inputStack);
RecipeProcessInfo recipeProcessInfo = processes.computeIfAbsent(item, i -> new RecipeProcessInfo());
recipeProcessInfo.processes.add(processInfo);
recipeProcessInfo.totalCount += inputStack.getCount();
if (recipeProcessInfo.lazyMinPerSlot == null && !CommonWorldTickHandler.flushTagAndRecipeCaches) {
// If we don't have a lazily initialized min per slot calculation set for it yet
// and our cache is not invalid/out of date due to a reload
CachedRecipe<RECIPE> cachedRecipe = getCachedRecipe(processInfo.getProcess());
if (isCachedRecipeValid(cachedRecipe, inputStack)) {
// And our current process has a cached recipe then set the lazily initialized per slot value
// Note: If something goes wrong, and we end up with zero as how much we need as an input
// we just bump the value up to one to make sure we properly handle it
recipeProcessInfo.lazyMinPerSlot = () -> Math.max(1, getNeededInput(cachedRecipe.getRecipe(), inputStack));
}
}
}
}
if (processes.isEmpty()) {
// If all input slots are empty, just exit
return;
}
for (Entry<HashedItem, RecipeProcessInfo> entry : processes.entrySet()) {
RecipeProcessInfo recipeProcessInfo = entry.getValue();
if (recipeProcessInfo.lazyMinPerSlot == null) {
// If we don't have a lazy initializer for our minPerSlot setup, that means that there is
// no valid cached recipe for any of the slots of this type currently, so we want to try and
// get the recipe we will have for the first slot, once we end up with more items in the stack
recipeProcessInfo.lazyMinPerSlot = () -> {
// Note: We put all of this logic in the lazy init, so that we don't actually call any of this
// until it is needed. That way if we have no empty slots and all our input slots are filled
// we don't do any extra processing here, and can properly short circuit
HashedItem item = entry.getKey();
ItemStack largerInput = item.createStack(Math.min(item.getStack().getMaxStackSize(), recipeProcessInfo.totalCount));
ProcessInfo processInfo = recipeProcessInfo.processes.get(0);
// Try getting a recipe for our input with a larger size, and update the cache if we find one
RECIPE recipe = getRecipeForInput(processInfo.getProcess(), largerInput, processInfo.getOutputSlot(), processInfo.getSecondaryOutputSlot(), true);
if (recipe != null) {
return Math.max(1, getNeededInput(recipe, largerInput));
}
return 1;
};
}
}
if (!emptyProcesses.isEmpty()) {
// If we have any empty slots, we need to factor them in as valid slots for items to transferred to
addEmptySlotsAsTargets(processes, emptyProcesses);
// Note: Any remaining empty slots are "ignored" as we don't have any
// spare items to distribute to them
}
// Distribute items among the slots
distributeItems(processes);
}
use of mekanism.api.inventory.IInventorySlot in project Mekanism by mekanism.
the class TileEntitySawingFactory method getSecondaryOutput.
// Methods relating to IComputerTile
@ComputerMethod
private ItemStack getSecondaryOutput(int process) throws ComputerException {
validateValidProcess(process);
IInventorySlot secondaryOutputSlot = processInfoSlots[process].getSecondaryOutputSlot();
// This should never be null, but in case it is, handle it
return secondaryOutputSlot == null ? ItemStack.EMPTY : secondaryOutputSlot.getStack();
}
use of mekanism.api.inventory.IInventorySlot in project Mekanism by mekanism.
the class ISideConfiguration method getActiveDataType.
@Nullable
default DataType getActiveDataType(Object container) {
ConfigInfo info = null;
TileComponentConfig config = getConfig();
if (container instanceof IGasTank && config.supports(TransmissionType.GAS)) {
info = config.getConfig(TransmissionType.GAS);
} else if (container instanceof IInfusionTank && config.supports(TransmissionType.INFUSION)) {
info = config.getConfig(TransmissionType.INFUSION);
} else if (container instanceof IPigmentTank && config.supports(TransmissionType.PIGMENT)) {
info = config.getConfig(TransmissionType.PIGMENT);
} else if (container instanceof ISlurryTank && config.supports(TransmissionType.SLURRY)) {
info = config.getConfig(TransmissionType.SLURRY);
} else if (container instanceof IExtendedFluidTank && config.supports(TransmissionType.FLUID)) {
info = config.getConfig(TransmissionType.FLUID);
} else if (container instanceof IInventorySlot && config.supports(TransmissionType.ITEM)) {
info = config.getConfig(TransmissionType.ITEM);
}
if (info != null) {
List<DataType> types = info.getDataTypeForContainer(container);
int count = types.size();
// of <= size - 1 to cut down slightly on the calculations
if (count > 0 && count < info.getSupportedDataTypes().size()) {
return types.get(0);
}
}
return null;
}
use of mekanism.api.inventory.IInventorySlot in project Mekanism by mekanism.
the class TileComponentConfig method setupItemIOConfig.
public ConfigInfo setupItemIOConfig(List<IInventorySlot> inputSlots, List<IInventorySlot> outputSlots, IInventorySlot energySlot, boolean alwaysAllow) {
ConfigInfo itemConfig = getConfig(TransmissionType.ITEM);
if (itemConfig != null) {
itemConfig.addSlotInfo(DataType.INPUT, new InventorySlotInfo(true, alwaysAllow, inputSlots));
itemConfig.addSlotInfo(DataType.OUTPUT, new InventorySlotInfo(alwaysAllow, true, outputSlots));
List<IInventorySlot> ioSlots = new ArrayList<>(inputSlots);
ioSlots.addAll(outputSlots);
itemConfig.addSlotInfo(DataType.INPUT_OUTPUT, new InventorySlotInfo(true, true, ioSlots));
itemConfig.addSlotInfo(DataType.ENERGY, new InventorySlotInfo(true, true, energySlot));
// Set default config directions
itemConfig.setDefaults();
}
return itemConfig;
}
use of mekanism.api.inventory.IInventorySlot in project Mekanism by mekanism.
the class TileEntityFormulaicAssemblicator method doSingleCraft.
private boolean doSingleCraft() {
recalculateRecipe();
ItemStack output = lastOutputStack;
if (!output.isEmpty() && tryMoveToOutput(output, Action.SIMULATE) && (lastRemainingItems.isEmpty() || lastRemainingItems.stream().allMatch(it -> it.isEmpty() || tryMoveToOutput(it, Action.SIMULATE)))) {
tryMoveToOutput(output, Action.EXECUTE);
// For example if there are multiple stacks of dirt in remaining and we have room for one stack, but given we only check one stack at a time...)
for (ItemStack remainingItem : lastRemainingItems) {
if (!remainingItem.isEmpty()) {
// TODO: Check if it matters that we are not actually updating the list of remaining items?
// The better solution would be to not allow continuing until we moved output AND all remaining items
// instead of trying to move all at once??
tryMoveToOutput(remainingItem, Action.EXECUTE);
}
}
for (IInventorySlot craftingSlot : craftingGridSlots) {
if (!craftingSlot.isEmpty()) {
MekanismUtils.logMismatchedStackSize(craftingSlot.shrinkStack(1, Action.EXECUTE), 1);
}
}
if (formula != null) {
moveItemsToGrid();
}
markDirty(false);
return true;
}
return false;
}
Aggregations