mirror of
https://github.com/GTNewHorizons/NotEnoughItems.git
synced 2026-11-15 01:34:42 +00:00
Compare commits
17
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43c12cd5c8 | ||
|
|
2c3f2cf5ec | ||
|
|
0714c185a3 | ||
|
|
03c84a5e16 | ||
|
|
6f3ae8b464 | ||
|
|
897b7ca60e | ||
|
|
679ed6dd53 | ||
|
|
d5c3552a9a | ||
|
|
167d6fdec5 | ||
|
|
080e49e2bb | ||
|
|
85d6247e13 | ||
|
|
06e72d4f2a | ||
|
|
a0c5afdbd4 | ||
|
|
983e921f04 | ||
|
|
b207292894 | ||
|
|
4c58e88577 | ||
|
|
b1178879c7 |
No files matched your search
@@ -207,11 +207,11 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean addRecipe(Recipe recipe, int groupId) {
|
||||
public boolean addRecipe(Recipe recipe, int multiplier, int groupId) {
|
||||
final RecipeId recipeId = recipe.getRecipeId();
|
||||
|
||||
if (recipe != null && this.grid.getGroup(groupId) != null && !this.grid.existsRecipe(recipeId, groupId)) {
|
||||
this.grid.addRecipe(recipe, groupId);
|
||||
this.grid.addRecipe(recipe, multiplier, groupId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
if (item instanceof Recipe recipe) {
|
||||
|
||||
if (uniqueRecipe.add(recipe.getRecipeId())) {
|
||||
this.grid.addRecipe(recipe, groupId);
|
||||
this.grid.addRecipe(recipe, 1, groupId);
|
||||
}
|
||||
|
||||
} else if (item instanceof RecipeId recipeId) {
|
||||
@@ -305,18 +305,20 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
final RecipeId recipeId = slot.getRecipeId();
|
||||
final BookmarkGroup group = slot.getGroup();
|
||||
|
||||
if (recipeId == null || !removeFullRecipe) {
|
||||
this.grid.removeRecipe(slot.itemIndex, removeFullRecipe);
|
||||
if (group.crafting != null && group.collapsed) {
|
||||
|
||||
if (!removeFullRecipe) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.grid.removeGroup(groupId);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (group.crafting != null && group.collapsed && removeFullRecipe) {
|
||||
this.grid.removeGroup(groupId);
|
||||
return true;
|
||||
} else if (group.crafting != null) {
|
||||
if (recipeId != null && group.crafting != null) {
|
||||
Set<RecipeId> recipes = group.crafting.recipeRelations.getOrDefault(recipeId, Collections.emptySet());
|
||||
|
||||
if (removeFullRecipe && recipes.isEmpty()) {
|
||||
if (recipes.isEmpty()) {
|
||||
for (Map.Entry<RecipeId, Set<RecipeId>> entry : group.crafting.recipeRelations.entrySet()) {
|
||||
if (entry.getValue().contains(recipeId)) {
|
||||
recipes = entry.getValue();
|
||||
@@ -326,8 +328,12 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
}
|
||||
|
||||
if (!recipes.isEmpty()) {
|
||||
boolean removed = false;
|
||||
|
||||
if (!removeFullRecipe) {
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean removed = false;
|
||||
for (RecipeId relRecipeId : recipes) {
|
||||
removed = this.grid.removeRecipe(relRecipeId, groupId) || removed;
|
||||
}
|
||||
@@ -336,6 +342,11 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
}
|
||||
}
|
||||
|
||||
if (recipeId == null || !removeFullRecipe) {
|
||||
this.grid.removeRecipe(slot.itemIndex, removeFullRecipe);
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.grid.removeRecipe(recipeId, groupId);
|
||||
}
|
||||
|
||||
@@ -435,7 +446,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
protected int resizeHeader(GuiContainer gui) {
|
||||
final LayoutStyleMinecraft layout = (LayoutStyleMinecraft) LayoutManager.getLayoutStyle();
|
||||
final int rows = (int) Math.ceil((double) layout.buttonCount / layout.numButtons);
|
||||
final int diff = rows * 19 + getMarginTop(gui) - y;
|
||||
final int diff = rows * 19 + PADDING - y;
|
||||
|
||||
if (diff > 0) {
|
||||
y += diff;
|
||||
@@ -493,24 +504,31 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
}
|
||||
}
|
||||
|
||||
protected String getPositioningSettingName() {
|
||||
return "world.panels.bookmarks";
|
||||
}
|
||||
public Rectangle4i calculateBounds() {
|
||||
final GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
final int width = (gui.width - gui.xSize) / 2 - PADDING * 2;
|
||||
final Rectangle4i bounds = new Rectangle4i(
|
||||
PADDING,
|
||||
PADDING,
|
||||
(gui.width - 176) / 2 - PADDING * 2,
|
||||
gui.height - PADDING * 2);
|
||||
|
||||
public int getMarginLeft(GuiContainer gui) {
|
||||
return PADDING;
|
||||
}
|
||||
int paddingLeft = (int) Math
|
||||
.ceil(bounds.w * NEIClientConfig.getSetting("world.panels.bookmarks.left").getIntValue() / 100000.0);
|
||||
int paddingTop = (int) Math
|
||||
.ceil(bounds.h * NEIClientConfig.getSetting("world.panels.bookmarks.top").getIntValue() / 100000.0);
|
||||
int paddingRight = (int) Math
|
||||
.ceil(bounds.w * NEIClientConfig.getSetting("world.panels.bookmarks.right").getIntValue() / 100000.0);
|
||||
int paddingBottom = (int) Math
|
||||
.ceil(bounds.h * NEIClientConfig.getSetting("world.panels.bookmarks.bottom").getIntValue() / 100000.0);
|
||||
|
||||
public int getMarginTop(GuiContainer gui) {
|
||||
return PADDING;
|
||||
}
|
||||
bounds.h = Math.max(ItemsGrid.SLOT_SIZE, bounds.h - paddingTop - paddingBottom);
|
||||
bounds.y = bounds.y + Math.min(paddingTop, bounds.h - ItemsGrid.SLOT_SIZE);
|
||||
|
||||
public int getWidth(GuiContainer gui) {
|
||||
return gui.width - (gui.xSize + gui.width) / 2 - PADDING * 2;
|
||||
}
|
||||
bounds.w = Math.max(ItemsGrid.SLOT_SIZE, Math.min(bounds.w - paddingLeft - paddingRight, width - paddingLeft));
|
||||
bounds.x = bounds.x + Math.min(paddingLeft, bounds.w - ItemsGrid.SLOT_SIZE);
|
||||
|
||||
public int getHeight(GuiContainer gui) {
|
||||
return gui.height - getMarginTop(gui) - PADDING;
|
||||
return bounds;
|
||||
}
|
||||
|
||||
protected ItemStack getDraggedStackWithQuantity(ItemStack itemStack) {
|
||||
@@ -1195,7 +1213,10 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
&& !handlerName.isEmpty()
|
||||
&& ingredients != null
|
||||
&& !ingredients.isEmpty()) {
|
||||
addRecipe(Recipe.of(Arrays.asList(stack), handlerName, ingredients), BookmarkGrid.DEFAULT_GROUP_ID);
|
||||
addRecipe(
|
||||
Recipe.of(Arrays.asList(stack), handlerName, ingredients),
|
||||
saveSize ? 1 : 0,
|
||||
BookmarkGrid.DEFAULT_GROUP_ID);
|
||||
} else {
|
||||
addItem(stack, saveSize);
|
||||
}
|
||||
@@ -1209,7 +1230,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
|
||||
@Deprecated
|
||||
public void addRecipe(BookmarkRecipe recipe, boolean saveSize, int groupId) {
|
||||
addRecipe(recipe.getRecipe(), groupId);
|
||||
addRecipe(recipe.getRecipe(), saveSize ? 1 : 0, groupId);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
||||
@@ -244,7 +244,7 @@ public class FavoriteRecipes {
|
||||
try (FileOutputStream output = new FileOutputStream(favoriteFile)) {
|
||||
IOUtils.writeLines(strings, "\n", output, StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Filed to save favorites list to file {}", favoriteFile, e);
|
||||
NEIClientConfig.logger.error("Failed to save favorites list to file {}", favoriteFile, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -293,7 +293,7 @@ public class ItemList {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void execute() {
|
||||
if (!NEIClientConfig.isEnabled()) return;
|
||||
if (!NEIClientConfig.isEnabled() || NEIClientUtils.mc().thePlayer == null) return;
|
||||
|
||||
ThreadOperationTimer timer = getTimer(NEIClientConfig.getItemLoadingTimeout());
|
||||
LayoutManager.itemsLoaded = true;
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.ItemsPanelGrid.ItemsPanelGridSlot;
|
||||
import codechicken.nei.util.NEIMouseUtils;
|
||||
|
||||
@@ -108,24 +109,31 @@ public class ItemPanel extends PanelWidget<ItemsPanelGrid> {
|
||||
return String.format("%d/%d", getPage(), Math.max(1, getNumPages()));
|
||||
}
|
||||
|
||||
protected String getPositioningSettingName() {
|
||||
return "world.panels.items";
|
||||
}
|
||||
public Rectangle4i calculateBounds() {
|
||||
final GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
final int width = (gui.width - gui.xSize) / 2 - PADDING * 2;
|
||||
final Rectangle4i bounds = new Rectangle4i(
|
||||
(gui.width + gui.xSize) / 2 + PADDING,
|
||||
PADDING,
|
||||
(gui.width - 176) / 2 - PADDING * 2,
|
||||
gui.height - PADDING * 2);
|
||||
|
||||
public int getMarginLeft(GuiContainer gui) {
|
||||
return (gui.width + gui.xSize) / 2 + PADDING;
|
||||
}
|
||||
int paddingLeft = (int) Math
|
||||
.ceil(bounds.w * NEIClientConfig.getSetting("world.panels.items.left").getIntValue() / 100000.0);
|
||||
int paddingTop = (int) Math
|
||||
.ceil(bounds.h * NEIClientConfig.getSetting("world.panels.items.top").getIntValue() / 100000.0);
|
||||
int paddingRight = (int) Math
|
||||
.ceil(bounds.w * NEIClientConfig.getSetting("world.panels.items.right").getIntValue() / 100000.0);
|
||||
int paddingBottom = (int) Math
|
||||
.ceil(bounds.h * NEIClientConfig.getSetting("world.panels.items.bottom").getIntValue() / 100000.0);
|
||||
|
||||
public int getMarginTop(GuiContainer gui) {
|
||||
return PADDING;
|
||||
}
|
||||
bounds.h = Math.max(ItemsGrid.SLOT_SIZE, bounds.h - paddingTop - paddingBottom);
|
||||
bounds.y = bounds.y + Math.min(paddingTop, bounds.h - ItemsGrid.SLOT_SIZE);
|
||||
|
||||
public int getWidth(GuiContainer gui) {
|
||||
return gui.width - (gui.xSize + gui.width) / 2 - PADDING * 2;
|
||||
}
|
||||
bounds.w = Math.max(ItemsGrid.SLOT_SIZE, Math.min(bounds.w - paddingLeft - paddingRight, width - paddingRight));
|
||||
bounds.x = bounds.x + Math.max(0, width - bounds.w - paddingRight);
|
||||
|
||||
public int getHeight(GuiContainer gui) {
|
||||
return gui.height - getMarginTop(gui) - PADDING;
|
||||
return bounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,6 +4,8 @@ import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
/**
|
||||
* Good old down/held/up keystate tracker
|
||||
*/
|
||||
@@ -26,7 +28,7 @@ public class KeyManager {
|
||||
|
||||
public static void tickKeyStates() {
|
||||
for (Entry<String, KeyState> entry : keyStates.entrySet()) {
|
||||
final boolean down = NEIClientConfig.isKeyHashDown(entry.getKey());
|
||||
final boolean down = Keyboard.isKeyDown(NEIClientConfig.getKeyBinding(entry.getKey()));
|
||||
final KeyState state = entry.getValue();
|
||||
|
||||
if (down) {
|
||||
|
||||
@@ -52,7 +52,7 @@ public class LayoutStyleMinecraft extends LayoutStyle {
|
||||
public void layout(GuiContainer gui, VisiblityData visiblity) {
|
||||
reset();
|
||||
|
||||
leftSize = ItemPanels.bookmarkPanel.getWidth(gui);
|
||||
leftSize = (gui.width - gui.xSize) / 2 - 4;
|
||||
numButtons = Math.max(leftSize / 20, 1);
|
||||
|
||||
LayoutManager.delete.state = 0x4;
|
||||
|
||||
@@ -390,6 +390,8 @@ public class NEIClientConfig {
|
||||
});
|
||||
tag.getTag("inventory.hotkeysHelpText").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.hotkeysHelpText", true));
|
||||
tag.getTag("inventory.showHotkeys").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.showHotkeys", true));
|
||||
|
||||
tag.getTag("loadPluginsInParallel").getBooleanValue(true);
|
||||
tag.getTag("itemLoadingTimeout").getIntValue(500);
|
||||
@@ -743,6 +745,7 @@ public class NEIClientConfig {
|
||||
API.addHashBind("gui.hide", Keyboard.KEY_O);
|
||||
API.addHashBind("gui.search", Keyboard.KEY_F);
|
||||
API.addKeyBind("gui.bookmark", Keyboard.KEY_A);
|
||||
API.addHashBind("gui.favorite", Keyboard.KEY_F + NEIClientUtils.SHIFT_HASH);
|
||||
API.addHashBind("gui.remove_recipe", Keyboard.KEY_A + NEIClientUtils.SHIFT_HASH);
|
||||
API.addKeyBind("gui.bookmark_pull_items", Keyboard.KEY_V);
|
||||
API.addKeyBind("gui.overlay", Keyboard.KEY_S);
|
||||
@@ -857,7 +860,7 @@ public class NEIClientConfig {
|
||||
final int hash = getKeyBinding(string);
|
||||
|
||||
if (hash != Keyboard.CHAR_NONE && Keyboard.getEventKeyState()) {
|
||||
return KeyManager.keyStates.containsKey(string) ? hash == Keyboard.getEventKey()
|
||||
return KeyManager.keyStates.containsKey(string) ? Keyboard.isKeyDown(hash)
|
||||
: hash == NEIClientUtils.getKeyHash();
|
||||
}
|
||||
|
||||
@@ -921,6 +924,7 @@ public class NEIClientConfig {
|
||||
});
|
||||
|
||||
RecipeCatalysts.loadCatalystInfo();
|
||||
SubsetWidget.loadCustomSubsets();
|
||||
SubsetWidget.loadHidden();
|
||||
CollapsibleItems.load();
|
||||
ItemSorter.loadConfig();
|
||||
|
||||
@@ -20,6 +20,7 @@ import codechicken.nei.api.IInfiniteItemHandler;
|
||||
import codechicken.nei.api.INEIGuiHandler;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
import codechicken.nei.commands.CommandBookmarkAdd;
|
||||
import codechicken.nei.commands.CommandRecipeId;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.guihook.IContainerInputHandler;
|
||||
import codechicken.nei.guihook.IContainerSlotClickHandler;
|
||||
@@ -66,6 +67,7 @@ public class NEIController implements IContainerSlotClickHandler, IContainerInpu
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static void registerClientCommands() {
|
||||
ClientCommandHandler.instance.registerCommand(new CommandBookmarkAdd());
|
||||
ClientCommandHandler.instance.registerCommand(new CommandRecipeId());
|
||||
}
|
||||
|
||||
public static void updateUnlimitedItems(InventoryPlayer inventory) {
|
||||
|
||||
@@ -84,44 +84,15 @@ public abstract class PanelWidget<T extends ItemsGrid<? extends ItemsGridSlot, ?
|
||||
|
||||
public abstract String getLabelText();
|
||||
|
||||
protected abstract String getPositioningSettingName();
|
||||
|
||||
public abstract int getMarginLeft(GuiContainer gui);
|
||||
|
||||
public abstract int getMarginTop(GuiContainer gui);
|
||||
|
||||
public abstract int getWidth(GuiContainer gui);
|
||||
|
||||
public abstract int getHeight(GuiContainer gui);
|
||||
public abstract Rectangle4i calculateBounds();
|
||||
|
||||
public void resize(GuiContainer gui) {
|
||||
final Rectangle4i margin = new Rectangle4i(
|
||||
getMarginLeft(gui),
|
||||
getMarginTop(gui),
|
||||
getWidth(gui),
|
||||
getHeight(gui));
|
||||
final Rectangle4i bounds = calculateBounds();
|
||||
|
||||
final String settingName = getPositioningSettingName();
|
||||
int paddingLeft = (int) Math
|
||||
.ceil(margin.w * NEIClientConfig.getSetting(settingName + ".left").getIntValue() / 100000.0);
|
||||
int paddingTop = (int) Math
|
||||
.ceil(margin.h * NEIClientConfig.getSetting(settingName + ".top").getIntValue() / 100000.0);
|
||||
int paddingRight = (int) Math
|
||||
.ceil(margin.w * NEIClientConfig.getSetting(settingName + ".right").getIntValue() / 100000.0);
|
||||
int paddingBottom = (int) Math
|
||||
.ceil(margin.h * NEIClientConfig.getSetting(settingName + ".bottom").getIntValue() / 100000.0);
|
||||
|
||||
int deltaHeight = Math.min(0, margin.h - paddingTop - paddingBottom - ItemsGrid.SLOT_SIZE) / 2;
|
||||
|
||||
paddingLeft = Math.min(paddingLeft, Math.max(0, margin.w - paddingRight - ItemsGrid.SLOT_SIZE));
|
||||
paddingRight = Math.min(paddingRight, Math.max(0, margin.w - paddingLeft - ItemsGrid.SLOT_SIZE));
|
||||
paddingTop = Math.min(margin.h - ItemsGrid.SLOT_SIZE, Math.max(0, paddingTop + deltaHeight));
|
||||
paddingBottom = Math.min(margin.h - paddingTop - ItemsGrid.SLOT_SIZE, Math.max(0, paddingBottom - deltaHeight));
|
||||
|
||||
x = margin.x + paddingLeft;
|
||||
y = margin.y + paddingTop;
|
||||
w = margin.w - paddingLeft - paddingRight;
|
||||
h = margin.h - paddingTop - paddingBottom;
|
||||
x = bounds.x;
|
||||
y = bounds.y;
|
||||
w = bounds.w;
|
||||
h = bounds.h;
|
||||
|
||||
final int header = resizeHeader(gui);
|
||||
final int footer = resizeFooter(gui);
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import codechicken.core.CommonUtils;
|
||||
import codechicken.nei.SubsetWidget.SubsetTag;
|
||||
import codechicken.nei.api.API;
|
||||
import codechicken.nei.api.IRecipeFilter;
|
||||
import codechicken.nei.api.IRecipeFilter.IRecipeFilterProvider;
|
||||
@@ -33,6 +34,7 @@ import codechicken.nei.util.NBTJson;
|
||||
public class PresetsList {
|
||||
|
||||
public enum PresetMode {
|
||||
SUBSET,
|
||||
HIDE,
|
||||
REMOVE,
|
||||
GROUP;
|
||||
@@ -216,6 +218,8 @@ public class PresetsList {
|
||||
if (!preset.items.isEmpty()) {
|
||||
presets.add(preset);
|
||||
}
|
||||
|
||||
updateSubsets();
|
||||
}
|
||||
|
||||
public static void savePresets() {
|
||||
@@ -236,14 +240,29 @@ public class PresetsList {
|
||||
try (FileOutputStream output = new FileOutputStream(presetsFile)) {
|
||||
IOUtils.writeLines(strings, "\n", output, StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Filed to save presets list to file {}", presetsFile, e);
|
||||
NEIClientConfig.logger.error("Failed to save presets list to file {}", presetsFile, e);
|
||||
}
|
||||
|
||||
recipeFilter.cache = null;
|
||||
itemFilter.cache = null;
|
||||
updateSubsets();
|
||||
CollapsibleItems.saveStates();
|
||||
CollapsibleItems.load();
|
||||
LayoutManager.markItemsDirty();
|
||||
}
|
||||
|
||||
private static void updateSubsets() {
|
||||
SubsetWidget.removeTag("Presets");
|
||||
|
||||
for (Preset preset : PresetsList.presets) {
|
||||
if (preset.enabled && preset.mode == PresetMode.SUBSET) {
|
||||
SubsetWidget.addTag(
|
||||
new SubsetTag(
|
||||
"Presets." + preset.name,
|
||||
stack -> preset.items.contains(Preset.getIdentifier(stack))));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
@@ -13,6 +14,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
@@ -23,6 +25,9 @@ import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import codechicken.core.gui.GuiScrollSlot;
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
@@ -35,6 +40,12 @@ import codechicken.nei.api.ItemFilter;
|
||||
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.guihook.IContainerTooltipHandler;
|
||||
import codechicken.nei.recipe.GuiCraftingRecipe;
|
||||
import codechicken.nei.recipe.GuiRecipeTab;
|
||||
import codechicken.nei.recipe.ICraftingHandler;
|
||||
import codechicken.nei.recipe.IRecipeHandler;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.util.NBTJson;
|
||||
import codechicken.nei.util.NEIMouseUtils;
|
||||
|
||||
public class SubsetWidget extends Button implements ItemFilterProvider, IContainerTooltipHandler {
|
||||
@@ -415,6 +426,17 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeTag(String path) {
|
||||
updateState.stop();
|
||||
|
||||
synchronized (tags) {
|
||||
tags.keySet().removeIf(
|
||||
parentpath -> parentpath.equals(path.toLowerCase())
|
||||
|| parentpath.startsWith(path.toLowerCase() + "."));
|
||||
updateHiddenItems();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isHidden(ItemStack item) {
|
||||
try {
|
||||
if (hiddenReadLock.tryLock(5, TimeUnit.SECONDS)) {
|
||||
@@ -535,6 +557,60 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadCustomSubsets() {
|
||||
File dir = new File(NEIClientConfig.configDir, "subsets");
|
||||
|
||||
if (!dir.exists() || !dir.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Stream.of(dir.listFiles()).filter(file -> !file.isDirectory()).forEach(file -> {
|
||||
ClientHandler.loadSettingsFile(
|
||||
"subsets/" + file.getName(),
|
||||
lines -> parseFile(file.getName(), lines.collect(Collectors.toList())));
|
||||
});
|
||||
}
|
||||
|
||||
private static void parseFile(String resource, List<String> itemStrings) {
|
||||
final JsonParser parser = new JsonParser();
|
||||
final String subsetNamespace = resource.substring(0, resource.lastIndexOf('.'));
|
||||
SubsetTag processedTag = new SubsetTag(subsetNamespace, new ItemStackSet());
|
||||
|
||||
for (String itemStr : itemStrings) {
|
||||
try {
|
||||
if (itemStr.startsWith("; ")) {
|
||||
final String handlerName = itemStr.substring(2);
|
||||
String recipeName = handlerName;
|
||||
addTag(processedTag);
|
||||
IRecipeHandler recipeHandler = GuiCraftingRecipe.craftinghandlers.stream()
|
||||
.filter(handler -> handlerName.equals(getHandlerName(handler))).findAny().orElse(null);
|
||||
|
||||
if (recipeHandler == null) {
|
||||
recipeHandler = GuiCraftingRecipe.serialCraftingHandlers.stream()
|
||||
.filter(handler -> handlerName.equals(getHandlerName(handler))).findAny().orElse(null);
|
||||
}
|
||||
|
||||
if (recipeHandler != null) {
|
||||
recipeName = recipeHandler.getRecipeName().trim();
|
||||
}
|
||||
|
||||
processedTag = new SubsetTag(
|
||||
subsetNamespace + "." + recipeName.replace(".", ""),
|
||||
new ItemStackSet());
|
||||
} else {
|
||||
((ItemStackSet) processedTag.filter)
|
||||
.add(StackInfo.loadFromNBT((NBTTagCompound) NBTJson.toNbt(parser.parse(itemStr))));
|
||||
}
|
||||
} catch (IllegalArgumentException | JsonSyntaxException | IllegalStateException e) {
|
||||
NEIClientConfig.logger.error("Failed to load collapsible items from json string:\n{}", itemStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getHandlerName(ICraftingHandler handler) {
|
||||
return GuiRecipeTab.getHandlerInfo(handler).getHandlerName();
|
||||
}
|
||||
|
||||
public static void loadHidden() {
|
||||
final List<ItemStack> itemList = new LinkedList<>();
|
||||
|
||||
|
||||
@@ -24,10 +24,12 @@ import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.SearchField;
|
||||
import codechicken.nei.bookmark.BookmarkGrid;
|
||||
import codechicken.nei.bookmark.BookmarkGroup;
|
||||
import codechicken.nei.bookmark.BookmarkItem;
|
||||
import codechicken.nei.bookmark.BookmarksGridSlot;
|
||||
import codechicken.nei.recipe.AutoCraftingManager;
|
||||
import codechicken.nei.recipe.GuiCraftingRecipe;
|
||||
import codechicken.nei.recipe.GuiFavoriteButton;
|
||||
import codechicken.nei.recipe.GuiRecipe;
|
||||
import codechicken.nei.recipe.GuiUsageRecipe;
|
||||
import codechicken.nei.recipe.Recipe;
|
||||
@@ -112,6 +114,10 @@ public abstract class ShortcutInputHandler {
|
||||
return GuiUsageRecipe.openRecipeGui("item", stackover);
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.favorite")) {
|
||||
return saveFavoriteTree(stackover);
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.bookmark")) {
|
||||
return saveRecipeInBookmark(stackover, NEIClientUtils.shiftKey(), NEIClientUtils.controlKey());
|
||||
}
|
||||
@@ -247,6 +253,25 @@ public abstract class ShortcutInputHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean saveFavoriteTree(ItemStack stackover) {
|
||||
final Point mouse = GuiDraw.getMousePosition();
|
||||
|
||||
if (ItemPanels.itemPanel.contains(mouse.x, mouse.y)
|
||||
|| ItemPanels.itemPanel.historyPanel.contains(mouse.x, mouse.y)) {
|
||||
final RecipeHandlerRef handlerRef = RecipeHandlerRef.of(FavoriteRecipes.getFavorite(stackover));
|
||||
|
||||
if (handlerRef != null) {
|
||||
final GuiFavoriteButton button = new GuiFavoriteButton(handlerRef, 0, 0);
|
||||
button.saveRecipeInBookmark();
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean saveRecipeInBookmark(ItemStack stackover, boolean saveIngredients, boolean saveStackSize) {
|
||||
final Point mousePos = GuiDraw.getMousePosition();
|
||||
|
||||
@@ -262,7 +287,8 @@ public abstract class ShortcutInputHandler {
|
||||
recipe.getIngredients());
|
||||
singleRecipe.setCustomRecipeId(recipe.getRecipeId());
|
||||
|
||||
ItemPanels.bookmarkPanel.addRecipe(singleRecipe, BookmarkGrid.DEFAULT_GROUP_ID);
|
||||
ItemPanels.bookmarkPanel
|
||||
.addRecipe(singleRecipe, saveStackSize ? 1 : 0, BookmarkGrid.DEFAULT_GROUP_ID);
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -378,15 +404,56 @@ public abstract class ShortcutInputHandler {
|
||||
final RecipeId recipeId = getHotkeyRecipeId(gui, mousex, mousey, stack, slot);
|
||||
|
||||
if (slot != null) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark"),
|
||||
NEIClientUtils.translate(slot.isIngredient() ? "bookmark.remove_item" : "bookmark.remove_recipe"));
|
||||
final BookmarkGroup group = slot.getGroup();
|
||||
|
||||
if (slot.isIngredient()) {
|
||||
if (group.crafting != null && group.collapsed) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.remove_recipe"));
|
||||
}
|
||||
NEIClientUtils.translate("bookmark.group.remove_recipe"));
|
||||
} else if (slot.getRecipeId() == null) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark"),
|
||||
NEIClientUtils.translate("bookmark.remove_item"));
|
||||
} else if (group.crafting != null && group.crafting.recipeRelations.entrySet().stream().anyMatch(
|
||||
entry -> entry.getKey().equals(slot.getRecipeId())
|
||||
|| entry.getValue().contains(slot.getRecipeId()))) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.remove_recipe"));
|
||||
} else {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.remove_recipe"));
|
||||
|
||||
if (slot.isIngredient()) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark"),
|
||||
NEIClientUtils.translate("bookmark.remove_item"));
|
||||
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.remove_recipe"));
|
||||
} else {
|
||||
final BookmarkItem item = slot.getBookmarkItem();
|
||||
|
||||
if (ItemPanels.bookmarkPanel.getGrid().createChainItems(groupId).values().stream()
|
||||
.noneMatch(
|
||||
m -> !m.isIngredient && !m.equals(item) && item.equalsRecipe(m))) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark"),
|
||||
NEIClientUtils.translate("bookmark.remove_recipe"));
|
||||
} else {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark"),
|
||||
NEIClientUtils.translate("bookmark.remove_item"));
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.remove_recipe"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (BookmarkContainerInfo.getBookmarkContainerHandler(gui) != null) {
|
||||
hotkeys.put(
|
||||
@@ -407,11 +474,22 @@ public abstract class ShortcutInputHandler {
|
||||
}
|
||||
|
||||
if (recipeId != null) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig
|
||||
.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH + NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("bookmark.add_item_with_recipe_and_count"));
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.add_item_with_recipe"));
|
||||
}
|
||||
|
||||
if ((ItemPanels.itemPanel.contains(mousex, mousey)
|
||||
|| ItemPanels.itemPanel.historyPanel.contains(mousex, mousey)) && FavoriteRecipes.contains(stack)) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.favorite"),
|
||||
NEIClientUtils.translate("recipe.favorite.bookmark_recipe"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
hotkeys.put(NEIClientConfig.getKeyName("gui.recipe"), NEIClientUtils.translate("itempanel.open_crafting"));
|
||||
|
||||
@@ -866,7 +866,7 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
onItemsChanged();
|
||||
}
|
||||
|
||||
public void addRecipe(Recipe recipe, int groupId) {
|
||||
public void addRecipe(Recipe recipe, int multiplier, int groupId) {
|
||||
final RecipeId recipeId = recipe.getRecipeId();
|
||||
final List<ItemStack> results = recipe.getResults().stream().map(res -> res.getItemStack())
|
||||
.collect(Collectors.toList());
|
||||
@@ -874,15 +874,19 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (ItemStack stack : ItemStackAmount.of(results).values()) {
|
||||
this.addItem(BookmarkItem.of(groupId, stack, StackInfo.getAmount(stack), recipeId, false), true);
|
||||
long factor = StackInfo.getAmount(stack);
|
||||
this.addItem(
|
||||
BookmarkItem.of(groupId, StackInfo.withAmount(stack, factor * multiplier), factor, recipeId, false),
|
||||
true);
|
||||
}
|
||||
|
||||
for (ItemStack stack : ItemStackAmount.of(ingredients).values()) {
|
||||
long factor = StackInfo.getAmount(stack);
|
||||
this.addItem(
|
||||
BookmarkItem.of(
|
||||
groupId,
|
||||
stack,
|
||||
StackInfo.getAmount(stack),
|
||||
StackInfo.withAmount(stack, factor * multiplier),
|
||||
factor,
|
||||
recipeId,
|
||||
true,
|
||||
BookmarkItem.generatePermutations(stack, recipe)),
|
||||
@@ -904,7 +908,7 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
|
||||
if (item.recipeId != null && removeFullRecipe) {
|
||||
removeRecipe(item.recipeId, item.groupId);
|
||||
} else {
|
||||
} else if (itemIndex >= 0) {
|
||||
this.bookmarkItems.remove(itemIndex);
|
||||
onItemsChanged();
|
||||
}
|
||||
@@ -1116,16 +1120,16 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
if (item.factor > 0
|
||||
&& outputRecipes.stream().anyMatch(recipeId -> item.equalsRecipe(recipeId, targetGroupId))) {
|
||||
final long multiplier = recipeMultipliers.getOrDefault(item.recipeId, (long) Integer.MAX_VALUE);
|
||||
final boolean isOutputRecipe = group.crafting != null
|
||||
&& !group.crafting.recipeInMiddle.contains(item.recipeId);
|
||||
final boolean recipeInMiddle = group.crafting != null
|
||||
&& group.crafting.recipeInMiddle.contains(item.recipeId);
|
||||
|
||||
recipeMultipliers.put(
|
||||
item.recipeId,
|
||||
Math.min(
|
||||
shiftMultiplier(
|
||||
Math.max(isOutputRecipe ? 1 : 0, item.getMultiplier()),
|
||||
Math.max(recipeInMiddle ? 1 : 0, item.getMultiplier()),
|
||||
shift,
|
||||
isOutputRecipe ? 1 : 0),
|
||||
recipeInMiddle ? 1 : 0),
|
||||
multiplier));
|
||||
items.add(item);
|
||||
}
|
||||
@@ -1148,16 +1152,16 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
} else if (targetItem.recipeId != null) {
|
||||
final RecipeId recipeId = this.gridGenerator.itemToRecipe
|
||||
.getOrDefault(targetItemIndex, targetItem.recipeId);
|
||||
final boolean isOutputRecipe = group.crafting != null && !group.crafting.recipeInMiddle.contains(recipeId);
|
||||
final boolean recipeInMiddle = group.crafting != null && group.crafting.recipeInMiddle.contains(recipeId);
|
||||
long multiplier = Integer.MAX_VALUE;
|
||||
|
||||
for (BookmarkItem item : this.bookmarkItems) {
|
||||
if (item.equalsRecipe(recipeId, targetItem.groupId) && item.factor > 0) {
|
||||
multiplier = Math.min(
|
||||
shiftMultiplier(
|
||||
Math.max(isOutputRecipe ? 1 : 0, item.getMultiplier()),
|
||||
Math.max(recipeInMiddle ? 1 : 0, item.getMultiplier()),
|
||||
shift,
|
||||
isOutputRecipe ? 1 : 0),
|
||||
recipeInMiddle ? 1 : 0),
|
||||
multiplier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,7 +359,7 @@ public class BookmarkStorage {
|
||||
IOUtils.writeLines(strings, "\n", output, StandardCharsets.UTF_8);
|
||||
NEIClientConfig.world.nbt.setTag("bookmark", navigation);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Filed to save bookmarks list to file {}", bookmarkFile, e);
|
||||
NEIClientConfig.logger.error("Failed to save bookmarks list to file {}", bookmarkFile, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -179,9 +179,10 @@ public class RecipeChainDetails {
|
||||
if (itemIndex >= 0 && this.calculatedItems.containsKey(itemIndex)) {
|
||||
final BookmarkItem item = entry.getValue();
|
||||
if (this.recipeInMiddle.contains(item.recipeId)) {
|
||||
this.calculatedItems.get(itemIndex).setRealAmount(item.amount);
|
||||
this.calculatedItems.get(itemIndex)
|
||||
.setRealAmount(Math.max(0, item.factor * (item.getMultiplier() - 1)));
|
||||
} else {
|
||||
this.calculatedItems.get(itemIndex).setRealAmount(Math.max(item.factor, item.amount));
|
||||
this.calculatedItems.get(itemIndex).setRealAmount(item.amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package codechicken.nei.commands;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.ICommand;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.JsonToNBT;
|
||||
@@ -12,7 +11,7 @@ import net.minecraft.util.ChatComponentTranslation;
|
||||
|
||||
import codechicken.nei.ItemPanels;
|
||||
|
||||
public class CommandBookmarkAdd extends CommandBase implements ICommand {
|
||||
public class CommandBookmarkAdd extends CommandBase {
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
|
||||
@@ -0,0 +1,298 @@
|
||||
package codechicken.nei.commands;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
import net.minecraft.util.ChatStyle;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import codechicken.core.CommonUtils;
|
||||
import codechicken.nei.ClientHandler;
|
||||
import codechicken.nei.ItemList;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.recipe.GuiCraftingRecipe;
|
||||
import codechicken.nei.recipe.GuiRecipeTab;
|
||||
import codechicken.nei.recipe.ICraftingHandler;
|
||||
import codechicken.nei.recipe.Recipe;
|
||||
import codechicken.nei.recipe.RecipeHandlerQuery;
|
||||
import codechicken.nei.util.NBTJson;
|
||||
|
||||
public class CommandRecipeId extends CommandBase {
|
||||
|
||||
protected static class ProcessDiffThread extends Thread {
|
||||
|
||||
protected final ICommandSender sender;
|
||||
protected final File prevFile;
|
||||
protected final File currFile;
|
||||
protected final File diffFile;
|
||||
|
||||
public ProcessDiffThread(ICommandSender sender, File prevFile, File currFile, File diffFile) {
|
||||
this.sender = sender;
|
||||
this.prevFile = prevFile;
|
||||
this.currFile = currFile;
|
||||
this.diffFile = diffFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
sendChatInfoMessage(sender, "nei.chat.recipeid.diff.start");
|
||||
|
||||
final Set<String> prevRecipes = loadFileContent(this.prevFile);
|
||||
final Set<String> currRecipes = loadFileContent(this.currFile);
|
||||
final Set<String> notAllowedRecipes = prevRecipes.stream().filter(recipe -> !currRecipes.contains(recipe))
|
||||
.collect(Collectors.toSet());
|
||||
final List<String> subsetsList = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, Set<String>> entry : generateSubsets(notAllowedRecipes).entrySet()) {
|
||||
subsetsList.add("; " + entry.getKey());
|
||||
subsetsList.addAll(entry.getValue());
|
||||
}
|
||||
|
||||
saveFile(this.diffFile, subsetsList);
|
||||
saveFile(getFile("not-allowed-recipes"), new ArrayList<>(notAllowedRecipes));
|
||||
|
||||
sendChatInfoMessage(sender, "nei.chat.recipeid.diff.finish");
|
||||
}
|
||||
|
||||
private Set<String> loadFileContent(File file) {
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
return new HashSet<>(IOUtils.readLines(reader));
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to load '{}' file {}", file.getName(), file, e);
|
||||
}
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
private Map<String, Set<String>> generateSubsets(Set<String> notAllowedRecipes) {
|
||||
final JsonParser parser = new JsonParser();
|
||||
final Map<String, Set<String>> subsetsBuilder = new HashMap<>();
|
||||
|
||||
for (String recipeStr : notAllowedRecipes) {
|
||||
try {
|
||||
final NBTTagCompound nbtRecipe = (NBTTagCompound) NBTJson.toNbt(parser.parse(recipeStr));
|
||||
|
||||
if (nbtRecipe.hasKey("result")) {
|
||||
final NBTTagCompound nbtStack = nbtRecipe.getCompoundTag("result");
|
||||
nbtStack.removeTag("Count");
|
||||
subsetsBuilder.computeIfAbsent(nbtRecipe.getString("handlerName"), rn -> new HashSet<>())
|
||||
.add(NBTJson.toJson(nbtStack));
|
||||
} else {
|
||||
NEIClientConfig.logger.error("Found Broken RecipeId {}", recipeStr);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
NEIClientConfig.logger.error("Found Broken RecipeId {}", recipeStr, ex);
|
||||
}
|
||||
}
|
||||
|
||||
return subsetsBuilder;
|
||||
}
|
||||
|
||||
private void saveFile(File file, List<String> content) {
|
||||
try (FileOutputStream output = new FileOutputStream(file)) {
|
||||
IOUtils.writeLines(content, "\n", output, StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to save recipeid diff list to file {}", file, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class ProcessDumpThread extends Thread {
|
||||
|
||||
private ArrayList<ICraftingHandler> craftinghandlers = new ArrayList<>();
|
||||
private ArrayList<ICraftingHandler> serialCraftingHandlers = new ArrayList<>();
|
||||
protected final ICommandSender sender;
|
||||
protected final File currFile;
|
||||
|
||||
public ProcessDumpThread(ICommandSender sender, File currFile) {
|
||||
this.sender = sender;
|
||||
this.currFile = currFile;
|
||||
ClientHandler.loadSettingsFile("recipeidblacklist.cfg", lines -> {
|
||||
final Set<String> names = lines.collect(Collectors.toSet());
|
||||
|
||||
this.craftinghandlers = GuiCraftingRecipe.craftinghandlers.stream()
|
||||
.filter(h -> !names.contains(GuiRecipeTab.getHandlerInfo(h).getHandlerName()))
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
this.serialCraftingHandlers = GuiCraftingRecipe.serialCraftingHandlers.stream()
|
||||
.filter(h -> !names.contains(GuiRecipeTab.getHandlerInfo(h).getHandlerName()))
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
NEIClientConfig.logger.info("Start processing recipe handlers!");
|
||||
sendChatInfoMessage(sender, "nei.chat.recipeid.dump.start");
|
||||
|
||||
try {
|
||||
if (!this.currFile.exists()) this.currFile.createNewFile();
|
||||
|
||||
final PrintWriter recipes = new PrintWriter(this.currFile);
|
||||
int total = ItemList.items.size();
|
||||
int count = 0;
|
||||
|
||||
for (ItemStack stack : ItemList.items) {
|
||||
|
||||
if ((count % 100) == 0) {
|
||||
NEIClientConfig.logger.info(
|
||||
"({}/{}). Processing {} crafting recipes...",
|
||||
count++,
|
||||
total,
|
||||
stack.getDisplayName());
|
||||
}
|
||||
|
||||
count++;
|
||||
|
||||
for (ICraftingHandler handler : getCraftingHandlers(stack)) {
|
||||
for (int index = 0; index < handler.numRecipes(); index++) {
|
||||
try {
|
||||
final Recipe recipe = Recipe.of(handler, index);
|
||||
if (recipe != null
|
||||
&& (!recipe.getIngredients().isEmpty() && !recipe.getResults().isEmpty())) {
|
||||
recipes.println(NBTJson.toJson(recipe.getRecipeId().toJsonObject()));
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
NEIClientConfig.logger.error(
|
||||
"Found Broken RecipeId {}:{}",
|
||||
GuiRecipeTab.getHandlerInfo(handler).getHandlerName(),
|
||||
stack,
|
||||
ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recipes.close();
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.error("Error dumping RecipeId", e);
|
||||
}
|
||||
|
||||
NEIClientConfig.logger.info("Finished processing recipe handlers!");
|
||||
sendChatInfoMessage(sender, "nei.chat.recipeid.dump.finish");
|
||||
}
|
||||
|
||||
private ArrayList<ICraftingHandler> getCraftingHandlers(Object... results) {
|
||||
return new RecipeHandlerQuery<>(
|
||||
h -> h.getRecipeHandler("item", results),
|
||||
this.craftinghandlers,
|
||||
this.serialCraftingHandlers,
|
||||
"Error while looking up crafting recipe",
|
||||
"outputId: item",
|
||||
"results: " + Arrays.toString(results))
|
||||
.runWithProfiling(NEIClientUtils.translate("recipe.concurrent.crafting"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "recipeid";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandUsage(ICommandSender sender) {
|
||||
return "/recipeid dump <filename> OR /recipeid diff <prev-filename> <curr-filename> [subset name]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRequiredPermissionLevel() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) {
|
||||
final String command = args.length == 0 ? null : args[0];
|
||||
|
||||
if ("dump".equals(command)) {
|
||||
processDumpCommand(sender, args);
|
||||
} else if ("diff".equals(command)) {
|
||||
processDiffCommand(sender, args);
|
||||
} else {
|
||||
sendChatErrorMessage(sender, getCommandUsage(sender));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void processDiffCommand(ICommandSender sender, String[] args) {
|
||||
|
||||
if (args.length > 4) {
|
||||
sendChatErrorMessage(sender, "nei.chat.recipeid.many_params", getCommandUsage(sender));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length < 3) {
|
||||
sendChatErrorMessage(sender, getCommandUsage(sender));
|
||||
return;
|
||||
}
|
||||
|
||||
final File prevFilename = getFile(args[1]);
|
||||
final File currFilename = getFile(args[2]);
|
||||
final File diffFilename = getFile(args.length > 3 ? args[3] : "changelog");
|
||||
|
||||
if (!prevFilename.exists()) {
|
||||
sendChatErrorMessage(sender, "nei.chat.recipeid.not_found", prevFilename.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!currFilename.exists()) {
|
||||
sendChatErrorMessage(sender, "nei.chat.recipeid.not_found", currFilename.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
(new ProcessDiffThread(sender, prevFilename, currFilename, diffFilename)).start();
|
||||
}
|
||||
|
||||
protected void processDumpCommand(ICommandSender sender, String[] args) {
|
||||
|
||||
if (args.length > 2) {
|
||||
sendChatErrorMessage(sender, "nei.chat.recipeid.many_params", getCommandUsage(sender));
|
||||
return;
|
||||
}
|
||||
|
||||
final File dir = new File(CommonUtils.getMinecraftDir(), "recipeid");
|
||||
final String currFilename = args.length == 2 ? args[1] : "recipeId";
|
||||
if (!dir.exists()) dir.mkdirs();
|
||||
|
||||
(new ProcessDumpThread(sender, getFile(currFilename))).start();
|
||||
}
|
||||
|
||||
private static File getFile(String filename) {
|
||||
return new File(CommonUtils.getMinecraftDir(), "recipeid/" + filename + ".json");
|
||||
}
|
||||
|
||||
private static void sendChatInfoMessage(ICommandSender sender, String translationKey, Object... args) {
|
||||
sender.addChatMessage(
|
||||
new ChatComponentTranslation(translationKey, args)
|
||||
.setChatStyle(new ChatStyle().setColor(EnumChatFormatting.AQUA)));
|
||||
}
|
||||
|
||||
private static void sendChatErrorMessage(ICommandSender sender, String translationKey, Object... args) {
|
||||
sender.addChatMessage(
|
||||
new ChatComponentTranslation(translationKey, args)
|
||||
.setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -160,8 +160,8 @@ public class GuiPanelSettings extends GuiScreenWidget {
|
||||
}
|
||||
|
||||
protected void drawItems() {
|
||||
final int columns = w / ItemsGrid.SLOT_SIZE;
|
||||
final int rows = (h - (PANEL_SIZE + 2) * 2) / ItemsGrid.SLOT_SIZE;
|
||||
final int columns = (w - 2) / ItemsGrid.SLOT_SIZE;
|
||||
final int rows = (h - (PANEL_SIZE + 2) * 2 - 2) / ItemsGrid.SLOT_SIZE;
|
||||
final int paddingLeft = (w % ItemsGrid.SLOT_SIZE) / 2;
|
||||
final List<ItemStack> items = ItemPanels.itemPanel.getItems();
|
||||
if (items.isEmpty()) return;
|
||||
|
||||
@@ -97,7 +97,7 @@ public class HandlerDumper extends DataDumper {
|
||||
}
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Filed to save dump handler list to file {}", file, e);
|
||||
NEIClientConfig.logger.error("Failed to save dump handler list to file {}", file, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -207,6 +207,10 @@ public class GuiPresetList extends GuiOptionPane {
|
||||
modeName = EnumChatFormatting.GOLD + NEIClientUtils.translate("presets.mode.hide.char")
|
||||
+ EnumChatFormatting.RESET;
|
||||
break;
|
||||
case SUBSET:
|
||||
modeName = EnumChatFormatting.DARK_PURPLE + NEIClientUtils.translate("presets.mode.subset.char")
|
||||
+ EnumChatFormatting.RESET;
|
||||
break;
|
||||
case REMOVE:
|
||||
modeName = EnumChatFormatting.RED + NEIClientUtils.translate("presets.mode.remove.char")
|
||||
+ EnumChatFormatting.RESET;
|
||||
|
||||
@@ -86,6 +86,7 @@ public class LeftPanel extends GuiWidget {
|
||||
protected Label modeLabel = new Label(NEIClientUtils.translate("presets.mode"), false);
|
||||
|
||||
protected CheckboxButton modeHide;
|
||||
protected CheckboxButton modeSubset;
|
||||
protected CheckboxButton modeRemove;
|
||||
protected CheckboxButton modeGroup;
|
||||
|
||||
@@ -114,6 +115,19 @@ public class LeftPanel extends GuiWidget {
|
||||
}
|
||||
};
|
||||
|
||||
modeSubset = new CheckboxButton(NEIClientUtils.translate("presets.mode.subset")) {
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return preset.mode == PresetMode.SUBSET;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onChange() {
|
||||
preset.mode = this.checked ? PresetMode.SUBSET : null;
|
||||
}
|
||||
};
|
||||
|
||||
modeRemove = new CheckboxButton(NEIClientUtils.translate("presets.mode.remove")) {
|
||||
|
||||
@Override
|
||||
@@ -164,6 +178,10 @@ public class LeftPanel extends GuiWidget {
|
||||
modeHide.handleClick(x, y, button);
|
||||
}
|
||||
|
||||
if (modeSubset.contains(x, y)) {
|
||||
modeSubset.handleClick(x, y, button);
|
||||
}
|
||||
|
||||
if (modeRemove.contains(x, y)) {
|
||||
modeRemove.handleClick(x, y, button);
|
||||
}
|
||||
@@ -248,7 +266,7 @@ public class LeftPanel extends GuiWidget {
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
int CHECKBOX_WIDTH = (this.width - 12) / 3;
|
||||
int CHECKBOX_WIDTH = (this.width - 12) / 4;
|
||||
nameLabel.x = this.x + 2;
|
||||
nameLabel.y = this.y + 4;
|
||||
nameLabel.w = this.width;
|
||||
@@ -269,12 +287,13 @@ public class LeftPanel extends GuiWidget {
|
||||
modeLabel.w = this.width;
|
||||
modeLabel.h = 10;
|
||||
|
||||
modeHide.w = modeRemove.w = modeGroup.w = CHECKBOX_WIDTH;
|
||||
modeHide.h = modeRemove.h = modeGroup.h = INPUT_HEIGHT;
|
||||
modeHide.y = modeRemove.y = modeGroup.y = modeLabel.y + modeLabel.h;
|
||||
modeHide.w = modeSubset.w = modeRemove.w = modeGroup.w = CHECKBOX_WIDTH;
|
||||
modeHide.h = modeSubset.h = modeRemove.h = modeGroup.h = INPUT_HEIGHT;
|
||||
modeHide.y = modeSubset.y = modeRemove.y = modeGroup.y = modeLabel.y + modeLabel.h;
|
||||
|
||||
modeHide.x = this.x + 1;
|
||||
modeRemove.x = modeHide.x + modeHide.w + 6;
|
||||
modeSubset.x = modeHide.x + modeHide.w + 6;
|
||||
modeRemove.x = modeSubset.x + modeSubset.w + 6;
|
||||
modeGroup.x = modeRemove.x + modeRemove.w + 6;
|
||||
|
||||
grid.setGridSize(
|
||||
@@ -292,6 +311,7 @@ public class LeftPanel extends GuiWidget {
|
||||
|
||||
modeLabel.draw(mousex, mousey);
|
||||
modeHide.draw(mousex, mousey);
|
||||
modeSubset.draw(mousex, mousey);
|
||||
modeRemove.draw(mousex, mousey);
|
||||
modeGroup.draw(mousex, mousey);
|
||||
|
||||
@@ -326,6 +346,8 @@ public class LeftPanel extends GuiWidget {
|
||||
|
||||
} else if (modeHide.contains(mousex, mousey)) {
|
||||
tooltip.add(NEIClientUtils.translate("presets.mode.hide.tip"));
|
||||
} else if (modeSubset.contains(mousex, mousey)) {
|
||||
tooltip.add(NEIClientUtils.translate("presets.mode.subset.tip"));
|
||||
} else if (modeRemove.contains(mousex, mousey)) {
|
||||
tooltip.add(NEIClientUtils.translate("presets.mode.remove.tip"));
|
||||
} else if (modeGroup.contains(mousex, mousey)) {
|
||||
|
||||
@@ -592,7 +592,7 @@ public class GuiContainerManager {
|
||||
|
||||
if (!tooltip.isEmpty()) tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE); // add space after 'title'
|
||||
|
||||
if (showTooltip) {
|
||||
if (showTooltip && NEIClientConfig.getBooleanSetting("inventory.showHotkeys")) {
|
||||
List<String> hotkeystips = collectHotkeyTips(mousex, mousey);
|
||||
|
||||
if (!hotkeystips.isEmpty()) {
|
||||
|
||||
@@ -119,7 +119,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
public void lastKeyTyped(GuiRecipe<?> gui, char keyChar, int keyID) {
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.bookmark") && NEIClientUtils.shiftKey()) {
|
||||
ItemPanels.bookmarkPanel.addGroup(getRecipesTree(getRecipe()), BookmarkViewMode.TODO_LIST, true);
|
||||
saveRecipeInBookmark();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -180,6 +180,10 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void saveRecipeInBookmark() {
|
||||
ItemPanels.bookmarkPanel.addGroup(getRecipesTree(getRecipe()), BookmarkViewMode.TODO_LIST, true);
|
||||
}
|
||||
|
||||
private List<Recipe> getRecipesTree(Recipe mainRecipe) {
|
||||
int depth = NEIClientConfig.getIntSetting("inventory.favorites.depth");
|
||||
final ItemStackSet items = new ItemStackSet();
|
||||
|
||||
@@ -155,6 +155,10 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("recipe.overlay.bookmarkRecipe"));
|
||||
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH + NEIClientUtils.CTRL_HASH),
|
||||
NEIClientUtils.translate("recipe.overlay.bookmarkRecipeAndCount"));
|
||||
|
||||
return hotkeys;
|
||||
}
|
||||
|
||||
@@ -309,7 +313,8 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
final Recipe recipe = getRecipe();
|
||||
|
||||
if (!ItemPanels.bookmarkPanel.removeRecipe(recipe.getRecipeId(), BookmarkGrid.DEFAULT_GROUP_ID)) {
|
||||
ItemPanels.bookmarkPanel.addRecipe(recipe, BookmarkGrid.DEFAULT_GROUP_ID);
|
||||
ItemPanels.bookmarkPanel
|
||||
.addRecipe(recipe, NEIClientUtils.controlKey() ? 1 : 0, BookmarkGrid.DEFAULT_GROUP_ID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,12 @@ package codechicken.nei.recipe;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.FluidContainerRegistry;
|
||||
@@ -36,10 +39,15 @@ public class Recipe {
|
||||
this.result = result != null ? StackInfo.withAmount(result, 0) : null;
|
||||
this.handlerName = handlerName;
|
||||
this.ingredients = ingredients;
|
||||
|
||||
if (!isSharpedRecipe()) {
|
||||
// sort to ignore ingredients position in shapeless recipes
|
||||
Collections.sort(this.ingredients, Comparator.comparing(StackInfo::getItemStackGUID));
|
||||
}
|
||||
}
|
||||
|
||||
public static RecipeId of(Object result, String handlerName, Iterable<?> ingredients) {
|
||||
return new RecipeId(extractItem(result), handlerName, extractItems(ingredients));
|
||||
return new RecipeId(extractItem(result), handlerName, extractIngredients(ingredients));
|
||||
}
|
||||
|
||||
public static RecipeId of(JsonObject json) {
|
||||
@@ -74,14 +82,14 @@ public class Recipe {
|
||||
return new ArrayList<>(this.ingredients);
|
||||
}
|
||||
|
||||
protected static List<ItemStack> extractItems(Iterable<?> items) {
|
||||
protected static List<ItemStack> extractIngredients(Iterable<?> items) {
|
||||
final List<ItemStack> list = new ArrayList<>();
|
||||
|
||||
for (Object item : items) {
|
||||
ItemStack stack = extractItem(item);
|
||||
final ItemStack stack = extractItem(item);
|
||||
|
||||
if (stack != null) {
|
||||
list.add(stack.copy());
|
||||
list.add(prepareIngredient(stack.copy()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,15 +123,56 @@ public class Recipe {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int index = 0; index < stacks.size(); index++) {
|
||||
if (!stacks.get(index).containsWithNBT(ingredients.get(index))) {
|
||||
return false;
|
||||
if (isSharpedRecipe()) {
|
||||
for (int index = 0; index < stacks.size(); index++) {
|
||||
if (!containsWithNBT(stacks.get(index), Arrays.asList(this.ingredients.get(index)))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (PositionedStack pStack : stacks) {
|
||||
if (!containsWithNBT(pStack, this.ingredients)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean containsWithNBT(PositionedStack pStack, List<ItemStack> ingrStacks) {
|
||||
for (ItemStack item : pStack.items) {
|
||||
final ItemStack pItem = prepareIngredient(item);
|
||||
if (ingrStacks.stream().anyMatch(stack -> StackInfo.equalItemAndNBT(pItem, stack, true))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static ItemStack prepareIngredient(ItemStack stack) {
|
||||
|
||||
// hack: remove metadata for "Data Stick"
|
||||
if (stack.hasTagCompound() && stack.getItemDamage() == 32708
|
||||
&& "gregtech:gt.metaitem.01".equals(Item.itemRegistry.getNameForObject(stack.getItem()))) {
|
||||
return new ItemStack(stack.getItem(), stack.getItemDamage());
|
||||
}
|
||||
|
||||
// hack: remove metadata for "Circuit Imprint"
|
||||
if (stack.hasTagCompound() && stack.getItemDamage() == 0
|
||||
&& "bartworks:gt.bwMetaGeneratedItem0"
|
||||
.equals(Item.itemRegistry.getNameForObject(stack.getItem()))) {
|
||||
return new ItemStack(stack.getItem(), stack.getItemDamage());
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
public boolean isSharpedRecipe() {
|
||||
return this.handlerName.equals("codechicken.nei.recipe.ShapedRecipeHandler")
|
||||
|| this.handlerName.equals("fox.spiteful.avaritia.compat.nei.ExtremeShapedRecipeHandler");
|
||||
}
|
||||
|
||||
public JsonObject toJsonObject() {
|
||||
final JsonObject json = new JsonObject();
|
||||
|
||||
@@ -142,8 +191,8 @@ public class Recipe {
|
||||
protected JsonArray convertItemsToJsonArray(List<ItemStack> items) {
|
||||
final JsonArray arr = new JsonArray();
|
||||
|
||||
for (ItemStack nbTag : items) {
|
||||
arr.add(NBTJson.toJsonObject(StackInfo.itemStackToNBT(nbTag)));
|
||||
for (ItemStack stack : items) {
|
||||
arr.add(NBTJson.toJsonObject(StackInfo.itemStackToNBT(stack)));
|
||||
}
|
||||
|
||||
return arr;
|
||||
|
||||
@@ -17,7 +17,7 @@ import codechicken.nei.ItemList;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.util.AsyncTaskProfiler;
|
||||
|
||||
class RecipeHandlerQuery<T extends IRecipeHandler> {
|
||||
public class RecipeHandlerQuery<T extends IRecipeHandler> {
|
||||
|
||||
private final Function<T, T> recipeHandlerFunction;
|
||||
private final List<T> recipeHandlers;
|
||||
@@ -25,15 +25,15 @@ class RecipeHandlerQuery<T extends IRecipeHandler> {
|
||||
private final String[] errorMessage;
|
||||
private boolean error = false;
|
||||
|
||||
RecipeHandlerQuery(Function<T, T> recipeHandlerFunction, List<T> recipeHandlers, List<T> serialRecipeHandlers,
|
||||
String... errorMessage) {
|
||||
public RecipeHandlerQuery(Function<T, T> recipeHandlerFunction, List<T> recipeHandlers,
|
||||
List<T> serialRecipeHandlers, String... errorMessage) {
|
||||
this.recipeHandlerFunction = recipeHandlerFunction;
|
||||
this.recipeHandlers = recipeHandlers;
|
||||
this.serialRecipeHandlers = serialRecipeHandlers;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
ArrayList<T> runWithProfiling(String profilerSection) {
|
||||
public ArrayList<T> runWithProfiling(String profilerSection) {
|
||||
TaskProfiler profiler = ProfilerRecipeHandler.getProfiler();
|
||||
|
||||
// Save the current config state here, as it may be altered
|
||||
|
||||
@@ -30,7 +30,7 @@ public class RecipeHandlerRef {
|
||||
|
||||
public static RecipeHandlerRef of(RecipeId recipeId) {
|
||||
|
||||
if (recipeId.getResult() != null && !recipeId.getIngredients().isEmpty()) {
|
||||
if (recipeId != null && recipeId.getResult() != null && !recipeId.getIngredients().isEmpty()) {
|
||||
return recipeRefCache.computeIfAbsent(recipeId, ri -> {
|
||||
final List<ICraftingHandler> handlers = GuiCraftingRecipe
|
||||
.getCraftingHandlers("recipeId", recipeId.getResult(), recipeId);
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@@ -22,6 +23,7 @@ import codechicken.nei.api.ItemInfo;
|
||||
import codechicken.nei.recipe.stackinfo.DefaultStackStringifyHandler;
|
||||
import codechicken.nei.recipe.stackinfo.GTFluidStackStringifyHandler;
|
||||
import codechicken.nei.util.ItemStackKey;
|
||||
import codechicken.nei.util.NBTHelper;
|
||||
|
||||
public class StackInfo {
|
||||
|
||||
@@ -144,7 +146,7 @@ public class StackInfo {
|
||||
final NBTTagCompound nbTag = itemStackToNBT(stack, false);
|
||||
|
||||
if (nbTag == null) {
|
||||
return null;
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
nbTag.removeTag("Count");
|
||||
@@ -157,9 +159,11 @@ public class StackInfo {
|
||||
nbTag.removeTag("tag");
|
||||
}
|
||||
|
||||
if (nbTag.hasKey("strId") && guidfilters.containsKey(nbTag.getString("strId"))) {
|
||||
if (nbTag.hasKey("strId") && (guidfilters.containsKey(nbTag.getString("strId"))
|
||||
|| guidfilters.containsKey(nbTag.getString("strId") + "&" + nbTag.getShort("Damage")))) {
|
||||
final String strId = nbTag.getString("strId")
|
||||
+ (guidfilters.containsKey(nbTag.getString("strId")) ? "" : "&" + nbTag.getShort("Damage"));
|
||||
final ArrayList<String> keys = new ArrayList<>();
|
||||
final String strId = nbTag.getString("strId");
|
||||
|
||||
keys.add(strId);
|
||||
|
||||
@@ -184,7 +188,7 @@ public class StackInfo {
|
||||
}
|
||||
|
||||
if (local instanceof NBTBase item) {
|
||||
keys.add(item.toString());
|
||||
keys.add(NBTHelper.toString(item));
|
||||
} else if (local != null) {
|
||||
keys.add(String.valueOf(local));
|
||||
}
|
||||
@@ -195,7 +199,7 @@ public class StackInfo {
|
||||
}
|
||||
} else {
|
||||
synchronized (guidcache) {
|
||||
guidcache.put(stack, nbTag.toString());
|
||||
guidcache.put(stack, NBTHelper.toString(nbTag));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,13 +222,17 @@ public class StackInfo {
|
||||
}
|
||||
|
||||
public static ItemStack getItemStackWithMinimumDamage(ItemStack[] stacks) {
|
||||
int damage = Short.MAX_VALUE;
|
||||
ItemStack result = stacks[0];
|
||||
|
||||
if (stacks.length > 1) {
|
||||
for (ItemStack stack : stacks) {
|
||||
if (stack.getItem() != null && !ItemInfo.isHidden(stack) && stack.getItemDamage() < damage) {
|
||||
damage = stack.getItemDamage();
|
||||
// to optimize compare recipes from permutation, an item with a minimum strId and damage is taken so as
|
||||
// not to check everything permutation items
|
||||
if (stack.getItem() != null && !ItemInfo.isHidden(stack)
|
||||
&& (stack.getItemDamage() < result.getItemDamage()
|
||||
|| stack.getItemDamage() == result.getItemDamage()
|
||||
&& Item.itemRegistry.getNameForObject(stack.getItem()).compareTo(
|
||||
Item.itemRegistry.getNameForObject(result.getItem())) == -1)) {
|
||||
result = stack;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,18 +116,18 @@ public class RecipeChainMath {
|
||||
}
|
||||
|
||||
for (Map.Entry<RecipeId, Long> entry : multipliers.entrySet()) {
|
||||
if (!this.outputRecipes.containsKey(entry.getKey()) && this.preferredItems.values().stream()
|
||||
.noneMatch(resItem -> resItem.recipeId.equals(entry.getKey()))) {
|
||||
this.outputRecipes.put(entry.getKey(), entry.getValue());
|
||||
final RecipeId recipeId = entry.getKey();
|
||||
final boolean isOutputRecipe = this.outputRecipes.containsKey(recipeId);
|
||||
final boolean recipeInMiddle = this.preferredItems.values().stream()
|
||||
.anyMatch(resItem -> resItem.recipeId.equals(recipeId));
|
||||
|
||||
if (!isOutputRecipe && !recipeInMiddle) {
|
||||
this.outputRecipes.put(recipeId, entry.getValue());
|
||||
} else if (isOutputRecipe && recipeInMiddle) {
|
||||
this.outputRecipes.put(recipeId, Math.max(0, entry.getValue() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<RecipeId, Long> entry : this.outputRecipes.entrySet()) {
|
||||
if (entry.getValue() == 0 && this.preferredItems.values().stream()
|
||||
.noneMatch(prefItem -> prefItem.recipeId.equals(entry.getKey()))) {
|
||||
entry.setValue(1L);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void collectPreferredItems(RecipeId recipeId, Map<BookmarkItem, BookmarkItem> preferredItems,
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package codechicken.nei.util;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
@@ -52,4 +56,26 @@ public class NBTHelper {
|
||||
private static NBTBase get(NBTTagList tag, int idx) {
|
||||
return idx >= 0 && idx < tag.tagList.size() ? (NBTBase) tag.tagList.get(idx) : null;
|
||||
}
|
||||
|
||||
public static String toString(NBTBase nbt) {
|
||||
|
||||
if (nbt instanceof NBTTagCompound nbtTagCompound) {
|
||||
final Map<String, NBTBase> tagMap = (Map<String, NBTBase>) nbtTagCompound.tagMap;
|
||||
return "{" + tagMap.entrySet().stream().sorted(Map.Entry.<String, NBTBase>comparingByKey())
|
||||
.map(nbtEntry -> nbtEntry.getKey() + ":" + toString(nbtEntry.getValue()))
|
||||
.collect(Collectors.joining(",")) + "}";
|
||||
} else if (nbt instanceof NBTTagList list) {
|
||||
|
||||
if (list.tagList.isEmpty()) {
|
||||
return "[]";
|
||||
} else {
|
||||
final StringJoiner arr = new StringJoiner(",");
|
||||
list.tagList.forEach(c -> arr.add(toString((NBTBase) c)));
|
||||
return "[" + arr.toString() + "]";
|
||||
}
|
||||
|
||||
} else {
|
||||
return nbt.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,12 +43,10 @@ public class NBTJson {
|
||||
// NBTTagCompound
|
||||
final NBTTagCompound nbtTagCompound = (NBTTagCompound) nbt;
|
||||
final Map<String, NBTBase> tagMap = (Map<String, NBTBase>) nbtTagCompound.tagMap;
|
||||
final JsonObject root = new JsonObject();
|
||||
|
||||
JsonObject root = new JsonObject();
|
||||
|
||||
for (Map.Entry<String, NBTBase> nbtEntry : tagMap.entrySet()) {
|
||||
root.add(nbtEntry.getKey(), toJsonObject(nbtEntry.getValue()));
|
||||
}
|
||||
tagMap.entrySet().stream().sorted(Map.Entry.<String, NBTBase>comparingByKey())
|
||||
.forEach(nbtEntry -> { root.add(nbtEntry.getKey(), toJsonObject(nbtEntry.getValue())); });
|
||||
|
||||
return root;
|
||||
} else if (nbt instanceof NBTTagByte) {
|
||||
|
||||
@@ -54,4 +54,5 @@ miscutils:personalHealingDevice
|
||||
tectech:item.em.debugContainer,tag.symbols
|
||||
tinkersdefense:Heater Shield,tag.InfiTool
|
||||
tinkersdefense:Round Shield,tag.InfiTool
|
||||
miscutils:itemCustomMetaCover.miscutils.GtMachineCasings,Damage
|
||||
miscutils:itemCustomMetaCover.miscutils.GtMachineCasings,Damage
|
||||
gregtech:gt.metaitem.01&32708,tag.output
|
||||
@@ -0,0 +1,3 @@
|
||||
# Each line in this file should either be a comment (line starts with '#'), handler name or handler id.
|
||||
# If you delete this file, it will be regenerated with the default handlers list.
|
||||
Unknown
|
||||
@@ -37,6 +37,7 @@ nei.bookmark.remove_recipe=Remove Recipe
|
||||
nei.bookmark.remove_item=Remove Item
|
||||
nei.bookmark.add_item=Add Bookmark
|
||||
nei.bookmark.add_item_with_recipe=Add Bookmark with Recipe
|
||||
nei.bookmark.add_item_with_recipe_and_count=Add Bookmark with Recipe & Count
|
||||
nei.bookmark.add_item_with_count=Add Bookmark with Count
|
||||
nei.bookmark.change_quantity=Change Quantity
|
||||
nei.bookmark.change_quantity_step=Change Quantity with Multiplier
|
||||
@@ -138,6 +139,13 @@ nei.chat.chunkoverlay.3=Chunk Overlay: GT Ore Veins
|
||||
nei.chat.item_link.text=<%s> §6Click to add bookmark: %s
|
||||
nei.chat.bookmark_added.text=Bookmark added!
|
||||
|
||||
nei.chat.recipeid.many_params=Too many parameters! Usage: %s
|
||||
nei.chat.recipeid.not_found=File %s not found!
|
||||
nei.chat.recipeid.diff.start=Start processing recipe diff!
|
||||
nei.chat.recipeid.diff.finish=Finished processing recipe diff!
|
||||
nei.chat.recipeid.dump.start=Start processing recipe handlers!
|
||||
nei.chat.recipeid.dump.finish=Finished processing recipe handlers!
|
||||
|
||||
nei.options=NEI Options
|
||||
nei.options.back=Back
|
||||
nei.options.save=Save
|
||||
@@ -166,8 +174,6 @@ nei.options.keys.gui.prev_machine=Prev Machine
|
||||
nei.options.keys.gui.search=Focus Search Bar
|
||||
nei.options.keys.gui.bookmark=Add Bookmark
|
||||
nei.options.keys.gui.remove_recipe=Remove Group from Bookmarks
|
||||
nei.options.keys.gui.bookmark_recipe=Add Bookmark with Recipe
|
||||
nei.options.keys.gui.bookmark_count=Add Bookmark with Count
|
||||
nei.options.keys.gui.bookmark_pull_items=Pull all Bookmarked Items
|
||||
nei.options.keys.gui.hide_bookmarks=Toggle Bookmark Panel Visibility
|
||||
nei.options.keys.gui.overlay=Fill/Overlay Crafting Grid
|
||||
@@ -242,6 +248,9 @@ nei.options.inventory.favorites.depth=Depth
|
||||
nei.options.inventory.hotkeysHelpText=Show Hotkeys Help Text
|
||||
nei.options.inventory.hotkeysHelpText.true=Yes
|
||||
nei.options.inventory.hotkeysHelpText.false=No
|
||||
nei.options.inventory.showHotkeys=Show Hotkeys
|
||||
nei.options.inventory.showHotkeys.true=Yes
|
||||
nei.options.inventory.showHotkeys.false=No
|
||||
nei.options.inventory.guirecipe=Recipes GUI
|
||||
nei.options.inventory.guirecipe.jeiStyleTabs=JEI Style Tabs
|
||||
nei.options.inventory.guirecipe.jeiStyleTabs.true=Yes
|
||||
@@ -508,6 +517,7 @@ nei.recipe.overlay.mismatch=Mismatch Crafting Grid
|
||||
nei.recipe.overlay.overlayRecipe=Overlay Recipe
|
||||
nei.recipe.overlay.fillCraftingGrid=Fill Crafting Grid
|
||||
nei.recipe.overlay.bookmarkRecipe=Save with Recipe
|
||||
nei.recipe.overlay.bookmarkRecipeAndCount=Save with Recipe & Count
|
||||
|
||||
nei.recipe.favorite=Favorite
|
||||
nei.recipe.favorite.bookmark_recipe=Save Recipe Tree
|
||||
@@ -572,6 +582,9 @@ nei.presets.mode=Mode
|
||||
nei.presets.mode.hide=Hide
|
||||
nei.presets.mode.hide.char=H
|
||||
nei.presets.mode.hide.tip=Hide items in panel
|
||||
nei.presets.mode.subset=Subset
|
||||
nei.presets.mode.subset.char=S
|
||||
nei.presets.mode.subset.tip=Create custom subsets
|
||||
nei.presets.mode.remove=Remove
|
||||
nei.presets.mode.remove.tip=Hide items in panel and their recipes
|
||||
nei.presets.mode.remove.char=R
|
||||
|
||||
Reference in new issue
Block a user