mirror of
https://github.com/GTNewHorizons/NotEnoughItems.git
synced 2026-10-26 14:24:07 +00:00
Bookmarks Improvements (#174)
* Add Drag&Drop (sorting items) in bookmarks * save recipes in bookmarks * Add possibility to extend bookmarks save/restore functions; in future supports GT++ fluids * change items sorting algorithm * add NBT support for different bookmarks * change saving recipe algorithm * save correct number type in bookmarks.ini Co-authored-by: Serghei Borovetchi <sborovetchi@estatim.com>
This commit is contained in:
1 parent
492c99b8e3
commit
b6070dd508
14 files changed
+640
-75
No files matched your search
@@ -117,6 +117,12 @@ nei.options.inventory.jei_style_tabs.false=No [Weirdo]
|
||||
nei.options.inventory.jei_style_item_presence_overlay=JEI Style Item Overlay on ?-Hover
|
||||
nei.options.inventory.jei_style_item_presence_overlay.true=Yes
|
||||
nei.options.inventory.jei_style_item_presence_overlay.false=No
|
||||
nei.options.inventory.saveCurrentRecipeInBookmarksEnabled=Save Current Recipe in Bookmarks
|
||||
nei.options.inventory.saveCurrentRecipeInBookmarksEnabled.true=Enabled
|
||||
nei.options.inventory.saveCurrentRecipeInBookmarksEnabled.false=Disabled
|
||||
nei.options.inventory.useNBTInBookmarks=Use NBT in Bookmarks
|
||||
nei.options.inventory.useNBTInBookmarks.true=Yes
|
||||
nei.options.inventory.useNBTInBookmarks.false=No
|
||||
nei.options.inventory.creative_tab_style=Creative or JEI tab style
|
||||
nei.options.inventory.creative_tab_style.true=Creative
|
||||
nei.options.inventory.creative_tab_style.false=JEI
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import codechicken.nei.util.NBTJson;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.recipe.BookmarkRecipeId;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import cpw.mods.fml.common.registry.GameData;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
@@ -23,6 +27,10 @@ import java.util.List;
|
||||
*/
|
||||
public class BookmarkPanel extends ItemPanel {
|
||||
|
||||
protected ArrayList<BookmarkRecipeId> _recipes = new ArrayList<>();
|
||||
protected boolean bookmarksIsLoaded = false;
|
||||
public int sortedStackIndex = -1;
|
||||
|
||||
public void init() {
|
||||
super.init();
|
||||
}
|
||||
@@ -36,55 +44,102 @@ public class BookmarkPanel extends ItemPanel {
|
||||
return super.getLabelText() + " [" + realItems.size() + "]";
|
||||
}
|
||||
|
||||
public void addOrRemoveItem(ItemStack item) {
|
||||
ItemStack normalized = normalize(item);
|
||||
if(!remove(normalized)) {
|
||||
public void addOrRemoveItem(ItemStack item)
|
||||
{
|
||||
addOrRemoveItem(item, null);
|
||||
}
|
||||
|
||||
public void addOrRemoveItem(ItemStack item, BookmarkRecipeId recipeId)
|
||||
{
|
||||
loadBookmarksIfNeeded();
|
||||
|
||||
ItemStack normalized = StackInfo.normalize(item);
|
||||
|
||||
if (normalized != null && !remove(normalized)) {
|
||||
_items.add(normalized);
|
||||
_recipes.add(recipeId);
|
||||
}
|
||||
|
||||
saveBookmarks();
|
||||
}
|
||||
|
||||
public static NBTTagCompound itemStackToNBT(ItemStack stack, NBTTagCompound nbTag)
|
||||
public BookmarkRecipeId getBookmarkRecipeId(ItemStack item)
|
||||
{
|
||||
String strId = Item.itemRegistry.getNameForObject(stack.getItem());
|
||||
nbTag.setString("strId", strId);
|
||||
nbTag.setByte("Count", (byte)stack.stackSize);
|
||||
nbTag.setShort("Damage", (short)stack.getItemDamage());
|
||||
int index = findStackIndex(item);
|
||||
|
||||
if (stack.stackTagCompound != null)
|
||||
{
|
||||
nbTag.setTag("tag", stack.stackTagCompound);
|
||||
if (index >= 0) {
|
||||
return _recipes.get(index);
|
||||
}
|
||||
|
||||
return nbTag;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemStack loadFromNBT(NBTTagCompound nbtTag)
|
||||
public int findStackIndex(ItemStack stackA)
|
||||
{
|
||||
if (!nbtTag.hasKey("id")) {
|
||||
final short id = (short)GameData.getItemRegistry().getId(nbtTag.getString("strId"));
|
||||
nbtTag.setShort("id", id);
|
||||
boolean useNBT = NEIClientConfig.useNBTInBookmarks();
|
||||
int i = 0;
|
||||
|
||||
for (ItemStack stackB : _items) {
|
||||
|
||||
if (StackInfo.equalItemAndNBT(stackA, stackB, useNBT)) {
|
||||
return i;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
ItemStack stack = ItemStack.loadItemStackFromNBT(nbtTag);
|
||||
return stack;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void saveBookmarks() {
|
||||
public void saveBookmarks()
|
||||
{
|
||||
List<String> strings = new ArrayList<>();
|
||||
for (ItemStack item:_items) {
|
||||
strings.add(NBTJson.toJson(itemStackToNBT(item, new NBTTagCompound())));
|
||||
int index = 0;
|
||||
|
||||
for (ItemStack item: _items) {
|
||||
try {
|
||||
final NBTTagCompound nbTag = StackInfo.itemStackToNBT(item);
|
||||
|
||||
if (nbTag != null) {
|
||||
JsonObject row = new JsonObject();
|
||||
BookmarkRecipeId recipeId = _recipes.get(index);
|
||||
|
||||
row.add("item", NBTJson.toJsonObject(nbTag));
|
||||
|
||||
if (recipeId != null) {
|
||||
row.add("recipeId", recipeId.toJsonObject());
|
||||
}
|
||||
|
||||
strings.add(NBTJson.toJson(row));
|
||||
}
|
||||
|
||||
} catch (JsonSyntaxException e) {
|
||||
NEIClientConfig.logger.error("Failed to stringify bookmarked ItemStack to json string");
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
File file = NEIClientConfig.bookmarkFile;
|
||||
if(file != null) {
|
||||
if (file != null) {
|
||||
try(FileWriter writer = new FileWriter(file)) {
|
||||
IOUtils.writeLines(strings, "\n", writer);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Filed to save bookmarks list to file {}", file, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void loadBookmarks() {
|
||||
public void loadBookmarksIfNeeded()
|
||||
{
|
||||
|
||||
if (bookmarksIsLoaded == true) {
|
||||
return;
|
||||
}
|
||||
|
||||
bookmarksIsLoaded = true;
|
||||
|
||||
File file = NEIClientConfig.bookmarkFile;
|
||||
if (file == null || !file.exists()) {
|
||||
return;
|
||||
@@ -97,37 +152,57 @@ public class BookmarkPanel extends ItemPanel {
|
||||
NEIClientConfig.logger.error("Failed to load bookmarks from file {}", file, e);
|
||||
return;
|
||||
}
|
||||
|
||||
_items.clear();
|
||||
JsonParser parser = new JsonParser();
|
||||
for (String itemStr: itemStrings) {
|
||||
try {
|
||||
NBTTagCompound itemStackNBT = (NBTTagCompound) NBTJson.toNbt(parser.parse(itemStr));
|
||||
ItemStack itemStack = loadFromNBT(itemStackNBT);
|
||||
JsonObject jsonObject = parser.parse(itemStr).getAsJsonObject();
|
||||
NBTTagCompound itemStackNBT = (NBTTagCompound) NBTJson.toNbt(jsonObject);
|
||||
BookmarkRecipeId recipeId = null;
|
||||
|
||||
if (jsonObject.get("item") != null) {
|
||||
itemStackNBT = (NBTTagCompound) NBTJson.toNbt(jsonObject.get("item"));
|
||||
} else {//old format
|
||||
itemStackNBT = (NBTTagCompound) NBTJson.toNbt(jsonObject);
|
||||
}
|
||||
|
||||
if (jsonObject.get("recipeId") != null && jsonObject.get("recipeId") instanceof JsonObject) {
|
||||
recipeId = new BookmarkRecipeId((JsonObject) jsonObject.get("recipeId"));
|
||||
}
|
||||
|
||||
ItemStack itemStack = StackInfo.loadFromNBT(itemStackNBT);
|
||||
|
||||
if (itemStack != null) {
|
||||
_items.add(itemStack);
|
||||
_recipes.add(recipeId);
|
||||
} else {
|
||||
NEIClientConfig.logger.warn("Failed to load bookmarked ItemStack from json string, the item no longer exists:\n{}", itemStr);
|
||||
}
|
||||
|
||||
} catch (IllegalArgumentException | JsonSyntaxException e) {
|
||||
NEIClientConfig.logger.error("Failed to load bookmarked ItemStack from json string:\n{}", itemStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ItemStack normalize(ItemStack item) {
|
||||
ItemStack copy = item.copy();
|
||||
copy.stackSize = 1;
|
||||
return copy;
|
||||
@Override
|
||||
public void draw(int mousex, int mousey)
|
||||
{
|
||||
loadBookmarksIfNeeded();
|
||||
super.draw(mousex, mousey);
|
||||
}
|
||||
private boolean remove(ItemStack item) {
|
||||
int i = 0;
|
||||
for (ItemStack existing : _items) {
|
||||
if (existing == item || existing.isItemEqual(item)) {
|
||||
_items.remove(i);
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
|
||||
private boolean remove(ItemStack item)
|
||||
{
|
||||
int index = findStackIndex(item);
|
||||
|
||||
if (index >= 0) {
|
||||
_items.remove(index);
|
||||
_recipes.remove(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -171,4 +246,51 @@ public class BookmarkPanel extends ItemPanel {
|
||||
return LayoutManager.getLeftSize(gui) - ( (gui.xSize + gui.width) / 2 + 3 ) - 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(int mousex, int mousey, int button, long heldTime)
|
||||
{
|
||||
|
||||
if (button == 0 && NEIClientUtils.shiftKey() && mouseDownSlot >= 0) {
|
||||
ItemPanelSlot mouseOverSlot = getSlotMouseOver(mousex, mousey);
|
||||
|
||||
if (mouseOverSlot == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sortedStackIndex == -1) {
|
||||
ItemStack stack = _items.get(mouseDownSlot);
|
||||
|
||||
if (stack != null && (mouseOverSlot == null || mouseOverSlot.slotIndex != mouseDownSlot || heldTime > 500)) {
|
||||
sortedStackIndex = mouseDownSlot;
|
||||
}
|
||||
|
||||
} else if (mouseOverSlot != null && mouseOverSlot.slotIndex != sortedStackIndex) {
|
||||
|
||||
int maxStackIndex = Math.max(mouseOverSlot.slotIndex, sortedStackIndex);
|
||||
int slotIndex = mouseOverSlot.slotIndex;
|
||||
|
||||
_items.add(slotIndex, _items.remove(sortedStackIndex));
|
||||
_recipes.add(slotIndex, _recipes.remove(sortedStackIndex));
|
||||
|
||||
sortedStackIndex = mouseOverSlot.slotIndex;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
super.mouseDragged(mousex, mousey, button, heldTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseUp(int mousex, int mousey, int button)
|
||||
{
|
||||
if (sortedStackIndex >= 0) {
|
||||
sortedStackIndex = -1;
|
||||
mouseDownSlot = -1;
|
||||
saveBookmarks();
|
||||
} else {
|
||||
super.mouseUp(mousex, mousey, button);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -265,7 +265,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void postRenderObjects(GuiContainer gui, int mousex, int mousey) {
|
||||
if (!isHidden() && isEnabled()) {
|
||||
@@ -310,13 +310,13 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
VisiblityData visiblity = new VisiblityData();
|
||||
if (isHidden())
|
||||
visiblity.showNEI = false;
|
||||
|
||||
|
||||
if (isBookmarkPanelHidden())
|
||||
visiblity.showBookmarkPanel = false;
|
||||
|
||||
|
||||
if (gui.height - gui.ySize <= 40)
|
||||
visiblity.showSearchSection = false;
|
||||
|
||||
|
||||
if (gui.guiLeft - 4 < 76)
|
||||
visiblity.showWidgets = false;
|
||||
try {
|
||||
@@ -325,7 +325,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
} finally {
|
||||
GuiInfo.readLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
visiblity.translateDependancies();
|
||||
|
||||
getLayoutStyle().layout(gui, visiblity);
|
||||
@@ -351,7 +351,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
this.icons[1] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 48, 0, 16, 16).build();
|
||||
this.icons[2] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 64, 0, 16, 16).build();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
if (!rightclick) {
|
||||
@@ -367,7 +367,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addTooltips(List<String> tooltip) {
|
||||
tooltip.add(translate("inventory.options.tip"));
|
||||
@@ -380,9 +380,9 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
String controlKeyLocalization = translate(Minecraft.isRunningOnMac ? "key.ctrl.mac" : "key.ctrl");
|
||||
tooltip.add(modeColor + translate("inventory.options.tip.cheatmode." + cheatMode));
|
||||
tooltip.add(modeColor + translate("inventory.options.tip.cheatmode.disable", controlKeyLocalization));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getRenderLabel() {
|
||||
return translate("inventory.options");
|
||||
@@ -396,7 +396,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
this.icons[0] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 0, 0, 16, 16).build();
|
||||
this.icons[1] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 16, 0, 16, 16).build();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
NEIClientConfig.toggleBooleanSetting("inventory.bookmarksEnabled");
|
||||
@@ -619,7 +619,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static void markItemsDirty() {
|
||||
// If anything has modified data this depends on, we'll need to reload the item list
|
||||
itemsLoaded = false;
|
||||
@@ -683,7 +683,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
if (visiblity.showBookmarkPanel) {
|
||||
addWidget(bookmarkPanel);
|
||||
bookmarkPanel.setVisible();
|
||||
}
|
||||
}
|
||||
|
||||
if (visiblity.showSearchSection) {
|
||||
addWidget(searchField);
|
||||
@@ -707,7 +707,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
if (canPerformAction("delete"))
|
||||
addWidget(delete);
|
||||
}
|
||||
|
||||
|
||||
if (!visiblity.showBookmarkPanel) {
|
||||
// Bookmarks or Subset/dropdown
|
||||
addWidget(dropDown);
|
||||
@@ -761,7 +761,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
|
||||
@Override
|
||||
public boolean shouldShowTooltip(GuiContainer gui) {
|
||||
return itemPanel.draggedStack == null;
|
||||
return itemPanel.draggedStack == null && bookmarkPanel.sortedStackIndex == -1;
|
||||
}
|
||||
|
||||
/** Note: this method isn't actually used by this mod, but NEI add-ons might need it. */
|
||||
@@ -799,16 +799,16 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
|
||||
public static void drawIcon(int x, int y, Image image) {
|
||||
final boolean isDrawableResource = image instanceof DrawableResource;
|
||||
|
||||
|
||||
if (!isDrawableResource)
|
||||
changeTexture("nei:textures/nei_sprites.png");
|
||||
|
||||
|
||||
GL11.glColor4f(1, 1, 1, 1);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
if(!isDrawableResource)
|
||||
drawTexturedModalRect(x, y, image.x, image.y, image.width, image.height);
|
||||
else
|
||||
else
|
||||
((DrawableResource)image).draw(x, y);
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
}
|
||||
@@ -884,4 +884,3 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ public class NEIClientConfig {
|
||||
|
||||
tag.getTag("inventory.widgetsenabled").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.widgetsenabled"));
|
||||
|
||||
|
||||
tag.getTag("inventory.hidden").getBooleanValue(false);
|
||||
tag.getTag("inventory.cheatmode").getIntValue(2);
|
||||
tag.getTag("inventory.lockmode").setComment("For those who can't help themselves.\nSet this to a mode and you will be unable to change it ingame").getIntValue(-1);
|
||||
@@ -174,14 +174,20 @@ public class NEIClientConfig {
|
||||
API.addOption(new OptionTextField("command.rain"));
|
||||
tag.getTag("command.heal").setDefaultValue("");
|
||||
API.addOption(new OptionTextField("command.heal"));
|
||||
|
||||
|
||||
tag.getTag("inventory.bookmarksEnabled").setComment("Enable/disable bookmarks").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.bookmarksEnabled", true));
|
||||
tag.getTag("inventory.saveCurrentRecipeInBookmarksEnabled").setComment("Save Current Recipe in Bookmarks").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.saveCurrentRecipeInBookmarksEnabled", true));
|
||||
tag.getTag("inventory.useNBTInBookmarks").setComment("Use NBT in Bookmarks").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.useNBTInBookmarks", true));
|
||||
|
||||
tag.getTag("inventory.jei_style_tabs").setComment("Enable/disable JEI Style Tabs").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButtonBoubs("inventory.jei_style_tabs", true));
|
||||
tag.getTag("inventory.jei_style_item_presence_overlay").setComment("Enable/disable JEI Style item presence overlay on ?-hover").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.jei_style_item_presence_overlay", true));
|
||||
|
||||
|
||||
|
||||
tag.getTag("inventory.creative_tab_style").setComment("Creative or JEI style tabs").getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.creative_tab_style", true));
|
||||
|
||||
@@ -308,7 +314,6 @@ public class NEIClientConfig {
|
||||
GuiInfo.load();
|
||||
RecipeInfo.load();
|
||||
LayoutManager.load();
|
||||
ItemPanels.bookmarkPanel.loadBookmarks();
|
||||
NEIController.load();
|
||||
|
||||
configLoaded = true;
|
||||
@@ -357,6 +362,12 @@ public class NEIClientConfig {
|
||||
public static boolean isBookmarkPanelHidden() {
|
||||
return !getBooleanSetting("inventory.bookmarksEnabled");
|
||||
}
|
||||
public static boolean saveCurrentRecipeInBookmarksEnabled() {
|
||||
return getBooleanSetting("inventory.saveCurrentRecipeInBookmarksEnabled");
|
||||
}
|
||||
public static boolean useNBTInBookmarks() {
|
||||
return getBooleanSetting("inventory.useNBTInBookmarks");
|
||||
}
|
||||
public static boolean areJEIStyleTabsVisible() {
|
||||
return getBooleanSetting("inventory.jei_style_tabs");
|
||||
}
|
||||
@@ -370,7 +381,7 @@ public class NEIClientConfig {
|
||||
return enabledOverride && getBooleanSetting("inventory.widgetsenabled");
|
||||
}
|
||||
public static boolean loadHandlersFromJar() {
|
||||
return !getBooleanSetting("tools.handler_load_from_config");
|
||||
return !getBooleanSetting("tools.handler_load_from_config");
|
||||
}
|
||||
|
||||
public static void setEnabled(boolean flag) {
|
||||
@@ -441,7 +452,7 @@ public class NEIClientConfig {
|
||||
public static boolean shouldInvertMouseScrollTransfer() {
|
||||
return !getBooleanSetting("inventory.invertMouseScrollTransfer");
|
||||
}
|
||||
|
||||
|
||||
public static boolean getMagnetMode() {
|
||||
return enabledActions.contains("magnet");
|
||||
}
|
||||
@@ -528,5 +539,5 @@ public class NEIClientConfig {
|
||||
if (file.isDirectory() && !saveFileNames.contains(file.getName()))
|
||||
ObfuscationRun.deleteDir(file, true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import codechicken.nei.recipe.GuiUsageRecipe;
|
||||
import codechicken.nei.recipe.ICraftingHandler;
|
||||
import codechicken.nei.recipe.IUsageHandler;
|
||||
import codechicken.nei.recipe.RecipeInfo;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
@@ -284,4 +285,10 @@ public class API
|
||||
ItemInfo.itemVariants.put(item, variant);
|
||||
LayoutManager.markItemsDirty();
|
||||
}
|
||||
|
||||
public static void registerStackStringifyHandler(IStackStringifyHandler handler)
|
||||
{
|
||||
StackInfo.stackStringifyHandlers.add(handler);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package codechicken.nei.api;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public interface IStackStringifyHandler
|
||||
{
|
||||
|
||||
public NBTTagCompound convertItemStackToNBT(ItemStack[] stacks);
|
||||
|
||||
public ItemStack convertNBTToItemStack(NBTTagCompound nbtTag);
|
||||
|
||||
public ItemStack normalize(ItemStack item);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import codechicken.nei.util.NBTJson;
|
||||
import codechicken.nei.PositionedStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class BookmarkRecipeId
|
||||
{
|
||||
public int position = -1;
|
||||
public int recipetype = -1;
|
||||
public String handlerName = null;
|
||||
public List<ItemStack> ingredients = new ArrayList<>();
|
||||
|
||||
public BookmarkRecipeId(String handlerName, List<PositionedStack> stacks, int recipetype, int position)
|
||||
{
|
||||
this.handlerName = handlerName;
|
||||
|
||||
for (PositionedStack pStack : stacks) {
|
||||
ingredients.add(getItemStackWithMinimumDamage(pStack.items));
|
||||
}
|
||||
|
||||
this.ingredients = ingredients;
|
||||
this.recipetype = recipetype;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public BookmarkRecipeId(String handlerName, List<PositionedStack> stacks)
|
||||
{
|
||||
this(handlerName, stacks, -1, -1);
|
||||
}
|
||||
|
||||
public BookmarkRecipeId(JsonObject json)
|
||||
{
|
||||
|
||||
if (json.get("handlerName") != null) {
|
||||
handlerName = json.get("handlerName").getAsString();
|
||||
}
|
||||
|
||||
if (json.get("ingredients") != null) {
|
||||
JsonArray arr = (JsonArray) json.get("ingredients");
|
||||
List<ItemStack> itemStacks = convertJsonArrayToIngredients(arr);
|
||||
|
||||
if (itemStacks != null) {
|
||||
ingredients = itemStacks;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean equalsIngredients(List<PositionedStack> stacks)
|
||||
{
|
||||
|
||||
if (ingredients.size() != stacks.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Short idx = 0;
|
||||
|
||||
for (PositionedStack pStack : stacks) {
|
||||
final ItemStack stackA = getItemStackWithMinimumDamage(pStack.items);
|
||||
final ItemStack stackB = ingredients.get(idx);
|
||||
|
||||
if (stackB == null || !StackInfo.equalItemAndNBT(stackA, stackB, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected ItemStack getItemStackWithMinimumDamage(ItemStack[] stacks)
|
||||
{
|
||||
int damage = Short.MAX_VALUE;
|
||||
ItemStack result = stacks[0];
|
||||
|
||||
if (stacks.length > 1) {
|
||||
for (ItemStack stack : stacks) {
|
||||
if (stack.getItemDamage() < damage) {
|
||||
damage = stack.getItemDamage();
|
||||
result = stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.copy();
|
||||
}
|
||||
|
||||
public JsonObject toJsonObject()
|
||||
{
|
||||
JsonObject json = new JsonObject();
|
||||
|
||||
if (handlerName != null) {
|
||||
json.add("handlerName", new JsonPrimitive(handlerName));
|
||||
json.add("ingredients", convertIngredientsToJsonArray(ingredients));
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
protected List<ItemStack> convertJsonArrayToIngredients(JsonArray arr)
|
||||
{
|
||||
List<ItemStack> ingredients = new ArrayList<>();
|
||||
|
||||
for (JsonElement elem : arr) {
|
||||
final ItemStack stack = StackInfo.loadFromNBT((NBTTagCompound) NBTJson.toNbt(elem));
|
||||
|
||||
if (stack == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ingredients.add(stack);
|
||||
}
|
||||
|
||||
return ingredients;
|
||||
}
|
||||
|
||||
protected JsonArray convertIngredientsToJsonArray(List<ItemStack> ingredients)
|
||||
{
|
||||
JsonArray arr = new JsonArray();
|
||||
|
||||
for (ItemStack stack : ingredients) {
|
||||
final NBTTagCompound nbTag = StackInfo.itemStackToNBT(stack);
|
||||
|
||||
if (nbTag == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
arr.add(NBTJson.toJsonObject(nbTag));
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,8 @@ import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import codechicken.nei.ItemPanels;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@@ -46,9 +48,19 @@ public class GuiCraftingRecipe extends GuiRecipe
|
||||
handlers.sort(NEIClientConfig.HANDLER_COMPARATOR);
|
||||
|
||||
mc.displayGuiScreen(new GuiCraftingRecipe(prevscreen, handlers));
|
||||
|
||||
if (NEIClientConfig.saveCurrentRecipeInBookmarksEnabled() && !NEIClientUtils.shiftKey() && outputId.equals("item") && mc.currentScreen instanceof GuiRecipe) {
|
||||
GuiCraftingRecipe.openTargetRecipe((GuiRecipe)mc.currentScreen, (ItemStack)results[0]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static void openTargetRecipe(GuiRecipe currentScreen, ItemStack stackover)
|
||||
{
|
||||
currentScreen.openTargetRecipe(ItemPanels.bookmarkPanel.getBookmarkRecipeId(stackover));
|
||||
}
|
||||
|
||||
private GuiCraftingRecipe(GuiScreen prevgui, ArrayList<ICraftingHandler> handlers) {
|
||||
super(prevgui);
|
||||
currenthandlers = handlers;
|
||||
|
||||
@@ -18,13 +18,16 @@ import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.guihook.IContainerTooltipHandler;
|
||||
import codechicken.nei.guihook.IGuiClientSide;
|
||||
import codechicken.nei.guihook.IGuiHandleMouseWheel;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Item;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
@@ -193,20 +196,98 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
|
||||
yShift = handlerInfo == null ? 0 : handlerInfo.getYShift();
|
||||
}
|
||||
|
||||
|
||||
public void setRecipePage(int idx) {
|
||||
setRecipePage(idx, 0);
|
||||
}
|
||||
|
||||
public void setRecipePage(int idx, int position) {
|
||||
recipetype = idx;
|
||||
if (recipetype < 0) recipetype = currenthandlers.size() - 1;
|
||||
else if (recipetype >= currenthandlers.size()) recipetype = 0;
|
||||
|
||||
handler = currenthandlers.get(recipetype);
|
||||
handlerInfo = getHandlerInfo(handler);
|
||||
page = 0;
|
||||
page = Math.min(Math.max(0, position), handler.numRecipes() - 1) / getRecipesPerPage();
|
||||
recipeTabs.calcPageNumber();
|
||||
checkYShift();
|
||||
initOverlayButtons();
|
||||
}
|
||||
|
||||
public void openTargetRecipe(BookmarkRecipeId recipeId)
|
||||
{
|
||||
|
||||
if (recipeId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (recipeId.recipetype == -1 || recipeId.position == -1) {
|
||||
recipeId.recipetype = 0;
|
||||
recipeId.position = 0;
|
||||
|
||||
if (recipeId.handlerName != null) {
|
||||
|
||||
for (int j = 0; j < currenthandlers.size(); j++) {
|
||||
IRecipeHandler localHandler = currenthandlers.get(j);
|
||||
HandlerInfo localHandlerInfo = getHandlerInfo(localHandler);
|
||||
|
||||
if (localHandlerInfo.getHandlerName().equals(recipeId.handlerName)) {
|
||||
recipeId.recipetype = j;
|
||||
|
||||
if (!recipeId.ingredients.isEmpty()) {
|
||||
for (int i = 0; i < localHandler.numRecipes(); i++) {
|
||||
|
||||
if (recipeId.equalsIngredients(localHandler.getIngredientStacks(i))) {
|
||||
recipeId.position = i;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setRecipePage(recipeId.recipetype, recipeId.position);
|
||||
}
|
||||
|
||||
public BookmarkRecipeId getFocusedRecipeId()
|
||||
{
|
||||
String handlerName = handlerInfo.getHandlerName();
|
||||
Point mousePos = GuiDraw.getMousePosition();
|
||||
int recipesPerPage = getRecipesPerPage();
|
||||
|
||||
for (int i = page * recipesPerPage; i < handler.numRecipes() && i < (page + 1) * recipesPerPage; i++) {
|
||||
if (recipeInFocus(i)) {
|
||||
return new BookmarkRecipeId(handlerName, handler.getIngredientStacks(i), recipetype, i);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Boolean recipeInFocus(int idx)
|
||||
{
|
||||
PositionedStack result = handler.getResultStack(idx);
|
||||
if (result != null && isMouseOver(result, idx)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
List<PositionedStack> stacks = handler.getOtherStacks(idx);
|
||||
for (PositionedStack stack : stacks) {
|
||||
if (isMouseOver(stack, idx)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public IRecipeHandler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
@@ -219,7 +300,6 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
|
||||
return IntStream.range(minIndex, maxIndex).boxed().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void keyTyped(char c, int i) {
|
||||
if (i == Keyboard.KEY_ESCAPE) //esc
|
||||
@@ -579,8 +659,12 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int getRecipesPerPage() {
|
||||
return getRecipesPerPage(handlerInfo);
|
||||
}
|
||||
|
||||
private int getRecipesPerPage(HandlerInfo handlerInfo) {
|
||||
if(handlerInfo != null)
|
||||
return Math.max(Math.min(((ySize - (buttonHeight*3)) / handlerInfo.getHeight()), handlerInfo.getMaxRecipesPerPage()), 1);
|
||||
else
|
||||
|
||||
@@ -119,5 +119,8 @@ public class RecipeInfo
|
||||
|
||||
API.registerRecipeHandler(new ProfilerRecipeHandler(true));
|
||||
API.registerUsageHandler(new ProfilerRecipeHandler(false));
|
||||
|
||||
API.registerStackStringifyHandler(new StackStringifyHandler());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,7 +25,12 @@ public class RecipeItemInputHandler implements IContainerInputHandler
|
||||
|
||||
if(keyCode == NEIClientConfig.getKeyBinding("gui.bookmark")) {
|
||||
NEIClientConfig.logger.debug("Adding or removing {} from bookmarks", stackover.getDisplayName());
|
||||
ItemPanels.bookmarkPanel.addOrRemoveItem(stackover.copy());
|
||||
BookmarkRecipeId recipeId = null;
|
||||
|
||||
if (gui instanceof GuiRecipe && NEIClientConfig.saveCurrentRecipeInBookmarksEnabled())
|
||||
recipeId = ((GuiRecipe)gui).getFocusedRecipeId();
|
||||
|
||||
ItemPanels.bookmarkPanel.addOrRemoveItem(stackover.copy(), recipeId);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -42,27 +47,32 @@ public class RecipeItemInputHandler implements IContainerInputHandler
|
||||
if (!(gui instanceof GuiRecipe))
|
||||
return false;
|
||||
|
||||
//disabled open recipe gui if hold shift (player have move recipe)
|
||||
if (button == 0 && ItemPanels.bookmarkPanel.getStackMouseOver(mousex, mousey) != null && NEIClientUtils.shiftKey()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(button == 0)
|
||||
return GuiCraftingRecipe.openRecipeGui("item", stackover.copy());
|
||||
|
||||
if(button == 1)
|
||||
return GuiUsageRecipe.openRecipeGui("item", stackover.copy());
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyTyped(GuiContainer gui, char keyChar, int keyID)
|
||||
public void onKeyTyped(GuiContainer gui, char keyChar, int keyID)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button)
|
||||
public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseUp(GuiContainer gui, int mousex, int mousey, int button)
|
||||
public void onMouseUp(GuiContainer gui, int mousex, int mousey, int button)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -71,18 +81,18 @@ public class RecipeItemInputHandler implements IContainerInputHandler
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onMouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onMouseDragged(GuiContainer gui, int mousex, int mousey, int button, long heldTime)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import codechicken.nei.api.IStackStringifyHandler;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class StackInfo
|
||||
{
|
||||
|
||||
public static final ArrayList<IStackStringifyHandler> stackStringifyHandlers = new ArrayList<>();
|
||||
|
||||
public static NBTTagCompound itemStackToNBT(ItemStack stack)
|
||||
{
|
||||
NBTTagCompound nbTag = null;
|
||||
ItemStack[] stacks = new ItemStack[]{stack};
|
||||
|
||||
for (int i = stackStringifyHandlers.size() - 1; i >= 0 && nbTag == null; i--) {
|
||||
nbTag = stackStringifyHandlers.get(i).convertItemStackToNBT(stacks);
|
||||
}
|
||||
|
||||
return nbTag;
|
||||
}
|
||||
|
||||
public static ItemStack loadFromNBT(NBTTagCompound nbtTag)
|
||||
{
|
||||
ItemStack stack = null;
|
||||
|
||||
for (int i = stackStringifyHandlers.size() - 1; i >= 0 && stack == null; i--) {
|
||||
stack = stackStringifyHandlers.get(i).convertNBTToItemStack(nbtTag);
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static ItemStack normalize(ItemStack item) {
|
||||
ItemStack copy = null;
|
||||
|
||||
for (int i = stackStringifyHandlers.size() - 1; i >= 0 && copy == null; i--) {
|
||||
copy = stackStringifyHandlers.get(i).normalize(item);
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
public static boolean equalItemAndNBT(ItemStack stackA, ItemStack stackB, boolean useNBT)
|
||||
{
|
||||
if (stackA.isItemEqual(stackB)) {
|
||||
NBTTagCompound tagCompoundA = stackA.getTagCompound();
|
||||
NBTTagCompound tagCompoundB = stackB.getTagCompound();
|
||||
|
||||
return !useNBT || (tagCompoundA == null && tagCompoundB == null) || (tagCompoundA != null && tagCompoundB != null && tagCompoundA.equals(tagCompoundB));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import codechicken.nei.api.IStackStringifyHandler;
|
||||
import cpw.mods.fml.common.registry.GameData;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Item;
|
||||
|
||||
public class StackStringifyHandler implements IStackStringifyHandler
|
||||
{
|
||||
|
||||
public NBTTagCompound convertItemStackToNBT(ItemStack[] stacks)
|
||||
{
|
||||
ItemStack stack = getItemStackWithMinimumDamage(stacks);
|
||||
NBTTagCompound nbTag = new NBTTagCompound();
|
||||
String strId = Item.itemRegistry.getNameForObject(stack.getItem());
|
||||
|
||||
nbTag.setString("strId", strId);
|
||||
nbTag.setShort("Damage", (short)stack.getItemDamage());
|
||||
|
||||
if (stack.hasTagCompound()) {
|
||||
nbTag.setTag("tag", stack.getTagCompound());
|
||||
}
|
||||
|
||||
return nbTag;
|
||||
}
|
||||
|
||||
public ItemStack convertNBTToItemStack(NBTTagCompound nbtTag)
|
||||
{
|
||||
|
||||
if (!nbtTag.hasKey("strId")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String strId = nbtTag.getString("strId");
|
||||
|
||||
nbtTag = (NBTTagCompound)nbtTag.copy();
|
||||
nbtTag.setByte("Count", (byte)1);
|
||||
nbtTag.setShort("id", (short)GameData.getItemRegistry().getId(strId));
|
||||
|
||||
return ItemStack.loadItemStackFromNBT(nbtTag);
|
||||
}
|
||||
|
||||
public ItemStack normalize(ItemStack item)
|
||||
{
|
||||
ItemStack copy = item.copy();
|
||||
copy.stackSize = 1;
|
||||
return copy;
|
||||
}
|
||||
|
||||
protected static ItemStack getItemStackWithMinimumDamage(ItemStack[] stacks)
|
||||
{
|
||||
int damage = Short.MAX_VALUE;
|
||||
ItemStack result = stacks[0];
|
||||
|
||||
if (stacks.length > 1) {
|
||||
for (ItemStack stack : stacks) {
|
||||
if (stack.getItemDamage() < damage) {
|
||||
damage = stack.getItemDamage();
|
||||
result = stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,7 +34,11 @@ public class NBTJson {
|
||||
private static final Gson gson = new GsonBuilder().create();
|
||||
|
||||
public static String toJson(NBTTagCompound tag) {
|
||||
final String jsonString = toJsonObject(tag).toString();
|
||||
return toJson(toJsonObject(tag));
|
||||
}
|
||||
|
||||
public static String toJson(JsonElement json) {
|
||||
final String jsonString = json.toString();
|
||||
return gson.toJson(parser.parse(jsonString));
|
||||
}
|
||||
|
||||
@@ -50,6 +54,24 @@ public class NBTJson {
|
||||
root.add(nbtEntry.getKey(), toJsonObject(nbtEntry.getValue()));
|
||||
}
|
||||
return root;
|
||||
} else if (nbt instanceof NBTTagByte) {
|
||||
// Number (byte)
|
||||
return new JsonPrimitive(Byte.toString(((NBTTagByte) nbt).func_150290_f()) + 'B');
|
||||
} else if (nbt instanceof NBTTagShort) {
|
||||
// Number (short)
|
||||
return new JsonPrimitive(Short.toString(((NBTTagShort) nbt).func_150289_e()) + 'S');
|
||||
} else if (nbt instanceof NBTTagInt) {
|
||||
// Number (int)
|
||||
return new JsonPrimitive(((NBTTagInt) nbt).func_150287_d());
|
||||
} else if (nbt instanceof NBTTagLong) {
|
||||
// Number (long)
|
||||
return new JsonPrimitive(Long.toString(((NBTTagLong) nbt).func_150291_c()) + 'L');
|
||||
} else if (nbt instanceof NBTTagFloat) {
|
||||
// Number (float)
|
||||
return new JsonPrimitive(Float.toString(((NBTTagFloat) nbt).func_150288_h()) + 'F');
|
||||
} else if (nbt instanceof NBTTagDouble) {
|
||||
// Number (double)
|
||||
return new JsonPrimitive(Double.toString(((NBTTagDouble) nbt).func_150286_g()) + 'D');
|
||||
} else if (nbt instanceof NBTBase.NBTPrimitive) {
|
||||
// Number
|
||||
return new JsonPrimitive(((NBTBase.NBTPrimitive) nbt).func_150286_g());
|
||||
|
||||
Reference in new issue
Block a user