Skip to content

Commit

Permalink
Fix the powder widget to also display the diff (SkyblockerMod#1103)
Browse files Browse the repository at this point in the history
  • Loading branch information
Emirlol authored Dec 24, 2024
1 parent 2335b31 commit 4fd198f
Showing 1 changed file with 89 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,39 +1,119 @@
package de.hysky.skyblocker.skyblock.tabhud.widget;


import de.hysky.skyblocker.annotations.RegisterWidget;
import de.hysky.skyblocker.skyblock.tabhud.util.Ico;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.IcoTextComponent;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.PlainTextComponent;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Util;
import org.apache.commons.lang3.math.NumberUtils;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

// this widget shows how much mithril and gemstone powder you have
// (dwarven mines and crystal hollows)
@RegisterWidget
public class PowderWidget extends TabHudWidget {
private static final MutableText TITLE = Text.literal("Powders").formatted(Formatting.DARK_AQUA, Formatting.BOLD);
private static final DecimalFormat DECIMAL_FORMAT = (DecimalFormat) NumberFormat.getInstance(Locale.ENGLISH);
private static final short UPDATE_INTERVAL = 2000;

static {
DECIMAL_FORMAT.setPositivePrefix("+"); // Causes the positive sign to be displayed for positive numbers, while the negative sign is always displayed for negative numbers. This removes the need to prepend a + if positive.
}

private static final MutableText TITLE = Text.literal("Powders").formatted(Formatting.DARK_AQUA,
Formatting.BOLD);
// Patterns to match the playerlist lines against
private static final Pattern MITHRIL_PATTERN = Pattern.compile("Mithril: ([\\d,]+)");
private static final Pattern GEMSTONE_PATTERN = Pattern.compile("Gemstone: ([\\d,]+)");
private static final Pattern GLACITE_PATTERN = Pattern.compile("Glacite: ([\\d,]+)");
// Amounts from last update
private int lastMithril = 0;
private int lastGemstone = 0;
private int lastGlacite = 0;
// The amount difference between the 2nd last and last update
private int lastMithrilDiff = 0;
private int lastGemstoneDiff = 0;
private int lastGlaciteDiff = 0;
// A bitfield to keep track of which powders have been updated.
// First 3 bits represent mithril, gemstone and glacite respectively, with 1 being found and 0 being not found.
// The 4th bit is for whether the current tick caused an update, which will change the value of lastUpdate when 1.
private byte updated = 0b0000;
private long lastUpdate = 0;

public PowderWidget() {
super("Powders", TITLE, Formatting.DARK_AQUA.getColorValue());
}

@Override
public void updateContent(List<Text> lines) {
Matcher matcher = Pattern.compile("").matcher(""); // Placeholder pattern and input to construct a matcher that can be reused
long msAfterLastUpdate = Util.getMeasuringTimeMs() - lastUpdate;

for (Text line : lines) {
switch (line.getString().toLowerCase()) {
case String s when s.contains("mithril") -> this.addComponent(new IcoTextComponent(Ico.MITHRIL, line));
case String s when s.contains("gemstone") -> this.addComponent(new IcoTextComponent(Ico.AMETHYST_SHARD, line));
case String s when s.contains("glacite") -> this.addComponent(new IcoTextComponent(Ico.BLUE_ICE, line));
default -> this.addComponent(new PlainTextComponent(line));
switch (matcher.reset(line.getString())) {
case Matcher m when m.usePattern(MITHRIL_PATTERN).matches() -> {
int mithril = parseAmount(m);
// Generally this will only work if the update interval has passed, but we also don't want to stall the update if the amount has changed
if (mithril != lastMithril || msAfterLastUpdate > UPDATE_INTERVAL) {
lastMithrilDiff = mithril - lastMithril;
updated |= 0b1000;
addComponent(new IcoTextComponent(Ico.MITHRIL, getTextToDisplay(lastMithrilDiff, line, Formatting.DARK_GREEN)));
lastMithril = mithril;
} else {
addComponent(new IcoTextComponent(Ico.MITHRIL, getTextToDisplay(lastMithrilDiff, line, Formatting.DARK_GREEN)));
}
updated |= 0b001;
}
case Matcher m when m.usePattern(GEMSTONE_PATTERN).matches() -> {
int gemstone = parseAmount(m);
// Generally this will only work if the update interval has passed, but we also don't want to stall the update if the amount has changed
if (gemstone != lastGemstone || msAfterLastUpdate > UPDATE_INTERVAL) {
lastGemstoneDiff = gemstone - lastGemstone;
updated |= 0b1000;
addComponent(new IcoTextComponent(Ico.AMETHYST_SHARD, getTextToDisplay(lastGemstoneDiff, line, Formatting.LIGHT_PURPLE)));
lastGemstone = gemstone;
} else {
addComponent(new IcoTextComponent(Ico.AMETHYST_SHARD, getTextToDisplay(lastGemstoneDiff, line, Formatting.LIGHT_PURPLE)));
}
updated |= 0b010;
}
case Matcher m when m.usePattern(GLACITE_PATTERN).matches() -> {
int glacite = parseAmount(m);
// Generally this will only work if the update interval has passed, but we also don't want to stall the update if the amount has changed
if (glacite != lastGlacite || msAfterLastUpdate > UPDATE_INTERVAL) {
lastGlaciteDiff = glacite - lastGlacite;
updated |= 0b1000;
addComponent(new IcoTextComponent(Ico.BLUE_ICE, getTextToDisplay(lastGlaciteDiff, line, Formatting.AQUA)));
lastGlacite = glacite;
} else {
addComponent(new IcoTextComponent(Ico.BLUE_ICE, getTextToDisplay(lastGlaciteDiff, line, Formatting.AQUA)));
}
updated |= 0b100;
}
default -> {}
}
if ((updated & 0b111) == 0b111) break; // All powder counts have been updated, no need to continue
}
if ((updated & 0b1000) == 0b1000) lastUpdate = Util.getMeasuringTimeMs();
updated = 0b0000; // Reset the bitfield for the next tick
}

private int parseAmount(Matcher matcher) {
return NumberUtils.toInt(matcher.group(1).replace(",", ""));
}

private MutableText getAppendix(int diff, Formatting formatting) {
return Text.literal(" (" + DECIMAL_FORMAT.format(diff) + ")").formatted(formatting);
}

// Decides whether the appendix should be appended to the line
private Text getTextToDisplay(int diff, Text line, Formatting formatting) {
return diff != 0 ? line.copy().append(getAppendix(diff, formatting)) : line;
}
}

0 comments on commit 4fd198f

Please sign in to comment.