Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d4e5734e8 | |||
| 00ac7c3334 | |||
| bcc28c0b28 | |||
| a03d6f4803 | |||
| e3b8228608 |
@@ -54,12 +54,19 @@ import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import static appeng.client.render.BlockPosHighlighter.hilightBlock;
|
||||
import static appeng.helpers.ItemStackHelper.stackFromNBT;
|
||||
@@ -109,7 +116,7 @@ public class GuiInterfaceTerminal extends AEBaseGui {
|
||||
this.setScrollBar(scrollbar);
|
||||
this.xSize = 208;
|
||||
this.ySize = 255;
|
||||
this.jeiEnabled = Platform.isModLoaded("jei");
|
||||
this.jeiEnabled = Loader.isModLoaded("jei");
|
||||
this.jeiButtonPadding = jeiEnabled ? 22 : 0;
|
||||
|
||||
searchFieldInputs = createTextField(86, 12, ButtonToolTips.SearchFieldInputs.getLocal());
|
||||
|
||||
@@ -31,7 +31,11 @@ import appeng.api.util.IConfigManager;
|
||||
import appeng.api.util.IConfigurableObject;
|
||||
import appeng.client.ActionKey;
|
||||
import appeng.client.gui.AEBaseMEGui;
|
||||
import appeng.client.gui.widgets.*;
|
||||
import appeng.client.gui.widgets.GuiImgButton;
|
||||
import appeng.client.gui.widgets.GuiScrollbar;
|
||||
import appeng.client.gui.widgets.GuiTabButton;
|
||||
import appeng.client.gui.widgets.ISortSource;
|
||||
import appeng.client.gui.widgets.MEGuiTextField;
|
||||
import appeng.client.me.InternalSlotME;
|
||||
import appeng.client.me.ItemRepo;
|
||||
import appeng.client.me.SlotME;
|
||||
@@ -57,6 +61,7 @@ import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
@@ -98,7 +103,7 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
|
||||
private int currentMouseY = 0;
|
||||
private boolean delayedUpdate;
|
||||
|
||||
protected int jeiOffset = Platform.isModLoaded("jei") ? 24 : 0;
|
||||
protected int jeiOffset = Loader.isModLoaded("jei") ? 24 : 0;
|
||||
|
||||
public GuiMEMonitorable(final InventoryPlayer inventoryPlayer, final ITerminalHost te) {
|
||||
this(inventoryPlayer, te, new ContainerMEMonitorable(inventoryPlayer, te));
|
||||
@@ -172,9 +177,10 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
|
||||
NetworkHandler.instance().sendToServer(new PacketSwitchGuis(GuiBridge.GUI_CRAFTING_STATUS));
|
||||
}
|
||||
|
||||
if (btn instanceof GuiImgButton iBtn) {
|
||||
if (btn instanceof GuiImgButton) {
|
||||
final boolean backwards = Mouse.isButtonDown(1);
|
||||
|
||||
final GuiImgButton iBtn = (GuiImgButton) btn;
|
||||
if (iBtn.getSetting() != Settings.ACTIONS) {
|
||||
final Enum cv = iBtn.getCurrentValue();
|
||||
final Enum next = Platform.rotateEnum(cv, backwards, iBtn.getSetting().getPossibleValues());
|
||||
|
||||
@@ -46,6 +46,7 @@ import appeng.api.util.IConfigurableObject;
|
||||
import appeng.client.gui.implementations.GuiMEMonitorable;
|
||||
import appeng.container.AEBaseContainer;
|
||||
import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.slot.AppEngSlot;
|
||||
import appeng.container.slot.SlotPlayerHotBar;
|
||||
import appeng.container.slot.SlotPlayerInv;
|
||||
import appeng.container.slot.SlotRestrictedInput;
|
||||
@@ -65,6 +66,7 @@ import net.minecraft.inventory.IContainerListener;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@@ -87,7 +89,7 @@ public class ContainerMEMonitorable extends AEBaseContainer implements IConfigMa
|
||||
private IConfigManagerHost gui;
|
||||
private IConfigManager serverCM;
|
||||
private IGridNode networkNode;
|
||||
protected int jeiOffset = Platform.isModLoaded("jei") ? 24 : 0;
|
||||
protected int jeiOffset = Loader.isModLoaded("jei") ? 24 : 0;
|
||||
|
||||
|
||||
public ContainerMEMonitorable(final InventoryPlayer ip, final ITerminalHost monitorable) {
|
||||
|
||||
@@ -30,13 +30,13 @@ import appeng.container.slot.SlotOutput;
|
||||
import appeng.container.slot.SlotRestrictedInput;
|
||||
import appeng.tile.inventory.AppEngInternalInventory;
|
||||
import appeng.tile.misc.TileSecurityStation;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.inv.IAEAppEngInventory;
|
||||
import appeng.util.inv.InvOperation;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.inventory.IContainerListener;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ContainerSecurityStation extends ContainerMEMonitorable implements
|
||||
@GuiSync(0)
|
||||
public int permissionMode = 0;
|
||||
|
||||
protected int jeiOffset = Platform.isModLoaded("jei") ? 24 : 0;
|
||||
protected int jeiOffset = Loader.isModLoaded("jei") ? 24 : 0;
|
||||
|
||||
public ContainerSecurityStation(final InventoryPlayer ip, final ITerminalHost monitorable) {
|
||||
super(ip, monitorable, false);
|
||||
@@ -75,7 +75,8 @@ public class ContainerSecurityStation extends ContainerMEMonitorable implements
|
||||
final SecurityPermissions permission = SecurityPermissions.valueOf(value);
|
||||
|
||||
final ItemStack a = this.configSlot.getStack();
|
||||
if (!a.isEmpty() && a.getItem() instanceof IBiometricCard bc) {
|
||||
if (!a.isEmpty() && a.getItem() instanceof IBiometricCard) {
|
||||
final IBiometricCard bc = (IBiometricCard) a.getItem();
|
||||
if (bc.hasPermission(a, permission)) {
|
||||
bc.removePermission(a, permission);
|
||||
} else {
|
||||
@@ -94,7 +95,8 @@ public class ContainerSecurityStation extends ContainerMEMonitorable implements
|
||||
this.setPermissionMode(0);
|
||||
|
||||
final ItemStack a = this.configSlot.getStack();
|
||||
if (!a.isEmpty() && a.getItem() instanceof IBiometricCard bc) {
|
||||
if (!a.isEmpty() && a.getItem() instanceof IBiometricCard) {
|
||||
final IBiometricCard bc = (IBiometricCard) a.getItem();
|
||||
|
||||
for (final SecurityPermissions sp : bc.getPermissions(a)) {
|
||||
this.setPermissionMode(this.getPermissionMode() | (1 << sp.ordinal()));
|
||||
|
||||
@@ -41,6 +41,9 @@ import appeng.util.inv.WrapperCursorItemHandler;
|
||||
import appeng.util.inv.WrapperInvItemHandler;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import com.blamejared.recipestages.recipes.RecipeStage;
|
||||
import net.darkhax.gamestages.GameStageHelper;
|
||||
import net.darkhax.itemstages.ItemStages;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.Item;
|
||||
@@ -50,6 +53,9 @@ import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -151,7 +157,8 @@ public class SlotCraftingTerm extends AppEngCraftingSlot {
|
||||
|
||||
// TODO: This is really hacky and NEEDS to be solved with a full container/gui refactoring.
|
||||
protected IRecipe findRecipe(InventoryCrafting ic, World world, EntityPlayer player) {
|
||||
if (this.container instanceof ContainerCraftingTerm containerTerminal) {
|
||||
if (this.container instanceof ContainerCraftingTerm) {
|
||||
final ContainerCraftingTerm containerTerminal = (ContainerCraftingTerm) this.container;
|
||||
final IRecipe recipe = containerTerminal.getCurrentRecipe();
|
||||
|
||||
if (recipe != null && recipe.matches(ic, world)) {
|
||||
@@ -164,8 +171,9 @@ public class SlotCraftingTerm extends AppEngCraftingSlot {
|
||||
|
||||
// Returns null in case this recipe is not yet unlocked
|
||||
private IRecipe handleRecipe(InventoryCrafting ic, IRecipe recipe, EntityPlayer player) {
|
||||
if (Platform.isModLoaded("recipestages")) {
|
||||
if (recipe instanceof RecipeStage staged) {
|
||||
if (Loader.isModLoaded("recipestages")) {
|
||||
if (recipe instanceof RecipeStage) {
|
||||
final RecipeStage staged = (RecipeStage) recipe;
|
||||
if (!staged.isGoodForCrafting(ic))
|
||||
return null;
|
||||
}
|
||||
@@ -177,7 +185,8 @@ public class SlotCraftingTerm extends AppEngCraftingSlot {
|
||||
// TODO: This is really hacky and NEEDS to be solved with a full container/gui refactoring.
|
||||
@Override
|
||||
protected NonNullList<ItemStack> getRemainingItems(InventoryCrafting ic, World world) {
|
||||
if (this.container instanceof ContainerCraftingTerm containerTerminal) {
|
||||
if (this.container instanceof ContainerCraftingTerm) {
|
||||
final ContainerCraftingTerm containerTerminal = (ContainerCraftingTerm) this.container;
|
||||
final IRecipe recipe = containerTerminal.getCurrentRecipe();
|
||||
|
||||
if (recipe != null && recipe.matches(ic, world)) {
|
||||
|
||||
@@ -32,9 +32,7 @@ import appeng.api.networking.storage.IStorageGrid;
|
||||
import appeng.api.storage.IMEMonitor;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.container.implementations.ContainerExpandedProcessingPatternTerm;
|
||||
import appeng.container.implementations.ContainerPatternEncoder;
|
||||
import appeng.container.implementations.ContainerPatternTerm;
|
||||
import appeng.core.sync.AppEngPacket;
|
||||
import appeng.core.sync.network.INetworkInfo;
|
||||
import appeng.helpers.IContainerCraftingPacket;
|
||||
@@ -47,6 +45,7 @@ import appeng.util.item.AEItemStack;
|
||||
import appeng.util.prioritylist.IPartitionList;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.inventory.Container;
|
||||
@@ -69,9 +68,10 @@ import static appeng.helpers.ItemStackHelper.stackFromNBT;
|
||||
|
||||
public class PacketJEIRecipe extends AppEngPacket {
|
||||
|
||||
static ItemStack[] emptyArray = {ItemStack.EMPTY};
|
||||
private List<ItemStack[]> recipe;
|
||||
private List<ItemStack> output;
|
||||
static ItemStack[] emptyArray = {ItemStack.EMPTY};
|
||||
private boolean shouldCondense;
|
||||
|
||||
|
||||
// automatic.
|
||||
@@ -80,6 +80,7 @@ public class PacketJEIRecipe extends AppEngPacket {
|
||||
bytes.skip(stream.readerIndex());
|
||||
final NBTTagCompound comp = CompressedStreamTools.readCompressed(bytes);
|
||||
if (comp != null) {
|
||||
this.shouldCondense = comp.getBoolean("condense");
|
||||
this.recipe = new ArrayList<>();
|
||||
|
||||
for (int x = 0; x < comp.getKeySet().size(); x++) {
|
||||
@@ -104,7 +105,6 @@ public class PacketJEIRecipe extends AppEngPacket {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// api
|
||||
@@ -124,167 +124,212 @@ public class PacketJEIRecipe extends AppEngPacket {
|
||||
|
||||
@Override
|
||||
public void serverPacketData(final INetworkInfo manager, final AppEngPacket packet, final EntityPlayer player) {
|
||||
// oops :)
|
||||
if (this.recipe == null) return;
|
||||
|
||||
final EntityPlayerMP pmp = (EntityPlayerMP) player;
|
||||
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();
|
||||
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
if (node == null) return;
|
||||
|
||||
final IGrid grid = node.getGrid();
|
||||
if (grid == null) {
|
||||
return;
|
||||
}
|
||||
if (grid == null) return;
|
||||
|
||||
final IStorageGrid inv = grid.getCache(IStorageGrid.class);
|
||||
if (inv == null) return;
|
||||
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 IItemHandler craftMatrix = cct.getInventoryByName("crafting");
|
||||
final IItemHandler playerInventory = cct.getInventoryByName("player");
|
||||
|
||||
if (inv != null && this.recipe != null && security != null) {
|
||||
final IMEMonitor<IAEItemStack> storage = inv.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class));
|
||||
final IPartitionList<IAEItemStack> filter = ItemViewCell.createFilter(cct.getViewCells());
|
||||
final Object2LongLinkedOpenHashMap<IAEItemStack> condensedBuffer;
|
||||
if (this.shouldCondense) {
|
||||
condensedBuffer = new Object2LongLinkedOpenHashMap<>();
|
||||
} else {
|
||||
condensedBuffer = null;
|
||||
}
|
||||
|
||||
for (int x = 0; x < craftMatrix.getSlots(); x++) {
|
||||
ItemStack currentItem = craftMatrix.getStackInSlot(x);
|
||||
final IMEMonitor<IAEItemStack> storage = inv.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class));
|
||||
final IPartitionList<IAEItemStack> filter = ItemViewCell.createFilter(cct.getViewCells());
|
||||
|
||||
if (x >= this.recipe.size()) {
|
||||
currentItem = ItemStack.EMPTY;
|
||||
// First iteration, find what can be used and send everything else into the network.
|
||||
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
|
||||
if (!currentItem.isEmpty()) {
|
||||
// already the correct item?
|
||||
ItemStack newItem = this.canUseInSlot(x, currentItem);
|
||||
// Second iteration, query AE2 & player inventory for items.
|
||||
for (int recipeSlotIndex = 0; recipeSlotIndex < recipe.size(); recipeSlotIndex++) {
|
||||
ItemStack currentItem;
|
||||
|
||||
if (!cct.useRealItems() && this.recipe.get(x) != null) {
|
||||
if (this.recipe.get(x).length > 0) {
|
||||
currentItem.setCount(recipe.get(x)[0].getCount());
|
||||
}
|
||||
}
|
||||
if (recipeSlotIndex < craftMatrix.getSlots()) {
|
||||
currentItem = craftMatrix.getStackInSlot(recipeSlotIndex);
|
||||
} 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 (newItem != currentItem && security.hasPermission(player, SecurityPermissions.INJECT)) {
|
||||
final IAEItemStack in = AEItemStack.fromItemStack(currentItem);
|
||||
final IAEItemStack out = cct.useRealItems() ? Platform.poweredInsert(energy, storage, in, cct.getActionSource()) : null;
|
||||
if (out != null) {
|
||||
currentItem = out.createItemStack();
|
||||
} else {
|
||||
currentItem = ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentItem.isEmpty() && recipe.get(recipeSlotIndex) != null) {
|
||||
// for each variant
|
||||
for (int y = 0; y < this.recipe.get(recipeSlotIndex).length && currentItem.isEmpty(); y++) {
|
||||
var recipeStackVariant = this.recipe.get(recipeSlotIndex)[y];
|
||||
final IAEItemStack request = AEItemStack.fromItemStack(recipeStackVariant);
|
||||
if (request != null) {
|
||||
// try ae
|
||||
if ((filter == null || filter.isListed(request)) && hasExtractPermissions) {
|
||||
request.setStackSize(1);
|
||||
IAEItemStack out;
|
||||
|
||||
if (currentItem.isEmpty() && recipe.size() > x && recipe.get(x) != null) {
|
||||
// for each variant
|
||||
for (int y = 0; y < this.recipe.get(x).length && currentItem.isEmpty(); y++) {
|
||||
final IAEItemStack request = AEItemStack.fromItemStack(this.recipe.get(x)[y]);
|
||||
if (request != null) {
|
||||
// try ae
|
||||
if ((filter == null || filter.isListed(request)) && security.hasPermission(player, SecurityPermissions.EXTRACT)) {
|
||||
request.setStackSize(1);
|
||||
IAEItemStack out;
|
||||
|
||||
if (cct.useRealItems()) {
|
||||
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) {
|
||||
if (cct.useRealItems()) {
|
||||
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;
|
||||
}
|
||||
if (Platform.isGTDamageableItem(request.getItem())) {
|
||||
if (!(is.getDefinition().getMetadata() == request.getDefinition().getMetadata())) {
|
||||
continue;
|
||||
}
|
||||
if (Platform.isGTDamageableItem(request.getItem())) {
|
||||
if (!(is.getDefinition().getMetadata() == request.getDefinition().getMetadata())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
out = Platform.poweredExtraction(energy, storage, is.copy().setStackSize(1), cct.getActionSource());
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
if (out != null) {
|
||||
if (!cct.useRealItems()) {
|
||||
out.setStackSize(recipe.get(x)[y].getCount());
|
||||
}
|
||||
currentItem = out.createItemStack();
|
||||
} 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());
|
||||
}
|
||||
}
|
||||
|
||||
// try inventory
|
||||
if (currentItem.isEmpty()) {
|
||||
AdaptorItemHandler ad = new AdaptorItemHandler(playerInventory);
|
||||
|
||||
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);
|
||||
if (out != null) {
|
||||
if (!cct.useRealItems()) {
|
||||
out.setStackSize(recipeStackVariant.getCount());
|
||||
}
|
||||
currentItem = out.createItemStack();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cct.useRealItems()) {
|
||||
if (currentItem.isEmpty() && recipe.size() > x && this.recipe.get(x) != null) {
|
||||
currentItem = this.recipe.get(x)[0].copy();
|
||||
|
||||
// try inventory
|
||||
if (currentItem.isEmpty()) {
|
||||
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 (this.output != null && ((con instanceof ContainerPatternEncoder && !((ContainerPatternEncoder) con).isCraftingMode()))) {
|
||||
IItemHandler outputSlots = cct.getInventoryByName("output");
|
||||
for (int i = 0; i < outputSlots.getSlots(); ++i) {
|
||||
ItemHandlerUtil.setStackInSlot(outputSlots, i, ItemStack.EMPTY);
|
||||
if (condensedBuffer != null) {
|
||||
var aeItemStack = AEItemStack.fromItemStack(currentItem);
|
||||
if (aeItemStack != null) {
|
||||
condensedBuffer.compute(aeItemStack, (k, v) -> (v == null ? 0 : v) + k.getStackSize());
|
||||
}
|
||||
for (int i = 0; i < this.output.size() && i < outputSlots.getSlots(); ++i) {
|
||||
if (this.output.get(i) == null || this.output.get(i) == ItemStack.EMPTY) {
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
ItemHandlerUtil.setStackInSlot(outputSlots, i, this.output.get(i));
|
||||
}
|
||||
|
||||
ItemHandlerUtil.setStackInSlot(outputSlots, i, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param slot
|
||||
* @param slot slot index
|
||||
* @param is itemstack
|
||||
* @return is if it can be used, else EMPTY
|
||||
*/
|
||||
private ItemStack canUseInSlot(int slot, ItemStack is) {
|
||||
if (this.recipe.get(slot) != null) {
|
||||
for (ItemStack option : this.recipe.get(slot)) {
|
||||
private boolean canUseInSlot(int slot, ItemStack is) {
|
||||
if (slot >= this.recipe.size()) return false;
|
||||
|
||||
var variants = this.recipe.get(slot);
|
||||
if (variants != null) {
|
||||
for (ItemStack option : variants) {
|
||||
if (ItemStack.areItemStacksEqual(is, option)) {
|
||||
return is;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.Optional;
|
||||
|
||||
public class PacketTerminalUse extends AppEngPacket {
|
||||
@@ -44,7 +45,7 @@ public class PacketTerminalUse extends AppEngPacket {
|
||||
|
||||
}
|
||||
}
|
||||
if (Platform.isModLoaded("baubles")) {
|
||||
if (Loader.isModLoaded("baubles")) {
|
||||
tryOpenBauble(player);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.energy.IEnergySource;
|
||||
import appeng.api.networking.security.IActionHost;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.networking.storage.IStorageGrid;
|
||||
import appeng.api.networking.ticking.IGridTickable;
|
||||
import appeng.api.networking.ticking.TickRateModulation;
|
||||
import appeng.api.networking.ticking.TickingRequest;
|
||||
@@ -50,7 +49,6 @@ import appeng.capabilities.Capabilities;
|
||||
import appeng.core.settings.TickRates;
|
||||
import appeng.fluids.util.AEFluidInventory;
|
||||
import appeng.fluids.util.AEFluidStack;
|
||||
import appeng.fluids.util.AENetworkFluidInventory;
|
||||
import appeng.fluids.util.IAEFluidInventory;
|
||||
import appeng.fluids.util.IAEFluidTank;
|
||||
import appeng.helpers.ICustomNameObject;
|
||||
@@ -92,7 +90,6 @@ import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
@@ -112,7 +109,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
private final UpgradeInventory upgrades;
|
||||
private boolean hasConfig = false;
|
||||
private final IStorageMonitorableAccessor accessor = this::getMonitorable;
|
||||
private final AEFluidInventory tanks;
|
||||
private final AEFluidInventory tanks = new AEFluidInventory(this, NUMBER_OF_TANKS, TANK_CAPACITY);
|
||||
private final AEFluidInventory config = new AEFluidInventory(this, NUMBER_OF_TANKS);
|
||||
private final IAEFluidStack[] requireWork;
|
||||
private int isWorking = -1;
|
||||
@@ -134,7 +131,6 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
|
||||
this.mySource = new MachineSource(this.iHost);
|
||||
this.interfaceRequestSource = new InterfaceRequestSource(this.iHost);
|
||||
this.tanks = new AENetworkFluidInventory(this::getStorageGrid, this.mySource, this, NUMBER_OF_TANKS, TANK_CAPACITY);
|
||||
|
||||
this.fluids.setChangeSource(this.mySource);
|
||||
this.items.setChangeSource(this.mySource);
|
||||
@@ -145,15 +141,6 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private IStorageGrid getStorageGrid() {
|
||||
try {
|
||||
return this.gridProxy.getStorage();
|
||||
} catch (GridAccessException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public IUpgradeableHost getHost() {
|
||||
return this.iHost;
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
package appeng.fluids.util;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.networking.storage.IStorageGrid;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
import appeng.api.storage.channels.IFluidStorageChannel;
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class AENetworkFluidInventory extends AEFluidInventory {
|
||||
|
||||
private final Supplier<IStorageGrid> supplier;
|
||||
private final IActionSource source;
|
||||
|
||||
public AENetworkFluidInventory(Supplier<IStorageGrid> networkSupplier, IActionSource source, IAEFluidInventory handler, int slots, int capcity) {
|
||||
super(handler, slots, capcity);
|
||||
this.supplier = networkSupplier;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fill(final FluidStack fluid, final boolean doFill) {
|
||||
if (fluid == null || fluid.amount <= 0) {
|
||||
return 0;
|
||||
}
|
||||
IStorageGrid storage = supplier.get();
|
||||
if (storage != null) {
|
||||
int originAmt = fluid.amount;
|
||||
IMEInventory<IAEFluidStack> dest = storage.getInventory(AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class));
|
||||
IAEFluidStack overflow = dest.injectItems(AEFluidStack.fromFluidStack(fluid), doFill ? Actionable.MODULATE : Actionable.SIMULATE, this.source);
|
||||
if (overflow != null && overflow.getStackSize() == originAmt) {
|
||||
return super.fill(fluid, doFill);
|
||||
} else if (overflow != null) {
|
||||
return (int) (originAmt - overflow.getStackSize());
|
||||
} else {
|
||||
return originAmt;
|
||||
}
|
||||
} else {
|
||||
return super.fill(fluid, doFill);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -35,7 +35,6 @@ import appeng.api.networking.energy.IEnergySource;
|
||||
import appeng.api.networking.events.MENetworkCraftingPatternChange;
|
||||
import appeng.api.networking.security.IActionHost;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.networking.storage.IStorageGrid;
|
||||
import appeng.api.networking.ticking.IGridTickable;
|
||||
import appeng.api.networking.ticking.TickRateModulation;
|
||||
import appeng.api.networking.ticking.TickingRequest;
|
||||
@@ -65,12 +64,8 @@ import appeng.parts.misc.PartInterface;
|
||||
import appeng.tile.inventory.AppEngInternalAEInventory;
|
||||
import appeng.tile.inventory.AppEngInternalInventory;
|
||||
import appeng.tile.inventory.AppEngInternalOversizedInventory;
|
||||
import appeng.tile.inventory.AppEngNetworkInventory;
|
||||
import appeng.tile.networking.TileCableBus;
|
||||
import appeng.util.ConfigManager;
|
||||
import appeng.util.IConfigManagerHost;
|
||||
import appeng.util.InventoryAdaptor;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.*;
|
||||
import appeng.util.inv.*;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@@ -93,6 +88,7 @@ import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.wrapper.RangedWrapper;
|
||||
@@ -102,8 +98,7 @@ import java.util.*;
|
||||
|
||||
import static appeng.api.config.LockCraftingMode.LOCK_UNTIL_PULSE;
|
||||
import static appeng.api.config.LockCraftingMode.LOCK_UNTIL_RESULT;
|
||||
import static appeng.helpers.ItemStackHelper.stackFromNBT;
|
||||
import static appeng.helpers.ItemStackHelper.stackToNBT;
|
||||
import static appeng.helpers.ItemStackHelper.*;
|
||||
|
||||
|
||||
public class DualityInterface implements IGridTickable, IStorageMonitorable, IInventoryDestination, IAEAppEngInventory, IConfigManagerHost, ICraftingProvider, IUpgradeableHost {
|
||||
@@ -120,7 +115,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
private final IActionSource interfaceRequestSource;
|
||||
private final ConfigManager cm = new ConfigManager(this);
|
||||
private final AppEngInternalAEInventory config = new AppEngInternalAEInventory(this, NUMBER_OF_CONFIG_SLOTS, 512);
|
||||
private final AppEngInternalInventory storage;
|
||||
private final AppEngInternalInventory storage = new AppEngInternalOversizedInventory(this, NUMBER_OF_STORAGE_SLOTS, 512);
|
||||
private final AppEngInternalInventory patterns = new AppEngInternalInventory(this, NUMBER_OF_PATTERN_SLOTS, 1);
|
||||
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>(new NullInventory<IAEItemStack>(), AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class));
|
||||
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>(new NullInventory<IAEFluidStack>(), AEApi.instance().storage().getStorageChannel(IFluidStorageChannel.class));
|
||||
@@ -158,22 +153,12 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
|
||||
final MachineSource actionSource = new MachineSource(this.iHost);
|
||||
this.mySource = actionSource;
|
||||
this.storage = new AppEngNetworkInventory(this::getStorageGrid, this.mySource, this, NUMBER_OF_STORAGE_SLOTS, 512);
|
||||
this.fluids.setChangeSource(actionSource);
|
||||
this.items.setChangeSource(actionSource);
|
||||
|
||||
this.interfaceRequestSource = new InterfaceRequestSource(this.iHost);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private IStorageGrid getStorageGrid() {
|
||||
try {
|
||||
return this.gridProxy.getStorage();
|
||||
} catch (GridAccessException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean invIsCustomBlocking(BlockingInventoryAdaptor inv) {
|
||||
return (inv.containsBlockingItems());
|
||||
}
|
||||
@@ -540,7 +525,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
return;
|
||||
}
|
||||
|
||||
if (is.getItem() instanceof ICraftingPatternItem cpi) {
|
||||
if (is.getItem() instanceof ICraftingPatternItem) {
|
||||
final ICraftingPatternItem cpi = (ICraftingPatternItem) is.getItem();
|
||||
final ICraftingPatternDetails details = cpi.getPatternForItem(is, this.iHost.getTileEntity().getWorld());
|
||||
|
||||
if (details != null) {
|
||||
@@ -1082,7 +1068,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
continue;
|
||||
}
|
||||
|
||||
if (te instanceof ICraftingMachine cm) {
|
||||
if (te instanceof ICraftingMachine) {
|
||||
final ICraftingMachine cm = (ICraftingMachine) te;
|
||||
if (cm.acceptsPlans()) {
|
||||
visitedFaces.remove(s);
|
||||
if (cm.pushPattern(patternDetails, table, s.getOpposite())) {
|
||||
@@ -1097,7 +1084,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
if (ad != null) {
|
||||
if (this.isBlocking()) {
|
||||
IPhantomTile phantomTE;
|
||||
if (Platform.isModLoaded("actuallyadditions") && te instanceof IPhantomTile) {
|
||||
if (Loader.isModLoaded("actuallyadditions") && te instanceof IPhantomTile) {
|
||||
phantomTE = ((IPhantomTile) te);
|
||||
if (phantomTE.hasBoundPosition()) {
|
||||
TileEntity phantom = w.getTileEntity(phantomTE.getBoundPosition());
|
||||
@@ -1237,7 +1224,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
|
||||
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor(te, s.getOpposite());
|
||||
if (ad != null) {
|
||||
if (Platform.isModLoaded("actuallyadditions") && Platform.GTLoaded && te instanceof IPhantomTile phantomTE) {
|
||||
if (Loader.isModLoaded("actuallyadditions") && Platform.GTLoaded && te instanceof IPhantomTile) {
|
||||
IPhantomTile phantomTE = ((IPhantomTile) te);
|
||||
if (phantomTE.hasBoundPosition()) {
|
||||
TileEntity phantom = w.getTileEntity(phantomTE.getBoundPosition());
|
||||
if (NonBlockingItems.INSTANCE.getMap().containsKey(w.getBlockState(phantomTE.getBoundPosition()).getBlock().getRegistryName().getNamespace())) {
|
||||
@@ -1465,7 +1453,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
|
||||
|
||||
public long getSortValue() {
|
||||
final TileEntity te = this.iHost.getTileEntity();
|
||||
return ((long) te.getPos().getZ() << 24) ^ ((long) te.getPos().getX() << 8) ^ te.getPos().getY();
|
||||
return (te.getPos().getZ() << 24) ^ (te.getPos().getX() << 8) ^ te.getPos().getY();
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
|
||||
@@ -9,6 +9,7 @@ import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
@@ -23,30 +24,65 @@ public class NonBlockingItems {
|
||||
private NonBlockingItems() {
|
||||
String[] strings = AEConfig.instance().getNonBlockingItems();
|
||||
String[] modids = new String[0];
|
||||
for (String s : strings) {
|
||||
if (s.startsWith("[") && s.endsWith("]")) {
|
||||
modids = s.substring(1, s.length() - 1).split("\\|");
|
||||
} else {
|
||||
for (String modid : modids) {
|
||||
if (!Platform.isModLoaded(modid)) {
|
||||
continue;
|
||||
}
|
||||
NON_BLOCKING_MAP.putIfAbsent(modid, new Object2ObjectOpenHashMap<>());
|
||||
if (strings.length > 0) {
|
||||
for (String s : strings) {
|
||||
if (s.startsWith("[") && s.endsWith("]")) {
|
||||
modids = s.substring(1, s.length() - 1).split("\\|");
|
||||
} else {
|
||||
for (String modid : modids) {
|
||||
if (!Loader.isModLoaded(modid)) {
|
||||
continue;
|
||||
}
|
||||
NON_BLOCKING_MAP.putIfAbsent(modid, new Object2ObjectOpenHashMap<>());
|
||||
|
||||
String[] ModItemMeta = s.split(":");
|
||||
String[] ModItemMeta = s.split(":");
|
||||
|
||||
if (ModItemMeta.length < 2 || ModItemMeta.length > 3) {
|
||||
AELog.error("Invalid non blocking item entry: " + s);
|
||||
continue;
|
||||
}
|
||||
if (ModItemMeta.length < 2 || ModItemMeta.length > 3) {
|
||||
AELog.error("Invalid non blocking item entry: " + s);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ModItemMeta[0].equals("gregtech") && Platform.GTLoaded) {
|
||||
boolean found = false;
|
||||
for (MetaItem<?> metaItem : MetaItem.getMetaItems()) {
|
||||
MetaItem<?>.MetaValueItem metaItem2 = metaItem.getItem(ModItemMeta[1]);
|
||||
if (metaItem.getItem(ModItemMeta[1]) != null) {
|
||||
found = true;
|
||||
ItemStack itemStack = metaItem2.getStackForm();
|
||||
if (ModItemMeta[0].equals("gregtech") && Platform.GTLoaded) {
|
||||
boolean found = false;
|
||||
for (MetaItem<?> metaItem : MetaItem.getMetaItems()) {
|
||||
MetaItem<?>.MetaValueItem metaItem2 = metaItem.getItem(ModItemMeta[1]);
|
||||
if (metaItem.getItem(ModItemMeta[1]) != null) {
|
||||
found = true;
|
||||
ItemStack itemStack = metaItem2.getStackForm();
|
||||
NON_BLOCKING_MAP.get(modid).putIfAbsent(itemStack.getItem(), new IntOpenHashSet());
|
||||
NON_BLOCKING_MAP.get(modid).computeIfPresent(itemStack.getItem(), (item, intSet) ->
|
||||
{
|
||||
intSet.add(itemStack.getItemDamage());
|
||||
return intSet;
|
||||
});
|
||||
} else {
|
||||
ItemStack itemStack = GameRegistry.makeItemStack(ModItemMeta[0] + ":" + ModItemMeta[1], ModItemMeta.length == 3 ? Integer.parseInt(ModItemMeta[2]) : 0, 1, null);
|
||||
if (!itemStack.isEmpty()) {
|
||||
NON_BLOCKING_MAP.get(modid).putIfAbsent(itemStack.getItem(), new IntOpenHashSet());
|
||||
NON_BLOCKING_MAP.get(modid).computeIfPresent(itemStack.getItem(), (item, intSet) ->
|
||||
{
|
||||
intSet.add(itemStack.getItemDamage());
|
||||
return intSet;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
AELog.error("Item not found on nonBlocking config: " + s);
|
||||
}
|
||||
} else if (ModItemMeta[0].equals("ore")) {
|
||||
OreDictionary.getOres(ModItemMeta[1]).forEach(itemStack ->
|
||||
{
|
||||
NON_BLOCKING_MAP.get(modid).putIfAbsent(itemStack.getItem(), new IntOpenHashSet());
|
||||
NON_BLOCKING_MAP.get(modid).computeIfPresent(itemStack.getItem(), (item, intSet) ->
|
||||
{
|
||||
intSet.add(itemStack.getItemDamage());
|
||||
return intSet;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
ItemStack itemStack = GameRegistry.makeItemStack(ModItemMeta[0] + ":" + ModItemMeta[1], ModItemMeta.length == 3 ? Integer.parseInt(ModItemMeta[2]) : 0, 1, null);
|
||||
if (!itemStack.isEmpty()) {
|
||||
NON_BLOCKING_MAP.get(modid).putIfAbsent(itemStack.getItem(), new IntOpenHashSet());
|
||||
NON_BLOCKING_MAP.get(modid).computeIfPresent(itemStack.getItem(), (item, intSet) ->
|
||||
{
|
||||
@@ -54,42 +90,9 @@ public class NonBlockingItems {
|
||||
return intSet;
|
||||
});
|
||||
} else {
|
||||
ItemStack itemStack = GameRegistry.makeItemStack(ModItemMeta[0] + ":" + ModItemMeta[1], ModItemMeta.length == 3 ? Integer.parseInt(ModItemMeta[2]) : 0, 1, null);
|
||||
if (!itemStack.isEmpty()) {
|
||||
NON_BLOCKING_MAP.get(modid).putIfAbsent(itemStack.getItem(), new IntOpenHashSet());
|
||||
NON_BLOCKING_MAP.get(modid).computeIfPresent(itemStack.getItem(), (item, intSet) ->
|
||||
{
|
||||
intSet.add(itemStack.getItemDamage());
|
||||
return intSet;
|
||||
});
|
||||
}
|
||||
AELog.error("Item not found on nonBlocking config: " + s);
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
AELog.error("Item not found on nonBlocking config: " + s);
|
||||
}
|
||||
} else if (ModItemMeta[0].equals("ore")) {
|
||||
OreDictionary.getOres(ModItemMeta[1]).forEach(itemStack ->
|
||||
{
|
||||
NON_BLOCKING_MAP.get(modid).putIfAbsent(itemStack.getItem(), new IntOpenHashSet());
|
||||
NON_BLOCKING_MAP.get(modid).computeIfPresent(itemStack.getItem(), (item, intSet) ->
|
||||
{
|
||||
intSet.add(itemStack.getItemDamage());
|
||||
return intSet;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
ItemStack itemStack = GameRegistry.makeItemStack(ModItemMeta[0] + ":" + ModItemMeta[1], ModItemMeta.length == 3 ? Integer.parseInt(ModItemMeta[2]) : 0, 1, null);
|
||||
if (!itemStack.isEmpty()) {
|
||||
NON_BLOCKING_MAP.get(modid).putIfAbsent(itemStack.getItem(), new IntOpenHashSet());
|
||||
NON_BLOCKING_MAP.get(modid).computeIfPresent(itemStack.getItem(), (item, intSet) ->
|
||||
{
|
||||
intSet.add(itemStack.getItemDamage());
|
||||
return intSet;
|
||||
});
|
||||
} else {
|
||||
AELog.error("Item not found on nonBlocking config: " + s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ package appeng.integration;
|
||||
import appeng.api.exceptions.ModNotInstalledException;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.AELog;
|
||||
import appeng.util.Platform;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.ModAPIManager;
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ final class IntegrationNode {
|
||||
switch (stage) {
|
||||
case PRE_INIT:
|
||||
final ModAPIManager apiManager = ModAPIManager.INSTANCE;
|
||||
boolean enabled = this.modID == null || Platform.isModLoaded(this.modID) || apiManager.hasAPI(this.modID);
|
||||
boolean enabled = this.modID == null || Loader.isModLoaded(this.modID) || apiManager.hasAPI(this.modID);
|
||||
|
||||
AEConfig.instance()
|
||||
.addCustomCategoryComment("ModIntegration",
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package appeng.integration.modules.bogosorter;
|
||||
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.util.Platform;
|
||||
import com.cleanroommc.bogosorter.common.sort.SortHandler;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class InventoryBogoSortModule {
|
||||
private static final boolean loaded = Platform.isModLoaded("bogosorter");
|
||||
private static final boolean loaded = Loader.isModLoaded("bogosorter");
|
||||
|
||||
public static final Comparator<IAEItemStack> COMPARATOR = (o1, o2) -> SortHandler.getClientItemComparator().compare(o1.getDefinition(), o2.getDefinition());
|
||||
|
||||
|
||||
@@ -16,9 +16,9 @@ import mezz.jei.gui.TooltipRenderer;
|
||||
import mezz.jei.gui.recipes.RecipeLayout;
|
||||
import mezz.jei.gui.recipes.RecipeTransferButton;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.ScaledResolution;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.text.translation.I18n;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.wrapper.PlayerMainInvWrapper;
|
||||
|
||||
@@ -26,12 +26,14 @@ import javax.annotation.Nonnull;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static mezz.jei.api.recipe.transfer.IRecipeTransferError.Type.USER_FACING;
|
||||
import static net.minecraft.client.resources.I18n.format;
|
||||
|
||||
public class JEIMissingItem implements IRecipeTransferError {
|
||||
|
||||
private final IRecipeLayout recipeLayout;
|
||||
private boolean errored;
|
||||
public long lastUpdate;
|
||||
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> used = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
||||
private boolean foundAny;
|
||||
|
||||
JEIMissingItem(Container container, @Nonnull IRecipeLayout recipeLayout) {
|
||||
this.recipeLayout = recipeLayout;
|
||||
|
||||
if (container instanceof ContainerMEMonitorable) {
|
||||
IItemList<IAEItemStack> ir = ((ContainerMEMonitorable) container).items;
|
||||
|
||||
@@ -57,8 +62,7 @@ public class JEIMissingItem implements IRecipeTransferError {
|
||||
if (i.isInput() && !i.getAllIngredients().isEmpty()) {
|
||||
List<?> allIngredients = i.getAllIngredients();
|
||||
for (Object allIngredient : allIngredients) {
|
||||
if (allIngredient instanceof ItemStack) {
|
||||
ItemStack stack = (ItemStack) allIngredient;
|
||||
if (allIngredient instanceof ItemStack stack) {
|
||||
if (!stack.isEmpty()) {
|
||||
IAEItemStack search = AEItemStack.fromItemStack(stack);
|
||||
if (stack.getItem().isDamageable() || Platform.isGTDamageableItem(stack.getItem())) {
|
||||
@@ -93,7 +97,8 @@ public class JEIMissingItem implements IRecipeTransferError {
|
||||
}
|
||||
if (!found) {
|
||||
this.errored = true;
|
||||
break;
|
||||
} else{
|
||||
this.foundAny = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,6 +108,13 @@ public class JEIMissingItem implements IRecipeTransferError {
|
||||
@Nonnull
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -111,12 +123,15 @@ public class JEIMissingItem implements IRecipeTransferError {
|
||||
Container c = minecraft.player.openContainer;
|
||||
if (c instanceof ContainerMEMonitorable container) {
|
||||
IItemList<IAEItemStack> ir = ((ContainerMEMonitorable) c).items;
|
||||
boolean found = false;
|
||||
boolean foundAny = false;
|
||||
boolean craftable = false;
|
||||
boolean foundAnyCraftable = false;
|
||||
boolean found;
|
||||
boolean craftable;
|
||||
|
||||
int foundMissing = 0;
|
||||
int foundCraftables = 0;
|
||||
int currentSlot = 0;
|
||||
|
||||
this.errored = false;
|
||||
this.foundAny = false;
|
||||
|
||||
if (System.currentTimeMillis() - lastUpdate > 1000) {
|
||||
lastUpdate = System.currentTimeMillis();
|
||||
@@ -144,6 +159,7 @@ public class JEIMissingItem implements IRecipeTransferError {
|
||||
found = false;
|
||||
craftable = false;
|
||||
IItemList<IAEItemStack> valid = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
|
||||
|
||||
if (i.isInput()) {
|
||||
List<?> allIngredients = i.getAllIngredients();
|
||||
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);
|
||||
this.craftableSlots.add(currentSlot);
|
||||
recipeLayout.getItemStacks().set(currentSlot, validStacks);
|
||||
foundAnyCraftable = true;
|
||||
foundCraftables++;
|
||||
} else {
|
||||
i.drawHighlight(minecraft, new Color(1.0f, 0.0f, 0.0f, 0.4f), recipeX, recipeY);
|
||||
}
|
||||
this.errored = true;
|
||||
foundMissing++;
|
||||
} else {
|
||||
foundAny = true;
|
||||
this.foundSlots.add(currentSlot);
|
||||
@@ -226,18 +243,42 @@ public class JEIMissingItem implements IRecipeTransferError {
|
||||
if (b != null) {
|
||||
List<String> tooltipLines = new ArrayList<>();
|
||||
b.init(c, minecraft.player);
|
||||
if (errored && foundAny) {
|
||||
tooltipLines.add(I18n.translateToLocal("gui.tooltips.appliedenergistics2.PartialTransfer"));
|
||||
if (foundAny) {
|
||||
tooltipLines.add(format("gui.tooltips.appliedenergistics2.PartialTransfer"));
|
||||
b.enabled = 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) {
|
||||
tooltipLines.add(I18n.translateToLocal("gui.tooltips.appliedenergistics2.CraftableItem"));
|
||||
if (foundCraftables > 0) {
|
||||
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.ContainerPatternEncoder;
|
||||
import appeng.container.implementations.ContainerWirelessCraftingTerminal;
|
||||
import appeng.container.slot.SlotCraftingMatrix;
|
||||
import appeng.container.slot.SlotFakeCraftingMatrix;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.PacketJEIRecipe;
|
||||
import appeng.core.sync.packets.PacketValueConfig;
|
||||
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.IRecipeLayout;
|
||||
import mezz.jei.api.recipe.VanillaRecipeCategoryUid;
|
||||
import mezz.jei.api.recipe.transfer.IRecipeTransferError;
|
||||
import mezz.jei.api.recipe.transfer.IRecipeTransferHandler;
|
||||
import mezz.jei.gui.recipes.RecipeLayout;
|
||||
import mezz.jei.transfer.RecipeTransferErrorInternal;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
@@ -50,6 +54,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static appeng.helpers.ItemStackHelper.stackToNBT;
|
||||
import static appeng.util.Platform.GTLoaded;
|
||||
|
||||
|
||||
class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandler<T> {
|
||||
@@ -61,7 +66,7 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> getContainerClass() {
|
||||
public @NotNull Class<T> getContainerClass() {
|
||||
return this.containerClass;
|
||||
}
|
||||
|
||||
@@ -77,19 +82,24 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
||||
if (!doTransfer) {
|
||||
if (recipeType.equals(VanillaRecipeCategoryUid.CRAFTING) && (container instanceof ContainerCraftingTerm || container instanceof ContainerWirelessCraftingTerminal)) {
|
||||
JEIMissingItem error = new JEIMissingItem(container, recipeLayout);
|
||||
|
||||
if (error.errored())
|
||||
return error;
|
||||
}
|
||||
return null;
|
||||
|
||||
if (container instanceof ContainerPatternEncoder || container instanceof ContainerCraftingTerm) {
|
||||
JEITransferInfo.INSTANCE.setRecipeLayout((RecipeLayout) recipeLayout);
|
||||
return JEITransferInfo.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
if (container instanceof ContainerPatternEncoder) {
|
||||
try {
|
||||
if (!((ContainerPatternEncoder) container).isCraftingMode()) {
|
||||
if (!((ContainerPatternEncoder) container).isCraftingMode() && !maxTransfer) {
|
||||
if (recipeType.equals(VanillaRecipeCategoryUid.CRAFTING)) {
|
||||
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"));
|
||||
}
|
||||
@@ -104,8 +114,7 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
||||
final NBTTagCompound recipe = new NBTTagCompound();
|
||||
final NBTTagList outputs = new NBTTagList();
|
||||
|
||||
|
||||
int slotIndex = 0;
|
||||
var slotIndex = 0;
|
||||
for (Map.Entry<Integer, ? extends IGuiIngredient<ItemStack>> ingredientEntry : ingredients.entrySet()) {
|
||||
IGuiIngredient<ItemStack> ingredient = ingredientEntry.getValue();
|
||||
if (!ingredient.isInput()) {
|
||||
@@ -117,45 +126,63 @@ class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandl
|
||||
continue;
|
||||
}
|
||||
|
||||
for (final Slot slot : container.inventorySlots) {
|
||||
if (slot instanceof SlotCraftingMatrix || slot instanceof SlotFakeCraftingMatrix) {
|
||||
if (slot.getSlotIndex() == slotIndex) {
|
||||
final NBTTagList tags = new NBTTagList();
|
||||
final List<ItemStack> list = new ArrayList<>();
|
||||
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
|
||||
if (displayed != null && !displayed.isEmpty()) {
|
||||
list.add(displayed);
|
||||
}
|
||||
// prefer currently displayed item
|
||||
if (displayed != null && !displayed.isEmpty()) {
|
||||
list.add(displayed);
|
||||
}
|
||||
|
||||
// prefer pure crystals.
|
||||
for (ItemStack stack : ingredient.getAllIngredients()) {
|
||||
if (stack == null) {
|
||||
continue;
|
||||
}
|
||||
if (Platform.isRecipePrioritized(stack)) {
|
||||
list.add(0, stack);
|
||||
} else {
|
||||
list.add(stack);
|
||||
}
|
||||
}
|
||||
|
||||
for (final ItemStack is : list) {
|
||||
final NBTTagCompound tag = stackToNBT(is);
|
||||
tags.appendTag(tag);
|
||||
}
|
||||
|
||||
recipe.setTag("#" + slot.getSlotIndex(), tags);
|
||||
break;
|
||||
}
|
||||
// prefer pure crystals.
|
||||
for (ItemStack stack : ingredient.getAllIngredients()) {
|
||||
if (stack == null) {
|
||||
continue;
|
||||
}
|
||||
if (Platform.isRecipePrioritized(stack)) {
|
||||
list.add(0, stack);
|
||||
} else {
|
||||
list.add(stack);
|
||||
}
|
||||
}
|
||||
|
||||
for (final ItemStack is : list) {
|
||||
final NBTTagCompound tag = stackToNBT(is);
|
||||
tags.appendTag(tag);
|
||||
}
|
||||
|
||||
recipe.setTag("#" + slotIndex, tags);
|
||||
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.setBoolean("condense", maxTransfer);
|
||||
|
||||
try {
|
||||
NetworkHandler.instance().sendToServer(new PacketJEIRecipe(recipe));
|
||||
|
||||
@@ -25,9 +25,9 @@ import appeng.core.AppEng;
|
||||
import appeng.services.version.*;
|
||||
import appeng.services.version.github.FormattedRelease;
|
||||
import appeng.services.version.github.ReleaseFetcher;
|
||||
import appeng.util.Platform;
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.event.FMLInterModComms;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@@ -82,7 +82,7 @@ public final class VersionChecker implements Runnable {
|
||||
final long lastCheck = Long.parseLong(rawLastCheck);
|
||||
final Date now = new Date();
|
||||
final long nowInMs = now.getTime();
|
||||
final long intervalInMs = (long) this.config.interval() * SEC_TO_HOUR * MS_TO_SEC;
|
||||
final long intervalInMs = this.config.interval() * SEC_TO_HOUR * MS_TO_SEC;
|
||||
final long lastAfterInterval = lastCheck + intervalInMs;
|
||||
|
||||
this.processInterval(nowInMs, lastAfterInterval);
|
||||
@@ -153,7 +153,7 @@ public final class VersionChecker implements Runnable {
|
||||
* @param changelog retrieved github changelog
|
||||
*/
|
||||
private void interactWithVersionCheckerMod(@Nonnull final String modFormatted, @Nonnull final String ghFormatted, @Nonnull final String changelog) {
|
||||
if (Platform.isModLoaded("VersionChecker")) {
|
||||
if (Loader.isModLoaded("VersionChecker")) {
|
||||
final NBTTagCompound versionInf = new NBTTagCompound();
|
||||
versionInf.setString("modDisplayName", AppEng.MOD_NAME);
|
||||
versionInf.setString("oldVersion", modFormatted);
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
package appeng.tile.inventory;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.config.Actionable;
|
||||
import appeng.api.networking.security.IActionSource;
|
||||
import appeng.api.networking.storage.IStorageGrid;
|
||||
import appeng.api.storage.IMEInventory;
|
||||
import appeng.api.storage.channels.IItemStorageChannel;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.util.inv.IAEAppEngInventory;
|
||||
import appeng.util.item.AEItemStack;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class AppEngNetworkInventory extends AppEngInternalOversizedInventory {
|
||||
|
||||
private final Supplier<IStorageGrid> supplier;
|
||||
private final IActionSource source;
|
||||
|
||||
public AppEngNetworkInventory(Supplier<IStorageGrid> networkSupplier, IActionSource source, IAEAppEngInventory inventory, int size, int maxStack) {
|
||||
super(inventory, size, maxStack);
|
||||
this.supplier = networkSupplier;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
|
||||
IStorageGrid storage = supplier.get();
|
||||
if (storage != null) {
|
||||
int originAmt = stack.getCount();
|
||||
IMEInventory<IAEItemStack> dest = storage.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class));
|
||||
IAEItemStack overflow = dest.injectItems(AEItemStack.fromItemStack(stack), simulate ? Actionable.SIMULATE : Actionable.MODULATE, this.source);
|
||||
if (overflow != null && overflow.getStackSize() == originAmt) {
|
||||
return super.insertItem(slot, stack, simulate);
|
||||
} else if (overflow != null) {
|
||||
return overflow.createItemStack();
|
||||
} else {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
} else {
|
||||
return super.insertItem(slot, stack, simulate);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -73,8 +73,6 @@ import gregtech.api.block.machines.BlockMachine;
|
||||
import gregtech.api.metatileentity.MetaTileEntity;
|
||||
import gregtech.api.util.GTUtility;
|
||||
import ic2.api.item.ICustomDamageItem;
|
||||
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -108,6 +106,7 @@ import net.minecraftforge.fluids.FluidRegistry;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.ModContainer;
|
||||
import net.minecraftforge.fml.common.Optional;
|
||||
import net.minecraftforge.fml.relauncher.ReflectionHelper;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
@@ -131,7 +130,6 @@ import java.util.*;
|
||||
*/
|
||||
@Optional.Interface(iface = "ic2.api.item.ICustomDamageItem", modid = "IC2")
|
||||
public class Platform {
|
||||
private static final Object2BooleanMap<String> CACHED_MODS = new Object2BooleanOpenHashMap<>();
|
||||
|
||||
public static final Block AIR_BLOCK = Blocks.AIR;
|
||||
|
||||
@@ -528,15 +526,18 @@ public class Platform {
|
||||
}
|
||||
|
||||
public static boolean isModLoaded(final String modid) {
|
||||
return CACHED_MODS.computeIfAbsent(modid, (k) -> {
|
||||
try {
|
||||
// if this fails for some reason, try the other method.
|
||||
return Loader.isModLoaded(k);
|
||||
} catch (final Throwable ignored) {}
|
||||
try {
|
||||
// if this fails for some reason, try the other method.
|
||||
return Loader.isModLoaded(modid);
|
||||
} catch (final Throwable ignored) {
|
||||
}
|
||||
|
||||
return Loader.instance().getActiveModList()
|
||||
.stream().anyMatch(mod -> mod.getModId().equals(k));
|
||||
});
|
||||
for (final ModContainer f : Loader.instance().getActiveModList()) {
|
||||
if (f.getModId().equals(modid)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static ItemStack findMatchingRecipeOutput(final InventoryCrafting ic, final World world) {
|
||||
@@ -550,7 +551,8 @@ public class Platform {
|
||||
}
|
||||
|
||||
ItemStack itemStack = ItemStack.EMPTY;
|
||||
if (o instanceof AEItemStack ais) {
|
||||
if (o instanceof AEItemStack) {
|
||||
final AEItemStack ais = (AEItemStack) o;
|
||||
return ais.getToolTip();
|
||||
} else if (o instanceof ItemStack) {
|
||||
itemStack = (ItemStack) o;
|
||||
@@ -653,7 +655,8 @@ public class Platform {
|
||||
|
||||
}
|
||||
|
||||
if (eq.getItem() instanceof IAEWrench wrench) {
|
||||
if (eq.getItem() instanceof IAEWrench) {
|
||||
final IAEWrench wrench = (IAEWrench) eq.getItem();
|
||||
return wrench.canWrench(eq, player, pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,16 +23,14 @@
|
||||
|
||||
package appeng.util.item;
|
||||
|
||||
import com.google.common.collect.MapMaker;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Map;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
public final class AEItemStackRegistry {
|
||||
|
||||
private static final ItemStackHashStrategy HASH_STRATEGY = ItemStackHashStrategy.comparingAllButCount();
|
||||
private static final Map<Integer, AESharedItemStack> REGISTRY = new MapMaker().weakValues().makeMap();
|
||||
private static final WeakHashMap<AESharedItemStack, WeakReference<AESharedItemStack>> REGISTRY = new WeakHashMap<>();
|
||||
|
||||
private AEItemStackRegistry() {
|
||||
}
|
||||
@@ -42,18 +40,23 @@ public final class AEItemStackRegistry {
|
||||
throw new IllegalArgumentException("stack cannot be empty");
|
||||
}
|
||||
|
||||
var hash = HASH_STRATEGY.hashCode(itemStack);
|
||||
var ret = REGISTRY.get(hash);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
int oldStackSize = itemStack.getCount();
|
||||
itemStack.setCount(1);
|
||||
|
||||
AESharedItemStack search = new AESharedItemStack(itemStack);
|
||||
WeakReference<AESharedItemStack> weak = REGISTRY.get(search);
|
||||
AESharedItemStack ret = null;
|
||||
|
||||
if (weak != null) {
|
||||
ret = weak.get();
|
||||
}
|
||||
|
||||
// computeIfAbsent is not feasible since new AESharedItemStack gets
|
||||
// instantly GC'd when leaving the lambda.
|
||||
var itemStackCopy = itemStack.copy();
|
||||
itemStackCopy.setCount(1);
|
||||
var sharedStack = new AESharedItemStack(itemStackCopy);
|
||||
REGISTRY.put(hash, sharedStack);
|
||||
return sharedStack;
|
||||
if (ret == null) {
|
||||
ret = new AESharedItemStack(itemStack.copy());
|
||||
REGISTRY.put(ret, new WeakReference<>(ret));
|
||||
}
|
||||
itemStack.setCount(oldStackSize);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ import java.util.Map;
|
||||
* {@link #findFuzzy(IAEItemStack, FuzzyMode)}.
|
||||
*/
|
||||
class FuzzyItemVariantList extends ItemVariantList {
|
||||
|
||||
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.
|
||||
@@ -47,6 +46,10 @@ class FuzzyItemVariantList extends ItemVariantList {
|
||||
|
||||
@Override
|
||||
public Collection<IAEItemStack> findFuzzy(final IAEItemStack filter, final FuzzyMode fuzzy) {
|
||||
if (fuzzy == FuzzyMode.IGNORE_ALL) {
|
||||
return this.records.values();
|
||||
}
|
||||
|
||||
ItemStack itemStack = filter.getDefinition();
|
||||
|
||||
ItemDamageBound lowerBound = makeLowerBound(itemStack, fuzzy);
|
||||
@@ -161,14 +164,8 @@ class FuzzyItemVariantList extends ItemVariantList {
|
||||
damage = stack.getItemDamage();
|
||||
}
|
||||
|
||||
if (fuzzy == FuzzyMode.IGNORE_ALL) {
|
||||
if (maxDamage != 0) {
|
||||
damage = maxDamage;
|
||||
}
|
||||
} else {
|
||||
final int breakpoint = fuzzy.calculateBreakPoint(maxDamage);
|
||||
damage = damage <= breakpoint ? breakpoint : maxDamage;
|
||||
}
|
||||
final int breakpoint = fuzzy.calculateBreakPoint(maxDamage);
|
||||
damage = damage <= breakpoint ? breakpoint : maxDamage;
|
||||
|
||||
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");
|
||||
|
||||
int damage;
|
||||
if (fuzzy == FuzzyMode.IGNORE_ALL) {
|
||||
damage = MIN_DAMAGE_VALUE;
|
||||
int maxDamage;
|
||||
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 {
|
||||
int maxDamage;
|
||||
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 {
|
||||
maxDamage = stack.getMaxDamage();
|
||||
damage = stack.getItemDamage();
|
||||
}
|
||||
|
||||
final int breakpoint = fuzzy.calculateBreakPoint(maxDamage);
|
||||
damage = damage <= breakpoint ? MIN_DAMAGE_VALUE : breakpoint;
|
||||
maxDamage = stack.getMaxDamage();
|
||||
damage = stack.getItemDamage();
|
||||
}
|
||||
|
||||
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.SearchFieldNames=Interface Names
|
||||
gui.tooltips.appliedenergistics2.PartialTransfer=Move stored items into the crafting grid
|
||||
gui.tooltips.appliedenergistics2.MissingItem=§cMissing item
|
||||
gui.tooltips.appliedenergistics2.CraftableItem=§9Craftable item
|
||||
gui.tooltips.appliedenergistics2.MissingItem=§cMissing %s items
|
||||
gui.tooltips.appliedenergistics2.CraftableItem=§9Found %s craftable items
|
||||
gui.tooltips.appliedenergistics2.CondenseItems=§5- hold Shift to condense items
|
||||
|
||||
// Units
|
||||
gui.appliedenergistics2.units.appliedenergstics=AE
|
||||
|
||||
Reference in New Issue
Block a user