diff --git a/src/main/java/net/earthcomputer/clientcommands/c2c/chess/ChessScreen.java b/src/main/java/net/earthcomputer/clientcommands/c2c/chess/ChessScreen.java index 7a99029a..fbba1876 100644 --- a/src/main/java/net/earthcomputer/clientcommands/c2c/chess/ChessScreen.java +++ b/src/main/java/net/earthcomputer/clientcommands/c2c/chess/ChessScreen.java @@ -9,6 +9,7 @@ import net.earthcomputer.clientcommands.c2c.packets.ChessResignC2CPacket; import net.earthcomputer.clientcommands.command.ClientCommandHelper; import net.earthcomputer.clientcommands.features.TwoPlayerGame; +import net.earthcomputer.clientcommands.interfaces.ISafeZoneScreen; import net.earthcomputer.clientcommands.render.ColoredTriangleRenderState; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; @@ -49,7 +50,7 @@ import java.util.Set; import java.util.stream.Stream; -public final class ChessScreen extends Screen { +public final class ChessScreen extends Screen implements ISafeZoneScreen { private static final Identifier BOARD_TEXTURE = Identifier.fromNamespaceAndPath("clientcommands", "textures/chess/board.png"); private static final Identifier SQUARE_HIGHLIGHT_TEXTURE = Identifier.fromNamespaceAndPath("clientcommands", "textures/chess/square_highlight.png"); private static final Identifier CAPTURE_HIGHLIGHT_TEXTURE = Identifier.fromNamespaceAndPath("clientcommands", "textures/chess/capture_highlight.png"); @@ -750,6 +751,16 @@ class Constants { } } + @Override + public int getSafeZoneWidth() { + return BOARD_SIZE; + } + + @Override + public int getSafeZoneHeight() { + return BOARD_SIZE; + } + private record Arrow(Vector2i from, Vector2i to) { } diff --git a/src/main/java/net/earthcomputer/clientcommands/command/ConnectFourCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/ConnectFourCommand.java index 996ec18b..a6f1b99a 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/ConnectFourCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/ConnectFourCommand.java @@ -7,6 +7,7 @@ import net.earthcomputer.clientcommands.c2c.C2CPacketHandler; import net.earthcomputer.clientcommands.c2c.packets.PutConnectFourPieceC2CPacket; import net.earthcomputer.clientcommands.features.TwoPlayerGame; +import net.earthcomputer.clientcommands.interfaces.ISafeZoneScreen; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; @@ -254,7 +255,7 @@ public enum Winner { DRAW } - public static class ConnectFourGameScreen extends Screen { + public static class ConnectFourGameScreen extends Screen implements ISafeZoneScreen { private final ConnectFourGame game; private static final Identifier BOARD_TEXTURE = Identifier.fromNamespaceAndPath("clientcommands", "textures/connect_four/board.png"); @@ -381,5 +382,15 @@ public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { return false; } + + @Override + public int getSafeZoneWidth() { + return BOARD_WIDTH; + } + + @Override + public int getSafeZoneHeight() { + return BOARD_HEIGHT; + } } } diff --git a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java index ad1c5ee1..ea77a346 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/MinesweeperCommand.java @@ -5,6 +5,7 @@ import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import net.earthcomputer.clientcommands.interfaces.ISafeZoneScreen; import it.unimi.dsi.fastutil.ints.IntArrayList; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.client.gui.GuiGraphicsExtractor; @@ -55,7 +56,7 @@ private static int minesweeper(FabricClientCommandSource source, int width, int return Command.SINGLE_SUCCESS; } - private static class MinesweeperGameScreen extends Screen { + private static class MinesweeperGameScreen extends Screen implements ISafeZoneScreen { private static final Identifier MINESWEEPER_ATLAS = Identifier.fromNamespaceAndPath("clientcommands", "textures/minesweeper_atlas.png"); private static final int MINESWEEPER_ATLAS_WIDTH = 128; private static final int MINESWEEPER_ATLAS_HEIGHT = 64; @@ -436,5 +437,15 @@ private byte createTile(boolean covered, boolean flagged, int type, @Nullable In return (byte) ((covered ? 0 : 1) | ((flagged ? 1 : 0) << 1) | (type << 2) | ((warningQuantity == null ? 0 : warningQuantity - 1) << 4)); } + + @Override + public int getSafeZoneWidth() { + return gameWidth; + } + + @Override + public int getSafeZoneHeight() { + return gameHeight; + } } } diff --git a/src/main/java/net/earthcomputer/clientcommands/command/SnakeCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/SnakeCommand.java index 8130002f..19e690bf 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/SnakeCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/SnakeCommand.java @@ -2,6 +2,7 @@ import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; +import net.earthcomputer.clientcommands.interfaces.ISafeZoneScreen; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; @@ -41,7 +42,7 @@ After executing a command, the current screen will be closed (the chat hud). } } -class SnakeGameScreen extends Screen { +class SnakeGameScreen extends Screen implements ISafeZoneScreen { private static final Minecraft minecraft = Minecraft.getInstance(); @@ -156,4 +157,14 @@ private boolean setDirection(Direction direction) { this.direction = direction; return true; } + + @Override + public int getSafeZoneWidth() { + return 16 + BOARD_SIZE + 16; + } + + @Override + public int getSafeZoneHeight() { + return 16 + BOARD_SIZE + 16; + } } diff --git a/src/main/java/net/earthcomputer/clientcommands/command/TicTacToeCommand.java b/src/main/java/net/earthcomputer/clientcommands/command/TicTacToeCommand.java index ac55c167..570f4556 100644 --- a/src/main/java/net/earthcomputer/clientcommands/command/TicTacToeCommand.java +++ b/src/main/java/net/earthcomputer/clientcommands/command/TicTacToeCommand.java @@ -6,6 +6,7 @@ import net.earthcomputer.clientcommands.c2c.C2CPacketHandler; import net.earthcomputer.clientcommands.c2c.packets.PutTicTacToeMarkC2CPacket; import net.earthcomputer.clientcommands.features.TwoPlayerGame; +import net.earthcomputer.clientcommands.interfaces.ISafeZoneScreen; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; @@ -118,7 +119,7 @@ public Mark opposite() { } } - public static class TicTacToeGameScreen extends Screen { + public static class TicTacToeGameScreen extends Screen implements ISafeZoneScreen { private final TicTacToeGame game; private static final Identifier GRID_TEXTURE = Identifier.fromNamespaceAndPath("clientcommands", "textures/tic_tac_toe/grid.png"); @@ -200,5 +201,15 @@ public boolean mouseClicked(MouseButtonEvent event, boolean doubleClick) { } return false; } + + @Override + public int getSafeZoneWidth() { + return GRID_SIZE; + } + + @Override + public int getSafeZoneHeight() { + return GRID_SIZE; + } } } diff --git a/src/main/java/net/earthcomputer/clientcommands/interfaces/ISafeZoneScreen.java b/src/main/java/net/earthcomputer/clientcommands/interfaces/ISafeZoneScreen.java new file mode 100644 index 00000000..640ae274 --- /dev/null +++ b/src/main/java/net/earthcomputer/clientcommands/interfaces/ISafeZoneScreen.java @@ -0,0 +1,7 @@ +package net.earthcomputer.clientcommands.interfaces; + +public interface ISafeZoneScreen { + int getSafeZoneWidth(); + + int getSafeZoneHeight(); +} diff --git a/src/main/java/net/earthcomputer/clientcommands/mixin/screen/MinecraftMixin.java b/src/main/java/net/earthcomputer/clientcommands/mixin/screen/MinecraftMixin.java new file mode 100644 index 00000000..549035e6 --- /dev/null +++ b/src/main/java/net/earthcomputer/clientcommands/mixin/screen/MinecraftMixin.java @@ -0,0 +1,41 @@ +package net.earthcomputer.clientcommands.mixin.screen; + +import com.llamalad7.mixinextras.expression.Definition; +import com.llamalad7.mixinextras.expression.Expression; +import com.mojang.blaze3d.platform.Window; +import net.minecraft.client.Minecraft; +import net.minecraft.client.Options; +import net.minecraft.client.gui.screens.Screen; +import org.jspecify.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Minecraft.class) +public abstract class MinecraftMixin { + @Shadow + @Nullable + public Screen screen; + + @Shadow + @Final + private Window window; + + @Shadow + @Final + public Options options; + + @Shadow + public abstract boolean isEnforceUnicode(); + + @Definition(id = "screen", field = "Lnet/minecraft/client/Minecraft;screen:Lnet/minecraft/client/gui/screens/Screen;") + @Expression("this.screen = ?") + @Inject(method = "setScreen", at = @At(value = "MIXINEXTRAS:EXPRESSION", shift = At.Shift.AFTER)) + private void onReplacement(Screen newScreen, CallbackInfo ci) { + // recache required due to `IScreenSafeZone` + window.setGuiScale(window.calculateScale(options.guiScale().get(), isEnforceUnicode())); + } +} diff --git a/src/main/java/net/earthcomputer/clientcommands/mixin/screen/WindowMixin.java b/src/main/java/net/earthcomputer/clientcommands/mixin/screen/WindowMixin.java new file mode 100644 index 00000000..477c51d1 --- /dev/null +++ b/src/main/java/net/earthcomputer/clientcommands/mixin/screen/WindowMixin.java @@ -0,0 +1,29 @@ +package net.earthcomputer.clientcommands.mixin.screen; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.mojang.blaze3d.platform.Window; +import net.earthcomputer.clientcommands.interfaces.ISafeZoneScreen; +import net.minecraft.client.Minecraft; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(Window.class) +public class WindowMixin { + @ModifyExpressionValue(method = "calculateScale", at = @At(value = "CONSTANT", args = "intValue=" + Window.BASE_WIDTH)) + private int getSafeZoneWidth(int original) { + Minecraft mc = Minecraft.getInstance(); + if (mc.screen instanceof ISafeZoneScreen safeZone) { + original = Math.max(original, safeZone.getSafeZoneWidth()); + } + return original; + } + + @ModifyExpressionValue(method = "calculateScale", at = @At(value = "CONSTANT", args = "intValue=" + Window.BASE_HEIGHT)) + private int getSafeZoneHeight(int original) { + Minecraft mc = Minecraft.getInstance(); + if (mc.screen instanceof ISafeZoneScreen safeZone) { + original = Math.max(original, safeZone.getSafeZoneHeight()); + } + return original; + } +} diff --git a/src/main/resources/mixins.clientcommands.json b/src/main/resources/mixins.clientcommands.json index ebdd5e54..ba920d27 100644 --- a/src/main/resources/mixins.clientcommands.json +++ b/src/main/resources/mixins.clientcommands.json @@ -85,6 +85,8 @@ "lengthextender.ChatScreenMixin", "rngevents.ClientLevelMixin", "scrambletitle.MinecraftMixin", + "screen.MinecraftMixin", + "screen.WindowMixin", "suggestionshook.ClientPacketListenerMixin" ] }