Add support for calculating multiple items (#14)

* Initial GUI work and basic functionality

* New implementation with linkedlist

* Use record for groupcraft

* Fix small bug with updating calculator and removing items properly

* Fix not saving on logout on client

* Restore tag workaround

* Fix format errors

* Revert using * in imports

* Spotless again

* update bs

* update deps

---------

Co-authored-by: Caedis <Caedis@users.noreply.github.com>
This commit is contained in:
BmandkandCaedis authored and GitHub committed 2024-08-06 18:59:17 -05:00
1 parent 949664b33c
commit da39c8e14a
8 files changed
+173 -56

No files matched your search

+13 -15
View File
@@ -1,22 +1,20 @@
// Add your dependencies here
dependencies {
// compile("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-291-GTNH:dev")
compile("com.github.GTNewHorizons:CodeChickenLib:1.1.10:dev")
compile("com.github.GTNewHorizons:CodeChickenCore:1.1.13:dev")
compile("com.github.GTNewHorizons:NotEnoughItems:2.4.13-GTNH:dev")
// compile("com.github.GTNewHorizons:Baubles:1.0.3:dev")
// compile("com.github.GTNewHorizons:WirelessCraftingTerminal:1.10.1:dev")
// compile("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-423-GTNH:dev")
compile("com.github.GTNewHorizons:CodeChickenCore:1.3.6:dev")
compile("com.github.GTNewHorizons:NotEnoughItems:2.6.19-GTNH:dev")
// compile("com.github.GTNewHorizons:Baubles:1.0.4:dev")
// compile("com.github.GTNewHorizons:WirelessCraftingTerminal:1.11.6:dev")
// compileOnly("com.github.GTNewHorizons:AE2FluidCraft-Rework:1.1.73-gtnh:dev") { transitive = false }
// compileOnly("com.github.GTNewHorizons:Avaritiaddons:1.6.0-GTNH:dev") { transitive = false }
// compileOnly("com.github.GTNewHorizons:BuildCraftCompat:7.1.16:dev") { transitive = false }
compileOnly('com.github.GTNewHorizons:EnderIO:2.5.8:dev') { transitive = false }
compileOnly("com.github.GTNewHorizons:ForestryMC:4.7.0:dev") { transitive = false }
compileOnly("com.github.GTNewHorizons:GT5-Unofficial:5.09.44.106:dev") { transitive = false }
compileOnly("com.github.GTNewHorizons:GTplusplus:1.10.51:dev") { transitive = false }
// compileOnly("com.github.GTNewHorizons:ThaumicEnergistics:1.5.4-GTNH:dev") { transitive = false }
compileOnly("com.github.GTNewHorizons:Botania:1.10.3-GTNH:dev") { transitive = false }
// compileOnly("com.github.GTNewHorizons:AE2FluidCraft-Rework:1.3.21-gtnh:dev") { transitive = false }
// compileOnly("com.github.GTNewHorizons:Avaritiaddons:1.7.1-GTNH:dev") { transitive = false }
// compileOnly("com.github.GTNewHorizons:BuildCraftCompat:7.1.17:dev") { transitive = false }
compileOnly('com.github.GTNewHorizons:EnderIO:2.8.17:dev') { transitive = false }
compileOnly("com.github.GTNewHorizons:ForestryMC:4.9.7:dev") { transitive = false }
compileOnly("com.github.GTNewHorizons:GT5-Unofficial:5.09.48.133:dev") { transitive = false }
// compileOnly("com.github.GTNewHorizons:ThaumicEnergistics:1.6.22-GTNH:dev") { transitive = false }
compileOnly("com.github.GTNewHorizons:Botania:1.11.3-GTNH:dev") { transitive = false }
compileOnly("com.gregoriust.gregtech:gregtech_1.7.10:6.14.23:dev") { transitive = false }
compileOnly("curse.maven:thaumcraft-nei-plugin-225095:2241913") { transitive = false }
// compileOnly("curse.maven:thermal-expansion-69163:2388759") { transitive = false }
+17 -5
View File
@@ -33,7 +33,7 @@ channel = stable
mappingsVersion = 12
# Defines other MCP mappings for dependency deobfuscation.
remoteMappings = https://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/
remoteMappings = https\://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/
# Select a default username for testing your mod. You can always override this per-run by running
# `./gradlew runClient --username=AnotherPlayer`, or configuring this command in your IDE.
@@ -61,6 +61,9 @@ gradleTokenModId = GRADLETOKEN_MODID
# [DEPRECATED] Mod name replacement token.
gradleTokenModName = GRADLETOKEN_MODNAME
# [DEPRECATED] Mod Group replacement token.
gradleTokenGroupName = GRADLETOKEN_GROUPNAME
# [DEPRECATED]
# Multiple source files can be defined here by providing a comma-separated list: Class1.java,Class2.java,Class3.java
# public static final String VERSION = "GRADLETOKEN_VERSION";
@@ -82,6 +85,11 @@ accessTransformersFile = jeca_at.cfg
# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled!
usesMixins = false
# Set to a non-empty string to configure mixins in a separate source set under src/VALUE, instead of src/main.
# This can speed up compile times thanks to not running the mixin annotation processor on all input sources.
# Mixin classes will have access to "main" classes, but not the other way around.
separateMixinSourceSet =
# Adds some debug arguments like verbose output and class export.
usesMixinDebug = false
@@ -114,16 +122,22 @@ minimizeShadowedDependencies = true
# If disabled, won't rename the shadowed classes.
relocateShadowedDependencies = true
# Adds the GTNH maven, CurseMaven, IC2/Player maven, and some more well-known 1.7.10 repositories.
# Adds CurseMaven, Modrinth, and some more well-known 1.7.10 repositories.
includeWellKnownRepositories = true
# A list of repositories to exclude from the includeWellKnownRepositories setting. Should be a space separated
# list of strings, with the acceptable keys being(case does not matter):
# cursemaven
# modrinth
excludeWellKnownRepositories =
# Change these to your Maven coordinates if you want to publish to a custom Maven repository instead of the default GTNH Maven.
# Authenticate with the MAVEN_USER and MAVEN_PASSWORD environment variables.
# If you need a more complex setup disable maven publishing here and add a publishing repository to addon.gradle.
usesMavenPublishing = true
# Maven repository to publish the mod to.
# mavenPublishUrl = https://nexus.gtnewhorizons.com/repository/releases/
# mavenPublishUrl = https\://nexus.gtnewhorizons.com/repository/releases/
# Publishing to Modrinth requires you to set the MODRINTH_TOKEN environment variable to your current Modrinth API token.
#
@@ -187,5 +201,3 @@ customArchiveBaseName = JustEnoughCalculation
# This is meant to be set in $HOME/.gradle/gradle.properties.
# ideaCheckSpotlessOnBuild = true
# Non-GTNH properties
gradleTokenGroupName = GRADLETOKEN_GROUPNAME
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
+1 -1
View File
@@ -17,7 +17,7 @@ pluginManagement {
}
plugins {
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.8'
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.26'
}
@@ -28,6 +28,7 @@ import me.towdium.jecalculation.data.structure.IRecord;
import me.towdium.jecalculation.data.structure.Recipe;
import me.towdium.jecalculation.data.structure.Recipes;
import me.towdium.jecalculation.data.structure.RecordCraft;
import me.towdium.jecalculation.data.structure.RecordGroupCraft;
import me.towdium.jecalculation.data.structure.RecordMath;
import me.towdium.jecalculation.data.structure.RecordPlayer;
import me.towdium.jecalculation.polyfill.MethodsReturnNonnullByDefault;
@@ -44,10 +45,12 @@ import me.towdium.jecalculation.utils.wrappers.Pair;
public class Controller {
public static final String KEY_MATH = "math";
public static final String KEY_GROUPCRAFT = "groupCraft";
public static final String KEY_CRAFT = "craft";
public static final String KEY_PLAYER = "player";
static RecordPlayer rPlayerClient;
static RecordGroupCraft rGroupCraftClient;
static RecordCraft rCraftClient;
static RecordMath rMathClient;
@@ -181,6 +184,14 @@ public class Controller {
return getR(rCraftClient, KEY_CRAFT, RecordCraft::new);
}
public static RecordGroupCraft getRGroupCraft() {
return getR(rGroupCraftClient, KEY_GROUPCRAFT, RecordGroupCraft::new);
}
public static void setRGroupCraft(RecordGroupCraft rgc) {
setR(rgc, i -> rGroupCraftClient = i, KEY_GROUPCRAFT);
}
public static RecordMath getRMath() {
return getR(rMathClient, KEY_MATH, RecordMath::new);
}
@@ -224,12 +235,14 @@ public class Controller {
boolean s = LPlaceholder.state;
LPlaceholder.state = true;
if (nbt != null) {
rGroupCraftClient = new RecordGroupCraft(nbt.getCompoundTag(KEY_GROUPCRAFT));
rCraftClient = new RecordCraft(nbt.getCompoundTag(KEY_CRAFT));
rMathClient = new RecordMath(nbt.getCompoundTag(KEY_MATH));
rPlayerClient = nbt.hasKey(KEY_PLAYER) ? new RecordPlayer(nbt.getCompoundTag(KEY_PLAYER))
: new RecordPlayer();
} else {
rPlayerClient = new RecordPlayer();
rGroupCraftClient = new RecordGroupCraft(new NBTTagCompound());
rCraftClient = new RecordCraft(new NBTTagCompound());
rMathClient = new RecordMath(new NBTTagCompound());
}
@@ -239,6 +252,7 @@ public class Controller {
public static void writeToLocal() {
File file = JecaConfig.recordFile;
NBTTagCompound nbt = new NBTTagCompound();
nbt.setTag(KEY_GROUPCRAFT, rGroupCraftClient.serialize());
nbt.setTag(KEY_CRAFT, rCraftClient.serialize());
nbt.setTag(KEY_PLAYER, rPlayerClient.serialize());
nbt.setTag(KEY_MATH, rMathClient.serialize());
@@ -0,0 +1,55 @@
package me.towdium.jecalculation.data.structure;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import me.towdium.jecalculation.data.label.ILabel;
public class RecordGroupCraft implements IRecord {
public static final String KEY_ITEMS = "items";
LinkedList<ILabel> craftList = new LinkedList<>();
public RecordGroupCraft(NBTTagCompound nbt) {
}
public void addLabel(ILabel l) {
if (l == ILabel.EMPTY) return;
craftList.remove(l);
craftList.addFirst(l);
}
public void setAmount(int index, long amount) {
if (index < 0 || index >= craftList.size()) return;
ILabel l = craftList.get(index);
if (l == ILabel.EMPTY) return;
l.setAmount(amount);
}
public void removeLabel(int index) {
if (index < 0 || index >= craftList.size()) return;
craftList.remove(index);
}
public List<ILabel> getCraftList() {
return craftList;
}
public ILabel getFirstOrEmpty() {
return craftList.isEmpty() ? ILabel.EMPTY : craftList.getFirst();
}
@Override
public NBTTagCompound serialize() {
NBTTagCompound nbt = new NBTTagCompound();
NBTTagList items = new NBTTagList();
craftList.forEach(l -> items.appendTag(l.SERIALIZER.serialize(l)));
nbt.setTag(KEY_ITEMS, items);
return nbt;
}
}
@@ -2,8 +2,8 @@ package me.towdium.jecalculation.event.handlers;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.InputEvent;
import cpw.mods.fml.common.gameevent.PlayerEvent;
import cpw.mods.fml.common.gameevent.TickEvent;
import cpw.mods.fml.common.network.FMLNetworkEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import me.towdium.jecalculation.JustEnoughCalculation;
@@ -24,14 +24,9 @@ public class FMLBusEventHandler {
JecaGui.onKey();
}
/**
* No effect at client only
*
* @param event event
*/
@Deprecated
@SubscribeEvent
public void onLogout(PlayerEvent.PlayerLoggedOutEvent event) {
public void onLogout(FMLNetworkEvent.ClientDisconnectionFromServerEvent event) {
JustEnoughCalculation.logger.info("on log out event");
Controller.writeToLocal();
LPlaceholder.onLogOut();
@@ -25,6 +25,7 @@ import me.towdium.jecalculation.data.label.ILabel;
import me.towdium.jecalculation.data.structure.CostList;
import me.towdium.jecalculation.data.structure.CostList.Calculator;
import me.towdium.jecalculation.data.structure.RecordCraft;
import me.towdium.jecalculation.data.structure.RecordGroupCraft;
import me.towdium.jecalculation.gui.JecaGui;
import me.towdium.jecalculation.gui.Resource;
import me.towdium.jecalculation.gui.widgets.WButton;
@@ -56,19 +57,21 @@ public class GuiCraft extends Gui {
Calculator calculator = null;
RecordCraft record;
WLabel label = new WLabel(31, 7, 20, 20, true).setLsnrUpdate((i, v) -> refreshLabel(v, false, true));
WLabelGroup recent = new WLabelGroup(7, 31, 8, 1, false).setLsnrLeftClick((i, v) -> {
RecordGroupCraft groupCraft;
WLabel label = new WLabel(31, 7, 20, 20, true).setLsnrUpdate((i, v) -> {
v.setAmount(getCurrentAmount());
addLabel(v);
refreshCrafts();
});
WLabelGroup recent = new WLabelGroup(7, 51, 8, 1, false).setLsnrLeftClick((i, v) -> {
ILabel l = i.get(v)
.getLabel();
if (l != ILabel.EMPTY) {
label.setLabel(
i.get(v)
.getLabel()
.copy(),
true);
addLabel(l);
refreshCrafts();
}
});
WLabelScroll result = new WLabelScroll(7, 87, 8, 4, false).setLsnrLeftClick((i, v) -> {
WLabelScroll result = new WLabelScroll(7, 107, 8, 4, false).setLsnrLeftClick((i, v) -> {
Object rep = i.get(v)
.getLabel()
.getRepresentation();
@@ -82,25 +85,38 @@ public class GuiCraft extends Gui {
})
.setFmtAmount(i -> i.getAmountString(true))
.setFmtTooltip((i, j) -> i.getToolTip(j, true));
WButton steps = new WButtonIcon(64, 62, 20, 20, Resource.BTN_LIST, "craft.step").setListener(i -> setMode(STEPS));
WButton catalyst = new WButtonIcon(45, 62, 20, 20, Resource.BTN_CAT, "common.catalyst")
WButton steps = new WButtonIcon(64, 82, 20, 20, Resource.BTN_LIST, "craft.step").setListener(i -> setMode(STEPS));
WButton catalyst = new WButtonIcon(45, 82, 20, 20, Resource.BTN_CAT, "common.catalyst")
.setListener(i -> setMode(CATALYST));
WButton output = new WButtonIcon(26, 62, 20, 20, Resource.BTN_OUT, "craft.output")
WButton output = new WButtonIcon(26, 82, 20, 20, Resource.BTN_OUT, "craft.output")
.setListener(i -> setMode(OUTPUT));
WButton input = new WButtonIcon(7, 62, 20, 20, Resource.BTN_IN, "common.input").setListener(i -> setMode(INPUT));
WButton invE = new WButtonIcon(149, 62, 20, 20, Resource.BTN_INV_E, "craft.inventory_enabled");
WButton invD = new WButtonIcon(149, 62, 20, 20, Resource.BTN_INV_D, "craft.inventory_disabled");
WButton input = new WButtonIcon(7, 82, 20, 20, Resource.BTN_IN, "common.input").setListener(i -> setMode(INPUT));
WButton invE = new WButtonIcon(149, 82, 20, 20, Resource.BTN_INV_E, "craft.inventory_enabled");
WButton invD = new WButtonIcon(149, 82, 20, 20, Resource.BTN_INV_D, "craft.inventory_disabled");
WTextField amount = new WTextField(60, 7, 65).setListener(i -> {
record.amount = i.getText();
Controller.setRCraft(record);
groupCraft.setAmount(0, getCurrentAmount());
refreshCalculator();
});
WLabelGroup craftingGroup = new WLabelGroup(7, 31, 8, 1, false).setLsnrLeftClick((i, v) -> {
ILabel item = i.get(v)
.getLabel();
if (item == ILabel.EMPTY) return;
addLabel(item);
amount.setText(item.getAmountString(false));
refreshCrafts();
})
.setLsnrRightClick((i, v) -> {
groupCraft.removeLabel(v + 1);
refreshCrafts();
})
.setFmtAmount(i -> i.getAmountString(true));
public GuiCraft() {
record = Controller.getRCraft();
groupCraft = Controller.getRGroupCraft();
amount.setText(record.amount);
add(new WHelp("craft"));
add(new WPanel());
add(new WPanel(0, 0, 176, 186));
add(
new WButtonIcon(7, 7, 20, 20, Resource.BTN_LABEL, "craft.label")
.setListener(i -> JecaGui.displayGui(new GuiLabel(l -> {
@@ -115,8 +131,18 @@ public class GuiCraft extends Gui {
.setListener(i -> JecaGui.displayGui(new GuiSearch())));
add(new WText(53, 13, JecaGui.Font.RAW, "x"));
add(new WLine(55));
add(new WIcon(151, 31, 18, 18, Resource.ICN_RECENT, "craft.history"));
add(recent, label, input, output, catalyst, steps, result, amount, record.inventory ? invE : invD);
add(new WIcon(151, 51, 18, 18, Resource.ICN_RECENT, "craft.history"));
add(
craftingGroup,
recent,
label,
input,
output,
catalyst,
steps,
result,
amount,
record.inventory ? invE : invD);
invE.setListener(i -> {
record.inventory = false;
Controller.setRCraft(record);
@@ -131,7 +157,7 @@ public class GuiCraft extends Gui {
add(invE);
refreshCalculator();
});
refreshRecent();
refreshRecent(true);
setMode(record.mode);
}
@@ -160,8 +186,8 @@ public class GuiCraft extends Gui {
refreshResult();
}
void refreshRecent() {
label.setLabel(record.getLatest());
void refreshRecent(boolean notify) {
label.setLabel(record.getLatest(), notify);
recent.setLabel(record.getHistory(), 0);
}
@@ -170,10 +196,7 @@ public class GuiCraft extends Gui {
String s = amount.getText();
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));
List<ILabel> dest = groupCraft.getCraftList();
CostList list = record.inventory ? new CostList(getInventory(), dest) : new CostList(dest);
calculator = list.calculate();
} catch (NumberFormatException | ArithmeticException e) {
@@ -218,7 +241,7 @@ public class GuiCraft extends Gui {
private void refreshLabel(ILabel l, boolean replace, boolean suggest) {
boolean dup = record.push(l, replace);
Controller.setRCraft(record);
refreshRecent();
refreshRecent(false);
refreshCalculator();
if (suggest && findRecipe(l).isEmpty()) {
Pair<List<ILabel>, List<ILabel>> guess = ILabel.CONVERTER.guess(Collections.singletonList(l), null);
@@ -240,6 +263,26 @@ public class GuiCraft extends Gui {
}
}
private void refreshCrafts() {
label.setLabel(groupCraft.getFirstOrEmpty(), false);
craftingGroup.setLabel(groupCraft.getCraftList(), 1);
refreshCalculator();
}
private long getCurrentAmount() {
String s = amount.getText();
return s.isEmpty() ? 1 : Long.parseLong(amount.getText());
}
private void addLabel(ILabel l) {
if (l == ILabel.EMPTY) return;
record.push(l, false);
Controller.setRCraft(record);
groupCraft.addLabel(l);
refreshCrafts();
refreshRecent(false);
}
private static List<ILabel> findRecipe(ILabel l) {
return Controller.recipeIterator()
.stream()