mirror of
https://github.com/TeamMidnightDust/MidnightControls.git
synced 2025-12-14 15:45:09 +01:00
Port to 1.20.2 & Revamp Touchscreen Input
- Port to 1.20.2 - Fixed virtual mouse cursor sometimes being hidden behind objects (closes #221) - Touchscreen is now actually usable (in theory, I'll have to wait a few weeks for my tablet to arrive to test further) - Made it possible to place/break blocks and interact with entities - Added a touchscreen mode for interacting with entities and blocks at the position the click was registered at, not just at the crosshair - Added a close button to screens without their own back button - Will be officially released when SpruceUI is updated
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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<String> arrowScreens = Lists.newArrayList(ChatScreen.class.getCanonicalName());
|
||||
@Entry(category = "screens", name = "WASD screens") public static List<String> wasdScreens = Lists.newArrayList("com.ultreon.devices.core.Laptop");
|
||||
@Entry(category = "touch", name = "Screens with close button") public static List<String> 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<String, String> BINDING = new HashMap<>();
|
||||
|
||||
private static final Pattern BUTTON_BINDING_PATTERN = Pattern.compile("(-?\\d+)\\+?");
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Boolean> cir) {
|
||||
if (MidnightControlsConfig.eyeTrackerAsMouse) cir.setReturnValue(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -92,7 +92,7 @@ public abstract class MouseMixin implements MouseAccessor {
|
||||
private void isCursorLocked(CallbackInfoReturnable<Boolean> 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Selectable> getSelectables();
|
||||
@Accessor @Nullable
|
||||
Selectable getSelected();
|
||||
}
|
||||
@@ -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 extends Element & Drawable & Selectable> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package eu.midnightdust.midnightcontrols.client.touch;
|
||||
|
||||
public enum TouchMode {
|
||||
CROSSHAIR, FINGER_POS
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user