diff --git a/src/main/java/com/mosadie/servermainmenu/api/MenuTheme.java b/src/main/java/com/mosadie/servermainmenu/api/MenuTheme.java index d9d1c09..6fe2775 100644 --- a/src/main/java/com/mosadie/servermainmenu/api/MenuTheme.java +++ b/src/main/java/com/mosadie/servermainmenu/api/MenuTheme.java @@ -8,11 +8,7 @@ public interface MenuTheme { String getId(); Identifier getPanorama(); - @Deprecated - default String getSplashText() { - return null; - } - Text getSplashAsText(); + SplashText getSplashText(); boolean rollOdds(); diff --git a/src/main/java/com/mosadie/servermainmenu/api/NormalTheme.java b/src/main/java/com/mosadie/servermainmenu/api/NormalTheme.java index 2d31016..d575d03 100644 --- a/src/main/java/com/mosadie/servermainmenu/api/NormalTheme.java +++ b/src/main/java/com/mosadie/servermainmenu/api/NormalTheme.java @@ -20,8 +20,11 @@ public Identifier getPanorama() { } @Override - public Text getSplashAsText() { - return Text.literal("Just a normal menu..."); + public SplashText getSplashText() { + return SplashText.builder() + .addLine("Just a normal menu...") + .addLine("yay!") + .build(); } @Override diff --git a/src/main/java/com/mosadie/servermainmenu/api/SplashText.java b/src/main/java/com/mosadie/servermainmenu/api/SplashText.java new file mode 100644 index 0000000..6e954ec --- /dev/null +++ b/src/main/java/com/mosadie/servermainmenu/api/SplashText.java @@ -0,0 +1,35 @@ +package com.mosadie.servermainmenu.api; + +import net.minecraft.text.Text; + +import java.util.ArrayList; +import java.util.List; + +public record SplashText(Text[] lines) { + public static Builder builder(Text text) { + return builder().addLine(text); + } + public static Builder builder(String text) { + return builder().addLine(text); + } + public static Builder builder() { + return new Builder(); + } + + public static final class Builder { + private final List lines = new ArrayList<>(); + + public Builder addLine(Text text) { + lines.add(text); + return this; + } + public Builder addLine(String text) { + lines.add(Text.literal(text).setStyle(Util.SPLASH_TEXT_STYLE)); + return this; + } + + public SplashText build() { + return new SplashText(lines.toArray(Text[]::new)); + } + } +} diff --git a/src/main/java/com/mosadie/servermainmenu/client/ServerMainMenuLibClient.java b/src/main/java/com/mosadie/servermainmenu/client/ServerMainMenuLibClient.java index 3326166..0760f92 100644 --- a/src/main/java/com/mosadie/servermainmenu/client/ServerMainMenuLibClient.java +++ b/src/main/java/com/mosadie/servermainmenu/client/ServerMainMenuLibClient.java @@ -78,15 +78,12 @@ public static MenuTheme getTheme() { private static ServerMainMenuLibConfig config; - @SuppressWarnings("deprecation") - public static Text getSplashText() { + public static Text[] getSplashText() { if (config != null && config.splashOptions.overrideSplash) { - return Text.of(config.splashOptions.overrideSplashText); + return new Text[] { Text.of(config.splashOptions.overrideSplashText) }; } - // Should still work with old mods that don't implement the asText method I hope... - if (getTheme().getSplashText() != null) return Text.literal(getTheme().getSplashText()).setStyle(Util.SPLASH_TEXT_STYLE); - return getTheme().getSplashAsText(); + return getTheme().getSplashText().lines(); } public static Text getButtonText() { diff --git a/src/main/java/com/mosadie/servermainmenu/duck/MultilineSplashTextRenderer.java b/src/main/java/com/mosadie/servermainmenu/duck/MultilineSplashTextRenderer.java new file mode 100644 index 0000000..4c1c954 --- /dev/null +++ b/src/main/java/com/mosadie/servermainmenu/duck/MultilineSplashTextRenderer.java @@ -0,0 +1,7 @@ +package com.mosadie.servermainmenu.duck; + +import net.minecraft.text.Text; + +public interface MultilineSplashTextRenderer { + void smm_lib$setMultilineText(Text[] multilineText); +} diff --git a/src/main/java/com/mosadie/servermainmenu/mixin/SplashTextRendererMixin.java b/src/main/java/com/mosadie/servermainmenu/mixin/SplashTextRendererMixin.java new file mode 100644 index 0000000..00c21ad --- /dev/null +++ b/src/main/java/com/mosadie/servermainmenu/mixin/SplashTextRendererMixin.java @@ -0,0 +1,62 @@ +package com.mosadie.servermainmenu.mixin; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.mosadie.servermainmenu.duck.MultilineSplashTextRenderer; +import net.minecraft.client.font.Alignment; +import net.minecraft.client.font.DrawnTextConsumer; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.screen.SplashTextRenderer; +import net.minecraft.text.StringVisitable; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(SplashTextRenderer.class) +public abstract class SplashTextRendererMixin implements MultilineSplashTextRenderer { + @Unique + private Text[] smm_lib$multilineText; + + @WrapOperation( + method = "render", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/font/TextRenderer;getWidth(Lnet/minecraft/text/StringVisitable;)I" + ) + ) + private int smm_lib$getMultilineTextWidth(TextRenderer instance, StringVisitable text, Operation original) { + if (smm_lib$multilineText == null) return original.call(instance, text); + + int result = 0; + for (Text line : smm_lib$multilineText) { + result = Math.max(original.call(instance, line), result); + } + return result; + } + + @WrapOperation( + method = "render", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/font/DrawnTextConsumer;text(Lnet/minecraft/client/font/Alignment;IILnet/minecraft/client/font/DrawnTextConsumer$Transformation;Lnet/minecraft/text/Text;)V" + ) + ) + private void smm_lib$renderMultilineText(DrawnTextConsumer instance, Alignment alignment, int x, int y, DrawnTextConsumer.Transformation transformation, Text text, Operation original) { + if (smm_lib$multilineText == null) { + original.call(instance, alignment, x, y, transformation, text); + return; + } + + for (Text line : smm_lib$multilineText) { + // Use center alignment as then... idk I'd say it looks better + original.call(instance, Alignment.CENTER, 0, y, transformation, line); + y += 9; + } + } + + @Override + public void smm_lib$setMultilineText(Text[] multilineText) { + this.smm_lib$multilineText = multilineText; + } +} diff --git a/src/main/java/com/mosadie/servermainmenu/mixin/TitleScreenMixin.java b/src/main/java/com/mosadie/servermainmenu/mixin/TitleScreenMixin.java index 392e93a..cd3f611 100644 --- a/src/main/java/com/mosadie/servermainmenu/mixin/TitleScreenMixin.java +++ b/src/main/java/com/mosadie/servermainmenu/mixin/TitleScreenMixin.java @@ -1,6 +1,7 @@ package com.mosadie.servermainmenu.mixin; import com.mosadie.servermainmenu.client.ServerMainMenuLibClient; +import com.mosadie.servermainmenu.duck.MultilineSplashTextRenderer; import com.terraformersmc.modmenu.ModMenu; import com.terraformersmc.modmenu.api.ModMenuApi; import net.minecraft.client.MinecraftClient; @@ -45,8 +46,12 @@ private void injectOnDisplayed(CallbackInfo ci) { @Inject(method = "init()V", at = @At("HEAD")) private void injectSplashText(CallbackInfo info) { - if (splashText == null) - this.splashText = new SplashTextRenderer(ServerMainMenuLibClient.getSplashText()); + if (splashText == null) { + Text[] splashes = ServerMainMenuLibClient.getSplashText(); + // Still provide the first line or empty to avoid anything else that tries to use it crashing + this.splashText = new SplashTextRenderer(splashes.length == 0 ? Text.of("") : splashes[0]); + ((MultilineSplashTextRenderer) this.splashText).smm_lib$setMultilineText(splashes); + } } @Redirect(method = "init()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/TitleScreen;addNormalWidgets(II)I")) diff --git a/src/main/resources/servermainmenu-lib.mixins.json b/src/main/resources/servermainmenu-lib.mixins.json index cff9e33..a95455f 100644 --- a/src/main/resources/servermainmenu-lib.mixins.json +++ b/src/main/resources/servermainmenu-lib.mixins.json @@ -6,9 +6,10 @@ "mixins": [ ], "client": [ + "IdentifierMixin", + "SplashTextRendererMixin", "TitleScreenInvoker", - "TitleScreenMixin", - "IdentifierMixin" + "TitleScreenMixin" ], "injectors": { "defaultRequire": 1