Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/main/java/com/ae2powertools/features/crafter/CrafterEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ public class CrafterEntry {
*/
private long targetQuantity;

/**
* If true, consumed inputs for this entry are matched in the ME network ignoring NBT (item + meta only).
* This does NOT affect catalyst slot validation.
*/
private boolean ignoreNbt;

// ==================== ERROR DETAILS ====================

/**
Expand Down Expand Up @@ -149,6 +155,7 @@ public CrafterEntry() {
this.lastCraftTick = 0;
this.metricsTotal = 0;
this.metricsError = 0;
this.ignoreNbt = false;
}

/**
Expand Down Expand Up @@ -471,6 +478,7 @@ public NBTTagCompound writeToNBT() {
tag.setInteger("state", state.ordinal());
tag.setLong("targetQty", targetQuantity);
tag.setLong("lastCraft", lastCraftTick);
tag.setBoolean("ignoreNbt", ignoreNbt);

// Save pending outputs as a list
if (!pendingOutputs.isEmpty()) {
Expand Down Expand Up @@ -525,6 +533,7 @@ public void readFromNBT(NBTTagCompound tag) {
if (targetQuantity == 0) targetQuantity = Long.MAX_VALUE;

lastCraftTick = tag.getLong("lastCraft");
ignoreNbt = tag.getBoolean("ignoreNbt");

// Load pending outputs
pendingOutputs.clear();
Expand Down Expand Up @@ -616,4 +625,14 @@ public IAEItemStack[] getInputGrid() {
// Fall back to synced data (client-side)
return syncedInputGrid;
}

// --- Ignore NBT ---

public boolean isIgnoreNbt() {
return ignoreNbt;
}

public void setIgnoreNbt(boolean ignoreNbt) {
this.ignoreNbt = ignoreNbt;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ public class GuiAutoCrafter extends GuiContainer {
private boolean overviewBtnHovered = false;
private boolean overviewCloseBtnHovered = false;

// Ignore NBT toggle button
private static final int IGNORE_NBT_BTN_X = 150;
private static final int IGNORE_NBT_BTN_Y = STATE_INDICATOR_Y;

// Hover state for Ignore NBT button
private boolean ignoreNbtBtnHovered = false;

// Hovered elements
private int hoveredRecipeSlot = -1;
private int hoveredOverviewRow = -1;
Expand Down Expand Up @@ -144,6 +151,7 @@ public class GuiAutoCrafter extends GuiContainer {
private final double[] syncedOccupancy = new double[TileAutoCrafter.ENTRY_COUNT];
private final double[] syncedErrorRate = new double[TileAutoCrafter.ENTRY_COUNT];
private final List<List<String>> syncedErrorDetails = new ArrayList<>();
private final boolean[] syncedIgnoreNbt = new boolean[TileAutoCrafter.ENTRY_COUNT];

// Catalyst info per entry (slot index -> expected item)
private final List<List<CatalystInfo>> syncedCatalystInfo = new ArrayList<>();
Expand Down Expand Up @@ -336,6 +344,7 @@ private void drawAE2Buttons(int mouseX, int mouseY) {
if (!overviewMode) {
drawPageNavigationButtons(mouseX, mouseY);
drawBatchSpeedButtons(mouseX, mouseY);
drawIgnoreNbtButton(mouseX, mouseY);
}
}

Expand Down Expand Up @@ -469,6 +478,32 @@ private void drawSquareButton(int x, int y, int size, String text, boolean enabl
fontRenderer.drawStringWithShadow(text, textX, textY, textColor);
}

/**
* Draws the per-entry Ignore NBT toggle button.
* This is a small square vanilla-style button that toggles fuzzy NBT matching for the current recipe entry.
*/
private void drawIgnoreNbtButton(int mouseX, int mouseY) {
int x = guiLeft + IGNORE_NBT_BTN_X;
int y = guiTop + IGNORE_NBT_BTN_Y;

int page = getCurrentPage();

// Only enable if this entry has a recipe/pattern to act on
boolean enabled = hasDisplayData(page);

ignoreNbtBtnHovered = enabled
&& mouseX >= x && mouseX < x + PAGE_BTN_SIZE
&& mouseY >= y && mouseY < y + PAGE_BTN_SIZE;

// Draw button with "N" label (NBT)
drawSquareButton(x, y, PAGE_BTN_SIZE, "N", enabled, ignoreNbtBtnHovered);

// Visual ON indicator (subtle green overlay)
if (enabled && isIgnoreNbtEnabled(page)) {
drawRect(x + 1, y + 1, x + PAGE_BTN_SIZE - 1, y + PAGE_BTN_SIZE - 1, 0x3000FF00);
}
}

/**
* Draws tooltips for custom buttons.
*/
Expand All @@ -493,6 +528,14 @@ private void drawAE2ButtonTooltips(int mouseX, int mouseY) {
FormatUtil.formatTimeTicks(container.syncSpeedTicks)));
tooltip.add("");
tooltip.add(TextFormatting.DARK_GRAY + I18n.format("gui.ae2powertools.crafter.speed.explanation"));
} else if (ignoreNbtBtnHovered) {
boolean ignored = isIgnoreNbtEnabled(getCurrentPage());
tooltip.add(I18n.format(ignored
? "gui.ae2powertools.crafter.nbt_matching.ignored"
: "gui.ae2powertools.crafter.nbt_matching.strict"));
tooltip.add(TextFormatting.DARK_GRAY + I18n.format(ignored
? "gui.ae2powertools.crafter.nbt_matching.ignored.desc"
: "gui.ae2powertools.crafter.nbt_matching.strict.desc"));
}

