From 3c47d087511440c5d1964b45cad8d483ab4aaa8e Mon Sep 17 00:00:00 2001 From: RoxareX <93204788+RoxareX@users.noreply.github.com> Date: Sun, 1 Jun 2025 03:33:58 +0300 Subject: Add ingame fishing hook timer display (#1269) * Add Skyblock fishing hook timer infront of players screen * Remake Display logic to get rid of flickering * Remake regex to only get "3.0" number types Fix to only get the armorstand if it hasn't already been assigned * Changes required by PR Remove unused UseItemCallback.EVENT.register Update deprecated "HudRenderCallback.EVENT.register" to "HudLayerRegistrationCallback.EVENT.register" Add "ClientPlayConnectionEvents.JOIN.register" to remove null the armorstand if joining a new server Move "Pattern pattern = Pattern.compile("\\b\\d\\.\\d\\b");" to the top to only do once not every call Comment out error message Add HelperCategory.java "Enable Fishing Hook Display" and its description to en_us.json * Changes required by PR Remove unused import statements Remove unused UseItemCallback.EVENT.register Update depricated "HudRenderCallback.EVENT.register" to "HudLayerRegistrationCallback.EVENT.register" Add "ClientPlayConnectionEvents.JOIN.register" to remove null the armorstand if joining a new server Move "Pattern pattern = Pattern.compile("\\b\\d\\.\\d\\b");" to the top to only do once not every call Comment out error message Add HelperCategory.java "Enable Fishing Hook Display" and its description to en_us.json * Changes required by PR Remove all commented out debugs Move the option for enabling the enableFishingHookDisplay to be below enableFishingHelper * Changes required by PR move variable to the same spot as the option for it * QOL Changes Checks if the armorstand is near the players fish bobber so the dmg armorstands show --- .../config/categories/HelperCategory.java | 9 +++ .../skyblocker/config/configs/HelperConfig.java | 3 + .../mixins/ClientPlayNetworkHandlerMixin.java | 4 ++ .../skyblock/fishing/FishingHookDisplayHelper.java | 80 ++++++++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/fishing/FishingHookDisplayHelper.java (limited to 'src/main/java') diff --git a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java index 6bc43655..3e15d136 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java @@ -124,6 +124,14 @@ public class HelperCategory { newValue -> config.helpers.fishing.enableFishingHelper = newValue) .controller(ConfigUtils::createBooleanController) .build()) + .option(Option.createBuilder() + .name(Text.translatable("skyblocker.config.helpers.fishing.enableFishingHookDisplay")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.helpers.fishing.enableFishingHookDisplay.@Tooltip"))) + .binding(defaults.helpers.fishing.enableFishingHookDisplay, + () -> config.helpers.fishing.enableFishingHookDisplay, + newValue -> config.helpers.fishing.enableFishingHookDisplay = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) .option(Option.createBuilder() .name(Text.translatable("skyblocker.config.helpers.fishing.enableFishingTimer")) .description(OptionDescription.of(Text.translatable("skyblocker.config.helpers.fishing.enableFishingTimer.@Tooltip"))) @@ -209,6 +217,7 @@ public class HelperCategory { rarity -> config.helpers.fishing.minimumNotificationRarity = rarity == SkyblockItemRarity.DIVINE ? SkyblockItemRarity.UNKNOWN : rarity) .controller(ConfigUtils::createEnumCyclingListController) .build()) + .build()) //Fairy Souls Helper diff --git a/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java index e5f5d1b2..0da94348 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java @@ -74,6 +74,9 @@ public class HelperConfig { @SerialEntry public boolean enableFishingHelper = true; + @SerialEntry + public boolean enableFishingHookDisplay = true; + @SerialEntry public boolean enableFishingTimer = false; diff --git a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java index 4a62bbde..97d289d5 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/ClientPlayNetworkHandlerMixin.java @@ -11,6 +11,7 @@ import de.hysky.skyblocker.config.configs.UIAndVisualsConfig; import de.hysky.skyblocker.skyblock.CompactDamage; import de.hysky.skyblocker.skyblock.HealthBars; import de.hysky.skyblocker.skyblock.fishing.FishingHelper; +import de.hysky.skyblocker.skyblock.fishing.FishingHookDisplayHelper; import de.hysky.skyblocker.skyblock.SmoothAOTE; import de.hysky.skyblocker.skyblock.chocolatefactory.EggFinder; import de.hysky.skyblocker.skyblock.crimson.dojo.DojoManager; @@ -85,6 +86,9 @@ public abstract class ClientPlayNetworkHandlerMixin extends ClientCommonNetworkH } catch (Exception e) { LOGGER.error("[Skyblocker Compact Damage] Failed to compact damage number", e); } + + + FishingHookDisplayHelper.onArmorStandSpawn(armorStandEntity); } @Inject(method = "method_64896", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;removeEntity(ILnet/minecraft/entity/Entity$RemovalReason;)V")) diff --git a/src/main/java/de/hysky/skyblocker/skyblock/fishing/FishingHookDisplayHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/fishing/FishingHookDisplayHelper.java new file mode 100644 index 00000000..a1608b0d --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/fishing/FishingHookDisplayHelper.java @@ -0,0 +1,80 @@ +package de.hysky.skyblocker.skyblock.fishing; + +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.annotations.Init; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; +import net.fabricmc.fabric.api.client.rendering.v1.HudLayerRegistrationCallback; +import net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.client.render.RenderTickCounter; +import net.minecraft.entity.decoration.ArmorStandEntity; +import net.minecraft.util.Identifier; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class FishingHookDisplayHelper { + private static ArmorStandEntity fishingHookArmorStand; + private static final Identifier FISHING_HOOK_DISPLAY = Identifier.of(SkyblockerMod.NAMESPACE, "fishing_hook_display"); + static Pattern pattern = Pattern.compile("\\d.\\d"); + + @Init + public static void init() { + ClientPlayConnectionEvents.JOIN.register((_handler, _sender, _client) -> fishingHookArmorStand = null); + + HudLayerRegistrationCallback.EVENT.register(d -> d.attachLayerAfter(IdentifiedLayer.TITLE_AND_SUBTITLE,FISHING_HOOK_DISPLAY,FishingHookDisplayHelper::render)); + } + + public static void render(DrawContext context, RenderTickCounter tickDelta) { + if (!SkyblockerConfigManager.get().helpers.fishing.enableFishingHookDisplay) return; + + + // Check if the armor stand is null or invalid + if (fishingHookArmorStand == null || !fishingHookArmorStand.isAlive() || !fishingHookArmorStand.hasCustomName()) { + fishingHookArmorStand = null; + return; + } + + + MinecraftClient client = MinecraftClient.getInstance(); + ClientPlayerEntity player = client.player; + if (player == null || player.fishHook == null) return; + + // Proceed only if fishingHookArmorStand is not null + if (fishingHookArmorStand != null) { + String armorStandName = fishingHookArmorStand.getName().getString(); + + int screenWidth = client.getWindow().getScaledWidth(); + int screenHeight = client.getWindow().getScaledHeight(); + int x = screenWidth / 2; // Center horizontally + int y = screenHeight / 2; // Position near the top + + // Scale the text by 3x + context.getMatrices().push(); + context.getMatrices().scale(3.0F, 3.0F, 1.0F); + context.drawCenteredTextWithShadow(client.textRenderer, armorStandName, (int) (x / 3.0F), (int) (y / 3.0F), 0xFFFF00); + context.getMatrices().pop(); + } + } + + public static void onArmorStandSpawn(ArmorStandEntity armorStand) { + if (!SkyblockerConfigManager.get().helpers.fishing.enableFishingHookDisplay) return; + if (fishingHookArmorStand != null) return; + + MinecraftClient client = MinecraftClient.getInstance(); + if (client.player == null || client.player.fishHook == null) return; + // Check the distance between the armor stand and the player's fishing hook + double distance = armorStand.getPos().distanceTo(client.player.fishHook.getPos()); + if (distance > 0.1) return; // Checks for a minimum distance of 0.1 blocks + + Matcher matcher = pattern.matcher(armorStand.getName().getString()); + if (armorStand.hasCustomName() && matcher.matches()) { + fishingHookArmorStand = armorStand; + } else { + fishingHookArmorStand = null; + } + } +} -- cgit