From e950575d4e11d27acbb6682b248de8f477a9ba50 Mon Sep 17 00:00:00 2001 From: olim Date: Tue, 23 Apr 2024 17:09:31 +0100 Subject: create mixin to render to the sign input screen and basic converter for k,m,b --- .../skyblocker/mixins/SignEditScreenMixin.java | 32 ++++++++++ .../hysky/skyblocker/skyblock/SignCalculator.java | 74 ++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java new file mode 100644 index 00000000..a88f97ef --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java @@ -0,0 +1,32 @@ +package de.hysky.skyblocker.mixin; + + +import de.hysky.skyblocker.skyblock.SignCalculator; +import net.minecraft.block.entity.SignBlockEntity; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ingame.AbstractSignEditScreen; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.Objects; + +@Mixin(AbstractSignEditScreen.class) +public abstract class SignEditScreenMixin{ + @Shadow + @Final + private String[] messages; + + @Inject(method = "render", at = @At("HEAD")) + private void skyblocker$render(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { + //if the sign is being used to enter number send it to the sign calculator + if (Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { + SignCalculator.renderSign(context, messages); + } + + } + +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java new file mode 100644 index 00000000..ab0d417c --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java @@ -0,0 +1,74 @@ +package de.hysky.skyblocker.skyblock; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.Util; +import net.minecraft.util.math.Vec3i; + +import java.awt.*; +import java.awt.image.LookupTable; +import java.text.DecimalFormat; +import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class SignCalculator { + + private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); + + private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+\\.?\\d*)([kmb]?)"); + private static final DecimalFormat FORMATTER = new DecimalFormat("#,###.##"); + + private static final HashMap magnitudeValues = Util.make(new HashMap<>(), map -> { + map.put("k", 1000); + map.put("m", 1000000); + map.put("b", 1000000000); + }); + + private static String input; + private static Double output; + + public static void renderSign(DrawContext context, String[] messages){ + input = messages[0]; + + calculateValue(); + + render(context); + } + + public static void calculateValue() { + Matcher numberMatcher = NUMBER_PATTERN.matcher(input.toLowerCase()); + if (!numberMatcher.matches()) { + output = null; + return; + } + double number = Double.parseDouble(numberMatcher.group(1)); // + String magnitude = numberMatcher.group(2); + + if (!magnitude.isEmpty()) { + if (!magnitudeValues.containsKey(magnitude)) {//its invalid if its another letter + output = null; + return; + } + number *= magnitudeValues.get(magnitude); + } + + output = number; + + } + + + private static void render(DrawContext context) { + Text text; + if (output == null) { + text = Text.literal("test").formatted(Formatting.RED); + } + else { + text = Text.literal(input +" = " + FORMATTER.format(output)).formatted(Formatting.GREEN); + } + + context.drawCenteredTextWithShadow(CLIENT.textRenderer, text,context.getScaledWindowWidth() /2 , 55,0xFFFFFFFF); + } +} -- cgit From e618d9e1e57b17c55b7b589e8a7e3f2ca2e95428 Mon Sep 17 00:00:00 2001 From: olim Date: Wed, 24 Apr 2024 13:12:46 +0100 Subject: calculations work should probaly move to utils function and need to add config and proper text --- .../skyblocker/mixins/SignEditScreenMixin.java | 8 + .../hysky/skyblocker/skyblock/SignCalculator.java | 223 +++++++++++++++++++-- 2 files changed, 214 insertions(+), 17 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java index a88f97ef..b160b3ac 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java @@ -26,6 +26,14 @@ public abstract class SignEditScreenMixin{ if (Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { SignCalculator.renderSign(context, messages); } + } + + @Inject(method = "finishEditing", at = @At("HEAD")) + private void skyblocker$finishEditing(CallbackInfo ci) { + //if the sign is being used to enter number get number from calculator for if maths has been done + if (Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { + messages[0] = SignCalculator.getNewValue(); + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java index ab0d417c..66b32028 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java @@ -1,16 +1,14 @@ package de.hysky.skyblocker.skyblock; +import de.hysky.skyblocker.skyblock.dungeon.puzzle.waterboard.Switch; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import net.minecraft.util.Util; -import net.minecraft.util.math.Vec3i; -import java.awt.*; -import java.awt.image.LookupTable; import java.text.DecimalFormat; -import java.util.HashMap; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -18,48 +16,239 @@ public class SignCalculator { private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); - private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+\\.?\\d*)([kmb]?)"); - private static final DecimalFormat FORMATTER = new DecimalFormat("#,###.##"); - + public enum TokenType { + NUMBER, OPERATOR, L_PARENTHESIS, R_PARENTHESIS + } + public static class Token { + public TokenType type; + String value; + int tokenLength; + } + private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+\\.?\\d*)([kmbs]?)"); private static final HashMap magnitudeValues = Util.make(new HashMap<>(), map -> { + map.put("s", 64); map.put("k", 1000); map.put("m", 1000000); map.put("b", 1000000000); }); + + + + private static final DecimalFormat FORMATTER = new DecimalFormat("#,###.##"); + + private static String lastInput; private static String input; private static Double output; public static void renderSign(DrawContext context, String[] messages){ input = messages[0]; - calculateValue(); + + //only update output if new input + if (!input.equals(lastInput)) { // + try { + output = evaluate(shunt(lex(input))); + } catch (Exception e){ + output = null; //todo log + } + } + render(context); + + lastInput = input; + } + + public static String getNewValue() { + if (output == null) { + return ""; + } + return Double.toString(output); + } + + private static List lex(String input) { + List tokens = new ArrayList<>(); + input = input.replace(" ", "").toLowerCase().replace("x","*"); + int i = 0; + while (i < input.length()) { + Token token = new Token(); + switch (input.charAt(i)) { + case '+','-','*','/' -> { + token.type = TokenType.OPERATOR; + token.value = String.valueOf(input.charAt(i)); + token.tokenLength = 1; + } + + case '(' -> { + token.type = TokenType.L_PARENTHESIS; + token.value = String.valueOf(input.charAt(i)); + token.tokenLength = 1; + //add implicit multiplication when there is a number before brackets + if (!tokens.isEmpty() ) { + TokenType lastType = tokens.get(tokens.size()-1).type; + if (lastType == TokenType.R_PARENTHESIS || lastType == TokenType.NUMBER) { + Token mutliplyToken = new Token(); + mutliplyToken.type = TokenType.OPERATOR; + mutliplyToken.value = "*"; + tokens.add(mutliplyToken); + } + } + } + + case ')' -> { + token.type = TokenType.R_PARENTHESIS; + token.value = String.valueOf(input.charAt(i)); + token.tokenLength = 1; + } + + default -> { + token.type = TokenType.NUMBER; + Matcher numberMatcher = NUMBER_PATTERN.matcher(input.substring(i)); + if (!numberMatcher.find()) {//invalid value to lex + throw new UnsupportedOperationException(); + } + int end = numberMatcher.end(); + token.value = input.substring(i,i + end); + token.tokenLength = end; + } + } + tokens.add(token); + + i += token.tokenLength; + } + + return tokens; } - public static void calculateValue() { - Matcher numberMatcher = NUMBER_PATTERN.matcher(input.toLowerCase()); + private static List shunt(List tokens) { + // This is an implementation of the shunting yard algorithm + // Converts equation to use reverse polish notation + + Deque operatorStack = new ArrayDeque<>(); + List outputQueue = new ArrayList<>(); + + for (Token shuntingToken : tokens) + switch (shuntingToken.type) { + case NUMBER -> { + outputQueue.add(shuntingToken); + } + case OPERATOR -> { + int precedence = getPrecedence(shuntingToken.value); + while (!operatorStack.isEmpty()) { + Token leftToken = operatorStack.peek(); + if (leftToken.type == TokenType.L_PARENTHESIS) { + break; + } + assert (leftToken.type == TokenType.OPERATOR); //todo why is this here + int leftPrecedence = getPrecedence(leftToken.value); + if (leftPrecedence >= precedence) { + outputQueue.add(operatorStack.pop()); + continue; + } + break; + } + operatorStack.push(shuntingToken); + } + case L_PARENTHESIS -> { + operatorStack.push(shuntingToken); + } + case R_PARENTHESIS -> { + while (true) { + if (operatorStack.isEmpty()) { + throw new UnsupportedOperationException("Unbalanced left parenthesis"); + } + Token leftToken = operatorStack.pop(); + if (leftToken.type == TokenType.L_PARENTHESIS) { + break; + } + outputQueue.add(leftToken); + } + } + } + //empty the operator stack + while (!operatorStack.isEmpty()) { + Token leftToken = operatorStack.pop(); + if (leftToken.type == TokenType.L_PARENTHESIS) { + throw new UnsupportedOperationException("Unbalanced left parenthesis"); + } + outputQueue.add(leftToken); + } + + return outputQueue.stream().toList(); + } + private static int getPrecedence(String operator) { + switch (operator) { + case "+","-" -> { + return 0; + } + case "*","/" -> { + return 1; + } + default -> { + throw new UnsupportedOperationException(); + } + } + } + + /** + * + * @param tokens list of Tokens in reverse polish notation + * @return answer to equation + */ + private static double evaluate(List tokens) { + Deque values = new ArrayDeque<>(); + for (Token token : tokens) { + switch (token.type) { + case NUMBER -> { + values.push(calculateValue(token.value)); + } + case OPERATOR -> { + double right = values.pop(); + double left = values.pop(); + switch (token.value) { + case "+" -> { + values.push(left + right); + } + case "-" -> { + values.push(left - right); + } + case "/" -> { + values.push(left / right); + } + case "*" -> { + values.push(left * right); + } + } + } + case L_PARENTHESIS, R_PARENTHESIS -> { + throw new UnsupportedOperationException("equation is not in RPN"); + } + } + } + return values.pop(); + } + + private static double calculateValue(String value) { + Matcher numberMatcher = NUMBER_PATTERN.matcher(value.toLowerCase()); if (!numberMatcher.matches()) { - output = null; - return; + throw new UnsupportedOperationException(); } - double number = Double.parseDouble(numberMatcher.group(1)); // + double number = Double.parseDouble(numberMatcher.group(1)); String magnitude = numberMatcher.group(2); if (!magnitude.isEmpty()) { if (!magnitudeValues.containsKey(magnitude)) {//its invalid if its another letter - output = null; - return; + throw new UnsupportedOperationException(); } number *= magnitudeValues.get(magnitude); } - output = number; - + return number; } + private static void render(DrawContext context) { Text text; if (output == null) { -- cgit From aa97d9a5bb3e9274ac04b47c5d711c20e7b30087 Mon Sep 17 00:00:00 2001 From: olim Date: Wed, 24 Apr 2024 16:26:50 +0100 Subject: fix amount outputs to be full numbers --- .../java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java | 7 ++++++- src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java index b160b3ac..3c1667f0 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java @@ -32,7 +32,12 @@ public abstract class SignEditScreenMixin{ private void skyblocker$finishEditing(CallbackInfo ci) { //if the sign is being used to enter number get number from calculator for if maths has been done if (Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { - messages[0] = SignCalculator.getNewValue(); + boolean isPrice = messages[2].contains("price"); + String value = SignCalculator.getNewValue(isPrice); + if (value.length() >= 15) { + value = value.substring(0,15); + } + messages[0] = value; } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java index 66b32028..e71442a5 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java @@ -60,11 +60,16 @@ public class SignCalculator { lastInput = input; } - public static String getNewValue() { + public static String getNewValue(Boolean isPrice) { if (output == null) { return ""; } - return Double.toString(output); + //price can except decimals and exponents + if (isPrice) { + return output.toString(); + } + //amounts want an integer number so round + return Long.toString(Math.round(output)); } private static List lex(String input) { -- cgit From 6ae6896b147cd9e012f52e15a2d5ac0beb898c44 Mon Sep 17 00:00:00 2001 From: olim Date: Wed, 24 Apr 2024 17:14:09 +0100 Subject: move the calculator to a util function --- .../hysky/skyblocker/skyblock/SignCalculator.java | 207 +------------------- .../java/de/hysky/skyblocker/utils/Calculator.java | 213 +++++++++++++++++++++ 2 files changed, 216 insertions(+), 204 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/utils/Calculator.java (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java index e71442a5..cf621ca7 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java @@ -1,6 +1,7 @@ package de.hysky.skyblocker.skyblock; import de.hysky.skyblocker.skyblock.dungeon.puzzle.waterboard.Switch; +import de.hysky.skyblocker.utils.Calculator; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.text.Text; @@ -16,25 +17,6 @@ public class SignCalculator { private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); - public enum TokenType { - NUMBER, OPERATOR, L_PARENTHESIS, R_PARENTHESIS - } - public static class Token { - public TokenType type; - String value; - int tokenLength; - } - private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+\\.?\\d*)([kmbs]?)"); - private static final HashMap magnitudeValues = Util.make(new HashMap<>(), map -> { - map.put("s", 64); - map.put("k", 1000); - map.put("m", 1000000); - map.put("b", 1000000000); - }); - - - - private static final DecimalFormat FORMATTER = new DecimalFormat("#,###.##"); private static String lastInput; @@ -48,13 +30,12 @@ public class SignCalculator { //only update output if new input if (!input.equals(lastInput)) { // try { - output = evaluate(shunt(lex(input))); + output = Calculator.calculate(input); } catch (Exception e){ output = null; //todo log } } - render(context); lastInput = input; @@ -72,192 +53,10 @@ public class SignCalculator { return Long.toString(Math.round(output)); } - private static List lex(String input) { - List tokens = new ArrayList<>(); - input = input.replace(" ", "").toLowerCase().replace("x","*"); - int i = 0; - while (i < input.length()) { - Token token = new Token(); - switch (input.charAt(i)) { - case '+','-','*','/' -> { - token.type = TokenType.OPERATOR; - token.value = String.valueOf(input.charAt(i)); - token.tokenLength = 1; - } - - case '(' -> { - token.type = TokenType.L_PARENTHESIS; - token.value = String.valueOf(input.charAt(i)); - token.tokenLength = 1; - //add implicit multiplication when there is a number before brackets - if (!tokens.isEmpty() ) { - TokenType lastType = tokens.get(tokens.size()-1).type; - if (lastType == TokenType.R_PARENTHESIS || lastType == TokenType.NUMBER) { - Token mutliplyToken = new Token(); - mutliplyToken.type = TokenType.OPERATOR; - mutliplyToken.value = "*"; - tokens.add(mutliplyToken); - } - } - } - - case ')' -> { - token.type = TokenType.R_PARENTHESIS; - token.value = String.valueOf(input.charAt(i)); - token.tokenLength = 1; - } - - default -> { - token.type = TokenType.NUMBER; - Matcher numberMatcher = NUMBER_PATTERN.matcher(input.substring(i)); - if (!numberMatcher.find()) {//invalid value to lex - throw new UnsupportedOperationException(); - } - int end = numberMatcher.end(); - token.value = input.substring(i,i + end); - token.tokenLength = end; - } - } - tokens.add(token); - - i += token.tokenLength; - } - - return tokens; - } - - private static List shunt(List tokens) { - // This is an implementation of the shunting yard algorithm - // Converts equation to use reverse polish notation - - Deque operatorStack = new ArrayDeque<>(); - List outputQueue = new ArrayList<>(); - - for (Token shuntingToken : tokens) - switch (shuntingToken.type) { - case NUMBER -> { - outputQueue.add(shuntingToken); - } - case OPERATOR -> { - int precedence = getPrecedence(shuntingToken.value); - while (!operatorStack.isEmpty()) { - Token leftToken = operatorStack.peek(); - if (leftToken.type == TokenType.L_PARENTHESIS) { - break; - } - assert (leftToken.type == TokenType.OPERATOR); //todo why is this here - int leftPrecedence = getPrecedence(leftToken.value); - if (leftPrecedence >= precedence) { - outputQueue.add(operatorStack.pop()); - continue; - } - break; - } - operatorStack.push(shuntingToken); - } - case L_PARENTHESIS -> { - operatorStack.push(shuntingToken); - } - case R_PARENTHESIS -> { - while (true) { - if (operatorStack.isEmpty()) { - throw new UnsupportedOperationException("Unbalanced left parenthesis"); - } - Token leftToken = operatorStack.pop(); - if (leftToken.type == TokenType.L_PARENTHESIS) { - break; - } - outputQueue.add(leftToken); - } - } - } - //empty the operator stack - while (!operatorStack.isEmpty()) { - Token leftToken = operatorStack.pop(); - if (leftToken.type == TokenType.L_PARENTHESIS) { - throw new UnsupportedOperationException("Unbalanced left parenthesis"); - } - outputQueue.add(leftToken); - } - - return outputQueue.stream().toList(); - } - private static int getPrecedence(String operator) { - switch (operator) { - case "+","-" -> { - return 0; - } - case "*","/" -> { - return 1; - } - default -> { - throw new UnsupportedOperationException(); - } - } - } - - /** - * - * @param tokens list of Tokens in reverse polish notation - * @return answer to equation - */ - private static double evaluate(List tokens) { - Deque values = new ArrayDeque<>(); - for (Token token : tokens) { - switch (token.type) { - case NUMBER -> { - values.push(calculateValue(token.value)); - } - case OPERATOR -> { - double right = values.pop(); - double left = values.pop(); - switch (token.value) { - case "+" -> { - values.push(left + right); - } - case "-" -> { - values.push(left - right); - } - case "/" -> { - values.push(left / right); - } - case "*" -> { - values.push(left * right); - } - } - } - case L_PARENTHESIS, R_PARENTHESIS -> { - throw new UnsupportedOperationException("equation is not in RPN"); - } - } - } - return values.pop(); - } - - private static double calculateValue(String value) { - Matcher numberMatcher = NUMBER_PATTERN.matcher(value.toLowerCase()); - if (!numberMatcher.matches()) { - throw new UnsupportedOperationException(); - } - double number = Double.parseDouble(numberMatcher.group(1)); - String magnitude = numberMatcher.group(2); - - if (!magnitude.isEmpty()) { - if (!magnitudeValues.containsKey(magnitude)) {//its invalid if its another letter - throw new UnsupportedOperationException(); - } - number *= magnitudeValues.get(magnitude); - } - - return number; - } - - - private static void render(DrawContext context) { Text text; if (output == null) { - text = Text.literal("test").formatted(Formatting.RED); + text = Text.literal("Invalid Equation").formatted(Formatting.RED); } else { text = Text.literal(input +" = " + FORMATTER.format(output)).formatted(Formatting.GREEN); diff --git a/src/main/java/de/hysky/skyblocker/utils/Calculator.java b/src/main/java/de/hysky/skyblocker/utils/Calculator.java new file mode 100644 index 00000000..61cdf169 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/Calculator.java @@ -0,0 +1,213 @@ +package de.hysky.skyblocker.utils; + +import de.hysky.skyblocker.skyblock.SignCalculator; +import net.minecraft.util.Util; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Calculator { + + public enum TokenType { + NUMBER, OPERATOR, L_PARENTHESIS, R_PARENTHESIS + } + public static class Token { + public TokenType type; + String value; + int tokenLength; + } + private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+\\.?\\d*)([kmbs]?)"); + private static final HashMap magnitudeValues = Util.make(new HashMap<>(), map -> { + map.put("s", 64); + map.put("k", 1000); + map.put("m", 1000000); + map.put("b", 1000000000); + }); + + + private static List lex(String input) { + List tokens = new ArrayList<>(); + input = input.replace(" ", "").toLowerCase().replace("x","*"); + int i = 0; + while (i < input.length()) { + Token token = new Token(); + switch (input.charAt(i)) { + case '+','-','*','/' -> { + token.type = TokenType.OPERATOR; + token.value = String.valueOf(input.charAt(i)); + token.tokenLength = 1; + } + + case '(' -> { + token.type = TokenType.L_PARENTHESIS; + token.value = String.valueOf(input.charAt(i)); + token.tokenLength = 1; + //add implicit multiplication when there is a number before brackets + if (!tokens.isEmpty() ) { + TokenType lastType = tokens.get(tokens.size()-1).type; + if (lastType == TokenType.R_PARENTHESIS || lastType == TokenType.NUMBER) { + Token mutliplyToken = new Token(); + mutliplyToken.type = TokenType.OPERATOR; + mutliplyToken.value = "*"; + tokens.add(mutliplyToken); + } + } + } + + case ')' -> { + token.type = TokenType.R_PARENTHESIS; + token.value = String.valueOf(input.charAt(i)); + token.tokenLength = 1; + } + + default -> { + token.type = TokenType.NUMBER; + Matcher numberMatcher = NUMBER_PATTERN.matcher(input.substring(i)); + if (!numberMatcher.find()) {//invalid value to lex + throw new UnsupportedOperationException(); + } + int end = numberMatcher.end(); + token.value = input.substring(i,i + end); + token.tokenLength = end; + } + } + tokens.add(token); + + i += token.tokenLength; + } + + return tokens; + } + + private static List shunt(List tokens) { + // This is an implementation of the shunting yard algorithm + // Converts equation to use reverse polish notation + + Deque operatorStack = new ArrayDeque<>(); + List outputQueue = new ArrayList<>(); + + for (Token shuntingToken : tokens) + switch (shuntingToken.type) { + case NUMBER -> { + outputQueue.add(shuntingToken); + } + case OPERATOR -> { + int precedence = getPrecedence(shuntingToken.value); + while (!operatorStack.isEmpty()) { + Token leftToken = operatorStack.peek(); + if (leftToken.type == TokenType.L_PARENTHESIS) { + break; + } + assert (leftToken.type == TokenType.OPERATOR); //todo why is this here + int leftPrecedence = getPrecedence(leftToken.value); + if (leftPrecedence >= precedence) { + outputQueue.add(operatorStack.pop()); + continue; + } + break; + } + operatorStack.push(shuntingToken); + } + case L_PARENTHESIS -> { + operatorStack.push(shuntingToken); + } + case R_PARENTHESIS -> { + while (true) { + if (operatorStack.isEmpty()) { + throw new UnsupportedOperationException("Unbalanced left parenthesis"); + } + Token leftToken = operatorStack.pop(); + if (leftToken.type == TokenType.L_PARENTHESIS) { + break; + } + outputQueue.add(leftToken); + } + } + } + //empty the operator stack + while (!operatorStack.isEmpty()) { + Token leftToken = operatorStack.pop(); + if (leftToken.type == TokenType.L_PARENTHESIS) { + throw new UnsupportedOperationException("Unbalanced left parenthesis"); + } + outputQueue.add(leftToken); + } + + return outputQueue.stream().toList(); + } + private static int getPrecedence(String operator) { + switch (operator) { + case "+","-" -> { + return 0; + } + case "*","/" -> { + return 1; + } + default -> { + throw new UnsupportedOperationException(); + } + } + } + + /** + * + * @param tokens list of Tokens in reverse polish notation + * @return answer to equation + */ + private static double evaluate(List tokens) { + Deque values = new ArrayDeque<>(); + for (Token token : tokens) { + switch (token.type) { + case NUMBER -> { + values.push(calculateValue(token.value)); + } + case OPERATOR -> { + double right = values.pop(); + double left = values.pop(); + switch (token.value) { + case "+" -> { + values.push(left + right); + } + case "-" -> { + values.push(left - right); + } + case "/" -> { + values.push(left / right); + } + case "*" -> { + values.push(left * right); + } + } + } + case L_PARENTHESIS, R_PARENTHESIS -> { + throw new UnsupportedOperationException("equation is not in RPN"); + } + } + } + return values.pop(); + } + + private static double calculateValue(String value) { + Matcher numberMatcher = NUMBER_PATTERN.matcher(value.toLowerCase()); + if (!numberMatcher.matches()) { + throw new UnsupportedOperationException(); + } + double number = Double.parseDouble(numberMatcher.group(1)); + String magnitude = numberMatcher.group(2); + + if (!magnitude.isEmpty()) { + if (!magnitudeValues.containsKey(magnitude)) {//its invalid if its another letter + throw new UnsupportedOperationException(); + } + number *= magnitudeValues.get(magnitude); + } + + return number; + } + + public static double calculate(String equation) { + return evaluate(shunt(lex(equation))); + } + +} -- cgit From 05c44d712d1a4f950733fae875cb97792e4fef1e Mon Sep 17 00:00:00 2001 From: olim Date: Wed, 24 Apr 2024 17:33:53 +0100 Subject: add messages to exceptions --- .../hysky/skyblocker/skyblock/SignCalculator.java | 2 +- .../java/de/hysky/skyblocker/utils/Calculator.java | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java index cf621ca7..cbff07c9 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java @@ -32,7 +32,7 @@ public class SignCalculator { try { output = Calculator.calculate(input); } catch (Exception e){ - output = null; //todo log + output = null; } } diff --git a/src/main/java/de/hysky/skyblocker/utils/Calculator.java b/src/main/java/de/hysky/skyblocker/utils/Calculator.java index 61cdf169..fb2b8b11 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Calculator.java +++ b/src/main/java/de/hysky/skyblocker/utils/Calculator.java @@ -65,7 +65,7 @@ public class Calculator { token.type = TokenType.NUMBER; Matcher numberMatcher = NUMBER_PATTERN.matcher(input.substring(i)); if (!numberMatcher.find()) {//invalid value to lex - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("invalid character"); } int end = numberMatcher.end(); token.value = input.substring(i,i + end); @@ -80,10 +80,13 @@ public class Calculator { return tokens; } - private static List shunt(List tokens) { - // This is an implementation of the shunting yard algorithm - // Converts equation to use reverse polish notation + /** + * This is an implementation of the shunting yard algorithm to convert the equation to reverse polish notation + * @param tokens equation in infix notation order + * @return equation in RPN order + */ + private static List shunt(List tokens) { Deque operatorStack = new ArrayDeque<>(); List outputQueue = new ArrayList<>(); @@ -99,7 +102,7 @@ public class Calculator { if (leftToken.type == TokenType.L_PARENTHESIS) { break; } - assert (leftToken.type == TokenType.OPERATOR); //todo why is this here + assert (leftToken.type == TokenType.OPERATOR); int leftPrecedence = getPrecedence(leftToken.value); if (leftPrecedence >= precedence) { outputQueue.add(operatorStack.pop()); @@ -145,7 +148,7 @@ public class Calculator { return 1; } default -> { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("invalid operator"); } } } @@ -173,6 +176,9 @@ public class Calculator { values.push(left - right); } case "/" -> { + if (right == 0) { + throw new UnsupportedOperationException("Can not divide by 0"); + } values.push(left / right); } case "*" -> { @@ -191,14 +197,14 @@ public class Calculator { private static double calculateValue(String value) { Matcher numberMatcher = NUMBER_PATTERN.matcher(value.toLowerCase()); if (!numberMatcher.matches()) { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("invalid number"); } double number = Double.parseDouble(numberMatcher.group(1)); String magnitude = numberMatcher.group(2); if (!magnitude.isEmpty()) { if (!magnitudeValues.containsKey(magnitude)) {//its invalid if its another letter - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("invalid magnitude"); } number *= magnitudeValues.get(magnitude); } -- cgit From 0619e195661f4ed285786ea679a27e1f28f9dd6e Mon Sep 17 00:00:00 2001 From: olim Date: Wed, 24 Apr 2024 17:41:35 +0100 Subject: add config option --- src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java | 7 +++++-- src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java index 3c1667f0..867edb7d 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java @@ -1,8 +1,11 @@ package de.hysky.skyblocker.mixin; +import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.SignCalculator; +import de.hysky.skyblocker.utils.Utils; import net.minecraft.block.entity.SignBlockEntity; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.ingame.AbstractSignEditScreen; import org.spongepowered.asm.mixin.Final; @@ -23,7 +26,7 @@ public abstract class SignEditScreenMixin{ @Inject(method = "render", at = @At("HEAD")) private void skyblocker$render(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { //if the sign is being used to enter number send it to the sign calculator - if (Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { + if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.enableSignCalculator && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { SignCalculator.renderSign(context, messages); } } @@ -31,7 +34,7 @@ public abstract class SignEditScreenMixin{ @Inject(method = "finishEditing", at = @At("HEAD")) private void skyblocker$finishEditing(CallbackInfo ci) { //if the sign is being used to enter number get number from calculator for if maths has been done - if (Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { + if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.enableSignCalculator && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { boolean isPrice = messages[2].contains("price"); String value = SignCalculator.getNewValue(isPrice); if (value.length() >= 15) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java index cbff07c9..be393b49 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java @@ -56,7 +56,7 @@ public class SignCalculator { private static void render(DrawContext context) { Text text; if (output == null) { - text = Text.literal("Invalid Equation").formatted(Formatting.RED); + text = Text.translatable("text.autoconfig.skyblocker.option.general.enableSignCalculator.invalidEquation").formatted(Formatting.RED); } else { text = Text.literal(input +" = " + FORMATTER.format(output)).formatted(Formatting.GREEN); -- cgit From 79ded04ec6834ad28f23f9db0f205689deda467d Mon Sep 17 00:00:00 2001 From: olim Date: Thu, 25 Apr 2024 11:45:23 +0100 Subject: be more lenient with brackets --- src/main/java/de/hysky/skyblocker/utils/Calculator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/utils/Calculator.java b/src/main/java/de/hysky/skyblocker/utils/Calculator.java index fb2b8b11..c8dcb6d8 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Calculator.java +++ b/src/main/java/de/hysky/skyblocker/utils/Calculator.java @@ -132,7 +132,8 @@ public class Calculator { while (!operatorStack.isEmpty()) { Token leftToken = operatorStack.pop(); if (leftToken.type == TokenType.L_PARENTHESIS) { - throw new UnsupportedOperationException("Unbalanced left parenthesis"); + //technically unbalanced left parenthesis error but just assume they are close after the equation and ignore them from here + continue; } outputQueue.add(leftToken); } -- cgit From feee94e2c2ce01262f3eb47d7b356ca9821bdb79 Mon Sep 17 00:00:00 2001 From: olim Date: Fri, 26 Apr 2024 18:01:09 +0100 Subject: add command add command to be able to use the calculator and fix crash with emty equations --- .../java/de/hysky/skyblocker/SkyblockerMod.java | 2 + .../skyblocker/mixins/SignEditScreenMixin.java | 4 +- .../hysky/skyblocker/skyblock/SignCalculator.java | 67 ---------------------- .../skyblock/calculators/CalculatorCommand.java | 57 ++++++++++++++++++ .../skyblock/calculators/SignCalculator.java | 62 ++++++++++++++++++++ .../java/de/hysky/skyblocker/utils/Calculator.java | 14 ++--- 6 files changed, 129 insertions(+), 77 deletions(-) delete mode 100644 src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index 3336cefb..9840c02f 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -7,6 +7,7 @@ import de.hysky.skyblocker.config.ImageRepoLoader; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.debug.Debug; import de.hysky.skyblocker.skyblock.*; +import de.hysky.skyblocker.skyblock.calculators.CalculatorCommand; import de.hysky.skyblocker.skyblock.chat.ChatRuleAnnouncementScreen; import de.hysky.skyblocker.skyblock.chat.ChatRulesHandler; import de.hysky.skyblocker.skyblock.crimson.kuudra.Kuudra; @@ -132,6 +133,7 @@ public class SkyblockerMod implements ClientModInitializer { Shortcuts.init(); ChatRulesHandler.init(); ChatRuleAnnouncementScreen.init(); + CalculatorCommand.init(); DiscordRPCManager.init(); LividColor.init(); FishingHelper.init(); diff --git a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java index 867edb7d..88c54878 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java @@ -2,10 +2,8 @@ package de.hysky.skyblocker.mixin; import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.hysky.skyblocker.skyblock.SignCalculator; +import de.hysky.skyblocker.skyblock.calculators.SignCalculator; import de.hysky.skyblocker.utils.Utils; -import net.minecraft.block.entity.SignBlockEntity; -import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.ingame.AbstractSignEditScreen; import org.spongepowered.asm.mixin.Final; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java deleted file mode 100644 index be393b49..00000000 --- a/src/main/java/de/hysky/skyblocker/skyblock/SignCalculator.java +++ /dev/null @@ -1,67 +0,0 @@ -package de.hysky.skyblocker.skyblock; - -import de.hysky.skyblocker.skyblock.dungeon.puzzle.waterboard.Switch; -import de.hysky.skyblocker.utils.Calculator; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Util; - -import java.text.DecimalFormat; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class SignCalculator { - - private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); - - private static final DecimalFormat FORMATTER = new DecimalFormat("#,###.##"); - - private static String lastInput; - private static String input; - private static Double output; - - public static void renderSign(DrawContext context, String[] messages){ - input = messages[0]; - - - //only update output if new input - if (!input.equals(lastInput)) { // - try { - output = Calculator.calculate(input); - } catch (Exception e){ - output = null; - } - } - - render(context); - - lastInput = input; - } - - public static String getNewValue(Boolean isPrice) { - if (output == null) { - return ""; - } - //price can except decimals and exponents - if (isPrice) { - return output.toString(); - } - //amounts want an integer number so round - return Long.toString(Math.round(output)); - } - - private static void render(DrawContext context) { - Text text; - if (output == null) { - text = Text.translatable("text.autoconfig.skyblocker.option.general.enableSignCalculator.invalidEquation").formatted(Formatting.RED); - } - else { - text = Text.literal(input +" = " + FORMATTER.format(output)).formatted(Formatting.GREEN); - } - - context.drawCenteredTextWithShadow(CLIENT.textRenderer, text,context.getScaledWindowWidth() /2 , 55,0xFFFFFFFF); - } -} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java b/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java new file mode 100644 index 00000000..f9b8b4cf --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java @@ -0,0 +1,57 @@ +package de.hysky.skyblocker.skyblock.calculators; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.StringArgumentType; +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.utils.Calculator; +import de.hysky.skyblocker.utils.Constants; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.client.MinecraftClient; +import net.minecraft.command.CommandRegistryAccess; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +import java.text.DecimalFormat; + +import static com.mojang.brigadier.arguments.StringArgumentType.getString; +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; + +public class CalculatorCommand { + private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); + + private static final DecimalFormat FORMATTER = new DecimalFormat("#,###.##"); + + public static void init() { + ClientCommandRegistrationCallback.EVENT.register(CalculatorCommand::calculate); + } + + private static void calculate(CommandDispatcher dispatcher, CommandRegistryAccess registryAccess) { + dispatcher.register(literal(SkyblockerMod.NAMESPACE) + .then(literal("calculate") + .then(argument("equation", StringArgumentType.greedyString()) + .executes(context -> doCalculation(getString(context, "equation")) ) + ) + ) + ); + } + + private static int doCalculation(String calculation) { + MutableText text = Constants.PREFIX.get(); + try { + text.append(Text.literal(FORMATTER.format(Calculator.calculate(calculation))).formatted(Formatting.GREEN)); + } catch (UnsupportedOperationException e) { + text.append(Text.literal("text.autoconfig.skyblocker.option.general.enableSignCalculator.invalidEquation").formatted(Formatting.RED)); + } + + if (CLIENT == null || CLIENT.player == null) { + return 0; + } + + CLIENT.player.sendMessage(text, false); + return Command.SINGLE_SUCCESS; + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java new file mode 100644 index 00000000..7dbeabd9 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java @@ -0,0 +1,62 @@ +package de.hysky.skyblocker.skyblock.calculators; + +import de.hysky.skyblocker.utils.Calculator; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +import java.text.DecimalFormat; + +public class SignCalculator { + + private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); + + private static final DecimalFormat FORMATTER = new DecimalFormat("#,###.##"); + + private static String lastInput; + private static String input; + private static Double output; + + public static void renderSign(DrawContext context, String[] messages){ + input = messages[0]; + + + //only update output if new input + if (!input.equals(lastInput)) { // + try { + output = Calculator.calculate(input); + } catch (Exception e){ + output = null; + } + } + + render(context); + + lastInput = input; + } + + public static String getNewValue(Boolean isPrice) { + if (output == null) { + return ""; + } + //price can except decimals and exponents + if (isPrice) { + return output.toString(); + } + //amounts want an integer number so round + return Long.toString(Math.round(output)); + } + + private static void render(DrawContext context) { + Text text; + if (output == null) { + text = Text.translatable("text.autoconfig.skyblocker.option.general.enableSignCalculator.invalidEquation").formatted(Formatting.RED); + } + else { + text = Text.literal(input +" = " + FORMATTER.format(output)).formatted(Formatting.GREEN); + } + + context.drawCenteredTextWithShadow(CLIENT.textRenderer, text,context.getScaledWindowWidth() /2 , 55,0xFFFFFFFF); + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/Calculator.java b/src/main/java/de/hysky/skyblocker/utils/Calculator.java index c8dcb6d8..19155708 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Calculator.java +++ b/src/main/java/de/hysky/skyblocker/utils/Calculator.java @@ -1,6 +1,5 @@ package de.hysky.skyblocker.utils; -import de.hysky.skyblocker.skyblock.SignCalculator; import net.minecraft.util.Util; import java.util.*; @@ -148,9 +147,7 @@ public class Calculator { case "*","/" -> { return 1; } - default -> { - throw new UnsupportedOperationException("invalid operator"); - } + default -> throw new UnsupportedOperationException("Invalid operator"); } } @@ -188,24 +185,27 @@ public class Calculator { } } case L_PARENTHESIS, R_PARENTHESIS -> { - throw new UnsupportedOperationException("equation is not in RPN"); + throw new UnsupportedOperationException("Equation is not in RPN"); } } } + if (values.isEmpty()) { + throw new UnsupportedOperationException("Equation is empty"); + } return values.pop(); } private static double calculateValue(String value) { Matcher numberMatcher = NUMBER_PATTERN.matcher(value.toLowerCase()); if (!numberMatcher.matches()) { - throw new UnsupportedOperationException("invalid number"); + throw new UnsupportedOperationException("Invalid number"); } double number = Double.parseDouble(numberMatcher.group(1)); String magnitude = numberMatcher.group(2); if (!magnitude.isEmpty()) { if (!magnitudeValues.containsKey(magnitude)) {//its invalid if its another letter - throw new UnsupportedOperationException("invalid magnitude"); + throw new UnsupportedOperationException("Invalid magnitude"); } number *= magnitudeValues.get(magnitude); } -- cgit From 08140d6b262a9b694cbc9d14189249d10c10eef6 Mon Sep 17 00:00:00 2001 From: olim Date: Thu, 2 May 2024 19:38:55 +0100 Subject: clean code and fix to 1.20.6 --- .../skyblocker/mixins/SignEditScreenMixin.java | 10 ++++---- .../skyblock/calculators/CalculatorCommand.java | 2 +- .../skyblock/calculators/SignCalculator.java | 15 +++++------- .../java/de/hysky/skyblocker/utils/Calculator.java | 27 +++++++++++----------- 4 files changed, 25 insertions(+), 29 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java index 88c54878..d1800e9b 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java @@ -1,4 +1,4 @@ -package de.hysky.skyblocker.mixin; +package de.hysky.skyblocker.mixins; import de.hysky.skyblocker.config.SkyblockerConfigManager; @@ -16,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Objects; @Mixin(AbstractSignEditScreen.class) -public abstract class SignEditScreenMixin{ +public abstract class SignEditScreenMixin { @Shadow @Final private String[] messages; @@ -32,15 +32,13 @@ public abstract class SignEditScreenMixin{ @Inject(method = "finishEditing", at = @At("HEAD")) private void skyblocker$finishEditing(CallbackInfo ci) { //if the sign is being used to enter number get number from calculator for if maths has been done - if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.enableSignCalculator && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { + if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.enableSignCalculator && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { boolean isPrice = messages[2].contains("price"); String value = SignCalculator.getNewValue(isPrice); if (value.length() >= 15) { - value = value.substring(0,15); + value = value.substring(0, 15); } messages[0] = value; } - } - } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java b/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java index f9b8b4cf..d78e2c0d 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java @@ -33,7 +33,7 @@ public class CalculatorCommand { dispatcher.register(literal(SkyblockerMod.NAMESPACE) .then(literal("calculate") .then(argument("equation", StringArgumentType.greedyString()) - .executes(context -> doCalculation(getString(context, "equation")) ) + .executes(context -> doCalculation(getString(context, "equation"))) ) ) ); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java index 7dbeabd9..82d86ba7 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java @@ -12,21 +12,19 @@ public class SignCalculator { private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); - private static final DecimalFormat FORMATTER = new DecimalFormat("#,###.##"); + private static final DecimalFormat FORMATTER = new DecimalFormat("#,###.##"); private static String lastInput; private static String input; private static Double output; - public static void renderSign(DrawContext context, String[] messages){ + public static void renderSign(DrawContext context, String[] messages) { input = messages[0]; - - //only update output if new input if (!input.equals(lastInput)) { // try { output = Calculator.calculate(input); - } catch (Exception e){ + } catch (Exception e) { output = null; } } @@ -52,11 +50,10 @@ public class SignCalculator { Text text; if (output == null) { text = Text.translatable("text.autoconfig.skyblocker.option.general.enableSignCalculator.invalidEquation").formatted(Formatting.RED); - } - else { - text = Text.literal(input +" = " + FORMATTER.format(output)).formatted(Formatting.GREEN); + } else { + text = Text.literal(input + " = " + FORMATTER.format(output)).formatted(Formatting.GREEN); } - context.drawCenteredTextWithShadow(CLIENT.textRenderer, text,context.getScaledWindowWidth() /2 , 55,0xFFFFFFFF); + context.drawCenteredTextWithShadow(CLIENT.textRenderer, text, context.getScaledWindowWidth() / 2, 55, 0xFFFFFFFF); } } diff --git a/src/main/java/de/hysky/skyblocker/utils/Calculator.java b/src/main/java/de/hysky/skyblocker/utils/Calculator.java index 19155708..bb6ed768 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Calculator.java +++ b/src/main/java/de/hysky/skyblocker/utils/Calculator.java @@ -11,11 +11,13 @@ public class Calculator { public enum TokenType { NUMBER, OPERATOR, L_PARENTHESIS, R_PARENTHESIS } + public static class Token { public TokenType type; String value; int tokenLength; } + private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+\\.?\\d*)([kmbs]?)"); private static final HashMap magnitudeValues = Util.make(new HashMap<>(), map -> { map.put("s", 64); @@ -24,15 +26,14 @@ public class Calculator { map.put("b", 1000000000); }); - private static List lex(String input) { List tokens = new ArrayList<>(); - input = input.replace(" ", "").toLowerCase().replace("x","*"); + input = input.replace(" ", "").toLowerCase().replace("x", "*"); int i = 0; while (i < input.length()) { Token token = new Token(); switch (input.charAt(i)) { - case '+','-','*','/' -> { + case '+', '-', '*', '/' -> { token.type = TokenType.OPERATOR; token.value = String.valueOf(input.charAt(i)); token.tokenLength = 1; @@ -43,8 +44,8 @@ public class Calculator { token.value = String.valueOf(input.charAt(i)); token.tokenLength = 1; //add implicit multiplication when there is a number before brackets - if (!tokens.isEmpty() ) { - TokenType lastType = tokens.get(tokens.size()-1).type; + if (!tokens.isEmpty()) { + TokenType lastType = tokens.get(tokens.size() - 1).type; if (lastType == TokenType.R_PARENTHESIS || lastType == TokenType.NUMBER) { Token mutliplyToken = new Token(); mutliplyToken.type = TokenType.OPERATOR; @@ -66,8 +67,8 @@ public class Calculator { if (!numberMatcher.find()) {//invalid value to lex throw new UnsupportedOperationException("invalid character"); } - int end = numberMatcher.end(); - token.value = input.substring(i,i + end); + int end = numberMatcher.end(); + token.value = input.substring(i, i + end); token.tokenLength = end; } } @@ -80,7 +81,8 @@ public class Calculator { } /** - * This is an implementation of the shunting yard algorithm to convert the equation to reverse polish notation + * This is an implementation of the shunting yard algorithm to convert the equation to reverse polish notation + * * @param tokens equation in infix notation order * @return equation in RPN order */ @@ -114,7 +116,7 @@ public class Calculator { case L_PARENTHESIS -> { operatorStack.push(shuntingToken); } - case R_PARENTHESIS -> { + case R_PARENTHESIS -> { while (true) { if (operatorStack.isEmpty()) { throw new UnsupportedOperationException("Unbalanced left parenthesis"); @@ -139,12 +141,13 @@ public class Calculator { return outputQueue.stream().toList(); } + private static int getPrecedence(String operator) { switch (operator) { - case "+","-" -> { + case "+", "-" -> { return 0; } - case "*","/" -> { + case "*", "/" -> { return 1; } default -> throw new UnsupportedOperationException("Invalid operator"); @@ -152,7 +155,6 @@ public class Calculator { } /** - * * @param tokens list of Tokens in reverse polish notation * @return answer to equation */ @@ -216,5 +218,4 @@ public class Calculator { public static double calculate(String equation) { return evaluate(shunt(lex(equation))); } - } -- cgit From 52054467eac250be104d53f2aa6264eced690d44 Mon Sep 17 00:00:00 2001 From: olim Date: Sun, 5 May 2024 19:28:40 +0100 Subject: add e (160) and addapt for other ui added magnitude e as valid. and added to EditBidPopup. --- .../de/hysky/skyblocker/mixins/SignEditScreenMixin.java | 2 +- .../hysky/skyblocker/skyblock/auction/EditBidPopup.java | 16 +++++++++++++--- .../skyblocker/skyblock/calculators/SignCalculator.java | 16 +++++++--------- src/main/java/de/hysky/skyblocker/utils/Calculator.java | 3 ++- 4 files changed, 23 insertions(+), 14 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java index d1800e9b..cdffc362 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java @@ -25,7 +25,7 @@ public abstract class SignEditScreenMixin { private void skyblocker$render(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { //if the sign is being used to enter number send it to the sign calculator if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.enableSignCalculator && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { - SignCalculator.renderSign(context, messages); + SignCalculator.renderCalculator(context, messages[0], context.getScaledWindowWidth() / 2, 55); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java index 9d460803..bc3d7708 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java @@ -1,5 +1,7 @@ package de.hysky.skyblocker.skyblock.auction; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.calculators.SignCalculator; import de.hysky.skyblocker.utils.render.gui.AbstractPopupScreen; import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.client.MinecraftClient; @@ -9,7 +11,6 @@ import net.minecraft.network.packet.c2s.play.UpdateSignC2SPacket; import net.minecraft.text.Style; import net.minecraft.text.Text; import org.jetbrains.annotations.NotNull; -import org.lwjgl.glfw.GLFW; public class EditBidPopup extends AbstractPopupScreen { private DirectionalLayoutWidget layout = DirectionalLayoutWidget.vertical(); @@ -55,6 +56,9 @@ public class EditBidPopup extends AbstractPopupScreen { public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { super.renderBackground(context, mouseX, mouseY, delta); drawPopupBackground(context, layout.getX(), layout.getY(), layout.getWidth(), layout.getHeight()); + if (SkyblockerConfigManager.get().general.enableSignCalculator) { + SignCalculator.renderCalculator(context, textFieldWidget.getText(), context.getScaledWindowWidth() / 2, textFieldWidget.getY() - 8); + } } private boolean isStringGood(String s) { @@ -69,8 +73,14 @@ public class EditBidPopup extends AbstractPopupScreen { } private void done(ButtonWidget widget) { - if (!isStringGood(textFieldWidget.getText().trim())) return; - sendPacket(textFieldWidget.getText().trim()); + if (SkyblockerConfigManager.get().general.enableSignCalculator) { + if (!isStringGood(SignCalculator.getNewValue(false))) return; + sendPacket(SignCalculator.getNewValue(false)); + } + else { + if (!isStringGood(textFieldWidget.getText().trim())) return; + sendPacket(textFieldWidget.getText().trim()); + } this.close(); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java index 82d86ba7..3a398c15 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java @@ -15,23 +15,21 @@ public class SignCalculator { private static final DecimalFormat FORMATTER = new DecimalFormat("#,###.##"); private static String lastInput; - private static String input; private static Double output; - public static void renderSign(DrawContext context, String[] messages) { - input = messages[0]; + public static void renderCalculator(DrawContext context, String message, int renderX, int renderY) { //only update output if new input - if (!input.equals(lastInput)) { // + if (!message.equals(lastInput)) { // try { - output = Calculator.calculate(input); + output = Calculator.calculate(message); } catch (Exception e) { output = null; } } - render(context); + render(context, message, renderX, renderY); - lastInput = input; + lastInput = message; } public static String getNewValue(Boolean isPrice) { @@ -46,7 +44,7 @@ public class SignCalculator { return Long.toString(Math.round(output)); } - private static void render(DrawContext context) { + private static void render(DrawContext context, String input, int renderX, int renderY) { Text text; if (output == null) { text = Text.translatable("text.autoconfig.skyblocker.option.general.enableSignCalculator.invalidEquation").formatted(Formatting.RED); @@ -54,6 +52,6 @@ public class SignCalculator { text = Text.literal(input + " = " + FORMATTER.format(output)).formatted(Formatting.GREEN); } - context.drawCenteredTextWithShadow(CLIENT.textRenderer, text, context.getScaledWindowWidth() / 2, 55, 0xFFFFFFFF); + context.drawCenteredTextWithShadow(CLIENT.textRenderer, text, renderX, renderY, 0xFFFFFFFF); } } diff --git a/src/main/java/de/hysky/skyblocker/utils/Calculator.java b/src/main/java/de/hysky/skyblocker/utils/Calculator.java index bb6ed768..157936b3 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Calculator.java +++ b/src/main/java/de/hysky/skyblocker/utils/Calculator.java @@ -18,9 +18,10 @@ public class Calculator { int tokenLength; } - private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+\\.?\\d*)([kmbs]?)"); + private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+\\.?\\d*)([kmbse]?)"); private static final HashMap magnitudeValues = Util.make(new HashMap<>(), map -> { map.put("s", 64); + map.put("e", 160); map.put("k", 1000); map.put("m", 1000000); map.put("b", 1000000000); -- cgit From da1baa8c0a22d4337f269e2eea9e33932c81ef70 Mon Sep 17 00:00:00 2001 From: olim Date: Sun, 5 May 2024 21:46:42 +0100 Subject: add option to need to start with ("=") also add key for magnitudes into option tooltip --- .../de/hysky/skyblocker/mixins/SignEditScreenMixin.java | 4 ++-- .../hysky/skyblocker/skyblock/auction/EditBidPopup.java | 4 ++-- .../skyblock/calculators/CalculatorCommand.java | 2 +- .../skyblocker/skyblock/calculators/SignCalculator.java | 17 +++++++++++++++-- 4 files changed, 20 insertions(+), 7 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java index cdffc362..c7053a39 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java @@ -24,7 +24,7 @@ public abstract class SignEditScreenMixin { @Inject(method = "render", at = @At("HEAD")) private void skyblocker$render(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { //if the sign is being used to enter number send it to the sign calculator - if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.enableSignCalculator && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { + if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.inputCalculator.enabled && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { SignCalculator.renderCalculator(context, messages[0], context.getScaledWindowWidth() / 2, 55); } } @@ -32,7 +32,7 @@ public abstract class SignEditScreenMixin { @Inject(method = "finishEditing", at = @At("HEAD")) private void skyblocker$finishEditing(CallbackInfo ci) { //if the sign is being used to enter number get number from calculator for if maths has been done - if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.enableSignCalculator && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { + if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.inputCalculator.enabled && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { boolean isPrice = messages[2].contains("price"); String value = SignCalculator.getNewValue(isPrice); if (value.length() >= 15) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java index bc3d7708..def718dd 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java @@ -56,7 +56,7 @@ public class EditBidPopup extends AbstractPopupScreen { public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { super.renderBackground(context, mouseX, mouseY, delta); drawPopupBackground(context, layout.getX(), layout.getY(), layout.getWidth(), layout.getHeight()); - if (SkyblockerConfigManager.get().general.enableSignCalculator) { + if (SkyblockerConfigManager.get().general.inputCalculator.enabled) { SignCalculator.renderCalculator(context, textFieldWidget.getText(), context.getScaledWindowWidth() / 2, textFieldWidget.getY() - 8); } } @@ -73,7 +73,7 @@ public class EditBidPopup extends AbstractPopupScreen { } private void done(ButtonWidget widget) { - if (SkyblockerConfigManager.get().general.enableSignCalculator) { + if (SkyblockerConfigManager.get().general.inputCalculator.enabled) { if (!isStringGood(SignCalculator.getNewValue(false))) return; sendPacket(SignCalculator.getNewValue(false)); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java b/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java index d78e2c0d..bc44c249 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java @@ -44,7 +44,7 @@ public class CalculatorCommand { try { text.append(Text.literal(FORMATTER.format(Calculator.calculate(calculation))).formatted(Formatting.GREEN)); } catch (UnsupportedOperationException e) { - text.append(Text.literal("text.autoconfig.skyblocker.option.general.enableSignCalculator.invalidEquation").formatted(Formatting.RED)); + text.append(Text.literal("text.autoconfig.skyblocker.option.general.inputCalculator.invalidEquation").formatted(Formatting.RED)); } if (CLIENT == null || CLIENT.player == null) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java index 3a398c15..ccdc67f6 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java @@ -1,5 +1,6 @@ package de.hysky.skyblocker.skyblock.calculators; +import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.Calculator; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; @@ -18,6 +19,16 @@ public class SignCalculator { private static Double output; public static void renderCalculator(DrawContext context, String message, int renderX, int renderY) { + if (SkyblockerConfigManager.get().general.inputCalculator.requiresEquals) { + if (message.startsWith("=")) { + message = message.substring(1); + } + else { + output = null; + lastInput = message; + return; + } + } //only update output if new input if (!message.equals(lastInput)) { // try { @@ -34,8 +45,10 @@ public class SignCalculator { public static String getNewValue(Boolean isPrice) { if (output == null) { - return ""; + //if mode is not activated or just invalid equation return what the user typed in + return lastInput; } + //price can except decimals and exponents if (isPrice) { return output.toString(); @@ -47,7 +60,7 @@ public class SignCalculator { private static void render(DrawContext context, String input, int renderX, int renderY) { Text text; if (output == null) { - text = Text.translatable("text.autoconfig.skyblocker.option.general.enableSignCalculator.invalidEquation").formatted(Formatting.RED); + text = Text.translatable("text.autoconfig.skyblocker.option.general.inputCalculator.invalidEquation").formatted(Formatting.RED); } else { text = Text.literal(input + " = " + FORMATTER.format(output)).formatted(Formatting.GREEN); } -- cgit From b96d59980e703c8238c2c3d066c8bedf87ffdf85 Mon Sep 17 00:00:00 2001 From: olim Date: Mon, 6 May 2024 18:28:07 +0100 Subject: add ability to use purse value --- src/main/java/de/hysky/skyblocker/utils/Calculator.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/utils/Calculator.java b/src/main/java/de/hysky/skyblocker/utils/Calculator.java index 157936b3..562c66bc 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Calculator.java +++ b/src/main/java/de/hysky/skyblocker/utils/Calculator.java @@ -1,5 +1,6 @@ package de.hysky.skyblocker.utils; +import de.hysky.skyblocker.config.SkyblockerConfigManager; import net.minecraft.util.Util; import java.util.*; @@ -217,6 +218,8 @@ public class Calculator { } public static double calculate(String equation) { + //custom bit for replacing purse with its value + equation = equation.replace("purse",String.valueOf((int)Utils.getPurse())); return evaluate(shunt(lex(equation))); } } -- cgit From 857a38181dc8513242624d260610dba8b7a4e97c Mon Sep 17 00:00:00 2001 From: olim Date: Thu, 9 May 2024 17:11:40 +0100 Subject: add (p) for purse also fix code a tad --- .../de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java | 2 +- src/main/java/de/hysky/skyblocker/utils/Calculator.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java b/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java index bc44c249..9c0d83e0 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java @@ -44,7 +44,7 @@ public class CalculatorCommand { try { text.append(Text.literal(FORMATTER.format(Calculator.calculate(calculation))).formatted(Formatting.GREEN)); } catch (UnsupportedOperationException e) { - text.append(Text.literal("text.autoconfig.skyblocker.option.general.inputCalculator.invalidEquation").formatted(Formatting.RED)); + text.append(Text.translatable("text.autoconfig.skyblocker.option.general.inputCalculator.invalidEquation").formatted(Formatting.RED)); } if (CLIENT == null || CLIENT.player == null) { diff --git a/src/main/java/de/hysky/skyblocker/utils/Calculator.java b/src/main/java/de/hysky/skyblocker/utils/Calculator.java index 562c66bc..9991c697 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Calculator.java +++ b/src/main/java/de/hysky/skyblocker/utils/Calculator.java @@ -47,7 +47,7 @@ public class Calculator { token.tokenLength = 1; //add implicit multiplication when there is a number before brackets if (!tokens.isEmpty()) { - TokenType lastType = tokens.get(tokens.size() - 1).type; + TokenType lastType = tokens.getLast().type; if (lastType == TokenType.R_PARENTHESIS || lastType == TokenType.NUMBER) { Token mutliplyToken = new Token(); mutliplyToken.type = TokenType.OPERATOR; @@ -219,7 +219,7 @@ public class Calculator { public static double calculate(String equation) { //custom bit for replacing purse with its value - equation = equation.replace("purse",String.valueOf((int)Utils.getPurse())); + equation = equation.toLowerCase().replaceAll("p(urse)?",String.valueOf((int)Utils.getPurse())); return evaluate(shunt(lex(equation))); } } -- cgit From 62f0a4f39e410928d3aeaea847922f44335faeef Mon Sep 17 00:00:00 2001 From: olim Date: Thu, 9 May 2024 22:07:05 +0100 Subject: fix conflicts with new config --- .../config/categories/UIAndVisualsCategory.java | 22 ++++++++++++++++++++++ .../config/configs/UIAndVisualsConfig.java | 11 +++++++++++ .../skyblocker/mixins/SignEditScreenMixin.java | 4 ++-- .../skyblocker/skyblock/auction/EditBidPopup.java | 4 ++-- .../skyblock/calculators/SignCalculator.java | 2 +- .../resources/assets/skyblocker/lang/en_us.json | 7 +++++++ 6 files changed, 45 insertions(+), 5 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java index c6936335..a613ebf1 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java @@ -333,6 +333,28 @@ public class UIAndVisualsCategory { .build()) .build()) + //Input Calculator + .group(OptionGroup.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator")) + .collapsed(true) + .option(Option.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.enabled")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.enabled.@Tooltip"))) + .binding(defaults.uiAndVisuals.inputCalculator.enabled, + () -> config.uiAndVisuals.inputCalculator.enabled, + newValue -> config.uiAndVisuals.inputCalculator.enabled = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.requiresEquals")) + .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.requiresEquals.@Tooltip"))) + .binding(defaults.uiAndVisuals.inputCalculator.requiresEquals, + () -> config.uiAndVisuals.inputCalculator.requiresEquals, + newValue -> config.uiAndVisuals.inputCalculator.requiresEquals = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .build()) + //Flame Overlay .group(OptionGroup.createBuilder() .name(Text.translatable("skyblocker.config.uiAndVisuals.flameOverlay")) diff --git a/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java index 267dde14..99c6381f 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java @@ -53,6 +53,9 @@ public class UIAndVisualsConfig { @SerialEntry public SearchOverlay searchOverlay = new SearchOverlay(); + @SerialEntry + public InputCalculator inputCalculator = new InputCalculator(); + @SerialEntry public FlameOverlay flameOverlay = new FlameOverlay(); @@ -239,6 +242,14 @@ public class UIAndVisualsConfig { public List auctionHistory = new ArrayList<>(); } + public static class InputCalculator { + @SerialEntry + public boolean enabled = true; + + @SerialEntry + public boolean requiresEquals = true; + } + public static class FlameOverlay { @SerialEntry public int flameHeight = 100; diff --git a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java index c7053a39..6706db58 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java @@ -24,7 +24,7 @@ public abstract class SignEditScreenMixin { @Inject(method = "render", at = @At("HEAD")) private void skyblocker$render(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { //if the sign is being used to enter number send it to the sign calculator - if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.inputCalculator.enabled && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { + if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().uiAndVisuals.inputCalculator.enabled && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { SignCalculator.renderCalculator(context, messages[0], context.getScaledWindowWidth() / 2, 55); } } @@ -32,7 +32,7 @@ public abstract class SignEditScreenMixin { @Inject(method = "finishEditing", at = @At("HEAD")) private void skyblocker$finishEditing(CallbackInfo ci) { //if the sign is being used to enter number get number from calculator for if maths has been done - if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.inputCalculator.enabled && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { + if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().uiAndVisuals.inputCalculator.enabled && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { boolean isPrice = messages[2].contains("price"); String value = SignCalculator.getNewValue(isPrice); if (value.length() >= 15) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java index def718dd..9114fc52 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java @@ -56,7 +56,7 @@ public class EditBidPopup extends AbstractPopupScreen { public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { super.renderBackground(context, mouseX, mouseY, delta); drawPopupBackground(context, layout.getX(), layout.getY(), layout.getWidth(), layout.getHeight()); - if (SkyblockerConfigManager.get().general.inputCalculator.enabled) { + if (SkyblockerConfigManager.get().uiAndVisuals.inputCalculator.enabled) { SignCalculator.renderCalculator(context, textFieldWidget.getText(), context.getScaledWindowWidth() / 2, textFieldWidget.getY() - 8); } } @@ -73,7 +73,7 @@ public class EditBidPopup extends AbstractPopupScreen { } private void done(ButtonWidget widget) { - if (SkyblockerConfigManager.get().general.inputCalculator.enabled) { + if (SkyblockerConfigManager.get().uiAndVisuals.inputCalculator.enabled) { if (!isStringGood(SignCalculator.getNewValue(false))) return; sendPacket(SignCalculator.getNewValue(false)); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java index ccdc67f6..02701c16 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java @@ -19,7 +19,7 @@ public class SignCalculator { private static Double output; public static void renderCalculator(DrawContext context, String message, int renderX, int renderY) { - if (SkyblockerConfigManager.get().general.inputCalculator.requiresEquals) { + if (SkyblockerConfigManager.get().uiAndVisuals.inputCalculator.requiresEquals) { if (message.startsWith("=")) { message = message.substring(1); } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 283175d0..493f14ec 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -537,6 +537,13 @@ "skyblocker.config.uiAndVisuals.searchOverlay.maxSuggestions": "Maximum Suggestions", "skyblocker.config.uiAndVisuals.searchOverlay.maxSuggestions.@Tooltip": "The maximum number of suggested items to show.", + "text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator": "Input Calculator", + "text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.enabled": "Enable Sign Calculator", + "text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.enabled.@Tooltip": "Enables the ability for you to do calculations when inputting values such as price for the ah.\n Key:\n S = 64\n E = 160\n K = 1,000\n M = 1,000,000\n B = 1,000,000,000\n\n purse/P = current purse value", + "text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.requiresEquals": "Only show with \"=\".", + "text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.requiresEquals.@Tooltip": "Only show the calculator when the message start with \"=\".", + "text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.invalidEquation": "Invalid Equation", + "skyblocker.config.uiAndVisuals.tabHud": "Fancy tab HUD (Temporarily disabled outside dungeons)", "skyblocker.config.uiAndVisuals.tabHud.enableHudBackground": "Enable HUD Background", "skyblocker.config.uiAndVisuals.tabHud.enableHudBackground.@Tooltip": "Enables the background of the non-tab HUD.", -- cgit From 0c0b11c80ca38b4631a0828358667bd64f05abdf Mon Sep 17 00:00:00 2001 From: olim Date: Thu, 9 May 2024 23:14:23 +0100 Subject: fix text name --- .../skyblocker/config/categories/UIAndVisualsCategory.java | 10 +++++----- src/main/resources/assets/skyblocker/lang/en_us.json | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java index a613ebf1..e6cd3c54 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/UIAndVisualsCategory.java @@ -335,19 +335,19 @@ public class UIAndVisualsCategory { //Input Calculator .group(OptionGroup.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator")) + .name(Text.translatable("skyblocker.config.uiAndVisuals.inputCalculator")) .collapsed(true) .option(Option.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.enabled")) - .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.enabled.@Tooltip"))) + .name(Text.translatable("skyblocker.config.uiAndVisuals.inputCalculator.enabled")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.uiAndVisuals.inputCalculator.enabled.@Tooltip"))) .binding(defaults.uiAndVisuals.inputCalculator.enabled, () -> config.uiAndVisuals.inputCalculator.enabled, newValue -> config.uiAndVisuals.inputCalculator.enabled = newValue) .controller(ConfigUtils::createBooleanController) .build()) .option(Option.createBuilder() - .name(Text.translatable("text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.requiresEquals")) - .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.requiresEquals.@Tooltip"))) + .name(Text.translatable("skyblocker.config.uiAndVisuals.inputCalculator.requiresEquals")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.uiAndVisuals.inputCalculator.requiresEquals.@Tooltip"))) .binding(defaults.uiAndVisuals.inputCalculator.requiresEquals, () -> config.uiAndVisuals.inputCalculator.requiresEquals, newValue -> config.uiAndVisuals.inputCalculator.requiresEquals = newValue) diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 493f14ec..49ba3653 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -537,12 +537,12 @@ "skyblocker.config.uiAndVisuals.searchOverlay.maxSuggestions": "Maximum Suggestions", "skyblocker.config.uiAndVisuals.searchOverlay.maxSuggestions.@Tooltip": "The maximum number of suggested items to show.", - "text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator": "Input Calculator", - "text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.enabled": "Enable Sign Calculator", - "text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.enabled.@Tooltip": "Enables the ability for you to do calculations when inputting values such as price for the ah.\n Key:\n S = 64\n E = 160\n K = 1,000\n M = 1,000,000\n B = 1,000,000,000\n\n purse/P = current purse value", - "text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.requiresEquals": "Only show with \"=\".", - "text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.requiresEquals.@Tooltip": "Only show the calculator when the message start with \"=\".", - "text.autoconfig.skyblocker.option.uiAndVisuals.inputCalculator.invalidEquation": "Invalid Equation", + "skyblocker.config.uiAndVisuals.inputCalculator": "Input Calculator", + "skyblocker.config.uiAndVisuals.inputCalculator.enabled": "Enable Sign Calculator", + "skyblocker.config.uiAndVisuals.inputCalculator.enabled.@Tooltip": "Enables the ability for you to do calculations when inputting values such as price for the ah.\n Key:\n S = 64\n E = 160\n K = 1,000\n M = 1,000,000\n B = 1,000,000,000\n\n purse/P = current purse value", + "skyblocker.config.uiAndVisuals.inputCalculator.requiresEquals": "Only show with \"=\".", + "skyblocker.config.uiAndVisuals.inputCalculator.requiresEquals.@Tooltip": "Only show the calculator when the message start with \"=\".", + "skyblocker.config.uiAndVisuals.inputCalculator.invalidEquation": "Invalid Equation", "skyblocker.config.uiAndVisuals.tabHud": "Fancy tab HUD (Temporarily disabled outside dungeons)", "skyblocker.config.uiAndVisuals.tabHud.enableHudBackground": "Enable HUD Background", -- cgit From 34a804caaebf08c448ac3ced76d265b9a8ba9457 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Sat, 11 May 2024 21:29:26 -0400 Subject: Fix invalid equation text and refactor --- .../config/configs/UIAndVisualsConfig.java | 2 +- .../skyblocker/skyblock/auction/EditBidPopup.java | 3 +- .../skyblock/calculators/CalculatorCommand.java | 7 ++-- .../skyblock/calculators/SignCalculator.java | 20 +++++---- .../java/de/hysky/skyblocker/utils/Calculator.java | 47 +++++++--------------- .../de/hysky/skyblocker/utils/CalculatorTest.java | 15 ++++--- 6 files changed, 38 insertions(+), 56 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java index 99c6381f..03d300f4 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/UIAndVisualsConfig.java @@ -247,7 +247,7 @@ public class UIAndVisualsConfig { public boolean enabled = true; @SerialEntry - public boolean requiresEquals = true; + public boolean requiresEquals = false; } public static class FlameOverlay { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java b/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java index 9114fc52..f96e3231 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/auction/EditBidPopup.java @@ -76,8 +76,7 @@ public class EditBidPopup extends AbstractPopupScreen { if (SkyblockerConfigManager.get().uiAndVisuals.inputCalculator.enabled) { if (!isStringGood(SignCalculator.getNewValue(false))) return; sendPacket(SignCalculator.getNewValue(false)); - } - else { + } else { if (!isStringGood(textFieldWidget.getText().trim())) return; sendPacket(textFieldWidget.getText().trim()); } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java b/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java index 9c0d83e0..d103bcdd 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/calculators/CalculatorCommand.java @@ -14,7 +14,7 @@ import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; -import java.text.DecimalFormat; +import java.text.NumberFormat; import static com.mojang.brigadier.arguments.StringArgumentType.getString; import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; @@ -22,8 +22,7 @@ import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.lit public class CalculatorCommand { private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); - - private static final DecimalFormat FORMATTER = new DecimalFormat("#,###.##"); + private static final NumberFormat FORMATTER = NumberFormat.getInstance(); public static void init() { ClientCommandRegistrationCallback.EVENT.register(CalculatorCommand::calculate); @@ -44,7 +43,7 @@ public class CalculatorCommand { try { text.append(Text.literal(FORMATTER.format(Calculator.calculate(calculation))).formatted(Formatting.GREEN)); } catch (UnsupportedOperationException e) { - text.append(Text.translatable("text.autoconfig.skyblocker.option.general.inputCalculator.invalidEquation").formatted(Formatting.RED)); + text.append(Text.translatable("skyblocker.config.uiAndVisuals.inputCalculator.invalidEquation").formatted(Formatting.RED)); } if (CLIENT == null || CLIENT.player == null) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java index 02701c16..f9bb1e9f 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java @@ -7,16 +7,14 @@ import net.minecraft.client.gui.DrawContext; import net.minecraft.text.Text; import net.minecraft.util.Formatting; -import java.text.DecimalFormat; +import java.text.NumberFormat; public class SignCalculator { - private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); - - private static final DecimalFormat FORMATTER = new DecimalFormat("#,###.##"); + private static final NumberFormat FORMATTER = NumberFormat.getInstance(); private static String lastInput; - private static Double output; + private static double output; public static void renderCalculator(DrawContext context, String message, int renderX, int renderY) { if (SkyblockerConfigManager.get().uiAndVisuals.inputCalculator.requiresEquals) { @@ -24,7 +22,7 @@ public class SignCalculator { message = message.substring(1); } else { - output = null; + output = -1; lastInput = message; return; } @@ -34,7 +32,7 @@ public class SignCalculator { try { output = Calculator.calculate(message); } catch (Exception e) { - output = null; + output = -1; } } @@ -44,14 +42,14 @@ public class SignCalculator { } public static String getNewValue(Boolean isPrice) { - if (output == null) { + if (output == -1) { //if mode is not activated or just invalid equation return what the user typed in return lastInput; } //price can except decimals and exponents if (isPrice) { - return output.toString(); + return FORMATTER.format(output); } //amounts want an integer number so round return Long.toString(Math.round(output)); @@ -59,8 +57,8 @@ public class SignCalculator { private static void render(DrawContext context, String input, int renderX, int renderY) { Text text; - if (output == null) { - text = Text.translatable("text.autoconfig.skyblocker.option.general.inputCalculator.invalidEquation").formatted(Formatting.RED); + if (output == -1) { + text = Text.translatable("skyblocker.config.uiAndVisuals.inputCalculator.invalidEquation").formatted(Formatting.RED); } else { text = Text.literal(input + " = " + FORMATTER.format(output)).formatted(Formatting.GREEN); } diff --git a/src/main/java/de/hysky/skyblocker/utils/Calculator.java b/src/main/java/de/hysky/skyblocker/utils/Calculator.java index 9991c697..30c1ee64 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Calculator.java +++ b/src/main/java/de/hysky/skyblocker/utils/Calculator.java @@ -1,14 +1,10 @@ package de.hysky.skyblocker.utils; -import de.hysky.skyblocker.config.SkyblockerConfigManager; -import net.minecraft.util.Util; - import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Calculator { - public enum TokenType { NUMBER, OPERATOR, L_PARENTHESIS, R_PARENTHESIS } @@ -20,13 +16,13 @@ public class Calculator { } private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+\\.?\\d*)([kmbse]?)"); - private static final HashMap magnitudeValues = Util.make(new HashMap<>(), map -> { - map.put("s", 64); - map.put("e", 160); - map.put("k", 1000); - map.put("m", 1000000); - map.put("b", 1000000000); - }); + private static final Map magnitudeValues = Map.of( + "s", 64, + "e", 160, + "k", 1000, + "m", 1000000, + "b", 1000000000 + ); private static List lex(String input) { List tokens = new ArrayList<>(); @@ -88,16 +84,13 @@ public class Calculator { * @param tokens equation in infix notation order * @return equation in RPN order */ - private static List shunt(List tokens) { Deque operatorStack = new ArrayDeque<>(); List outputQueue = new ArrayList<>(); for (Token shuntingToken : tokens) switch (shuntingToken.type) { - case NUMBER -> { - outputQueue.add(shuntingToken); - } + case NUMBER -> outputQueue.add(shuntingToken); case OPERATOR -> { int precedence = getPrecedence(shuntingToken.value); while (!operatorStack.isEmpty()) { @@ -115,9 +108,7 @@ public class Calculator { } operatorStack.push(shuntingToken); } - case L_PARENTHESIS -> { - operatorStack.push(shuntingToken); - } + case L_PARENTHESIS -> operatorStack.push(shuntingToken); case R_PARENTHESIS -> { while (true) { if (operatorStack.isEmpty()) { @@ -164,33 +155,23 @@ public class Calculator { Deque values = new ArrayDeque<>(); for (Token token : tokens) { switch (token.type) { - case NUMBER -> { - values.push(calculateValue(token.value)); - } + case NUMBER -> values.push(calculateValue(token.value)); case OPERATOR -> { double right = values.pop(); double left = values.pop(); switch (token.value) { - case "+" -> { - values.push(left + right); - } - case "-" -> { - values.push(left - right); - } + case "+" -> values.push(left + right); + case "-" -> values.push(left - right); case "/" -> { if (right == 0) { throw new UnsupportedOperationException("Can not divide by 0"); } values.push(left / right); } - case "*" -> { - values.push(left * right); - } + case "*" -> values.push(left * right); } } - case L_PARENTHESIS, R_PARENTHESIS -> { - throw new UnsupportedOperationException("Equation is not in RPN"); - } + case L_PARENTHESIS, R_PARENTHESIS -> throw new UnsupportedOperationException("Equation is not in RPN"); } } if (values.isEmpty()) { diff --git a/src/test/java/de/hysky/skyblocker/utils/CalculatorTest.java b/src/test/java/de/hysky/skyblocker/utils/CalculatorTest.java index 84834c57..c29efdf2 100644 --- a/src/test/java/de/hysky/skyblocker/utils/CalculatorTest.java +++ b/src/test/java/de/hysky/skyblocker/utils/CalculatorTest.java @@ -5,22 +5,27 @@ import org.junit.jupiter.api.Test; public class CalculatorTest { @Test - void testCalculator() { - //check the magnitudes are working + void testShorthands() { Assertions.assertEquals(Calculator.calculate("1k"), 1000); Assertions.assertEquals(Calculator.calculate("0.12k"), 120); Assertions.assertEquals(Calculator.calculate("1k + 0.12k"), 1120); Assertions.assertEquals(Calculator.calculate("1 + 1s + 1k + 1m + 1b"), 1001001065); + } - //check precedence works + @Test + void testPrecedence() { Assertions.assertEquals(Calculator.calculate("5 + 2 * 2"), 9); Assertions.assertEquals(Calculator.calculate("5 - 2 / 2"), 4); Assertions.assertEquals(Calculator.calculate("5 * (1 + 2)"), 15); + } - //check implicit multiplication + @Test + void testImplicitMultiplication() { Assertions.assertEquals(Calculator.calculate("5(2 + 2)"), 20); + } - //check unclosed parenthesis work + @Test + void testImplicitClosingParenthesis() { Assertions.assertEquals(Calculator.calculate("5(2 + 2"), 20); } } -- cgit From 7edaa418067580434ef189a361a6802faabb3b1e Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Sat, 11 May 2024 22:10:03 -0400 Subject: Allow equals sign --- .../skyblock/calculators/SignCalculator.java | 16 +++++++-------- .../java/de/hysky/skyblocker/utils/Calculator.java | 24 ++++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java b/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java index f9bb1e9f..dc51e48c 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/calculators/SignCalculator.java @@ -17,15 +17,13 @@ public class SignCalculator { private static double output; public static void renderCalculator(DrawContext context, String message, int renderX, int renderY) { - if (SkyblockerConfigManager.get().uiAndVisuals.inputCalculator.requiresEquals) { - if (message.startsWith("=")) { - message = message.substring(1); - } - else { - output = -1; - lastInput = message; - return; - } + if (SkyblockerConfigManager.get().uiAndVisuals.inputCalculator.requiresEquals && !message.startsWith("=")) { + output = -1; + lastInput = message; + return; + } + if (message.startsWith("=")) { + message = message.substring(1); } //only update output if new input if (!message.equals(lastInput)) { // diff --git a/src/main/java/de/hysky/skyblocker/utils/Calculator.java b/src/main/java/de/hysky/skyblocker/utils/Calculator.java index 30c1ee64..7b0baaf6 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Calculator.java +++ b/src/main/java/de/hysky/skyblocker/utils/Calculator.java @@ -15,13 +15,14 @@ public class Calculator { int tokenLength; } - private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+\\.?\\d*)([kmbse]?)"); - private static final Map magnitudeValues = Map.of( - "s", 64, - "e", 160, - "k", 1000, - "m", 1000000, - "b", 1000000000 + private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+\\.?\\d*)([sekmbt]?)"); + private static final Map MAGNITUDE_VALUES = Map.of( + "s", 64L, + "e", 160L, + "k", 1_000L, + "m", 1_000_000L, + "b", 1_000_000_000L, + "t", 1_000_000_000_000L ); private static List lex(String input) { @@ -88,7 +89,7 @@ public class Calculator { Deque operatorStack = new ArrayDeque<>(); List outputQueue = new ArrayList<>(); - for (Token shuntingToken : tokens) + for (Token shuntingToken : tokens) { switch (shuntingToken.type) { case NUMBER -> outputQueue.add(shuntingToken); case OPERATOR -> { @@ -122,6 +123,7 @@ public class Calculator { } } } + } //empty the operator stack while (!operatorStack.isEmpty()) { Token leftToken = operatorStack.pop(); @@ -189,10 +191,10 @@ public class Calculator { String magnitude = numberMatcher.group(2); if (!magnitude.isEmpty()) { - if (!magnitudeValues.containsKey(magnitude)) {//its invalid if its another letter + if (!MAGNITUDE_VALUES.containsKey(magnitude)) {//its invalid if its another letter throw new UnsupportedOperationException("Invalid magnitude"); } - number *= magnitudeValues.get(magnitude); + number *= MAGNITUDE_VALUES.get(magnitude); } return number; @@ -200,7 +202,7 @@ public class Calculator { public static double calculate(String equation) { //custom bit for replacing purse with its value - equation = equation.toLowerCase().replaceAll("p(urse)?",String.valueOf((int)Utils.getPurse())); + equation = equation.toLowerCase().replaceAll("p(urse)?", String.valueOf(Utils.getPurse())); return evaluate(shunt(lex(equation))); } } -- cgit