forked from SkyblockerMod/Skyblocker
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix the powder widget to also display the diff (SkyblockerMod#1103)
- Loading branch information
Showing
1 changed file
with
89 additions
and
9 deletions.
There are no files selected for viewing
98 changes: 89 additions & 9 deletions
98
src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/PowderWidget.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |