diff options
author | Aaron <51387595+AzureAaron@users.noreply.github.com> | 2024-05-29 14:24:24 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-29 14:24:24 -0400 |
commit | 0451352b08c530980fbe543ecad8e1949a0ebaab (patch) | |
tree | e135f68e03db84497ff3ba8d57a671d25fb0bc18 | |
parent | fb6beb6b25e8fb71cbc3b6927c65630fa5bc0a8b (diff) | |
parent | bffa76f7b12bd6d65e2f603d622db226e610dc73 (diff) | |
download | Skyblocker-0451352b08c530980fbe543ecad8e1949a0ebaab.tar.gz Skyblocker-0451352b08c530980fbe543ecad8e1949a0ebaab.tar.bz2 Skyblocker-0451352b08c530980fbe543ecad8e1949a0ebaab.zip |
Merge pull request #734 from Emirlol/chocolate-factory-helper-alpha
Update chocolate factory for chocolate factory 2
-rw-r--r-- | src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java | 77 | ||||
-rw-r--r-- | src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java | 24 |
2 files changed, 78 insertions, 23 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java index 2d530b6d..2662b8e1 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/ChocolateFactorySolver.java @@ -28,6 +28,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class ChocolateFactorySolver extends ContainerSolver { + //Patterns private static final Pattern CPS_PATTERN = Pattern.compile("([\\d,.]+) Chocolate per second"); private static final Pattern CPS_INCREASE_PATTERN = Pattern.compile("\\+([\\d,]+) Chocolate per second"); private static final Pattern COST_PATTERN = Pattern.compile("Cost ([\\d,]+) Chocolate"); @@ -36,17 +37,31 @@ public class ChocolateFactorySolver extends ContainerSolver { private static final Pattern CHOCOLATE_PATTERN = Pattern.compile("^([\\d,]+) Chocolate$"); private static final Pattern PRESTIGE_REQUIREMENT_PATTERN = Pattern.compile("Chocolate this Prestige: ([\\d,]+) +Requires (\\S+) Chocolate this Prestige!"); private static final Pattern TIME_TOWER_STATUS_PATTERN = Pattern.compile("Status: (ACTIVE|INACTIVE)"); - private static final ObjectArrayList<Rabbit> cpsIncreaseFactors = new ObjectArrayList<>(6); + + private static final ObjectArrayList<Rabbit> cpsIncreaseFactors = new ObjectArrayList<>(8); private static long totalChocolate = -1L; private static double totalCps = -1.0; private static double totalCpsMultiplier = -1.0; private static long requiredUntilNextPrestige = -1L; + private static boolean canPrestige = false; + private static boolean reachedMaxPrestige = false; private static double timeTowerMultiplier = -1.0; private static boolean isTimeTowerActive = false; private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#,###.#", DecimalFormatSymbols.getInstance(Locale.ENGLISH)); private static ItemStack bestUpgrade = null; private static ItemStack bestAffordableUpgrade = null; + //Slots, for ease of maintenance rather than using magic numbers everywhere. + private static final byte RABBITS_START = 28; + private static final byte RABBITS_END = 34; + private static final byte COACH_SLOT = 42; + private static final byte CHOCOLATE_SLOT = 13; + private static final byte CPS_SLOT = 45; + private static final byte PRESTIGE_SLOT = 27; + private static final byte TIME_TOWER_SLOT = 39; + private static final byte STRAY_RABBIT_START = 0; + private static final byte STRAY_RABBIT_END = 26; + public ChocolateFactorySolver() { super("^Chocolate Factory$"); ItemTooltipCallback.EVENT.register(ChocolateFactorySolver::handleTooltip); @@ -62,7 +77,8 @@ public class ChocolateFactorySolver extends ContainerSolver { updateFactoryInfo(slots); List<ColorHighlight> highlights = new ArrayList<>(); - getPrestigeHighlight(slots.get(28)).ifPresent(highlights::add); + getPrestigeHighlight().ifPresent(highlights::add); + highlights.addAll(getStrayRabbitHighlight(slots)); if (totalChocolate <= 0 || cpsIncreaseFactors.isEmpty()) return highlights; //Something went wrong or there's nothing we can afford. Rabbit bestRabbit = cpsIncreaseFactors.getFirst(); @@ -87,7 +103,7 @@ public class ChocolateFactorySolver extends ContainerSolver { private static void updateFactoryInfo(Int2ObjectMap<ItemStack> slots) { cpsIncreaseFactors.clear(); - for (int i = 29; i <= 33; i++) { // The 5 rabbits slots are in 29, 30, 31, 32 and 33. + for (int i = RABBITS_START; i <= RABBITS_END; i++) { // The 7 rabbits slots are in 28, 29, 30, 31, 32, 33 and 34. ItemStack item = slots.get(i); if (item.isOf(Items.PLAYER_HEAD)) { getRabbit(item, i).ifPresent(cpsIncreaseFactors::add); @@ -95,20 +111,21 @@ public class ChocolateFactorySolver extends ContainerSolver { } //Coach is in slot 42 - getCoach(slots.get(42)).ifPresent(cpsIncreaseFactors::add); + getCoach(slots.get(COACH_SLOT)).ifPresent(cpsIncreaseFactors::add); //The clickable chocolate is in slot 13, holds the total chocolate - RegexUtils.getLongFromMatcher(CHOCOLATE_PATTERN.matcher(slots.get(13).getName().getString())).ifPresent(l -> totalChocolate = l); + RegexUtils.getLongFromMatcher(CHOCOLATE_PATTERN.matcher(slots.get(CHOCOLATE_SLOT).getName().getString())).ifPresent(l -> totalChocolate = l); //Cps item (cocoa bean) is in slot 45 - String cpsItemLore = getConcatenatedLore(slots.get(45)); + String cpsItemLore = getConcatenatedLore(slots.get(CPS_SLOT)); Matcher cpsMatcher = CPS_PATTERN.matcher(cpsItemLore); RegexUtils.getDoubleFromMatcher(cpsMatcher).ifPresent(d -> totalCps = d); Matcher multiplierMatcher = TOTAL_MULTIPLIER_PATTERN.matcher(cpsItemLore); RegexUtils.getDoubleFromMatcher(multiplierMatcher, cpsMatcher.hasMatch() ? cpsMatcher.end() : 0).ifPresent(d -> totalCpsMultiplier = d); //Prestige item is in slot 28 - Matcher prestigeMatcher = PRESTIGE_REQUIREMENT_PATTERN.matcher(getConcatenatedLore(slots.get(28))); + String prestigeLore = getConcatenatedLore(slots.get(PRESTIGE_SLOT)); + Matcher prestigeMatcher = PRESTIGE_REQUIREMENT_PATTERN.matcher(prestigeLore); OptionalLong currentChocolate = RegexUtils.getLongFromMatcher(prestigeMatcher); if (currentChocolate.isPresent()) { String requirement = prestigeMatcher.group(2); //If the first one matched, we can assume the 2nd one is also matched since it's one whole regex @@ -117,11 +134,17 @@ public class ChocolateFactorySolver extends ContainerSolver { if (NumberUtils.isParsable(amountString)) { requiredUntilNextPrestige = Long.parseLong(amountString) - currentChocolate.getAsLong(); } + } else if (prestigeLore.endsWith("Click to prestige!")) { + canPrestige = true; + reachedMaxPrestige = false; + } else if (prestigeLore.endsWith("You have reached max prestige!")) { + canPrestige = false; + reachedMaxPrestige = true; } //Time Tower is in slot 39 - timeTowerMultiplier = romanToDecimal(StringUtils.substringAfterLast(slots.get(39).getName().getString(), ' ')) / 10.0; //The name holds the level, which is multiplier * 10 in roman numerals - Matcher timeTowerStatusMatcher = TIME_TOWER_STATUS_PATTERN.matcher(getConcatenatedLore(slots.get(39))); + timeTowerMultiplier = romanToDecimal(StringUtils.substringAfterLast(slots.get(TIME_TOWER_SLOT).getName().getString(), ' ')) / 10.0; //The name holds the level, which is multiplier * 10 in roman numerals + Matcher timeTowerStatusMatcher = TIME_TOWER_STATUS_PATTERN.matcher(getConcatenatedLore(slots.get(TIME_TOWER_SLOT))); if (timeTowerStatusMatcher.find()) { isTimeTowerActive = timeTowerStatusMatcher.group(1).equals("ACTIVE"); } @@ -146,7 +169,7 @@ public class ChocolateFactorySolver extends ContainerSolver { if (cost.isPresent()) shouldAddLine = addUpgradeTimerToLore(lines, cost.getAsLong()); //Prestige item - if (stack.isOf(Items.DROPPER) && requiredUntilNextPrestige != -1L) { + if (stack.isOf(Items.DROPPER)) { shouldAddLine = addPrestigeTimerToLore(lines) || shouldAddLine; } //Time tower @@ -171,11 +194,13 @@ public class ChocolateFactorySolver extends ContainerSolver { } private static boolean addPrestigeTimerToLore(List<Text> lines) { - if (requiredUntilNextPrestige == -1L || totalCps == -1.0) return false; - lines.add(Text.empty() - .append(Text.literal("Chocolate until next prestige: ").formatted(Formatting.GRAY)) - .append(Text.literal(DECIMAL_FORMAT.format(requiredUntilNextPrestige)).formatted(Formatting.GOLD))); - lines.add(Text.empty() + if (totalCps < 0.0 || reachedMaxPrestige) return false; + if (requiredUntilNextPrestige > 0 && !canPrestige) { + lines.add(Text.empty() + .append(Text.literal("Chocolate until next prestige: ").formatted(Formatting.GRAY)) + .append(Text.literal(DECIMAL_FORMAT.format(requiredUntilNextPrestige)).formatted(Formatting.GOLD))); + } + lines.add(Text.empty() //Keep this outside of the `if` to match the format of the upgrade tooltips, that say "Time until upgrade: Now" when it's possible .append(Text.literal("Time until next prestige: ").formatted(Formatting.GRAY)) .append(formatTime(requiredUntilNextPrestige / totalCps))); return true; @@ -292,7 +317,7 @@ public class ChocolateFactorySolver extends ContainerSolver { OptionalInt cost = RegexUtils.getIntFromMatcher(costMatcher, multiplierIncreaseMatcher.hasMatch() ? multiplierIncreaseMatcher.end() : 0); //Cost comes after the multiplier line if (cost.isEmpty()) return Optional.empty(); - return Optional.of(new Rabbit(totalCps / totalCpsMultiplier * (nextCpsMultiplier.getAsDouble() - currentCpsMultiplier.getAsDouble()), cost.getAsInt(), 42, coachItem)); + return Optional.of(new Rabbit(totalCps / totalCpsMultiplier * (nextCpsMultiplier.getAsDouble() - currentCpsMultiplier.getAsDouble()), cost.getAsInt(), COACH_SLOT, coachItem)); } private static Optional<Rabbit> getRabbit(ItemStack item, int slot) { @@ -312,13 +337,21 @@ public class ChocolateFactorySolver extends ContainerSolver { return Optional.of(new Rabbit(nextCps.getAsInt() - currentCps.getAsInt(), cost.getAsInt(), slot, item)); } - private static Optional<ColorHighlight> getPrestigeHighlight(ItemStack item) { - List<Text> loreList = ItemUtils.getLore(item); - if (loreList.isEmpty()) return Optional.empty(); + private static Optional<ColorHighlight> getPrestigeHighlight() { + if (reachedMaxPrestige) return Optional.empty(); + if (canPrestige) return Optional.of(ColorHighlight.green(PRESTIGE_SLOT)); + return Optional.of(ColorHighlight.red(PRESTIGE_SLOT)); + } - String lore = loreList.getLast().getString(); //The last line holds the text we're looking for - if (lore.equals("Click to prestige!")) return Optional.of(ColorHighlight.green(28)); - return Optional.of(ColorHighlight.red(28)); + private static List<ColorHighlight> getStrayRabbitHighlight(Int2ObjectMap<ItemStack> slots) { + final List<ColorHighlight> highlights = new ArrayList<>(); + for (byte i = STRAY_RABBIT_START; i < STRAY_RABBIT_END; i++) { + ItemStack item = slots.get(i); + if (item.isOf(Items.PLAYER_HEAD) && item.getName().getString().equals("CLICK ME!")) { + highlights.add(ColorHighlight.green(i)); + } + } + return highlights; } private record Rabbit(double cpsIncrease, int cost, int slot, ItemStack itemStack) { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java index c4fd7d4d..0175306a 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/chocolatefactory/EggFinder.java @@ -1,10 +1,17 @@ package de.hysky.skyblocker.skyblock.chocolatefactory; +import com.mojang.brigadier.Command; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.events.SkyblockEvents; import de.hysky.skyblocker.utils.*; +import de.hysky.skyblocker.utils.scheduler.MessageScheduler; import de.hysky.skyblocker.utils.waypoint.Waypoint; import it.unimi.dsi.fastutil.objects.ObjectImmutableList; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; @@ -13,6 +20,8 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.entity.Entity; import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.item.ItemStack; +import net.minecraft.text.ClickEvent; +import net.minecraft.text.HoverEvent; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import org.apache.commons.lang3.mutable.MutableObject; @@ -39,6 +48,17 @@ public class EggFinder { SkyblockEvents.LOCATION_CHANGE.register(EggFinder::handleLocationChange); ClientReceiveMessageEvents.GAME.register(EggFinder::onChatMessage); WorldRenderEvents.AFTER_TRANSLUCENT.register(EggFinder::renderWaypoints); + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal(SkyblockerMod.NAMESPACE) + .then(ClientCommandManager.literal("eggFinder") + .then(ClientCommandManager.literal("shareLocation") + .then(ClientCommandManager.argument("x", IntegerArgumentType.integer()) + .then(ClientCommandManager.argument("y", IntegerArgumentType.integer()) + .then(ClientCommandManager.argument("z", IntegerArgumentType.integer()) + .then(ClientCommandManager.argument("eggType", StringArgumentType.word()) + .executes(context -> { + MessageScheduler.INSTANCE.sendMessageAfterCooldown("[Skyblocker] Chocolate " + context.getArgument("eggType", String.class) + " Egg found at " + context.getArgument("x", Integer.class) + " " + context.getArgument("y", Integer.class) + " " + context.getArgument("z", Integer.class) + "!"); + return Command.SINGLE_SUCCESS; + }))))))))); } private static void handleLocationChange(Location location) { @@ -102,7 +122,9 @@ public class EggFinder { .append("Found a ") .append(Text.literal("Chocolate " + eggType + " Egg") .withColor(eggType.color)) - .append(" at " + entity.getBlockPos().up(2).toShortString() + "!")); + .append(" at " + entity.getBlockPos().up(2).toShortString() + "!") + .styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/skyblocker eggFinder shareLocation " + entity.getBlockX() + " " + entity.getBlockY() + 2 + " " + entity.getBlockZ() + " " + eggType)) + .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.literal("Click to share the location in chat!").formatted(Formatting.GREEN))))); } private static void renderWaypoints(WorldRenderContext context) { |