diff --git a/gradle.properties b/gradle.properties index 345fac7..d43ae89 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,22 +3,22 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use -minecraft_version=1.20 -yarn_mappings=1.20+build.1 -loader_version=0.14.21 +minecraft_version=1.20.2 +yarn_mappings=1.20.2+build.1 +loader_version=0.14.22 # Mod Properties -mod_version = 1.8.2 +mod_version = 1.8.3 maven_group = eu.midnightdust archives_base_name = midnightcontrols modrinth_id=bXX9h73M # Dependencies # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api -fabric_version=0.83.0+1.20 +fabric_version=0.89.2+1.20.2 sodium_version=mc1.19.2-0.4.4 spruceui_version=5.0.0+1.20 -midnightlib_version=1.4.1-fabric +midnightlib_version=1.5.0-fabric modmenu_version=7.0.0 emotecraft_version=2.1.3-SNAPSHOT-build.29-MC1.19-fabric bendylib_version=2.0.+ diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java index a742b0f..0e3b38e 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java @@ -28,6 +28,7 @@ import eu.midnightdust.midnightcontrols.client.mixin.KeyBindingRegistryImplAcces import eu.midnightdust.midnightcontrols.client.ring.ButtonBindingRingAction; import eu.midnightdust.midnightcontrols.client.ring.MidnightRing; import dev.lambdaurora.spruceui.hud.HudManager; +import eu.midnightdust.midnightcontrols.client.util.RainbowColor; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; @@ -122,20 +123,21 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo this.input.onScreenOpen(client, client.getWindow().getWidth(), client.getWindow().getHeight()); } }); + final MinecraftClient client = MinecraftClient.getInstance(); + int delay = 0; // delay for 0 sec. + int period = 1; // repeat every 0.001 sec. (100 times a second) + Timer timer = new Timer(); + timer.scheduleAtFixedRate(new TimerTask() { + public void run() { + input.updateCamera(client); + } + }, delay, period); HudManager.register(this.hud = new MidnightControlsHud(this)); FabricLoader.getInstance().getModContainer("midnightcontrols").ifPresent(modContainer -> { ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","bedrock"), modContainer, ResourcePackActivationType.NORMAL); ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","legacy"), modContainer, ResourcePackActivationType.NORMAL); }); - int delay = 0; // delay for 0 sec. - int period = 1; // repeat every 0.001 sec. (100 times a second) - Timer timer = new Timer(); - timer.scheduleAtFixedRate(new TimerTask() { - public void run() { - input.updateCamera(MinecraftClient.getInstance()); - } - }, delay, period); } /** @@ -227,9 +229,7 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo MidnightControlsConfig.enableHints = false; MidnightControlsConfig.save(); } - } - public void onRender(MinecraftClient client) { - //this.input.onRender(client); + RainbowColor.tick(); } /** diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java index 2476180..820978c 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java @@ -18,8 +18,10 @@ import eu.midnightdust.midnightcontrols.MidnightControlsFeature; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import eu.midnightdust.midnightcontrols.client.controller.Controller; import eu.midnightdust.midnightcontrols.client.controller.InputManager; +import eu.midnightdust.midnightcontrols.client.touch.TouchMode; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ChatScreen; +import net.minecraft.client.gui.screen.advancement.AdvancementsScreen; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.lwjgl.glfw.GLFW; @@ -79,6 +81,10 @@ public class MidnightControlsConfig extends MidnightConfig { "me.shedaniel.clothconfig2.gui.ClothConfigScreen", "com.mamiyaotaru.voxelmap.gui.GuiWaypoints", "com.mamiyaotaru.voxelmap.gui.GuiPersistentMap"); @Entry(category = "screens", name = "Arrow screens") public static List arrowScreens = Lists.newArrayList(ChatScreen.class.getCanonicalName()); @Entry(category = "screens", name = "WASD screens") public static List wasdScreens = Lists.newArrayList("com.ultreon.devices.core.Laptop"); + @Entry(category = "touch", name = "Screens with close button") public static List closeButtonScreens = Lists.newArrayList(ChatScreen.class.getCanonicalName(), AdvancementsScreen.class.getCanonicalName()); + @Entry(category = "touch", name = "midnightcontrols.menu.touch_speed", isSlider = true, min = 0, max = 150, precision = 10) public static double touchSpeed = 25.0; + @Entry(category = "touch", name = "midnightcontrols.menu.touch_mode") public static TouchMode touchMode = TouchMode.CROSSHAIR; + @Entry @Hidden public static Map BINDING = new HashMap<>(); private static final Pattern BUTTON_BINDING_PATTERN = Pattern.compile("(-?\\d+)\\+?"); diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java index 8193ece..2dd875c 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java @@ -203,18 +203,8 @@ public class MidnightInput { } client.getTutorialManager().onUpdateMouse(this.targetPitch, this.targetYaw); MidnightControlsCompat.HANDLERS.forEach(handler -> handler.handleCamera(client, targetYaw, targetPitch)); - this.onRender(client); } } - /** - * This method is deprecated and will be removed in future versions - * It is just kept, because the current version of 'Do a Barrel Roll' mixins into this method - * - * @param client the client instance - */ - @Deprecated - public void onRender(@NotNull MinecraftClient client) { - } /** * This method is called when a Screen is opened. @@ -540,7 +530,7 @@ public class MidnightInput { var accessor = (CreativeInventoryScreenAccessor) creativeInventoryScreen; // @TODO allow rebinding to left stick if (accessor.midnightcontrols$hasScrollbar() && absValue >= deadZone) { - creativeInventoryScreen.mouseScrolled(0.0, 0.0, -value); + creativeInventoryScreen.mouseScrolled(0.0, 0.0, 0, -value); } return; } @@ -548,7 +538,7 @@ public class MidnightInput { if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) { // @TODO allow rebinding to left stick if (absValue >= deadZone) { - merchantScreen.mouseScrolled(0.0, 0.0, -(value * 1.5f)); + merchantScreen.mouseScrolled(0.0, 0.0, 0, -(value * 1.5f)); } return; } @@ -556,7 +546,7 @@ public class MidnightInput { if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y) { // @TODO allow rebinding to left stick if (absValue >= deadZone) { - stonecutterScreen.mouseScrolled(0.0, 0.0, -(value * 1.5f)); + stonecutterScreen.mouseScrolled(0.0, 0.0, 0, -(value * 1.5f)); } return; } @@ -575,7 +565,7 @@ public class MidnightInput { .map(element -> (SpruceEntryListWidget) element) .filter(AbstractSpruceWidget::isFocusedOrHovered) .noneMatch(element -> { - element.mouseScrolled(0.0, 0.0, -finalValue); + element.mouseScrolled(0.0, 0.0, 0, -finalValue); return true; }) && @@ -583,11 +573,11 @@ public class MidnightInput { .map(element -> (EntryListWidget) element) .filter(element -> element.getType().isFocused()) .noneMatch(element -> { - element.mouseScrolled(0.0, 0.0, -finalValue); + element.mouseScrolled(0.0, 0.0, 0, -finalValue); return true; })) { - client.currentScreen.mouseScrolled(0.0, 0.0, -(value * 1.5f)); + client.currentScreen.mouseScrolled(0.0, 0.0, 0, -(value * 1.5f)); } else if (isScreenInteractive(client.currentScreen) && absValue >= deadZone) { if (value > 0 && joystickCooldown == 0) { diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightReacharound.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightReacharound.java index 52b3b21..ca9554d 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightReacharound.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightReacharound.java @@ -73,7 +73,7 @@ public class MidnightReacharound { return MidnightControlsFeature.HORIZONTAL_REACHAROUND.isAvailable() || MidnightControlsFeature.VERTICAL_REACHAROUND.isAvailable(); } - private float getPlayerRange(@NotNull MinecraftClient client) { + public static float getPlayerRange(@NotNull MinecraftClient client) { return client.interactionManager != null ? client.interactionManager.getReachDistance() : 0.f; } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/ButtonBinding.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/ButtonBinding.java index 4402653..a574c62 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/ButtonBinding.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/ButtonBinding.java @@ -13,6 +13,8 @@ import eu.midnightdust.midnightcontrols.client.ButtonState; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.gui.RingScreen; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.hud.DebugHud; +import net.minecraft.client.gui.hud.InGameHud; import net.minecraft.client.option.GameOptions; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.resource.language.I18n; @@ -75,9 +77,8 @@ public class ButtonBinding { .action(MovementHandler.HANDLER).onlyInGame().register(); public static final ButtonBinding SCREENSHOT = new Builder("screenshot").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_A) .action(InputHandlers::handleScreenshot).cooldown().register(); - public static final ButtonBinding DEBUG_SCREEN = new Builder("debug_screen").buttons(GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_GAMEPAD_BUTTON_B) - .action((client,binding,value,action) -> {if (action == ButtonState.PRESS) client.options.debugEnabled = !client.options.debugEnabled; return true;}).cooldown().register(); + .action((client,binding,value,action) -> {if (action == ButtonState.PRESS) client.inGameHud.getDebugHud().toggleDebugHud(); return true;}).cooldown().register(); public static final ButtonBinding SLOT_DOWN = new Builder("slot_down").buttons(GLFW_GAMEPAD_BUTTON_DPAD_DOWN) .action(InputHandlers.handleInventorySlotPad(1)).onlyInInventory().cooldown().register(); public static final ButtonBinding SLOT_LEFT = new Builder("slot_left").buttons(GLFW_GAMEPAD_BUTTON_DPAD_LEFT) diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java index b39c68a..d917f91 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java @@ -10,6 +10,7 @@ package eu.midnightdust.midnightcontrols.client.controller; import com.google.common.collect.Lists; +import eu.midnightdust.lib.util.PlatformFunctions; import eu.midnightdust.midnightcontrols.client.ButtonState; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; @@ -19,17 +20,16 @@ import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; import eu.midnightdust.midnightcontrols.client.compat.SodiumCompat; import eu.midnightdust.midnightcontrols.client.compat.YACLCompat; import eu.midnightdust.midnightcontrols.client.gui.RingScreen; +import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay; import eu.midnightdust.midnightcontrols.client.mixin.AdvancementsScreenAccessor; import eu.midnightdust.midnightcontrols.client.mixin.CreativeInventoryScreenAccessor; import eu.midnightdust.midnightcontrols.client.mixin.RecipeBookWidgetAccessor; import eu.midnightdust.midnightcontrols.client.mixin.TabNavigationWidgetAccessor; import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor; import eu.midnightdust.midnightcontrols.client.util.MouseAccessor; -import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; import net.fabricmc.fabric.impl.client.itemgroup.CreativeGuiExtensions; import net.fabricmc.fabric.impl.client.itemgroup.FabricCreativeGuiComponents; import net.fabricmc.fabric.impl.itemgroup.FabricItemGroup; -import net.fabricmc.fabric.impl.itemgroup.ItemGroupEventsImpl; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.TitleScreen; @@ -100,6 +100,7 @@ public class InputHandlers { } else if (client.currentScreen instanceof RingScreen) { MidnightControlsClient.get().ring.cyclePage(next); } else if (client.currentScreen instanceof CreativeInventoryScreenAccessor inventory) { + if (PlatformFunctions.isModLoaded("connectormod")) return true; ItemGroup currentTab = CreativeInventoryScreenAccessor.getSelectedTab(); int currentColumn = currentTab.getColumn(); ItemGroup.Row currentRow = currentTab.getRow(); @@ -160,7 +161,7 @@ public class InputHandlers { nextTab = tabs.size() - 1; else if (nextTab >= tabs.size()) nextTab = 0; - screen.getAdvancementManager().selectTab(tabs.get(nextTab).getRoot(), true); + screen.getAdvancementManager().selectTab(tabs.get(nextTab).getRoot().getAdvancementEntry(), true); break; } } @@ -277,7 +278,7 @@ public class InputHandlers { if (action == ButtonState.PRESS) { // If in game, then pause the game. if (client.currentScreen == null || client.currentScreen instanceof RingScreen) - client.openPauseMenu(false); + client.openGameMenu(false); else if (client.currentScreen instanceof HandledScreen && client.player != null) // If the current screen is a container then close it. client.player.closeHandledScreen(); else // Else just close the current screen. @@ -418,7 +419,7 @@ public class InputHandlers { * @return true if the client is in game, else false */ public static boolean inGame(@NotNull MinecraftClient client, @NotNull ButtonBinding binding) { - return (client.currentScreen == null && MidnightControlsClient.get().input.screenCloseCooldown <= 0) || client.currentScreen instanceof RingScreen; + return (client.currentScreen == null && MidnightControlsClient.get().input.screenCloseCooldown <= 0) || client.currentScreen instanceof TouchscreenOverlay || client.currentScreen instanceof RingScreen; } /** diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsRenderer.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsRenderer.java index 0917938..b4afbd9 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsRenderer.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/MidnightControlsRenderer.java @@ -21,9 +21,7 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.resource.language.I18n; -import net.minecraft.client.util.math.MatrixStack; import net.minecraft.screen.slot.Slot; -import net.minecraft.util.Identifier; import org.jetbrains.annotations.NotNull; import org.lwjgl.glfw.GLFW; @@ -234,6 +232,7 @@ public class MidnightControlsRenderer { } //context.getMatrices().push(); + context.getMatrices().translate(0f, 0f, 999f); drawCursor(context, mouseX, mouseY, hoverSlot, client); //context.getMatrices().pop(); } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/TouchscreenOverlay.java b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/TouchscreenOverlay.java index 8fa1d61..4ef1a75 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/gui/TouchscreenOverlay.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/gui/TouchscreenOverlay.java @@ -15,16 +15,23 @@ import eu.midnightdust.midnightcontrols.client.HudSide; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.gui.widget.SilentTexturedButtonWidget; +import eu.midnightdust.midnightcontrols.client.touch.TouchUtils; import eu.midnightdust.midnightcontrols.client.util.KeyBindingAccessor; -import net.minecraft.client.gui.screen.ChatScreen; -import net.minecraft.client.gui.screen.GameMenuScreen; -import net.minecraft.client.gui.screen.Screen; +import net.minecraft.block.BlockState; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.*; import net.minecraft.client.gui.screen.ingame.InventoryScreen; -import net.minecraft.client.gui.widget.TexturedButtonWidget; +import net.minecraft.client.gui.widget.TextIconButtonWidget; +import net.minecraft.client.option.KeyBinding; +import net.minecraft.client.util.InputUtil; +import net.minecraft.item.ItemStack; import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.text.Text; import net.minecraft.util.Arm; import net.minecraft.util.Identifier; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.EntityHitResult; +import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import org.jetbrains.annotations.NotNull; @@ -62,11 +69,7 @@ public class TouchscreenOverlay extends Screen { } @Override - public boolean keyPressed(int keyCode, int scanCode, int modifiers) { - super.keyPressed(keyCode,scanCode,modifiers); - //return false; - return true; - } + public void renderInGameBackground(DrawContext context) {} private void pauseGame(boolean bl) { if (this.client == null) @@ -135,28 +138,15 @@ public class TouchscreenOverlay extends Screen { ((KeyBindingAccessor) this.client.options.jumpKey).midnightcontrols$handlePressState(state); } - @Override - public void tick() { - if (this.forwardButtonTick > 0) { - this.forwardButtonTick--; - } else if (this.forwardButtonTick == 0) { - if (this.forwardLeftButton.isVisible()) - this.forwardLeftButton.setVisible(false); - if (this.forwardRightButton.isVisible()) - this.forwardRightButton.setVisible(false); - } - this.updateJumpButtons(); - } - @Override protected void init() { super.init(); int scaledWidth = this.client.getWindow().getScaledWidth(); int scaledHeight = this.client.getWindow().getScaledHeight(); - this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2 - 20, 0, 20, 20, 0, 106, 20, new Identifier("textures/gui/widgets.png"), 256, 256, - btn -> this.client.setScreen(new ChatScreen("")), Text.empty())); - this.addDrawableChild(new TexturedButtonWidget(scaledWidth / 2, 0, 20, 20, 0, 0, 20, WIDGETS_LOCATION, 256, 256, - btn -> this.pauseGame(false))); + TextIconButtonWidget chatButton = TextIconButtonWidget.builder(Text.empty(), btn -> this.client.setScreen(new ChatScreen("")), true).width(20).texture(new Identifier("icon/language"), 15, 15).build(); + chatButton.setPosition(scaledWidth / 2 - 20, 0); + this.addDrawableChild(chatButton); + this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(scaledWidth / 2, 0), 20, 20, Text.empty(), btn -> this.pauseGame(false), 0, 0, 20, WIDGETS_LOCATION, 256, 256)); // Inventory buttons. int inventoryButtonX = scaledWidth / 2; int inventoryButtonY = scaledHeight - 16 - 5; @@ -165,15 +155,15 @@ public class TouchscreenOverlay extends Screen { } else { inventoryButtonX = inventoryButtonX + 91 + 4; } - this.addDrawableChild(new TexturedButtonWidget(inventoryButtonX, inventoryButtonY, 20, 20, 20, 0, 20, WIDGETS_LOCATION, 256, 256, - btn -> { - if (this.client.interactionManager.hasRidingInventory()) { - this.client.player.openRidingInventory(); - } else { - this.client.getTutorialManager().onInventoryOpened(); - this.client.setScreen(new InventoryScreen(this.client.player)); - } - })); + this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(inventoryButtonX, inventoryButtonY), 20, 20, Text.empty(), btn -> { + if (this.client.interactionManager.hasRidingInventory()) { + this.client.player.openRidingInventory(); + } else { + this.client.getTutorialManager().onInventoryOpened(); + this.client.setScreen(new InventoryScreen(this.client.player)); + } + }, 20, 0, 20, WIDGETS_LOCATION, 256, 256)); + ; int jumpButtonX, swapHandsX, sneakButtonX; int sneakButtonY = scaledHeight - 10 - 40 - 5; if (MidnightControlsConfig.hudSide == HudSide.LEFT) { @@ -196,7 +186,7 @@ public class TouchscreenOverlay extends Screen { },0, 160, 20, WIDGETS_LOCATION)); // Drop this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(swapHandsX, sneakButtonY + 5 + 20), 20, 20, Text.empty(), btn -> - ((KeyBindingAccessor) this.client.options.dropKey).midnightcontrols$handlePressState(btn.isActive()), 0, 160, 20, WIDGETS_LOCATION)); + client.player.getInventory().dropSelectedItem(false), 20, 160, 20, WIDGETS_LOCATION)); // Jump keys this.addDrawableChild(this.jumpButton = new SilentTexturedButtonWidget(Position.of(jumpButtonX, sneakButtonY), 20, 20, Text.empty(), this::handleJump, 0, 40, 20, WIDGETS_LOCATION)); this.addDrawableChild(this.flyButton = new SilentTexturedButtonWidget(Position.of(jumpButtonX, sneakButtonY), 20, 20, Text.empty(),btn -> { @@ -247,7 +237,7 @@ public class TouchscreenOverlay extends Screen { this.updateForwardButtonsState(btn.isActive()); }, 100, 80, 20, WIDGETS_LOCATION )); - this.forwardRightButton.setVisible(true); + this.forwardRightButton.setVisible(false); this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(sneakButtonX + 20 + 5, sneakButtonY), 20, 20, Text.empty(), btn -> ((KeyBindingAccessor) this.client.options.rightKey).midnightcontrols$handlePressState(btn.isActive()), 20, 80, 20, WIDGETS_LOCATION )); @@ -259,36 +249,120 @@ public class TouchscreenOverlay extends Screen { )); } + @Override + public void tick() { + if (this.forwardButtonTick > 0) { + this.forwardButtonTick--; + } else if (this.forwardButtonTick == 0) { + if (this.forwardLeftButton.isVisible()) + this.forwardLeftButton.setVisible(false); + if (this.forwardRightButton.isVisible()) + this.forwardRightButton.setVisible(false); + } + this.updateJumpButtons(); + double scaleFactor = client.getWindow().getScaleFactor(); + if (clickStartTime > 0 && System.currentTimeMillis() - clickStartTime >= 100) mouseHeldDown(client.mouse.getX() / scaleFactor, client.mouse.getY() / scaleFactor); + else client.interactionManager.cancelBlockBreaking(); + } + + private long clickStartTime; + private double[] firstPosition = new double[2]; @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { - if (mouseY >= (double) (this.height - 22) && this.client != null && this.client.player != null) { - int centerX = this.width / 2; - if (mouseX >= (double) (centerX - 90) && mouseX <= (double) (centerX + 90)) { - for (int slot = 0; slot < 9; ++slot) { - int slotX = centerX - 90 + slot * 20 + 2; - if (mouseX >= (double) slotX && mouseX <= (double) (slotX + 20)) { - this.client.player.getInventory().selectedSlot = slot; + int centerX = this.width / 2; + if (mouseY >= (double) (this.height - 22) && this.client != null && this.client.player != null && mouseX >= (double) (centerX - 90) && mouseX <= (double) (centerX + 90)) { + for (int slot = 0; slot < 9; ++slot) { + int slotX = centerX - 90 + slot * 20 + 2; + if (mouseX >= (double) slotX && mouseX <= (double) (slotX + 20)) { + this.client.player.getInventory().selectedSlot = slot; + return true; + } + } + } else { + clickStartTime = System.currentTimeMillis(); + firstPosition[0] = mouseX; + firstPosition[1] = mouseY; + } + return super.mouseClicked(mouseX, mouseY, button); + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + if (!super.mouseReleased(mouseX, mouseY, button) && System.currentTimeMillis() - clickStartTime < 200) { + clickStartTime = -1; + HitResult result = TouchUtils.getTargettedObject(mouseX, mouseY); + if (result == null) return false; + + if (result.getType() == HitResult.Type.BLOCK) { + BlockHitResult blockHit = (BlockHitResult) result; + BlockPos blockPos = blockHit.getBlockPos().offset(blockHit.getSide()); + BlockState state = client.world.getBlockState(blockPos); + + if (client.world.isAir(blockPos) || state.isReplaceable()) { + ItemStack stackInHand = client.player.getMainHandStack(); + int previousStackCount = stackInHand.getCount(); + var interaction = client.interactionManager.interactBlock(client.player, client.player.getActiveHand(), blockHit); + if (interaction.isAccepted()) { + if (interaction.shouldSwingHand()) { + client.player.swingHand(client.player.preferredHand); + if (!stackInHand.isEmpty() && (stackInHand.getCount() != previousStackCount || client.interactionManager.hasCreativeInventory())) { + client.gameRenderer.firstPersonRenderer.resetEquipProgress(client.player.preferredHand); + } + } return true; } } } + if (result.getType() == HitResult.Type.ENTITY) { + client.interactionManager.attackEntity(client.player, ((EntityHitResult)result).getEntity()); + } } - return super.mouseClicked(mouseX, mouseY, button); + firstPosition = new double[2]; + clickStartTime = -1; + return false; + } + public boolean mouseHeldDown(double mouseX, double mouseY) { + System.out.println(mouseX + " " + firstPosition[0]); + if (!isDragging() && Math.abs(mouseX-firstPosition[0]) < 1 && Math.abs(mouseY-firstPosition[1]) < 1) { + HitResult result = TouchUtils.getTargettedObject(mouseX, mouseY); + if (result == null) return false; + + if (result.getType() == HitResult.Type.BLOCK) { + BlockHitResult blockHit = (BlockHitResult) result; + System.out.println(blockHit.getBlockPos().toString()); + return client.interactionManager.updateBlockBreakingProgress(blockHit.getBlockPos(), blockHit.getSide()); + } + if (result.getType() == HitResult.Type.ENTITY) { + client.interactionManager.interactEntity(client.player, ((EntityHitResult)result).getEntity(), client.player.getActiveHand()); + } + } + return false; } @Override public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { if (button == GLFW.GLFW_MOUSE_BUTTON_1 && this.client != null) { if (deltaY > 0.01) - this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 2); - else if (deltaY < 0.01) - this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs(deltaY / 5.0), 1); + this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs((deltaY / 3.0)*MidnightControlsConfig.touchSpeed/100), 2); + else this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_Y, (float) Math.abs((deltaY / 3.0)*MidnightControlsConfig.touchSpeed/100), 1); if (deltaX > 0.01) - this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 2); - else if (deltaX < 0.01) - this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs(deltaX / 5.0), 1); + this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs((deltaX / 3.0)*MidnightControlsConfig.touchSpeed/100), 2); + else this.mod.input.handleLook(this.client, GLFW_GAMEPAD_AXIS_RIGHT_X, (float) Math.abs((deltaX / 3.0)*MidnightControlsConfig.touchSpeed/100), 1); } return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); } + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + KeyBinding.onKeyPressed(InputUtil.fromKeyCode(keyCode, scanCode)); + //return false; + super.keyPressed(keyCode,scanCode,modifiers); + return true; + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + super.render(context, mouseX, mouseY, delta); + context.fill(mouseX-10, mouseY-10, mouseX+10, mouseY+10, 0xFFFFFF); + } } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ControlsOptionsScreenMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ControlsOptionsScreenMixin.java index 46dbb41..590118f 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ControlsOptionsScreenMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ControlsOptionsScreenMixin.java @@ -9,11 +9,11 @@ package eu.midnightdust.midnightcontrols.client.mixin; -import eu.midnightdust.lib.util.screen.TexturedOverlayButtonWidget; import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsSettingsScreen; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.option.ControlsOptionsScreen; import net.minecraft.client.gui.screen.option.GameOptionsScreen; +import net.minecraft.client.gui.widget.TextIconButtonWidget; import net.minecraft.client.option.GameOptions; import net.minecraft.text.Text; import net.minecraft.util.Identifier; @@ -32,8 +32,9 @@ public abstract class ControlsOptionsScreenMixin extends GameOptionsScreen { } @Inject(method = "init", at = @At(value = "INVOKE", ordinal = 1, shift = At.Shift.AFTER, target = "Lnet/minecraft/client/gui/screen/option/ControlsOptionsScreen;addDrawableChild(Lnet/minecraft/client/gui/Element;)Lnet/minecraft/client/gui/Element;")) private void addControllerButton(CallbackInfo ci) { - this.addDrawableChild(new TexturedOverlayButtonWidget(this.width / 2 + 158, this.height / 6 - 12, 20, 20,0,0,20, new Identifier("midnightcontrols", "textures/gui/midnightcontrols_button.png"), 32, 64, (button) -> { - this.client.setScreen(new MidnightControlsSettingsScreen(this, false)); - }, Text.translatable("midnightcontrols.menu.title.controller"))); + TextIconButtonWidget iconWidget = TextIconButtonWidget.builder(Text.translatable("midnightcontrols.menu.title.controller"), (button -> this.client.setScreen(new MidnightControlsSettingsScreen(this, false))), true) + .dimension(20,20).texture(new Identifier("midnightcontrols", "icon/button"), 20, 20).build(); + iconWidget.setPosition(this.width / 2 + 158, this.height / 6 - 12); + this.addDrawableChild(iconWidget); } } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/GameRendererMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/GameRendererMixin.java index 9414b84..036dcb3 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/GameRendererMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/GameRendererMixin.java @@ -9,14 +9,19 @@ package eu.midnightdust.midnightcontrols.client.mixin; +import com.mojang.blaze3d.systems.RenderSystem; import eu.midnightdust.midnightcontrols.ControlsMode; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsRenderer; +import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay; +import eu.midnightdust.midnightcontrols.client.touch.TouchUtils; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.render.GameRenderer; +import net.minecraft.client.util.Window; import net.minecraft.client.util.math.MatrixStack; +import org.joml.Matrix4f; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -26,7 +31,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(GameRenderer.class) -public class GameRendererMixin { +public abstract class GameRendererMixin { @Shadow @Final MinecraftClient client; @@ -37,8 +42,14 @@ public class GameRendererMixin { MidnightControlsClient.get().input.onPreRenderScreen(this.client, this.client.currentScreen); } @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;draw()V", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILSOFT) - private void renderVirtualCursor(float tickDelta, long startTime, boolean tick, CallbackInfo ci, MatrixStack matrixStack, DrawContext drawContext) { + private void renderVirtualCursor(float tickDelta, long startTime, boolean tick, CallbackInfo ci, boolean bl, MatrixStack matrixStack, DrawContext drawContext) { MidnightControlsRenderer.renderVirtualCursor(drawContext, client); drawContext.draw(); } + @Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/GameRenderer;renderHand:Z", ordinal = 0), method = "renderWorld") + private void postWorldRender(float tickDelta, long limitTime, MatrixStack matrix, CallbackInfo ci) { + TouchUtils.lastProjMat.set(RenderSystem.getProjectionMatrix()); + TouchUtils.lastModMat.set(RenderSystem.getModelViewMatrix()); + TouchUtils.lastWorldSpaceMatrix.set(matrix.peek().getPositionMatrix()); + } } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/InputUtilMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/InputUtilMixin.java index 37505f3..4230d73 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/InputUtilMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/InputUtilMixin.java @@ -2,20 +2,14 @@ package eu.midnightdust.midnightcontrols.client.mixin; import net.minecraft.client.util.InputUtil; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Final; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; -import java.lang.invoke.MethodHandle; - +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(InputUtil.class) public abstract class InputUtilMixin { - @Final - @Shadow - private static MethodHandle GLFW_RAW_MOUSE_MOTION_SUPPORTED_HANDLE; - /** * @author kabliz * @reason This method is static, and there is a terrible UX issue if raw input is turned on at the same time as @@ -23,17 +17,8 @@ public abstract class InputUtilMixin { * unresponsive and the player not understanding why. This overwrite preserves the user's mouse preferences, * while not interfering with eye tracking, and the two modes can be switched between during a play session. */ - @Overwrite - public static boolean isRawMouseMotionSupported(){ - if(MidnightControlsConfig.eyeTrackerAsMouse){ - return false; - } else { //Paste original implementation from InputUtil below. - try { - return GLFW_RAW_MOUSE_MOTION_SUPPORTED_HANDLE != null && - (boolean) GLFW_RAW_MOUSE_MOTION_SUPPORTED_HANDLE.invokeExact(); - } catch (Throwable var1) { - throw new RuntimeException(var1); - } - } + @Inject(method = "isRawMouseMotionSupported", at = @At("HEAD"), cancellable = true) + private static void setRawMouseMotionSupported(CallbackInfoReturnable cir) { + if (MidnightControlsConfig.eyeTrackerAsMouse) cir.setReturnValue(false); } } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingMixin.java index 0655e90..832f0cf 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/KeyBindingMixin.java @@ -15,7 +15,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @Mixin(KeyBinding.class) -public class KeyBindingMixin implements KeyBindingAccessor { +public abstract class KeyBindingMixin implements KeyBindingAccessor { @Shadow private int timesPressed; diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MinecraftClientMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MinecraftClientMixin.java index 630edc0..6a4f275 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MinecraftClientMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MinecraftClientMixin.java @@ -115,10 +115,6 @@ public abstract class MinecraftClientMixin { // } this.midnightcontrols$lastPos = this.player.getPos(); } - @Inject(method = "render", at = @At("HEAD")) - private void onRender(CallbackInfo ci) { - MidnightControlsClient.get().onRender((MinecraftClient) (Object) (this)); - } @Inject(at = @At("TAIL"), method = "setScreen") private void setScreen(Screen screen, CallbackInfo info) { diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MouseMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MouseMixin.java index ab2b112..40a4962 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MouseMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/MouseMixin.java @@ -92,7 +92,7 @@ public abstract class MouseMixin implements MouseAccessor { private void isCursorLocked(CallbackInfoReturnable ci) { if (this.client.currentScreen == null) { if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.virtualMouse) { - ci.setReturnValue(true); + //ci.setReturnValue(true); ci.cancel(); } } @@ -100,8 +100,9 @@ public abstract class MouseMixin implements MouseAccessor { @Inject(method = "lockCursor", at = @At("HEAD"), cancellable = true) private void onCursorLocked(CallbackInfo ci) { - if (/*config.getControlsMode() == ControlsMode.TOUCHSCREEN - ||*/ (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.virtualMouse)) + if ((MidnightControlsConfig.eyeTrackerAsMouse && client.isWindowFocused() && !this.cursorLocked) + || MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN + || (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.virtualMouse)) ci.cancel(); } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ScreenAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ScreenAccessor.java deleted file mode 100644 index f9b2b01..0000000 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ScreenAccessor.java +++ /dev/null @@ -1,17 +0,0 @@ -package eu.midnightdust.midnightcontrols.client.mixin; - -import net.minecraft.client.gui.Selectable; -import net.minecraft.client.gui.screen.Screen; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.util.List; - -@Mixin(Screen.class) -public interface ScreenAccessor { - @Accessor - List getSelectables(); - @Accessor @Nullable - Selectable getSelected(); -} diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ScreenMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ScreenMixin.java new file mode 100644 index 0000000..dd5ac1e --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ScreenMixin.java @@ -0,0 +1,38 @@ +package eu.midnightdust.midnightcontrols.client.mixin; + +import dev.lambdaurora.spruceui.Position; +import eu.midnightdust.midnightcontrols.ControlsMode; +import eu.midnightdust.midnightcontrols.client.ButtonState; +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; +import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; +import eu.midnightdust.midnightcontrols.client.controller.InputHandlers; +import eu.midnightdust.midnightcontrols.client.gui.widget.SilentTexturedButtonWidget; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.Drawable; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.Selectable; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.text.Text; +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; + +import static eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay.WIDGETS_LOCATION; + +@Mixin(Screen.class) +public abstract class ScreenMixin { + @Shadow protected abstract T addDrawableChild(T drawableElement); + + @Shadow public int width; + + @Inject(method = "init(Lnet/minecraft/client/MinecraftClient;II)V", at = @At("TAIL")) + public void midnightcontrols$addCloseButton(MinecraftClient client, int width, int height, CallbackInfo ci) { + if (MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN && (MidnightControlsConfig.closeButtonScreens.stream().anyMatch(s -> this.getClass().getName().startsWith(s) || ((Object)this) instanceof HandledScreen))) { + this.addDrawableChild(new SilentTexturedButtonWidget(Position.of(this.width - 30, 10), 20, 20, Text.empty(), btn -> + InputHandlers.handleExit().press(client, ButtonBinding.BACK, 0f, ButtonState.PRESS), 20, 160, 20, WIDGETS_LOCATION)); + } + } +} diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/WorldRendererMixin.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/WorldRendererMixin.java index 48b3b89..3e5b265 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/WorldRendererMixin.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/WorldRendererMixin.java @@ -12,6 +12,7 @@ package eu.midnightdust.midnightcontrols.client.mixin; import eu.midnightdust.lib.util.MidnightColorUtil; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; +import eu.midnightdust.midnightcontrols.client.util.RainbowColor; import net.minecraft.block.ShapeContext; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.*; @@ -90,7 +91,7 @@ public abstract class WorldRendererMixin { var outlineShape = placementState.getOutlineShape(this.client.world, blockPos, ShapeContext.of(camera.getFocusedEntity())); Color rgb = MidnightColorUtil.hex2Rgb(MidnightControlsConfig.reacharoundOutlineColorHex); - if (MidnightControlsConfig.reacharoundOutlineColorHex.isEmpty()) rgb = MidnightColorUtil.radialRainbow(1,1); + if (MidnightControlsConfig.reacharoundOutlineColorHex.isEmpty()) rgb = RainbowColor.radialRainbow(1,1); matrices.push(); var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines()); drawCuboidShapeOutline(matrices, vertexConsumer, outlineShape, diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/touch/TouchMode.java b/src/main/java/eu/midnightdust/midnightcontrols/client/touch/TouchMode.java new file mode 100644 index 0000000..c6c69a8 --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/touch/TouchMode.java @@ -0,0 +1,5 @@ +package eu.midnightdust.midnightcontrols.client.touch; + +public enum TouchMode { + CROSSHAIR, FINGER_POS +} diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/touch/TouchUtils.java b/src/main/java/eu/midnightdust/midnightcontrols/client/touch/TouchUtils.java new file mode 100644 index 0000000..9e622d9 --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/touch/TouchUtils.java @@ -0,0 +1,60 @@ +package eu.midnightdust.midnightcontrols.client.touch; + +import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.Camera; +import net.minecraft.entity.projectile.ProjectileUtil; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.EntityHitResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.RaycastContext; +import org.joml.Matrix4f; +import org.joml.Vector3f; +import org.lwjgl.opengl.GL11; + +import static eu.midnightdust.midnightcontrols.client.MidnightReacharound.getPlayerRange; + +public class TouchUtils { + private static final MinecraftClient client = MinecraftClient.getInstance(); + public static final Matrix4f lastWorldSpaceMatrix = new Matrix4f(); + public static final Matrix4f lastProjMat = new Matrix4f(); + public static final Matrix4f lastModMat = new Matrix4f(); + public static HitResult getTargettedObject(double mouseX, double mouseY) { + if (MidnightControlsConfig.touchMode == TouchMode.CROSSHAIR) { + return client.crosshairTarget; + } + Vec3d near = screenSpaceToWorldSpace(mouseX, mouseY, 0); + Vec3d far = screenSpaceToWorldSpace(mouseX, mouseY, 1); + EntityHitResult entityCast = ProjectileUtil.raycast(client.player, near, far, Box.from(client.player.getPos()).expand(getPlayerRange(client)), entity -> (!entity.isSpectator() && entity.isAttackable()), getPlayerRange(client) * getPlayerRange(client)); + + if (entityCast != null && entityCast.getType() == HitResult.Type.ENTITY) return entityCast; + + BlockHitResult result = client.world.raycast(new RaycastContext(near, far, RaycastContext.ShapeType.OUTLINE, RaycastContext.FluidHandling.ANY, client.player)); + + if (client.player.getPos().distanceTo(result.getPos()) > getPlayerRange(client)) return null; + return result; + } + + /* Taken from https://github.com/0x3C50/Renderer/blob/master/src/main/java/me/x150/renderer/util/RendererUtils.java#L270 + * Credits to 0x3C50 */ + public static Vec3d screenSpaceToWorldSpace(double x, double y, double d) { + Camera camera = client.getEntityRenderDispatcher().camera; + int displayHeight = client.getWindow().getScaledHeight(); + int displayWidth = client.getWindow().getScaledWidth(); + int[] viewport = new int[4]; + GL11.glGetIntegerv(GL11.GL_VIEWPORT, viewport); + Vector3f target = new Vector3f(); + + Matrix4f matrixProj = new Matrix4f(lastProjMat); + Matrix4f matrixModel = new Matrix4f(lastModMat); + + matrixProj.mul(matrixModel) + .mul(lastWorldSpaceMatrix) + .unproject((float) x / displayWidth * viewport[2], + (float) (displayHeight - y) / displayHeight * viewport[3], (float) d, viewport, target); + + return new Vec3d(target.x, target.y, target.z).add(camera.getPos()); + } +} diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/util/RainbowColor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/util/RainbowColor.java new file mode 100644 index 0000000..88a33aa --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/util/RainbowColor.java @@ -0,0 +1,15 @@ +package eu.midnightdust.midnightcontrols.client.util; + +import java.awt.*; + +public class RainbowColor { + public static float hue; + public static void tick() { + if (hue > 1) hue = 0f; + hue = hue + 0.01f; + } + + public static Color radialRainbow(float saturation, float brightness) { + return Color.getHSBColor(hue, saturation, brightness); + } +} diff --git a/src/main/resources/assets/midnightcontrols/textures/gui/midnightcontrols_button.png b/src/main/resources/assets/midnightcontrols/textures/gui/midnightcontrols_button.png deleted file mode 100644 index 5c5a7a2..0000000 Binary files a/src/main/resources/assets/midnightcontrols/textures/gui/midnightcontrols_button.png and /dev/null differ diff --git a/src/main/resources/assets/midnightcontrols/textures/gui/sprites/icon/button.png b/src/main/resources/assets/midnightcontrols/textures/gui/sprites/icon/button.png new file mode 100644 index 0000000..b8c742b Binary files /dev/null and b/src/main/resources/assets/midnightcontrols/textures/gui/sprites/icon/button.png differ diff --git a/src/main/resources/midnightcontrols.mixins.json b/src/main/resources/midnightcontrols.mixins.json index 57f2c20..fd098ca 100644 --- a/src/main/resources/midnightcontrols.mixins.json +++ b/src/main/resources/midnightcontrols.mixins.json @@ -21,8 +21,8 @@ "WorldRendererMixin", "KeyBindingRegistryImplAccessor", "KeyBindingIDAccessor", - "ScreenAccessor", - "TabNavigationWidgetAccessor" + "TabNavigationWidgetAccessor", + "ScreenMixin" ], "injectors": { "defaultRequire": 1