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:
slprimeandSerghei Borovetchi authored and GitHub committed 2021-11-21 19:31:02 -08:00
1 parent 492c99b8e3
commit b6070dd508
14 files changed
+640 -75

No files matched your search

+6
View File
@@ -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
+159 -37
View File
@@ -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);
}
}
}
+17 -18
View File
@@ -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
}
}
+18 -7
View File
@@ -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);
}
}
+7
View File
@@ -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;
+88 -4
View File
@@ -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)
{
+59
View File
@@ -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;
}
}
+23 -1
View File
@@ -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());