Skip to content

Commit 5ab05af

Browse files
committed
Auto-detect McGrubber stacks
1 parent f2597a9 commit 5ab05af

4 files changed

Lines changed: 143 additions & 0 deletions

File tree

src/main/java/de/hysky/skyblocker/config/categories/OtherLocationsCategory.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,14 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig
9999
newValue -> config.otherLocations.rift.highlightFoundEnigmaSouls = newValue)
100100
.controller(ConfigUtils.createBooleanController())
101101
.build())
102+
.option(Option.<Boolean>createBuilder()
103+
.name(Component.translatable("skyblocker.config.otherLocations.rift.autoDetectMcGrubber"))
104+
.description(Component.translatable("skyblocker.config.otherLocations.rift.autoDetectMcGrubber.@Tooltip"))
105+
.binding(defaults.otherLocations.rift.autoDetectMcGrubber,
106+
() -> config.otherLocations.rift.autoDetectMcGrubber,
107+
newValue -> config.otherLocations.rift.autoDetectMcGrubber = newValue)
108+
.controller(ConfigUtils.createBooleanController())
109+
.build())
102110
.option(Option.<Integer>createBuilder()
103111
.name(Component.translatable("skyblocker.config.otherLocations.rift.mcGrubberStacks"))
104112
.description(Component.translatable("skyblocker.config.otherLocations.rift.mcGrubberStacks.@Tooltip"))

src/main/java/de/hysky/skyblocker/config/configs/OtherLocationsConfig.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public static class Rift {
3232

3333
public boolean highlightFoundEnigmaSouls = true;
3434

35+
public boolean autoDetectMcGrubber = true;
36+
3537
public int mcGrubberStacks = 0;
3638
}
3739

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package de.hysky.skyblocker.skyblock.rift;
2+
3+
import de.hysky.skyblocker.annotations.Init;
4+
import de.hysky.skyblocker.config.SkyblockerConfigManager;
5+
import de.hysky.skyblocker.skyblock.item.tooltip.info.TooltipInfoType;
6+
import de.hysky.skyblocker.utils.ItemUtils;
7+
import de.hysky.skyblocker.utils.RegexUtils;
8+
import de.hysky.skyblocker.utils.Utils;
9+
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
10+
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
11+
import net.minecraft.client.Minecraft;
12+
import net.minecraft.client.gui.screens.inventory.ContainerScreen;
13+
import net.minecraft.network.chat.Component;
14+
import net.minecraft.world.inventory.Slot;
15+
import net.minecraft.world.item.ItemStack;
16+
17+
import org.apache.commons.lang3.math.NumberUtils;
18+
19+
import java.util.regex.Matcher;
20+
import java.util.regex.Pattern;
21+
22+
/**
23+
* Updates the McGrubber Burger count for players automatically when the
24+
* related config option is enabled.
25+
*/
26+
public class McGrubberUpdater {
27+
private static final String MOTES_GRUBBER = "Motes Grubber";
28+
private static final String CONSUMABLE_ITEMS = "Miscellaneous ➜ Consumable Items";
29+
private static final Pattern ORB_PICKUP = Pattern.compile("ORB! Picked up \\+(?<motes>\\d+) Motes, recovered \\+2ф Rift Time!");
30+
private static final Pattern MOTES_PRICE = Pattern.compile("(?<price>\\d+(\\.\\d)?) Motes");
31+
private static final Pattern MCGRUBBER_PROGRESS = Pattern.compile("Total Progress: (?<percent>\\d+)%");
32+
33+
private McGrubberUpdater() {}
34+
35+
@Init
36+
public static void init() {
37+
ScreenEvents.BEFORE_INIT.register((_client, screen, _scaledWidth, _scaledHeight) -> {
38+
if (!Utils.isOnSkyblock() || !(screen instanceof ContainerScreen containerScreen)) {
39+
return;
40+
} else if (!SkyblockerConfigManager.get().otherLocations.rift.autoDetectMcGrubber) {
41+
return;
42+
}
43+
44+
if (Utils.isInTheRift() && containerScreen.getTitle().getString().equals(MOTES_GRUBBER)) {
45+
ScreenEvents.remove(screen).register(_screen -> McGrubberUpdater.fromMotesGrubber(containerScreen));
46+
} else if (!Utils.isInTheRift() && containerScreen.getTitle().getString().equals(CONSUMABLE_ITEMS)) {
47+
ScreenEvents.remove(screen).register(_screen -> McGrubberUpdater.fromConsumableItems(containerScreen));
48+
}
49+
});
50+
ClientReceiveMessageEvents.ALLOW_GAME.register(McGrubberUpdater::fromOrbPickup);
51+
}
52+
53+
/**
54+
* Detects McGrubber stacks when selling to Motes Grubber NPC
55+
*/
56+
private static void fromMotesGrubber(ContainerScreen screen) {
57+
for (Slot slot : screen.getMenu().slots) {
58+
if (slot.container != Minecraft.getInstance().player.getInventory()) continue;
59+
60+
ItemStack item = slot.getItem();
61+
Matcher matcher = ItemUtils.getLoreLineIfMatch(item, MOTES_PRICE);
62+
63+
if (matcher == null) continue;
64+
65+
float price = NumberUtils.toFloat(matcher.group("price"));
66+
final String internalID = item.getSkyblockId();
67+
68+
// Compare against base price to determine mcgrubber stacks
69+
if (TooltipInfoType.MOTES.hasOrNullWarning(internalID)) {
70+
// x is mcgrubber stacks, y is final price, & z is initial price
71+
// y = (1 + 0.05x)z -> reorder to solve for x -> x = 20y / z - 20
72+
int mcGrubberStacks = Math.round(20 * price / TooltipInfoType.MOTES.getData().getInt(internalID) - 20);
73+
74+
if (SkyblockerConfigManager.get().otherLocations.rift.mcGrubberStacks != mcGrubberStacks) {
75+
SkyblockerConfigManager.updateOnly(config -> config.otherLocations.rift.mcGrubberStacks = mcGrubberStacks);
76+
}
77+
78+
break;
79+
}
80+
}
81+
}
82+
83+
/**
84+
* Detects McGrubber stacks from the /sblevels GUI
85+
*/
86+
private static void fromConsumableItems(ContainerScreen screen) {
87+
for (Slot slot : screen.getMenu().slots) {
88+
ItemStack item = slot.getItem();
89+
90+
if (!item.getSkyblockId().equals("MCGRUBBER_BURGER")) continue;
91+
92+
Matcher matcher = ItemUtils.getLoreLineIfMatch(item, MCGRUBBER_PROGRESS);
93+
94+
if (matcher == null) continue;
95+
96+
// 20% progress per mcgrubber stack
97+
int mcGrubberStacks = RegexUtils.parseIntFromMatcher(matcher, "percent") / 20;
98+
99+
if (SkyblockerConfigManager.get().otherLocations.rift.mcGrubberStacks != mcGrubberStacks) {
100+
SkyblockerConfigManager.updateOnly(config -> config.otherLocations.rift.mcGrubberStacks = mcGrubberStacks);
101+
}
102+
103+
break;
104+
}
105+
}
106+
107+
/**
108+
* Detects McGrubber stacks from picking up orbs in the rift
109+
*/
110+
private static boolean fromOrbPickup(Component text, boolean overlay) {
111+
if (!SkyblockerConfigManager.get().otherLocations.rift.autoDetectMcGrubber) {
112+
return true;
113+
} else if (!Utils.isOnSkyblock() || !Utils.isInTheRift() || overlay) {
114+
return true;
115+
}
116+
117+
Matcher matcher = ORB_PICKUP.matcher(text.getString());
118+
119+
if (matcher.matches()) {
120+
int motes = RegexUtils.parseIntFromMatcher(matcher, "motes");
121+
// Base of 5 motes, +60 motes per mcGrubber stack.
122+
int mcGrubberStacks = (motes - 5) / 60;
123+
124+
if (SkyblockerConfigManager.get().otherLocations.rift.mcGrubberStacks != mcGrubberStacks) {
125+
SkyblockerConfigManager.updateOnly(config -> config.otherLocations.rift.mcGrubberStacks = mcGrubberStacks);
126+
}
127+
}
128+
129+
return true;
130+
}
131+
}

src/main/resources/assets/skyblocker/lang/en_us.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,8 @@
973973
"skyblocker.config.otherLocations.end.zealotKillsEnabled.@Tooltip": "Only counts melee kills!\n\nKills can be updated by going to the Zealot page in the Bestiary.",
974974

975975
"skyblocker.config.otherLocations.rift": "The Rift",
976+
"skyblocker.config.otherLocations.rift.autoDetectMcGrubber": "Autodetect McGrubber Stacks",
977+
"skyblocker.config.otherLocations.rift.autoDetectMcGrubber.@Tooltip": "Detects McGrubber stacks (e.g. from Orb pickup messages) and adjusts the stack count below automatically.",
976978
"skyblocker.config.otherLocations.rift.blobbercystGlow": "Blobbercyst Glow",
977979
"skyblocker.config.otherLocations.rift.blobbercystGlow.@Tooltip": "Applies the glowing effect to the Blobbercysts from the BACTE fight.",
978980
"skyblocker.config.otherLocations.rift.enigmaSoulWaypoints": "Enable Enigma Soul Waypoints",

0 commit comments

Comments
 (0)