diff --git a/README.md b/README.md index f50b9b3..a7ba410 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,10 @@ the [release page](https://minecraft.curseforge.com/projects/just-enough-calcula ## Known Issues - [ ] 无法识别流体 -- [x] 无法覆盖NEI默认点击行为 - [ ] OreDict 部分渲染存在问题 +- [ ] OreDict 识别存在问题 - [ ] capability -- [x] 带 nbt 的物品存储到本地存在问题 -- [x] 主界面合成表转移存在问题 +- [ ] gui 界面 z-level 过高,会遮住 nei 的各种 gui [1]: http://cf.way2muchnoise.eu/full_just-enough-calculation_downloads.svg diff --git a/gradle.properties b/gradle.properties index 11c9786..4b5850f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,4 +4,4 @@ org.gradle.jvmargs=-Xmx3G # suppress inspection "UnusedProperty" for whole file mc_version=1.7.10 nei_version=2.1.2-GTNH -proj_version=0.4.0 \ No newline at end of file +proj_version=1.0-GTNH \ No newline at end of file diff --git a/src/main/java/me/towdium/jecalculation/gui/JecaGui.java b/src/main/java/me/towdium/jecalculation/gui/JecaGui.java index 5769c0f..7435d63 100644 --- a/src/main/java/me/towdium/jecalculation/gui/JecaGui.java +++ b/src/main/java/me/towdium/jecalculation/gui/JecaGui.java @@ -96,12 +96,12 @@ public class JecaGui extends GuiContainer { if (diff != 0) gui.root.onScroll(gui, mouseX, mouseY, diff); } else if (Mouse.getEventButtonState()) { - if (gui.root.onClicked(gui, mouseX, mouseY, button)) + if (gui.root.onClicked(gui, mouseX, mouseY, button)) { return true; - else if (gui.hand != ILabel.EMPTY) { - gui.hand = ILabel.EMPTY; + } else if (gui.hand != ILabel.EMPTY) { + gui.hand = button == 0 ? NEIPlugin.getLabelUnderMouse() : ILabel.EMPTY; return true; - } else { + } else if (button == 0) { ILabel e = NEIPlugin.getLabelUnderMouse(); if (e != ILabel.EMPTY) { gui.hand = e; @@ -171,8 +171,7 @@ public class JecaGui extends GuiContainer { public static JecaGui getCurrent() { GuiScreen gui = Minecraft.getMinecraft().currentScreen; JecaGui ret = gui instanceof JecaGui ? (JecaGui) gui : null; - Objects.requireNonNull(ret); - return ret; + return Objects.requireNonNull(ret); } private static void displayGuiUnsafe(boolean updateParent, boolean acceptsTransfer, IGui root) { @@ -267,6 +266,7 @@ public class JecaGui extends GuiContainer { @Override // modified from vanilla public void drawHoveringText(List lines, int x, int y, FontRenderer font) { + //noinspection unchecked List textLines = (List) lines; if (!textLines.isEmpty()) { GlStateManager.disableRescaleNormal(); @@ -347,11 +347,12 @@ public class JecaGui extends GuiContainer { } public void drawFluid(Fluid f, int xPos, int yPos, int xSize, int ySize) { - IIcon fluidStillIcon = f.getStillIcon(); + IIcon fluidIcon = f.getFlowingIcon(); + if(fluidIcon == null) fluidIcon = f.getStillIcon(); mc.renderEngine.bindTexture(TextureMap.locationBlocksTexture); setColor(f.getColor() & 0x00FFFFFF); - if (fluidStillIcon != null) - drawTexturedModelRectFromIcon(xPos, yPos, fluidStillIcon, xSize, ySize); + if (fluidIcon != null) + drawTexturedModelRectFromIcon(xPos, yPos, fluidIcon, xSize, ySize); } public void drawRectangle(int xPos, int yPos, int xSize, int ySize, int color) { @@ -366,10 +367,10 @@ public class JecaGui extends GuiContainer { GlStateManager.color(f, f1, f2, f3); GlStateManager.disableAlpha(); tessellator.startDrawingQuads(); - tessellator.addVertex((double) xPos, (double) bottom, 0.0D); - tessellator.addVertex((double) right, (double) bottom, 0.0D); - tessellator.addVertex((double) right, (double) yPos, 0.0D); - tessellator.addVertex((double) xPos, (double) yPos, 0.0D); + tessellator.addVertex(xPos, bottom, 0.0D); + tessellator.addVertex(right, bottom, 0.0D); + tessellator.addVertex(right, yPos, 0.0D); + tessellator.addVertex(xPos, yPos, 0.0D); tessellator.draw(); GlStateManager.enableAlpha(); GlStateManager.enableTexture2D(); diff --git a/src/main/java/me/towdium/jecalculation/gui/guis/GuiRecipe.java b/src/main/java/me/towdium/jecalculation/gui/guis/GuiRecipe.java index f3b7ba6..ff08fc3 100644 --- a/src/main/java/me/towdium/jecalculation/gui/guis/GuiRecipe.java +++ b/src/main/java/me/towdium/jecalculation/gui/guis/GuiRecipe.java @@ -1,5 +1,6 @@ package me.towdium.jecalculation.gui.guis; +import codechicken.nei.PositionedStack; import codechicken.nei.recipe.IRecipeHandler; import me.towdium.jecalculation.data.Controller; import me.towdium.jecalculation.data.label.ILabel; @@ -55,8 +56,8 @@ public class GuiRecipe extends WContainer implements IGui { Controller.addRecipe(group.getText(), toRecipe()); JecaGui.displayParent(); }); - WButton label = new WButtonIcon(45, 32, 20, 20, BTN_LABEL, "recipe.label") - .setListener(i -> JecaGui.displayGui(new GuiLabel((l) -> { + WButton label = new WButtonIcon(45, 32, 20, 20, BTN_LABEL, "recipe.label").setListener( + i -> JecaGui.displayGui(new GuiLabel((l) -> { JecaGui.displayParent(); JecaGui.getCurrent().hand = l; }))); @@ -147,19 +148,22 @@ public class GuiRecipe extends WContainer implements IGui { disambCache = new HashMap<>(); // input - recipe.getIngredientStacks(recipeIndex).stream() - .map((positionedStack) -> positionedStack.items) - .forEach(i -> merge(input, Arrays.asList(i), recipe)); + recipe.getIngredientStacks(recipeIndex) + .stream() + .map((positionedStack) -> positionedStack.items) + .forEach(i -> merge(input, Arrays.asList(i), recipe)); // output - merge(output, Arrays.asList(recipe.getResultStack(recipeIndex).items), recipe); + PositionedStack resultStack = recipe.getResultStack(recipeIndex); + if (resultStack != null) + merge(output, Arrays.asList(resultStack.items), recipe); // catalyst. Ignore multiple catalyst - NEIPlugin.getCatalyst(recipe).map(ILabel.Converter::from).ifPresent(catalyst -> { - this.catalyst.setLabel(catalyst, 0); - }); + NEIPlugin.getCatalyst(recipe) + .map(ILabel.Converter::from) + .ifPresent(catalyst -> this.catalyst.setLabel(catalyst, 0)); // other. Unused. For example fuel in furnaces. - recipe.getOtherStacks(recipeIndex).stream(); + // recipe.getOtherStacks(recipeIndex).stream(); this.input.setLabel(sort(input, 0), 0); this.output.setLabel(sort(output, 21), 0); @@ -167,7 +171,9 @@ public class GuiRecipe extends WContainer implements IGui { } private void merge(ArrayList> dst, List gi, IRecipeHandler context) { - List list = gi.stream().map(ILabel.Converter::from).filter(i -> i != ILabel.EMPTY) + List list = gi.stream() + .map(ILabel.Converter::from) + .filter(i -> i != ILabel.EMPTY) .collect(Collectors.toList()); if (list.isEmpty()) return; diff --git a/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerSimple.java b/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerSimple.java index 4031f1e..95709a6 100644 --- a/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerSimple.java +++ b/src/main/java/me/towdium/jecalculation/gui/guis/pickers/PickerSimple.java @@ -2,20 +2,22 @@ package me.towdium.jecalculation.gui.guis.pickers; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import me.towdium.jecalculation.gui.Resource; -import me.towdium.jecalculation.gui.guis.IGui; -import me.towdium.jecalculation.gui.widgets.*; import me.towdium.jecalculation.data.label.ILabel; import me.towdium.jecalculation.data.label.labels.LFluidStack; import me.towdium.jecalculation.data.label.labels.LOreDict; +import me.towdium.jecalculation.gui.guis.IGui; +import me.towdium.jecalculation.gui.widgets.WIcon; +import me.towdium.jecalculation.gui.widgets.WLabel; +import me.towdium.jecalculation.gui.widgets.WLabelScroll; +import me.towdium.jecalculation.gui.widgets.WSearch; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.oredict.OreDictionary; import javax.annotation.ParametersAreNonnullByDefault; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; + import static me.towdium.jecalculation.gui.Resource.ICN_TEXT; /** @@ -26,11 +28,12 @@ import static me.towdium.jecalculation.gui.Resource.ICN_TEXT; @SideOnly(Side.CLIENT) public class PickerSimple extends IPicker.Impl implements IGui { /** - * @param labels label to be displayed for selection + * @param labels label to be displayed for selection */ public PickerSimple(List labels) { WLabelScroll ls = new WLabelScroll(7, 33, 8, 7, WLabel.Mode.PICKER, true).setLabels(labels) - .setListener((i, v) -> notifyLsnr(i.get(v))); + .setListener((i, v) -> notifyLsnr( + i.get(v))); add(new WSearch(26, 7, 90, ls)); add(new WIcon(7, 7, 20, 20, ICN_TEXT, "common.search")); add(ls); @@ -39,8 +42,13 @@ public class PickerSimple extends IPicker.Impl implements IGui { public static class FluidStack extends PickerSimple { public FluidStack() { - super(FluidRegistry.getRegisteredFluids().entrySet().stream() - .map(e -> new LFluidStack(1000, e.getValue())).collect(Collectors.toList())); + super(FluidRegistry.getRegisteredFluids() + .values() + .stream() + // filter the fluid with no icon + .filter(fluid -> fluid.getStillIcon() != null || fluid.getFlowingIcon() != null) + .map(fluid -> new LFluidStack(1000, fluid)) + .collect(Collectors.toList())); } } @@ -52,7 +60,8 @@ public class PickerSimple extends IPicker.Impl implements IGui { static List generate() { return Arrays.stream(OreDictionary.getOreNames()) .filter(i -> !OreDictionary.getOres(i).isEmpty()) - .map(LOreDict::new).collect(Collectors.toList()); + .map(LOreDict::new) + .collect(Collectors.toList()); } } } diff --git a/src/main/java/me/towdium/jecalculation/gui/widgets/WLabel.java b/src/main/java/me/towdium/jecalculation/gui/widgets/WLabel.java index 9080258..63c6339 100644 --- a/src/main/java/me/towdium/jecalculation/gui/widgets/WLabel.java +++ b/src/main/java/me/towdium/jecalculation/gui/widgets/WLabel.java @@ -5,11 +5,14 @@ import codechicken.nei.recipe.GuiCraftingRecipe; import codechicken.nei.recipe.GuiUsageRecipe; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import me.towdium.jecalculation.JustEnoughCalculation; import me.towdium.jecalculation.data.label.ILabel; import me.towdium.jecalculation.gui.JecaGui; import me.towdium.jecalculation.gui.Resource; import me.towdium.jecalculation.utils.IllegalPositionException; import me.towdium.jecalculation.utils.Utilities; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; @@ -118,16 +121,19 @@ public class WLabel implements IWidget { } else return false; case RESULT: - // open NEI + // open NEI recipe gui Object item = label.getRepresentation(); - if (item != null) { + if ((item instanceof ItemStack || item instanceof FluidStack)) { + String id = item instanceof ItemStack ? "item" : "liquid"; if (button == 0) { - GuiCraftingRecipe.openRecipeGui("item", item); + GuiCraftingRecipe.openRecipeGui(id, item); return true; } else if (button == 1) { - GuiUsageRecipe.openRecipeGui("item", item); + GuiUsageRecipe.openRecipeGui(id, item); return true; } + } else if (item != null) { + JustEnoughCalculation.logger.warn("unknown label representation " + item); } return false; case PICKER: diff --git a/src/main/java/me/towdium/jecalculation/nei/NEICalculatorConfig.java b/src/main/java/me/towdium/jecalculation/nei/NEICalculatorConfig.java index a8422d8..dba51e0 100644 --- a/src/main/java/me/towdium/jecalculation/nei/NEICalculatorConfig.java +++ b/src/main/java/me/towdium/jecalculation/nei/NEICalculatorConfig.java @@ -5,16 +5,22 @@ import codechicken.nei.api.IConfigureNEI; import me.towdium.jecalculation.JustEnoughCalculation; import me.towdium.jecalculation.gui.JecaGui; +import java.util.stream.Stream; + public class NEICalculatorConfig implements IConfigureNEI { @Override public void loadConfig() { - System.out.println("loaded nei config"); - String [] recipeType = new String[]{ "crafting", "crafting2x2", "smelting", "fuel", "brewing"}; - for (String ident : recipeType) { - API.registerGuiOverlay(JecaGui.class, ident); - API.registerGuiOverlayHandler(JecaGui.class, new JecaOverlayHandler(), ident); - } + String[] baseOverlayIdentifiers = new String[]{"crafting", "crafting2x2", "smelting", "fuel", "brewing"}; + String[] ae2OverlayIdentifiers = new String[]{"inscriber", "grindstone"}; + /* For the recipeHandlers which extend `TemplateRecipeHandler` without override the `getOverlayIdentifier` function */ + String[] nullOverlayIdentifiers = new String[]{null}; + Stream.of(baseOverlayIdentifiers, ae2OverlayIdentifiers, nullOverlayIdentifiers) + .flatMap(Stream::of) + .forEach(ident -> { + API.registerGuiOverlay(JecaGui.class, ident); + API.registerGuiOverlayHandler(JecaGui.class, new JecaOverlayHandler(), ident); + }); } @Override diff --git a/src/main/java/me/towdium/jecalculation/utils/OptionalEither.java b/src/main/java/me/towdium/jecalculation/utils/OptionalEither.java new file mode 100644 index 0000000..7dba8f9 --- /dev/null +++ b/src/main/java/me/towdium/jecalculation/utils/OptionalEither.java @@ -0,0 +1,59 @@ +package me.towdium.jecalculation.utils; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Function; + +@ParametersAreNonnullByDefault +final public class OptionalEither { + public static OptionalEither left(L value) { + return new OptionalEither<>(Optional.of(value), Optional.empty()); + } + + public static OptionalEither right(R value) { + return new OptionalEither<>(Optional.empty(), Optional.of(value)); + } + + public static OptionalEither empty() { + return new OptionalEither<>(Optional.empty(), Optional.empty()); + } + + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + private final Optional left; + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + private final Optional right; + + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + private OptionalEither(Optional l, Optional r) { + left = l; + right = r; + } + + public Optional map(Function lFunc, Function rFunc) { + if(left.isPresent()){ + return left.map(lFunc); + } else if(right.isPresent()){ + return right.map(rFunc); + } else { + return Optional.empty(); + } + } + + public OptionalEither mapLeft(Function lFunc) { + return new OptionalEither<>(left.map(lFunc), right); + } + + public OptionalEither mapRight(Function rFunc) { + return new OptionalEither<>(left, right.map(rFunc)); + } + + public void apply(Consumer lFunc, Consumer rFunc) { + left.ifPresent(lFunc); + right.ifPresent(rFunc); + } + + public boolean isPresent() { + return left.isPresent() || right.isPresent(); + } +} diff --git a/src/main/java/me/towdium/jecalculation/utils/Utilities.java b/src/main/java/me/towdium/jecalculation/utils/Utilities.java index 282c9a7..2d37b11 100644 --- a/src/main/java/me/towdium/jecalculation/utils/Utilities.java +++ b/src/main/java/me/towdium/jecalculation/utils/Utilities.java @@ -4,6 +4,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.registry.GameData; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @@ -17,9 +18,11 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.IIcon; import net.minecraftforge.fluids.Fluid; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringEscapeUtils; +import org.apache.commons.lang3.text.WordUtils; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; @@ -77,7 +80,8 @@ public class Utilities { public static String repeat(String s, int n) { StringBuilder sb = new StringBuilder(); - for (int i = 0; i < n; i++) sb.append(s); + for (int i = 0; i < n; i++) + sb.append(s); return sb.toString(); } @@ -89,13 +93,46 @@ public class Utilities { return id.equals("minecraft") ? "Minecraft" : Loader.instance().getIndexedModList().get(id).getName(); } + /** + * If fluid is lava or water, return 'Minecraft'. + * If has still icon or flowing icon, get the icon name, or return 'unknown'; + * The icon name should be similar to 'modId:fluidId', then get the modId. + * Use the mod id to find in mod list, if not found, use the capitalized mod id to find in mod list; + * If still not found, return the capitalized mod id + * @param fluid fluid + * @return mod name + */ public static String getModName(Fluid fluid) { String name = fluid.getName(); if (name.equals("lava") || name.equals("water")) return "Minecraft"; - else - return Loader.instance().getIndexedModList().get(fluid.getStillIcon().getIconName().split(":")[0]) - .getName(); + else { + IIcon icon = getFluidIcon(fluid); + if (icon == null) { + return "Unknown"; + } + String iconName = icon.getIconName(); + String modId = iconName.split(":")[0]; + + Map indexedModList = Loader.instance().getIndexedModList(); + ModContainer modContainer = indexedModList.get(modId); + if(modContainer == null) { + String capitalizedModId =WordUtils.capitalize(modId); + modContainer = indexedModList.get(capitalizedModId); + if(modContainer == null) { + return capitalizedModId; + } + } + return modContainer.getName(); + } + } + + private static IIcon getFluidIcon(Fluid fluid) { + IIcon icon = fluid.getFlowingIcon(); + if(icon == null) { + icon = fluid.getStillIcon(); + } + return icon; } public static NBTTagCompound getTag(ItemStack is) { @@ -114,7 +151,8 @@ public class Utilities { @Nullable public V get(K a, K b) { V ret = data.get(new Pair<>(a, b)); - if (ret == null) ret = data.get(new Pair<>(b, a)); + if (ret == null) + ret = data.get(new Pair<>(b, a)); return ret; } } @@ -318,10 +356,12 @@ public class Utilities { } public boolean push(T obj, boolean replace) { - if (replace) data.pop(); + if (replace) + data.pop(); boolean ret = data.removeIf(t -> tester != null ? tester.test(t, obj) : t.equals(obj)); data.addFirst(obj); - if (data.size() > limit) data.removeLast(); + if (data.size() > limit) + data.removeLast(); return ret; } @@ -423,6 +463,7 @@ public class Utilities { w.sb.append('['); if (wrap) w.indent++; + //noinspection unchecked for (NBTBase i : (List) tags.tagList) { if (first) first = false; @@ -467,4 +508,10 @@ public class Utilities { else return new Locale(parts[0], parts[1], parts[2]); } + + public static String[] mergeStringArrays(String[] ...arrays){ + return Stream.of(arrays) + .flatMap(Stream::of) + .toArray(String[]::new); + } }