diff options
author | Yasin <a.piri@hotmail.de> | 2023-10-09 12:58:02 +0200 |
---|---|---|
committer | Yasin <a.piri@hotmail.de> | 2023-10-09 12:58:02 +0200 |
commit | bd3f0329d0e391bd84b5f9e3ff207d9dd9815853 (patch) | |
tree | 2fd1d1ef625f57acc2e4916c967d8d2393844798 /src/main/java/de/hysky/skyblocker/utils/render/title | |
parent | 2315b90da8117f28f66348927afdb621ee4fc815 (diff) | |
download | Skyblocker-bd3f0329d0e391bd84b5f9e3ff207d9dd9815853.tar.gz Skyblocker-bd3f0329d0e391bd84b5f9e3ff207d9dd9815853.tar.bz2 Skyblocker-bd3f0329d0e391bd84b5f9e3ff207d9dd9815853.zip |
new pr because fixing merge conflict would take too long
Diffstat (limited to 'src/main/java/de/hysky/skyblocker/utils/render/title')
3 files changed, 398 insertions, 0 deletions
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/title/Title.java b/src/main/java/de/hysky/skyblocker/utils/render/title/Title.java new file mode 100644 index 00000000..1e167afa --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/render/title/Title.java @@ -0,0 +1,53 @@ +package de.hysky.skyblocker.utils.render.title; + +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +/** + * Represents a title used for {@link TitleContainer}. + * + * @see TitleContainer + */ +public class Title { + private MutableText text; + protected float x = -1; + protected float y = -1; + + /** + * Constructs a new title with the given translation key and formatting to be applied. + * + * @param textKey the translation key + * @param formatting the formatting to be applied to the text + */ + public Title(String textKey, Formatting formatting) { + this(Text.translatable(textKey).formatted(formatting)); + } + + /** + * Constructs a new title with the given {@link MutableText}. + * Use {@link Text#literal(String)} or {@link Text#translatable(String)} to create a {@link MutableText} + * + * @param text the mutable text + */ + public Title(MutableText text) { + this.text = text; + } + + public MutableText getText() { + return text; + } + + public void setText(MutableText text) { + this.text = text; + } + + protected boolean isDefaultPos() { + return x == -1 && y == -1; + } + + protected void resetPos() { + this.x = -1; + this.y = -1; + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainer.java b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainer.java new file mode 100644 index 00000000..487e3d8b --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainer.java @@ -0,0 +1,175 @@ +package de.hysky.skyblocker.utils.render.title; + +import de.hysky.skyblocker.config.SkyblockerConfig; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.scheduler.Scheduler; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.util.math.MathHelper; + +import java.util.LinkedHashSet; +import java.util.Set; + +public class TitleContainer { + /** + * The set of titles which will be rendered. + * + * @see #containsTitle(Title) + * @see #addTitle(Title) + * @see #addTitle(Title, int) + * @see #removeTitle(Title) + */ + private static final Set<Title> titles = new LinkedHashSet<>(); + + public static void init() { + HudRenderCallback.EVENT.register(TitleContainer::render); + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal("skyblocker") + .then(ClientCommandManager.literal("hud") + .then(ClientCommandManager.literal("titleContainer") + .executes(Scheduler.queueOpenScreenCommand(TitleContainerConfigScreen::new)))))); + } + + /** + * Returns {@code true} if the title is currently shown. + * + * @param title the title to check + * @return whether the title in currently shown + */ + public static boolean containsTitle(Title title) { + return titles.contains(title); + } + + /** + * Adds a title to be shown + * + * @param title the title to be shown + * @return whether the title is already currently being shown + */ + public static boolean addTitle(Title title) { + if (titles.add(title)) { + title.resetPos(); + return true; + } + return false; + } + + /** + * Adds a title to be shown for a set number of ticks + * + * @param title the title to be shown + * @param ticks the number of ticks to show the title + * @return whether the title is already currently being shown + */ + public static boolean addTitle(Title title, int ticks) { + if (addTitle(title)) { + Scheduler.INSTANCE.schedule(() -> TitleContainer.removeTitle(title), ticks); + return true; + } + return false; + } + + /** + * Stops showing a title + * + * @param title the title to stop showing + */ + public static void removeTitle(Title title) { + titles.remove(title); + } + + private static void render(DrawContext context, float tickDelta) { + render(context, titles, SkyblockerConfigManager.get().general.titleContainer.x, SkyblockerConfigManager.get().general.titleContainer.y, tickDelta); + } + + protected static void render(DrawContext context, Set<Title> titles, int xPos, int yPos, float tickDelta) { + var client = MinecraftClient.getInstance(); + TextRenderer textRenderer = client.textRenderer; + + // Calculate Scale to use + float scale = 3F * (SkyblockerConfigManager.get().general.titleContainer.titleContainerScale / 100F); + + // Grab direction and alignment values + SkyblockerConfig.Direction direction = SkyblockerConfigManager.get().general.titleContainer.direction; + SkyblockerConfig.Alignment alignment = SkyblockerConfigManager.get().general.titleContainer.alignment; + // x/y refer to the starting position for the text + // y always starts at yPos + float x = 0; + float y = yPos; + + //Calculate the width of combined text + float width = 0; + for (Title title : titles) { + width += textRenderer.getWidth(title.getText()) * scale + 10; + } + + if (alignment == SkyblockerConfig.Alignment.MIDDLE) { + if (direction == SkyblockerConfig.Direction.HORIZONTAL) { + //If middle aligned horizontally, start the xPosition at half of the width to the left. + x = xPos - (width / 2); + } else { + //If middle aligned vertically, start at xPos, we will shift each text to the left later + x = xPos; + } + } + if (alignment == SkyblockerConfig.Alignment.LEFT || alignment == SkyblockerConfig.Alignment.RIGHT) { + //If left or right aligned, start at xPos, we will shift each text later + x = xPos; + } + + for (Title title : titles) { + + //Calculate which x the text should use + float xToUse; + if (direction == SkyblockerConfig.Direction.HORIZONTAL) { + xToUse = alignment == SkyblockerConfig.Alignment.RIGHT ? + x - (textRenderer.getWidth(title.getText()) * scale) : //if right aligned we need the text position to be aligned on the right side. + x; + } else { + xToUse = alignment == SkyblockerConfig.Alignment.MIDDLE ? + x - (textRenderer.getWidth(title.getText()) * scale) / 2 : //if middle aligned we need the text position to be aligned in the middle. + alignment == SkyblockerConfig.Alignment.RIGHT ? + x - (textRenderer.getWidth(title.getText()) * scale) : //if right aligned we need the text position to be aligned on the right side. + x; + } + + //Start displaying the title at the correct position, not at the default position + if (title.isDefaultPos()) { + title.x = xToUse; + title.y = y; + } + + //Lerp the texts x and y variables + title.x = MathHelper.lerp(tickDelta * 0.5F, title.x, xToUse); + title.y = MathHelper.lerp(tickDelta * 0.5F, title.y, y); + + //Translate the matrix to the texts position and scale + context.getMatrices().push(); + context.getMatrices().translate(title.x, title.y, 200); + context.getMatrices().scale(scale, scale, scale); + + //Draw text + context.drawTextWithShadow(textRenderer, title.getText(), 0, 0, 0xFFFFFF); + context.getMatrices().pop(); + + //Calculate the x and y positions for the next title + if (direction == SkyblockerConfig.Direction.HORIZONTAL) { + if (alignment == SkyblockerConfig.Alignment.MIDDLE || alignment == SkyblockerConfig.Alignment.LEFT) { + //Move to the right if middle or left aligned + x += textRenderer.getWidth(title.getText()) * scale + 10; + } + + if (alignment == SkyblockerConfig.Alignment.RIGHT) { + //Move to the left if right aligned + x -= textRenderer.getWidth(title.getText()) * scale + 10; + } + } else { + //Y always moves by the same amount if vertical + y += textRenderer.fontHeight * scale + 10; + } + } + } +}
\ No newline at end of file diff --git a/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java new file mode 100644 index 00000000..5a42eeb4 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java @@ -0,0 +1,170 @@ +package de.hysky.skyblocker.utils.render.title; + +import de.hysky.skyblocker.config.SkyblockerConfig; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.render.RenderHelper; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.util.math.Vector2f; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.Pair; +import org.lwjgl.glfw.GLFW; + +import java.awt.*; +import java.util.Set; + +public class TitleContainerConfigScreen extends Screen { + private final Title example1 = new Title(Text.literal("Test1").formatted(Formatting.RED)); + private final Title example2 = new Title(Text.literal("Test23").formatted(Formatting.AQUA)); + private final Title example3 = new Title(Text.literal("Testing1234").formatted(Formatting.DARK_GREEN)); + private float hudX = SkyblockerConfigManager.get().general.titleContainer.x; + private float hudY = SkyblockerConfigManager.get().general.titleContainer.y; + private final Screen parent; + + protected TitleContainerConfigScreen() { + this(null); + } + + public TitleContainerConfigScreen(Screen parent) { + super(Text.of("Title Container HUD Config")); + this.parent = parent; + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + super.render(context, mouseX, mouseY, delta); + renderBackground(context, mouseX, mouseY, delta); + TitleContainer.render(context, Set.of(example1, example2, example3), (int) hudX, (int) hudY, delta); + SkyblockerConfig.Direction direction = SkyblockerConfigManager.get().general.titleContainer.direction; + SkyblockerConfig.Alignment alignment = SkyblockerConfigManager.get().general.titleContainer.alignment; + context.drawCenteredTextWithShadow(textRenderer, "Press Q/E to change Alignment: " + alignment, width / 2, textRenderer.fontHeight * 2, Color.WHITE.getRGB()); + context.drawCenteredTextWithShadow(textRenderer, "Press R to change Direction: " + direction, width / 2, textRenderer.fontHeight * 3 + 5, Color.WHITE.getRGB()); + context.drawCenteredTextWithShadow(textRenderer, "Press +/- to change Scale", width / 2, textRenderer.fontHeight * 4 + 10, Color.WHITE.getRGB()); + context.drawCenteredTextWithShadow(textRenderer, "Right Click To Reset Position", width / 2, textRenderer.fontHeight * 5 + 15, Color.GRAY.getRGB()); + + Pair<Vector2f, Vector2f> boundingBox = getSelectionBoundingBox(); + int x1 = (int) boundingBox.getLeft().getX(); + int y1 = (int) boundingBox.getLeft().getY(); + int x2 = (int) boundingBox.getRight().getX(); + int y2 = (int) boundingBox.getRight().getY(); + + context.drawHorizontalLine(x1, x2, y1, Color.RED.getRGB()); + context.drawHorizontalLine(x1, x2, y2, Color.RED.getRGB()); + context.drawVerticalLine(x1, y1, y2, Color.RED.getRGB()); + context.drawVerticalLine(x2, y1, y2, Color.RED.getRGB()); + } + + private Pair<Vector2f, Vector2f> getSelectionBoundingBox() { + SkyblockerConfig.Alignment alignment = SkyblockerConfigManager.get().general.titleContainer.alignment; + + float midWidth = getSelectionWidth() / 2F; + float x1 = 0; + float x2 = 0; + float y1 = hudY; + float y2 = hudY + getSelectionHeight(); + switch (alignment) { + case RIGHT -> { + x1 = hudX - midWidth * 2; + x2 = hudX; + } + case MIDDLE -> { + x1 = hudX - midWidth; + x2 = hudX + midWidth; + } + case LEFT -> { + x1 = hudX; + x2 = hudX + midWidth * 2; + } + } + return new Pair<>(new Vector2f(x1, y1), new Vector2f(x2, y2)); + } + + private float getSelectionHeight() { + float scale = (3F * (SkyblockerConfigManager.get().general.titleContainer.titleContainerScale / 100F)); + return SkyblockerConfigManager.get().general.titleContainer.direction == SkyblockerConfig.Direction.HORIZONTAL ? + (textRenderer.fontHeight * scale) : + (textRenderer.fontHeight + 10F) * 3F * scale; + } + + private float getSelectionWidth() { + float scale = (3F * (SkyblockerConfigManager.get().general.titleContainer.titleContainerScale / 100F)); + return SkyblockerConfigManager.get().general.titleContainer.direction == SkyblockerConfig.Direction.HORIZONTAL ? + (textRenderer.getWidth("Test1") + 10 + textRenderer.getWidth("Test23") + 10 + textRenderer.getWidth("Testing1234")) * scale : + textRenderer.getWidth("Testing1234") * scale; + } + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + float midWidth = getSelectionWidth() / 2; + float midHeight = getSelectionHeight() / 2; + var alignment = SkyblockerConfigManager.get().general.titleContainer.alignment; + + Pair<Vector2f, Vector2f> boundingBox = getSelectionBoundingBox(); + float x1 = boundingBox.getLeft().getX(); + float y1 = boundingBox.getLeft().getY(); + float x2 = boundingBox.getRight().getX(); + float y2 = boundingBox.getRight().getY(); + + if (RenderHelper.pointIsInArea(mouseX, mouseY, x1, y1, x2, y2) && button == 0) { + hudX = switch (alignment) { + case LEFT -> (int) mouseX - midWidth; + case MIDDLE -> (int) mouseX; + case RIGHT -> (int) mouseX + midWidth; + }; + hudY = (int) (mouseY - midHeight); + } + return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (button == 1) { + hudX = (float) this.width / 2; + hudY = this.height * 0.6F; + } + return super.mouseClicked(mouseX, mouseY, button); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (keyCode == GLFW.GLFW_KEY_Q) { + SkyblockerConfig.Alignment current = SkyblockerConfigManager.get().general.titleContainer.alignment; + SkyblockerConfigManager.get().general.titleContainer.alignment = switch (current) { + case LEFT -> SkyblockerConfig.Alignment.MIDDLE; + case MIDDLE -> SkyblockerConfig.Alignment.RIGHT; + case RIGHT -> SkyblockerConfig.Alignment.LEFT; + }; + } + if (keyCode == GLFW.GLFW_KEY_E) { + SkyblockerConfig.Alignment current = SkyblockerConfigManager.get().general.titleContainer.alignment; + SkyblockerConfigManager.get().general.titleContainer.alignment = switch (current) { + case LEFT -> SkyblockerConfig.Alignment.RIGHT; + case MIDDLE -> SkyblockerConfig.Alignment.LEFT; + case RIGHT -> SkyblockerConfig.Alignment.MIDDLE; + }; + } + if (keyCode == GLFW.GLFW_KEY_R) { + SkyblockerConfig.Direction current = SkyblockerConfigManager.get().general.titleContainer.direction; + SkyblockerConfigManager.get().general.titleContainer.direction = switch (current) { + case HORIZONTAL -> SkyblockerConfig.Direction.VERTICAL; + case VERTICAL -> SkyblockerConfig.Direction.HORIZONTAL; + }; + } + if (keyCode == GLFW.GLFW_KEY_EQUAL) { + SkyblockerConfigManager.get().general.titleContainer.titleContainerScale += 10; + } + if (keyCode == GLFW.GLFW_KEY_MINUS) { + SkyblockerConfigManager.get().general.titleContainer.titleContainerScale -= 10; + } + return super.keyPressed(keyCode, scanCode, modifiers); + } + + @Override + public void close() { + SkyblockerConfigManager.get().general.titleContainer.x = (int) hudX; + SkyblockerConfigManager.get().general.titleContainer.y = (int) hudY; + SkyblockerConfigManager.save(); + this.client.setScreen(parent); + } +} |