diff --git a/src/main/java/me/towdium/jecalculation/algorithm/CostList.java b/src/main/java/me/towdium/jecalculation/algorithm/CostList.java index 812d12e..de01d44 100644 --- a/src/main/java/me/towdium/jecalculation/algorithm/CostList.java +++ b/src/main/java/me/towdium/jecalculation/algorithm/CostList.java @@ -1,52 +1,67 @@ package me.towdium.jecalculation.algorithm; +import me.towdium.jecalculation.data.Controller; import me.towdium.jecalculation.data.label.ILabel; +import me.towdium.jecalculation.data.structure.Recipe; import me.towdium.jecalculation.utils.wrappers.Pair; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; public class CostList { - ArrayList labels; + List labels; public CostList() { labels = new ArrayList<>(); } public CostList(List labels) { - this.labels = new ArrayList<>(labels); + this.labels = labels.stream().map(ILabel::copy).collect(Collectors.toList()); } public CostList(List positive, List negative) { - labels = new ArrayList<>(positive); + labels = positive.stream().map(ILabel::copy).collect(Collectors.toList()); negative.forEach(i -> { ILabel l = i.copy(); labels.add(l.invertAmount()); }); } - @SuppressWarnings("UnusedReturnValue") - public CostList merge(CostList costList, boolean add) { - costList.labels.forEach(i -> labels.add(add ? i.copy() : i.copy().invertAmount())); - return cancel(); + public CostList(Recipe recipe) { + this(Arrays.asList(recipe.getLabel(Recipe.enumIoType.OUTPUT)), + Arrays.asList(recipe.getLabel(Recipe.enumIoType.INPUT))); } - private CostList cancel() { - ArrayList cancelled = new ArrayList<>(); + @SuppressWarnings("UnusedReturnValue") + public CostList merge(CostList costList, boolean add, boolean strict) { + CostList ret = copy(); + costList.labels.forEach(i -> ret.labels.add(add ? i.copy() : i.copy().invertAmount())); + ret.cancel(strict); + return ret; + } + + private void cancel(boolean strict) { for (int i = 0; i < labels.size(); i++) { - for (int j = i + 1; j < labels.size(); j++) { - Optional> l = ILabel.MERGER.merge(labels.get(i), labels.get(j), true); - if (l.isPresent()) { - labels.set(i, l.get().one); - labels.set(j, ILabel.EMPTY); - cancelled.add(l.get().two); + for (int j = 0; j < labels.size(); j++) { + if (i == j) + continue; + if (strict) { + ILabel a = labels.get(i); + ILabel b = labels.get(j); + if (a.matches(b)) { + labels.set(i, a.setAmount(a.getAmount() + b.getAmount())); + labels.set(j, ILabel.EMPTY); + } + } else { + Optional l = ILabel.MERGER.merge(labels.get(i), labels.get(j), true); + if (l.isPresent()) { + labels.set(i, l.get()); + labels.set(j, ILabel.EMPTY); + } } } } - labels = labels.stream().filter(i -> i != ILabel.EMPTY).collect(Collectors.toCollection(ArrayList::new)); - return new CostList(cancelled); + labels = labels.stream().filter(i -> i != ILabel.EMPTY).collect(Collectors.toList()); } @Override @@ -54,22 +69,94 @@ public class CostList { if (obj instanceof CostList) { CostList c = (CostList) obj; CostList m = c.copy(); - m.merge(this, false); - return m.labels.isEmpty(); + return m.merge(this, false, true).labels.isEmpty(); } else return false; } public CostList copy() { CostList ret = new CostList(); - ret.labels = labels.stream().map(ILabel::copy).collect(Collectors.toCollection(ArrayList::new)); + ret.labels = labels.stream().map(ILabel::copy).collect(Collectors.toList()); return ret; } + public boolean isEmpty() { return labels.isEmpty(); } - public ArrayList getLabels() { + public List getLabels() { return labels; } + + + public Calculator calculate() { + return new Calculator(this); + } + + @Override + public int hashCode() { + int hash = 0; + for (ILabel i : labels) + hash ^= i.hashCode(); + return hash; + } + + public static class Calculator { + CostList start; + ArrayList> procedure; + List catalysts; + private int index; + + public Calculator(CostList cl) { + HashSet set = new HashSet<>(); + start = cl; + set.add(start); + Recipe next = find(true); + while (next != null) { + CostList original = getCurrent(); + CostList difference = new CostList(next); + CostList result = original.merge(difference, false, false); + if (set.contains(result)) + next = find(false); + else { + set.add(result); + procedure.add(new Pair<>(result, difference)); + addCatalyst(next.getLabel(Recipe.enumIoType.CATALYST)); + next = find(true); + } + } + } + + private Recipe find(boolean reset) { + if (reset) + index = 0; + List labels = getCurrent().labels; + for (; index < labels.size(); index++) { + ILabel label = labels.get(index); + if (label.getAmount() >= 0) + continue; + Optional recipe = Controller.getRecipe(label, Recipe.enumIoType.OUTPUT); + if (recipe.isPresent()) + return recipe.get(); + } + return null; + } + + private void addCatalyst(ILabel[] labels) { + LOOP: + for (ILabel i : labels) { + for (ILabel j : catalysts) { + if (j.matches(i)) { + j.setAmount(j.getAmount() + i.getAmount()); + continue LOOP; + } + } + catalysts.add(i.copy()); + } + } + + private CostList getCurrent() { + return procedure.isEmpty() ? start : procedure.get(procedure.size() - 1).one; + } + } } diff --git a/src/main/java/me/towdium/jecalculation/data/ControllerClient.java b/src/main/java/me/towdium/jecalculation/data/Controller.java similarity index 92% rename from src/main/java/me/towdium/jecalculation/data/ControllerClient.java rename to src/main/java/me/towdium/jecalculation/data/Controller.java index 79adf1b..2968e93 100644 --- a/src/main/java/me/towdium/jecalculation/data/ControllerClient.java +++ b/src/main/java/me/towdium/jecalculation/data/Controller.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; /** @@ -26,7 +27,7 @@ import java.util.stream.Collectors; * Date: 17-10-15. */ @SideOnly(Side.CLIENT) -public class ControllerClient { +public class Controller { public static final String KEY_RECIPES = "recipes"; public static final String KEY_RECENTS = "recents"; static Recipes recipesClient; @@ -71,11 +72,11 @@ public class ControllerClient { return getRecord().getRecipes(group); } - public static List> getRecipes(ILabel label, Recipe.enumIoType type) { - return getRecord().getRecipes(label, type); + public static Optional getRecipe(ILabel label, Recipe.enumIoType type) { + return getRecord().getRecipe(label, type); } - public static List getRecent() { + public static List getRecent() { // TODO reduce usage of it since it reads nbt again return recentsClient.getRecords(); } diff --git a/src/main/java/me/towdium/jecalculation/data/capacity/JecaCapabilityProvider.java b/src/main/java/me/towdium/jecalculation/data/capability/JecaCapabilityProvider.java similarity index 90% rename from src/main/java/me/towdium/jecalculation/data/capacity/JecaCapabilityProvider.java rename to src/main/java/me/towdium/jecalculation/data/capability/JecaCapabilityProvider.java index bb349e6..2db66a8 100644 --- a/src/main/java/me/towdium/jecalculation/data/capacity/JecaCapabilityProvider.java +++ b/src/main/java/me/towdium/jecalculation/data/capability/JecaCapabilityProvider.java @@ -1,11 +1,9 @@ -package me.towdium.jecalculation.data.capacity; +package me.towdium.jecalculation.data.capability; import me.towdium.jecalculation.JustEnoughCalculation; import me.towdium.jecalculation.data.structure.Recipes; import net.minecraft.entity.Entity; -import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import net.minecraftforge.common.IExtendedEntityProperties; diff --git a/src/main/java/me/towdium/jecalculation/data/label/ILabel.java b/src/main/java/me/towdium/jecalculation/data/label/ILabel.java index 1db2cfe..b5af599 100644 --- a/src/main/java/me/towdium/jecalculation/data/label/ILabel.java +++ b/src/main/java/me/towdium/jecalculation/data/label/ILabel.java @@ -54,6 +54,8 @@ public interface ILabel { ILabel invertAmount(); + int getAmount(); + static void initClient() { CONVERTER.register(LOreDict::guess); EDITOR.register(PickerSimple.FluidStack::new, "fluid_stack", new LFluidStack(1000, FluidRegistry.WATER)); @@ -63,14 +65,6 @@ public interface ILabel { MERGER.register("oreDict", "oreDict", LOreDict::mergeOreDict); } - int getAmount(); - - - String getAmountString(); - - @SideOnly(Side.CLIENT) - String getDisplayName(); - static void initServer() { DESERIALIZER.register(LFluidStack.IDENTIFIER, LFluidStack::new); DESERIALIZER.register(LItemStack.IDENTIFIER, LItemStack::new); @@ -79,25 +73,25 @@ public interface ILabel { DESERIALIZER.register(LEmpty.IDENTIFIER, i -> EMPTY); } + String getAmountString(); + + String getDisplayName(); + List getToolTip(List existing, boolean detailed); ILabel copy(); NBTTagCompound toNBTTagCompound(); - void setAmount(int amount); - String getIdentifier(); - @SideOnly(Side.CLIENT) - default void drawLabel(JecaGui gui, int xPos, int yPos, boolean center) { - GlStateManager.pushMatrix(); - GlStateManager.translate(center ? xPos - 8 : xPos, center ? yPos - 8 : yPos, 0); - drawLabel(gui); - GlStateManager.popMatrix(); - } + ILabel setAmount(int amount); + + boolean matches(Object l); + + @SideOnly(Side.CLIENT) + void drawLabel(JecaGui gui, int xPos, int yPos, boolean center); - void drawLabel(JecaGui gui); /** * Since {@link ILabel} merging is bidirectional, it is redundant to @@ -118,14 +112,15 @@ public interface ILabel { functions.add(a, b, func); } - public Optional> merge(ILabel a, ILabel b, boolean add) { + public Optional merge(ILabel a, ILabel b, boolean add) { Optional ret = functions.get(a.getIdentifier(), b.getIdentifier()) .orElse((x, y, f) -> Optional.empty()).merge(a, b, add); if (ret.isPresent() && ret.get() != ILabel.EMPTY && (ret.get() == a || ret.get() == b)) throw new RuntimeException("Merger should not modify the given label."); - return ret.map(i -> new Pair<>(i, add ? b.copy().invertAmount() : b.copy())); + return ret; } + @FunctionalInterface public interface MergerFunction { /** @@ -240,6 +235,11 @@ public interface ILabel { class LEmpty implements ILabel { public static final String IDENTIFIER = "empty"; + @Override + public boolean matches(Object l) { + return l == this; + } + private LEmpty() { } @@ -274,10 +274,10 @@ public interface ILabel { } @Override - public void setAmount(int amount) { + public ILabel setAmount(int amount) { + return this; } - @Override public String getAmountString() { return ""; @@ -309,7 +309,7 @@ public interface ILabel { } @Override - public void drawLabel(JecaGui gui) { + public void drawLabel(JecaGui gui, int xPos, int yPos, boolean center) { } } @@ -317,6 +317,11 @@ public interface ILabel { public static final String KEY_AMOUNT = "amount"; protected int amount; + @Override + public String toString() { + return getDisplayName() + 'x' + getAmount(); + } + public Impl(int amount) { this.amount = amount; } @@ -333,6 +338,14 @@ public interface ILabel { return 1; } + @Override + public void drawLabel(JecaGui gui, int xPos, int yPos, boolean center) { + GlStateManager.pushMatrix(); + GlStateManager.translate(center ? xPos - 8 : xPos, center ? yPos - 8 : yPos, 0); + drawLabel(gui); + GlStateManager.popMatrix(); + } + @Override public ILabel increaseAmount() { setAmount(getAmount() + getMultiplier()); @@ -373,7 +386,7 @@ public interface ILabel { @SideOnly(Side.CLIENT) public List getToolTip(List existing, boolean detailed) { if (detailed) existing.add(FORMAT_GREY + - Utilities.I18n.format("label.common.tooltip.amount", Integer.toString(getAmount()))); + Utilities.I18n.format("label.common.tooltip.amount", getAmountString())); return existing; } @@ -390,8 +403,10 @@ public interface ILabel { } @Override - public void setAmount(int amount) { + public ILabel setAmount(int amount) { + if (amount == 0) return ILabel.EMPTY; this.amount = amount; + return this; } @Override @@ -402,7 +417,9 @@ public interface ILabel { @Override public boolean equals(Object obj) { - return obj instanceof Impl && amount == ((Impl) obj).amount; + return obj instanceof Impl && amount == ((Impl) obj).amount && matches(obj); } + + abstract protected void drawLabel(JecaGui gui); } } diff --git a/src/main/java/me/towdium/jecalculation/data/label/labels/LFluidStack.java b/src/main/java/me/towdium/jecalculation/data/label/labels/LFluidStack.java index c6c2b3c..a9d5ca7 100644 --- a/src/main/java/me/towdium/jecalculation/data/label/labels/LFluidStack.java +++ b/src/main/java/me/towdium/jecalculation/data/label/labels/LFluidStack.java @@ -79,6 +79,14 @@ public class LFluidStack extends ILabel.Impl { return IDENTIFIER; } + @Override + public boolean matches(Object l) { + if (l instanceof LFluidStack) { + LFluidStack lfs = (LFluidStack) l; + return (nbt == null ? lfs.nbt == null : nbt.equals(lfs.nbt)) && fluid == lfs.fluid; + } else return false; + } + @Override public ILabel copy() { return new LFluidStack(this); @@ -88,7 +96,7 @@ public class LFluidStack extends ILabel.Impl { public NBTTagCompound toNBTTagCompound() { NBTTagCompound ret = super.toNBTTagCompound(); ret.setString(KEY_FLUID, FluidRegistry.getFluidName(fluid)); - ret.setTag(KEY_NBT, nbt); + if (nbt != null) ret.setTag(KEY_NBT, nbt); return ret; } @@ -109,13 +117,8 @@ public class LFluidStack extends ILabel.Impl { gui.drawFluid(fluid, 2, 2, 12, 12); } - @Override - public boolean equals(Object obj) { - return obj instanceof LFluidStack && fluid.equals(((LFluidStack) obj).fluid); - } - @Override public int hashCode() { - return fluid.hashCode(); + return fluid.getUnlocalizedName().hashCode() ^ amount ^ (nbt == null ? 0 : nbt.hashCode()); } } diff --git a/src/main/java/me/towdium/jecalculation/data/label/labels/LItemStack.java b/src/main/java/me/towdium/jecalculation/data/label/labels/LItemStack.java index d0069d0..9ed6ccd 100644 --- a/src/main/java/me/towdium/jecalculation/data/label/labels/LItemStack.java +++ b/src/main/java/me/towdium/jecalculation/data/label/labels/LItemStack.java @@ -66,8 +66,7 @@ public class LItemStack extends ILabel.Impl { LItemStack lisA = (LItemStack) a; LItemStack lisB = (LItemStack) b; boolean wildcard = lisA.meta == OreDictionary.WILDCARD_VALUE || lisB.meta == OreDictionary.WILDCARD_VALUE; - if ((Objects.equals(lisA.nbt, lisB.nbt)) && - (lisA.meta == lisB.meta || wildcard)) { + if ((Objects.equals(lisA.nbt, lisB.nbt)) && (lisA.meta == lisB.meta || wildcard)) { LItemStack ret = new LItemStack(lisA); if (wildcard) ret.meta = OreDictionary.WILDCARD_VALUE; @@ -101,6 +100,15 @@ public class LItemStack extends ILabel.Impl { return IDENTIFIER; } + @Override + public boolean matches(Object l) { + if (l instanceof LItemStack) { + LItemStack lis = (LItemStack) l; + return (Objects.equals(nbt, lis.nbt)) && meta == lis.meta && item == lis.item; + } else + return false; + } + @Override public ILabel copy() { return new LItemStack(this); @@ -125,17 +133,8 @@ public class LItemStack extends ILabel.Impl { gui.drawItemStack(0, 0, temp, false); } - @Override - public boolean equals(Object obj) { - if (obj instanceof LItemStack) { - LItemStack lis = (LItemStack) obj; - return super.equals(obj) && lis.item == item && lis.meta == meta && Objects.equals(nbt, lis.nbt); - } else - return false; - } - @Override public int hashCode() { - return meta ^ item.getUnlocalizedName().hashCode() ^ (nbt == null ? 0 : nbt.hashCode()); + return (nbt == null ? 0 : nbt.hashCode()) ^ meta ^ item.getUnlocalizedName().hashCode() ^ amount; } } diff --git a/src/main/java/me/towdium/jecalculation/data/label/labels/LOreDict.java b/src/main/java/me/towdium/jecalculation/data/label/labels/LOreDict.java index 770fbc7..85b4055 100644 --- a/src/main/java/me/towdium/jecalculation/data/label/labels/LOreDict.java +++ b/src/main/java/me/towdium/jecalculation/data/label/labels/LOreDict.java @@ -124,6 +124,11 @@ public class LOreDict extends ILabel.Impl { return IDENTIFIER; } + @Override + public boolean matches(Object l) { + return l instanceof LOreDict && name.equals(((LOreDict) l).name); + } + @Override public LOreDict copy() { return new LOreDict(this); @@ -169,12 +174,6 @@ public class LOreDict extends ILabel.Impl { return name.hashCode() ^ amount; } - @Override - public boolean equals(Object obj) { - return obj instanceof LOreDict - && amount == ((LOreDict) obj).amount && name.equals(((LOreDict) obj).name); - } - public String getName() { return name; } diff --git a/src/main/java/me/towdium/jecalculation/data/label/labels/LString.java b/src/main/java/me/towdium/jecalculation/data/label/labels/LString.java index 2278315..1f0d341 100644 --- a/src/main/java/me/towdium/jecalculation/data/label/labels/LString.java +++ b/src/main/java/me/towdium/jecalculation/data/label/labels/LString.java @@ -47,6 +47,11 @@ public class LString extends ILabel.Impl { return "string"; } + @Override + public boolean matches(Object l) { + return l instanceof LString && name.equals(((LString) l).name); + } + @Override public ILabel copy() { return new LString(this); @@ -66,12 +71,6 @@ public class LString extends ILabel.Impl { gui.drawResource(Resource.LBL_UNIV_F, 0, 0, (name.hashCode() * 0x131723) & 0xFFFFFF); } - @Override - public boolean equals(Object obj) { - return obj instanceof LString - && name.equals(((LString) obj).name) && amount == ((LString) obj).amount; - } - @Override public int hashCode() { return name.hashCode() ^ amount; diff --git a/src/main/java/me/towdium/jecalculation/data/structure/Recipe.java b/src/main/java/me/towdium/jecalculation/data/structure/Recipe.java index 11f7c0d..82e3706 100644 --- a/src/main/java/me/towdium/jecalculation/data/structure/Recipe.java +++ b/src/main/java/me/towdium/jecalculation/data/structure/Recipe.java @@ -105,6 +105,10 @@ public class Recipe { return ret; } + public boolean matches(ILabel label, enumIoType type) { + return Arrays.stream(getLabel(type)).anyMatch(i -> ILabel.MERGER.merge(label, i, true).isPresent()); + } + public enum enumIoType { INPUT, OUTPUT, CATALYST; diff --git a/src/main/java/me/towdium/jecalculation/data/structure/Recipes.java b/src/main/java/me/towdium/jecalculation/data/structure/Recipes.java index 6945fe0..a6dbe10 100644 --- a/src/main/java/me/towdium/jecalculation/data/structure/Recipes.java +++ b/src/main/java/me/towdium/jecalculation/data/structure/Recipes.java @@ -7,10 +7,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.BiConsumer; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -98,13 +95,8 @@ public class Recipes { return flatStream(group).collect(Collectors.toCollection(ArrayList::new)); } - public List> getRecipes(ILabel label, Recipe.enumIoType type) { - return getRecipes(flatStream(), r -> IntStream.range(0, type.getSize()).anyMatch(i -> - ILabel.MERGER.merge(label, r.getLabel(type)[i], true).isPresent())); - } - - private List> getRecipes(Stream> list, Predicate pre) { - return list.filter(i -> pre.test(i.one)).collect(Collectors.toCollection(ArrayList::new)); + public Optional getRecipe(ILabel label, Recipe.enumIoType type) { + return flatStream().map(i -> i.one).filter(i -> i.matches(label, type)).findFirst(); } public void forEach(BiConsumer> consumer) { diff --git a/src/main/java/me/towdium/jecalculation/event/Handlers.java b/src/main/java/me/towdium/jecalculation/event/Handlers.java index 6c15a45..6b4f17c 100644 --- a/src/main/java/me/towdium/jecalculation/event/Handlers.java +++ b/src/main/java/me/towdium/jecalculation/event/Handlers.java @@ -1,6 +1,5 @@ package me.towdium.jecalculation.event; -import me.towdium.jecalculation.data.ControllerClient; import me.towdium.jecalculation.event.handlers.InputEventHandler; import java.util.ArrayList; diff --git a/src/main/java/me/towdium/jecalculation/event/handlers/InputEventHandler.java b/src/main/java/me/towdium/jecalculation/event/handlers/InputEventHandler.java index d432bc9..4d299ce 100644 --- a/src/main/java/me/towdium/jecalculation/event/handlers/InputEventHandler.java +++ b/src/main/java/me/towdium/jecalculation/event/handlers/InputEventHandler.java @@ -7,14 +7,13 @@ import cpw.mods.fml.common.gameevent.PlayerEvent; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import me.towdium.jecalculation.JustEnoughCalculation; -import me.towdium.jecalculation.data.ControllerClient; +import me.towdium.jecalculation.data.Controller; import me.towdium.jecalculation.gui.JecaGui; import me.towdium.jecalculation.gui.guis.GuiCalculator; import me.towdium.jecalculation.network.ClientHandler; import net.minecraft.client.Minecraft; import net.minecraft.util.ChatComponentTranslation; import net.minecraftforge.client.event.GuiScreenEvent; -import net.minecraftforge.event.entity.EntityEvent; /** * Author: towdium @@ -45,7 +44,7 @@ public class InputEventHandler { @SubscribeEvent public void onLogout(PlayerEvent.PlayerLoggedOutEvent event) { JustEnoughCalculation.logger.info("on log out event"); - ControllerClient.writeToLocal();; + Controller.writeToLocal();; } } diff --git a/src/main/java/me/towdium/jecalculation/gui/JecaGui.java b/src/main/java/me/towdium/jecalculation/gui/JecaGui.java index ed613aa..eff7676 100644 --- a/src/main/java/me/towdium/jecalculation/gui/JecaGui.java +++ b/src/main/java/me/towdium/jecalculation/gui/JecaGui.java @@ -134,8 +134,8 @@ public class JecaGui extends GuiContainer { root.onDraw(this, mouseX - guiLeft, mouseY - guiTop); GlStateManager.popMatrix(); GlStateManager.pushMatrix(); - GlStateManager.translate(mouseX - 8, mouseY - 8, 80); - hand.drawLabel(this); + GlStateManager.translate(0, 0, 80); + hand.drawLabel(this, mouseX, mouseY, true); GlStateManager.popMatrix(); drawBufferedTooltip(); GlStateManager.enableLighting(); diff --git a/src/main/java/me/towdium/jecalculation/gui/drawables/WContainer.java b/src/main/java/me/towdium/jecalculation/gui/drawables/WContainer.java index 22a0419..a6f72bf 100644 --- a/src/main/java/me/towdium/jecalculation/gui/drawables/WContainer.java +++ b/src/main/java/me/towdium/jecalculation/gui/drawables/WContainer.java @@ -16,6 +16,7 @@ import java.util.List; @ParametersAreNonnullByDefault @SideOnly(Side.CLIENT) public class WContainer implements IWidget { + boolean modified = false; protected List widgets = new ArrayList<>(); public void add(IWidget w) { @@ -62,13 +63,4 @@ public class WContainer implements IWidget { for (IWidget w : widgets) if (w.onScroll(gui, xMouse, yMouse, diff)) return true; return false; } - - /*public Optional getLabelAt(int xMouse, int yMouse) { - return drawables.stream().map(w -> { - if (w instanceof WLabelGroup) return ((WLabelGroup) w).getLabelAt(xMouse, yMouse); - else if (w instanceof WLabel) return Optional.ofNullable( - ((WLabel) w).mouseIn(xMouse, yMouse) ? ((WLabel) w) : null); - else return Optional.empty(); - }).filter(Optional::isPresent).findFirst().orElse(Optional.empty()); - }*/ } diff --git a/src/main/java/me/towdium/jecalculation/gui/drawables/WLabel.java b/src/main/java/me/towdium/jecalculation/gui/drawables/WLabel.java index 05f5d66..bc98eb8 100644 --- a/src/main/java/me/towdium/jecalculation/gui/drawables/WLabel.java +++ b/src/main/java/me/towdium/jecalculation/gui/drawables/WLabel.java @@ -49,8 +49,8 @@ public class WLabel implements IWidget { public void setLabel(ILabel label) { this.label = label; - if (mode == enumMode.EDITOR || mode == enumMode.SELECTOR) - notifyLsnr(); +// if (mode == enumMode.EDITOR || mode == enumMode.SELECTOR) +// notifyLsnr(); } @Override @@ -58,7 +58,7 @@ public class WLabel implements IWidget { gui.drawResourceContinuous(Resource.WGT_SLOT, xPos, yPos, xSize, ySize, 3, 3, 3, 3); label.drawLabel(gui, xPos + xSize / 2, yPos + ySize / 2, true); if (mode == enumMode.RESULT || mode == enumMode.EDITOR) - gui.drawText(xPos + xSize / 2 + 7.5f, yPos + ySize / 2 + 7 - + gui.drawText(xPos + xSize / 2.0f + 7.5f, yPos + ySize / 2 + 7 - (int) (font.size * gui.getFontRenderer().FONT_HEIGHT), font, label.getAmountString()); if (mouseIn(xMouse, yMouse)) { gui.drawRectangle(xPos + 1, yPos + 1, xSize - 2, ySize - 2, 0x80FFFFFF); diff --git a/src/main/java/me/towdium/jecalculation/gui/drawables/WLabelScroll.java b/src/main/java/me/towdium/jecalculation/gui/drawables/WLabelScroll.java index 86c18fd..a4fc571 100644 --- a/src/main/java/me/towdium/jecalculation/gui/drawables/WLabelScroll.java +++ b/src/main/java/me/towdium/jecalculation/gui/drawables/WLabelScroll.java @@ -55,11 +55,9 @@ public class WLabelScroll extends WContainer { public boolean onScroll(JecaGui gui, int xMouse, int yMouse, int diff) { boolean in = JecaGui.mouseIn(xPos, yPos, column * 18, row * 18, xMouse, yMouse); if (in) { - scroll.setLsnrScroll(null); float pos = getPos(current - diff); scroll.setCurrent(pos); update(pos); - scroll.setLsnrScroll(this::update); } return in; } @@ -79,6 +77,7 @@ public class WLabelScroll extends WContainer { filtered = labels.stream().filter(l -> Utilities.contains(l.getDisplayName().toLowerCase(), str.toLowerCase())) .collect(Collectors.toList()); scroll.setCurrent(0); + update(0); return filtered.size() != 0; } diff --git a/src/main/java/me/towdium/jecalculation/gui/drawables/WScroll.java b/src/main/java/me/towdium/jecalculation/gui/drawables/WScroll.java index 80c6ed7..0361e23 100644 --- a/src/main/java/me/towdium/jecalculation/gui/drawables/WScroll.java +++ b/src/main/java/me/towdium/jecalculation/gui/drawables/WScroll.java @@ -31,7 +31,7 @@ public class WScroll implements IWidget { @Override public void onDraw(JecaGui gui, int xMouse, int yMouse) { - if (Mouse.isButtonDown(0) && drag) setCurrent(yMouse - yPos - 9); + if (Mouse.isButtonDown(0) && drag) setCurrent(yMouse - yPos - 9, true); else drag = false; gui.drawResourceContinuous(Resource.WGT_SLOT, xPos, yPos, 14, ySize, 3, 3, 3, 3); @@ -41,19 +41,19 @@ public class WScroll implements IWidget { @Override public boolean onClicked(JecaGui gui, int xMouse, int yMouse, int button) { drag = mouseIn(xMouse, yMouse); - if (drag) setCurrent(yMouse - yPos - 9); + if (drag) setCurrent(yMouse - yPos - 9, true); return drag; } - private void setCurrent(int pos) { + private void setCurrent(int pos, boolean notify) { current = pos; if (current < 0) current = 0; if (current > ySize - 17) current = ySize - 17; - if (lsnrScroll != null) lsnrScroll.accept(current / (ySize - 17f)); + if (notify && lsnrScroll != null) lsnrScroll.accept(current / (ySize - 17f)); } public void setCurrent(float ratio) { - setCurrent((int) ((ySize - 17) * ratio)); + setCurrent((int) ((ySize - 17) * ratio), false); } public boolean mouseIn(int xMouse, int yMouse) { diff --git a/src/main/java/me/towdium/jecalculation/gui/drawables/WSearch.java b/src/main/java/me/towdium/jecalculation/gui/drawables/WSearch.java index 2c64285..563e5ee 100644 --- a/src/main/java/me/towdium/jecalculation/gui/drawables/WSearch.java +++ b/src/main/java/me/towdium/jecalculation/gui/drawables/WSearch.java @@ -22,13 +22,16 @@ public class WSearch extends WContainer { public WSearch(Consumer callback, WTextField tf, WLabelScroll... lss) { clbk = callback; List lst = Arrays.asList(lss); - tf.setLsnrText(s -> tf.setColor(lst.stream().anyMatch(ls -> ls.setFilter(s)) ? - JecaGui.COLOR_TEXT_WHITE : JecaGui.COLOR_TEXT_RED)); + tf.setLsnrText(s -> { + boolean b = false; + for (WLabelScroll i : lss) if (i.setFilter(s)) b = true; + tf.setColor(b ? JecaGui.COLOR_TEXT_WHITE : JecaGui.COLOR_TEXT_RED); + }); add(tf); addAll(lss); for (WLabelScroll i : lss) i.setLsnrUpdate(j -> { - if (clbk != null) clbk.accept(i.getLabelAt(j)); + if (clbk != null) clbk.accept(i.getLabelAt(j).copy()); }); } } diff --git a/src/main/java/me/towdium/jecalculation/gui/drawables/WTextField.java b/src/main/java/me/towdium/jecalculation/gui/drawables/WTextField.java index 16f7327..6d59da5 100644 --- a/src/main/java/me/towdium/jecalculation/gui/drawables/WTextField.java +++ b/src/main/java/me/towdium/jecalculation/gui/drawables/WTextField.java @@ -30,10 +30,8 @@ public class WTextField implements IWidget { @Override public boolean onClicked(JecaGui gui, int xMouse, int yMouse, int button) { - boolean flag = xMouse >= textField.xPosition && xMouse < textField.xPosition + textField.width && - yMouse >= textField.yPosition && yMouse < textField.yPosition + textField.height; textField.mouseClicked(xMouse, yMouse, button); - return textField.isFocused() && flag && button == 0; + return false; } @Override diff --git a/src/main/java/me/towdium/jecalculation/gui/guis/GuiCalculator.java b/src/main/java/me/towdium/jecalculation/gui/guis/GuiCalculator.java index 38adabf..38e3d14 100644 --- a/src/main/java/me/towdium/jecalculation/gui/guis/GuiCalculator.java +++ b/src/main/java/me/towdium/jecalculation/gui/guis/GuiCalculator.java @@ -6,7 +6,7 @@ import me.towdium.jecalculation.gui.JecaGui; import me.towdium.jecalculation.gui.Resource; import me.towdium.jecalculation.gui.drawables.*; import me.towdium.jecalculation.data.label.ILabel; -import me.towdium.jecalculation.data.ControllerClient; +import me.towdium.jecalculation.data.Controller; import javax.annotation.ParametersAreNonnullByDefault; import java.util.List; @@ -40,17 +40,17 @@ public class GuiCalculator extends WContainer { add(new WIcon(151, 31, 18, 18, Resource.ICN_RECENT_N, Resource.ICN_RECENT_F, "calculator.history")); add(new WSwitcher(7, 56, 162, 5)); refresh(); - List recent = ControllerClient.getRecent(); - if (recent.size() > 0) wLabel.setLabel(ControllerClient.getRecent().get(0)); + List recent = Controller.getRecent(); + if (recent.size() > 0) wLabel.setLabel(Controller.getRecent().get(0)); wLabel.setLsnrUpdate(() -> { - ControllerClient.setRecent(wLabel.label); + Controller.setRecent(wLabel.label); refresh(); }); wRecent.setLsnrUpdate(l -> JecaGui.getCurrent().hand = wRecent.getLabelAt(l)); } void refresh() { - List recent = ControllerClient.getRecent(); + List recent = Controller.getRecent(); if (recent.size() > 1) wRecent.setLabel(recent.subList(1, recent.size()), 0); } 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 b64c01a..8b429a4 100644 --- a/src/main/java/me/towdium/jecalculation/gui/guis/GuiRecipe.java +++ b/src/main/java/me/towdium/jecalculation/gui/guis/GuiRecipe.java @@ -2,9 +2,9 @@ package me.towdium.jecalculation.gui.guis; import codechicken.nei.recipe.IRecipeHandler; import me.towdium.jecalculation.algorithm.CostList; +import me.towdium.jecalculation.data.Controller; import me.towdium.jecalculation.data.label.ILabel; import me.towdium.jecalculation.data.structure.Recipe; -import me.towdium.jecalculation.data.ControllerClient; import me.towdium.jecalculation.gui.JecaGui; import me.towdium.jecalculation.gui.Resource; import me.towdium.jecalculation.gui.drawables.*; @@ -26,11 +26,11 @@ import java.util.stream.Stream; public class GuiRecipe extends WContainer { Pair dest; HashMap> disambiguation = new HashMap<>(); - WSwitcher switcherGroup = new WSwitcher(7, 7, 162, ControllerClient.getGroups()); + WSwitcher switcherGroup = new WSwitcher(7, 7, 162, Controller.getGroups()); WTextField textField = new WTextField(49, 33, 119); WButton buttonCopy = new WButtonIcon(83, 33, 20, 20, Resource.BTN_COPY_N, Resource.BTN_COPY_F, Resource.BTN_COPY_D, "recipe.copy").setDisabled(true).setListenerLeft(() -> { - ControllerClient.addRecipe(switcherGroup.getText(), toRecipe()); + Controller.addRecipe(switcherGroup.getText(), toRecipe()); JecaGui.displayParent(); }); @@ -61,13 +61,13 @@ public class GuiRecipe extends WContainer { WButton buttonSave = new WButtonIcon(26, 33, 20, 20, Resource.BTN_SAVE_N, Resource.BTN_SAVE_F, "recipe.save") .setListenerLeft(() -> { if (dest == null) - ControllerClient.addRecipe(switcherGroup.getText(), toRecipe()); + Controller.addRecipe(switcherGroup.getText(), toRecipe()); else { if (textField.getText().equals(dest.one)) - ControllerClient.setRecipe(dest.one, dest.two, toRecipe()); + Controller.setRecipe(dest.one, dest.two, toRecipe()); else { - ControllerClient.removeRecipe(dest.one, dest.two); - ControllerClient.addRecipe(switcherGroup.getText(), toRecipe()); + Controller.removeRecipe(dest.one, dest.two); + Controller.addRecipe(switcherGroup.getText(), toRecipe()); } } JecaGui.displayParent(); @@ -77,7 +77,7 @@ public class GuiRecipe extends WContainer { .setListenerLeft(() -> setModeNewGroup(true)); WButton buttonDel = new WButtonIcon(102, 33, 20, 20, Resource.BTN_NO_N, Resource.BTN_NO_F, Resource.BTN_NO_D, "recipe.delete").setDisabled(true).setListenerLeft(() -> { - ControllerClient.removeRecipe(dest.one, dest.two); + Controller.removeRecipe(dest.one, dest.two); JecaGui.displayParent(); }); WButton buttonYes = new WButtonIcon(7, 33, 20, 20, Resource.BTN_YES_N, Resource.BTN_YES_F, "recipe.confirm") @@ -93,9 +93,9 @@ public class GuiRecipe extends WContainer { public GuiRecipe(String group, int index) { this(); dest = new Pair<>(group, index); - Recipe r = ControllerClient.getRecipe(group, index); + Recipe r = Controller.getRecipe(group, index); fromRecipe(r); - switcherGroup.setIndex(ControllerClient.getGroups().indexOf(group)); + switcherGroup.setIndex(Controller.getGroups().indexOf(group)); buttonCopy.setDisabled(false); buttonDel.setDisabled(false); } @@ -131,56 +131,51 @@ public class GuiRecipe extends WContainer { // item disamb raw ArrayList> input = new ArrayList<>(); ArrayList> output = new ArrayList<>(); - HashMap> disamb = new HashMap<>(); - - BiConsumer>, List> merge = (dst, list) -> { - if (list.isEmpty()) - return; - dst.stream().filter(p -> { - CostList cl = new CostList(list); - if (p.three.equals(cl)) { - ILabel.MERGER.merge(p.one, ILabel.CONVERTER.first(list), true).ifPresent(i -> p.one = i.one); - p.two.merge(cl, true); - return true; - } else - return false; - }).findAny().orElseGet(() -> { - Triple ret = new Triple<>(ILabel.CONVERTER.first(list), new CostList(list), - new CostList(list)); - dst.add(ret); - return ret; - }); - }; - - BiFunction>, Integer, ArrayList> sort = (src, offset) -> { - ArrayList ret = new ArrayList<>(); - for (int i = 0; i < src.size(); i++) { - Triple p = src.get(i); - ret.add(p.one); - if (!ILabel.CONVERTER.guess(p.three.getLabels()).isEmpty()) - disamb.put(i + offset, p.two.getLabels()); - } - return ret; - }; + disambiguation = new HashMap<>(); // input List itemStacks = recipe.getIngredientStacks(recipeIndex).stream() .map((positionedStack) -> positionedStack.item).collect(Collectors.toList()); - - - merge.accept(input, itemStacks.stream().map(ILabel.Converter::from).collect(Collectors.toList())); + merge(input, itemStacks.stream().map(ILabel.Converter::from).collect(Collectors.toList())); // output ItemStack outputStack = recipe.getResultStack(recipeIndex).item; - merge.accept(output, Stream.of(outputStack).map(ILabel.Converter::from).collect(Collectors.toList())); + merge(output, Stream.of(outputStack).map(ILabel.Converter::from).collect(Collectors.toList())); - groupInput.setLabel(sort.apply(input, 0), 0); - groupOutput.setLabel(sort.apply(output, 14), 0); - disambiguation = disamb; + groupInput.setLabel(sort(input, 0, true), 0); + groupOutput.setLabel(sort(output, 14, false), 0); refresh(); } - Recipe toRecipe() { + private void merge(ArrayList> dst, List list) { + if (list.isEmpty()) return; + dst.stream().filter(p -> { + CostList cl = new CostList(list); + if (p.three.equals(cl)) { + ILabel.MERGER.merge(p.one, ILabel.CONVERTER.first(list), true).ifPresent(i -> p.one = i); + p.two = p.two.merge(cl, true, true); + return true; + } else return false; + }).findAny().orElseGet(() -> { + Triple ret = new Triple<>( + ILabel.CONVERTER.first(list), new CostList(list), new CostList(list)); + dst.add(ret); + return ret; + }); + } + + private ArrayList sort(ArrayList> src, int offset, boolean guess) { + ArrayList ret = new ArrayList<>(); + for (int i = 0; i < src.size(); i++) { + Triple p = src.get(i); + ret.add(p.one); + if (guess && !ILabel.CONVERTER.guess(p.three.getLabels()).isEmpty()) + disambiguation.put(i + offset, p.two.getLabels()); + } + return ret; + } + + private Recipe toRecipe() { return new Recipe(groupInput.getLabels(), groupCatalyst.getLabels(), groupOutput.getLabels()); } diff --git a/src/main/java/me/towdium/jecalculation/gui/guis/GuiSearch.java b/src/main/java/me/towdium/jecalculation/gui/guis/GuiSearch.java index de3ddbe..e58a6ae 100644 --- a/src/main/java/me/towdium/jecalculation/gui/guis/GuiSearch.java +++ b/src/main/java/me/towdium/jecalculation/gui/guis/GuiSearch.java @@ -1,7 +1,7 @@ package me.towdium.jecalculation.gui.guis; import me.towdium.jecalculation.data.structure.Recipe; -import me.towdium.jecalculation.data.ControllerClient; +import me.towdium.jecalculation.data.Controller; import me.towdium.jecalculation.gui.JecaGui; import me.towdium.jecalculation.gui.Resource; import me.towdium.jecalculation.gui.drawables.*; @@ -20,7 +20,7 @@ public class GuiSearch extends WContainer { public GuiSearch() { ArrayList groups = new ArrayList<>(); groups.add(Utilities.I18n.format("gui.search.all")); - groups.addAll(ControllerClient.getGroups()); + groups.addAll(Controller.getGroups()); switcherGroup = new WSwitcher(7, 7, 162, groups).setListener(this::refresh); labelScroll = new WLabelScroll(7, 51, 8, 6, WLabel.enumMode.PICKER, true); add(new WPanel()); @@ -34,7 +34,7 @@ public class GuiSearch extends WContainer { public void refresh() { int iGroup = switcherGroup.getIndex(); - content = iGroup == 0 ? ControllerClient.getRecipes() : ControllerClient.getRecipes(switcherGroup.getText()); + content = iGroup == 0 ? Controller.getRecipes() : Controller.getRecipes(switcherGroup.getText()); labelScroll.setLabels(content.stream().map(i -> i.one.getRep()).collect(Collectors.toCollection(ArrayList::new))); } } diff --git a/src/main/java/me/towdium/jecalculation/network/ClientHandler.java b/src/main/java/me/towdium/jecalculation/network/ClientHandler.java index e5c31e7..bd072c1 100644 --- a/src/main/java/me/towdium/jecalculation/network/ClientHandler.java +++ b/src/main/java/me/towdium/jecalculation/network/ClientHandler.java @@ -2,17 +2,14 @@ package me.towdium.jecalculation.network; import cpw.mods.fml.client.registry.ClientRegistry; import cpw.mods.fml.common.FMLCommonHandler; -import me.towdium.jecalculation.data.ControllerClient; +import me.towdium.jecalculation.data.Controller; import me.towdium.jecalculation.event.Handlers; -import me.towdium.jecalculation.gui.JecaGui; -import me.towdium.jecalculation.gui.guis.GuiCalculator; import me.towdium.jecalculation.command.JecaCommand; import me.towdium.jecalculation.data.label.ILabel; import net.minecraft.client.Minecraft; import net.minecraft.client.settings.KeyBinding; import net.minecraft.entity.player.EntityPlayer; import net.minecraftforge.client.ClientCommandHandler; -import net.minecraftforge.common.MinecraftForge; import org.lwjgl.input.Keyboard; public class ClientHandler { @@ -27,7 +24,7 @@ public class ClientHandler { ILabel.initServer(); ClientCommandHandler.instance.registerCommand(new JecaCommand()); ILabel.initClient(); - ControllerClient.loadFromLocal(); + Controller.loadFromLocal(); } public void init() {