if (!tooltip.isEmpty()) {
Expand Down Expand Up @@ -1013,6 +1056,14 @@ protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOEx
openSpeedDialog();
return;
}

// Ignore NBT toggle button
if (ignoreNbtBtnHovered) {
int page = getCurrentPage();
PowerToolsNetwork.INSTANCE.sendToServer(new PacketToggleCrafterIgnoreNbt(
container.getTile().getPos(), page));
return;
}
}

// Handle result right-click to disable
Expand Down Expand Up @@ -1134,6 +1185,9 @@ public void handleStateSync(NBTTagCompound data) {
syncedStates[i] = CrafterState.NO_PATTERN;
}

// Per-entry ignore NBT setting
syncedIgnoreNbt[i] = entryTag.getBoolean("ignoreNbt");

// Metrics
syncedMetricsTotal[i] = entryTag.getLong("metricsTotal");
long metricsError = entryTag.getLong("metricsError");
Expand Down Expand Up @@ -1303,4 +1357,14 @@ private int getSyncedBatchSize() {
private int getSyncedEffectiveBatchSize() {
return hasSyncedData ? syncedEffectiveBatchSize : container.syncEffectiveBatchSize;
}

/** Gets whether Ignore NBT is enabled for an entry. */
private boolean isIgnoreNbtEnabled(int entryIndex) {
if (hasSyncedData && entryIndex >= 0 && entryIndex < TileAutoCrafter.ENTRY_COUNT) {
return syncedIgnoreNbt[entryIndex];
}

CrafterEntry entry = container.getTile().getEntry(entryIndex);
return entry != null && entry.isIgnoreNbt();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ public static PacketCrafterStateSync fromTile(TileAutoCrafter tile) {
entryTag.setInteger("state", entry.getState().ordinal());
entryTag.setBoolean("enabled", entry.isEnabled());

// Per-entry ignore NBT setting
entryTag.setBoolean("ignoreNbt", entry.isIgnoreNbt());

// Metrics
entryTag.setLong("metricsTotal", entry.getMetricsTotal());
entryTag.setLong("metricsError", entry.getMetricsError());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.ae2powertools.features.crafter;

import io.netty.buffer.ByteBuf;

import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;

/**
* Packet to toggle the per-entry Ignore NBT setting for the AutoCrafter.
*/
public class PacketToggleCrafterIgnoreNbt implements IMessage {

private BlockPos pos;
private int entryIndex;

public PacketToggleCrafterIgnoreNbt() {}

public PacketToggleCrafterIgnoreNbt(BlockPos pos, int entryIndex) {
this.pos = pos;
this.entryIndex = entryIndex;
}

@Override
public void fromBytes(ByteBuf buf) {
int x = buf.readInt();
int y = buf.readInt();
int z = buf.readInt();
this.pos = new BlockPos(x, y, z);
this.entryIndex = buf.readInt();
}

@Override
public void toBytes(ByteBuf buf) {
buf.writeInt(pos.getX());
buf.writeInt(pos.getY());
buf.writeInt(pos.getZ());
buf.writeInt(entryIndex);
}

public static class Handler implements IMessageHandler<PacketToggleCrafterIgnoreNbt, IMessage> {

@Override
public IMessage onMessage(PacketToggleCrafterIgnoreNbt message, MessageContext ctx) {
EntityPlayerMP player = ctx.getServerHandler().player;
World world = player.world;

player.getServerWorld().addScheduledTask(() -> {
TileEntity te = world.getTileEntity(message.pos);
if (te instanceof TileAutoCrafter) {
TileAutoCrafter crafter = (TileAutoCrafter) te;
crafter.toggleIgnoreNbt(message.entryIndex);
}
});

return null;
}
}
}
Loading