diff options
author | Rime <81419447+Emirlol@users.noreply.github.com> | 2024-05-29 18:49:55 +0300 |
---|---|---|
committer | Rime <81419447+Emirlol@users.noreply.github.com> | 2024-06-08 04:13:47 +0300 |
commit | b157736114a1e6c5ace90a65a483c087326a5a1e (patch) | |
tree | 0b334a32d00810084fb074618abd1599daab8df0 /src | |
parent | 8ffde8a752b8a3bffa0015b1eb73fa449bd9e823 (diff) | |
download | Skyblocker-b157736114a1e6c5ace90a65a483c087326a5a1e.tar.gz Skyblocker-b157736114a1e6c5ace90a65a483c087326a5a1e.tar.bz2 Skyblocker-b157736114a1e6c5ace90a65a483c087326a5a1e.zip |
Add slot text adders, which render arbitrary text on arbitrary slots
Diffstat (limited to 'src')
4 files changed, 115 insertions, 0 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index 462e6a4a..7b379495 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -31,6 +31,7 @@ import de.hysky.skyblocker.skyblock.garden.FarmingHud; import de.hysky.skyblocker.skyblock.garden.LowerSensitivity; import de.hysky.skyblocker.skyblock.garden.VisitorHelper; import de.hysky.skyblocker.skyblock.item.*; +import de.hysky.skyblocker.skyblock.item.slottext.SlotTextManager; import de.hysky.skyblocker.skyblock.item.tooltip.AccessoriesHelper; import de.hysky.skyblocker.skyblock.item.tooltip.BackpackPreview; import de.hysky.skyblocker.skyblock.item.tooltip.ItemTooltip; @@ -188,6 +189,7 @@ public class SkyblockerMod implements ClientModInitializer { TimeTowerReminder.init(); SkyblockTime.init(); TooltipManager.init(); + SlotTextManager.init(); Scheduler.INSTANCE.scheduleCyclic(Utils::update, 20); Scheduler.INSTANCE.scheduleCyclic(DiscordRPCManager::updateDataAndPresence, 200); diff --git a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java index 0c413fc8..847416aa 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/HandledScreenMixin.java @@ -14,6 +14,7 @@ import de.hysky.skyblocker.skyblock.garden.VisitorHelper; import de.hysky.skyblocker.skyblock.item.ItemProtection; import de.hysky.skyblocker.skyblock.item.ItemRarityBackgrounds; import de.hysky.skyblocker.skyblock.item.WikiLookup; +import de.hysky.skyblocker.skyblock.item.slottext.SlotTextManager; import de.hysky.skyblocker.skyblock.item.tooltip.BackpackPreview; import de.hysky.skyblocker.skyblock.item.tooltip.CompactorDeletorPreview; import de.hysky.skyblocker.skyblock.item.tooltip.TooltipManager; @@ -27,6 +28,7 @@ import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.item.TooltipData; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.inventory.SimpleInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -309,4 +311,19 @@ public abstract class HandledScreenMixin<T extends ScreenHandler> extends Screen RenderSystem.disableBlend(); } } + + @Inject(method = "drawSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V")) + private void skyblocker$drawSlotText(DrawContext context, Slot slot, CallbackInfo ci) { + Text text = SlotTextManager.getText(slot); + if (text == null) return; + MatrixStack matrices = context.getMatrices(); + matrices.push(); + matrices.translate(0.0f, 0.0f, 200.0f); + int length = textRenderer.getWidth(text); + if (length > 16) { + matrices.scale(16.0f / length, 16.0f / length, 1.0f); //Make them fit in the slot. FYI, a slot is sized 16x16. + } + context.drawText(textRenderer, text, length > 16 ? (int) (slot.x * length / 16f) : slot.x, length > 16 ? (int) ((slot.y + 9) * length / 16f) : slot.y, 0xFFFFFF, true); + matrices.pop(); + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextAdder.java b/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextAdder.java new file mode 100644 index 00000000..5ef388bd --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextAdder.java @@ -0,0 +1,42 @@ +package de.hysky.skyblocker.skyblock.item.slottext; + +import net.minecraft.screen.slot.Slot; +import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; + +import java.util.regex.Pattern; + +/** + * Extend this class and add it to {@link SlotTextManager#adders} to add text to any arbitrary slot. + */ +public abstract class SlotTextAdder { + /** + * The title of the screen must match this pattern for this adder to be applied. Null means it will be applied to all screens. + */ + public final Pattern titlePattern; + + protected SlotTextAdder(String titlePattern) { + this(Pattern.compile(titlePattern)); + } + + protected SlotTextAdder(Pattern titlePattern) { + this.titlePattern = titlePattern; + } + + /** + * Creates a SlotTextRenderer that will be applied to all screens. + */ + protected SlotTextAdder() { + this.titlePattern = null; + } + + /** + * This method will be called for each rendered slot. Consider using a switch statement on {@link Slot#getIndex()} if you wish to add different text to different slots. + * + * @return The text to be rendered. Return null if no text should be rendered. + * @implNote By minecraft's design, scaled text inexplicably moves around. + * So, limit your text to 3 characters (or roughly less than 20 width) if you want it to not look horrible. + */ + @Nullable + public abstract Text getText(Slot slot); +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextManager.java b/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextManager.java new file mode 100644 index 00000000..b6dfa6cd --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/slottext/SlotTextManager.java @@ -0,0 +1,54 @@ +package de.hysky.skyblocker.skyblock.item.slottext; + +import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.screen.slot.Slot; +import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; + +public class SlotTextManager { + private static final SlotTextAdder[] adders = new SlotTextAdder[]{ + }; + private static final ArrayList<SlotTextAdder> currentScreenAdders = new ArrayList<>(); + + private SlotTextManager() { + } + + public static void init() { + ScreenEvents.AFTER_INIT.register((client, screen, width, height) -> { + if (screen instanceof HandledScreen<?>) { + onScreenChange(screen); + ScreenEvents.remove(screen).register(ignored -> currentScreenAdders.clear()); + } + }); + } + + private static void onScreenChange(Screen screen) { + final String title = screen.getTitle().getString(); + for (SlotTextAdder adder : adders) { + if (adder.titlePattern == null || adder.titlePattern.matcher(title).matches()) { + currentScreenAdders.add(adder); + } + } + } + + /** + * The returned text is rendered on top of the slot. The text will be scaled if it doesn't fit in the slot, + * but 3 characters should be seen as the maximum to keep it readable and in place as it tends to move around when scaled. + * + * @implNote Only the first adder that returns a non-null text will be used. + * The order of the adders remains the same as they were added to the {@link SlotTextManager#adders} array. + */ + @Nullable + public static Text getText(Slot slot) { + if (currentScreenAdders.isEmpty()) return null; + for (SlotTextAdder adder : currentScreenAdders) { + Text text = adder.getText(slot); + if (text != null) return text; + } + return null; + } +} |