From 2ac58b9f9646733acde3b05c0ec2533c37c95080 Mon Sep 17 00:00:00 2001 From: Manchick0 Date: Sat, 28 Dec 2024 15:44:35 +0100 Subject: [PATCH 01/18] Add Speed Presets for configurable speed settings Introduced a Speed Presets system with customizable presets for the rancher boots. Added a GUI to manage presets and integrated support for the `setmaxspeed` command, and the sign-editor to use these presets. Besides all of that, refactored item protection rendering logic to show it everywhere, where applicable, and render it in front of the item, as well as updated the texture being used. --- .../config/categories/GeneralCategory.java | 18 ++ .../config/configs/GeneralConfig.java | 9 + .../mixins/CommandTreeS2CPacketMixin.java | 2 + .../skyblocker/mixins/DrawContextMixin.java | 41 +++- .../skyblocker/mixins/HandledScreenMixin.java | 13 -- .../mixins/SignEditScreenMixin.java | 59 +++-- .../speedPreset/SpeedPresetListWidget.java | 208 ++++++++++++++++++ .../skyblock/speedPreset/SpeedPresets.java | 147 +++++++++++++ .../speedPreset/SpeedPresetsScreen.java | 75 +++++++ .../assets/skyblocker/lang/en_us.json | 6 + .../textures/gui/item_protection.png | Bin 235 -> 204 bytes 11 files changed, 548 insertions(+), 30 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java diff --git a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java index b041a9fe74..944e9d2ec7 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java @@ -8,6 +8,7 @@ import de.hysky.skyblocker.skyblock.item.slottext.SlotTextMode; import de.hysky.skyblocker.skyblock.item.tooltip.adders.CraftPriceTooltip; import de.hysky.skyblocker.skyblock.shortcut.ShortcutsConfigScreen; +import de.hysky.skyblocker.skyblock.speedPreset.SpeedPresetsScreen; import dev.isxander.yacl3.api.*; import dev.isxander.yacl3.api.controller.FloatSliderControllerBuilder; import net.minecraft.client.MinecraftClient; @@ -58,6 +59,23 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig .controller(ConfigUtils::createBooleanController) .build()) + .group(OptionGroup.createBuilder() + .name(Text.translatable("skyblocker.config.general.speedPresets")) + .collapsed(true) + .option(Option.createBuilder() + .name(Text.translatable("skyblocker.config.general.speedPresets.enableSpeedPresets")) + .binding(defaults.general.speedPresets.enableSpeedPresets, + () -> config.general.speedPresets.enableSpeedPresets, + newValue -> config.general.speedPresets.enableSpeedPresets = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(ButtonOption.createBuilder() + .name(Text.translatable("skyblocker.config.general.speedPresets.config")) + .text(Text.translatable("text.skyblocker.open")) + .action((screen, opt) -> MinecraftClient.getInstance().setScreen(new SpeedPresetsScreen(screen))) + .build()) + .build()) + //Shortcuts .group(OptionGroup.createBuilder() .name(Text.translatable("skyblocker.config.general.shortcuts")) diff --git a/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java index 912dd76958..bb66625a5d 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java @@ -22,6 +22,9 @@ public class GeneralConfig { @SerialEntry public boolean acceptReparty = true; + @SerialEntry + public SpeedPresets speedPresets = new SpeedPresets(); + @SerialEntry public Shortcuts shortcuts = new Shortcuts(); @@ -68,6 +71,12 @@ public class GeneralConfig { @SerialEntry public Object2ObjectOpenHashMap customAnimatedDyes = new Object2ObjectOpenHashMap<>(); + public static class SpeedPresets { + + @SerialEntry + public boolean enableSpeedPresets = true; + } + public static class Shortcuts { @SerialEntry public boolean enableShortcuts = true; diff --git a/src/main/java/de/hysky/skyblocker/mixins/CommandTreeS2CPacketMixin.java b/src/main/java/de/hysky/skyblocker/mixins/CommandTreeS2CPacketMixin.java index b96d5a5f83..83605ca95b 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/CommandTreeS2CPacketMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/CommandTreeS2CPacketMixin.java @@ -7,6 +7,7 @@ import de.hysky.skyblocker.skyblock.SackItemAutocomplete; import de.hysky.skyblocker.skyblock.ViewstashAutocomplete; import de.hysky.skyblocker.skyblock.WarpAutocomplete; +import de.hysky.skyblocker.skyblock.speedPreset.SpeedPresets; import de.hysky.skyblocker.utils.Utils; import net.minecraft.command.CommandSource; import org.spongepowered.asm.mixin.Mixin; @@ -18,6 +19,7 @@ public class CommandTreeS2CPacketMixin { public CommandNode modifyCommandSuggestions(CommandNode original) { if (Utils.isOnHypixel() && original instanceof LiteralCommandNode literalCommandNode) { return switch (literalCommandNode.getLiteral()) { + case String s when s.equals("setmaxspeed") -> SpeedPresets.getCommandNode(); case String s when s.equals("warp") && WarpAutocomplete.commandNode != null -> WarpAutocomplete.commandNode; case String s when s.equals("getfromsacks") && SackItemAutocomplete.longCommandNode != null -> SackItemAutocomplete.longCommandNode; case String s when s.equals("gfs") && SackItemAutocomplete.shortCommandNode != null -> SackItemAutocomplete.shortCommandNode; diff --git a/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java b/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java index 56a5183a91..cf3bac50d5 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java @@ -2,17 +2,56 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; +import com.mojang.blaze3d.systems.RenderSystem; +import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.skyblock.item.ItemCooldowns; +import de.hysky.skyblocker.skyblock.item.ItemProtection; import de.hysky.skyblocker.utils.Utils; +import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; +import net.minecraft.util.Identifier; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.function.Function; @Mixin(DrawContext.class) public abstract class DrawContextMixin { - @ModifyExpressionValue(method = "drawCooldownProgress", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/ItemCooldownManager;getCooldownProgress(Lnet/minecraft/item/ItemStack;F)F")) + + @Unique + private static final Identifier ITEM_PROTECTION = Identifier.of(SkyblockerMod.NAMESPACE, "textures/gui/item_protection.png"); + + @Shadow + public abstract void drawTexture(Function renderLayers, Identifier sprite, int x, int y, float u, float v, int width, int height, int textureWidth, int textureHeight); + + @Shadow + public abstract MatrixStack getMatrices(); + + @ModifyExpressionValue(method = "drawCooldownProgress", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/ItemCooldownManager;getCooldownProgress(Lnet/minecraft/item/ItemStack;F)F")) private float skyblocker$modifyItemCooldown(float cooldownProgress, @Local(argsOnly = true) ItemStack stack) { return Utils.isOnSkyblock() && ItemCooldowns.isOnCooldown(stack) ? ItemCooldowns.getItemCooldownEntry(stack).getRemainingCooldownPercent() : cooldownProgress; } + + @Inject(method = "drawStackOverlay(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawCooldownProgress(Lnet/minecraft/item/ItemStack;II)V", + shift = At.Shift.AFTER)) + private void skyblocker$onDrawStackOverlay(TextRenderer textRenderer, ItemStack stack, int x, int y, String stackCountText, CallbackInfo ci) { + if (ItemProtection.isItemProtected(stack)) { + RenderSystem.enableBlend(); + var matrices = this.getMatrices(); + matrices.push(); + matrices.translate(x, y, 233); + matrices.scale(0.5F, 0.5F, 1F); + this.drawTexture(RenderLayer::getGuiTextured, ITEM_PROTECTION, 16, 16, 0, 0, 16, 16, 16, 16); + matrices.pop(); + RenderSystem.disableBlend(); + } + } } diff --git a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java index c833d06c5d..a0c6922e45 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java @@ -2,9 +2,7 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; -import com.mojang.blaze3d.systems.RenderSystem; -import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.config.SkyblockerConfig; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.InventorySearch; @@ -28,7 +26,6 @@ import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.widget.ClickableWidget; -import net.minecraft.client.render.RenderLayer; import net.minecraft.inventory.SimpleInventory; import net.minecraft.item.ItemStack; import net.minecraft.screen.GenericContainerScreenHandler; @@ -36,7 +33,6 @@ import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.SlotActionType; import net.minecraft.text.Text; -import net.minecraft.util.Identifier; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; @@ -63,9 +59,6 @@ public abstract class HandledScreenMixin extends Screen @Unique private static final int OUT_OF_BOUNDS_SLOT = -999; - @Unique - private static final Identifier ITEM_PROTECTION = Identifier.of(SkyblockerMod.NAMESPACE, "textures/gui/item_protection.png"); - @Unique private static final Set FILLER_ITEMS = Set.of( " ", // Empty menu item @@ -335,12 +328,6 @@ protected HandledScreenMixin(Text title) { private void skyblocker$drawOnItem(DrawContext context, Slot slot, CallbackInfo ci) { if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.itemInfoDisplay.itemRarityBackgrounds) ItemRarityBackgrounds.tryDraw(slot.getStack(), context, slot.x, slot.y); - // Item protection - if (ItemProtection.isItemProtected(slot.getStack())) { - RenderSystem.enableBlend(); - context.drawTexture(RenderLayer::getGuiTextured, ITEM_PROTECTION, slot.x, slot.y, 0, 0, 16, 16, 16, 16); - RenderSystem.disableBlend(); - } // Search // Darken the slots if (InventorySearch.isSearching() && !InventorySearch.slotMatches(slot)) { diff --git a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java index 04342f3793..14769a7618 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/SignEditScreenMixin.java @@ -3,9 +3,13 @@ import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.calculators.SignCalculator; +import de.hysky.skyblocker.skyblock.speedPreset.SpeedPresets; import de.hysky.skyblocker.utils.Utils; import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.AbstractSignEditScreen; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -15,32 +19,55 @@ import com.llamalad7.mixinextras.sugar.Local; -import java.util.Objects; - @Mixin(AbstractSignEditScreen.class) -public abstract class SignEditScreenMixin { +public abstract class SignEditScreenMixin extends Screen { + @Shadow @Final private String[] messages; - @Inject(method = "render", at = @At("HEAD")) + protected SignEditScreenMixin(Text title) { + super(title); + } + + @Inject(method = "render", at = @At("HEAD")) private void skyblocker$render(CallbackInfo ci, @Local(argsOnly = true) DrawContext context) { - //if the sign is being used to enter number send it to the sign calculator - if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().uiAndVisuals.inputCalculator.enabled && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { - SignCalculator.renderCalculator(context, messages[0], context.getScaledWindowWidth() / 2, 55); - } + if (Utils.isOnSkyblock()) { + var config = SkyblockerConfigManager.get(); + if (messages[1].equals("^^^^^^") && config.general.speedPresets.enableSpeedPresets) { + var presets = SpeedPresets.getInstance(); + if (presets.hasPreset(messages[0])) { + context.drawCenteredTextWithShadow(this.textRenderer, Text.literal(String.format("%s ยป %d", messages[0], presets.getPreset(messages[0]))).formatted(Formatting.GREEN), + context.getScaledWindowWidth() / 2, 55, 0xFFFFFFFF); + } + } + //if the sign is being used to enter number send it to the sign calculator + if (messages[1].equals("^^^^^^^^^^^^^^^") && config.uiAndVisuals.inputCalculator.enabled) { + SignCalculator.renderCalculator(context, messages[0], context.getScaledWindowWidth() / 2, 55); + } + } } @Inject(method = "finishEditing", at = @At("HEAD")) private void skyblocker$finishEditing(CallbackInfo ci) { - //if the sign is being used to enter number get number from calculator for if maths has been done - if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().uiAndVisuals.inputCalculator.enabled && Objects.equals(messages[1], "^^^^^^^^^^^^^^^")) { - boolean isPrice = messages[2].contains("price"); - String value = SignCalculator.getNewValue(isPrice); - if (value.length() >= 15) { - value = value.substring(0, 15); - } - messages[0] = value; + var config = SkyblockerConfigManager.get(); + if (Utils.isOnSkyblock()) { + //if the sign is being used to enter the speed cap, retrieve the value from speed presets. + if (messages[1].equals("^^^^^^") && config.general.speedPresets.enableSpeedPresets) { + var presets = SpeedPresets.getInstance(); + if (presets.hasPreset(messages[0])) { + messages[0] = String.valueOf(presets.getPreset(messages[0])); + } + } + //if the sign is being used to enter number get number from calculator for if maths has been done + if (messages[1].equals("^^^^^^^^^^^^^^^") && config.uiAndVisuals.inputCalculator.enabled) { + boolean isPrice = messages[2].contains("price"); + String value = SignCalculator.getNewValue(isPrice); + if (value.length() >= 15) { + value = value.substring(0, 15); + } + messages[0] = value; + } } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java new file mode 100644 index 0000000000..c2ddbd083b --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java @@ -0,0 +1,208 @@ +package de.hysky.skyblocker.skyblock.speedPreset; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.Drawable; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.Selectable; +import net.minecraft.client.gui.widget.*; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.regex.Pattern; + +public class SpeedPresetListWidget extends ElementListWidget { + + private static final Pattern NUMBER = Pattern.compile("^-?\\d+(\\.\\d+)?$"); + // Alphanumeric sequence that doesn't start with a number. + private static final Pattern TITLE = Pattern.compile("^[a-zA-Z][a-zA-Z0-9_]*$"); + private static final Logger LOGGER = LoggerFactory.getLogger(SpeedPresetListWidget.class); + + public SpeedPresetListWidget(int width, int height, int y) { + super(MinecraftClient.getInstance(), width, height, y, 25); + var presets = SpeedPresets.getInstance(); + addEntry(new TitleEntry()); + if (presets.getPresetCount() > 0) + presets.forEach((title, speed) -> + this.addEntry(new SpeedPresetEntry(title, String.valueOf(speed)))); + else + this.addEntry(new SpeedPresetEntry("", "")); + } + + @Override + public int getRowWidth() { + return super.getRowWidth() + 104; + } + + /** + * Checks whether the state of the widget has been modified compared to the preset data. + *

+ * This method determines if any of the following conditions are met: + *

    + *
  • The number of children entries in the widget is less than the current number of presets.
  • + *
  • An entry has been modified.
  • + *
  • The number of entries worth saving does not match the number of presets.
  • + *
+ * + * @return true if the state has been modified; false otherwise. + */ + public boolean hasBeenChanged() { + var presets = SpeedPresets.getInstance().getPresetCount(); + // Accounting 1 for the title entry. + var children = children().size() - 1; + if (children < presets) return true; + + children = 0; + for (var child : children()) { + if (child.hasBeenModified()) return true; + if (child instanceof SpeedPresetEntry entry) { + children = entry.isEmpty() ? children : children + 1; + } + } + return children != presets; + } + + public void updatePosition() { + children().forEach(AbstractEntry::updatePosition); + } + + public void newEntry() { + var entry = new SpeedPresetEntry("", ""); + this.addEntry(entry); + this.centerScrollOn(entry); + this.setSelected(entry); + this.setFocused(entry); + } + + public void save() { + var presets = SpeedPresets.getInstance(); + presets.clear(); + children().forEach(entry -> { + if (entry instanceof SpeedPresetEntry speedPresetEntry) + speedPresetEntry.save(); + }); + presets.savePresets(); // Write down the changes. + } + + public abstract static class AbstractEntry extends ElementListWidget.Entry { + + protected boolean hasBeenModified() { + return false; + } + + protected void updatePosition(){} + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + this.children().forEach(child -> { + if (child instanceof Widget widget) + widget.setY(y); + if (child instanceof Drawable drawable) + drawable.render(context, mouseX, mouseY, tickDelta); + }); + } + } + + public class TitleEntry extends AbstractEntry { + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + var renderer = SpeedPresetListWidget.this.client.textRenderer; + // The line height is 25, the height of a single character is always 9. + // 25 - 9 = 16, 16 / 2 = 8, therefore the Y-offset should be 8. + context.drawCenteredTextWithShadow(renderer, Text.translatable("skyblocker.config.general.speedPresets.config.title"), width / 2 - 50, y + 8, 0xFFFFFF); + context.drawCenteredTextWithShadow(renderer, Text.translatable("skyblocker.config.general.speedPresets.config.speed"), width / 2 + 50, y + 8, 0xFFFFFF); + } + + @Override + public List selectableChildren() { + return List.of(); + } + + @Override + public List children() { + return List.of(); + } + } + + public class SpeedPresetEntry extends AbstractEntry { + + protected final TextFieldWidget titleInput; + protected final TextFieldWidget speedInput; + protected final ButtonWidget removeButton; + + protected boolean hasBeenModified; + + public SpeedPresetEntry(String title, String speed) { + var client = SpeedPresetListWidget.this.client; + + // All Xs and Ys are then set using the initPosition() method. + this.titleInput = new TextFieldWidget(client.textRenderer, 0, 0, 120, 20, Text.empty()); + this.titleInput.setTextPredicate(str -> str.isEmpty() || TITLE.matcher(str).matches()); + this.titleInput.setText(title); + this.titleInput.setMaxLength(16); + this.titleInput.setPlaceholder(Text.literal("newPreset").formatted(Formatting.DARK_GRAY)); + this.titleInput.setChangedListener(str -> this.hasBeenModified = true); + this.speedInput = new TextFieldWidget(client.textRenderer, 0, 0, 50, 20, Text.empty()); + + this.speedInput.setTextPredicate(str -> str.isEmpty() || NUMBER.matcher(str).matches()); + this.speedInput.setText(speed); + this.speedInput.setMaxLength(3); + this.speedInput.setPlaceholder(Text.literal("0").formatted(Formatting.DARK_GRAY)); + this.speedInput.setChangedListener(str -> this.hasBeenModified = true); + + this.removeButton = ButtonWidget.builder(Text.literal("-"), (btn) -> { + SpeedPresetListWidget.this.removeEntry(this); + }).dimensions(0, 0, 20, 20).build(); + + this.hasBeenModified = false; + this.updatePosition(); + } + + @Override + public List selectableChildren() { + return List.of(titleInput, speedInput, removeButton); + } + + @Override + public List children() { + return List.of(titleInput, speedInput, removeButton); + } + + public void save() { + var presets = SpeedPresets.getInstance(); + assert presets != null && children().size() == 3; + var title = ((TextFieldWidget) children().get(0)).getText(); + var speed = ((TextFieldWidget) children().get(1)).getText(); + if (title.isEmpty()) return; + try { + presets.setPreset(title, Short.parseShort(speed)); + } catch (NumberFormatException e) { + LOGGER.warn("Couldn't save speed preset '{}' because of an invalid speed value: {}", title, speed); + } + } + + protected boolean isEmpty() { + return titleInput.getText().isEmpty() && speedInput.getText().isEmpty(); + } + + @Override + protected void updatePosition() { + var grid = new GridWidget(); + grid.setSpacing(2); + grid.add(titleInput, 0, 0, 1, 3); + grid.add(speedInput, 0, 3, 1, 2); + grid.add(removeButton, 0, 5, 1, 1); + grid.refreshPositions(); + SimplePositioningWidget.setPos(grid, 0, 0, width, itemHeight, 0.5f, 0.5f); + } + + @Override + protected boolean hasBeenModified() { + return hasBeenModified; + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java new file mode 100644 index 0000000000..2efc9ef33a --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java @@ -0,0 +1,147 @@ +package de.hysky.skyblocker.skyblock.speedPreset; + +import com.google.common.io.Files; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.tree.CommandNode; +import com.mojang.serialization.Codec; +import com.mojang.serialization.JsonOps; +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.annotations.Init; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.Utils; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.fabricmc.fabric.api.client.message.v1.ClientSendMessageEvents; +import net.minecraft.command.CommandSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.regex.Pattern; + +public class SpeedPresets { + + private static final Pattern COMMAND_PATTERN = Pattern.compile("^setmaxspeed\\s([a-zA-Z][a-zA-Z0-9_]*)$"); + + private static final Logger LOGGER = LoggerFactory.getLogger(SpeedPresets.class); + private static final Codec> MAP_CODEC = Codec.unboundedMap(Codec.STRING, Codec.SHORT); + private static final File PRESETS_FILE = new File(SkyblockerMod.CONFIG_DIR.toFile(), "speed_presets.json"); + + private static SpeedPresets instance; + + private final Map presets; + + private SpeedPresets() { + this.presets = new LinkedHashMap<>(); + this.loadPresets(); + } + + public static SpeedPresets getInstance() { + return instance == null ? instance = new SpeedPresets() : instance; + } + + public static CommandNode getCommandNode() { + return ClientCommandManager.literal("setmaxspeed") + .requires(client -> Utils.isOnSkyblock()) + .then(ClientCommandManager.argument("preset", StringArgumentType.string()) + .suggests((ctx, builder) -> { + if (SkyblockerConfigManager.get().general.speedPresets.enableSpeedPresets) { + return CommandSource.suggestMatching(getInstance().presets.keySet(), builder); + } + return builder.buildFuture(); + })).build(); + } + + @Init + public static void init() { + ClientSendMessageEvents.MODIFY_COMMAND.register((command) -> { + var matcher = COMMAND_PATTERN.matcher(command); + if (matcher.matches() && SkyblockerConfigManager.get().general.speedPresets.enableSpeedPresets) { + var presets = getInstance(); + var preset = matcher.group(1); + if (presets.presets.containsKey(preset)) { + return String.format("setmaxspeed %d", presets.getPreset(preset)); + } + } + return command; + }); + } + + public void clear() { + this.presets.clear(); + } + + public Set> entries() { + return this.presets.entrySet(); + } + + public boolean hasPreset(String name) { + return this.presets.containsKey(name); + } + + public short getPreset(String name) { + return this.presets.getOrDefault(name, (short) 0); + } + + public void setPreset(String name, short value) { + this.presets.put(name, value); + savePresets(); + } + + public void forEach(BiConsumer consumer) { + this.presets.forEach(consumer); + } + + public int getPresetCount() { + return this.presets.size(); + } + + public void loadPresets() { + try (var reader = Files.newReader(PRESETS_FILE, StandardCharsets.UTF_8)) { + var element = JsonParser.parseReader(reader); + var map = MAP_CODEC.decode(JsonOps.INSTANCE, element).resultOrPartial(LOGGER::warn); + map.ifPresent(mapResult -> this.presets.putAll(mapResult.getFirst())); + } catch (FileNotFoundException e) { + LOGGER.warn("Couldn't find speed presets file, creating one automatically..."); + this.loadDefaults(); + this.savePresets(); + } catch (IOException e) { + LOGGER.warn("Couldn't load speed presets: ", e); + } + } + + @SuppressWarnings("ResultOfMethodCallIgnored") + public void savePresets() { + try { + if (!PRESETS_FILE.exists()) PRESETS_FILE.createNewFile(); + try (var writer = Files.newWriter(PRESETS_FILE, StandardCharsets.UTF_8)) { + var element = MAP_CODEC.encodeStart(JsonOps.INSTANCE, this.presets).resultOrPartial(LOGGER::warn) + .orElse(new JsonObject()); + writer.write(SkyblockerMod.GSON.toJson(element) + "\n"); + } + } catch (IOException e) { + LOGGER.warn("Couldn't create speed presets file: ", e); + } + } + + // According to: https://www.reddit.com/r/HypixelSkyblock/comments/14kkz07/speed_vs_farming_fortune/ + public void loadDefaults() { + this.presets.clear(); + this.presets.put("default", (short) 100); + this.presets.put("crops", (short) 93); + this.presets.put("cocoa", (short) 155); + this.presets.put("mushroom", (short) 233); + this.presets.put("cane", (short) 327); + this.presets.put("squash", (short) 327); + this.presets.put("cactus", (short) 464); + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java new file mode 100644 index 0000000000..688d15a227 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java @@ -0,0 +1,75 @@ +package de.hysky.skyblocker.skyblock.speedPreset; + +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ConfirmScreen; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.*; +import net.minecraft.screen.ScreenTexts; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +public class SpeedPresetsScreen extends Screen { + + protected final Screen parent; + protected SpeedPresetListWidget list; + + public SpeedPresetsScreen(Screen parent) { + super(Text.translatable("skyblocker.config.general.speedPresets.config")); + this.parent = parent; + } + + @Override + protected void init() { + if (this.list == null) + this.list = new SpeedPresetListWidget(0, 0, 24); + this.list.setDimensions(this.width, this.height - 24 - 32); + this.list.updatePosition(); + this.addDrawableChild(this.list); + + var grid = new GridWidget(); + grid.setSpacing(4); + var doneButton = ButtonWidget.builder(ScreenTexts.DONE, + button -> { + this.list.save(); + assert this.client != null; + this.client.setScreen(parent); + }) + .dimensions(0, 0, Math.max(textRenderer.getWidth(ScreenTexts.DONE) + 8, 100), 20) + .build(); + grid.add(doneButton, 0, 0, 1, 2); + var plusButton = ButtonWidget.builder(Text.literal("+"), + button -> list.newEntry()) + .dimensions(0, 0, 20, 20) + .build(); + grid.add(plusButton, 0, 2, 1, 1); + grid.refreshPositions(); + SimplePositioningWidget.setPos(grid, 0, this.height - 24, this.width, 24, 0.5f, 0.5f); + grid.forEachChild(this::addDrawableChild); + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + super.render(context, mouseX, mouseY, delta); + assert this.client != null; + var renderer = this.client.textRenderer; + context.drawCenteredTextWithShadow(renderer, this.title, this.width / 2, + 8, 0xFFFFFF); + } + + @Override + public void close() { + assert this.client != null; + if (this.list.hasBeenChanged()) { + client.setScreen(new ConfirmScreen(callback -> { + if (callback) { + this.client.setScreen(parent); + } else { + this.client.setScreen(this); + } + }, Text.translatable("text.skyblocker.quit_config"), Text.translatable("text.skyblocker.quit_config_sure"), Text.translatable("text.skyblocker.quit_discard") + .formatted(Formatting.RED), ScreenTexts.CANCEL)); + return; + } + this.client.setScreen(parent); + } +} diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index f1575d0280..8181ae1c63 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -332,6 +332,12 @@ "skyblocker.config.general.searchOverlay.maxPet": "Max Pet Level", "skyblocker.config.general.searchOverlay.maxPet.@Tooltip": "Only show pets that are max level", + "skyblocker.config.general.speedPresets": "Speed Presets", + "skyblocker.config.general.speedPresets.config": "Speed Presets Config...", + "skyblocker.config.general.speedPresets.config.title": "Title", + "skyblocker.config.general.speedPresets.config.speed": "Speed", + "skyblocker.config.general.speedPresets.enableSpeedPresets": "Enable Speed Presets", + "skyblocker.config.general.shortcuts": "Shortcuts", "skyblocker.config.general.shortcuts.config": "Shortcuts Config...", "skyblocker.config.general.shortcuts.enableCommandArgShortcuts": "Enable Command Argument Shortcuts", diff --git a/src/main/resources/assets/skyblocker/textures/gui/item_protection.png b/src/main/resources/assets/skyblocker/textures/gui/item_protection.png index b76fe034481ab5321bbd13cb80b86f32a99aab6a..847840fe53353e3922b3eb648bb684c90a12d6e9 100644 GIT binary patch literal 204 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|+B{txLo9le z6C_v{H+Tf>d2e)h|Nr8D|9{&*x8EfrytHlegUNrsUU~EX^5S^OC08d)N=RG^IJ#!1 zvV%fB^s#QAV)33p?&+e z|I+-Dk|s|SryaT>8ol1g$UuODS;FC3!<(8_3=C19Y|a{;FJB0B5re0zpUXO@geCxh CI8}TA literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCikh0(?STKm1?y;XlKNyFfkzWB&HNAax}{e!>6$|7UQ}TKNUY=PdAuEM{Qf zI}E~%$MaXD00r$lT^vI!{NMIzi!m5*9KKcb-@3oQt@ET{qo*9h?hTF`9X~n>6mdE1 zV`->fet*I&DZeH2>lT=>=_P-0tT2|HQ_8&~s Date: Sun, 29 Dec 2024 02:15:13 +0100 Subject: [PATCH 02/18] Reverted the proposed changes to the protected item texture I apologize for the changes, since I didn't know that the texture was applied elsewhere. This commit reverts all the changes to the size of the texture and the way it is rendered, to hopefully prevent any issues. --- .../skyblocker/mixins/DrawContextMixin.java | 38 ------------------ .../skyblocker/mixins/HandledScreenMixin.java | 10 +++++ .../textures/gui/item_protection.png | Bin 204 -> 250 bytes 3 files changed, 10 insertions(+), 38 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java b/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java index cf3bac50d5..0e6c851656 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java @@ -2,56 +2,18 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; -import com.mojang.blaze3d.systems.RenderSystem; -import de.hysky.skyblocker.SkyblockerMod; import de.hysky.skyblocker.skyblock.item.ItemCooldowns; -import de.hysky.skyblocker.skyblock.item.ItemProtection; import de.hysky.skyblocker.utils.Utils; -import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemStack; -import net.minecraft.util.Identifier; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.function.Function; @Mixin(DrawContext.class) public abstract class DrawContextMixin { - @Unique - private static final Identifier ITEM_PROTECTION = Identifier.of(SkyblockerMod.NAMESPACE, "textures/gui/item_protection.png"); - - @Shadow - public abstract void drawTexture(Function renderLayers, Identifier sprite, int x, int y, float u, float v, int width, int height, int textureWidth, int textureHeight); - - @Shadow - public abstract MatrixStack getMatrices(); - @ModifyExpressionValue(method = "drawCooldownProgress", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/ItemCooldownManager;getCooldownProgress(Lnet/minecraft/item/ItemStack;F)F")) private float skyblocker$modifyItemCooldown(float cooldownProgress, @Local(argsOnly = true) ItemStack stack) { return Utils.isOnSkyblock() && ItemCooldowns.isOnCooldown(stack) ? ItemCooldowns.getItemCooldownEntry(stack).getRemainingCooldownPercent() : cooldownProgress; } - - @Inject(method = "drawStackOverlay(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawCooldownProgress(Lnet/minecraft/item/ItemStack;II)V", - shift = At.Shift.AFTER)) - private void skyblocker$onDrawStackOverlay(TextRenderer textRenderer, ItemStack stack, int x, int y, String stackCountText, CallbackInfo ci) { - if (ItemProtection.isItemProtected(stack)) { - RenderSystem.enableBlend(); - var matrices = this.getMatrices(); - matrices.push(); - matrices.translate(x, y, 233); - matrices.scale(0.5F, 0.5F, 1F); - this.drawTexture(RenderLayer::getGuiTextured, ITEM_PROTECTION, 16, 16, 0, 0, 16, 16, 16, 16); - matrices.pop(); - RenderSystem.disableBlend(); - } - } } diff --git a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java index a0c6922e45..2c9febc241 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java @@ -3,6 +3,7 @@ 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; import de.hysky.skyblocker.skyblock.InventorySearch; @@ -26,6 +27,7 @@ import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.widget.ClickableWidget; +import net.minecraft.client.render.RenderLayer; import net.minecraft.inventory.SimpleInventory; import net.minecraft.item.ItemStack; import net.minecraft.screen.GenericContainerScreenHandler; @@ -95,6 +97,8 @@ public abstract class HandledScreenMixin extends Screen @Shadow protected abstract List getTooltipFromItem(ItemStack stack); + @Shadow + private boolean touchIsRightClickDrag; @Unique private List quickNavButtons; @@ -328,6 +332,12 @@ protected HandledScreenMixin(Text title) { private void skyblocker$drawOnItem(DrawContext context, Slot slot, CallbackInfo ci) { if (Utils.isOnSkyblock() && SkyblockerConfigManager.get().general.itemInfoDisplay.itemRarityBackgrounds) ItemRarityBackgrounds.tryDraw(slot.getStack(), context, slot.x, slot.y); + // Item Protection + if (ItemProtection.isItemProtected(slot.getStack())) { + RenderSystem.enableBlend(); + context.drawTexture(RenderLayer::getGuiTextured, ItemProtection.ITEM_PROTECTION_TEX, slot.x, slot.y, 0, 0, 16, 16, 16, 16); + RenderSystem.disableBlend(); + } // Search // Darken the slots if (InventorySearch.isSearching() && !InventorySearch.slotMatches(slot)) { diff --git a/src/main/resources/assets/skyblocker/textures/gui/item_protection.png b/src/main/resources/assets/skyblocker/textures/gui/item_protection.png index 847840fe53353e3922b3eb648bb684c90a12d6e9..6d6016e1c08524eeccfd25e88c829867a8e0feaa 100644 GIT binary patch literal 250 zcmVPx#v`IukR9J=W(jgAQKoEuDzl2~oLPaG_c6AL$=p~wvZ~;yLs)wkcvONT@21^C5 zLF^G~Dmu6lAS9TrnorJ%w=+ASlu}A5rIb=L8Ksa>3i+%r<_JGrZa;fVpTUDm#5FzP zW(VxwYuh!e@EZ8c2Ov+4bhVMeB{H}~y4pydn&~V2zkt`&z}Mv7Zy>W)T+>sPP?g}C zp3K^5172?cAdZCNDd60;0l@uXC5{AI-^qV^0=QX1S$Y2Vq5uE@07*qoM6N<$f??Zb A?*IS* literal 204 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|+B{txLo9le z6C_v{H+Tf>d2e)h|Nr8D|9{&*x8EfrytHlegUNrsUU~EX^5S^OC08d)N=RG^IJ#!1 zvV%fB^s#QAV)33p?&+e z|I+-Dk|s|SryaT>8ol1g$UuODS;FC3!<(8_3=C19Y|a{;FJB0B5re0zpUXO@geCxh CI8}TA From 919f9b8eb5c28dcadddcc98e63cf5623577d97fa Mon Sep 17 00:00:00 2001 From: Wanja <105125277+Manchick0@users.noreply.github.com> Date: Sun, 29 Dec 2024 23:40:06 +0100 Subject: [PATCH 03/18] Update src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java Co-authored-by: Kevin <92656833+kevinthegreat1@users.noreply.github.com> --- .../skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java index 688d15a227..622c3d5720 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java @@ -60,8 +60,8 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { public void close() { assert this.client != null; if (this.list.hasBeenChanged()) { - client.setScreen(new ConfirmScreen(callback -> { - if (callback) { + client.setScreen(new ConfirmScreen(confirmedAction -> { + if (confirmedAction) { this.client.setScreen(parent); } else { this.client.setScreen(this); From 50774d4a02960448760a6707066c58db2fcc5283 Mon Sep 17 00:00:00 2001 From: Wanja <105125277+Manchick0@users.noreply.github.com> Date: Sun, 29 Dec 2024 23:40:20 +0100 Subject: [PATCH 04/18] Update src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java Co-authored-by: Kevin <92656833+kevinthegreat1@users.noreply.github.com> --- .../skyblock/speedPreset/SpeedPresetListWidget.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java index c2ddbd083b..e7cef4055b 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java @@ -80,10 +80,7 @@ public void newEntry() { public void save() { var presets = SpeedPresets.getInstance(); presets.clear(); - children().forEach(entry -> { - if (entry instanceof SpeedPresetEntry speedPresetEntry) - speedPresetEntry.save(); - }); + children().stream().filter(SpeedPresetEntry.class::isInstance).map(SpeedPresetEntry.class::cast).forEach(SpeedPresetEntry::save); presets.savePresets(); // Write down the changes. } From 4dd9fb62e4b4b8479b6da35c5f6b29c68c4c58ab Mon Sep 17 00:00:00 2001 From: Wanja <105125277+Manchick0@users.noreply.github.com> Date: Sun, 29 Dec 2024 23:40:29 +0100 Subject: [PATCH 05/18] Update src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java Co-authored-by: Kevin <92656833+kevinthegreat1@users.noreply.github.com> --- .../de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java index 2efc9ef33a..f6ea7b21e8 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java @@ -129,7 +129,7 @@ public void savePresets() { writer.write(SkyblockerMod.GSON.toJson(element) + "\n"); } } catch (IOException e) { - LOGGER.warn("Couldn't create speed presets file: ", e); + LOGGER.error("[Skyblocker Speed Presets] Couldn't create speed presets file", e); } } From 1aa8859c5cff2b42b06ea8150a27f1ae4ca8b01f Mon Sep 17 00:00:00 2001 From: Wanja <105125277+Manchick0@users.noreply.github.com> Date: Sun, 29 Dec 2024 23:40:40 +0100 Subject: [PATCH 06/18] Update src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java Co-authored-by: Kevin <92656833+kevinthegreat1@users.noreply.github.com> --- .../skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java index 622c3d5720..aecffe7477 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java @@ -34,7 +34,7 @@ protected void init() { assert this.client != null; this.client.setScreen(parent); }) - .dimensions(0, 0, Math.max(textRenderer.getWidth(ScreenTexts.DONE) + 8, 100), 20) + .width(Math.max(textRenderer.getWidth(ScreenTexts.DONE) + 8, 100)) .build(); grid.add(doneButton, 0, 0, 1, 2); var plusButton = ButtonWidget.builder(Text.literal("+"), From d36930b8baad01903b12638f9ad8894af22ccfdf Mon Sep 17 00:00:00 2001 From: Wanja <105125277+Manchick0@users.noreply.github.com> Date: Sun, 29 Dec 2024 23:40:54 +0100 Subject: [PATCH 07/18] Update src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java Co-authored-by: Kevin <92656833+kevinthegreat1@users.noreply.github.com> --- .../skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java index aecffe7477..2f7d462be7 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetsScreen.java @@ -39,7 +39,7 @@ protected void init() { grid.add(doneButton, 0, 0, 1, 2); var plusButton = ButtonWidget.builder(Text.literal("+"), button -> list.newEntry()) - .dimensions(0, 0, 20, 20) + .width(20) .build(); grid.add(plusButton, 0, 2, 1, 1); grid.refreshPositions(); From 617084ca74dd173c21e9144e2b57bae8eb07b957 Mon Sep 17 00:00:00 2001 From: Wanja <105125277+Manchick0@users.noreply.github.com> Date: Sun, 29 Dec 2024 23:41:23 +0100 Subject: [PATCH 08/18] Update src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java Co-authored-by: Kevin <92656833+kevinthegreat1@users.noreply.github.com> --- .../skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java index e7cef4055b..06d933de66 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java @@ -107,7 +107,6 @@ public class TitleEntry extends AbstractEntry { @Override public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { - var renderer = SpeedPresetListWidget.this.client.textRenderer; // The line height is 25, the height of a single character is always 9. // 25 - 9 = 16, 16 / 2 = 8, therefore the Y-offset should be 8. context.drawCenteredTextWithShadow(renderer, Text.translatable("skyblocker.config.general.speedPresets.config.title"), width / 2 - 50, y + 8, 0xFFFFFF); From 947c21bdff901ef0973c7c1b750b9cffb639ab43 Mon Sep 17 00:00:00 2001 From: Wanja <105125277+Manchick0@users.noreply.github.com> Date: Sun, 29 Dec 2024 23:44:46 +0100 Subject: [PATCH 09/18] Update src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java Co-authored-by: Kevin <92656833+kevinthegreat1@users.noreply.github.com> --- .../de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java index f6ea7b21e8..ce115b33e0 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java @@ -108,8 +108,7 @@ public int getPresetCount() { public void loadPresets() { try (var reader = Files.newReader(PRESETS_FILE, StandardCharsets.UTF_8)) { var element = JsonParser.parseReader(reader); - var map = MAP_CODEC.decode(JsonOps.INSTANCE, element).resultOrPartial(LOGGER::warn); - map.ifPresent(mapResult -> this.presets.putAll(mapResult.getFirst())); + MAP_CODEC.parse(JsonOps.INSTANCE, element).resultOrPartial(LOGGER::error).ifPresent(this.presets::putAll); } catch (FileNotFoundException e) { LOGGER.warn("Couldn't find speed presets file, creating one automatically..."); this.loadDefaults(); From 5c4d6ee60da3b4567ff1a5b153bedea73c1f508b Mon Sep 17 00:00:00 2001 From: Wanja <105125277+Manchick0@users.noreply.github.com> Date: Sun, 29 Dec 2024 23:45:02 +0100 Subject: [PATCH 10/18] Update src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java Co-authored-by: Kevin <92656833+kevinthegreat1@users.noreply.github.com> --- .../de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java index ce115b33e0..c28bfc408e 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java @@ -110,7 +110,7 @@ public void loadPresets() { var element = JsonParser.parseReader(reader); MAP_CODEC.parse(JsonOps.INSTANCE, element).resultOrPartial(LOGGER::error).ifPresent(this.presets::putAll); } catch (FileNotFoundException e) { - LOGGER.warn("Couldn't find speed presets file, creating one automatically..."); + LOGGER.warn("[Skyblocker Speed Presets] Couldn't find speed presets file, creating one automatically..."); this.loadDefaults(); this.savePresets(); } catch (IOException e) { From 6a4b474714fa019493f485200aa3bdf5f8b791cf Mon Sep 17 00:00:00 2001 From: Wanja <105125277+Manchick0@users.noreply.github.com> Date: Sun, 29 Dec 2024 23:45:17 +0100 Subject: [PATCH 11/18] Update src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java Co-authored-by: Kevin <92656833+kevinthegreat1@users.noreply.github.com> --- .../de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java index c28bfc408e..7ac359d651 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java @@ -123,7 +123,7 @@ public void savePresets() { try { if (!PRESETS_FILE.exists()) PRESETS_FILE.createNewFile(); try (var writer = Files.newWriter(PRESETS_FILE, StandardCharsets.UTF_8)) { - var element = MAP_CODEC.encodeStart(JsonOps.INSTANCE, this.presets).resultOrPartial(LOGGER::warn) + var element = MAP_CODEC.encodeStart(JsonOps.INSTANCE, this.presets).resultOrPartial(LOGGER::error) .orElse(new JsonObject()); writer.write(SkyblockerMod.GSON.toJson(element) + "\n"); } From ed4cfdcc18d636e51dff6ef90b7a848e2c0a3538 Mon Sep 17 00:00:00 2001 From: Wanja <105125277+Manchick0@users.noreply.github.com> Date: Sun, 29 Dec 2024 23:45:25 +0100 Subject: [PATCH 12/18] Update src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java Co-authored-by: Kevin <92656833+kevinthegreat1@users.noreply.github.com> --- .../skyblock/speedPreset/SpeedPresetListWidget.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java index 06d933de66..b031b3f500 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java @@ -109,8 +109,8 @@ public class TitleEntry extends AbstractEntry { public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { // The line height is 25, the height of a single character is always 9. // 25 - 9 = 16, 16 / 2 = 8, therefore the Y-offset should be 8. - context.drawCenteredTextWithShadow(renderer, Text.translatable("skyblocker.config.general.speedPresets.config.title"), width / 2 - 50, y + 8, 0xFFFFFF); - context.drawCenteredTextWithShadow(renderer, Text.translatable("skyblocker.config.general.speedPresets.config.speed"), width / 2 + 50, y + 8, 0xFFFFFF); + context.drawCenteredTextWithShadow(client.textRenderer, Text.translatable("skyblocker.config.general.speedPresets.config.title"), width / 2 - 50, y + 8, 0xFFFFFF); + context.drawCenteredTextWithShadow(client.textRenderer, Text.translatable("skyblocker.config.general.speedPresets.config.speed"), width / 2 + 50, y + 8, 0xFFFFFF); } @Override From ab8f7ceb2e0b663347da2c79dc7ba27c05992cb1 Mon Sep 17 00:00:00 2001 From: Wanja <105125277+Manchick0@users.noreply.github.com> Date: Sun, 29 Dec 2024 23:45:33 +0100 Subject: [PATCH 13/18] Update src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java Co-authored-by: Kevin <92656833+kevinthegreat1@users.noreply.github.com> --- .../de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java index 7ac359d651..d816b8d553 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java @@ -51,7 +51,7 @@ public static SpeedPresets getInstance() { public static CommandNode getCommandNode() { return ClientCommandManager.literal("setmaxspeed") - .requires(client -> Utils.isOnSkyblock()) + .requires(source -> Utils.isOnSkyblock()) .then(ClientCommandManager.argument("preset", StringArgumentType.string()) .suggests((ctx, builder) -> { if (SkyblockerConfigManager.get().general.speedPresets.enableSpeedPresets) { From 1c78583addc9dc3672e918120befec14b267b240 Mon Sep 17 00:00:00 2001 From: Wanja <105125277+Manchick0@users.noreply.github.com> Date: Sun, 29 Dec 2024 23:45:45 +0100 Subject: [PATCH 14/18] Update src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java Co-authored-by: Kevin <92656833+kevinthegreat1@users.noreply.github.com> --- .../de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java index d816b8d553..2db6ee5af6 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java @@ -114,7 +114,7 @@ public void loadPresets() { this.loadDefaults(); this.savePresets(); } catch (IOException e) { - LOGGER.warn("Couldn't load speed presets: ", e); + LOGGER.error("[Skyblocker Speed Presets] Couldn't load speed presets", e); } } From 43d08ea37b9f78e88deade5e3a4539067fe5c8a5 Mon Sep 17 00:00:00 2001 From: Manchick0 Date: Sun, 29 Dec 2024 23:55:03 +0100 Subject: [PATCH 15/18] Refactor modification checks for SpeedPreset entries. Removed the `hasBeenModified` flag, and replaced it with direct comparisons of initial and current values. --- .../speedPreset/SpeedPresetListWidget.java | 41 ++++++------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java index b031b3f500..4fa03d24c8 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java @@ -37,32 +37,13 @@ public int getRowWidth() { return super.getRowWidth() + 104; } - /** - * Checks whether the state of the widget has been modified compared to the preset data. - *

- * This method determines if any of the following conditions are met: - *

    - *
  • The number of children entries in the widget is less than the current number of presets.
  • - *
  • An entry has been modified.
  • - *
  • The number of entries worth saving does not match the number of presets.
  • - *
- * - * @return true if the state has been modified; false otherwise. - */ public boolean hasBeenChanged() { var presets = SpeedPresets.getInstance().getPresetCount(); - // Accounting 1 for the title entry. - var children = children().size() - 1; - if (children < presets) return true; - - children = 0; - for (var child : children()) { - if (child.hasBeenModified()) return true; - if (child instanceof SpeedPresetEntry entry) { - children = entry.isEmpty() ? children : children + 1; - } - } - return children != presets; + // If there are fewer children than presets, some were removed, and all further checks are pointless + if (children().size() < presets) return true; + return presets != children().stream().filter(SpeedPresetEntry.class::isInstance) + .filter(preset -> !((SpeedPresetEntry) preset).isEmpty()) + .count() || children().stream().filter(SpeedPresetEntry.class::isInstance).map(SpeedPresetEntry.class::cast).anyMatch(SpeedPresetEntry::hasBeenModified); } public void updatePosition() { @@ -130,31 +111,32 @@ public class SpeedPresetEntry extends AbstractEntry { protected final TextFieldWidget speedInput; protected final ButtonWidget removeButton; - protected boolean hasBeenModified; + protected final String initialTitle; + protected final String initialSpeed; public SpeedPresetEntry(String title, String speed) { var client = SpeedPresetListWidget.this.client; + this.initialTitle = title; + this.initialSpeed = speed; + // All Xs and Ys are then set using the initPosition() method. this.titleInput = new TextFieldWidget(client.textRenderer, 0, 0, 120, 20, Text.empty()); this.titleInput.setTextPredicate(str -> str.isEmpty() || TITLE.matcher(str).matches()); this.titleInput.setText(title); this.titleInput.setMaxLength(16); this.titleInput.setPlaceholder(Text.literal("newPreset").formatted(Formatting.DARK_GRAY)); - this.titleInput.setChangedListener(str -> this.hasBeenModified = true); this.speedInput = new TextFieldWidget(client.textRenderer, 0, 0, 50, 20, Text.empty()); this.speedInput.setTextPredicate(str -> str.isEmpty() || NUMBER.matcher(str).matches()); this.speedInput.setText(speed); this.speedInput.setMaxLength(3); this.speedInput.setPlaceholder(Text.literal("0").formatted(Formatting.DARK_GRAY)); - this.speedInput.setChangedListener(str -> this.hasBeenModified = true); this.removeButton = ButtonWidget.builder(Text.literal("-"), (btn) -> { SpeedPresetListWidget.this.removeEntry(this); }).dimensions(0, 0, 20, 20).build(); - this.hasBeenModified = false; this.updatePosition(); } @@ -198,7 +180,8 @@ protected void updatePosition() { @Override protected boolean hasBeenModified() { - return hasBeenModified; + return !this.titleInput.getText().equals(this.initialTitle) + || !this.speedInput.getText().equals(this.initialSpeed); } } } From 010b3282a97bea0e51ac589b77cb1455ded6c5f9 Mon Sep 17 00:00:00 2001 From: Manchick0 Date: Mon, 30 Dec 2024 00:02:52 +0100 Subject: [PATCH 16/18] Clean up pointless changes --- .../skyblocker/mixins/DrawContextMixin.java | 1 - .../skyblocker/mixins/HandledScreenMixin.java | 2 -- .../skyblocker/textures/gui/item_protection.png | Bin 250 -> 235 bytes 3 files changed, 3 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java b/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java index 0e6c851656..8e78bf5ab2 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java @@ -11,7 +11,6 @@ @Mixin(DrawContext.class) public abstract class DrawContextMixin { - @ModifyExpressionValue(method = "drawCooldownProgress", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/ItemCooldownManager;getCooldownProgress(Lnet/minecraft/item/ItemStack;F)F")) private float skyblocker$modifyItemCooldown(float cooldownProgress, @Local(argsOnly = true) ItemStack stack) { return Utils.isOnSkyblock() && ItemCooldowns.isOnCooldown(stack) ? ItemCooldowns.getItemCooldownEntry(stack).getRemainingCooldownPercent() : cooldownProgress; diff --git a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java index 2c9febc241..d092de6e2e 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java @@ -97,8 +97,6 @@ public abstract class HandledScreenMixin extends Screen @Shadow protected abstract List getTooltipFromItem(ItemStack stack); - @Shadow - private boolean touchIsRightClickDrag; @Unique private List quickNavButtons; diff --git a/src/main/resources/assets/skyblocker/textures/gui/item_protection.png b/src/main/resources/assets/skyblocker/textures/gui/item_protection.png index 6d6016e1c08524eeccfd25e88c829867a8e0feaa..b76fe034481ab5321bbd13cb80b86f32a99aab6a 100644 GIT binary patch delta 218 zcmeyx_?mHoWIZzj1B1(wu46!ou{g-xiDBJ2nU_EgOS+@4BLl<6e(pbstUx|bfKQ0) zhySZS{Ac)Z7szK|%-_Bjq^=~$FZloe{|pXVE588woCO|{#S9F5he4R}c>anMprD&u`8WOD#92wV!D45B<;{an^LB{Ts5 D2*^hW delta 233 zcmVg~t>|)<*+cm538u-iyAWw~S zwUNOkGPp##+DM+7=_~xdfY;Q(*W})BAhT9n(^HjDmEfA5%-U%KUT**(j)dbW;M}$W j!2Mw*js#lY$$xqRxLHD3dH(mJ00000NkvXXu0mjffVyTo From ea4efb811ef965567e4eec959a6e29ca22f68249 Mon Sep 17 00:00:00 2001 From: Manchick0 Date: Mon, 30 Dec 2024 00:30:08 +0100 Subject: [PATCH 17/18] Refactor SpeedPresets to use Object2IntMap. Replaced LinkedHashMap with Object2IntMap for efficiency and consistency in managing speed presets. Adjusted related methods and logic to accommodate the new data structure. Updated SpeedPresetListWidget to handle changes and comparisons using the revised map implementation. --- .../speedPreset/SpeedPresetListWidget.java | 66 +++++++++---------- .../skyblock/speedPreset/SpeedPresets.java | 24 +++---- 2 files changed, 43 insertions(+), 47 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java index 4fa03d24c8..fe7e2aacff 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java @@ -1,5 +1,7 @@ package de.hysky.skyblocker.skyblock.speedPreset; +import it.unimi.dsi.fastutil.Pair; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.Drawable; @@ -8,10 +10,10 @@ import net.minecraft.client.gui.widget.*; import net.minecraft.text.Text; import net.minecraft.util.Formatting; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.Objects; import java.util.regex.Pattern; public class SpeedPresetListWidget extends ElementListWidget { @@ -19,7 +21,6 @@ public class SpeedPresetListWidget extends ElementListWidget !((SpeedPresetEntry) preset).isEmpty()) - .count() || children().stream().filter(SpeedPresetEntry.class::isInstance).map(SpeedPresetEntry.class::cast).anyMatch(SpeedPresetEntry::hasBeenModified); + if (children().size() < presets.getPresetCount()) return true; + var childrenMap = new Object2IntOpenHashMap(); + this.children().stream() + .filter(SpeedPresetEntry.class::isInstance) + .map(SpeedPresetEntry.class::cast) + .filter(entry -> !entry.isEmpty()) + .map(SpeedPresetEntry::getMapping) + .filter(Objects::nonNull) + .forEach(mapping -> childrenMap.put(mapping.first(), mapping.second())); + return !presets.compare(childrenMap); } public void updatePosition() { @@ -67,11 +74,7 @@ public void save() { public abstract static class AbstractEntry extends ElementListWidget.Entry { - protected boolean hasBeenModified() { - return false; - } - - protected void updatePosition(){} + protected void updatePosition() {} @Override public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { @@ -111,15 +114,9 @@ public class SpeedPresetEntry extends AbstractEntry { protected final TextFieldWidget speedInput; protected final ButtonWidget removeButton; - protected final String initialTitle; - protected final String initialSpeed; - public SpeedPresetEntry(String title, String speed) { var client = SpeedPresetListWidget.this.client; - this.initialTitle = title; - this.initialSpeed = speed; - // All Xs and Ys are then set using the initPosition() method. this.titleInput = new TextFieldWidget(client.textRenderer, 0, 0, 120, 20, Text.empty()); this.titleInput.setTextPredicate(str -> str.isEmpty() || TITLE.matcher(str).matches()); @@ -133,9 +130,10 @@ public SpeedPresetEntry(String title, String speed) { this.speedInput.setMaxLength(3); this.speedInput.setPlaceholder(Text.literal("0").formatted(Formatting.DARK_GRAY)); - this.removeButton = ButtonWidget.builder(Text.literal("-"), (btn) -> { - SpeedPresetListWidget.this.removeEntry(this); - }).dimensions(0, 0, 20, 20).build(); + this.removeButton = ButtonWidget.builder(Text.literal("-"), + (btn) -> SpeedPresetListWidget.this.removeEntry(this)) + .dimensions(0, 0, 20, 20) + .build(); this.updatePosition(); } @@ -152,15 +150,10 @@ public List children() { public void save() { var presets = SpeedPresets.getInstance(); - assert presets != null && children().size() == 3; - var title = ((TextFieldWidget) children().get(0)).getText(); - var speed = ((TextFieldWidget) children().get(1)).getText(); - if (title.isEmpty()) return; - try { - presets.setPreset(title, Short.parseShort(speed)); - } catch (NumberFormatException e) { - LOGGER.warn("Couldn't save speed preset '{}' because of an invalid speed value: {}", title, speed); - } + if (this.isEmpty()) return; + var mapping = getMapping(); + if (mapping != null) + presets.setPreset(mapping.first(), mapping.second()); } protected boolean isEmpty() { @@ -178,10 +171,13 @@ protected void updatePosition() { SimplePositioningWidget.setPos(grid, 0, 0, width, itemHeight, 0.5f, 0.5f); } - @Override - protected boolean hasBeenModified() { - return !this.titleInput.getText().equals(this.initialTitle) - || !this.speedInput.getText().equals(this.initialSpeed); + @Nullable + protected Pair getMapping() { + try { + return Pair.of(titleInput.getText(), Short.parseShort(speedInput.getText())); + } catch (NumberFormatException e) { + return null; + } } } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java index 2db6ee5af6..63d32cd5ad 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java @@ -11,6 +11,8 @@ import de.hysky.skyblocker.annotations.Init; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.Utils; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.fabricmc.fabric.api.client.message.v1.ClientSendMessageEvents; @@ -22,9 +24,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.util.LinkedHashMap; import java.util.Map; -import java.util.Set; import java.util.function.BiConsumer; import java.util.regex.Pattern; @@ -33,15 +33,15 @@ public class SpeedPresets { private static final Pattern COMMAND_PATTERN = Pattern.compile("^setmaxspeed\\s([a-zA-Z][a-zA-Z0-9_]*)$"); private static final Logger LOGGER = LoggerFactory.getLogger(SpeedPresets.class); - private static final Codec> MAP_CODEC = Codec.unboundedMap(Codec.STRING, Codec.SHORT); + private static final Codec> MAP_CODEC = Codec.unboundedMap(Codec.STRING, Codec.INT); private static final File PRESETS_FILE = new File(SkyblockerMod.CONFIG_DIR.toFile(), "speed_presets.json"); private static SpeedPresets instance; - private final Map presets; + private final Object2IntMap presets; private SpeedPresets() { - this.presets = new LinkedHashMap<>(); + this.presets = new Object2IntOpenHashMap<>(); this.loadPresets(); } @@ -80,16 +80,12 @@ public void clear() { this.presets.clear(); } - public Set> entries() { - return this.presets.entrySet(); - } - public boolean hasPreset(String name) { return this.presets.containsKey(name); } - public short getPreset(String name) { - return this.presets.getOrDefault(name, (short) 0); + public int getPreset(String name) { + return this.presets.getOrDefault(name, 0); } public void setPreset(String name, short value) { @@ -97,10 +93,14 @@ public void setPreset(String name, short value) { savePresets(); } - public void forEach(BiConsumer consumer) { + public void forEach(BiConsumer consumer) { this.presets.forEach(consumer); } + public boolean compare(Map presets) { + return this.presets.equals(presets); + } + public int getPresetCount() { return this.presets.size(); } From 5332083d378f206e2ca55adb7cb1f729994a6717 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Sun, 29 Dec 2024 15:48:16 -0800 Subject: [PATCH 18/18] Refactor SpeedPresets --- .../skyblocker/mixins/DrawContextMixin.java | 2 +- .../speedPreset/SpeedPresetListWidget.java | 21 ++++++++----------- .../skyblock/speedPreset/SpeedPresets.java | 18 ++++++++-------- 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java b/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java index 8e78bf5ab2..56a5183a91 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/DrawContextMixin.java @@ -11,7 +11,7 @@ @Mixin(DrawContext.class) public abstract class DrawContextMixin { - @ModifyExpressionValue(method = "drawCooldownProgress", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/ItemCooldownManager;getCooldownProgress(Lnet/minecraft/item/ItemStack;F)F")) + @ModifyExpressionValue(method = "drawCooldownProgress", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/ItemCooldownManager;getCooldownProgress(Lnet/minecraft/item/ItemStack;F)F")) private float skyblocker$modifyItemCooldown(float cooldownProgress, @Local(argsOnly = true) ItemStack stack) { return Utils.isOnSkyblock() && ItemCooldowns.isOnCooldown(stack) ? ItemCooldowns.getItemCooldownEntry(stack).getRemainingCooldownPercent() : cooldownProgress; } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java index fe7e2aacff..bfe22a6c97 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresetListWidget.java @@ -1,7 +1,6 @@ package de.hysky.skyblocker.skyblock.speedPreset; -import it.unimi.dsi.fastutil.Pair; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectIntPair; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.Drawable; @@ -15,6 +14,7 @@ import java.util.List; import java.util.Objects; import java.util.regex.Pattern; +import java.util.stream.Collectors; public class SpeedPresetListWidget extends ElementListWidget { @@ -42,15 +42,13 @@ public boolean hasBeenChanged() { var presets = SpeedPresets.getInstance(); // If there are fewer children than presets, some were removed, and all further checks are pointless if (children().size() < presets.getPresetCount()) return true; - var childrenMap = new Object2IntOpenHashMap(); - this.children().stream() + var childrenMap = this.children().stream() .filter(SpeedPresetEntry.class::isInstance) .map(SpeedPresetEntry.class::cast) - .filter(entry -> !entry.isEmpty()) .map(SpeedPresetEntry::getMapping) .filter(Objects::nonNull) - .forEach(mapping -> childrenMap.put(mapping.first(), mapping.second())); - return !presets.compare(childrenMap); + .collect(Collectors.toMap(ObjectIntPair::key, ObjectIntPair::valueInt)); + return !presets.arePresetsEqual(childrenMap); } public void updatePosition() { @@ -149,11 +147,9 @@ public List children() { } public void save() { - var presets = SpeedPresets.getInstance(); - if (this.isEmpty()) return; var mapping = getMapping(); if (mapping != null) - presets.setPreset(mapping.first(), mapping.second()); + SpeedPresets.getInstance().setPreset(mapping.key(), mapping.valueInt()); } protected boolean isEmpty() { @@ -172,9 +168,10 @@ protected void updatePosition() { } @Nullable - protected Pair getMapping() { + protected ObjectIntPair getMapping() { + if (isEmpty()) return null; try { - return Pair.of(titleInput.getText(), Short.parseShort(speedInput.getText())); + return ObjectIntPair.of(titleInput.getText(), Integer.parseInt(speedInput.getText())); } catch (NumberFormatException e) { return null; } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java index 63d32cd5ad..b3af7c413c 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/speedPreset/SpeedPresets.java @@ -88,7 +88,7 @@ public int getPreset(String name) { return this.presets.getOrDefault(name, 0); } - public void setPreset(String name, short value) { + public void setPreset(String name, int value) { this.presets.put(name, value); savePresets(); } @@ -97,7 +97,7 @@ public void forEach(BiConsumer consumer) { this.presets.forEach(consumer); } - public boolean compare(Map presets) { + public boolean arePresetsEqual(Map presets) { return this.presets.equals(presets); } @@ -135,12 +135,12 @@ public void savePresets() { // According to: https://www.reddit.com/r/HypixelSkyblock/comments/14kkz07/speed_vs_farming_fortune/ public void loadDefaults() { this.presets.clear(); - this.presets.put("default", (short) 100); - this.presets.put("crops", (short) 93); - this.presets.put("cocoa", (short) 155); - this.presets.put("mushroom", (short) 233); - this.presets.put("cane", (short) 327); - this.presets.put("squash", (short) 327); - this.presets.put("cactus", (short) 464); + this.presets.put("default", 100); + this.presets.put("crops", 93); + this.presets.put("cocoa", 155); + this.presets.put("mushroom", 233); + this.presets.put("cane", 327); + this.presets.put("squash", 327); + this.presets.put("cactus", 464); } }