2025-04-24 18:48:40 +03:00
|
|
|
package codechicken.nei.recipe;
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
import net.minecraft.client.gui.inventory.GuiContainer;
|
2025-07-11 17:33:14 +03:00
|
|
|
import net.minecraft.inventory.Slot;
|
|
|
|
|
import net.minecraft.inventory.SlotCrafting;
|
2025-04-24 18:48:40 +03:00
|
|
|
|
2025-07-01 13:52:46 +03:00
|
|
|
import codechicken.nei.ItemPanels;
|
2025-04-24 18:48:40 +03:00
|
|
|
import codechicken.nei.ItemStackAmount;
|
|
|
|
|
import codechicken.nei.NEIClientUtils;
|
|
|
|
|
import codechicken.nei.RestartableTask;
|
|
|
|
|
import codechicken.nei.bookmark.BookmarkItem;
|
|
|
|
|
import codechicken.nei.recipe.Recipe.RecipeId;
|
|
|
|
|
import codechicken.nei.recipe.chain.RecipeChainIterator;
|
|
|
|
|
import codechicken.nei.recipe.chain.RecipeChainMath;
|
|
|
|
|
|
|
|
|
|
public class AutoCraftingManager {
|
|
|
|
|
|
|
|
|
|
private static RecipeChainMath math;
|
|
|
|
|
|
|
|
|
|
private static final RestartableTask task = new RestartableTask("NEI Bookmark AutoCraft Processing") {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void execute() {
|
|
|
|
|
final GuiContainer guiContainer = NEIClientUtils.getGuiContainer();
|
2025-07-11 17:33:14 +03:00
|
|
|
final List<BookmarkItem> initialItems = prepareInitialItems(math, getInventoryItems(guiContainer));
|
2025-04-24 18:48:40 +03:00
|
|
|
boolean processed = false;
|
|
|
|
|
boolean changed = false;
|
|
|
|
|
|
2025-07-11 17:33:14 +03:00
|
|
|
StackInfo.pauseItemDamageSound(true);
|
2025-07-08 16:41:42 +03:00
|
|
|
|
2025-04-24 18:48:40 +03:00
|
|
|
do {
|
|
|
|
|
changed = false;
|
|
|
|
|
|
|
|
|
|
RecipeChainIterator iterator = new RecipeChainIterator(math, initialItems);
|
2025-07-11 17:33:14 +03:00
|
|
|
iterator.updateInventory(getInventoryItems(guiContainer));
|
2025-04-24 18:48:40 +03:00
|
|
|
|
|
|
|
|
while (iterator.hasNext() && !interrupted(guiContainer)) {
|
|
|
|
|
final Map<RecipeId, Long> recipes = iterator.next();
|
|
|
|
|
boolean craft = false;
|
|
|
|
|
|
|
|
|
|
for (Map.Entry<RecipeId, Long> entry : recipes.entrySet()) {
|
|
|
|
|
final RecipeHandlerRef handler = RecipeHandlerRef.of(entry.getKey());
|
|
|
|
|
|
|
|
|
|
if (handler != null && handler.canCraft(guiContainer)) {
|
|
|
|
|
long multiplier = entry.getValue();
|
|
|
|
|
|
|
|
|
|
while (multiplier > 0 && !interrupted(guiContainer)
|
|
|
|
|
&& handler.craft(guiContainer, (int) Math.min(64, multiplier))) {
|
|
|
|
|
multiplier -= 64;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
craft = multiplier != entry.getValue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (interrupted(guiContainer)) break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (craft) {
|
|
|
|
|
changed = true;
|
|
|
|
|
processed = true;
|
2025-07-11 17:33:14 +03:00
|
|
|
iterator.updateInventory(getInventoryItems(guiContainer));
|
2025-04-24 18:48:40 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} while (changed && !interrupted(guiContainer));
|
|
|
|
|
|
2025-07-11 17:33:14 +03:00
|
|
|
StackInfo.pauseItemDamageSound(false);
|
2025-07-08 16:41:42 +03:00
|
|
|
|
2025-04-24 18:48:40 +03:00
|
|
|
if (processed && !changed && !interrupted(guiContainer)) {
|
|
|
|
|
NEIClientUtils.playClickSound();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void clearTasks() {
|
|
|
|
|
super.clearTasks();
|
|
|
|
|
AutoCraftingManager.math = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean interrupted(GuiContainer guiContainer) {
|
|
|
|
|
return interrupted() || guiContainer != NEIClientUtils.getGuiContainer();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<BookmarkItem> prepareInitialItems(RecipeChainMath math, ItemStackAmount inventory) {
|
|
|
|
|
final List<BookmarkItem> initialItems = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
for (BookmarkItem item : math.initialItems) {
|
|
|
|
|
final long invStackSize = inventory.getOrDefault(item.itemStack, 0L);
|
|
|
|
|
final long amount = Math.max(0, item.amount - invStackSize * item.fluidCellAmount);
|
|
|
|
|
if (amount > 0) {
|
|
|
|
|
initialItems.add(item.copyWithAmount(amount));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return initialItems;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
private AutoCraftingManager() {}
|
|
|
|
|
|
|
|
|
|
public static void runProcessing(RecipeChainMath math) {
|
|
|
|
|
task.stop();
|
|
|
|
|
AutoCraftingManager.math = math;
|
|
|
|
|
|
|
|
|
|
if (AutoCraftingManager.math != null) {
|
2025-07-01 13:52:46 +03:00
|
|
|
ItemPanels.bookmarkPanel.clearTooltips();
|
2025-06-22 18:49:20 +03:00
|
|
|
math.createMasterRoot();
|
2025-04-24 18:48:40 +03:00
|
|
|
task.restart();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static boolean processing() {
|
|
|
|
|
return AutoCraftingManager.math != null && !task.interrupted();
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-11 17:33:14 +03:00
|
|
|
public static ItemStackAmount getInventoryItems(GuiContainer guiContainer) {
|
|
|
|
|
final ItemStackAmount inventory = new ItemStackAmount();
|
|
|
|
|
|
|
|
|
|
for (Slot slot : guiContainer.inventorySlots.inventorySlots) {
|
|
|
|
|
if (slot.getHasStack() && !(slot instanceof SlotCrafting) && slot.canTakeStack(guiContainer.mc.thePlayer)) {
|
|
|
|
|
inventory.add(slot.getStack());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return inventory;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-24 18:48:40 +03:00
|
|
|
}
|