Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d4e5734e8 | |||
| 00ac7c3334 | |||
| bcc28c0b28 | |||
| a03d6f4803 | |||
| e3b8228608 |
@@ -32,9 +32,7 @@ import appeng.api.networking.storage.IStorageGrid;
|
|||||||
import appeng.api.storage.IMEMonitor;
|
import appeng.api.storage.IMEMonitor;
|
||||||
import appeng.api.storage.channels.IItemStorageChannel;
|
import appeng.api.storage.channels.IItemStorageChannel;
|
||||||
import appeng.api.storage.data.IAEItemStack;
|
import appeng.api.storage.data.IAEItemStack;
|
||||||
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
|
|
||||||
import appeng.container.implementations.ContainerPatternEncoder;
|
import appeng.container.implementations.ContainerPatternEncoder;
|
||||||
import appeng.container.implementations.ContainerPatternTerm;
|
|
||||||
import appeng.core.sync.AppEngPacket;
|
import appeng.core.sync.AppEngPacket;
|
||||||
import appeng.core.sync.network.INetworkInfo;
|
import appeng.core.sync.network.INetworkInfo;
|
||||||
import appeng.helpers.IContainerCraftingPacket;
|
import appeng.helpers.IContainerCraftingPacket;
|
||||||
@@ -47,6 +45,7 @@ import appeng.util.item.AEItemStack;
|
|||||||
import appeng.util.prioritylist.IPartitionList;
|
import appeng.util.prioritylist.IPartitionList;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
import net.minecraft.inventory.Container;
|
import net.minecraft.inventory.Container;
|
||||||
@@ -69,9 +68,10 @@ import static appeng.helpers.ItemStackHelper.stackFromNBT;
|
|||||||
|
|
||||||
public class PacketJEIRecipe extends AppEngPacket {
|
public class PacketJEIRecipe extends AppEngPacket {
|
||||||
|
|
||||||
|
static ItemStack[] emptyArray = {ItemStack.EMPTY};
|
||||||
private List<ItemStack[]> recipe;
|
private List<ItemStack[]> recipe;
|
||||||
private List<ItemStack> output;
|
private List<ItemStack> output;
|
||||||
static ItemStack[] emptyArray = {ItemStack.EMPTY};
|
private boolean shouldCondense;
|
||||||
|
|
||||||
|
|
||||||
// automatic.
|
// automatic.
|
||||||
@@ -80,6 +80,7 @@ public class PacketJEIRecipe extends AppEngPacket {
|
|||||||
bytes.skip(stream.readerIndex());
|
bytes.skip(stream.readerIndex());
|
||||||
final NBTTagCompound comp = CompressedStreamTools.readCompressed(bytes);
|
final NBTTagCompound comp = CompressedStreamTools.readCompressed(bytes);
|
||||||
if (comp != null) {
|
if (comp != null) {
|
||||||
|
this.shouldCondense = comp.getBoolean("condense");
|
||||||
this.recipe = new ArrayList<>();
|
this.recipe = new ArrayList<>();
|
||||||
|
|
||||||
for (int x = 0; x < comp.getKeySet().size(); x++) {
|
for (int x = 0; x < comp.getKeySet().size(); x++) {
|
||||||
@@ -104,7 +105,6 @@ public class PacketJEIRecipe extends AppEngPacket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// api
|
// api
|
||||||
@@ -124,167 +124,212 @@ public class PacketJEIRecipe extends AppEngPacket {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serverPacketData(final INetworkInfo manager, final AppEngPacket packet, final EntityPlayer player) {
|
public void serverPacketData(final INetworkInfo manager, final AppEngPacket packet, final EntityPlayer player) {
|
||||||
|
// oops :)
|
||||||
|
if (this.recipe == null) return;
|
||||||
|
|
||||||
final EntityPlayerMP pmp = (EntityPlayerMP) player;
|
final EntityPlayerMP pmp = (EntityPlayerMP) player;
|
||||||
final Container con = pmp.openContainer;
|
final Container con = pmp.openContainer;
|
||||||
|
if (!(con instanceof IContainerCraftingPacket cct)) return;
|
||||||
|
|
||||||
if (!(con instanceof IContainerCraftingPacket)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final IContainerCraftingPacket cct = (IContainerCraftingPacket) con;
|
|
||||||
final IGridNode node = cct.getNetworkNode();
|
final IGridNode node = cct.getNetworkNode();
|
||||||
|
if (node == null) return;
|
||||||
if (node == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final IGrid grid = node.getGrid();
|
final IGrid grid = node.getGrid();
|
||||||
if (grid == null) {
|
if (grid == null) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final IStorageGrid inv = grid.getCache(IStorageGrid.class);
|
final IStorageGrid inv = grid.getCache(IStorageGrid.class);
|
||||||
|
if (inv == null) return;
|
||||||
final IEnergyGrid energy = grid.getCache(IEnergyGrid.class);
|
final IEnergyGrid energy = grid.getCache(IEnergyGrid.class);
|
||||||
final ISecurityGrid security = grid.getCache(ISecurityGrid.class);
|
if (energy == null) return;
|
||||||
|
|
||||||
|
final boolean hasExtractPermissions;
|
||||||
|
final boolean hasInjectPermissions;
|
||||||
|
if (grid.getCache(ISecurityGrid.class) instanceof ISecurityGrid security) {
|
||||||
|
hasInjectPermissions = security.hasPermission(player, SecurityPermissions.INJECT);
|
||||||
|
hasExtractPermissions = security.hasPermission(player, SecurityPermissions.EXTRACT);
|
||||||
|
} else {
|
||||||
|
hasInjectPermissions = false;
|
||||||
|
hasExtractPermissions = false;
|
||||||
|
}
|
||||||
|
|
||||||
final ICraftingGrid crafting = grid.getCache(ICraftingGrid.class);
|
final ICraftingGrid crafting = grid.getCache(ICraftingGrid.class);
|
||||||
final IItemHandler craftMatrix = cct.getInventoryByName("crafting");
|
final IItemHandler craftMatrix = cct.getInventoryByName("crafting");
|
||||||
final IItemHandler playerInventory = cct.getInventoryByName("player");
|
final IItemHandler playerInventory = cct.getInventoryByName("player");
|
||||||
|
|
||||||
if (inv != null && this.recipe != null && security != null) {
|
final Object2LongLinkedOpenHashMap<IAEItemStack> condensedBuffer;
|
||||||
final IMEMonitor<IAEItemStack> storage = inv.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class));
|
if (this.shouldCondense) {
|
||||||
final IPartitionList<IAEItemStack> filter = ItemViewCell.createFilter(cct.getViewCells());
|
condensedBuffer = new Object2LongLinkedOpenHashMap<>();
|
||||||
|
} else {
|
||||||
|
condensedBuffer = null;
|
||||||
|
}
|
||||||
|
|
||||||
for (int x = 0; x < craftMatrix.getSlots(); x++) {
|
final IMEMonitor<IAEItemStack> storage = inv.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class));
|
||||||
ItemStack currentItem = craftMatrix.getStackInSlot(x);
|
final IPartitionList<IAEItemStack> filter = ItemViewCell.createFilter(cct.getViewCells());
|
||||||
|
|
||||||
if (x >= this.recipe.size()) {
|
// First iteration, find what can be used and send everything else into the network.
|
||||||
currentItem = ItemStack.EMPTY;
|
for (int matrixSlotIndex = 0; matrixSlotIndex < craftMatrix.getSlots(); matrixSlotIndex++) {
|
||||||
|
var currentItem = craftMatrix.getStackInSlot(matrixSlotIndex);
|
||||||
|
if (!currentItem.isEmpty()) {
|
||||||
|
if (this.canUseInSlot(matrixSlotIndex, currentItem)) continue;
|
||||||
|
|
||||||
|
if (!cct.useRealItems()) {
|
||||||
|
currentItem.setCount(0);
|
||||||
|
} else if (hasInjectPermissions) {
|
||||||
|
final var out = Platform.poweredInsert(energy, storage,
|
||||||
|
AEItemStack.fromItemStack(currentItem), cct.getActionSource());
|
||||||
|
|
||||||
|
currentItem.setCount(out != null ? (int) out.getStackSize() : 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// prepare slots
|
// Second iteration, query AE2 & player inventory for items.
|
||||||
if (!currentItem.isEmpty()) {
|
for (int recipeSlotIndex = 0; recipeSlotIndex < recipe.size(); recipeSlotIndex++) {
|
||||||
// already the correct item?
|
ItemStack currentItem;
|
||||||
ItemStack newItem = this.canUseInSlot(x, currentItem);
|
|
||||||
|
|
||||||
if (!cct.useRealItems() && this.recipe.get(x) != null) {
|
if (recipeSlotIndex < craftMatrix.getSlots()) {
|
||||||
if (this.recipe.get(x).length > 0) {
|
currentItem = craftMatrix.getStackInSlot(recipeSlotIndex);
|
||||||
currentItem.setCount(recipe.get(x)[0].getCount());
|
} else if (this.shouldCondense) {
|
||||||
}
|
// If the inputs should be condensed, we can read past the current grid.
|
||||||
}
|
currentItem = ItemStack.EMPTY;
|
||||||
|
} else {
|
||||||
|
// Otherwise break.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// put away old item
|
if (currentItem.isEmpty() && recipe.get(recipeSlotIndex) != null) {
|
||||||
if (newItem != currentItem && security.hasPermission(player, SecurityPermissions.INJECT)) {
|
// for each variant
|
||||||
final IAEItemStack in = AEItemStack.fromItemStack(currentItem);
|
for (int y = 0; y < this.recipe.get(recipeSlotIndex).length && currentItem.isEmpty(); y++) {
|
||||||
final IAEItemStack out = cct.useRealItems() ? Platform.poweredInsert(energy, storage, in, cct.getActionSource()) : null;
|
var recipeStackVariant = this.recipe.get(recipeSlotIndex)[y];
|
||||||
if (out != null) {
|
final IAEItemStack request = AEItemStack.fromItemStack(recipeStackVariant);
|
||||||
currentItem = out.createItemStack();
|
if (request != null) {
|
||||||
} else {
|
// try ae
|
||||||
currentItem = ItemStack.EMPTY;
|
if ((filter == null || filter.isListed(request)) && hasExtractPermissions) {
|
||||||
}
|
request.setStackSize(1);
|
||||||
}
|
IAEItemStack out;
|
||||||
}
|
|
||||||
|
|
||||||
if (currentItem.isEmpty() && recipe.size() > x && recipe.get(x) != null) {
|
if (cct.useRealItems()) {
|
||||||
// for each variant
|
out = Platform.poweredExtraction(energy, storage, request, cct.getActionSource());
|
||||||
for (int y = 0; y < this.recipe.get(x).length && currentItem.isEmpty(); y++) {
|
if (out == null) {
|
||||||
final IAEItemStack request = AEItemStack.fromItemStack(this.recipe.get(x)[y]);
|
if (request.getItem().isDamageable() || Platform.isGTDamageableItem(request.getItem())) {
|
||||||
if (request != null) {
|
Collection<IAEItemStack> outList = inv.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)).getStorageList().findFuzzy(request, FuzzyMode.IGNORE_ALL);
|
||||||
// try ae
|
for (IAEItemStack is : outList) {
|
||||||
if ((filter == null || filter.isListed(request)) && security.hasPermission(player, SecurityPermissions.EXTRACT)) {
|
if (is.getStackSize() == 0) {
|
||||||
request.setStackSize(1);
|
continue;
|
||||||
IAEItemStack out;
|
}
|
||||||
|
if (Platform.isGTDamageableItem(request.getItem())) {
|
||||||
if (cct.useRealItems()) {
|
if (!(is.getDefinition().getMetadata() == request.getDefinition().getMetadata())) {
|
||||||
out = Platform.poweredExtraction(energy, storage, request, cct.getActionSource());
|
|
||||||
if (out == null) {
|
|
||||||
if (request.getItem().isDamageable() || Platform.isGTDamageableItem(request.getItem())) {
|
|
||||||
Collection<IAEItemStack> outList = inv.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)).getStorageList().findFuzzy(request, FuzzyMode.IGNORE_ALL);
|
|
||||||
for (IAEItemStack is : outList) {
|
|
||||||
if (is.getStackSize() == 0) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (Platform.isGTDamageableItem(request.getItem())) {
|
}
|
||||||
if (!(is.getDefinition().getMetadata() == request.getDefinition().getMetadata())) {
|
out = Platform.poweredExtraction(energy, storage, is.copy().setStackSize(1), cct.getActionSource());
|
||||||
continue;
|
if (out != null) {
|
||||||
}
|
break;
|
||||||
}
|
|
||||||
out = Platform.poweredExtraction(energy, storage, is.copy().setStackSize(1), cct.getActionSource());
|
|
||||||
if (out != null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Query the crafting grid if there is a pattern providing the item
|
|
||||||
if (!crafting.getCraftingFor(request, null, 0, null).isEmpty()) {
|
|
||||||
out = request;
|
|
||||||
} else {
|
|
||||||
// Fall back using an existing item
|
|
||||||
out = storage.extractItems(request, Actionable.SIMULATE, cct.getActionSource());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if (out != null) {
|
// Query the crafting grid if there is a pattern providing the item
|
||||||
if (!cct.useRealItems()) {
|
if (!crafting.getCraftingFor(request, null, 0, null).isEmpty()) {
|
||||||
out.setStackSize(recipe.get(x)[y].getCount());
|
out = request;
|
||||||
}
|
} else {
|
||||||
currentItem = out.createItemStack();
|
// Fall back using an existing item
|
||||||
|
out = storage.extractItems(request, Actionable.SIMULATE, cct.getActionSource());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// try inventory
|
if (out != null) {
|
||||||
if (currentItem.isEmpty()) {
|
if (!cct.useRealItems()) {
|
||||||
AdaptorItemHandler ad = new AdaptorItemHandler(playerInventory);
|
out.setStackSize(recipeStackVariant.getCount());
|
||||||
|
|
||||||
if (cct.useRealItems()) {
|
|
||||||
currentItem = ad.removeSimilarItems(1, this.recipe.get(x)[y], FuzzyMode.IGNORE_ALL, null);
|
|
||||||
} else {
|
|
||||||
currentItem = ad.simulateSimilarRemove(recipe.get(x)[y].getCount(), this.recipe.get(x)[y], FuzzyMode.IGNORE_ALL, null);
|
|
||||||
}
|
}
|
||||||
|
currentItem = out.createItemStack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!cct.useRealItems()) {
|
// try inventory
|
||||||
if (currentItem.isEmpty() && recipe.size() > x && this.recipe.get(x) != null) {
|
if (currentItem.isEmpty()) {
|
||||||
currentItem = this.recipe.get(x)[0].copy();
|
AdaptorItemHandler ad = new AdaptorItemHandler(playerInventory);
|
||||||
|
|
||||||
|
if (cct.useRealItems()) {
|
||||||
|
currentItem = ad.removeSimilarItems(1, recipeStackVariant, FuzzyMode.IGNORE_ALL, null);
|
||||||
|
} else {
|
||||||
|
currentItem = ad.simulateSimilarRemove(recipeStackVariant.getCount(), recipeStackVariant, FuzzyMode.IGNORE_ALL, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ItemHandlerUtil.setStackInSlot(craftMatrix, x, currentItem);
|
|
||||||
|
if (!cct.useRealItems()) {
|
||||||
|
if (currentItem.isEmpty() && recipe.size() > recipeSlotIndex && this.recipe.get(recipeSlotIndex) != null) {
|
||||||
|
currentItem = this.recipe.get(recipeSlotIndex)[0].copy();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
con.onCraftMatrixChanged(new WrapperInvItemHandler(craftMatrix));
|
if (condensedBuffer != null) {
|
||||||
|
var aeItemStack = AEItemStack.fromItemStack(currentItem);
|
||||||
if (this.output != null && ((con instanceof ContainerPatternEncoder && !((ContainerPatternEncoder) con).isCraftingMode()))) {
|
if (aeItemStack != null) {
|
||||||
IItemHandler outputSlots = cct.getInventoryByName("output");
|
condensedBuffer.compute(aeItemStack, (k, v) -> (v == null ? 0 : v) + k.getStackSize());
|
||||||
for (int i = 0; i < outputSlots.getSlots(); ++i) {
|
|
||||||
ItemHandlerUtil.setStackInSlot(outputSlots, i, ItemStack.EMPTY);
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < this.output.size() && i < outputSlots.getSlots(); ++i) {
|
} else {
|
||||||
if (this.output.get(i) == null || this.output.get(i) == ItemStack.EMPTY) {
|
ItemHandlerUtil.setStackInSlot(craftMatrix, recipeSlotIndex, currentItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (condensedBuffer != null) {
|
||||||
|
var slotIndex = 0;
|
||||||
|
|
||||||
|
// Fill the craft matrix with items from the condensed buffer.
|
||||||
|
for (var entry : condensedBuffer.entrySet()) {
|
||||||
|
if (slotIndex >= craftMatrix.getSlots()) break;
|
||||||
|
|
||||||
|
ItemHandlerUtil.setStackInSlot(craftMatrix, slotIndex,
|
||||||
|
entry.getKey().copy().setStackSize(entry.getValue()).createItemStack());
|
||||||
|
slotIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the remaining slots.
|
||||||
|
for (var i = slotIndex; i < craftMatrix.getSlots(); i++) {
|
||||||
|
ItemHandlerUtil.setStackInSlot(craftMatrix, i, ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
con.onCraftMatrixChanged(new WrapperInvItemHandler(craftMatrix));
|
||||||
|
|
||||||
|
if (this.output != null && con instanceof ContainerPatternEncoder encoder && !encoder.isCraftingMode()) {
|
||||||
|
var outputSlots = cct.getInventoryByName("output");
|
||||||
|
for (int i = 0; i < outputSlots.getSlots(); ++i) {
|
||||||
|
if (i < this.output.size()) {
|
||||||
|
var outputStack = this.output.get(i);
|
||||||
|
if (outputStack != null && outputStack != ItemStack.EMPTY) {
|
||||||
|
ItemHandlerUtil.setStackInSlot(outputSlots, i, outputStack);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ItemHandlerUtil.setStackInSlot(outputSlots, i, this.output.get(i));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ItemHandlerUtil.setStackInSlot(outputSlots, i, ItemStack.EMPTY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param slot
|
* @param slot slot index
|
||||||
* @param is itemstack
|
* @param is itemstack
|
||||||
* @return is if it can be used, else EMPTY
|
* @return is if it can be used, else EMPTY
|
||||||
*/
|
*/
|
||||||
private ItemStack canUseInSlot(int slot, ItemStack is) {
|
private boolean canUseInSlot(int slot, ItemStack is) {
|
||||||
if (this.recipe.get(slot) != null) {
|
if (slot >= this.recipe.size()) return false;
|
||||||
for (ItemStack option : this.recipe.get(slot)) {
|
|
||||||
|
var variants = this.recipe.get(slot);
|
||||||
|
if (variants != null) {
|
||||||
|
for (ItemStack option : variants) {
|
||||||
if (ItemStack.areItemStacksEqual(is, option)) {
|
if (ItemStack.areItemStacksEqual(is, option)) {
|
||||||
return is;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ItemStack.EMPTY;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ import mezz.jei.gui.TooltipRenderer;
|
|||||||
import mezz.jei.gui.recipes.RecipeLayout;
|
import mezz.jei.gui.recipes.RecipeLayout;
|
||||||
import mezz.jei.gui.recipes.RecipeTransferButton;
|
import mezz.jei.gui.recipes.RecipeTransferButton;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.ScaledResolution;
|
||||||
import net.minecraft.inventory.Container;
|
import net.minecraft.inventory.Container;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.text.translation.I18n;
|
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
import net.minecraftforge.items.wrapper.PlayerMainInvWrapper;
|
import net.minecraftforge.items.wrapper.PlayerMainInvWrapper;
|
||||||
|
|
||||||
@@ -26,12 +26,14 @@ import javax.annotation.Nonnull;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static mezz.jei.api.recipe.transfer.IRecipeTransferError.Type.USER_FACING;
|
import static mezz.jei.api.recipe.transfer.IRecipeTransferError.Type.USER_FACING;
|
||||||
|
import static net.minecraft.client.resources.I18n.format;
|
||||||
|
|
||||||
public class JEIMissingItem implements IRecipeTransferError {
|
public class JEIMissingItem implements IRecipeTransferError {
|
||||||
|
private final IRecipeLayout recipeLayout;
|
||||||
private boolean errored;
|
private boolean errored;
|
||||||
public long lastUpdate;
|
public long lastUpdate;
|
||||||
private final List<Integer> craftableSlots = new ArrayList<>();
|
private final List<Integer> craftableSlots = new ArrayList<>();
|
||||||
@@ -40,8 +42,11 @@ public class JEIMissingItem implements IRecipeTransferError {
|
|||||||
IItemList<IAEItemStack> available = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
IItemList<IAEItemStack> available = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
||||||
|
|
||||||
IItemList<IAEItemStack> used = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
IItemList<IAEItemStack> used = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
||||||
|
private boolean foundAny;
|
||||||
|
|
||||||
JEIMissingItem(Container container, @Nonnull IRecipeLayout recipeLayout) {
|
JEIMissingItem(Container container, @Nonnull IRecipeLayout recipeLayout) {
|
||||||
|
this.recipeLayout = recipeLayout;
|
||||||
|
|
||||||
if (container instanceof ContainerMEMonitorable) {
|
if (container instanceof ContainerMEMonitorable) {
|
||||||
IItemList<IAEItemStack> ir = ((ContainerMEMonitorable) container).items;
|
IItemList<IAEItemStack> ir = ((ContainerMEMonitorable) container).items;
|
||||||
|
|
||||||
@@ -57,8 +62,7 @@ public class JEIMissingItem implements IRecipeTransferError {
|
|||||||
if (i.isInput() && !i.getAllIngredients().isEmpty()) {
|
if (i.isInput() && !i.getAllIngredients().isEmpty()) {
|
||||||
List<?> allIngredients = i.getAllIngredients();
|
List<?> allIngredients = i.getAllIngredients();
|
||||||
for (Object allIngredient : allIngredients) {
|
for (Object allIngredient : allIngredients) {
|
||||||
if (allIngredient instanceof ItemStack) {
|
if (allIngredient instanceof ItemStack stack) {
|
||||||
ItemStack stack = (ItemStack) allIngredient;
|
|
||||||
if (!stack.isEmpty()) {
|
if (!stack.isEmpty()) {
|
||||||
IAEItemStack search = AEItemStack.fromItemStack(stack);
|
IAEItemStack search = AEItemStack.fromItemStack(stack);
|
||||||
if (stack.getItem().isDamageable() || Platform.isGTDamageableItem(stack.getItem())) {
|
if (stack.getItem().isDamageable() || Platform.isGTDamageableItem(stack.getItem())) {
|
||||||
@@ -93,7 +97,8 @@ public class JEIMissingItem implements IRecipeTransferError {
|
|||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
this.errored = true;
|
this.errored = true;
|
||||||
break;
|
} else{
|
||||||
|
this.foundAny = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,6 +108,13 @@ public class JEIMissingItem implements IRecipeTransferError {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Type getType() {
|
public Type getType() {
|
||||||
|
// Workaround. Re-enable the button if not errored.
|
||||||
|
if (this.errored && this.foundAny && this.recipeLayout instanceof RecipeLayout castedRecipeLayout) {
|
||||||
|
var recipeTransferButton = castedRecipeLayout.getRecipeTransferButton();
|
||||||
|
if (recipeTransferButton != null) {
|
||||||
|
recipeTransferButton.enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return USER_FACING;
|
return USER_FACING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,12 +123,15 @@ public class JEIMissingItem implements IRecipeTransferError {
|
|||||||
Container c = minecraft.player.openContainer;
|
Container c = minecraft.player.openContainer;
|
||||||
if (c instanceof ContainerMEMonitorable container) {
|
if (c instanceof ContainerMEMonitorable container) {
|
||||||
IItemList<IAEItemStack> ir = ((ContainerMEMonitorable) c).items;
|
IItemList<IAEItemStack> ir = ((ContainerMEMonitorable) c).items;
|
||||||
boolean found = false;
|
boolean found;
|
||||||
boolean foundAny = false;
|
boolean craftable;
|
||||||
boolean craftable = false;
|
|
||||||
boolean foundAnyCraftable = false;
|
int foundMissing = 0;
|
||||||
|
int foundCraftables = 0;
|
||||||
int currentSlot = 0;
|
int currentSlot = 0;
|
||||||
|
|
||||||
this.errored = false;
|
this.errored = false;
|
||||||
|
this.foundAny = false;
|
||||||
|
|
||||||
if (System.currentTimeMillis() - lastUpdate > 1000) {
|
if (System.currentTimeMillis() - lastUpdate > 1000) {
|
||||||
lastUpdate = System.currentTimeMillis();
|
lastUpdate = System.currentTimeMillis();
|
||||||
@@ -144,6 +159,7 @@ public class JEIMissingItem implements IRecipeTransferError {
|
|||||||
found = false;
|
found = false;
|
||||||
craftable = false;
|
craftable = false;
|
||||||
IItemList<IAEItemStack> valid = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
IItemList<IAEItemStack> valid = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
||||||
|
|
||||||
if (i.isInput()) {
|
if (i.isInput()) {
|
||||||
List<?> allIngredients = i.getAllIngredients();
|
List<?> allIngredients = i.getAllIngredients();
|
||||||
for (Object allIngredient : allIngredients) {
|
for (Object allIngredient : allIngredients) {
|
||||||
@@ -209,11 +225,12 @@ public class JEIMissingItem implements IRecipeTransferError {
|
|||||||
i.drawHighlight(minecraft, new Color(0.0f, 0.0f, 1.0f, 0.4f), recipeX, recipeY);
|
i.drawHighlight(minecraft, new Color(0.0f, 0.0f, 1.0f, 0.4f), recipeX, recipeY);
|
||||||
this.craftableSlots.add(currentSlot);
|
this.craftableSlots.add(currentSlot);
|
||||||
recipeLayout.getItemStacks().set(currentSlot, validStacks);
|
recipeLayout.getItemStacks().set(currentSlot, validStacks);
|
||||||
foundAnyCraftable = true;
|
foundCraftables++;
|
||||||
} else {
|
} else {
|
||||||
i.drawHighlight(minecraft, new Color(1.0f, 0.0f, 0.0f, 0.4f), recipeX, recipeY);
|
i.drawHighlight(minecraft, new Color(1.0f, 0.0f, 0.0f, 0.4f), recipeX, recipeY);
|
||||||
}
|
}
|
||||||
this.errored = true;
|
this.errored = true;
|
||||||
|
foundMissing++;
|
||||||
} else {
|
} else {
|
||||||
foundAny = true;
|
foundAny = true;
|
||||||
this.foundSlots.add(currentSlot);
|
this.foundSlots.add(currentSlot);
|
||||||
@@ -226,18 +243,42 @@ public class JEIMissingItem implements IRecipeTransferError {
|
|||||||
if (b != null) {
|
if (b != null) {
|
||||||
List<String> tooltipLines = new ArrayList<>();
|
List<String> tooltipLines = new ArrayList<>();
|
||||||
b.init(c, minecraft.player);
|
b.init(c, minecraft.player);
|
||||||
if (errored && foundAny) {
|
if (foundAny) {
|
||||||
tooltipLines.add(I18n.translateToLocal("gui.tooltips.appliedenergistics2.PartialTransfer"));
|
tooltipLines.add(format("gui.tooltips.appliedenergistics2.PartialTransfer"));
|
||||||
b.enabled = true;
|
b.enabled = true;
|
||||||
b.visible = true;
|
b.visible = true;
|
||||||
|
|
||||||
|
tooltipLines.add(format("gui.tooltips.appliedenergistics2.CondenseItems"));
|
||||||
}
|
}
|
||||||
if (errored) {
|
|
||||||
tooltipLines.add(I18n.translateToLocal("gui.tooltips.appliedenergistics2.MissingItem"));
|
if (foundMissing > 0) {
|
||||||
|
tooltipLines.add(format("gui.tooltips.appliedenergistics2.MissingItem", String.valueOf(foundMissing)));
|
||||||
}
|
}
|
||||||
if (foundAnyCraftable) {
|
if (foundCraftables > 0) {
|
||||||
tooltipLines.add(I18n.translateToLocal("gui.tooltips.appliedenergistics2.CraftableItem"));
|
tooltipLines.add(format("gui.tooltips.appliedenergistics2.CraftableItem", foundCraftables));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tooltipLines.size() > 0) {
|
||||||
|
var longestStringWidth = minecraft.fontRenderer.getStringWidth(tooltipLines.stream()
|
||||||
|
.max(Comparator.comparingInt(String::length)).get());
|
||||||
|
|
||||||
|
var background = ((RecipeLayout) recipeLayout).getRecipeCategory().getBackground();
|
||||||
|
var scaledresolution = new ScaledResolution(minecraft);
|
||||||
|
|
||||||
|
// Mostly reverse-engineered Minecraft code.
|
||||||
|
final int offset;
|
||||||
|
if (mouseX + longestStringWidth + 4 + 12 > scaledresolution.getScaledWidth()) {
|
||||||
|
// The tooltip will appear to the left of the mouse cursor.
|
||||||
|
// Need to offset Y so that the tooltip doesn't block the ingredients.
|
||||||
|
offset = background.getHeight() + recipeY
|
||||||
|
+ (minecraft.fontRenderer.FONT_HEIGHT * tooltipLines.size()
|
||||||
|
+ 2 * (tooltipLines.size() - 1)) / 2
|
||||||
|
+ 4;
|
||||||
|
} else {
|
||||||
|
offset = mouseY;
|
||||||
|
}
|
||||||
|
TooltipRenderer.drawHoveringText(minecraft, tooltipLines, mouseX, offset);
|
||||||
}
|
}
|
||||||
TooltipRenderer.drawHoveringText(minecraft, tooltipLines, mouseX, mouseY);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package appeng.integration.modules.jei;
|
||||||
|
|
||||||
|
import mezz.jei.api.gui.IRecipeLayout;
|
||||||
|
import mezz.jei.api.recipe.transfer.IRecipeTransferError;
|
||||||
|
import mezz.jei.gui.TooltipRenderer;
|
||||||
|
import mezz.jei.gui.recipes.RecipeLayout;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.resources.I18n;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class JEITransferInfo implements IRecipeTransferError {
|
||||||
|
|
||||||
|
public static final JEITransferInfo INSTANCE = new JEITransferInfo();
|
||||||
|
private RecipeLayout recipeLayout;
|
||||||
|
|
||||||
|
|
||||||
|
private JEITransferInfo() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Type getType() {
|
||||||
|
// Workaround. Re-enable the button.
|
||||||
|
if (recipeLayout != null) {
|
||||||
|
var recipeTransferButton = recipeLayout.getRecipeTransferButton();
|
||||||
|
if (recipeTransferButton != null) {
|
||||||
|
recipeTransferButton.enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Type.USER_FACING;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRecipeLayout(RecipeLayout recipeLayout) {
|
||||||
|
this.recipeLayout = recipeLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showError(@NotNull Minecraft minecraft, int mouseX, int mouseY, @NotNull IRecipeLayout recipeLayout, int recipeX, int recipeY) {
|
||||||
|
var tooltipLines = new ArrayList<String>();
|
||||||
|
tooltipLines.add(I18n.format("gui.tooltips.appliedenergistics2.PartialTransfer"));
|
||||||
|
tooltipLines.add(I18n.format("gui.tooltips.appliedenergistics2.CondenseItems"));
|
||||||
|
TooltipRenderer.drawHoveringText(minecraft, tooltipLines, mouseX, mouseY);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,25 +22,29 @@ package appeng.integration.modules.jei;
|
|||||||
import appeng.container.implementations.ContainerCraftingTerm;
|
import appeng.container.implementations.ContainerCraftingTerm;
|
||||||
import appeng.container.implementations.ContainerPatternEncoder;
|
import appeng.container.implementations.ContainerPatternEncoder;
|
||||||
import appeng.container.implementations.ContainerWirelessCraftingTerminal;
|
import appeng.container.implementations.ContainerWirelessCraftingTerminal;
|
||||||
import appeng.container.slot.SlotCraftingMatrix;
|
|
||||||
import appeng.container.slot.SlotFakeCraftingMatrix;
|
|
||||||
import appeng.core.AELog;
|
import appeng.core.AELog;
|
||||||
import appeng.core.sync.network.NetworkHandler;
|
import appeng.core.sync.network.NetworkHandler;
|
||||||
import appeng.core.sync.packets.PacketJEIRecipe;
|
import appeng.core.sync.packets.PacketJEIRecipe;
|
||||||
import appeng.core.sync.packets.PacketValueConfig;
|
import appeng.core.sync.packets.PacketValueConfig;
|
||||||
import appeng.util.Platform;
|
import appeng.util.Platform;
|
||||||
|
import gregtech.api.capability.IMultiblockController;
|
||||||
|
import gregtech.api.util.GTUtility;
|
||||||
|
import gregtech.integration.jei.multiblock.MultiblockInfoCategory;
|
||||||
import mezz.jei.api.gui.IGuiIngredient;
|
import mezz.jei.api.gui.IGuiIngredient;
|
||||||
import mezz.jei.api.gui.IRecipeLayout;
|
import mezz.jei.api.gui.IRecipeLayout;
|
||||||
import mezz.jei.api.recipe.VanillaRecipeCategoryUid;
|
import mezz.jei.api.recipe.VanillaRecipeCategoryUid;
|
||||||
import mezz.jei.api.recipe.transfer.IRecipeTransferError;
|
import mezz.jei.api.recipe.transfer.IRecipeTransferError;
|
||||||
import mezz.jei.api.recipe.transfer.IRecipeTransferHandler;
|
import mezz.jei.api.recipe.transfer.IRecipeTransferHandler;
|
||||||
|
import mezz.jei.gui.recipes.RecipeLayout;
|
||||||
import mezz.jei.transfer.RecipeTransferErrorInternal;
|
import mezz.jei.transfer.RecipeTransferErrorInternal;
|
||||||
|
import net.minecraft.client.resources.I18n;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.init.Items;
|
||||||
import net.minecraft.inventory.Container;
|
import net.minecraft.inventory.Container;
|
||||||
import net.minecraft.inventory.Slot;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.nbt.NBTTagList;
|
import net.minecraft.nbt.NBTTagList;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -50,6 +54,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static appeng.helpers.ItemStackHelper.stackToNBT;
|
import static appeng.helpers.ItemStackHelper.stackToNBT;
|
||||||
|
import static appeng.util.Platform.GTLoaded;
|
||||||
|
|
||||||
|
|
||||||
class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandler<T> {
|
class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandler<T> {
|
||||||
@@ -61,7 +66,7 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<T> getContainerClass() {
|
public @NotNull Class<T> getContainerClass() {
|
||||||
return this.containerClass;
|
return this.containerClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,19 +82,24 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
|||||||
if (!doTransfer) {
|
if (!doTransfer) {
|
||||||
if (recipeType.equals(VanillaRecipeCategoryUid.CRAFTING) && (container instanceof ContainerCraftingTerm || container instanceof ContainerWirelessCraftingTerminal)) {
|
if (recipeType.equals(VanillaRecipeCategoryUid.CRAFTING) && (container instanceof ContainerCraftingTerm || container instanceof ContainerWirelessCraftingTerminal)) {
|
||||||
JEIMissingItem error = new JEIMissingItem(container, recipeLayout);
|
JEIMissingItem error = new JEIMissingItem(container, recipeLayout);
|
||||||
|
|
||||||
if (error.errored())
|
if (error.errored())
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
|
if (container instanceof ContainerPatternEncoder || container instanceof ContainerCraftingTerm) {
|
||||||
|
JEITransferInfo.INSTANCE.setRecipeLayout((RecipeLayout) recipeLayout);
|
||||||
|
return JEITransferInfo.INSTANCE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container instanceof ContainerPatternEncoder) {
|
if (container instanceof ContainerPatternEncoder) {
|
||||||
try {
|
try {
|
||||||
if (!((ContainerPatternEncoder) container).isCraftingMode()) {
|
if (!((ContainerPatternEncoder) container).isCraftingMode() && !maxTransfer) {
|
||||||
if (recipeType.equals(VanillaRecipeCategoryUid.CRAFTING)) {
|
if (recipeType.equals(VanillaRecipeCategoryUid.CRAFTING)) {
|
||||||
NetworkHandler.instance().sendToServer(new PacketValueConfig("PatternTerminal.CraftMode", "1"));
|
NetworkHandler.instance().sendToServer(new PacketValueConfig("PatternTerminal.CraftMode", "1"));
|
||||||
}
|
}
|
||||||
} else if (!recipeType.equals(VanillaRecipeCategoryUid.CRAFTING)) {
|
} else if (!recipeType.equals(VanillaRecipeCategoryUid.CRAFTING) || maxTransfer) {
|
||||||
|
|
||||||
NetworkHandler.instance().sendToServer(new PacketValueConfig("PatternTerminal.CraftMode", "0"));
|
NetworkHandler.instance().sendToServer(new PacketValueConfig("PatternTerminal.CraftMode", "0"));
|
||||||
}
|
}
|
||||||
@@ -104,8 +114,7 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
|||||||
final NBTTagCompound recipe = new NBTTagCompound();
|
final NBTTagCompound recipe = new NBTTagCompound();
|
||||||
final NBTTagList outputs = new NBTTagList();
|
final NBTTagList outputs = new NBTTagList();
|
||||||
|
|
||||||
|
var slotIndex = 0;
|
||||||
int slotIndex = 0;
|
|
||||||
for (Map.Entry<Integer, ? extends IGuiIngredient<ItemStack>> ingredientEntry : ingredients.entrySet()) {
|
for (Map.Entry<Integer, ? extends IGuiIngredient<ItemStack>> ingredientEntry : ingredients.entrySet()) {
|
||||||
IGuiIngredient<ItemStack> ingredient = ingredientEntry.getValue();
|
IGuiIngredient<ItemStack> ingredient = ingredientEntry.getValue();
|
||||||
if (!ingredient.isInput()) {
|
if (!ingredient.isInput()) {
|
||||||
@@ -117,45 +126,63 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Slot slot : container.inventorySlots) {
|
final NBTTagList tags = new NBTTagList();
|
||||||
if (slot instanceof SlotCraftingMatrix || slot instanceof SlotFakeCraftingMatrix) {
|
final List<ItemStack> list = new ArrayList<>();
|
||||||
if (slot.getSlotIndex() == slotIndex) {
|
final ItemStack displayed = ingredient.getDisplayedIngredient();
|
||||||
final NBTTagList tags = new NBTTagList();
|
|
||||||
final List<ItemStack> list = new ArrayList<>();
|
|
||||||
final ItemStack displayed = ingredient.getDisplayedIngredient();
|
|
||||||
|
|
||||||
// prefer currently displayed item
|
// prefer currently displayed item
|
||||||
if (displayed != null && !displayed.isEmpty()) {
|
if (displayed != null && !displayed.isEmpty()) {
|
||||||
list.add(displayed);
|
list.add(displayed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// prefer pure crystals.
|
// prefer pure crystals.
|
||||||
for (ItemStack stack : ingredient.getAllIngredients()) {
|
for (ItemStack stack : ingredient.getAllIngredients()) {
|
||||||
if (stack == null) {
|
if (stack == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (Platform.isRecipePrioritized(stack)) {
|
if (Platform.isRecipePrioritized(stack)) {
|
||||||
list.add(0, stack);
|
list.add(0, stack);
|
||||||
} else {
|
} else {
|
||||||
list.add(stack);
|
list.add(stack);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final ItemStack is : list) {
|
|
||||||
final NBTTagCompound tag = stackToNBT(is);
|
|
||||||
tags.appendTag(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
recipe.setTag("#" + slot.getSlotIndex(), tags);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (final ItemStack is : list) {
|
||||||
|
final NBTTagCompound tag = stackToNBT(is);
|
||||||
|
tags.appendTag(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
recipe.setTag("#" + slotIndex, tags);
|
||||||
slotIndex++;
|
slotIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (outputs.isEmpty() && GTLoaded && recipeLayout.getRecipeCategory() instanceof MultiblockInfoCategory) {
|
||||||
|
// JEI doesn't allow getting the recipe wrapper :(
|
||||||
|
String controllerName = null;
|
||||||
|
for (var ingredient : ingredients.entrySet()) {
|
||||||
|
if (!ingredient.getValue().isInput()) continue;
|
||||||
|
|
||||||
|
var ingredientStack = ingredient.getValue().getDisplayedIngredient();
|
||||||
|
if (ingredientStack == null) continue;
|
||||||
|
|
||||||
|
var meta = GTUtility.getMetaTileEntity(ingredientStack);
|
||||||
|
if (meta == null) continue;
|
||||||
|
|
||||||
|
if (!(meta instanceof IMultiblockController)) continue;
|
||||||
|
|
||||||
|
controllerName = I18n.format(meta.getMetaFullName());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (controllerName != null) {
|
||||||
|
var paper = Items.PAPER.getDefaultInstance().copy();
|
||||||
|
paper.setStackDisplayName(controllerName);
|
||||||
|
outputs.appendTag(stackToNBT(paper));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
recipe.setTag("outputs", outputs);
|
recipe.setTag("outputs", outputs);
|
||||||
|
recipe.setBoolean("condense", maxTransfer);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
NetworkHandler.instance().sendToServer(new PacketJEIRecipe(recipe));
|
NetworkHandler.instance().sendToServer(new PacketJEIRecipe(recipe));
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ import java.util.Map;
|
|||||||
* {@link #findFuzzy(IAEItemStack, FuzzyMode)}.
|
* {@link #findFuzzy(IAEItemStack, FuzzyMode)}.
|
||||||
*/
|
*/
|
||||||
class FuzzyItemVariantList extends ItemVariantList {
|
class FuzzyItemVariantList extends ItemVariantList {
|
||||||
|
|
||||||
static final SharedStackComparator COMPARATOR = new SharedStackComparator();
|
static final SharedStackComparator COMPARATOR = new SharedStackComparator();
|
||||||
|
|
||||||
// NOTE: We only use Object as they key here so we can pass our special DamageBounds to the subMap method.
|
// NOTE: We only use Object as they key here so we can pass our special DamageBounds to the subMap method.
|
||||||
@@ -47,6 +46,10 @@ class FuzzyItemVariantList extends ItemVariantList {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<IAEItemStack> findFuzzy(final IAEItemStack filter, final FuzzyMode fuzzy) {
|
public Collection<IAEItemStack> findFuzzy(final IAEItemStack filter, final FuzzyMode fuzzy) {
|
||||||
|
if (fuzzy == FuzzyMode.IGNORE_ALL) {
|
||||||
|
return this.records.values();
|
||||||
|
}
|
||||||
|
|
||||||
ItemStack itemStack = filter.getDefinition();
|
ItemStack itemStack = filter.getDefinition();
|
||||||
|
|
||||||
ItemDamageBound lowerBound = makeLowerBound(itemStack, fuzzy);
|
ItemDamageBound lowerBound = makeLowerBound(itemStack, fuzzy);
|
||||||
@@ -161,14 +164,8 @@ class FuzzyItemVariantList extends ItemVariantList {
|
|||||||
damage = stack.getItemDamage();
|
damage = stack.getItemDamage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fuzzy == FuzzyMode.IGNORE_ALL) {
|
final int breakpoint = fuzzy.calculateBreakPoint(maxDamage);
|
||||||
if (maxDamage != 0) {
|
damage = damage <= breakpoint ? breakpoint : maxDamage;
|
||||||
damage = maxDamage;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
final int breakpoint = fuzzy.calculateBreakPoint(maxDamage);
|
|
||||||
damage = damage <= breakpoint ? breakpoint : maxDamage;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ItemDamageBound(damage);
|
return new ItemDamageBound(damage);
|
||||||
}
|
}
|
||||||
@@ -181,26 +178,19 @@ class FuzzyItemVariantList extends ItemVariantList {
|
|||||||
Preconditions.checkState(stack.getItem().isDamageable() || (Platform.isGTDamageableItem(stack.getItem())), "Item#isDamageable() has to be true");
|
Preconditions.checkState(stack.getItem().isDamageable() || (Platform.isGTDamageableItem(stack.getItem())), "Item#isDamageable() has to be true");
|
||||||
|
|
||||||
int damage;
|
int damage;
|
||||||
if (fuzzy == FuzzyMode.IGNORE_ALL) {
|
int maxDamage;
|
||||||
damage = MIN_DAMAGE_VALUE;
|
if (Platform.isIC2DamageableItem(stack.getItem())) {
|
||||||
|
maxDamage = ((ICustomDamageItem) stack.getItem()).getMaxCustomDamage(stack);
|
||||||
|
damage = ((ICustomDamageItem) stack.getItem()).getCustomDamage(stack);
|
||||||
|
} else if (Platform.isGTDamageableItem(stack.getItem())) {
|
||||||
|
maxDamage = ToolClass.getGTMaxDamage(stack);
|
||||||
|
damage = ToolClass.getGTitemDamage(stack);
|
||||||
} else {
|
} else {
|
||||||
int maxDamage;
|
maxDamage = stack.getMaxDamage();
|
||||||
if (Platform.isIC2DamageableItem(stack.getItem())) {
|
damage = stack.getItemDamage();
|
||||||
maxDamage = ((ICustomDamageItem) stack.getItem()).getMaxCustomDamage(stack);
|
|
||||||
damage = ((ICustomDamageItem) stack.getItem()).getCustomDamage(stack);
|
|
||||||
} else if (Platform.isGTDamageableItem(stack.getItem())) {
|
|
||||||
maxDamage = ToolClass.getGTMaxDamage(stack);
|
|
||||||
damage = ToolClass.getGTitemDamage(stack);
|
|
||||||
} else {
|
|
||||||
maxDamage = stack.getMaxDamage();
|
|
||||||
damage = stack.getItemDamage();
|
|
||||||
}
|
|
||||||
|
|
||||||
final int breakpoint = fuzzy.calculateBreakPoint(maxDamage);
|
|
||||||
damage = damage <= breakpoint ? MIN_DAMAGE_VALUE : breakpoint;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ItemDamageBound(damage);
|
final int breakpoint = fuzzy.calculateBreakPoint(maxDamage);
|
||||||
|
return new ItemDamageBound(damage <= breakpoint ? MIN_DAMAGE_VALUE : breakpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -397,8 +397,9 @@ gui.tooltips.appliedenergistics2.SearchFieldInputs=Recipe Inputs
|
|||||||
gui.tooltips.appliedenergistics2.SearchFieldOutputs=Recipe Outputs
|
gui.tooltips.appliedenergistics2.SearchFieldOutputs=Recipe Outputs
|
||||||
gui.tooltips.appliedenergistics2.SearchFieldNames=Interface Names
|
gui.tooltips.appliedenergistics2.SearchFieldNames=Interface Names
|
||||||
gui.tooltips.appliedenergistics2.PartialTransfer=Move stored items into the crafting grid
|
gui.tooltips.appliedenergistics2.PartialTransfer=Move stored items into the crafting grid
|
||||||
gui.tooltips.appliedenergistics2.MissingItem=§cMissing item
|
gui.tooltips.appliedenergistics2.MissingItem=§cMissing %s items
|
||||||
gui.tooltips.appliedenergistics2.CraftableItem=§9Craftable item
|
gui.tooltips.appliedenergistics2.CraftableItem=§9Found %s craftable items
|
||||||
|
gui.tooltips.appliedenergistics2.CondenseItems=§5- hold Shift to condense items
|
||||||
|
|
||||||
// Units
|
// Units
|
||||||
gui.appliedenergistics2.units.appliedenergstics=AE
|
gui.appliedenergistics2.units.appliedenergstics=AE
|
||||||
|
|||||||
Reference in New Issue
Block a user