diff options
| author | upfault.lol <johian2004@gmail.com> | 2025-03-02 22:08:45 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-03 12:08:45 +0800 |
| commit | 0d0aae6b88b34d7f85ba397eea2469fb4a95a51e (patch) | |
| tree | 305dfaaf2ae59cbe7ec0ab176b1514613bc17ad0 /src | |
| parent | e428f5aca33d42bf35f6ee0dc8edc8df2cc753b3 (diff) | |
| download | Skyblocker-0d0aae6b88b34d7f85ba397eea2469fb4a95a51e.tar.gz Skyblocker-0d0aae6b88b34d7f85ba397eea2469fb4a95a51e.tar.bz2 Skyblocker-0d0aae6b88b34d7f85ba397eea2469fb4a95a51e.zip | |
Garden Tweaks & Features (#1118)
* Sum visitors with alike crops, fix Farming XP/h regex, and improve precision for XP/h and Blocks/s
* Added Show Stacks in Visitor Helper
* Re-added the drawItemEntry into drawScreen
* VacuumSolver, VisitorHelper, PestHighlighter
* Forgot to fix highlight flicker in VacuumSolver
* removed imports from MBB
* Updated Regex & MayorUtils catch block
* Forgot to add the visitor head and name coloring back into the render method during some tests
* Refactor visitor package name
* Clean up visitor helper and garden
* Clean up visitor helper some more
* Fix visitor requirements
* Fix block breaks
* Use primitive types and fixes
* Missed a primitive
* Remove vacuum solver
* Fix amount parsing
---------
Co-authored-by: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com>
Diffstat (limited to 'src')
18 files changed, 561 insertions, 384 deletions
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java index 242bfd24..5a210017 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java @@ -36,8 +36,8 @@ public class CrimsonIsleCategory { .build()) .option(Option.<Waypoint.Type>createBuilder() .name(Text.translatable("skyblocker.config.crimsonIsle.kuudra.suppliesAndFuelWaypointType")) - .description(OptionDescription.of(Text.translatable("skyblocker.config.dungeons.secretWaypoints.waypointType.@Tooltip"), - Text.translatable("skyblocker.config.dungeons.secretWaypoints.waypointType.generalNote"))) + .description(OptionDescription.of(Text.translatable("skyblocker.config.uiAndVisuals.waypoints.waypointType.@Tooltip"), + Text.translatable("skyblocker.config.uiAndVisuals.waypoints.waypointType.generalNote"))) .binding(defaults.crimsonIsle.kuudra.suppliesAndFuelWaypointType, () -> config.crimsonIsle.kuudra.suppliesAndFuelWaypointType, newValue -> config.crimsonIsle.kuudra.suppliesAndFuelWaypointType = newValue) diff --git a/src/main/java/de/hysky/skyblocker/config/categories/FarmingCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/FarmingCategory.java index 929256c6..9b90c096 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/FarmingCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/FarmingCategory.java @@ -38,13 +38,14 @@ public class FarmingCategory { newValue -> config.farming.garden.dicerTitlePrevent = newValue) .controller(ConfigUtils::createBooleanController) .build()) - .option(Option.<Boolean>createBuilder() - .name(Text.translatable("skyblocker.config.farming.garden.visitorHelper")) - .binding(defaults.farming.garden.visitorHelper, - () -> config.farming.garden.visitorHelper, - newValue -> config.farming.garden.visitorHelper = newValue) - .controller(ConfigUtils::createBooleanController) - .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.config.farming.garden.pestHighlighter")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.farming.garden.pestHighlighter.@Tooltip"))) + .binding(defaults.farming.garden.pestHighlighter, + () -> config.farming.garden.pestHighlighter, + newValue -> config.farming.garden.pestHighlighter = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) .option(Option.<Boolean>createBuilder() .name(Text.translatable("skyblocker.config.farming.garden.lockMouseTool")) .binding(defaults.farming.garden.lockMouseTool, @@ -76,6 +77,35 @@ public class FarmingCategory { .controller(ConfigUtils::createBooleanController) .build()) .build()) + .group(OptionGroup.createBuilder() + .name(Text.translatable("skyblocker.config.farming.visitorHelper")) + .collapsed(false) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.config.farming.visitorHelper.visitorHelper")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.farming.visitorHelper.visitorHelper.@Tooltip"))) + .binding(defaults.farming.visitorHelper.visitorHelper, + () -> config.farming.visitorHelper.visitorHelper, + newValue -> config.farming.visitorHelper.visitorHelper = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.config.farming.visitorHelper.visitorHelperGardenOnly")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.farming.visitorHelper.visitorHelperGardenOnly.@Tooltip"))) + .binding(defaults.farming.visitorHelper.visitorHelperGardenOnly, + () -> config.farming.visitorHelper.visitorHelperGardenOnly, + newValue -> config.farming.visitorHelper.visitorHelperGardenOnly = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.config.farming.visitorHelper.showStacksInVisitorHelper")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.farming.visitorHelper.showStacksInVisitorHelper.@Tooltip"))) + .binding(defaults.farming.visitorHelper.showStacksInVisitorHelper, + () -> config.farming.visitorHelper.showStacksInVisitorHelper, + newValue -> config.farming.visitorHelper.showStacksInVisitorHelper = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .build()) .build(); + } } diff --git a/src/main/java/de/hysky/skyblocker/config/configs/FarmingConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/FarmingConfig.java index 568165a7..88506bfe 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/FarmingConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/FarmingConfig.java @@ -7,6 +7,9 @@ public class FarmingConfig { @SerialEntry public Garden garden = new Garden(); + @SerialEntry + public VisitorHelper visitorHelper = new VisitorHelper(); + public static class Garden { @SerialEntry public FarmingHud farmingHud = new FarmingHud(); @@ -14,8 +17,8 @@ public class FarmingConfig { @SerialEntry public boolean dicerTitlePrevent = true; - @SerialEntry - public boolean visitorHelper = true; + @SerialEntry + public boolean pestHighlighter = true; @SerialEntry public boolean lockMouseTool = false; @@ -30,6 +33,17 @@ public class FarmingConfig { public boolean closeScreenOnPlotClick = false; } + public static class VisitorHelper { + @SerialEntry + public boolean visitorHelper = true; + + @SerialEntry + public boolean visitorHelperGardenOnly = true; + + @SerialEntry + public boolean showStacksInVisitorHelper = false; + } + public static class FarmingHud { @SerialEntry public boolean enableHud = true; diff --git a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java index 426f45df..1b6842f6 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java @@ -2,7 +2,6 @@ package de.hysky.skyblocker.mixins; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; - import com.mojang.blaze3d.systems.RenderSystem; import de.hysky.skyblocker.config.SkyblockerConfig; import de.hysky.skyblocker.config.SkyblockerConfigManager; @@ -11,7 +10,7 @@ import de.hysky.skyblocker.skyblock.PetCache; import de.hysky.skyblocker.skyblock.experiment.ExperimentSolver; import de.hysky.skyblocker.skyblock.experiment.SuperpairsSolver; import de.hysky.skyblocker.skyblock.experiment.UltrasequencerSolver; -import de.hysky.skyblocker.skyblock.garden.VisitorHelper; +import de.hysky.skyblocker.skyblock.garden.visitor.VisitorHelper; import de.hysky.skyblocker.skyblock.item.*; import de.hysky.skyblocker.skyblock.item.slottext.SlotTextManager; import de.hysky.skyblocker.skyblock.item.tooltip.BackpackPreview; @@ -136,13 +135,6 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen } } - @Inject(at = @At("HEAD"), method = "mouseClicked") - public void skyblocker$mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> cir) { - if (SkyblockerConfigManager.get().farming.garden.visitorHelper && (Utils.getLocationRaw().equals("garden") && !getTitle().getString().contains("Logbook") || getTitle().getString().startsWith("Bazaar"))) { - VisitorHelper.onMouseClicked(mouseX, mouseY, button, this.textRenderer); - } - } - @ModifyExpressionValue(method = "mouseClicked", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;mouseClicked(DDI)Z")) public boolean skyblocker$passThroughSearchFieldUnfocusedClicks(boolean superClicked, double mouseX, double mouseY, int button) { //Handle Search Field clicks - as of 1.21.4 the game will only send clicks to the selected element rather than trying to send one to each and stopping when the first returns true (if any). @@ -224,6 +216,7 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen /** * Avoids getting currentSolver again when it's already in the scope for some usages of this method. + * * @see #skyblocker$experimentSolvers$getStack(Slot, ItemStack, ContainerSolver) */ @Unique @@ -297,8 +290,7 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen switch (this.handler) { case GenericContainerScreenHandler genericContainerScreenHandler when genericContainerScreenHandler.getRows() == 6 -> { - VisitorHelper.onSlotClick(slot, slotId, title, genericContainerScreenHandler.getSlot(13).getStack()); - + VisitorHelper.onSlotClick(slot, slotId, title); // Prevent selling to NPC shops ItemStack sellStack = this.handler.slots.get(49).getStack(); if (sellStack.getName().getString().equals("Sell Item") || ItemUtils.getLoreLineIf(sellStack, text -> text.contains("buyback")) != null) { @@ -329,6 +321,13 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen } } + @Inject(at = @At("HEAD"), method = "mouseClicked") + public void skyblocker$mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> cir) { + if (VisitorHelper.shouldRender()) { + VisitorHelper.handleMouseClick(mouseX, mouseY, button, this.textRenderer); + } + } + @Inject(method = "drawSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawItem(Lnet/minecraft/item/ItemStack;III)V")) private void skyblocker$drawOnItem(DrawContext context, Slot slot, CallbackInfo ci) { if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.itemInfoDisplay.itemRarityBackgrounds) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobBoundingBoxes.java b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobBoundingBoxes.java index 65ad6918..d5081668 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobBoundingBoxes.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobBoundingBoxes.java @@ -50,7 +50,7 @@ public class MobBoundingBoxes { return false; } - + public static float[] getBoxColor(Entity entity) { int color = MobGlow.getMobGlow(entity); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java index 91469c38..76930bd8 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java @@ -33,7 +33,7 @@ import net.minecraft.util.Formatting; import net.minecraft.util.math.Box; import net.minecraft.world.World; -import java.util.List; +import java.util.*; public class MobGlow { public static final int NO_GLOW = 0; @@ -42,6 +42,31 @@ public class MobGlow { */ private static final String NUKEKUBI_HEAD_TEXTURE = "eyJ0aW1lc3RhbXAiOjE1MzQ5NjM0MzU5NjIsInByb2ZpbGVJZCI6ImQzNGFhMmI4MzFkYTRkMjY5NjU1ZTMzYzE0M2YwOTZjIiwicHJvZmlsZU5hbWUiOiJFbmRlckRyYWdvbiIsInNpZ25hdHVyZVJlcXVpcmVkIjp0cnVlLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZWIwNzU5NGUyZGYyNzM5MjFhNzdjMTAxZDBiZmRmYTExMTVhYmVkNWI5YjIwMjllYjQ5NmNlYmE5YmRiYjRiMyJ9fX0="; private static final String FEL_HEAD_TEXTURE = "ewogICJ0aW1lc3RhbXAiIDogMTcyMDAyNTQ4Njg2MywKICAicHJvZmlsZUlkIiA6ICIzZDIxZTYyMTk2NzQ0Y2QwYjM3NjNkNTU3MWNlNGJlZSIsCiAgInByb2ZpbGVOYW1lIiA6ICJTcl83MUJsYWNrYmlyZCIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9jMjg2ZGFjYjBmMjE0NGQ3YTQxODdiZTM2YmJhYmU4YTk4ODI4ZjdjNzlkZmY1Y2UwMTM2OGI2MzAwMTU1NjYzIiwKICAgICAgIm1ldGFkYXRhIiA6IHsKICAgICAgICAibW9kZWwiIDogInNsaW0iCiAgICAgIH0KICAgIH0KICB9Cn0="; + private static final Set<String> PEST_HEAD_TEXTURES = Set.of( + // Mosquito + "ewogICJ0aW1lc3RhbXAiIDogMTY5Njk0NTAyOTQ2MSwKICAicHJvZmlsZUlkIiA6ICI3NTE0NDQ4MTkxZTY0NTQ2OGM5NzM5YTZlMzk1N2JlYiIsCiAgInByb2ZpbGVOYW1lIiA6ICJUaGFua3NNb2phbmciLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNTJhOWZlMDViYzY2M2VmY2QxMmU1NmEzY2NjNWVjMDM1YmY1NzdiNzg3MDg1NDhiNmY0ZmZjZjFkMzBlY2NmZSIKICAgIH0KICB9Cn0=", + // Rat + "ewogICJ0aW1lc3RhbXAiIDogMTYxODQxOTcwMTc1MywKICAicHJvZmlsZUlkIiA6ICI3MzgyZGRmYmU0ODU0NTVjODI1ZjkwMGY4OGZkMzJmOCIsCiAgInByb2ZpbGVOYW1lIiA6ICJCdUlJZXQiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYThhYmI0NzFkYjBhYjc4NzAzMDExOTc5ZGM4YjQwNzk4YTk0MWYzYTRkZWMzZWM2MWNiZWVjMmFmOGNmZmU4IiwKICAgICAgIm1ldGFkYXRhIiA6IHsKICAgICAgICAibW9kZWwiIDogInNsaW0iCiAgICAgIH0KICAgIH0KICB9Cn0=", + // Locust + "ewogICJ0aW1lc3RhbXAiIDogMTY5NzU1NzA3NzAzNywKICAicHJvZmlsZUlkIiA6ICI0YjJlMGM1ODliZjU0ZTk1OWM1ZmJlMzg5MjQ1MzQzZSIsCiAgInByb2ZpbGVOYW1lIiA6ICJfTmVvdHJvbl8iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNGIyNGE0ODJhMzJkYjFlYTc4ZmI5ODA2MGIwYzJmYTRhMzczY2JkMThhNjhlZGRkZWI3NDE5NDU1YTU5Y2RhOSIKICAgIH0KICB9Cn0=", + // Cricket + "ewogICJ0aW1lc3RhbXAiIDogMTcyMzE3OTgxMTI2NCwKICAicHJvZmlsZUlkIiA6ICJjZjc4YzFkZjE3ZTI0Y2Q5YTIxYmU4NWQ0NDk5ZWE4ZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJNYXR0c0FybW9yU3RhbmRzIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2EyNGM2OWY5NmNlNTU2MjIxZTE5NWM4ZWYyYmZhZDcxZWJmN2Y5NWY1YWU5MTRhNDg0YThkMGVjMjE2NzI2NzQiCiAgICB9CiAgfQp9", + // Fly + "ewogICJ0aW1lc3RhbXAiIDogMTY5Njk0NTA2MzI4MSwKICAicHJvZmlsZUlkIiA6ICJjN2FmMWNkNjNiNTE0Y2YzOGY4NWQ2ZDUxNzhjYThlNCIsCiAgInByb2ZpbGVOYW1lIiA6ICJtb25zdGVyZ2FtZXIzMTUiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOWQ5MGU3Nzc4MjZhNTI0NjEzNjhlMjZkMWIyZTE5YmZhMWJhNTgyZDYwMjQ4M2U1NDVmNDEyNGQwZjczMTg0MiIKICAgIH0KICB9Cn0=", + // Beetle + "ewogICJ0aW1lc3RhbXAiIDogMTcyMzE3OTc4OTkzNCwKICAicHJvZmlsZUlkIiA6ICJlMjc5NjliODYyNWY0NDg1YjkyNmM5NTBhMDljMWMwMSIsCiAgInByb2ZpbGVOYW1lIiA6ICJLRVZJTktFTE9LRSIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS83MGExZTgzNmJmMTk2OGIyZWFhNDgzNzIyN2ExOTIwNGYxNzI5NWQ4NzBlZTllNzU0YmQ2YjZkNjBkZGJlZDNjIgogICAgfQogIH0KfQ==", + // Slug + "ewogICJ0aW1lc3RhbXAiIDogMTY5NzQ3MDQ0MzA4MiwKICAicHJvZmlsZUlkIiA6ICJkOGNkMTNjZGRmNGU0Y2IzODJmYWZiYWIwOGIyNzQ4OSIsCiAgInByb2ZpbGVOYW1lIiA6ICJaYWNoeVphY2giLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2E3OWQwZmQ2NzdiNTQ1MzA5NjExMTdlZjg0YWRjMjA2ZTJjYzUwNDVjMTM0NGQ2MWQ3NzZiZjhhYzJmZTFiYSIKICAgIH0KICB9Cn0=", + // Moth + "ewogICJ0aW1lc3RhbXAiIDogMTY5Njg3MDQwNTk1NCwKICAicHJvZmlsZUlkIiA6ICJiMTUyZDlhZTE1MTM0OWNmOWM2NmI0Y2RjMTA5NTZjOCIsCiAgInByb2ZpbGVOYW1lIiA6ICJNaXNxdW90aCIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS82NTQ4NWM0YjM0ZTViNTQ3MGJlOTRkZTEwMGU2MWY3ODE2ZjgxYmM1YTExZGZkZjBlY2NmODkwMTcyZGE1ZDBhIgogICAgfQogIH0KfQ==", + // Mite + "ewogICJ0aW1lc3RhbXAiIDogMTY5Njg3MDQxOTcyNSwKICAicHJvZmlsZUlkIiA6ICJkYjYzNWE3MWI4N2U0MzQ5YThhYTgwOTMwOWFhODA3NyIsCiAgInByb2ZpbGVOYW1lIiA6ICJFbmdlbHMxNzQiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmU2YmFmNjQzMWE5ZGFhMmNhNjA0ZDVhM2MyNmU5YTc2MWQ1OTUyZjA4MTcxNzRhNGZlMGI3NjQ2MTZlMjFmZiIKICAgIH0KICB9Cn0=", + // Earthworm + "ewogICJ0aW1lc3RhbXAiIDogMTY5NzQ3MDQ1OTc0NywKICAicHJvZmlsZUlkIiA6ICIyNTBlNzc5MjZkNDM0ZDIyYWM2MTQ4N2EyY2M3YzAwNCIsCiAgInByb2ZpbGVOYW1lIiA6ICJMdW5hMTIxMDUiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNjQwM2JhNDAyN2EzMzNkOGQyZmQzMmFiNTlkMWNmZGJhYTdkOTA4ZDgwZDIzODFkYjJhNjljYmU2NTQ1MGFkOCIKICAgIH0KICB9Cn0=", + // Field Mouse + "ewogICJ0aW1lc3RhbXAiIDogMTcyNzkwNDc5NzQ1OSwKICAicHJvZmlsZUlkIiA6ICI0MmIwOTMyZDUwMWI0MWQ1YTM4YjEwOTcxYTYwYmYxMyIsCiAgInByb2ZpbGVOYW1lIiA6ICJBaXJib2x0MDc4IiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2YzNzllMDkyNTI4MTczMTRiZDBiNjk0ZjdkNTNiNDhhZjJjN2ZhODQ5OTEwOTgwMmE0MWJiMjk0ZDJmOTNlM2UiLAogICAgICAibWV0YWRhdGEiIDogewogICAgICAgICJtb2RlbCIgOiAic2xpbSIKICAgICAgfQogICAgfQogIH0KfQ==" + ); + /** * Cache for mob glow. Absence means the entity does not have custom glow. * If an entity is in the cache, it must have custom glow. @@ -141,6 +166,9 @@ public class MobGlow { // Enderman Slayer's Nukekubi Skulls case ArmorStandEntity armorStand when SkyblockerConfigManager.get().slayers.endermanSlayer.highlightNukekubiHeads && Utils.isInTheEnd() && armorStand.isMarker() && SlayerManager.isInSlayer() && isNukekubiHead(armorStand) -> 0x990099; + // Pests + case ArmorStandEntity armorStand when SkyblockerConfigManager.get().farming.garden.pestHighlighter && Utils.isInGarden() && isPestHead(armorStand) -> 0xb62f00; + // Blaze Slayer's Demonic minions case WitherSkeletonEntity e when SkyblockerConfigManager.get().slayers.highlightBosses == SlayersConfig.HighlightSlayerEntities.GLOW && SlayerManager.isInSlayerType(SlayerType.DEMONLORD) && e.distanceTo(MinecraftClient.getInstance().player) <= 15 -> AttunementColors.getColor(e); case ZombifiedPiglinEntity e when SkyblockerConfigManager.get().slayers.highlightBosses == SlayersConfig.HighlightSlayerEntities.GLOW && SlayerManager.isInSlayerType(SlayerType.DEMONLORD) && e.distanceTo(MinecraftClient.getInstance().player) <= 15 -> AttunementColors.getColor(e); @@ -192,4 +220,13 @@ public class MobGlow { private static boolean isNukekubiHead(ArmorStandEntity entity) { return Streams.stream(entity.getArmorItems()).map(ItemUtils::getHeadTexture).anyMatch(headTexture -> headTexture.contains(NUKEKUBI_HEAD_TEXTURE)); } + + /** + * Compares the armor items of an armor stand to the Pest head texture to determine if it is a Pest head. + */ + private static boolean isPestHead(ArmorStandEntity entity) { + return Streams.stream(entity.getArmorItems()) + .map(ItemUtils::getHeadTexture) + .anyMatch(PEST_HEAD_TEXTURES::contains); + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHud.java b/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHud.java index eea3a3b7..ab1cfe2d 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHud.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHud.java @@ -20,6 +20,7 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtElement; +import net.minecraft.util.Formatting; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,119 +36,129 @@ import java.util.regex.Pattern; import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; public class FarmingHud { - private static final Logger LOGGER = LoggerFactory.getLogger(FarmingHud.class); - public static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance(Locale.US); - private static final Pattern FARMING_XP = Pattern.compile("ยง3\\+(?<xp>\\d+.?\\d*) Farming \\((?<percent>[\\d,]+.?\\d*)%\\)"); - private static final MinecraftClient client = MinecraftClient.getInstance(); - private static CounterType counterType = CounterType.NONE; - private static final Deque<IntLongPair> counter = new ArrayDeque<>(); - private static final LongPriorityQueue blockBreaks = new LongArrayFIFOQueue(); - private static final Queue<FloatLongPair> farmingXp = new ArrayDeque<>(); - private static float farmingXpPercentProgress; - - @Init - public static void init() { - HudRenderEvents.AFTER_MAIN_HUD.register((context, tickCounter) -> { - if (shouldRender()) { - if (!counter.isEmpty() && counter.peek().rightLong() + 5000 < System.currentTimeMillis()) { - counter.poll(); - } - if (!blockBreaks.isEmpty() && blockBreaks.firstLong() + 1000 < System.currentTimeMillis()) { - blockBreaks.dequeueLong(); - } - if (!farmingXp.isEmpty() && farmingXp.peek().rightLong() + 1000 < System.currentTimeMillis()) { - farmingXp.poll(); - } - - ItemStack stack = client.player.getMainHandStack(); - if (stack == null || !tryGetCounter(stack, CounterType.CULTIVATING) && !tryGetCounter(stack, CounterType.COUNTER)) { - counterType = CounterType.NONE; - } - } - }); - ClientPlayerBlockBreakEvents.AFTER.register((world, player, pos, state) -> { - if (shouldRender()) { - blockBreaks.enqueue(System.currentTimeMillis()); - } - }); - ClientReceiveMessageEvents.GAME.register((message, overlay) -> { - if (shouldRender() && overlay) { - Matcher matcher = FARMING_XP.matcher(message.getString()); - if (matcher.matches()) { - try { - farmingXp.offer(FloatLongPair.of(NUMBER_FORMAT.parse(matcher.group("xp")).floatValue(), System.currentTimeMillis())); - farmingXpPercentProgress = NUMBER_FORMAT.parse(matcher.group("percent")).floatValue(); - } catch (ParseException e) { - LOGGER.error("[Skyblocker Farming HUD] Failed to parse farming xp", e); - } - } - } - }); - ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(literal("hud").then(literal("farming") - .executes(Scheduler.queueOpenScreenCommand(() -> new WidgetsConfigurationScreen(Location.GARDEN, "hud_garden", null))))))); - } - - private static boolean tryGetCounter(ItemStack stack, CounterType counterType) { - NbtCompound customData = ItemUtils.getCustomData(stack); - if (customData == null || !customData.contains(counterType.nbtKey, NbtElement.NUMBER_TYPE)) return false; - int count = customData.getInt(counterType.nbtKey); - if (FarmingHud.counterType != counterType) { - counter.clear(); - FarmingHud.counterType = counterType; - } - if (counter.isEmpty() || counter.peekLast().leftInt() != count) { - counter.offer(IntLongPair.of(count, System.currentTimeMillis())); - } - return true; - } - - private static boolean shouldRender() { - return SkyblockerConfigManager.get().farming.garden.farmingHud.enableHud && client.player != null && Utils.getLocation() == Location.GARDEN; - } - - public static String counterText() { - return counterType.text; - } - - public static int counter() { - return counter.isEmpty() ? 0 : counter.peekLast().leftInt(); - } - - public static float cropsPerMinute() { - if (counter.isEmpty()) { - return 0; - } - IntLongPair first = counter.peek(); - IntLongPair last = counter.peekLast(); - return (float) (last.leftInt() - first.leftInt()) / (last.rightLong() - first.rightLong()) * 60_000f; - } - - public static int blockBreaks() { - return blockBreaks.size(); - } - - public static float farmingXpPercentProgress() { - return farmingXpPercentProgress; - } - - public static double farmingXpPerHour() { - return farmingXp.stream().mapToDouble(FloatLongPair::leftFloat).sum() * blockBreaks() * 1800; // Hypixel only sends xp updates around every half a second - } - - public enum CounterType { - NONE("", "No Counter"), - COUNTER("mined_crops", "Counter: "), - CULTIVATING("farmed_cultivating", "Cultivating Counter: "); - - private final String nbtKey; - private final String text; - - CounterType(String nbtKey, String text) { - this.nbtKey = nbtKey; - this.text = text; - } - public boolean matchesText(String textToMatch) { - return this.text.equals(textToMatch); - } - } + private static final Logger LOGGER = LoggerFactory.getLogger(FarmingHud.class); + public static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance(Locale.US); + private static final Pattern FARMING_XP = Pattern.compile("\\+(?<xp>\\d+(?:\\.\\d+)?) Farming \\((?<percent>[\\d,]+(?:\\.\\d+)?%|[\\d,]+/[\\d,]+)\\)"); + private static final MinecraftClient client = MinecraftClient.getInstance(); + private static CounterType counterType = CounterType.NONE; + private static final Deque<IntLongPair> counter = new ArrayDeque<>(); + private static final LongPriorityQueue blockBreaks = new LongArrayFIFOQueue(); + private static final Queue<FloatLongPair> farmingXp = new ArrayDeque<>(); + private static float farmingXpPercentProgress; + + @Init + public static void init() { + HudRenderEvents.AFTER_MAIN_HUD.register((context, tickCounter) -> { + if (shouldRender()) { + if (!counter.isEmpty() && counter.peek().rightLong() + 5000 < System.currentTimeMillis()) { + counter.poll(); + } + if (!blockBreaks.isEmpty() && blockBreaks.firstLong() + 1000 < System.currentTimeMillis()) { + blockBreaks.dequeueLong(); + } + if (!farmingXp.isEmpty() && farmingXp.peek().rightLong() + 1000 < System.currentTimeMillis()) { + farmingXp.poll(); + } + + assert client.player != null; + ItemStack stack = client.player.getMainHandStack(); + if (stack == null || tryGetCounter(stack, CounterType.CULTIVATING) && tryGetCounter(stack, CounterType.COUNTER)) { + counterType = CounterType.NONE; + } + } + }); + ClientPlayerBlockBreakEvents.AFTER.register((world, player, pos, state) -> { + if (shouldRender()) { + blockBreaks.enqueue(System.currentTimeMillis()); + } + }); + ClientReceiveMessageEvents.GAME.register((message, overlay) -> { + if (shouldRender() && overlay) { + Matcher matcher = FARMING_XP.matcher(Formatting.strip(message.getString())); + if (matcher.matches()) { + try { + farmingXp.offer(FloatLongPair.of(NUMBER_FORMAT.parse(matcher.group("xp")).floatValue(), System.currentTimeMillis())); + farmingXpPercentProgress = NUMBER_FORMAT.parse(matcher.group("percent")).floatValue(); + } catch (ParseException e) { + LOGGER.error("[Skyblocker Farming HUD] Failed to parse farming xp", e); + } + } + } + }); + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(literal("hud").then(literal("farming") + .executes(Scheduler.queueOpenScreenCommand(() -> new WidgetsConfigurationScreen(Location.GARDEN, "hud_garden", null))))))); + } + + private static boolean tryGetCounter(ItemStack stack, CounterType counterType) { + NbtCompound customData = ItemUtils.getCustomData(stack); + if (customData.isEmpty() || !customData.contains(counterType.nbtKey, NbtElement.NUMBER_TYPE)) return true; + int count = customData.getInt(counterType.nbtKey); + if (FarmingHud.counterType != counterType) { + counter.clear(); + FarmingHud.counterType = counterType; + } + if (counter.isEmpty() || counter.peekLast().leftInt() != count) { + counter.offer(IntLongPair.of(count, System.currentTimeMillis())); + } + return false; + } + + private static boolean shouldRender() { + return SkyblockerConfigManager.get().farming.garden.farmingHud.enableHud && client.player != null && Utils.getLocation() == Location.GARDEN; + } + + public static String counterText() { + return counterType.text; + } + + public static int counter() { + return counter.isEmpty() ? 0 : counter.peekLast().leftInt(); + } + + public static float cropsPerMinute() { + if (counter.isEmpty()) { + return 0; + } + IntLongPair first = counter.peek(); + IntLongPair last = counter.peekLast(); + return (float) (last.leftInt() - first.leftInt()) / (last.rightLong() - first.rightLong()) * 60_000f; + } + + public static double blockBreaks() { + if (blockBreaks.isEmpty()) { + return 0; + } + long firstTimestamp = blockBreaks.firstLong(); + long lastTimestamp = blockBreaks.lastLong(); + return Math.round((blockBreaks.size() - 1) / (double) (lastTimestamp - firstTimestamp) * 10000) / 10d; + } + + public static float farmingXpPercentProgress() { + return Math.clamp(farmingXpPercentProgress, 0, 100); + } + + public static double farmingXpPerHour() { + if (farmingXp.isEmpty()) { + return 0; + } + return Math.round(farmingXp.peek().leftFloat() * blockBreaks() * 3600 * 10) / 10d; + } + + public enum CounterType { + NONE("", "No Counter"), + COUNTER("mined_crops", "Counter: "), + CULTIVATING("farmed_cultivating", "Cultivating Counter: "); + + private final String nbtKey; + private final String text; + + CounterType(String nbtKey, String text) { + this.nbtKey = nbtKey; + this.text = text; + } + + public boolean matchesText(String textToMatch) { + return this.text.equals(textToMatch); + } + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHudWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHudWidget.java index ab37080f..efe67cc4 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHudWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/garden/FarmingHudWidget.java @@ -94,10 +94,10 @@ public class FarmingHudWidget extends ComponentBasedWidget { float cropsPerMinute = FarmingHud.cropsPerMinute(); addSimpleIcoText(cropStack, "Crops/min: ", Formatting.YELLOW, FarmingHud.NUMBER_FORMAT.format((int) cropsPerMinute / 10 * 10)); addSimpleIcoText(Ico.GOLD, "Coins/h: ", Formatting.GOLD, getPriceText(cropItemId, cropsPerMinute)); - addSimpleIcoText(cropStack, "Blocks/s: ", Formatting.YELLOW, Integer.toString(FarmingHud.blockBreaks())); + addSimpleIcoText(cropStack, "Blocks/s: ", Formatting.YELLOW, Double.toString(FarmingHud.blockBreaks())); //noinspection DataFlowIssue - addComponent(Components.progressComponent(Ico.LANTERN, Text.literal("Farming Level: "), FarmingHud.farmingXpPercentProgress(), Formatting.GOLD.getColorValue())); - addSimpleIcoText(Ico.LIME_DYE, "Farming XP/h: ", Formatting.YELLOW, FarmingHud.NUMBER_FORMAT.format((int) FarmingHud.farmingXpPerHour())); + addComponent(Components.progressComponent(Ico.LANTERN, Text.literal("Farming Level:"), FarmingHud.farmingXpPercentProgress(), Formatting.GOLD.getColorValue())); + addSimpleIcoText(Ico.LIME_DYE, "Farming XP/h: ", Formatting.YELLOW, FarmingHud.NUMBER_FORMAT.format(FarmingHud.farmingXpPerHour())); Entity cameraEntity = client.getCameraEntity(); String yaw = cameraEntity == null ? "No Camera Entity" : String.format("%.2f", MathHelper.wrapDegrees(cameraEntity.getYaw())); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/garden/VisitorHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/garden/VisitorHelper.java deleted file mode 100644 index db946317..00000000 --- a/src/main/java/de/hysky/skyblocker/skyblock/garden/VisitorHelper.java +++ /dev/null @@ -1,224 +0,0 @@ -package de.hysky.skyblocker.skyblock.garden; - -import de.hysky.skyblocker.annotations.Init; -import de.hysky.skyblocker.config.SkyblockerConfigManager; -import de.h |
