This commit is contained in:
Discreater committed 2021-05-01 22:34:55 +08:00
1 parent d6ead4a4e9
commit 1c05e9d154
37 files changed
+763 -474

No files matched your search

@@ -10,16 +10,11 @@ import me.towdium.jecalculation.data.structure.Recipe;
import me.towdium.jecalculation.data.structure.Recipes;
import me.towdium.jecalculation.utils.Utilities;
import me.towdium.jecalculation.utils.wrappers.Pair;
import me.towdium.jecalculation.utils.wrappers.Trio;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import javax.annotation.ParametersAreNonnullByDefault;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -35,8 +30,10 @@ public class Controller {
public static final String KEY_RECIPES = "recipes";
public static final String KEY_RECENTS = "recents";
public static final String KEY_AMOUNT = "amount";
public static final String KEY_INVENTORY = "inventory";
static Recipes recipesClient;
static Recents recentsClient;
static boolean inventoryClient;
static String amountClient;
static Recipes getRecord() {
@@ -51,26 +48,26 @@ public class Controller {
public static List<Pair<String, Recipes>> discover() {
File dir = JecaConfig.dataDir;
File[] fs = dir.listFiles();
if (fs == null) return new ArrayList<>();
if (fs == null)
return new ArrayList<>();
Function<File, Recipes> read = f -> {
NBTTagCompound nbt = Utilities.Json.read(f);
JustEnoughCalculation.logger.warn("File " + f.getAbsolutePath() + " contains invalid records.");
return nbt == null ? null : new Recipes(nbt);
};
return Arrays.stream(fs)
.map(i -> new Pair<>(i.getName(), read.apply(i)))
.filter(i -> i.two != null)
return Arrays.stream(fs).map(i -> new Pair<>(i.getName(), read.apply(i))).filter(i -> i.two != null)
.collect(Collectors.toList());
}
public static void inport(Recipes recipes, String group) {
ArrayList<Recipe> buffer = new ArrayList<>();
recipes.getGroup(group).forEach(i ->
getRecord().getGroup(group).stream().filter(j -> j.equals(i)).findAny().orElseGet(() -> {
buffer.add(i);
return null;
}));
for (Recipe r : buffer) addRecipe(group, r);
recipes.getGroup(group)
.forEach(i -> getRecord().getGroup(group).stream().filter(j -> j.equals(i)).findAny().orElseGet(() -> {
buffer.add(i);
return null;
}));
for (Recipe r : buffer)
addRecipe(group, r);
}
public static File export(String group) {
@@ -132,16 +129,27 @@ public class Controller {
amountClient = amount;
}
public static boolean getDetectInv() {
return inventoryClient;
}
public static void setDetectInv(boolean b) {
inventoryClient = b;
}
public static List<ILabel> getRecent() {
return recentsClient.getRecords();
}
public static void setRecent(ILabel label) {
recentsClient.push(label);
public static void setRecent(ILabel label, boolean replace) {
recentsClient.push(label, replace);
writeToLocal();
}
public static boolean hasDuplicate(Recipe r) {
return getRecord().hasDuplicate(r);
}
public static void loadFromLocal() {
//noinspection ResultOfMethodCallIgnored
JecaConfig.dataDir.mkdirs();
@@ -151,13 +159,13 @@ public class Controller {
recipesClient = nbt.hasKey(KEY_RECIPES) ? new Recipes(nbt.getCompoundTag(KEY_RECIPES)) : new Recipes();
recentsClient = nbt.hasKey(KEY_RECENTS) ? new Recents(nbt.getTagList(KEY_RECENTS, 10)) : new Recents();
amountClient = nbt.hasKey(KEY_AMOUNT) ? nbt.getString(KEY_AMOUNT) : "";
return;
inventoryClient = !nbt.hasKey(KEY_INVENTORY) || nbt.getBoolean(KEY_INVENTORY);
} else {
recipesClient = new Recipes();
recentsClient = new Recents();
amountClient = "";
inventoryClient = true;
}
file = JecaConfig.defaultFile;
nbt = Utilities.Json.read(file);
recipesClient = nbt == null ? new Recipes() : new Recipes(nbt);
recentsClient = new Recents();
amountClient = "";
}
public static void writeToLocal() {
@@ -166,6 +174,7 @@ public class Controller {
nbt.setTag(KEY_RECENTS, recentsClient.serialize());
nbt.setTag(KEY_RECIPES, recipesClient.serialize());
nbt.setString(KEY_AMOUNT, amountClient);
nbt.setBoolean(KEY_INVENTORY, inventoryClient);
Utilities.Json.write(nbt, file);
}
}
@@ -1,5 +1,6 @@
package me.towdium.jecalculation.data.label;
import codechicken.nei.recipe.IRecipeHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import me.towdium.jecalculation.JustEnoughCalculation;
@@ -15,6 +16,7 @@ import me.towdium.jecalculation.gui.guis.pickers.PickerSimple;
import me.towdium.jecalculation.polyfill.mc.client.renderer.GlStateManager;
import me.towdium.jecalculation.utils.Utilities;
import me.towdium.jecalculation.utils.Utilities.ReversedIterator;
import me.towdium.jecalculation.utils.wrappers.Pair;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -23,10 +25,7 @@ import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -56,7 +55,11 @@ public interface ILabel {
ILabel decreaseAmount();
static void initClient() {
CONVERTER.register(LOreDict::guess);
CONVERTER.register(LItemStack::suggest, Converter.Priority.SUGGEST);
CONVERTER.register(LOreDict::suggest, Converter.Priority.SUGGEST);
CONVERTER.register(LFluidStack::suggest, Converter.Priority.SUGGEST);
CONVERTER.register(LItemStack::fallback, Converter.Priority.FALLBACK);
CONVERTER.register(LOreDict::fallback, Converter.Priority.FALLBACK);
EDITOR.register(PickerSimple.FluidStack::new, "fluid", new LFluidStack(1000, FluidRegistry.WATER));
EDITOR.register(PickerSimple.OreDict::new, "ore", new LOreDict("ingotIron"));
EDITOR.register(PickerPlaceholder::new, "placeholder", new LPlaceholder("example", 1, true));
@@ -64,7 +67,10 @@ public interface ILabel {
MERGER.register("itemStack", "itemStack", Impl.form(LItemStack.class, LItemStack.class, LItemStack::merge));
MERGER.register("oreDict", "oreDict", Impl.form(LOreDict.class, LOreDict.class, LOreDict::mergeSame));
MERGER.register("oreDict", "itemStack", Impl.form(LOreDict.class, LItemStack.class, LOreDict::mergeFuzzy));
MERGER.register("fluidStack", "fluidStack", Impl.form(LFluidStack.class, LFluidStack.class, LFluidStack::merge));
MERGER.register("fluidStack", "fluidStack",
Impl.form(LFluidStack.class, LFluidStack.class, LFluidStack::merge));
MERGER.register("placeholder", "placeholder",
Impl.form(LPlaceholder.class, LPlaceholder.class, LPlaceholder::merge));
}
long getAmount();
@@ -137,7 +143,8 @@ public interface ILabel {
*/
public Optional<ILabel> merge(ILabel a, ILabel b) {
MergerFunction mf = functions.get(a.getIdentifier(), b.getIdentifier());
if (mf == null) return Optional.empty();
if (mf == null)
return Optional.empty();
return Optional.ofNullable(mf.merge(a, b));
}
@@ -190,11 +197,13 @@ public interface ILabel {
public ILabel deserialize(NBTTagCompound nbt) {
String s = nbt.getString(KEY_IDENTIFIER);
Function<NBTTagCompound, ILabel> func = idToData.get(s);
if (func == null) JustEnoughCalculation.logger.warn("Unrecognized identifier \"" + s + "\", abort");
else try {
return func.apply(nbt.getCompoundTag(KEY_CONTENT));
} catch (SerializationException ignored) {
}
if (func == null)
JustEnoughCalculation.logger.warn("Unrecognized identifier \"" + s + "\", abort");
else
try {
return func.apply(nbt.getCompoundTag(KEY_CONTENT));
} catch (SerializationException ignored) {
}
return EMPTY;
}
@@ -219,7 +228,15 @@ public interface ILabel {
* It can also convert ItemStack or FluidStack to ILabel
*/
class Converter {
ArrayList<Function<List<ILabel>, List<ILabel>>> handlers = new ArrayList<>();
static EnumMap<Priority, ArrayList<ConverterFunction>> handlers;
public enum Priority {SUGGEST, FALLBACK}
static {
handlers = new EnumMap<>(Priority.class);
handlers.put(Priority.SUGGEST, new ArrayList<>());
handlers.put(Priority.FALLBACK, new ArrayList<>());
}
public static ILabel from(@Nullable Object o) {
if (o == null)
@@ -232,20 +249,37 @@ public interface ILabel {
throw new RuntimeException("Unrecognized ingredient type: " + o.getClass());
}
public void register(Function<List<ILabel>, List<ILabel>> handler) {
handlers.add(handler);
public void register(ConverterFunction handler, Priority priority) {
handlers.get(priority).add(handler);
}
// get most possible guess from labels
public ILabel first(List<ILabel> labels) {
List<ILabel> guess = guess(labels);
public ILabel first(List<ILabel> labels, @Nullable IRecipeHandler context) {
List<ILabel> guess = guess(labels, context).one;
return guess.isEmpty() ? labels.get(0) : guess.get(0);
}
public ILabel first(List<ILabel> labels) {
return first(labels, null);
}
// to test if the labels can be converted to other labels (like oreDict)
public List<ILabel> guess(List<ILabel> labels) {
return new ReversedIterator<>(handlers).stream().flatMap(h -> h.apply(labels).stream())
.collect(Collectors.toList());
public Pair<List<ILabel>, List<ILabel>> guess(List<ILabel> labels) {
return guess(labels, null);
}
public Pair<List<ILabel>, List<ILabel>> guess(List<ILabel> labels, @Nullable IRecipeHandler context) {
List<ILabel> ret = new ArrayList<>();
List<ILabel> suggest = new ReversedIterator<>(handlers.get(Priority.SUGGEST)).stream().flatMap(
h -> h.convert(labels, context).stream()).collect(Collectors.toList());
List<ILabel> fallback = new ReversedIterator<>(handlers.get(Priority.FALLBACK)).stream().flatMap(
h -> h.convert(labels, context).stream()).collect(Collectors.toList());
return new Pair<>(suggest, fallback);
}
@FunctionalInterface
public interface ConverterFunction {
List<ILabel> convert(List<ILabel> a, @Nullable IRecipeHandler context);
}
}
@@ -440,17 +474,22 @@ public interface ILabel {
long amountD = d.isPercent() ? d.getAmount() : Math.multiplyExact(d.getAmount(), 100);
long amount = Math.addExact(amountC, amountD);
long amountI = (amount > 0 ? Math.addExact(amount, 99) : Math.subtractExact(amount, 99)) / 100;
if (amount == 0) return EMPTY;
else if (amount > 0) return d.copy().setAmount(d.isPercent() ? amount : amountI);
else return c.copy().setAmount(c.isPercent() ? amount : amountI);
} else return null;
if (amount == 0)
return EMPTY;
else if (amount > 0)
return d.copy().setAmount(d.isPercent() ? amount : amountI);
else
return c.copy().setAmount(c.isPercent() ? amount : amountI);
} else
return null;
};
}
@Override
public ILabel multiply(float i) {
float amount = i * getAmount();
if (amount > Long.MAX_VALUE) throw new ArithmeticException("Multiply overflow");
if (amount > Long.MAX_VALUE)
throw new ArithmeticException("Multiply overflow");
setAmount((long) amount);
return this;
}
@@ -460,8 +499,7 @@ public interface ILabel {
@SideOnly(Side.CLIENT)
public void getToolTip(List<String> existing, boolean detailed) {
if (detailed)
existing.add(
FORMAT_GREY + Utilities.I18n.get("label.common.tooltip.amount", getAmountString(false)));
existing.add(FORMAT_GREY + Utilities.I18n.get("label.common.amount", getAmountString(false)));
}
@Override
@@ -481,7 +519,8 @@ public interface ILabel {
public NBTTagCompound toNbt() {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setLong(KEY_AMOUNT, amount);
if (percent) nbt.setBoolean(KEY_PERCENT, true);
if (percent)
nbt.setBoolean(KEY_PERCENT, true);
return nbt;
}
@@ -1,5 +1,6 @@
package me.towdium.jecalculation.data.label.labels;
import codechicken.nei.recipe.IRecipeHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import me.towdium.jecalculation.gui.JecaGui;
@@ -13,6 +14,8 @@ import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -122,7 +125,7 @@ public class LFluidStack extends ILabel.Impl {
@SideOnly(Side.CLIENT)
public void getToolTip(List<String> existing, boolean detailed) {
if (detailed) existing.add(FORMAT_GREY +
Utilities.I18n.get("label.common.tooltip.amount", Long.toString(getAmount())) + "mB");
Utilities.I18n.get("label.common.amount", Long.toString(getAmount())) + "mB");
existing.add(FORMAT_BLUE + FORMAT_ITALIC + Utilities.getModName(fluid));
}
@@ -136,7 +139,11 @@ public class LFluidStack extends ILabel.Impl {
@Override
public int hashCode() {
return fluid.getUnlocalizedName().hashCode() ^ (int) amount ^ (nbt == null ? 0 : nbt.hashCode());
return super.hashCode() ^ fluid.getUnlocalizedName().hashCode() ^ (nbt == null ? 0 : nbt.hashCode());
}
public static List<ILabel> suggest(List<ILabel> iss, @Nullable IRecipeHandler rl) {
return new ArrayList<>();
}
public static boolean merge(ILabel a, ILabel b) {
@@ -1,5 +1,6 @@
package me.towdium.jecalculation.data.label.labels;
import codechicken.nei.recipe.IRecipeHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import me.towdium.jecalculation.data.label.ILabel;
@@ -12,6 +13,8 @@ import net.minecraft.nbt.NBTTagCompound;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -77,13 +80,13 @@ public class LItemStack extends ILabel.Impl {
boolean fNbt) {
Objects.requireNonNull(item);
this.item = item;
this.meta = meta;
this.nbt = nbt;
this.meta = fMeta ? 0 : meta;
this.nbt = fNbt ? null : nbt;
this.fMeta = fMeta;
this.fCap = fCap;
this.fNbt = fNbt;
temp = new ItemStack(item, 1, meta);
temp.setTagCompound(nbt);
temp = new ItemStack(item, 1, this.meta);
temp.setTagCompound(this.nbt);
}
@@ -103,18 +106,60 @@ public class LItemStack extends ILabel.Impl {
return false;
}
public ILabel setFMeta(boolean f) {
public static List<ILabel> suggest(List<ILabel> iss, @Nullable IRecipeHandler rl) {
if (iss.size() == 0) return new ArrayList<>();
for (ILabel i : iss) if (!(i instanceof LItemStack)) return new ArrayList<>();
LItemStack lis = (LItemStack) iss.get(0);
boolean fMeta = false;
boolean fNbt = false;
boolean fCap = false;
for (ILabel i : iss) {
LItemStack ii = (LItemStack) i;
if (ii.item != lis.item) return new ArrayList<>();
if (ii.meta != lis.meta || ii.fMeta) fMeta = true;
if (!Objects.equals(ii.nbt, lis.nbt)) fNbt = true;
}
if (fMeta || fNbt || fCap) return Collections.singletonList(
lis.copy().setFCap(fCap).setFMeta(fMeta).setFNbt(fNbt));
else return new ArrayList<>();
}
public static List<ILabel> fallback(List<ILabel> iss, @Nullable IRecipeHandler rl) {
List<ILabel> ret = new ArrayList<>();
if (iss.size() == 1) {
ILabel label = iss.get(0);
if (!(label instanceof LItemStack)) return ret;
LItemStack lis = (LItemStack) label;
if (lis.fCap || lis.fNbt || lis.fMeta) return new ArrayList<>();
ret.add(lis.copy().setFMeta(true));
ret.add(lis.copy().setFNbt(true));
ret.add(lis.copy().setFCap(true));
ret.add(lis.copy().setFMeta(true).setFNbt(true).setFCap(true));
}
return ret;
}
public LItemStack setFMeta(boolean f) {
fMeta = f;
if (f) meta = 0;
temp = new ItemStack(item, 1, meta);
temp.setTagCompound(nbt);
return this;
}
public ILabel setFNbt(boolean f) {
public LItemStack setFNbt(boolean f) {
fNbt = f;
if (f) nbt = null;
temp = new ItemStack(item, 1, meta);
temp.setTagCompound(nbt);
return this;
}
public ILabel setFCap(boolean f) {
public LItemStack setFCap(boolean f) {
fCap = f;
temp = new ItemStack(item, 1, meta);
temp.setTagCompound(nbt);
return this;
}
@@ -126,6 +171,9 @@ public class LItemStack extends ILabel.Impl {
@SideOnly(Side.CLIENT)
public void getToolTip(List<String> existing, boolean detailed) {
super.getToolTip(existing, detailed);
if (fMeta) existing.add(FORMAT_GREY + Utilities.I18n.get("label.item_stack.fuzzy_meta"));
if (fNbt) existing.add(FORMAT_GREY + Utilities.I18n.get("label.item_stack.fuzzy_nbt"));
if (fCap) existing.add(FORMAT_GREY + Utilities.I18n.get("label.item_stack.fuzzy_cap"));
existing.add(FORMAT_BLUE + FORMAT_ITALIC + Utilities.getModName(item));
}
@@ -1,5 +1,6 @@
package me.towdium.jecalculation.data.label.labels;
import codechicken.nei.recipe.IRecipeHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import me.towdium.jecalculation.JustEnoughCalculation;
@@ -9,16 +10,19 @@ import me.towdium.jecalculation.gui.Resource;
import me.towdium.jecalculation.polyfill.mc.util.NonNullList;
import me.towdium.jecalculation.utils.ItemStackHelper;
import me.towdium.jecalculation.utils.Utilities;
import me.towdium.jecalculation.utils.wrappers.Wrapper;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.oredict.OreDictionary;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.function.BiPredicate;
import java.util.stream.Collectors;
/**
@@ -53,10 +57,6 @@ public class LOreDict extends ILabel.Impl {
name = nbt.getString(KEY_NAME);
}
public boolean isEmpty() {
return OreDictionary.getOres(name).isEmpty();
}
@Override
@Nonnull
public ItemStack getRepresentation() {
@@ -97,53 +97,44 @@ public class LOreDict extends ILabel.Impl {
return false;
}
public static List<ILabel> guess(List<ILabel> iss) {
public static List<ILabel> suggest(List<ILabel> iss, @Nullable IRecipeHandler rl) {
ILabel l = iss.get(0);
if (!(l instanceof LItemStack)) return new ArrayList<>();
LItemStack lis = (LItemStack) l;
HashSet<Integer> ids = new HashSet<>();
long amount = l.getAmount();
for (int i : OreDictionary.getOreIDs(((LItemStack) l).getRep()))
if (check(i, iss))
long amount = lis.getAmount();
for (int i : OreDictionary.getOreIDs(lis.getRep()))
if (check(i, iss, true)) ids.add(i);
return ids.stream().map(i -> new LOreDict(OreDictionary.getOreName(i), amount))
.collect(Collectors.toList());
}
public static List<ILabel> fallback(List<ILabel> iss, @Nullable IRecipeHandler rl) {
ILabel l = iss.get(0);
if (!(l instanceof LItemStack)) return new ArrayList<>();
LItemStack lis = (LItemStack) l;
HashSet<Integer> ids = new HashSet<>();
long amount = lis.getAmount();
for (int i : OreDictionary.getOreIDs(lis.getRep()))
if (check(i, iss, false))
ids.add(i);
return ids.stream().map(i -> new LOreDict(OreDictionary.getOreName(i), amount)).collect(Collectors.toList());
}
// check labels in the list suitable for the ore id
private static boolean check(int id, List<ILabel> labels) {
private static boolean check(int id, List<ILabel> labels, boolean biDir) {
ArrayList<ItemStack> ores = OreDictionary.getOres(OreDictionary.getOreName(id));
if (labels.size() == 1 && ores.size() == 1 &&
(ores.get(0).getItemDamage() == OreDictionary.WILDCARD_VALUE || !MODE_FORCE))
if (labels.size() == 1 && ores.size() == 1 && biDir && !MODE_FORCE)
return false;
boolean acceptable = true;
for (ItemStack ore : ores) {
boolean found = false;
for (ILabel label : labels) {
if (label instanceof LItemStack &&
OreDictionary.itemMatches(ore, ((LItemStack) label).getRep(), false)) {
found = true;
break;
}
}
if (!found) {
acceptable = false;
break;
}
}
for (ILabel label : labels) {
boolean found = false;
for (ItemStack ore : ores) {
if (label instanceof LItemStack &&
OreDictionary.itemMatches(ore, ((LItemStack) label).getRep(), false)) {
found = true;
break;
}
}
if (!found) {
acceptable = false;
break;
}
}
return acceptable;
Wrapper<Boolean> acceptable = new Wrapper<>(true);
BiPredicate<ILabel, ItemStack> match = (l, o) -> l instanceof LItemStack
&& OreDictionary.itemMatches(o, ((LItemStack) l).getRep(), false);
if (biDir) ores.stream().filter(ore -> labels.stream().noneMatch(label -> match.test(label, ore)))
.findAny().ifPresent(i -> acceptable.value = false);
labels.stream().filter(label -> ores.stream().noneMatch(ore -> match.test(label, ore)))
.findAny().ifPresent(i -> acceptable.value = false);
return acceptable.value;
}
@Override
@@ -164,21 +155,7 @@ public class LOreDict extends ILabel.Impl {
@Override
@SideOnly(Side.CLIENT)
public void drawLabel(JecaGui gui) {
NonNullList<ItemStack> list = NonNullList.create();
OreDictionary.getOres(name).forEach(is -> {
if (is.getItemDamage() == OreDictionary.WILDCARD_VALUE) {
is.getItem().getSubItems(is.getItem(), CreativeTabs.tabAllSearch, list);
} else
list.add(is);
});
if (list.isEmpty())
return;
long index = System.currentTimeMillis() / 1500;
//GlStateManager.pushMatrix();
//GlStateManager.translate(1, 1, 0);
//GlStateManager.scale(14f / 16, 14f / 16, 1);
gui.drawItemStack(0, 0, list.get((int) (index % list.size())), false);
//GlStateManager.popMatrix();
gui.drawItemStack(0, 0, getRepresentation(), false);
gui.drawResource(Resource.LBL_FRAME, 0, 0);
}
@@ -39,7 +39,7 @@ public class LPlaceholder extends ILabel.Impl {
public LPlaceholder(String name, long amount, boolean silent) {
super(amount, false);
this.name = name;
if (!silent) getRecord().push(new LPlaceholder(name, 1, true));
if (!silent) getRecord().push(new LPlaceholder(name, 1, true), false);
}
public LPlaceholder(LPlaceholder label) {
@@ -111,4 +111,12 @@ public class LPlaceholder extends ILabel.Impl {
super.getToolTip(existing, detailed);
existing.add(FORMAT_BLUE + FORMAT_ITALIC + JustEnoughCalculation.Reference.MODNAME);
}
public static boolean merge(ILabel a, ILabel b) {
if (a instanceof LPlaceholder && b instanceof LPlaceholder) {
LPlaceholder lpA = (LPlaceholder) a;
LPlaceholder lpB = (LPlaceholder) b;
return lpA.name.equals(lpB.name);
} else return false;
}
}
@@ -158,7 +158,7 @@ public class CostList {
if (label.getAmount() >= 0) continue;
while (iterator.hasNext()) {
Recipe r = iterator.next();
if (r.matches(label)) return new Pair<>(r, r.multiplier(label));
if (r.matches(label).isPresent()) return new Pair<>(r, r.multiplier(label));
}
iterator = Controller.recipeIterator();
}
@@ -187,7 +187,7 @@ public class CostList {
.collect(Collectors.toList());
}
public List<ILabel> getOutputs(List<ILabel> ignore) {
public List<ILabel> getOutputs(List<ILabel> ignore) { // TODO check logic
return getCurrent().labels.stream()
.map(i -> i.copy().multiply(-1))
.map(i -> ignore.stream().flatMap(j -> stream(ILabel.MERGER.merge(i, j))).findFirst().orElse(i))
@@ -20,14 +20,14 @@ public class Recents {
.filter(n -> n instanceof NBTTagCompound)
.map(n -> ILabel.SERIALIZER.deserialize((NBTTagCompound) n))
.collect(Collectors.toList());
new Utilities.ReversedIterator<>(ls).forEachRemaining(l -> record.push(l));
new Utilities.ReversedIterator<>(ls).forEachRemaining(l -> record.push(l, false));
}
public Recents() {
}
public void push(ILabel label) {
record.push(label);
public void push(ILabel label, boolean replace) {
record.push(label, replace);
}
public ILabel getLatest() {
@@ -9,15 +9,13 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
@@ -33,7 +31,6 @@ public class Recipe {
ILabel[] input;
ILabel[] catalyst;
ILabel[] output;
int hashcode;
public Recipe(NBTTagCompound nbt) {
this(readNbtList(nbt.getTagList(KEY_INPUT, 10)),
@@ -53,19 +50,15 @@ public class Recipe {
for (int j = ls.length; j < i; j++) ret[j] = ILabel.EMPTY;
return ret;
};
this.input = convert.apply(input, 16);
this.catalyst = convert.apply(catalyst, 8);
this.output = convert.apply(output, 8);
Wrapper<Integer> hash = new Wrapper<>(0);
Consumer<ILabel[]> hasher = (ls) -> Arrays.stream(ls)
.filter(Objects::nonNull).forEach(i -> hash.value ^= i.hashCode());
hasher.accept(input);
hasher.accept(catalyst);
hasher.accept(output);
hashcode = hash.value;
this.input = convert.apply(input, 14);
this.catalyst = convert.apply(catalyst, 7);
this.output = convert.apply(output, 7);
Stream.of(input, output).forEach(i -> Arrays.stream(i).filter(j -> j != ILabel.EMPTY).findAny()
.orElseThrow(() -> new IllegalArgumentException("Invalid recipe")));
}
static private List<ILabel> readNbtList(NBTTagList list) {
return StreamSupport.stream(NBTHelper.spliterator(list), false)
.filter(n -> n instanceof NBTTagCompound)
@@ -75,12 +68,18 @@ public class Recipe {
@Override
public int hashCode() {
return hashcode;
Wrapper<Integer> hash = new Wrapper<>(0);
Consumer<ILabel[]> hasher = (ls) -> Arrays.stream(ls)
.filter(Objects::nonNull).forEach(i -> hash.value ^= i.hashCode());
hasher.accept(input);
hasher.accept(catalyst);
hasher.accept(output);
return hash.value;
}
@Override
public boolean equals(Object obj) {
if (obj == null || hashcode != obj.hashCode() || !(obj instanceof Recipe)) return false;
if (!(obj instanceof Recipe)) return false;
Recipe r = (Recipe) obj;
BiPredicate<ILabel[], ILabel[]> p = (i, j) -> {
if (i.length != j.length) return false;
@@ -133,8 +132,8 @@ public class Recipe {
return ret;
}
public boolean matches(ILabel label) {
return Arrays.stream(output).anyMatch(i -> ILabel.MERGER.merge(label, i).isPresent());
public Optional<ILabel> matches(ILabel label) {
return Arrays.stream(output).filter(i -> ILabel.MERGER.merge(label, i).isPresent()).findAny();
}
public long multiplier(ILabel label) {
@@ -1,7 +1,10 @@
package me.towdium.jecalculation.data.structure;
import me.towdium.jecalculation.JecaConfig;
import me.towdium.jecalculation.JustEnoughCalculation;
import me.towdium.jecalculation.data.label.ILabel;
import me.towdium.jecalculation.polyfill.NBTHelper;
import me.towdium.jecalculation.utils.Utilities;
import me.towdium.jecalculation.utils.wrappers.Pair;
import me.towdium.jecalculation.utils.wrappers.Trio;
import net.minecraft.nbt.NBTTagCompound;
@@ -9,6 +12,7 @@ import net.minecraft.nbt.NBTTagList;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.io.File;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
@@ -19,32 +23,41 @@ import java.util.stream.StreamSupport;
@ParametersAreNonnullByDefault
public class Recipes {
LinkedHashMap<String, List<Recipe>> records = new LinkedHashMap<>();
HashSet<Recipe> cache = new HashSet<>();
public Recipes() {
File file = JecaConfig.defaultFile;
NBTTagCompound nbt = Utilities.Json.read(file);
if (nbt == null) JustEnoughCalculation.logger.info("Failed to load default records at " + file + ".");
else {
JustEnoughCalculation.logger.info("Loading default records at " + file + ".");
deserialize(nbt);
}
}
public Recipes(NBTTagCompound nbt) {
deserialize(nbt);
}
public void deserialize(NBTTagCompound nbt) {
protected void deserialize(NBTTagCompound nbt) {
Set<String> keySet = (Set<String>) nbt.func_150296_c();
keySet.stream().sorted().forEach(i -> {
NBTTagList group = nbt.getTagList(i, 10);
StreamSupport.stream(NBTHelper.spliterator(group), false)
.filter(r -> r instanceof NBTTagCompound)
.forEach(r -> add(i, new Recipe((NBTTagCompound) r)));
.forEach(r -> {
try {
add(i, new Recipe((NBTTagCompound) r));
} catch (IllegalArgumentException e) {
JustEnoughCalculation.logger.warn("Invalid recipe record :" + r);
}
});
});
}
public void add(String group, Recipe recipe) {
if (records.containsKey(group)) {
records.get(group).add(recipe);
} else {
ArrayList<Recipe> l = new ArrayList<>();
l.add(recipe);
records.put(group, l);
}
records.computeIfAbsent(group, k -> new ArrayList<>()).add(recipe);
cache.add(recipe);
}
public void modify(String group, int index, @Nullable Recipe recipe) {
@@ -54,7 +67,9 @@ public class Recipes {
}
public void set(String group, int index, Recipe recipe) {
records.get(group).set(index, recipe);
Recipe r = records.get(group).set(index, recipe);
cache.remove(r);
cache.add(recipe);
}
public int size() {
@@ -67,7 +82,7 @@ public class Recipes {
public void remove(String group, int index) {
List<Recipe> l = records.get(group);
l.remove(index);
cache.remove(l.remove(index));
if (l.isEmpty()) records.remove(group);
}
@@ -87,6 +102,12 @@ public class Recipes {
records.forEach(consumer);
}
/**
* Do not modify return value!
*
* @param group Name of group to get
* @return List of Recipes in group
*/
public List<Recipe> getGroup(String group) {
return records.get(group);
}
@@ -132,5 +153,13 @@ public class Recipes {
while (j == null || !j.hasNext()) if (i.hasNext()) j = i.next().getValue().iterator();
return j.next();
}
public Stream<Recipe> stream() {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(this, Spliterator.ORDERED), false);
}
}
public boolean hasDuplicate(Recipe r) {
return cache.contains(r);
}
}
@@ -57,6 +57,12 @@ public class JecaGui extends GuiContainer {
((JecContainer) inventorySlots).setGui(this);
}
@Override
public void initGui() {
this.guiLeft = (this.width - this.xSize) / 2;
this.guiTop = (this.height - this.ySize) / 2;
}
public static boolean mouseIn(int xPos, int yPos, int xSize, int ySize, int xMouse, int yMouse) {
return xMouse > xPos && yMouse > yPos && xMouse <= xPos + xSize && yMouse <= yPos + ySize;
}
@@ -173,22 +179,13 @@ public class JecaGui extends GuiContainer {
int yMouse = this.height - Mouse.getEventY() * this.height / this.mc.displayHeight - 1;
int button = Mouse.getEventButton();
if (Mouse.getEventButtonState()) {
if (button == 0) {
if (hand == ILabel.EMPTY) {
ILabel e = NEIPlugin.getLabelUnderMouse();
if (e != ILabel.EMPTY) {
hand = e;
return true;
}
} else {
if (!mouseIn(guiLeft, guiTop, width, height, xMouse, yMouse)) {
hand = ILabel.EMPTY;
return true;
}
}
} else if (button == 1) {
if (hand != ILabel.EMPTY) {
hand = ILabel.EMPTY;
if (hand != ILabel.EMPTY) {
hand = ILabel.EMPTY;
return true;
} else {
ILabel e = NEIPlugin.getLabelUnderMouse();
if (e != ILabel.EMPTY) {
hand = e;
return true;
}
}
@@ -295,7 +292,7 @@ public class JecaGui extends GuiContainer {
boolean unicode = fontRendererObj.getUnicodeFlag();
if (f.half) fontRendererObj.setUnicodeFlag(false);
GlStateManager.pushMatrix();
GlStateManager.translate(xPos, yPos, 0);
GlStateManager.translate(unicode && f.half ? xPos - 5 : xPos, yPos, 0);
if (f.half) GlStateManager.scale(0.5, 0.5, 1);
r.run();
GlStateManager.popMatrix();
@@ -26,6 +26,7 @@ public class Resource {
public static final Resource BTN_SEARCH_F = getIcon(2, 0);
public static final Resource BTN_SAVE_N = getIcon(3, 1);
public static final Resource BTN_SAVE_F = getIcon(3, 0);
public static final Resource BTN_SAVE_D = getIcon(3, 2);
public static final Resource BTN_COPY_N = getIcon(4, 1);
public static final Resource BTN_COPY_F = getIcon(4, 0);
public static final Resource BTN_COPY_D = getIcon(4, 2);
@@ -52,63 +53,78 @@ public class Resource {
public static final Resource BTN_LIST_N = getIcon(12, 1);
public static final Resource BTN_LIST_F = getIcon(12, 0);
public static final Resource BTN_LIST_D = getIcon(12, 2);
public static final Resource BTN_META_N_N = getIcon(14, 0);
public static final Resource BTN_META_N_F = getIcon(13, 0);
public static final Resource BTN_META_F_N = getIcon(16, 0);
public static final Resource BTN_META_F_F = getIcon(15, 0);
public static final Resource BTN_META_D = getIcon(17, 0);
public static final Resource BTN_NBT_N_N = getIcon(14, 1);
public static final Resource BTN_NBT_N_F = getIcon(13, 1);
public static final Resource BTN_NBT_F_N = getIcon(16, 1);
public static final Resource BTN_NBT_F_F = getIcon(15, 1);
public static final Resource BTN_NBT_D = getIcon(17, 1);
public static final Resource BTN_CAP_N_N = getIcon(14, 2);
public static final Resource BTN_CAP_N_F = getIcon(13, 2);
public static final Resource BTN_CAP_F_N = getIcon(16, 2);
public static final Resource BTN_CAP_F_F = getIcon(15, 2);
public static final Resource BTN_CAP_D = getIcon(17, 2);
public static final Resource WGT_BUTTON_N = new Resource(40, 232, 20, 20);
public static final Resource WGT_BUTTON_F = new Resource(60, 232, 20, 20);
public static final Resource WGT_BUTTON_D = new Resource(80, 232, 20, 20);
public static final Resource WGT_BUTTON_S_N = new Resource(0, 212, 20, 20);
public static final Resource WGT_BUTTON_S_F = new Resource(20, 212, 20, 20);
public static final Resource WGT_BUTTON_S_D = new Resource(40, 212, 20, 20);
public static final Resource WGT_SLOT = new Resource(20, 232, 20, 20);
public static final Resource WGT_LINE = new Resource(0, 252, 163, 4);
public static final Resource WGT_PANEL_F = new Resource(0, 232, 20, 20);
public static final Resource WGT_PAGER_FN = new Resource(100, 232, 20, 20);
public static final Resource WGT_PAGER_F0 = new Resource(120, 232, 20, 20);
public static final Resource WGT_PANEL_N = new Resource(140, 232, 20, 20);
public static final Resource WGT_ARR_L_F = new Resource(160, 232, 7, 9);
public static final Resource WGT_ARR_L_N = new Resource(167, 232, 7, 9);
public static final Resource WGT_ARR_L_D = new Resource(174, 232, 7, 9);
public static final Resource WGT_ARR_R_F = new Resource(160, 242, 7, 9);
public static final Resource WGT_ARR_R_N = new Resource(167, 242, 7, 9);
public static final Resource WGT_ARR_R_D = new Resource(174, 242, 7, 9);
public static final Resource WGT_SCROLL = new Resource(181, 232, 12, 15);
public static final Resource WGT_HELP_F = new Resource(193, 232, 20, 20);
public static final Resource WGT_HELP_N = new Resource(213, 232, 20, 20);
public static final Resource WGT_HELP_B = new Resource(233, 232, 20, 20);
public static final Resource ICN_RECENT_N = getIcon(0, 4);
public static final Resource ICN_RECENT_F = getIcon(0, 3);
public static final Resource ICN_INPUT_N = getIcon(1, 4);
public static final Resource ICN_INPUT_F = getIcon(1, 3);
public static final Resource ICN_OUTPUT_N = getIcon(2, 4);
public static final Resource ICN_OUTPUT_F = getIcon(2, 3);
public static final Resource ICN_CATALYST_N = getIcon(3, 4);
public static final Resource ICN_CATALYST_F = getIcon(3, 3);
public static final Resource ICN_LIST_N = getIcon(4, 4);
public static final Resource ICN_LIST_F = getIcon(4, 3);
public static final Resource ICN_LABEL_N = getIcon(5, 4);
public static final Resource ICN_LABEL_F = getIcon(5, 3);
public static final Resource ICN_HELP_N = getIcon(6, 4);
public static final Resource ICN_HELP_F = getIcon(6, 3);
public static final Resource ICN_STACK_N = getIcon(7, 4);
public static final Resource ICN_STACK_F = getIcon(7, 3);
public static final Resource ICN_TEXT_N = getIcon(8, 4);
public static final Resource ICN_TEXT_F = getIcon(8, 3);
public static final Resource ICN_MULTI_N = getIcon(9, 4);
public static final Resource ICN_MULTI_F = getIcon(9, 3);
public static final Resource BTN_IMPORT_N = getIcon(13, 1);
public static final Resource BTN_IMPORT_F = getIcon(13, 0);
public static final Resource BTN_IMPORT_D = getIcon(13, 2);
public static final Resource BTN_EXPORT_N_N = getIcon(14, 1);
public static final Resource BTN_EXPORT_N_F = getIcon(14, 0);
public static final Resource BTN_EXPORT_N_D = getIcon(14, 2);
public static final Resource BTN_EXPORT_1_N = getIcon(15, 1);
public static final Resource BTN_EXPORT_1_F = getIcon(15, 0);
public static final Resource BTN_EXPORT_1_D = getIcon(15, 2);
public static final Resource BTN_INV_E_N = getIcon(16, 1);
public static final Resource BTN_INV_E_F = getIcon(16, 0);
public static final Resource BTN_INV_D_N = getIcon(17, 1);
public static final Resource BTN_INV_D_F = getIcon(17, 0);
public static final Resource BTN_CAP_N_N = getIcon(0, 4);
public static final Resource BTN_CAP_N_F = getIcon(0, 3);
public static final Resource BTN_CAP_F_N = getIcon(1, 4);
public static final Resource BTN_CAP_F_F = getIcon(1, 3);
public static final Resource BTN_CAP_D = getIcon(0, 5);
public static final Resource BTN_META_N_N = getIcon(2, 4);
public static final Resource BTN_META_N_F = getIcon(2, 3);
public static final Resource BTN_META_F_N = getIcon(3, 4);
public static final Resource BTN_META_F_F = getIcon(3, 3);
public static final Resource BTN_META_D = getIcon(2, 5);
public static final Resource BTN_NBT_N_N = getIcon(4, 4);
public static final Resource BTN_NBT_N_F = getIcon(4, 3);
public static final Resource BTN_NBT_F_N = getIcon(5, 4);
public static final Resource BTN_NBT_F_F = getIcon(5, 3);
public static final Resource BTN_NBT_D = getIcon(4, 5);
public static final Resource WGT_BUTTON_N = getWidget(0);
public static final Resource WGT_BUTTON_F = getWidget(1);
public static final Resource WGT_BUTTON_D = getWidget(2);
public static final Resource WGT_BUTTON_S_N = getWidget(3);
public static final Resource WGT_BUTTON_S_F = getWidget(4);
public static final Resource WGT_BUTTON_S_D = getWidget(5);
public static final Resource WGT_SLOT = getWidget(6);
public static final Resource WGT_PANEL_N = getWidget(7);
public static final Resource WGT_PANEL_F = getWidget(8);
public static final Resource WGT_PAGER_F = getWidget(9);
public static final Resource WGT_HELP_B = getWidget(10);
public static final Resource WGT_LCD_BG = getWidget(11);
public static final Resource WGT_ARR_L_F = new Resource(112, 132, 7, 10);
public static final Resource WGT_ARR_L_N = new Resource(119, 132, 7, 10);
public static final Resource WGT_ARR_L_D = new Resource(126, 132, 7, 10);
public static final Resource WGT_ARR_R_F = new Resource(112, 142, 7, 10);
public static final Resource WGT_ARR_R_N = new Resource(119, 142, 7, 10);
public static final Resource WGT_ARR_R_D = new Resource(126, 142, 7, 10);
public static final Resource WGT_SCROLL = new Resource(133, 132, 14, 17);
public static final Resource WGT_HELP_F = new Resource(147, 132, 20, 20);
public static final Resource WGT_HELP_N = new Resource(167, 132, 20, 20);
public static final Resource ICN_RECENT_N = getIcon(0, 7);
public static final Resource ICN_RECENT_F = getIcon(0, 6);
public static final Resource ICN_INPUT_N = getIcon(1, 7);
public static final Resource ICN_INPUT_F = getIcon(1, 6);
public static final Resource ICN_OUTPUT_N = getIcon(2, 7);
public static final Resource ICN_OUTPUT_F = getIcon(2, 6);
public static final Resource ICN_CATALYST_N = getIcon(3, 7);
public static final Resource ICN_CATALYST_F = getIcon(3, 6);
public static final Resource ICN_LIST_N = getIcon(4, 7);
public static final Resource ICN_LIST_F = getIcon(4, 6);
public static final Resource ICN_LABEL_N = getIcon(5, 7);
public static final Resource ICN_LABEL_F = getIcon(5, 6);
public static final Resource ICN_HELP_N = getIcon(6, 7);
public static final Resource ICN_HELP_F = getIcon(6, 6);
public static final Resource ICN_STACK_N = getIcon(7, 7);
public static final Resource ICN_STACK_F = getIcon(7, 6);
public static final Resource ICN_TEXT_N = getIcon(8, 7);
public static final Resource ICN_TEXT_F = getIcon(8, 6);
public static final Resource ICN_MULTI_N = getIcon(9, 7);
public static final Resource ICN_MULTI_F = getIcon(9, 6);
public static final Resource LBL_FRAME = getLabel(0);
public static final Resource LBL_FLUID = getLabel(1);
public static final Resource LBL_UNIV_B = getLabel(2);
@@ -120,7 +136,7 @@ public class Resource {
public static final ResourceGroup BTN_LABEL = new ResourceGroup(BTN_LABEL_N, BTN_LABEL_F);
public static final ResourceGroup BTN_NEW = new ResourceGroup(BTN_NEW_N, BTN_NEW_F);
public static final ResourceGroup BTN_SEARCH = new ResourceGroup(BTN_SEARCH_N, BTN_SEARCH_F);
public static final ResourceGroup BTN_SAVE = new ResourceGroup(BTN_SAVE_N, BTN_SAVE_F);
public static final ResourceGroup BTN_SAVE = new ResourceGroup(BTN_SAVE_N, BTN_SAVE_F, BTN_SAVE_D);
public static final ResourceGroup BTN_COPY = new ResourceGroup(BTN_COPY_N, BTN_COPY_F, BTN_COPY_D);
public static final ResourceGroup BTN_DEL = new ResourceGroup(BTN_DEL_N, BTN_DEL_F);
public static final ResourceGroup BTN_YES = new ResourceGroup(BTN_YES_N, BTN_YES_F, BTN_YES_D);
@@ -130,6 +146,12 @@ public class Resource {
public static final ResourceGroup BTN_OUT = new ResourceGroup(BTN_OUT_N, BTN_OUT_F, BTN_OUT_D);
public static final ResourceGroup BTN_CAT = new ResourceGroup(BTN_CAT_N, BTN_CAT_F, BTN_CAT_D);
public static final ResourceGroup BTN_LIST = new ResourceGroup(BTN_LIST_N, BTN_LIST_F, BTN_LIST_D);
public static final ResourceGroup BTN_IMPORT = new ResourceGroup(BTN_IMPORT_N, BTN_IMPORT_F, BTN_IMPORT_D);
public static final ResourceGroup BTN_EXPORT_N = new ResourceGroup(BTN_EXPORT_N_N, BTN_EXPORT_N_F, BTN_EXPORT_N_D);
public static final ResourceGroup BTN_EXPORT_1 = new ResourceGroup(BTN_EXPORT_1_N, BTN_EXPORT_1_F, BTN_EXPORT_1_D);
public static final ResourceGroup BTN_INV_E = new ResourceGroup(BTN_INV_E_N, BTN_INV_E_F);
public static final ResourceGroup BTN_INV_D = new ResourceGroup(BTN_INV_D_N, BTN_INV_D_F);
public static final ResourceGroup BTN_META_N = new ResourceGroup(BTN_META_N_N, BTN_META_N_F, BTN_META_D);
public static final ResourceGroup BTN_CAP_N = new ResourceGroup(BTN_CAP_N_N, BTN_CAP_N_F, BTN_CAP_D);
public static final ResourceGroup BTN_NBT_N = new ResourceGroup(BTN_NBT_N_N, BTN_NBT_N_F, BTN_NBT_D);
@@ -145,6 +167,7 @@ public class Resource {
public static final ResourceGroup ICN_LIST = new ResourceGroup(ICN_LIST_N, ICN_LIST_F);
public static final ResourceGroup ICN_LABEL = new ResourceGroup(ICN_LABEL_N, ICN_LABEL_F);
public static final ResourceGroup ICN_TEXT = new ResourceGroup(ICN_TEXT_N, ICN_TEXT_F);
public static final ResourceGroup ICN_HELP = new ResourceGroup(ICN_HELP_N, ICN_HELP_F);
protected int xPos, yPos, xSize, ySize;
protected ResourceLocation rl;
@@ -186,7 +209,11 @@ public class Resource {
}
private static Resource getLabel(int x) {
return new Resource(x * 16, 70, 16, 16);
return new Resource(x * 16, 132, 16, 16);
}
private static Resource getWidget(int x) {
return new Resource(x * 20, 112, 20, 20);
}
public static class ResourceGroup {
@@ -9,16 +9,16 @@ import me.towdium.jecalculation.gui.JecaGui;
import me.towdium.jecalculation.gui.Resource;
import me.towdium.jecalculation.gui.widgets.*;
import me.towdium.jecalculation.utils.ItemStackHelper;
import me.towdium.jecalculation.utils.wrappers.Pair;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import org.lwjgl.input.Keyboard;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
@@ -45,11 +45,9 @@ public class GuiCalculator extends WContainer implements IGui {
Controller.setAmount(i.getText());
refreshCalculator();
});
WLabel label = new WLabel(31, 7, 20, 20, WLabel.Mode.SELECTOR).setListener((i, v) -> {
Controller.setRecent(v);
refreshRecent();
refreshCalculator();
});
WLabel label = new WLabel(31, 7, 20, 20, WLabel.Mode.SELECTOR).setListener((i, v) -> refreshLabel(v, false));
WButton invE = new WButtonIcon(149, 62, 20, 20, Resource.BTN_INV_E, "calculator.inventory_enabled");
WButton invD = new WButtonIcon(149, 62, 20, 20, Resource.BTN_INV_D, "calculator.inventory_disabled");
public GuiCalculator() {
add(new WHelp("calculator"));
@@ -66,7 +64,19 @@ public class GuiCalculator extends WContainer implements IGui {
add(new WText(53, 13, JecaGui.Font.PLAIN, "x"));
add(new WLine(55));
add(new WIcon(151, 31, 18, 18, Resource.ICN_RECENT, "calculator.history"));
addAll(recent, label, input, output, catalyst, steps, result, amount);
add(recent, label, input, output, catalyst, steps, result, amount, Controller.getDetectInv() ? invE : invD);
invE.setListener(i -> {
Controller.setDetectInv(false);
remove(invE);
add(invD);
refreshCalculator();
});
invD.setListener(i -> {
Controller.setDetectInv(true);
remove(invD);
add(invE);
refreshCalculator();
});
refreshRecent();
setMode(Mode.INPUT);
}
@@ -97,7 +107,8 @@ public class GuiCalculator extends WContainer implements IGui {
long i = s.isEmpty() ? 1 : Long.parseLong(amount.getText());
amount.setColor(JecaGui.COLOR_TEXT_WHITE);
List<ILabel> dest = Collections.singletonList(label.getLabel().copy().setAmount(i));
calculator = new CostList(getInventory(), dest).calculate();
CostList list = Controller.getDetectInv() ? new CostList(getInventory(), dest) : new CostList(dest);
calculator = list.calculate();
} catch (NumberFormatException | ArithmeticException e) {
amount.setColor(JecaGui.COLOR_TEXT_RED);
calculator = null;
@@ -138,7 +149,69 @@ public class GuiCalculator extends WContainer implements IGui {
}
}
private void refreshLabel(ILabel l, boolean replace) {
Controller.setRecent(l, replace);
refreshRecent();
refreshCalculator();
if (findRecipe(l).isEmpty()) {
Pair<List<ILabel>, List<ILabel>> guess = ILabel.CONVERTER.guess(Collections.singletonList(l));
LinkedHashSet<ILabel> match = new LinkedHashSet<>();
List<ILabel> fuzzy = new ArrayList<>();
Stream.of(guess.one, guess.two).flatMap(Collection::stream).forEach(i -> {
List<ILabel> list = findRecipe(i);
list.forEach(j -> match.add(j.setPercent(false).setAmount(1)));
if (!list.isEmpty()) fuzzy.add(i);
});
match.addAll(fuzzy);
List<ILabel> list = new ArrayList<>(match);
if (!match.isEmpty()) add(new Suggest(list.size() > 3 ? list.subList(0, 3) : list));
}
}
private static List<ILabel> findRecipe(ILabel l) {
return Controller.recipeIterator().stream()
.map(i -> i.matches(l))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
}
enum Mode {
INPUT, OUTPUT, CATALYST, STEPS
}
class Suggest extends WContainer {
public Suggest(List<ILabel> labels) {
int width = labels.size() * 20;
add(new WPanel(0 - width, 2, 56 + width, 30));
add(new WLabel(31, 7, 20, 20, WLabel.Mode.SELECTOR).setLabel(label.getLabel())
.setListener((i, v) -> refresh(v)));
add(new WIcon(5 - width, 7, 18, 20, Resource.ICN_HELP, "calculator.suggest"));
add(new WLine(26, 7, 20, false));
for (int i = 0; i < labels.size(); i++) {
add(new WLabel(3 - i * 20, 7, 20, 20, WLabel.Mode.PICKER).setLabel(labels.get(i))
.setListener((j, v) -> refresh(v)));
}
}
public void refresh(ILabel l) {
GuiCalculator.this.remove(this);
refreshLabel(l, true);
}
@Override
public boolean onClicked(JecaGui gui, int xMouse, int yMouse, int button) {
if (!super.onClicked(gui, xMouse, yMouse, button)) GuiCalculator.this.remove(this);
return true;
}
@Override
public boolean onKey(JecaGui gui, char ch, int code) {
if (!super.onKey(gui, ch, code)) {
if (code == Keyboard.KEY_ESCAPE) {
GuiCalculator.this.remove(this);
return true;
} else return false;
} else return true;
}
}
}
@@ -11,8 +11,7 @@ import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
import java.util.function.Consumer;
import static me.towdium.jecalculation.gui.Resource.ICN_LABEL;
import static me.towdium.jecalculation.gui.Resource.ICN_LIST;
import static me.towdium.jecalculation.gui.Resource.*;
/**
* Author: towdium
@@ -30,16 +29,17 @@ public class GuiDisambiguation extends IPicker.Impl implements IGui {
WSwitcher switcher = new WSwitcher(7, 7, 162, this.record.size()).setListener(i -> setPage(i.getIndex()));
ListenerValue<WLabelScroll, Integer> consumer = (i, v) -> callback.accept(i.get(v).copy().multiply(-1));
add(new WPanel());
add(new WIcon(7, 48, 18, 54, ICN_LIST, "disambiguation.list"));
add(new WIcon(7, 105, 18, 54, ICN_LABEL, "disambiguation.label"));
add(new WIcon(7, 24, 20, 20, ICN_TEXT, "common.search"));
add(new WIcon(7, 48, 18, 54, ICN_LIST, "disamb.list"));
add(new WIcon(7, 105, 18, 54, ICN_LABEL, "disamb.label"));
add(new WSearch(25, 24, 90, lsUp.setListener(consumer), lsDown.setListener(consumer)));
addAll(switcher, lsUp, lsDown);
add(switcher, lsUp, lsDown);
setPage(0);
}
protected void setPage(int n) {
lsUp.setLabels(record.get(n));
lsDown.setLabels(ILabel.CONVERTER.guess(record.get(n)));
lsDown.setLabels(ILabel.CONVERTER.guess(record.get(n)).one);
}
}
@@ -25,9 +25,9 @@ import static me.towdium.jecalculation.gui.Resource.ICN_TEXT;
public class GuiImport extends WContainer implements IGui, ISearchable {
List<Quad<Boolean, String, String, Recipes>> data; // selected, file, group, recipes
List<Quad<Boolean, String, String, Recipes>> filtered;
WSearch search = new WSearch(25, 25, 90, this);
WSearch search = new WSearch(26, 25, 90, this);
WSwitcher page;
WButton confirm = new WButtonIcon(149, 25, 20, 20, BTN_YES, "common.confirm").setDisabled(true)
WButton confirm = new WButtonIcon(149, 25, 20, 20, BTN_YES, "import.confirm").setDisabled(true)
.setListener(i -> {
data.stream().filter(j -> j.one).forEach(j -> Controller.inport(j.four, j.three));
JecaGui.displayParent();
@@ -35,9 +35,9 @@ public class GuiImport extends WContainer implements IGui, ISearchable {
List<Pair<WTick, WText>> content = new ArrayList<>();
public GuiImport() {
add(new WPanel());
add(new WHelp("import"), new WPanel());
add(new WIcon(7, 25, 20, 20, ICN_TEXT, "common.search"));
addAll(search, confirm);
add(search, confirm);
IntStream.range(0, 7).forEach(i -> {
WTick tick = new WTick(7, 49 + 16 * i, 13, 13, "import.tick").setDisabled(true)
.setListener(j -> {
@@ -45,7 +45,7 @@ public class GuiImport extends WContainer implements IGui, ISearchable {
confirm.setDisabled(data.stream().noneMatch(k -> k.one));
});
WText text = new WTextExpand(49 + 16 * i, "");
addAll(tick, text);
add(tick, text);
content.add(new Pair<>(tick, text));
});
}
@@ -40,7 +40,7 @@ public class GuiLabel extends WContainer implements IGui {
add(new WPage(i, r, false).setListener(j -> refresh(i)));
index.value += 1;
});
addAll(new WHelp("label"), new WPanel());
add(new WHelp("label"), new WPanel());
add(container);
refresh(0);
}
@@ -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;
@@ -26,34 +27,37 @@ public class GuiRecipe extends WContainer implements IGui {
Pair<String, Integer> dest;
HashMap<Integer, List<ILabel>> disambiguation = new HashMap<>();
WSwitcher switcherGroup = new WSwitcher(7, 7, 162, Controller.getGroups());
WTextField textField = new WTextField(49, 33, 119);
WLabelGroup groupCatalyst = new WLabelGroup(28, 87, 7, 1, 20, 20, WLabel.Mode.EDITOR);
WButton buttonDisamb = new WButtonIcon(121, 33, 20, 20, BTN_DISAMB, "recipe.disamb").setListener(i -> {
WTextField textField = new WTextField(49, 31, 119);
WLabelGroup groupCatalyst = new WLabelGroup(29, 87, 7, 1, 20, 20, WLabel.Mode.EDITOR).setListener((i, v) -> {
disambiguation.remove(v + 14);
refresh();
});
WLabelGroup groupInput = new WLabelGroup(29, 111, 7, 2, 20, 20, WLabel.Mode.EDITOR).setListener((i, v) -> {
disambiguation.remove(v);
refresh();
});
WLabelGroup groupOutput = new WLabelGroup(29, 63, 7, 1, 20, 20, WLabel.Mode.EDITOR).setListener((i, v) -> {
disambiguation.remove(v + 21);
refresh();
});
WButton buttonDisamb = new WButtonIcon(121, 31, 20, 20, BTN_DISAMB, "recipe.disamb").setListener(i -> {
if (disambiguation != null) JecaGui.displayGui(new GuiDisambiguation(new ArrayList<>(disambiguation.values()))
.setCallback(l -> {
JecaGui.displayParent();
JecaGui.getCurrent().hand = l;
}));
});
WLabelGroup groupInput = new WLabelGroup(28, 111, 7, 2, 20, 20, WLabel.Mode.EDITOR).setListener((i, v) -> {
disambiguation.remove(v);
refresh();
});
WLabelGroup groupOutput = new WLabelGroup(28, 63, 7, 1, 20, 20, WLabel.Mode.EDITOR).setListener((i, v) -> {
disambiguation.remove(v + 21);
refresh();
});
WButton buttonClear = new WButtonIcon(64, 33, 20, 20, BTN_DEL, "recipe.clear").setListener(i -> clear());
WButton buttonCopy = new WButtonIcon(83, 33, 20, 20, BTN_COPY, "recipe.copy").setListener(i -> {
WButton buttonClear = new WButtonIcon(64, 31, 20, 20, BTN_DEL, "recipe.clear").setListener(i -> clear());
WButton buttonCopy = new WButtonIcon(83, 31, 20, 20, BTN_COPY, "recipe.copy").setListener(i -> {
Controller.addRecipe(switcherGroup.getText(), toRecipe());
JecaGui.displayParent();
});
WButton buttonLabel = new WButtonIcon(45, 33, 20, 20, BTN_LABEL, "recipe.label").setListener(i ->
WButton buttonLabel = new WButtonIcon(45, 31, 20, 20, BTN_LABEL, "recipe.label").setListener(i ->
JecaGui.displayGui(new GuiLabel((l) -> {
JecaGui.displayParent();
JecaGui.getCurrent().hand = l;
})));
WButton buttonSave = new WButtonIcon(26, 33, 20, 20, BTN_SAVE, "recipe.save").setListener(i -> {
WButton buttonSave = new WButtonIcon(26, 31, 20, 20, BTN_SAVE, "recipe.save").setDisabled(true).setListener(i -> {
if (dest == null)
Controller.addRecipe(switcherGroup.getText(), toRecipe());
else {
@@ -66,17 +70,17 @@ public class GuiRecipe extends WContainer implements IGui {
}
JecaGui.displayParent();
});
WButton buttonDel = new WButtonIcon(102, 33, 20, 20, BTN_NO, "recipe.delete").setListener(i -> {
WButton buttonDel = new WButtonIcon(102, 31, 20, 20, BTN_NO, "recipe.delete").setListener(i -> {
Controller.removeRecipe(dest.one, dest.two);
JecaGui.displayParent();
});
WButton buttonYes = new WButtonIcon(7, 33, 20, 20, BTN_YES, "recipe.confirm").setDisabled(true).setListener(i -> {
WButton buttonYes = new WButtonIcon(7, 31, 20, 20, BTN_YES, "recipe.confirm").setDisabled(true).setListener(i -> {
switcherGroup.setTemp(textField.getText());
textField.setText("");
setNewGroup(false);
});
WButton buttonNo = new WButtonIcon(26, 33, 20, 20, BTN_NO, "common.cancel").setListener(i -> setNewGroup(false));
WButton buttonNew = new WButtonIcon(7, 33, 20, 20, BTN_NEW, "recipe.new").setListener(i -> setNewGroup(true));
WButton buttonNo = new WButtonIcon(26, 31, 20, 20, BTN_NO, "common.cancel").setListener(i -> setNewGroup(false));
WButton buttonNew = new WButtonIcon(7, 31, 20, 20, BTN_NEW, "recipe.new").setListener(i -> setNewGroup(true));
public GuiRecipe(String group, int index) {
this();
@@ -86,15 +90,16 @@ public class GuiRecipe extends WContainer implements IGui {
switcherGroup.setIndex(Controller.getGroups().indexOf(group));
buttonCopy.setDisabled(false);
buttonDel.setDisabled(false);
buttonSave.setDisabled(false);
}
public GuiRecipe() {
addAll(new WHelp("recipe"), new WPanel());
add(new WIcon(7, 63, 21, 20, ICN_OUTPUT, "common.output"));
add(new WIcon(7, 87, 21, 20, ICN_CATALYST, "common.catalyst"));
add(new WIcon(7, 111, 21, 40, ICN_INPUT, "common.input"));
add(new WHelp("recipe"), new WPanel());
add(new WIcon(7, 63, 22, 20, ICN_OUTPUT, "common.output"));
add(new WIcon(7, 87, 22, 20, ICN_CATALYST, "common.catalyst"));
add(new WIcon(7, 111, 22, 40, ICN_INPUT, "common.input"));
add(new WLine(57));
addAll(groupInput, groupCatalyst, groupOutput, switcherGroup);
add(groupInput, groupCatalyst, groupOutput, switcherGroup);
if (switcherGroup.getTexts().isEmpty()) switcherGroup.setTemp(Utilities.I18n.get("gui.common.default"));
setNewGroup(false);
buttonCopy.setDisabled(true);
@@ -105,11 +110,11 @@ public class GuiRecipe extends WContainer implements IGui {
public void setNewGroup(boolean b) {
if (b) {
removeAll(buttonNew, buttonLabel, buttonClear, buttonCopy, buttonSave, buttonDisamb, buttonDel);
addAll(buttonYes, buttonNo, textField);
remove(buttonNew, buttonLabel, buttonClear, buttonCopy, buttonSave, buttonDisamb, buttonDel);
add(buttonYes, buttonNo, textField);
} else {
addAll(buttonNew, buttonLabel, buttonClear, buttonCopy, buttonSave, buttonDisamb, buttonDel);
removeAll(buttonYes, buttonNo, textField);
add(buttonNew, buttonLabel, buttonClear, buttonCopy, buttonSave, buttonDisamb, buttonDel);
remove(buttonYes, buttonNo, textField);
}
}
@@ -126,50 +131,49 @@ public class GuiRecipe extends WContainer implements IGui {
disambiguation = new HashMap<>();
// input
List<ItemStack> itemStacks = recipe.getIngredientStacks(recipeIndex).stream()
List<ItemStack> inputItemStacks = recipe.getIngredientStacks(recipeIndex).stream()
.map((positionedStack) -> positionedStack.item).collect(Collectors.toList());
merge(input, itemStacks.stream().map(ILabel.Converter::from).collect(Collectors.toList()));
List<ItemStack> outputItemStacks = Collections.singletonList(recipe.getResultStack(recipeIndex).item);
// output
ItemStack outputStack = recipe.getResultStack(recipeIndex).item;
merge(output, Stream.of(outputStack).map(ILabel.Converter::from).collect(Collectors.toList()));
merge(input, inputItemStacks, recipe);
merge(output, outputItemStacks, recipe);
// catalyst ignore multiple catalyst
NEIPlugin.getCatalyst(recipe).map(ILabel.Converter::from).ifPresent(catalyst -> {
groupCatalyst.setLabel(catalyst, 0);
});
groupInput.setLabel(sort(input, 0, true), 0);
groupOutput.setLabel(sort(output, 21, false), 0);
groupInput.setLabel(sort(input, 0), 0);
groupOutput.setLabel(sort(output, 21), 0);
refresh();
}
private void merge(ArrayList<Trio<ILabel, CostList, CostList>> dst, List<ILabel> list) {
private void merge(ArrayList<Trio<ILabel, CostList, CostList>> dst, List<ItemStack> gi, IRecipeHandler context) {
List<ILabel> list = gi.stream().map(ILabel.Converter::from).collect(Collectors.toList());
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)).ifPresent(i -> p.one = i);
ILabel.MERGER.merge(p.one, ILabel.CONVERTER.first(list, context)).ifPresent(i -> p.one = i);
p.two = p.two.merge(cl, true, false);
return true;
} else
return false;
}).findAny().orElseGet(() -> {
Trio<ILabel, CostList, CostList> ret = new Trio<>(ILabel.CONVERTER.first(list), new CostList(list),
Trio<ILabel, CostList, CostList> ret = new Trio<>(ILabel.CONVERTER.first(list, context), new CostList(list),
new CostList(list));
dst.add(ret);
return ret;
});
}
private ArrayList<ILabel> sort(ArrayList<Trio<ILabel, CostList, CostList>> src, int offset, boolean guess) {
private ArrayList<ILabel> sort(ArrayList<Trio<ILabel, CostList, CostList>> src, int offset) {
ArrayList<ILabel> ret = new ArrayList<>();
for (int i = 0; i < src.size(); i++) {
Trio<ILabel, CostList, CostList> p = src.get(i);
ret.add(p.one);
if (guess && !ILabel.CONVERTER.guess(p.three.getLabels()).isEmpty())
disambiguation.put(i + offset, p.two.getLabels());
if (p.two.getLabels().size() > 1) disambiguation.put(i + offset, p.two.getLabels());
}
return ret;
}
@@ -190,5 +194,11 @@ public class GuiRecipe extends WContainer implements IGui {
void refresh() {
buttonDisamb.setDisabled(disambiguation.isEmpty());
try {
Recipe r = toRecipe();
buttonSave.setDisabled(Controller.hasDuplicate(r));
} catch (IllegalArgumentException e) {
buttonSave.setDisabled(true);
}
}
}
@@ -1,8 +1,10 @@
package me.towdium.jecalculation.gui.guis;
import me.towdium.jecalculation.data.Controller;
import me.towdium.jecalculation.data.label.ILabel;
import me.towdium.jecalculation.data.structure.Recipe;
import me.towdium.jecalculation.gui.JecaGui;
import me.towdium.jecalculation.gui.Resource;
import me.towdium.jecalculation.gui.widgets.*;
import me.towdium.jecalculation.polyfill.google.common.collect.Streams;
import me.towdium.jecalculation.utils.Utilities;
@@ -12,37 +14,52 @@ import net.minecraft.util.ChatComponentTranslation;
import java.io.File;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import static me.towdium.jecalculation.gui.Resource.*;
import static me.towdium.jecalculation.gui.widgets.WLabel.Mode.PICKER;
public class GuiSearch extends WContainer implements IGui {
WSwitcher group;
WButton export;
List<Trio<Recipe, String, Integer>> recipes;
WLabelScroll labels = new WLabelScroll(7, 51, 8, 6, PICKER, true).setListener((i, v) ->
JecaGui.displayGui(true, true, new GuiRecipe(recipes.get(v).two, recipes.get(v).three)));
List<ILabel> identifiers;
IdentityHashMap<ILabel, Trio<Recipe, String, Integer>> recipes;
WLabelScroll labels = new WLabelScroll(7, 51, 8, 6, PICKER, true).setListener((i, v) -> {
Trio<Recipe, String, Integer> recipe = recipes.get(i.get(v));
JecaGui.displayGui(true, true, new GuiRecipe(recipe.two, recipe.three));
});
public GuiSearch() {
add(new WPanel());
add(new WSearch(25, 25, 90, labels));
add(new WHelp("search"), new WPanel());
add(new WSearch(26, 25, 90, labels));
add(new WIcon(7, 25, 20, 20, ICN_TEXT, "common.search"));
add(new WButtonIcon(131, 25, 20, 20, BTN_IN, "search.import")
add(new WButtonIcon(131, 25, 20, 20, BTN_IMPORT, "search.import")
.setListener(i -> JecaGui.displayGui(new GuiImport())));
add(labels);
}
private void generate() {
identifiers = new ArrayList<>();
recipes = new IdentityHashMap<>();
Consumer<Trio<Recipe, String, Integer>> add = i -> {
ILabel id = i.one.getRep();
recipes.put(id, i);
identifiers.add(id);
};
if (group.getIndex() == 0) {
recipes = Controller.stream()
.flatMap(i -> Streams.mapWithIndex(i.two.stream(), (j, k) -> new Trio<>(j, i.one, (int) k)))
.collect(Collectors.toList());
Controller.stream()
.flatMap(i -> Streams.mapWithIndex(i.two.stream(), (j, k) -> new Trio<>(j, i.one, (int) k)))
.forEach(add);
} else {
String s = group.getText();
recipes = Streams.mapWithIndex(Controller.getRecipes(s).stream(), (i, j) -> new Trio<>(i, s, (int) j))
.collect(Collectors.toList());
Streams.mapWithIndex(Controller.getRecipes(s).stream(), (j, k) -> new Trio<>(j, s, (int) k))
.forEach(add);
}
}
@@ -51,16 +68,19 @@ public class GuiSearch extends WContainer implements IGui {
remove(export);
String tooltip;
Supplier<File> func;
ResourceGroup texture;
generate();
if (group.getIndex() == 0) {
tooltip = "search.export_all";
func = Controller::export;
texture = Resource.BTN_EXPORT_N;
} else {
tooltip = "search.export_group";
func = () -> Controller.export(group.getText());
texture = Resource.BTN_EXPORT_1;
}
labels.setLabels(recipes.stream().map(i -> i.one.getRep()).collect(Collectors.toList()));
export = new WButtonIcon(149, 25, 20, 20, BTN_OUT, tooltip).setListener(i -> {
labels.setLabels(identifiers);
export = new WButtonIcon(149, 25, 20, 20, texture, tooltip).setListener(i -> {
File f = func.get();
Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentTranslation(
"jecalculation.chat.export", f.getAbsolutePath()));
@@ -70,7 +90,7 @@ public class GuiSearch extends WContainer implements IGui {
@Override
public void onVisible(JecaGui gui) {
removeAll(group);
this.remove(group);
ArrayList<String> groups = new ArrayList<>();
groups.add(Utilities.I18n.get("gui.search.all"));
groups.addAll(Controller.getGroups());
@@ -78,7 +98,7 @@ public class GuiSearch extends WContainer implements IGui {
if (index >= groups.size()) index = groups.size() - 1;
group = new WSwitcher(7, 7, 162, groups).setListener(i -> refresh());
group.setIndex(index);
addAll(group);
this.add(group);
refresh();
}
}
@@ -22,53 +22,54 @@ import static me.towdium.jecalculation.gui.Resource.*;
@ParametersAreNonnullByDefault
@SideOnly(Side.CLIENT)
public class PickerItemStack extends IPicker.Impl implements IGui {
WLabel label = new WLabel(7, 7, 20, 20, WLabel.Mode.SELECTOR).setListener((i, v) -> update());
WButton bConfirm = new WButtonIcon(149, 7, 20, 20, BTN_YES).setListener(i -> callback.accept(label.getLabel()));
WButton bBbtN = new WButtonIcon(49, 7, 20, 20, BTN_NBT_N).setListener(i -> setFNbt(true));
WButton bNbtF = new WButtonIcon(49, 7, 20, 20, BTN_NBT_F).setListener(i -> setFNbt(false));
WButton bCapN = new WButtonIcon(68, 7, 20, 20, BTN_CAP_N).setListener(i -> setFCap(true));
WButton bCapF = new WButtonIcon(68, 7, 20, 20, BTN_CAP_F).setListener(i -> setFCap(false));
WButton bMetaN = new WButtonIcon(30, 7, 20, 20, BTN_META_N).setListener(i -> setFMeta(true));
WButton bMetaF = new WButtonIcon(30, 7, 20, 20, BTN_META_F).setListener(i -> setFMeta(false));
WLabel label = new WLabel(7, 7, 20, 20, WLabel.Mode.SELECTOR).setListener((i, v) -> update(v));
WButton bConfirm = new WButtonIcon(149, 7, 20, 20, BTN_YES, "item_stack.confirm").setListener(i -> callback.accept(label.getLabel()));
WButton bNbtN = new WButtonIcon(49, 7, 20, 20, BTN_NBT_N, "item_stack.nbt_normal").setListener(i -> setFNbt(true));
WButton bNbtF = new WButtonIcon(49, 7, 20, 20, BTN_NBT_F, "item_stack.nbt_fuzzy").setListener(i -> setFNbt(false));
WButton bCapN = new WButtonIcon(68, 7, 20, 20, BTN_CAP_N, "item_stack.capability_normal").setListener(i -> setFCap(true));
WButton bCapF = new WButtonIcon(68, 7, 20, 20, BTN_CAP_F, "item_stack.capability_fuzzy").setListener(i -> setFCap(false));
WButton bMetaN = new WButtonIcon(30, 7, 20, 20, BTN_META_N, "item_stack.meta_normal").setListener(i -> setFMeta(true));
WButton bMetaF = new WButtonIcon(30, 7, 20, 20, BTN_META_F, "item_stack.meta_fuzzy").setListener(i -> setFMeta(false));
ILabel raw = ILabel.EMPTY;
boolean fMeta, fNbt, fCap = false;
public PickerItemStack() {
addAll(label, bConfirm);
add(bConfirm);
update();
add(label, bConfirm);
update(ILabel.EMPTY);
}
public void update() {
public void update(ILabel l) {
raw = l;
setFCap(false);
setFMeta(false);
setFNbt(false);
boolean b = label.getLabel() == ILabel.EMPTY;
bBbtN.setDisabled(b);
boolean b = l == ILabel.EMPTY;
bNbtN.setDisabled(b);
bCapN.setDisabled(b);
bMetaN.setDisabled(b);
bConfirm.setDisabled(b);
}
private void setFNbt(boolean b) {
setF(b, bBbtN, bNbtF, i -> i.setFNbt(b));
setF(b, bNbtN, bNbtF, () -> fNbt = b);
}
private void setFMeta(boolean b) {
setF(b, bMetaN, bMetaF, i -> i.setFMeta(b));
setF(b, bMetaN, bMetaF, () -> fMeta = b);
}
private void setFCap(boolean b) {
setF(b, bCapN, bCapF, i -> i.setFCap(b));
setF(b, bCapN, bCapF, () -> fCap = b);
}
private void setF(boolean b, WButton be, WButton bd, Consumer<LItemStack> c) {
if (b) {
remove(be);
add(bd);
} else {
remove(bd);
add(be);
private void setF(boolean b, WButton be, WButton bd, Runnable r) {
remove(be, bd);
if (b) add(bd);
else add(be);
r.run();
if (raw instanceof LItemStack) {
LItemStack lis = (LItemStack) raw;
label.setLabel(lis.copy().setFCap(fCap).setFMeta(fMeta).setFNbt(fNbt));
}
ILabel l = label.getLabel();
if (l instanceof LItemStack) c.accept((LItemStack) l);
}
}
@@ -33,6 +33,6 @@ public class PickerPlaceholder extends IPicker.Impl implements IGui {
add(new WButtonIcon(95, 7, 20, 20, BTN_YES, "common.confirm").setListener(i -> {
if (!create.getText().equals("")) callback.accept(new LPlaceholder(create.getText(), 1));
}));
addAll(scroll, create);
add(scroll, create);
}
}
@@ -50,11 +50,9 @@ public class PickerSimple extends IPicker.Impl implements IGui {
}
static List<ILabel> generate() {
List<ILabel> present = new ArrayList<>();
List<ILabel> empty = new ArrayList<>();
Arrays.stream(OreDictionary.getOreNames()).map(LOreDict::new).forEach(i -> (i.isEmpty() ? empty : present).add(i));
present.addAll(empty);
return present;
return Arrays.stream(OreDictionary.getOreNames())
.filter(i -> !OreDictionary.getOres(i).isEmpty())
.map(LOreDict::new).collect(Collectors.toList());
}
}
}
@@ -5,13 +5,9 @@ package me.towdium.jecalculation.gui.widgets;
* Date: 18-9-25
*/
public interface IContainer extends IWidget {
void add(IWidget w);
void add(IWidget... w);
void addAll(IWidget... w);
void remove(IWidget w);
void removeAll(IWidget... w);
void remove(IWidget... w);
void clear();
}
@@ -37,24 +37,12 @@ public abstract class WButton extends WTooltip {
return this;
}
protected Resource getDisabled() {
return WGT_BUTTON_D;
}
protected Resource getNormal() {
return WGT_BUTTON_N;
}
protected Resource getFocused() {
return WGT_BUTTON_F;
}
@Override
public void onDraw(JecaGui gui, int xMouse, int yMouse) {
super.onDraw(gui, xMouse, yMouse);
boolean hovered = JecaGui.mouseIn(xPos + 1, yPos + 1, xSize - 2, ySize - 2, xMouse, yMouse);
gui.drawResourceContinuous(disabled ? getDisabled() : (hovered ? getFocused() : getNormal()), xPos, yPos, xSize,
ySize, 5, 5, 5, 5);
gui.drawResourceContinuous(disabled ? WGT_BUTTON_D : (hovered ? WGT_BUTTON_F : WGT_BUTTON_N)
, xPos, yPos, xSize, ySize, 5, 5, 5, 5);
}
@Override
@@ -82,6 +70,6 @@ public abstract class WButton extends WTooltip {
@Override
protected List<String> getSuffix() {
return disabled ? Arrays.asList("disabled", "active", "") : Arrays.asList("active", "");
return disabled ? Arrays.asList("disabled", "enabled", "") : Arrays.asList("enabled", "");
}
}
@@ -44,6 +44,6 @@ public class WButtonIcon extends WButton {
super.onDraw(gui, xMouse, yMouse);
Resource r = disabled ? rDisabled : (mouseIn(xMouse, yMouse) ? rFocused : rNormal);
if (r != null)
gui.drawResource(r, xPos + (xSize - r.getXSize()) / 2, yPos + (ySize - r.getYSize()) / 2);
gui.drawResource(r, xPos + (xSize - r.getXSize() + 1) / 2, yPos + (ySize - r.getYSize() + 1) / 2);
}
}
@@ -9,6 +9,7 @@ import me.towdium.jecalculation.utils.Utilities;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -25,18 +26,14 @@ public class WContainer implements IContainer {
widgets.add(w);
}
public void addAll(IWidget... w) {
for (IWidget aw : w)
add(aw);
public void add(IWidget... w) {
if (w.length == 1) widgets.add(w[0]);
else widgets.addAll(Arrays.asList(w));
}
public void remove(IWidget w) {
widgets.remove(w);
}
public void removeAll(IWidget... w) {
for (IWidget aw : w)
remove(aw);
public void remove(IWidget... w) {
if (w.length == 1) widgets.remove(w[0]);
else widgets.removeAll(Arrays.asList(w));
}
public void clear() {
@@ -17,43 +17,53 @@ import static me.towdium.jecalculation.gui.Resource.*;
* Date: 18-9-23
*/
@ParametersAreNonnullByDefault
public class WHelp extends WTooltip {
public class WHelp extends WContainer {
protected String key;
public WHelp(String content) {
super("common.help");
key = content;
if (I18n.search("gui." + WHelp.this.key + ".title").two
&& I18n.search("gui." + WHelp.this.key + ".help").two) {
add(new Impl());
}
}
@Override
public void onDraw(JecaGui gui, int xMouse, int yMouse) {
super.onDraw(gui, xMouse, yMouse);
gui.drawResourceContinuous(WGT_PANEL_N, -21, 0, 25, 24, 4);
gui.drawResource(WGT_HELP_N, -19, 2);
}
private class Impl extends WTooltip {
public Impl() {
super("common.help");
}
@Override
public boolean mouseIn(int xMouse, int yMouse) {
return JecaGui.mouseIn(-21, 0, 24, 24, xMouse, yMouse);
}
@Override
public void onDraw(JecaGui gui, int xMouse, int yMouse) {
super.onDraw(gui, xMouse, yMouse);
gui.drawResourceContinuous(WGT_PANEL_N, -21, 0, 25, 24, 4);
gui.drawResource(WGT_HELP_N, -19, 2);
}
@Override
public boolean onClicked(JecaGui gui, int xMouse, int yMouse, int button) {
boolean ret = mouseIn(xMouse, yMouse);
if (ret)
gui.root.add(new Doc());
return ret;
@Override
public boolean mouseIn(int xMouse, int yMouse) {
return JecaGui.mouseIn(-21, 0, 24, 24, xMouse, yMouse);
}
@Override
public boolean onClicked(JecaGui gui, int xMouse, int yMouse, int button) {
boolean ret = mouseIn(xMouse, yMouse);
if (ret)
gui.root.add(new Doc());
return ret;
}
}
private class Doc extends WContainer {
Text text = new Text();
WSwitcher switcher = new WSwitcher(7, 146, 162, text.amount()).setListener(i -> text.setPage(i.getIndex()));
public Doc() {
Text tContent = new Text();
WSwitcher sPage = new WSwitcher(7, 146, 162, tContent.amount());
sPage.setListener(i -> tContent.setPage(i.getIndex()));
WText tTitle = new WText(7, 7, SHADOW, I18n.get("gui." + WHelp.this.key + ".title"));
addAll(new WPanel(), new Icon(), tTitle, tContent, sPage);
WText title = new WText(7, 7, SHADOW, I18n.get("gui." + key + ".title"));
add(new WPanel(), new Icon(), title, text, switcher);
}
@Override
public boolean onClicked(JecaGui gui, int xMouse, int yMouse, int button) {
if (!super.onClicked(gui, xMouse, yMouse, button))
@@ -61,12 +71,19 @@ public class WHelp extends WTooltip {
return true;
}
@Override
public boolean onScroll(JecaGui gui, int xMouse, int yMouse, int diff) {
switcher.move(-diff);
text.setPage(switcher.getIndex());
return super.onScroll(gui, xMouse, yMouse, diff);
}
public class Text implements IWidget {
List<List<String>> pages = new ArrayList<>();
int page;
public Text() {
List<String> ss = I18n.wrap(I18n.get("gui." + WHelp.this.key + ".help"), 162);
List<String> ss = I18n.wrap(I18n.get("gui." + key + ".help"), 162);
List<String> tmp = new ArrayList<>();
int count = 0;
for (String s : ss) {
@@ -85,8 +102,7 @@ public class WHelp extends WTooltip {
count++;
}
}
if (!tmp.isEmpty())
pages.add(tmp);
if (!tmp.isEmpty()) pages.add(tmp);
}
@Override
@@ -31,7 +31,7 @@ import static me.towdium.jecalculation.gui.Resource.BTN_YES;
@SideOnly(Side.CLIENT)
public class WLabel implements IWidget {
public int xPos, yPos, xSize, ySize;
public ILabel label;
ILabel label;
public Mode mode;
public ListenerValue<? super WLabel, ILabel> listener;
protected Utilities.Timer timer = new Utilities.Timer();
@@ -50,8 +50,9 @@ public class WLabel implements IWidget {
return label;
}
public void setLabel(ILabel label) {
public WLabel setLabel(ILabel label) {
this.label = label;
return this;
}
@Override
@@ -85,13 +86,14 @@ public class WLabel implements IWidget {
@Override
public boolean onScroll(JecaGui gui, int xMouse, int yMouse, int diff) {
if (mouseIn(xMouse, yMouse) && mode == Mode.EDITOR && label != ILabel.EMPTY) {
for (int i = 0; i < Math.abs(diff); i++)
label = diff > 0 ? label.increaseAmount() : label.decreaseAmount();
notifyLsnr();
if (mouseIn(xMouse, yMouse)) {
if (mode == Mode.EDITOR && label != ILabel.EMPTY) {
for (int i = 0; i < Math.abs(diff); i++)
label = diff > 0 ? label.increaseAmount() : label.decreaseAmount();
notifyLsnr();
}
return true;
} else
return false;
} else return false;
}
@@ -165,59 +167,62 @@ public class WLabel implements IWidget {
class WAmount extends WContainer {
long old = label.getAmount();
WButton bAmount = new WButtonText(xPos + xSize + 60, yPos, 20, 20, "general.to_percent", "#")
.setListener(i -> setPercent(true));
WTextField wtf = new WTextField(xPos + xSize + 10, yPos + ySize / 2 - WTextField.HEIGHT / 2, 50);
WButton bPercent = new WButtonText(xPos + xSize + 60, yPos, 20, 20, "general.to_percent", "%")
.setListener(i -> setPercent(false));
WLabel wl = new WLabel(xPos, yPos, xSize, ySize, Mode.SELECTOR).setListener((i, v) -> update());
WButton bYes = new WButtonIcon(xPos + xSize + 83, yPos, 20, 20, BTN_YES).setListener(i -> {
setLabel(wl.getLabel().setAmount(
wtf.getText().isEmpty() ? 0 : Integer.parseInt(wtf.getText())));
JecaGui.getCurrent().root.remove(this);
});
WButton bYes = new WButtonIcon(xPos + xSize + 83, yPos, 20, 20, BTN_YES)
.setListener(i -> JecaGui.getCurrent().root.remove(this));
WButton bNo = new WButtonIcon(xPos + xSize + 102, yPos, 20, 20, BTN_NO).setListener(i -> {
setLabel(ILabel.EMPTY);
JecaGui.getCurrent().root.remove(this);
});
public WAmount() {
wl.setLabel(label);
add(new WPanel(xPos - 5, yPos - 5, xSize + 133, ySize + 10));
add(new WText(xPos + xSize + 3, yPos + 5, PLAIN, "x"));
addAll(wl, wtf, bYes, bNo);
add(wl, wtf, bYes, bNo);
wtf.setListener(i -> {
try {
Integer.parseInt(wtf.getText());
long n = Long.parseLong(wtf.getText());
label.setAmount(n);
wtf.setColor(COLOR_TEXT_WHITE);
bYes.setDisabled(false);
} catch (NumberFormatException e) {
boolean acceptable = wtf.getText().isEmpty();
wtf.setColor(acceptable ? COLOR_TEXT_WHITE : COLOR_TEXT_RED);
bYes.setDisabled(!acceptable);
label.setAmount(acceptable ? 1 : old);
}
notifyLsnr();
});
update();
}
private void update() {
label = wl.label;
bAmount.setDisabled(!wl.label.acceptPercent());
setPercent(label.isPercent());
}
private void setPercent(boolean b) {
if (b) {
bAmount.setDisabled(!label.acceptPercent());
if (label.isPercent()) {
remove(bAmount);
add(bPercent);
} else {
remove(bPercent);
add(bAmount);
}
if (label.acceptPercent()) label.setPercent(b);
wtf.setText(Long.toString(label.getAmount()));
}
private void setPercent(boolean b) {
boolean original = label.isPercent();
if (label.acceptPercent()) label.setPercent(b);
if (b != original) notifyLsnr();
update();
}
@Override
public boolean onKey(JecaGui gui, char ch, int code) {
if (super.onKey(gui, ch, code))
@@ -6,7 +6,7 @@ import me.towdium.jecalculation.gui.JecaGui;
import me.towdium.jecalculation.gui.Resource;
import javax.annotation.ParametersAreNonnullByDefault;
import static me.towdium.jecalculation.gui.Resource.WGT_LINE;
/**
* Author: towdium
* Date: 17-8-18.
@@ -14,14 +14,26 @@ import static me.towdium.jecalculation.gui.Resource.WGT_LINE;
@ParametersAreNonnullByDefault
@SideOnly(Side.CLIENT)
public class WLine implements IWidget {
public int y;
int xPos, yPos, xSize, ySize;
public WLine(int y) {
this.y = y;
this(7, y, 162, true);
}
public WLine(int xPos, int yPos, int size, boolean horizontal) {
this.yPos = yPos;
this.xPos = xPos;
if (horizontal) {
xSize = size;
ySize = 2;
} else {
xSize = 2;
ySize = size;
}
}
@Override
public void onDraw(JecaGui gui, int xMouse, int yMouse) {
gui.drawResource(WGT_LINE, 6, y - 1);
gui.drawResourceContinuous(Resource.WGT_SLOT, xPos, yPos, xSize, ySize, 1);
}
}
@@ -33,9 +33,9 @@ public class WPage extends WTooltip {
@Override
public void onDraw(JecaGui gui, int xMouse, int yMouse) {
Resource resource = focused ? (index == 0 ? WGT_PAGER_F0 : WGT_PAGER_FN) : WGT_PANEL_N;
gui.drawResourceContinuous(resource, index * 24, -21, 24, 25, 4, 4, 4, 4);
record.representation.drawLabel(gui, index * 24 + 4, -17, false);
Resource resource = focused ? WGT_PAGER_F : WGT_PANEL_N;
gui.drawResourceContinuous(resource, index * 24 + 3, -21, 24, 25, 4, 4, 4, 4);
record.representation.drawLabel(gui, index * 24 + 7, -17, false);
super.onDraw(gui, xMouse, yMouse);
}
@@ -34,7 +34,7 @@ public class WScroll implements IWidget {
else drag = false;
gui.drawResourceContinuous(Resource.WGT_SLOT, xPos, yPos, 14, ySize, 3, 3, 3, 3);
gui.drawResource(Resource.WGT_SCROLL, xPos + 1, yPos + 1 + current);
gui.drawResource(Resource.WGT_SCROLL, xPos, yPos + current);
}
@Override
@@ -47,29 +47,29 @@ public class WSwitcher extends WContainer {
this.yPos = yPos;
this.keys = keys;
left = new WButtonIcon(xPos, yPos, SIZE, SIZE, WGT_ARR_L).setListener(i -> {
if (temp == null) move(false);
if (temp == null) move(-1);
else setTemp(null);
});
right = new WButtonIcon(xPos + xSize - SIZE, yPos, SIZE, SIZE, WGT_ARR_R).setListener(i -> {
if (temp == null) move(true);
if (temp == null) move(1);
else setTemp(null);
});
wRect = new WRectangle(xPos + SIZE, yPos, xSize - 2 * SIZE, SIZE, COLOR_GUI_GREY);
wText = new WText(xPos + SIZE, yPos + 2, xSize - 2 * SIZE, SHADOW, "", true);
index = new Circulator(keys.size());
refresh();
addAll(left, right, wRect, wText);
add(left, right, wRect, wText);
}
protected void move(boolean forward) {
if (temp == null) {
if (forward)
index.move(1);
else
index.move(-1);
} else
public void move(int diff) {
if (diff == 0) return;
if (temp != null) {
temp = null;
if (diff > 0) diff -= 1;
else diff += 1;
}
index.move(diff);
notifyLsnr();
refresh();
}
@@ -31,6 +31,10 @@ public class WTextField implements IWidget {
@Override
public boolean onClicked(JecaGui gui, int xMouse, int yMouse, int button) {
textField.mouseClicked(xMouse, yMouse, button);
if (textField.isFocused() && button == 1) {
textField.setText("");
notifyLsnr();
}
return false;
}
@@ -1,10 +1,12 @@
package me.towdium.jecalculation.gui.widgets;
import me.towdium.jecalculation.gui.JecaGui;
import me.towdium.jecalculation.gui.Resource;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
@@ -57,7 +59,7 @@ public class WTick extends WContainer {
private class Normal extends WButton {
public Normal(int xPos, int yPos, int xSize, int ySize, @Nullable String name) {
super(xPos, yPos, xSize, ySize, name + ".normal");
super(xPos, yPos, xSize, ySize, name);
listener = i -> {
setSelected(true);
WTick.this.listener.invoke(WTick.this);
@@ -67,13 +69,13 @@ public class WTick extends WContainer {
@Override
protected List<String> getSuffix() {
return new ArrayList<>();
return Collections.singletonList("unselected");
}
}
private class Selected extends WButton {
public Selected(int xPos, int yPos, int xSize, int ySize, @Nullable String name) {
super(xPos, yPos, xSize, ySize, name + ".selected");
super(xPos, yPos, xSize, ySize, name);
listener = i -> {
setSelected(false);
WTick.this.listener.invoke(WTick.this);
@@ -81,24 +83,17 @@ public class WTick extends WContainer {
disabled = WTick.this.disabled;
}
@Override
protected Resource getDisabled() {
return WGT_BUTTON_S_D;
}
@Override
protected Resource getNormal() {
return WGT_BUTTON_S_N;
}
@Override
protected Resource getFocused() {
return WGT_BUTTON_S_F;
}
@Override
protected List<String> getSuffix() {
return new ArrayList<>();
return Collections.singletonList("selected");
}
@Override
public void onDraw(JecaGui gui, int xMouse, int yMouse) {
super.onDraw(gui, xMouse, yMouse);
boolean hovered = JecaGui.mouseIn(xPos + 1, yPos + 1, xSize - 2, ySize - 2, xMouse, yMouse);
gui.drawResourceContinuous(disabled ? WGT_BUTTON_S_D : (hovered ? WGT_BUTTON_S_F : WGT_BUTTON_S_N)
, xPos, yPos, xSize, ySize, 5, 5, 5, 5);
}
}
}
@@ -34,8 +34,8 @@ public class NBTHelper {
}
public static Spliterator<NBTBase> spliterator(NBTTagList list) {
List tagList = (List) ReflectionHelper.get(list, "tagList");
return Spliterators.spliteratorUnknownSize(((List<NBTBase>)tagList).iterator(), 0);
List<NBTBase> tagList = (List<NBTBase>) list.tagList;
return Spliterators.spliteratorUnknownSize(tagList.iterator(), 0);
}
public static NBTTagCompound getOrCreateSubCompound(ItemStack itemStack, String key) {
@@ -75,6 +75,11 @@ 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);
return sb.toString();
}
// MOD NAME
@Nullable
@@ -312,11 +317,11 @@ public class Utilities {
this.limit = limit;
}
public void push(T obj) {
public void push(T obj, boolean replace) {
if (replace) data.pop();
data.removeIf(t -> tester != null ? tester.test(t, obj) : t.equals(obj));
data.push(obj);
if (data.size() > limit)
data.pop();
data.addFirst(obj);
if (data.size() > limit) data.removeLast();
}
public List<T> toList() {