Compare commits

..

5 Commits

Author SHA1 Message Date
Martin Prokoph
e022fd1827 chore: bump version 2025-05-24 11:25:41 +02:00
Martin Prokoph
fbecfd5642 Merge pull request #346 from Hedwig7s/architectury-1.21
Fix Network Protocol Error when joining server on NeoForge
2025-05-24 11:21:06 +02:00
Martin Prokoph
036be42bec fix: camera randomly stops working 2025-05-24 11:18:01 +02:00
Martin Prokoph
4cfee5ba2e fix: working touchscreen camera 2025-05-19 14:12:10 +02:00
Hedwig7s
d753641fa9 Fix #326 2025-04-30 19:27:15 +02:00
42 changed files with 132 additions and 990 deletions

View File

@@ -13,9 +13,6 @@ repositories {
maven { maven {
url = "https://api.modrinth.com/maven" url = "https://api.modrinth.com/maven"
} }
flatDir {
dirs("localMaven")
}
} }
subprojects { subprojects {
@@ -25,9 +22,6 @@ subprojects {
url = "https://api.modrinth.com/maven" url = "https://api.modrinth.com/maven"
} }
maven { url 'https://jitpack.io' } maven { url 'https://jitpack.io' }
flatDir {
dirs("../localMaven")
}
} }
dependencies { dependencies {

View File

@@ -39,7 +39,7 @@ dependencies {
modCompileOnlyApi "org.quiltmc:quilt-json5:1.0.0" modCompileOnlyApi "org.quiltmc:quilt-json5:1.0.0"
modImplementation "maven.modrinth:sodium:${project.sodium_version}-fabric" modImplementation "maven.modrinth:sodium:${project.sodium_version}-fabric"
modCompileOnlyApi "maven.modrinth:emi:${project.emi_version}" modCompileOnlyApi "maven.modrinth:emi:${project.emi_version}"
modImplementation "maven.modrinth:emotecraft:${project.emotecraft_version}" modCompileOnlyApi "maven.modrinth:emotecraft:${project.emotecraft_version}"
modCompileOnlyApi "io.github.kosmx:bendy-lib:${project.bendylib_version}" modCompileOnlyApi "io.github.kosmx:bendy-lib:${project.bendylib_version}"
modCompileOnlyApi "dev.isxander:yet-another-config-lib:${project.yacl_version}" modCompileOnlyApi "dev.isxander:yet-another-config-lib:${project.yacl_version}"
modCompileOnlyApi "maven.modrinth:inventory-tabs-updated:${project.inventorytabs_version}" modCompileOnlyApi "maven.modrinth:inventory-tabs-updated:${project.inventorytabs_version}"

View File

@@ -26,7 +26,6 @@ import eu.midnightdust.midnightcontrols.client.mixin.KeyBindingIDAccessor;
import eu.midnightdust.midnightcontrols.client.ring.ButtonBindingRingAction; import eu.midnightdust.midnightcontrols.client.ring.ButtonBindingRingAction;
import eu.midnightdust.midnightcontrols.client.ring.MidnightRing; import eu.midnightdust.midnightcontrols.client.ring.MidnightRing;
import eu.midnightdust.midnightcontrols.client.util.platform.NetworkUtil; import eu.midnightdust.midnightcontrols.client.util.platform.NetworkUtil;
import eu.midnightdust.midnightcontrols.client.virtualkeyboard.MouseClickInterceptor;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import org.thinkingstudio.obsidianui.hud.HudManager; import org.thinkingstudio.obsidianui.hud.HudManager;
import eu.midnightdust.midnightcontrols.client.touch.TouchInput; import eu.midnightdust.midnightcontrols.client.touch.TouchInput;
@@ -76,7 +75,6 @@ public class MidnightControlsClient extends MidnightControls {
public static final MidnightInput input = new MidnightInput(); public static final MidnightInput input = new MidnightInput();
public static final MidnightRing ring = new MidnightRing(); public static final MidnightRing ring = new MidnightRing();
public static final MidnightReacharound reacharound = new MidnightReacharound(); public static final MidnightReacharound reacharound = new MidnightReacharound();
public static final MouseClickInterceptor clickInterceptor = new MouseClickInterceptor();
public static boolean isWayland; public static boolean isWayland;
private static MidnightControlsHud hud; private static MidnightControlsHud hud;
private static ControlsMode previousControlsMode; private static ControlsMode previousControlsMode;
@@ -91,7 +89,7 @@ public class MidnightControlsClient extends MidnightControls {
public void run() { public void run() {
try { try {
if (lateInitDone && client.isRunning()) { if (lateInitDone && client.isRunning()) {
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && (client.isWindowFocused() || MidnightControlsConfig.unfocusedInput)) { if (MidnightControlsConfig.controlsMode != ControlsMode.DEFAULT && (client.isWindowFocused() || MidnightControlsConfig.unfocusedInput)) {
input.tickCameraStick(); input.tickCameraStick();
input.updateCamera(); input.updateCamera();
} }
@@ -206,7 +204,6 @@ public class MidnightControlsClient extends MidnightControls {
RainbowColor.tick(); RainbowColor.tick();
TouchInput.tick(); TouchInput.tick();
} }
/** /**
* Called when opening a screen. * Called when opening a screen.
*/ */

View File

@@ -88,7 +88,6 @@ public class MidnightControlsConfig extends MidnightConfig {
@Entry(category = SCREENS, name = "midnightcontrols.menu.virtual_mouse") public static boolean virtualMouse = false; @Entry(category = SCREENS, name = "midnightcontrols.menu.virtual_mouse") public static boolean virtualMouse = false;
@Entry(category = SCREENS, name = "midnightcontrols.menu.virtual_mouse.skin") public static VirtualMouseSkin virtualMouseSkin = VirtualMouseSkin.DEFAULT_LIGHT; @Entry(category = SCREENS, name = "midnightcontrols.menu.virtual_mouse.skin") public static VirtualMouseSkin virtualMouseSkin = VirtualMouseSkin.DEFAULT_LIGHT;
@Entry(category = SCREENS, name = "midnightcontrols.menu.hide_cursor") public static boolean hideNormalMouse = false; @Entry(category = SCREENS, name = "midnightcontrols.menu.hide_cursor") public static boolean hideNormalMouse = false;
@Entry(category = SCREENS, name = "midnightcontrols.menu.virtual_keyboard") public static boolean virtualKeyboard = false;
@Entry(category = CONTROLLER, name = "Controller ID") @Hidden public static Object controllerID = 0; @Entry(category = CONTROLLER, name = "Controller ID") @Hidden public static Object controllerID = 0;
@Entry(category = CONTROLLER, name = "2nd Controller ID") @Hidden public static Object secondControllerID = -1; @Entry(category = CONTROLLER, name = "2nd Controller ID") @Hidden public static Object secondControllerID = -1;
@Entry(category = VISUAL, name = "midnightcontrols.menu.controller_type") public static ControllerType controllerType = ControllerType.DEFAULT; @Entry(category = VISUAL, name = "midnightcontrols.menu.controller_type") public static ControllerType controllerType = ControllerType.DEFAULT;
@@ -375,7 +374,6 @@ public class MidnightControlsConfig extends MidnightConfig {
unfocusedInput = false; unfocusedInput = false;
virtualMouse = false; virtualMouse = false;
virtualMouseSkin = VirtualMouseSkin.DEFAULT_LIGHT; virtualMouseSkin = VirtualMouseSkin.DEFAULT_LIGHT;
virtualKeyboard = false;
controllerID = 0; controllerID = 0;
secondControllerID = -1; secondControllerID = -1;
controllerType = ControllerType.DEFAULT; controllerType = ControllerType.DEFAULT;

View File

@@ -77,7 +77,7 @@ public class MidnightReacharound {
} }
public static float getPlayerRange(@NotNull MinecraftClient client) { public static float getPlayerRange(@NotNull MinecraftClient client) {
return client.player != null ? Double.valueOf(client.player.getAttributeValue(EntityAttributes.BLOCK_INTERACTION_RANGE)).floatValue() : 0.f; return client.player != null ? Double.valueOf(client.player.getAttributeValue(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE)).floatValue() : 0.f;
} }
/** /**

View File

@@ -1,51 +1,36 @@
package eu.midnightdust.midnightcontrols.client.compat; package eu.midnightdust.midnightcontrols.client.compat;
import eu.midnightdust.midnightcontrols.client.controller.InputManager; import eu.midnightdust.midnightcontrols.client.controller.InputManager;
import eu.midnightdust.midnightcontrols.client.mixin.MouseAccessor; import io.github.kosmx.emotes.arch.gui.EmoteMenuImpl;
import io.github.kosmx.emotes.arch.screen.ingame.FastMenuScreen; import io.github.kosmx.emotes.arch.gui.screen.ingame.FastChosseScreen;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import org.joml.Vector2i;
import org.lwjgl.glfw.GLFW;
public class EmotecraftCompat { public class EmotecraftCompat {
private static final MinecraftClient client = MinecraftClient.getInstance(); private static final MinecraftClient client = MinecraftClient.getInstance();
public static void openEmotecraftScreen(Screen parent) { public static void openEmotecraftScreen(Screen parent) {
client.setScreen(new FastMenuScreen(parent)); client.setScreen(new EmoteMenuImpl(parent));
} }
public static boolean isEmotecraftScreen(Screen screen) { public static boolean isEmotecraftScreen(Screen screen) {
return screen instanceof FastMenuScreen; return screen instanceof FastChosseScreen;
} }
static int prevIndex = -1;
public static void handleEmoteSelector(int index) { public static void handleEmoteSelector(int index) {
try { if (client.currentScreen instanceof FastChosseScreen) {
if (client.currentScreen instanceof FastMenuScreen) { int x = client.getWindow().getWidth() / 2;
boolean stickReleased = index == -1 && prevIndex != -1; int y = client.getWindow().getHeight() / 2;
var pos = calcMousePos(stickReleased ? prevIndex : index); switch (index) {
InputManager.queueMousePosition(pos.x, pos.y); case 0, 3, 5 -> x -= 200;
InputManager.INPUT_MANAGER.updateMousePosition(client); case 2, 4, 7 -> x += 200;
}
switch (index) {
case 0, 1, 2 -> y -= 200;
case 5, 6, 7 -> y += 200;
}
InputManager.queueMousePosition(x, y);
if (stickReleased) { InputManager.INPUT_MANAGER.updateMousePosition(client);
((MouseAccessor) client.mouse).midnightcontrols$onMouseButton(client.getWindow().getHandle(), GLFW.GLFW_MOUSE_BUTTON_LEFT, GLFW.GLFW_PRESS, 0);
prevIndex = -1;
}
else prevIndex = index;
} else prevIndex = -1;
} catch (Exception ignored) {}
}
public static Vector2i calcMousePos(int index) {
int x = client.getWindow().getWidth() / 2;
int y = client.getWindow().getHeight() / 2;
switch (index) {
case 0, 3, 5 -> x -= 275;
case 2, 4, 7 -> x += 275;
} }
switch (index) {
case 0, 1, 2 -> y -= 275;
case 5, 6, 7 -> y += 275;
}
return new Vector2i(x, y);
} }
} }

View File

@@ -60,11 +60,10 @@ public class InputHandlers {
// When in-game // When in-game
if (client.currentScreen == null && client.player != null) { if (client.currentScreen == null && client.player != null) {
if (!client.player.isSpectator()) { if (!client.player.isSpectator()) {
var inv = client.player.getInventory();
if (next) if (next)
inv.setSelectedSlot(inv.selectedSlot < 8 ? inv.selectedSlot + 1 : inv.selectedSlot - 8); client.player.getInventory().scrollInHotbar(-1.0);
else else
inv.setSelectedSlot(inv.selectedSlot > 0 ? inv.selectedSlot - 1 : inv.selectedSlot + 8); client.player.getInventory().scrollInHotbar(1.0);
} }
else { else {
if (client.inGameHud.getSpectatorHud().isOpen()) { if (client.inGameHud.getSpectatorHud().isOpen()) {
@@ -80,9 +79,11 @@ public class InputHandlers {
} else if (client.currentScreen instanceof CreativeInventoryScreenAccessor inventory) { } else if (client.currentScreen instanceof CreativeInventoryScreenAccessor inventory) {
inventory.midnightcontrols$setSelectedTab(ItemGroupUtil.cycleTab(next, client)); inventory.midnightcontrols$setSelectedTab(ItemGroupUtil.cycleTab(next, client));
return true; return true;
} else if (client.currentScreen instanceof RecipeBookScreen<?> recipeBookScreen) { } else if (client.currentScreen instanceof InventoryScreen || client.currentScreen instanceof CraftingScreen || client.currentScreen instanceof AbstractFurnaceScreen<?>) {
RecipeBookWidget<?> recipeBook = ((RecipeBookScreenAccessor) recipeBookScreen).getRecipeBook(); RecipeBookWidget recipeBook;
if (client.currentScreen instanceof InventoryScreen inventoryScreen) recipeBook = inventoryScreen.getRecipeBookWidget();
else if (client.currentScreen instanceof CraftingScreen craftingScreen) recipeBook = craftingScreen.getRecipeBookWidget();
else recipeBook = ((AbstractFurnaceScreen<?>)client.currentScreen).getRecipeBookWidget();
var recipeBookAccessor = (RecipeBookWidgetAccessor) recipeBook; var recipeBookAccessor = (RecipeBookWidgetAccessor) recipeBook;
var tabs = recipeBookAccessor.getTabButtons(); var tabs = recipeBookAccessor.getTabButtons();
var currentTab = recipeBookAccessor.getCurrentTab(); var currentTab = recipeBookAccessor.getCurrentTab();
@@ -97,7 +98,7 @@ public class InputHandlers {
currentTab.setToggled(false); currentTab.setToggled(false);
recipeBookAccessor.setCurrentTab(currentTab = tabs.get(nextTab)); recipeBookAccessor.setCurrentTab(currentTab = tabs.get(nextTab));
currentTab.setToggled(true); currentTab.setToggled(true);
recipeBookScreen.refreshRecipeBook(); recipeBookAccessor.midnightcontrols$refreshResults(true);
return true; return true;
} else if (client.currentScreen instanceof AdvancementsScreenAccessor screen) { } else if (client.currentScreen instanceof AdvancementsScreenAccessor screen) {
var tabs = screen.getTabs().values().stream().distinct().toList(); var tabs = screen.getTabs().values().stream().distinct().toList();

View File

@@ -15,7 +15,6 @@ import eu.midnightdust.midnightcontrols.client.util.MathUtil;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.util.PlayerInput;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -49,8 +48,10 @@ public final class MovementHandler implements PressAction {
public void applyMovement(@NotNull ClientPlayerEntity player) { public void applyMovement(@NotNull ClientPlayerEntity player) {
if (!this.shouldOverrideMovement) if (!this.shouldOverrideMovement)
return; return;
player.input.playerInput = new PlayerInput(this.pressingForward, this.pressingBack, this.pressingLeft, this.pressingRight, player.input.pressingForward = this.pressingForward;
player.input.playerInput.jump(), player.input.playerInput.sneak(), player.input.playerInput.sprint()); player.input.pressingBack = this.pressingBack;
player.input.pressingLeft = this.pressingLeft;
player.input.pressingRight = this.pressingRight;
polarUtil.calculate(this.movementSideways, this.movementForward, this.slowdownFactor); polarUtil.calculate(this.movementSideways, this.movementForward, this.slowdownFactor);
player.input.movementForward = polarUtil.polarY; player.input.movementForward = polarUtil.polarY;
@@ -80,7 +81,7 @@ public final class MovementHandler implements PressAction {
} }
this.slowdownFactor = client.player.shouldSlowDown() ? (MathHelper.clamp( this.slowdownFactor = client.player.shouldSlowDown() ? (MathHelper.clamp(
0.3F + (float) client.player.getAttributeValue(EntityAttributes.SNEAKING_SPEED), 0.3F + (float) client.player.getAttributeValue(EntityAttributes.PLAYER_SNEAKING_SPEED),
0.0F, 0.0F,
1.0F 1.0F
)) : 1.f; )) : 1.f;

View File

@@ -18,23 +18,24 @@ import eu.midnightdust.midnightcontrols.client.MidnightInput;
import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat;
import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding;
import eu.midnightdust.midnightcontrols.client.enums.VirtualMouseSkin; import eu.midnightdust.midnightcontrols.client.enums.VirtualMouseSkin;
import eu.midnightdust.midnightcontrols.client.mixin.DrawContextAccessor;
import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor; import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.*; import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.BufferRenderer;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.Sprite;
import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.Slot;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.ColorHelper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.util.function.Function;
import static eu.midnightdust.midnightcontrols.MidnightControls.id; import static eu.midnightdust.midnightcontrols.MidnightControls.id;
/** /**
@@ -174,7 +175,7 @@ public class MidnightControlsRenderer {
int assetSize = axis || (button >= 15 && button <= 18) ? AXIS_SIZE : BUTTON_SIZE; int assetSize = axis || (button >= 15 && button <= 18) ? AXIS_SIZE : BUTTON_SIZE;
RenderSystem.setShaderColor(1.f, second ? 0.f : 1.f, 1.f, 1.f); RenderSystem.setShaderColor(1.f, second ? 0.f : 1.f, 1.f, 1.f);
context.drawTexture(RenderLayer::getGuiTextured, axis ? MidnightControlsClient.CONTROLLER_AXIS : button >= 15 && button <= 19 ? MidnightControlsClient.CONTROLLER_EXPANDED :MidnightControlsClient.CONTROLLER_BUTTONS context.drawTexture(axis ? MidnightControlsClient.CONTROLLER_AXIS : button >= 15 && button <= 19 ? MidnightControlsClient.CONTROLLER_EXPANDED :MidnightControlsClient.CONTROLLER_BUTTONS
, x + (ICON_SIZE / 2 - assetSize / 2), y + (ICON_SIZE / 2 - assetSize / 2), , x + (ICON_SIZE / 2 - assetSize / 2), y + (ICON_SIZE / 2 - assetSize / 2),
(float) buttonOffset, (float) (controllerType * assetSize), (float) buttonOffset, (float) (controllerType * assetSize),
assetSize, assetSize, assetSize, assetSize,
@@ -215,7 +216,7 @@ public class MidnightControlsRenderer {
if (MidnightControlsConfig.virtualMouseSkin == VirtualMouseSkin.DEFAULT_DARK || MidnightControlsConfig.virtualMouseSkin == VirtualMouseSkin.SECOND_DARK) if (MidnightControlsConfig.virtualMouseSkin == VirtualMouseSkin.DEFAULT_DARK || MidnightControlsConfig.virtualMouseSkin == VirtualMouseSkin.SECOND_DARK)
spritePath = MidnightControlsClient.WAYLAND_CURSOR_TEXTURE_DARK; spritePath = MidnightControlsClient.WAYLAND_CURSOR_TEXTURE_DARK;
Sprite sprite = client.getGuiAtlasManager().getSprite(spritePath); Sprite sprite = client.getGuiAtlasManager().getSprite(spritePath);
drawUnalignedTexturedQuad(RenderLayer::getGuiTextured, sprite.getAtlasId(), context, mouseX, mouseX + 8, mouseY, mouseY + 8, 999, sprite.getMinU(), sprite.getMaxU(), sprite.getMinV(), sprite.getMaxV()); drawUnalignedTexturedQuad(sprite.getAtlasId(), context, mouseX, mouseX + 8, mouseY, mouseY + 8, 999, sprite.getMinU(), sprite.getMaxU(), sprite.getMinV(), sprite.getMaxV());
} catch (IllegalStateException ignored) {} } catch (IllegalStateException ignored) {}
} }
@@ -259,20 +260,19 @@ public class MidnightControlsRenderer {
try { try {
Sprite sprite = client.getGuiAtlasManager().getSprite(id(MidnightControlsConfig.virtualMouseSkin.getSpritePath() + (hoverSlot ? "_slot" : ""))); Sprite sprite = client.getGuiAtlasManager().getSprite(id(MidnightControlsConfig.virtualMouseSkin.getSpritePath() + (hoverSlot ? "_slot" : "")));
drawUnalignedTexturedQuad(RenderLayer::getGuiTextured, sprite.getAtlasId(), context, mouseX, mouseX + 16, mouseY, mouseY + 16, 999, sprite.getMinU(), sprite.getMaxU(), sprite.getMinV(), sprite.getMaxV()); drawUnalignedTexturedQuad(sprite.getAtlasId(), context, mouseX, mouseX + 16, mouseY, mouseY + 16, 999, sprite.getMinU(), sprite.getMaxU(), sprite.getMinV(), sprite.getMaxV());
} catch (IllegalStateException ignored) {} } catch (IllegalStateException ignored) {}
} }
private static void drawUnalignedTexturedQuad(Function<Identifier, RenderLayer> renderLayers, Identifier texture, DrawContext context, float x1, float x2, float y1, float y2, float z, float u1, float u2, float v1, float v2) { private static void drawUnalignedTexturedQuad(Identifier texture, DrawContext context, float x1, float x2, float y1, float y2, float z, float u1, float u2, float v1, float v2) {
RenderLayer renderLayer = renderLayers.apply(texture); RenderSystem.setShaderTexture(0, texture);
//RenderSystem.setShaderTexture(0, texture); RenderSystem.setShader(GameRenderer::getPositionTexProgram);
Matrix4f matrix4f = context.getMatrices().peek().getPositionMatrix(); Matrix4f matrix4f = context.getMatrices().peek().getPositionMatrix();
//BufferBuilder bufferBuilder = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE); BufferBuilder bufferBuilder = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE);
VertexConsumer vertexConsumer = ((DrawContextAccessor)context).getVertexConsumers().getBuffer(renderLayer); bufferBuilder.vertex(matrix4f, x1, y1, z).texture(u1, v1);
vertexConsumer.vertex(matrix4f, x1, y1, z).texture(u1, v1).color(ColorHelper.getWhite(1.0f)); bufferBuilder.vertex(matrix4f, x1, y2, z).texture(u1, v2);
vertexConsumer.vertex(matrix4f, x1, y2, z).texture(u1, v2).color(ColorHelper.getWhite(1.0f)); bufferBuilder.vertex(matrix4f, x2, y2, z).texture(u2, v2);
vertexConsumer.vertex(matrix4f, x2, y2, z).texture(u2, v2).color(ColorHelper.getWhite(1.0f)); bufferBuilder.vertex(matrix4f, x2, y1, z).texture(u2, v1);
vertexConsumer.vertex(matrix4f, x2, y1, z).texture(u2, v1).color(ColorHelper.getWhite(1.0f)); BufferRenderer.drawWithGlobalProgram(bufferBuilder.end());
context.draw();
} }
public record ButtonSize(int length, int height) { public record ButtonSize(int length, int height) {

View File

@@ -14,7 +14,6 @@ import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.util.platform.NetworkUtil; import eu.midnightdust.midnightcontrols.client.util.platform.NetworkUtil;
import org.thinkingstudio.obsidianui.background.Background; import org.thinkingstudio.obsidianui.background.Background;
import org.thinkingstudio.obsidianui.mixin.DrawContextAccessor;
import org.thinkingstudio.obsidianui.widget.SpruceWidget; import org.thinkingstudio.obsidianui.widget.SpruceWidget;
import eu.midnightdust.lib.util.MidnightColorUtil; import eu.midnightdust.lib.util.MidnightColorUtil;
import eu.midnightdust.midnightcontrols.MidnightControls; import eu.midnightdust.midnightcontrols.MidnightControls;
@@ -64,7 +63,6 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
private final SpruceOption eyeTrackingAsMouseOption; private final SpruceOption eyeTrackingAsMouseOption;
private final SpruceOption eyeTrackingDeadzone; private final SpruceOption eyeTrackingDeadzone;
private final SpruceOption virtualMouseOption; private final SpruceOption virtualMouseOption;
private final SpruceOption virtualKeyboardOption;
private final SpruceOption hideCursorOption; private final SpruceOption hideCursorOption;
private final SpruceOption resetOption; private final SpruceOption resetOption;
private final SpruceOption advancedConfigOption; private final SpruceOption advancedConfigOption;
@@ -300,8 +298,6 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
value -> MidnightControlsConfig.unfocusedInput = value, Text.translatable("midnightcontrols.menu.unfocused_input.tooltip")); value -> MidnightControlsConfig.unfocusedInput = value, Text.translatable("midnightcontrols.menu.unfocused_input.tooltip"));
this.virtualMouseOption = new SpruceToggleBooleanOption("midnightcontrols.menu.virtual_mouse", () -> MidnightControlsConfig.virtualMouse, this.virtualMouseOption = new SpruceToggleBooleanOption("midnightcontrols.menu.virtual_mouse", () -> MidnightControlsConfig.virtualMouse,
value -> MidnightControlsConfig.virtualMouse = value, Text.translatable("midnightcontrols.menu.virtual_mouse.tooltip")); value -> MidnightControlsConfig.virtualMouse = value, Text.translatable("midnightcontrols.menu.virtual_mouse.tooltip"));
this.virtualKeyboardOption = new SpruceToggleBooleanOption("midnightcontrols.menu.virtual_keyboard", () -> MidnightControlsConfig.virtualMouse,
value -> MidnightControlsConfig.virtualKeyboard = value, Text.translatable("midnightcontrols.menu.virtual_keyboard.tooltip"));
this.hideCursorOption = new SpruceToggleBooleanOption("midnightcontrols.menu.hide_cursor", () -> MidnightControlsConfig.hideNormalMouse, this.hideCursorOption = new SpruceToggleBooleanOption("midnightcontrols.menu.hide_cursor", () -> MidnightControlsConfig.hideNormalMouse,
value -> MidnightControlsConfig.hideNormalMouse = value, Text.translatable("midnightcontrols.menu.hide_cursor.tooltip")); value -> MidnightControlsConfig.hideNormalMouse = value, Text.translatable("midnightcontrols.menu.hide_cursor.tooltip"));
// Touch options // Touch options
@@ -393,7 +389,6 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
list.addSingleOptionEntry(this.yAxisRotationSpeedOption); list.addSingleOptionEntry(this.yAxisRotationSpeedOption);
list.addSingleOptionEntry(this.mouseSpeedOption); list.addSingleOptionEntry(this.mouseSpeedOption);
list.addSingleOptionEntry(this.virtualMouseOption); list.addSingleOptionEntry(this.virtualMouseOption);
list.addSingleOptionEntry(this.virtualKeyboardOption);
list.addSingleOptionEntry(this.hideCursorOption); list.addSingleOptionEntry(this.hideCursorOption);
list.addSingleOptionEntry(this.joystickAsMouseOption); list.addSingleOptionEntry(this.joystickAsMouseOption);
list.addSingleOptionEntry(this.eyeTrackingAsMouseOption); list.addSingleOptionEntry(this.eyeTrackingAsMouseOption);
@@ -506,24 +501,27 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
} }
@Override @Override
public void render(DrawContext context, SpruceWidget widget, int vOffset, int mouseX, int mouseY, float delta) { public void render(DrawContext context, SpruceWidget widget, int vOffset, int mouseX, int mouseY, float delta) {
fill(context, widget.getX(), widget.getY(), widget.getX() + widget.getWidth(), widget.getY() + widget.getHeight(), Color.black); fill(context.getMatrices(), widget.getX(), widget.getY(), widget.getX() + widget.getWidth(), widget.getY() + widget.getHeight(), MidnightColorUtil.hex2Rgb("#000000"));
} }
private static void fill(DrawContext context, int x2, int y2, int x1, int y1, Color color) { private static void fill(MatrixStack matrixStack, int x2, int y2, int x1, int y1, Color color) {
RenderLayer renderLayer = RenderLayer.getGui(); matrixStack.push();
VertexConsumer vertexConsumer = ((DrawContextAccessor)context).getVertexConsumers().getBuffer(renderLayer);
Matrix4f matrix = matrixStack.peek().getPositionMatrix();
float r = (float)(color.getRed()) / 255.0F; float r = (float)(color.getRed()) / 255.0F;
float g = (float)(color.getGreen()) / 255.0F; float g = (float)(color.getGreen()) / 255.0F;
float b = (float)(color.getBlue()) / 255.0F; float b = (float)(color.getBlue()) / 255.0F;
float t = (float)(transparency) / 255.0F; float t = (float)(transparency) / 255.0F;
BufferBuilder bufferBuilder = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
RenderSystem.enableBlend(); RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc(); RenderSystem.defaultBlendFunc();
vertexConsumer.vertex((float)x1, (float)y2, 0.0F).color(r, g, b, t); RenderSystem.setShader(GameRenderer::getPositionColorProgram);
vertexConsumer.vertex((float)x2, (float)y2, 0.0F).color(r, g, b, t); bufferBuilder.vertex(matrix, (float)x1, (float)y2, 0.0F).color(r, g, b, t);
vertexConsumer.vertex((float)x2, (float)y1, 0.0F).color(r, g, b, t); bufferBuilder.vertex(matrix, (float)x2, (float)y2, 0.0F).color(r, g, b, t);
vertexConsumer.vertex((float)x1, (float)y1, 0.0F).color(r, g, b, t); bufferBuilder.vertex(matrix, (float)x2, (float)y1, 0.0F).color(r, g, b, t);
bufferBuilder.vertex(matrix, (float)x1, (float)y1, 0.0F).color(r, g, b, t);
BufferRenderer.drawWithGlobalProgram(bufferBuilder.end());
RenderSystem.disableBlend(); RenderSystem.disableBlend();
context.draw(); matrixStack.pop();
} }
} }
} }

View File

@@ -1,15 +0,0 @@
package eu.midnightdust.midnightcontrols.client.mixin;
import net.minecraft.block.entity.SignText;
import net.minecraft.client.gui.screen.ingame.AbstractSignEditScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(AbstractSignEditScreen.class)
public interface AbstractSignEditScreenAccessor {
@Accessor("text")
SignText midnightcontrols$getText();
@Accessor("text")
void midnightcontrols$setText(SignText text);
}

View File

@@ -1,28 +0,0 @@
package eu.midnightdust.midnightcontrols.client.mixin;
import net.minecraft.client.gui.screen.ingame.BookEditScreen;
import net.minecraft.client.util.SelectionManager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(BookEditScreen.class)
public interface BookEditScreenAccessor {
@Accessor("signing")
boolean midnightcontrols$isSigning();
@Accessor("title")
String midnightcontrols$getTitle();
@Accessor("title")
void midnightcontrols$setTitle(String title);
@Accessor("currentPageSelectionManager")
SelectionManager midnightcontrols$getCurrentPageSelectionManager();
@Invoker("getCurrentPageContent")
String midnightcontrols$getCurrentPageContent();
@Invoker("setPageContent")
void midnightcontrols$setPageContent(String newContent);
}

View File

@@ -77,7 +77,7 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity
} }
} }
@Inject(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/input/Input;tick()V", shift = At.Shift.AFTER)) @Inject(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/input/Input;tick(ZF)V", shift = At.Shift.AFTER))
public void onInputUpdate(CallbackInfo ci) { public void onInputUpdate(CallbackInfo ci) {
MovementHandler.HANDLER.applyMovement((ClientPlayerEntity) (Object) this); MovementHandler.HANDLER.applyMovement((ClientPlayerEntity) (Object) this);
} }
@@ -88,11 +88,11 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity
if (MidnightControlsConfig.verticalFlyDrifting || !MidnightControls.isExtrasLoaded) if (MidnightControlsConfig.verticalFlyDrifting || !MidnightControls.isExtrasLoaded)
return; return;
int moving = 0; int moving = 0;
if (this.input.playerInput.sneak()) { if (this.input.sneaking) {
--moving; --moving;
} }
if (this.input.playerInput.jump()) { if (this.input.jumping) {
++moving; ++moving;
} }

View File

@@ -58,10 +58,4 @@ public interface CreativeInventoryScreenAccessor {
*/ */
@Invoker("hasScrollbar") @Invoker("hasScrollbar")
boolean midnightcontrols$hasScrollbar(); boolean midnightcontrols$hasScrollbar();
/**
* Triggers searching the creative inventory from the current value of the internal {@link net.minecraft.client.gui.widget.TextFieldWidget}
*/
@Invoker("search")
void midnightcontrols$search();
} }

View File

@@ -1,21 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of midnightcontrols.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package eu.midnightdust.midnightcontrols.client.mixin;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.VertexConsumerProvider;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(DrawContext.class)
public interface DrawContextAccessor {
@Accessor("vertexConsumers")
VertexConsumerProvider.Immediate getVertexConsumers();
}

View File

@@ -33,29 +33,22 @@ import static eu.midnightdust.midnightcontrols.MidnightControls.id;
@Mixin(GameOptionsScreen.class) @Mixin(GameOptionsScreen.class)
public abstract class GameOptionsScreenMixin extends Screen { public abstract class GameOptionsScreenMixin extends Screen {
@Shadow @Nullable protected OptionListWidget body; @Shadow @Nullable protected OptionListWidget body;
@Unique TextIconButtonWidget midnightcontrols$button = TextIconButtonWidget.builder(Text.translatable("midnightcontrols.menu.title.controller"), @Unique TextIconButtonWidget midnightcontrols$button = TextIconButtonWidget.builder(Text.translatable("midnightcontrols.menu.title.controller"), (button -> this.client.setScreen(new MidnightControlsSettingsScreen(this, false))), true)
(button -> this.client.setScreen(new MidnightControlsSettingsScreen(this, false))), true)
.dimension(20,20).texture(id("icon/controller"), 20, 20).build(); .dimension(20,20).texture(id("icon/controller"), 20, 20).build();
protected GameOptionsScreenMixin(Text title) { protected GameOptionsScreenMixin(Text title) {
super(title); super(title);
} }
@Inject(method = "initBody", at = @At("TAIL")) @Inject(method = "init", at = @At("TAIL"))
public void midnightcontrols$addMCButton(CallbackInfo ci) { public void midnightcontrols$addMCButton(CallbackInfo ci) {
if (this.getClass().toString().equals(ControlsOptionsScreen.class.toString())) { if (this.getClass().toString().equals(ControlsOptionsScreen.class.toString())) {
this.midnightcontrols$setButtonPos(); this.midnightcontrols$setButtonPos();
this.addSelectableChild(midnightcontrols$button);
}
}
@Inject(method = "init", at = @At("TAIL"))
public void midnightcontrols$drawMCButton(CallbackInfo ci) {
if (this.getClass().toString().equals(ControlsOptionsScreen.class.toString())) {
this.addDrawableChild(midnightcontrols$button); this.addDrawableChild(midnightcontrols$button);
} }
} }
@Inject(method = "refreshWidgetPositions", at = @At("TAIL")) @Inject(method = "initTabNavigation", at = @At("TAIL"))
public void midnightcontrols$onResize(CallbackInfo ci) { public void midnightcontrols$onResize(CallbackInfo ci) {
this.midnightcontrols$setButtonPos(); this.midnightcontrols$setButtonPos();
} }

View File

@@ -127,12 +127,12 @@ public abstract class MinecraftClientMixin {
int previousStackCount = stackInHand.getCount(); int previousStackCount = stackInHand.getCount();
var result = this.interactionManager.interactBlock(this.player, hand, hitResult); var result = this.interactionManager.interactBlock(this.player, hand, hitResult);
if (result.isAccepted()) { if (result.isAccepted()) {
//if (result.shouldSwingHand()) { if (result.shouldSwingHand()) {
this.player.swingHand(hand); this.player.swingHand(hand);
if (!stackInHand.isEmpty() && (stackInHand.getCount() != previousStackCount || this.interactionManager.hasCreativeInventory())) { if (!stackInHand.isEmpty() && (stackInHand.getCount() != previousStackCount || this.interactionManager.hasCreativeInventory())) {
this.gameRenderer.firstPersonRenderer.resetEquipProgress(hand); this.gameRenderer.firstPersonRenderer.resetEquipProgress(hand);
} }
//} }
ci.cancel(); ci.cancel();
} }

View File

@@ -20,7 +20,7 @@ import net.minecraft.client.Mouse;
import net.minecraft.client.util.GlfwUtil; import net.minecraft.client.util.GlfwUtil;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.ThrowablePotionItem; import net.minecraft.item.ThrowablePotionItem;
import net.minecraft.item.consume.UseAction; import net.minecraft.util.UseAction;
import net.minecraft.util.math.Smoother; import net.minecraft.util.math.Smoother;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;

View File

@@ -1,21 +0,0 @@
/*
* Copyright © 2021 LambdAurora <aurora42lambda@gmail.com>
*
* This file is part of midnightcontrols.
*
* Licensed under the MIT license. For more information,
* see the LICENSE file.
*/
package eu.midnightdust.midnightcontrols.client.mixin;
import net.minecraft.client.gui.screen.ingame.RecipeBookScreen;
import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(RecipeBookScreen.class)
public interface RecipeBookScreenAccessor {
@Accessor("recipeBook")
RecipeBookWidget<?> getRecipeBook();
}

View File

@@ -27,4 +27,7 @@ public interface RecipeBookWidgetAccessor {
@Accessor("currentTab") @Accessor("currentTab")
void setCurrentTab(RecipeGroupButtonWidget currentTab); void setCurrentTab(RecipeGroupButtonWidget currentTab);
@Invoker("refreshResults")
void midnightcontrols$refreshResults(boolean resetCurrentPage);
} }

View File

@@ -9,8 +9,10 @@
package eu.midnightdust.midnightcontrols.client.mixin; package eu.midnightdust.midnightcontrols.client.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import eu.midnightdust.lib.util.MidnightColorUtil; import eu.midnightdust.lib.util.MidnightColorUtil;
import eu.midnightdust.midnightcontrols.ControlsMode; import eu.midnightdust.midnightcontrols.ControlsMode;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.touch.TouchInput; import eu.midnightdust.midnightcontrols.client.touch.TouchInput;
import eu.midnightdust.midnightcontrols.client.enums.TouchMode; import eu.midnightdust.midnightcontrols.client.enums.TouchMode;
@@ -26,7 +28,8 @@ import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult; import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.ColorHelper; import net.minecraft.util.shape.VoxelShape;
import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@@ -58,8 +61,12 @@ public abstract class WorldRendererMixin {
@Final @Final
private BufferBuilderStorage bufferBuilders; private BufferBuilderStorage bufferBuilders;
@Redirect(method = "renderTargetBlockOutline", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/hit/BlockHitResult;getType()Lnet/minecraft/util/hit/HitResult$Type;")) @Shadow
private HitResult.Type dontRenderOutline(BlockHitResult instance) { private static void drawCuboidShapeOutline(MatrixStack matrices, VertexConsumer vertexConsumer, VoxelShape shape, double offsetX, double offsetY, double offsetZ, float red, float green, float blue, float alpha) {
}
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/hit/HitResult;getType()Lnet/minecraft/util/hit/HitResult$Type;"))
private HitResult.Type dontRenderOutline(HitResult instance) {
if (MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN && MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) { if (MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN && MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) {
return HitResult.Type.MISS; return HitResult.Type.MISS;
} }
@@ -67,10 +74,15 @@ public abstract class WorldRendererMixin {
} }
@Inject( @Inject(
method = "renderTargetBlockOutline", method = "render",
at = @At("HEAD") at = @At(
value = "FIELD",
target = "Lnet/minecraft/client/MinecraftClient;crosshairTarget:Lnet/minecraft/util/hit/HitResult;",
ordinal = 1,
shift = At.Shift.AFTER
)
) )
private void onOutlineRender(Camera camera, VertexConsumerProvider.Immediate vertexConsumers, MatrixStack matrices, boolean translucent, CallbackInfo ci) { private void onOutlineRender(RenderTickCounter tickCounter, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, Matrix4f matrix4f2, CallbackInfo ci, @Local MatrixStack matrices) {
if (((MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.touchInControllerMode) || MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN) if (((MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.touchInControllerMode) || MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN)
&& MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) { && MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) {
this.midnightcontrols$renderFingerOutline(matrices, camera); this.midnightcontrols$renderFingerOutline(matrices, camera);
@@ -90,8 +102,8 @@ public abstract class WorldRendererMixin {
var pos = camera.getPos(); var pos = camera.getPos();
matrices.push(); matrices.push();
var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines()); var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines());
VertexRendering.drawOutline(matrices, vertexConsumer, outlineShape, blockPos.getX() - pos.getX(), blockPos.getY() - pos.getY(), blockPos.getZ() - pos.getZ(), drawCuboidShapeOutline(matrices, vertexConsumer, outlineShape, blockPos.getX() - pos.getX(), blockPos.getY() - pos.getY(), blockPos.getZ() - pos.getZ(),
ColorHelper.withAlpha(MidnightControlsConfig.touchOutlineColorAlpha, rgb.getRGB())); rgb.getRed() / 255.f, rgb.getGreen() / 255.f, rgb.getBlue() / 255.f, MidnightControlsConfig.touchOutlineColorAlpha / 255.f);
matrices.pop(); matrices.pop();
} }
} }
@@ -122,8 +134,9 @@ public abstract class WorldRendererMixin {
if (MidnightControlsConfig.reacharoundOutlineColorHex.isEmpty()) rgb = RainbowColor.radialRainbow(1,1); if (MidnightControlsConfig.reacharoundOutlineColorHex.isEmpty()) rgb = RainbowColor.radialRainbow(1,1);
matrices.push(); matrices.push();
var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines()); var vertexConsumer = this.bufferBuilders.getEntityVertexConsumers().getBuffer(RenderLayer.getLines());
VertexRendering.drawOutline(matrices, vertexConsumer, outlineShape, blockPos.getX() - pos.getX(), blockPos.getY() - pos.getY(), blockPos.getZ() - pos.getZ(), drawCuboidShapeOutline(matrices, vertexConsumer, outlineShape,
ColorHelper.withAlpha(MidnightControlsConfig.touchOutlineColorAlpha, rgb.getRGB())); (double) blockPos.getX() - pos.getX(), (double) blockPos.getY() - pos.getY(), (double) blockPos.getZ() - pos.getZ(),
rgb.getRed() / 255.f, rgb.getGreen() / 255.f, rgb.getBlue() / 255.f, MidnightControlsConfig.reacharoundOutlineColorAlpha / 255.f);
matrices.pop(); matrices.pop();
} }
} }

View File

@@ -85,12 +85,12 @@ public class TouchInput {
int previousStackCount = stackInHand.getCount(); int previousStackCount = stackInHand.getCount();
var interaction = client.interactionManager.interactBlock(client.player, client.player.getActiveHand(), blockHit); var interaction = client.interactionManager.interactBlock(client.player, client.player.getActiveHand(), blockHit);
if (interaction.isAccepted()) { if (interaction.isAccepted()) {
//if (interaction.shouldSwingHand()) { if (interaction.shouldSwingHand()) {
client.player.swingHand(client.player.preferredHand); client.player.swingHand(client.player.preferredHand);
if (!stackInHand.isEmpty() && (stackInHand.getCount() != previousStackCount || client.interactionManager.hasCreativeInventory())) { if (!stackInHand.isEmpty() && (stackInHand.getCount() != previousStackCount || client.interactionManager.hasCreativeInventory())) {
client.gameRenderer.firstPersonRenderer.resetEquipProgress(client.player.preferredHand); client.gameRenderer.firstPersonRenderer.resetEquipProgress(client.player.preferredHand);
} }
//} }
return true; return true;
} }
} }

View File

@@ -7,7 +7,7 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.Camera; import net.minecraft.client.render.Camera;
import net.minecraft.entity.projectile.ProjectileUtil; import net.minecraft.entity.projectile.ProjectileUtil;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.consume.UseAction; import net.minecraft.util.UseAction;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult; import net.minecraft.util.hit.HitResult;

View File

@@ -1,12 +1,12 @@
package eu.midnightdust.midnightcontrols.client.touch.gui; package eu.midnightdust.midnightcontrols.client.touch.gui;
import net.minecraft.item.consume.UseAction;
import org.thinkingstudio.obsidianui.Position; import org.thinkingstudio.obsidianui.Position;
import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget; import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget;
import eu.midnightdust.midnightcontrols.MidnightControlsConstants; import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import net.minecraft.item.ArmorItem; import net.minecraft.item.ArmorItem;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.UseAction;
public class ItemUseButtonWidget extends SpruceButtonWidget { public class ItemUseButtonWidget extends SpruceButtonWidget {

View File

@@ -15,10 +15,10 @@ import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.screen.GameMenuScreen; import net.minecraft.client.gui.screen.GameMenuScreen;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.item.ArmorItem; import net.minecraft.item.ArmorItem;
import net.minecraft.item.consume.UseAction;
import net.minecraft.util.Arm; import net.minecraft.util.Arm;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.UseAction;
import org.thinkingstudio.obsidianui.Position; import org.thinkingstudio.obsidianui.Position;
import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget; import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget;
import eu.midnightdust.lib.util.PlatformFunctions; import eu.midnightdust.lib.util.PlatformFunctions;

View File

@@ -1,60 +0,0 @@
package eu.midnightdust.midnightcontrols.client.virtualkeyboard;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class KeyboardLayout {
public static KeyboardLayout QWERTY = new KeyboardLayout(createQwertyLetterLayout(), createSymbolLayout());
private final List<List<String>> letters;
private final List<List<String>> symbols;
private KeyboardLayout(List<List<String>> letters, List<List<String>> symbols) {
this.letters = letters;
this.symbols = symbols;
}
public List<List<String>> getLetters() {
return letters;
}
public List<List<String>> getSymbols() {
return symbols;
}
private static List<List<String>> createQwertyLetterLayout() {
List<List<String>> letters = new ArrayList<>();
letters.add(Arrays.asList(
"q", "w", "e", "r", "t",
"y", "u", "i", "o", "p"
));
letters.add(Arrays.asList(
"a", "s", "d", "f", "g",
"h", "j", "k", "l"
));
letters.add(Arrays.asList(
"z", "x", "c", "v",
"b", "n", "m"
));
return letters;
}
private static List<List<String>> createSymbolLayout() {
List<List<String>> symbols = new ArrayList<>();
symbols.add(Arrays.asList(
"1", "2", "3", "4", "5",
"6", "7", "8", "9", "0"
));
symbols.add(Arrays.asList(
"@", "#", "$", "%", "&",
"*", "-", "+", "(", ")"
));
symbols.add(Arrays.asList(
"!", "\"", "'", ":", ";",
",", ".", "?", "/"
));
return symbols;
}
}

View File

@@ -1,36 +0,0 @@
package eu.midnightdust.midnightcontrols.client.virtualkeyboard;
import eu.midnightdust.midnightcontrols.client.virtualkeyboard.clickhandler.AbstractScreenClickHandler;
import eu.midnightdust.midnightcontrols.client.virtualkeyboard.clickhandler.BookEditScreenClickHandler;
import eu.midnightdust.midnightcontrols.client.virtualkeyboard.clickhandler.DefaultScreenClickHandler;
import eu.midnightdust.midnightcontrols.client.virtualkeyboard.clickhandler.SignEditScreenClickHandler;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.BookEditScreen;
import net.minecraft.client.gui.screen.ingame.SignEditScreen;
import java.util.HashMap;
import java.util.Map;
public class MouseClickInterceptor {
private final Map<Class<?>, AbstractScreenClickHandler<?>> clickHandlers;
public MouseClickInterceptor() {
this.clickHandlers = new HashMap<>();
this.clickHandlers.put(BookEditScreen.class, new BookEditScreenClickHandler());
this.clickHandlers.put(SignEditScreen.class, new SignEditScreenClickHandler());
this.clickHandlers.put(Screen.class, new DefaultScreenClickHandler());
}
@SuppressWarnings("unchecked")
public <T extends Screen> void intercept(T screen, double mouseX, double mouseY) {
AbstractScreenClickHandler<T> handler = (AbstractScreenClickHandler<T>) clickHandlers.get(screen.getClass());
if (handler == null) {
handler = (AbstractScreenClickHandler<T>) clickHandlers.get(Screen.class);
}
handler.handle(screen, mouseX, mouseY);
}
}

View File

@@ -1,7 +0,0 @@
package eu.midnightdust.midnightcontrols.client.virtualkeyboard.clickhandler;
import net.minecraft.client.gui.screen.Screen;
public abstract class AbstractScreenClickHandler<T extends Screen> {
public abstract void handle(T screen, double mouseX, double mouseY);
}

View File

@@ -1,36 +0,0 @@
package eu.midnightdust.midnightcontrols.client.virtualkeyboard.clickhandler;
import eu.midnightdust.midnightcontrols.client.mixin.BookEditScreenAccessor;
import eu.midnightdust.midnightcontrols.client.virtualkeyboard.gui.VirtualKeyboardScreen;
import net.minecraft.client.gui.screen.ingame.BookEditScreen;
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.client;
public class BookEditScreenClickHandler extends AbstractScreenClickHandler<BookEditScreen> {
@Override
public void handle(BookEditScreen screen, double mouseX, double mouseY) {
// don't open the keyboard if a UI element was clicked
if(screen.hoveredElement(mouseX, mouseY).isPresent()) {
return;
}
var accessor = (BookEditScreenAccessor) screen;
VirtualKeyboardScreen virtualKeyboardScreen;
if(accessor.midnightcontrols$isSigning()) {
virtualKeyboardScreen = new VirtualKeyboardScreen(accessor.midnightcontrols$getTitle(), (text) -> {
client.setScreen(screen);
accessor.midnightcontrols$setTitle(text);
}, true);
}
else {
virtualKeyboardScreen = new VirtualKeyboardScreen(accessor.midnightcontrols$getCurrentPageContent(), (text) -> {
client.setScreen(screen);
accessor.midnightcontrols$setPageContent(text);
accessor.midnightcontrols$getCurrentPageSelectionManager().putCursorAtEnd();
}, true);
}
client.setScreen(virtualKeyboardScreen);
}
}

View File

@@ -1,144 +0,0 @@
package eu.midnightdust.midnightcontrols.client.virtualkeyboard.clickhandler;
import eu.midnightdust.midnightcontrols.client.mixin.CreativeInventoryScreenAccessor;
import eu.midnightdust.midnightcontrols.client.virtualkeyboard.gui.VirtualKeyboardScreen;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.ParentElement;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import org.lwjgl.glfw.GLFW;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.client;
public class DefaultScreenClickHandler extends AbstractScreenClickHandler<Screen> {
private Screen parentScreen;
private List<Integer> textFieldElementPath;
@Override
public void handle(Screen screen, double mouseX, double mouseY) {
var textField = findClickedTextField(screen.children(), mouseX, mouseY);
if (textField == null) {
return;
}
this.parentScreen = screen;
this.textFieldElementPath = calculatePathToElement(screen, textField.asElement());
var virtualKeyboardScreen = new VirtualKeyboardScreen(textField.getText(), this::handleKeyboardClose, false);
client.setScreen(virtualKeyboardScreen);
}
private void handleKeyboardClose(String newText) {
if (this.parentScreen == null || this.textFieldElementPath == null) {
return;
}
client.setScreen(this.parentScreen);
TextFieldWrapper textField = findTextFieldByPath(this.parentScreen, this.textFieldElementPath);
if (textField == null) {
return;
}
textField.setText(newText);
switch (this.parentScreen) {
case CreativeInventoryScreen creativeInventoryScreen -> {
var accessor = (CreativeInventoryScreenAccessor) creativeInventoryScreen;
accessor.midnightcontrols$search();
}
case ChatScreen chatScreen -> {
// send the chat message
chatScreen.keyPressed(GLFW.GLFW_KEY_ENTER, 0, 0);
}
default -> {
}
}
}
private TextFieldWrapper findClickedTextField(List<? extends Element> elements, double mouseX, double mouseY) {
for (Element element : elements) {
if (TextFieldWrapper.isValidTextField(element)) {
TextFieldWrapper textField = new TextFieldWrapper(element);
if (textField.isMouseOver(mouseX, mouseY) && textField.isFocused()) {
return textField;
}
}
if (element instanceof ParentElement parentElement) {
TextFieldWrapper found = findClickedTextField(parentElement.children(), mouseX, mouseY);
if (found != null) {
return found;
}
}
}
return null;
}
/**
* Calculates the path between a parent and a target in the UI hierarchy
*/
protected List<Integer> calculatePathToElement(Element parent, Element target) {
if (!(parent instanceof ParentElement parentElement)) {
return null;
}
List<? extends Element> children = parentElement.children();
for (int i = 0; i < children.size(); i++) {
Element child = children.get(i);
if (child == target) {
return Collections.singletonList(i);
}
if (child instanceof ParentElement) {
List<Integer> subPath = calculatePathToElement(child, target);
if (subPath != null) {
List<Integer> fullPath = new ArrayList<>(subPath.size() + 1);
fullPath.add(i);
fullPath.addAll(subPath);
return fullPath;
}
}
}
return null;
}
protected TextFieldWrapper findTextFieldByPath(Element parent, List<Integer> path) {
if (path == null || path.isEmpty()) {
return null;
}
if (!(parent instanceof ParentElement parentElement)) {
return null;
}
List<? extends Element> children = parentElement.children();
int index = path.get(0);
if (index < 0 || index >= children.size()) {
return null;
}
Element child = children.get(index);
if (path.size() == 1) {
return TextFieldWrapper.isValidTextField(child) ? new TextFieldWrapper(child) : null;
}
if (child instanceof ParentElement) {
return findTextFieldByPath(child, path.subList(1, path.size()));
}
return null;
}
}

View File

@@ -1,16 +0,0 @@
package eu.midnightdust.midnightcontrols.client.virtualkeyboard.clickhandler;
import eu.midnightdust.midnightcontrols.client.mixin.AbstractSignEditScreenAccessor;
import net.minecraft.client.gui.screen.ingame.SignEditScreen;
public class SignEditScreenClickHandler extends AbstractScreenClickHandler<SignEditScreen> {
@Override
public void handle(SignEditScreen screen, double mouseX, double mouseY) {
// don't open the keyboard if a UI element was clicked
if(screen.hoveredElement(mouseX, mouseY).isPresent()) {
return;
}
var accessor = (AbstractSignEditScreenAccessor) screen;
}
}

View File

@@ -1,77 +0,0 @@
package eu.midnightdust.midnightcontrols.client.virtualkeyboard.clickhandler;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.widget.TextFieldWidget;
import org.thinkingstudio.obsidianui.widget.text.SpruceTextFieldWidget;
public record TextFieldWrapper(Object textField) {
public TextFieldWrapper {
if (!isValidTextField(textField)) {
throw new IllegalArgumentException("Type " + textField.getClass() + " is not marked as a valid text field");
}
}
Element asElement() {
return (Element) textField;
}
String getText() {
switch (textField) {
case SpruceTextFieldWidget spruceTextField -> {
return spruceTextField.getText();
}
case TextFieldWidget vanillaTextField -> {
return vanillaTextField.getText();
}
default -> {
return null;
}
}
}
void setText(String text) {
switch (textField) {
case SpruceTextFieldWidget spruceTextField -> {
spruceTextField.setText(text);
}
case TextFieldWidget vanillaTextField -> {
vanillaTextField.setText(text);
}
default -> {
}
}
}
boolean isMouseOver(double mouseX, double mouseY) {
switch (textField) {
case SpruceTextFieldWidget spruceTextField -> {
return spruceTextField.isMouseOver(mouseX, mouseY);
}
case TextFieldWidget vanillaTextField -> {
return vanillaTextField.isMouseOver(mouseX, mouseY);
}
default -> {
return false;
}
}
}
boolean isFocused() {
switch (textField) {
case SpruceTextFieldWidget spruceTextField -> {
return spruceTextField.isFocused();
}
case TextFieldWidget vanillaTextField -> {
return vanillaTextField.isFocused();
}
default -> {
return false;
}
}
}
static boolean isValidTextField(Object textField) {
return textField instanceof TextFieldWidget || textField instanceof SpruceTextFieldWidget;
}
}

View File

@@ -1,300 +0,0 @@
package eu.midnightdust.midnightcontrols.client.virtualkeyboard.gui;
import eu.midnightdust.midnightcontrols.client.virtualkeyboard.KeyboardLayout;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text;
import org.thinkingstudio.obsidianui.Position;
import org.thinkingstudio.obsidianui.SpruceTexts;
import org.thinkingstudio.obsidianui.screen.SpruceScreen;
import org.thinkingstudio.obsidianui.widget.SpruceButtonWidget;
import org.thinkingstudio.obsidianui.widget.container.SpruceContainerWidget;
import org.thinkingstudio.obsidianui.widget.text.SpruceTextAreaWidget;
import java.util.List;
public class VirtualKeyboardScreen extends SpruceScreen {
@FunctionalInterface
public interface CloseCallback {
void onClose(String text);
}
private static final int STANDARD_KEY_WIDTH = 20;
private static final int SPECIAL_KEY_WIDTH = (int) (STANDARD_KEY_WIDTH * 1.5);
private static final int KEY_HEIGHT = 20;
private static final int HORIZONTAL_SPACING = 2;
private static final int VERTICAL_SPACING = 4;
private static final int CONTAINER_PADDING = 10;
// Key symbols
private static final String BACKSPACE_SYMBOL = "\b";
private static final String NEWLINE_SYMBOL = "\n";
private static final String SPACE_SYMBOL = " ";
private final StringBuilder buffer;
private final CloseCallback closeCallback;
private final KeyboardLayout layout;
private final boolean newLineSupport;
private boolean capsMode;
private boolean symbolMode;
private SpruceTextAreaWidget bufferDisplayArea;
private SpruceContainerWidget keyboardContainer;
public VirtualKeyboardScreen(String initialText, CloseCallback closeCallback, boolean newLineSupport) {
super(Text.literal("Virtual Keyboard"));
this.buffer = new StringBuilder(initialText);
this.closeCallback = closeCallback;
this.layout = KeyboardLayout.QWERTY;
this.capsMode = false;
this.symbolMode = false;
this.newLineSupport = newLineSupport;
}
@Override
protected void init() {
super.init();
this.bufferDisplayArea = createBufferDisplayArea();
this.addDrawableChild(this.bufferDisplayArea);
rebuildKeyboard();
int doneButtonY = this.keyboardContainer.getY() + this.keyboardContainer.getHeight() + VERTICAL_SPACING * 2;
this.addDrawableChild(
new SpruceButtonWidget(
Position.of(this, this.width / 2 - 50, doneButtonY),
100,
20,
SpruceTexts.GUI_DONE,
btn -> this.close()
)
);
}
@Override
public void render(DrawContext drawContext, int mouseX, int mouseY, float delta) {
this.renderBackground(drawContext, mouseX, mouseY, delta);
super.render(drawContext, mouseX, mouseY, delta);
}
@Override
public boolean shouldPause() {
return false;
}
@Override
public void close() {
super.close();
if (this.closeCallback != null) {
this.closeCallback.onClose(this.buffer.toString());
}
}
private void rebuildKeyboard() {
if (this.keyboardContainer != null) {
this.remove(this.keyboardContainer);
}
var layoutKeys = getActiveKeyLayout();
var keyboardContainer = createKeyboardContainer(layoutKeys);
addLayoutRows(keyboardContainer, layoutKeys);
addFunctionKeys(keyboardContainer);
addBottomRow(keyboardContainer);
this.keyboardContainer = keyboardContainer;
this.addDrawableChild(this.keyboardContainer);
}
private SpruceContainerWidget createKeyboardContainer(List<List<String>> layoutKeys) {
int containerWidth = this.width;
int totalKeyboardHeight = calculateKeyboardHeight(layoutKeys);
int keyboardY = this.bufferDisplayArea.getY() + this.bufferDisplayArea.getHeight() + VERTICAL_SPACING * 2;
return new SpruceContainerWidget(
Position.of(0, keyboardY),
containerWidth,
totalKeyboardHeight
);
}
private SpruceTextAreaWidget createBufferDisplayArea() {
int lineCount = this.newLineSupport ? 4 : 1;
int bufferX = this.width / 2 - 100;
int bufferY = this.height / 4 - VERTICAL_SPACING * 5 - 5;
int bufferWidth = 200;
int desiredHeight = (this.textRenderer.fontHeight + 2) * lineCount + 6;
var bufferDisplay = new SpruceTextAreaWidget(
Position.of(bufferX, bufferY),
bufferWidth,
desiredHeight,
Text.literal("Buffer Display")
);
bufferDisplay.setText(this.buffer.toString());
bufferDisplay.setEditable(false);
bufferDisplay.setUneditableColor(0xFFFFFFFF);
bufferDisplay.setDisplayedLines(lineCount);
bufferDisplay.setCursorToEnd();
return bufferDisplay;
}
private int calculateKeyboardHeight(List<List<String>> keyRows) {
return keyRows.size() * (KEY_HEIGHT + VERTICAL_SPACING) +
(KEY_HEIGHT + VERTICAL_SPACING) + // space for bottom row
CONTAINER_PADDING * 2; // top and bottom padding
}
private void addLayoutRows(SpruceContainerWidget container, List<List<String>> keyLayoutRows) {
int currentY = CONTAINER_PADDING;
for (List<String> row : keyLayoutRows) {
int rowWidth = calculateRowWidth(row);
// center row
int currentX = (container.getWidth() - rowWidth) / 2;
for (String key : row) {
String displayText = (this.capsMode && !this.symbolMode) ? key.toUpperCase() : key;
container.addChild(
new SpruceButtonWidget(
Position.of(currentX, currentY),
STANDARD_KEY_WIDTH,
KEY_HEIGHT,
Text.literal(displayText),
btn -> handleKeyPress(displayText)
)
);
currentX += STANDARD_KEY_WIDTH + HORIZONTAL_SPACING;
}
currentY += KEY_HEIGHT + VERTICAL_SPACING;
}
}
private int calculateRowWidth(List<String> row) {
int rowWidth = 0;
for (int i = 0; i < row.size(); i++) {
rowWidth += STANDARD_KEY_WIDTH;
// padding
if (i < row.size() - 1) {
rowWidth += HORIZONTAL_SPACING;
}
}
return rowWidth;
}
private void addFunctionKeys(SpruceContainerWidget container) {
List<String> firstRow = getActiveKeyLayout().get(0);
int firstRowWidth = calculateRowWidth(firstRow);
// position backspace at the right of the first row
int backspaceWidth = (int) (STANDARD_KEY_WIDTH * 1.5);
int backspaceX = (container.getWidth() + firstRowWidth) / 2 + HORIZONTAL_SPACING;
container.addChild(
new SpruceButtonWidget(
Position.of(backspaceX, CONTAINER_PADDING),
backspaceWidth,
KEY_HEIGHT,
Text.literal(""),
btn -> handleKeyPress(BACKSPACE_SYMBOL)
)
);
if (this.newLineSupport) {
// position newline at the right of the second row
List<String> secondRow = getActiveKeyLayout().get(1);
int newlineWidth = (int) (STANDARD_KEY_WIDTH * 1.5);
int secondRowWidth = calculateRowWidth(secondRow);
int newlineX = (container.getWidth() + secondRowWidth) / 2 + HORIZONTAL_SPACING;
int newlineY = CONTAINER_PADDING + (KEY_HEIGHT + VERTICAL_SPACING);
container.addChild(
new SpruceButtonWidget(
Position.of(newlineX, newlineY),
newlineWidth,
KEY_HEIGHT,
Text.literal(""),
btn -> handleKeyPress(NEWLINE_SYMBOL)
)
);
}
}
private void addBottomRow(SpruceContainerWidget container) {
// calculate positions for bottom row
int rowY = CONTAINER_PADDING + getActiveKeyLayout().size() * (KEY_HEIGHT + VERTICAL_SPACING);
// space bar - wide key in the middle
double spaceWidthFactor = 5.0;
int spaceKeyWidth = (int) (STANDARD_KEY_WIDTH * spaceWidthFactor);
int spaceX = (container.getWidth() - spaceKeyWidth) / 2;
container.addChild(
new SpruceButtonWidget(
Position.of(spaceX, rowY),
spaceKeyWidth,
KEY_HEIGHT,
Text.literal("Space"),
btn -> handleKeyPress(SPACE_SYMBOL)
)
);
// caps key - left of space
if (!this.symbolMode) {
int capsX = spaceX - SPECIAL_KEY_WIDTH - HORIZONTAL_SPACING * 2;
var capsModeButton = new SpruceButtonWidget(
Position.of(capsX, rowY),
SPECIAL_KEY_WIDTH,
KEY_HEIGHT,
Text.literal(this.capsMode ? "caps" : "CAPS"),
btn -> toggleCapsMode());
container.addChild(capsModeButton);
}
// symbols key - right of space
int symbolsX = spaceX + spaceKeyWidth + HORIZONTAL_SPACING * 2;
var symbolModeButton = new SpruceButtonWidget(
Position.of(symbolsX, rowY),
SPECIAL_KEY_WIDTH,
KEY_HEIGHT,
Text.literal(this.symbolMode ? "ABC" : "123?!"),
btn -> toggleSymbolMode()
);
container.addChild(symbolModeButton);
}
private void handleKeyPress(String key) {
if (key.equals(BACKSPACE_SYMBOL)) {
if (!this.buffer.isEmpty()) {
this.buffer.deleteCharAt(buffer.length() - 1);
}
} else {
this.buffer.append(key);
}
if (this.bufferDisplayArea != null) {
this.bufferDisplayArea.setText(this.buffer.toString());
this.bufferDisplayArea.setCursorToEnd();
}
}
private List<List<String>> getActiveKeyLayout() {
return this.symbolMode ? this.layout.getSymbols() : this.layout.getLetters();
}
private void toggleCapsMode() {
this.capsMode = !this.capsMode;
rebuildKeyboard();
}
private void toggleSymbolMode() {
this.symbolMode = !this.symbolMode;
rebuildKeyboard();
}
}

View File

@@ -220,8 +220,6 @@
"midnightcontrols.menu.virtual_mouse": "Virtual Mouse", "midnightcontrols.menu.virtual_mouse": "Virtual Mouse",
"midnightcontrols.menu.virtual_mouse.tooltip": "Enables the virtual mouse, which is useful during splitscreen.", "midnightcontrols.menu.virtual_mouse.tooltip": "Enables the virtual mouse, which is useful during splitscreen.",
"midnightcontrols.menu.virtual_mouse.skin": "Virtual Mouse Skin", "midnightcontrols.menu.virtual_mouse.skin": "Virtual Mouse Skin",
"midnightcontrols.menu.virtual_keyboard": "Virtual Keyboard",
"midnightcontrols.menu.virtual_keyboard.tooltip": "Enables a virtual on-screen keyboard",
"midnightcontrols.menu.hide_cursor": "Hide Normal Mouse Cursor", "midnightcontrols.menu.hide_cursor": "Hide Normal Mouse Cursor",
"midnightcontrols.menu.hide_cursor.tooltip": "Hides the normal mouse cursor, leaving only the virtual mouse visible.", "midnightcontrols.menu.hide_cursor.tooltip": "Hides the normal mouse cursor, leaving only the virtual mouse visible.",
"midnightcontrols.narrator.unbound": "Unbound %s", "midnightcontrols.narrator.unbound": "Unbound %s",

View File

@@ -3,29 +3,25 @@
"package": "eu.midnightdust.midnightcontrols.client.mixin", "package": "eu.midnightdust.midnightcontrols.client.mixin",
"compatibilityLevel": "JAVA_21", "compatibilityLevel": "JAVA_21",
"client": [ "client": [
"AdvancementsScreenAccessor",
"BookEditScreenAccessor",
"ChatScreenMixin",
"ClickableWidgetAccessor", "ClickableWidgetAccessor",
"AdvancementsScreenAccessor",
"ClientPlayerEntityMixin", "ClientPlayerEntityMixin",
"CreativeInventoryScreenAccessor",
"DrawContextAccessor",
"GameOptionsScreenMixin", "GameOptionsScreenMixin",
"CreativeInventoryScreenAccessor",
"GameRendererMixin", "GameRendererMixin",
"HandledScreenMixin", "HandledScreenMixin",
"InputUtilMixin",
"KeyBindingIDAccessor",
"KeyBindingMixin", "KeyBindingMixin",
"KeyboardMixin", "InputUtilMixin",
"MinecraftClientMixin", "MinecraftClientMixin",
"MouseAccessor",
"MouseMixin", "MouseMixin",
"RecipeBookScreenAccessor", "MouseAccessor",
"ChatScreenMixin",
"RecipeBookWidgetAccessor", "RecipeBookWidgetAccessor",
"ScreenMixin", "WorldRendererMixin",
"AbstractSignEditScreenAccessor", "KeyBindingIDAccessor",
"TabNavigationWidgetAccessor", "TabNavigationWidgetAccessor",
"WorldRendererMixin" "ScreenMixin",
"KeyboardMixin"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1

View File

@@ -26,7 +26,7 @@ dependencies {
modImplementation include ("maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric") modImplementation include ("maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric")
modImplementation include ("maven.modrinth:obsidianui:${rootProject.obsidianui_version}-fabric") {} modImplementation include ("maven.modrinth:obsidianui:${rootProject.obsidianui_version}-fabric") {}
include 'org.aperlambda:lambdajcommon:1.8.1' include 'org.aperlambda:lambdajcommon:1.8.1'
modCompileOnly "maven.modrinth:emi:${project.emi_version}" modImplementation "maven.modrinth:emi:${project.emi_version}"
common(project(path: ":common", configuration: "namedElements")) { transitive false } common(project(path: ":common", configuration: "namedElements")) { transitive false }
shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false }
@@ -92,8 +92,7 @@ unifiedPublishing {
curseforge { curseforge {
token = CURSEFORGE_TOKEN token = CURSEFORGE_TOKEN
id = rootProject.curseforge_id id = rootProject.curseforge_id
gameVersions.addAll "Java 21", project.minecraft_version gameVersions.addAll "Java 21", project.minecraft_version, project.supported_versions
if (project.supported_versions != "") gameVersions.addAll project.supported_versions
} }
} }
@@ -103,8 +102,7 @@ unifiedPublishing {
token = MODRINTH_TOKEN token = MODRINTH_TOKEN
id = rootProject.modrinth_id id = rootProject.modrinth_id
version = "$project.version-$project.name" version = "$project.version-$project.name"
gameVersions.addAll project.minecraft_version gameVersions.addAll project.minecraft_version, project.supported_versions
if (project.supported_versions != "") gameVersions.addAll project.supported_versions
} }
} }
} }

View File

@@ -3,7 +3,6 @@ package eu.midnightdust.midnightcontrols.fabric;
import eu.midnightdust.midnightcontrols.MidnightControlsConstants; import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.fabric.event.MouseClickListener;
import eu.midnightdust.midnightcontrols.packet.ControlsModePayload; import eu.midnightdust.midnightcontrols.packet.ControlsModePayload;
import eu.midnightdust.midnightcontrols.packet.FeaturePayload; import eu.midnightdust.midnightcontrols.packet.FeaturePayload;
import eu.midnightdust.midnightcontrols.packet.HelloPayload; import eu.midnightdust.midnightcontrols.packet.HelloPayload;
@@ -12,12 +11,11 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
import net.fabricmc.fabric.api.client.screen.v1.ScreenMouseEvents;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.fabricmc.fabric.api.resource.ResourcePackActivationType; import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.ModContainer;
import org.thinkingstudio.obsidianui.fabric.event.OpenScreenCallback;
import java.util.Optional; import java.util.Optional;
@@ -53,9 +51,6 @@ public class MidnightControlsClientFabric implements ClientModInitializer {
ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> MidnightControlsClient.onLeave()); ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> MidnightControlsClient.onLeave());
ClientTickEvents.START_CLIENT_TICK.register(MidnightControlsClient::onTick); ClientTickEvents.START_CLIENT_TICK.register(MidnightControlsClient::onTick);
ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
ScreenMouseEvents.allowMouseClick(screen).register(new MouseClickListener(screen));
});
FabricLoader.getInstance().getModContainer(MidnightControlsConstants.NAMESPACE).ifPresent(modContainer -> { FabricLoader.getInstance().getModContainer(MidnightControlsConstants.NAMESPACE).ifPresent(modContainer -> {
ResourceManagerHelper.registerBuiltinResourcePack(id("bedrock"), modContainer, ResourcePackActivationType.NORMAL); ResourceManagerHelper.registerBuiltinResourcePack(id("bedrock"), modContainer, ResourcePackActivationType.NORMAL);

View File

@@ -1,40 +0,0 @@
package eu.midnightdust.midnightcontrols.fabric.event;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import net.fabricmc.fabric.api.client.screen.v1.ScreenMouseEvents;
import net.minecraft.client.gui.screen.Screen;
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.clickInterceptor;
public class MouseClickListener implements ScreenMouseEvents.AllowMouseClick {
private final Screen screen;
public MouseClickListener(Screen screen) {
this.screen = screen;
}
@Override
public boolean allowMouseClick(Screen screen, double mouseX, double mouseY, int button) {
if(MidnightControlsConfig.virtualKeyboard) {
clickInterceptor.intercept(screen, mouseX, mouseY);
}
return true;
}
// Add equals and hashCode to prevent duplicate registrations
@Override
public boolean equals(Object obj) {
if (obj instanceof MouseClickListener) {
return ((MouseClickListener) obj).screen == this.screen;
}
return false;
}
@Override
public int hashCode() {
return screen.hashCode();
}
}

View File

@@ -2,34 +2,34 @@
org.gradle.parallel=true org.gradle.parallel=true
org.gradle.jvmargs=-Xmx2048M org.gradle.jvmargs=-Xmx2048M
minecraft_version=1.21.4 minecraft_version=1.21
supported_versions= supported_versions=1.21.1
yarn_mappings=1.21.4+build.1 yarn_mappings=1.21+build.2
enabled_platforms=fabric,neoforge enabled_platforms=fabric,neoforge
archives_base_name=midnightcontrols archives_base_name=midnightcontrols
mod_version=1.10.5 mod_version=1.10.0.1
maven_group=eu.midnightdust maven_group=eu.midnightdust
release_type=release release_type=beta
modrinth_id = bXX9h73M modrinth_id = bXX9h73M
curseforge_id = 621768 curseforge_id = 621768
# Configure the IDs here after creating the projects on the websites # Configure the IDs here after creating the projects on the websites
midnightlib_version=1.6.8+1.21.4 midnightlib_version=1.6.3
fabric_loader_version=0.16.9 fabric_loader_version=0.15.11
fabric_api_version=0.110.5+1.21.4 fabric_api_version=0.100.1+1.21
neoforge_version=21.4.9-beta neoforge_version=21.0.14-beta
yarn_mappings_patch_neoforge_version = 1.21+build.4 yarn_mappings_patch_neoforge_version = 1.21+build.4
quilt_loader_version=0.19.0-beta.18 quilt_loader_version=0.19.0-beta.18
quilt_fabric_api_version=7.0.1+0.83.0-1.20 quilt_fabric_api_version=7.0.1+0.83.0-1.20
sodium_version=mc1.21-0.6.0-beta.1 sodium_version=mc1.21-0.6.0-beta.1
obsidianui_version=0.2.10+mc1.21.3 obsidianui_version=0.2.7+mc1.21
modmenu_version=10.0.0-beta.1 modmenu_version=10.0.0-beta.1
emotecraft_version=2.5.5+1.21.4-fabric emotecraft_version=2.1.3-SNAPSHOT-build.29-MC1.19-fabric
bendylib_version=2.0.+ bendylib_version=2.0.+
emi_version=1.1.10+1.21+fabric emi_version=1.1.10+1.21+fabric
libgui_version=6.0.0+1.19 libgui_version=6.0.0+1.19

View File

@@ -104,8 +104,7 @@ unifiedPublishing {
curseforge { curseforge {
token = CURSEFORGE_TOKEN token = CURSEFORGE_TOKEN
id = rootProject.curseforge_id id = rootProject.curseforge_id
gameVersions.addAll "Java 21", project.minecraft_version gameVersions.addAll "Java 21", project.minecraft_version, project.supported_versions
if (project.supported_versions != "") gameVersions.addAll project.supported_versions
} }
} }
@@ -115,8 +114,7 @@ unifiedPublishing {
token = MODRINTH_TOKEN token = MODRINTH_TOKEN
id = rootProject.modrinth_id id = rootProject.modrinth_id
version = "$project.version-$project.name" version = "$project.version-$project.name"
gameVersions.addAll project.minecraft_version gameVersions.addAll project.minecraft_version, project.supported_versions
if (project.supported_versions != "") gameVersions.addAll project.supported_versions
} }
} }
} }

View File

@@ -3,7 +3,7 @@ package eu.midnightdust.midnightcontrols.client.util.platform.neoforge;
import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.network.packet.CustomPayload; import net.minecraft.network.packet.CustomPayload;
import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.c2s.common.CustomPayloadC2SPacket; import net.neoforged.neoforge.network.PacketDistributor;
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.client; import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.client;
@@ -19,12 +19,7 @@ public class NetworkUtilImpl {
handler.send(packet); handler.send(packet);
} }
public static void sendPayloadC2S(CustomPayload payload) { public static void sendPayloadC2S(CustomPayload payload) {
if (handler != null && client.world != null) { if (handler != null && client.world != null && handler.hasChannel(payload.getId().id()))
try { PacketDistributor.sendToServer(payload);
handler.send(new CustomPayloadC2SPacket(payload));
} catch (Exception e) {
e.fillInStackTrace();
}
}
} }
} }

View File

@@ -5,7 +5,6 @@ import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.client.util.platform.NetworkUtil; import eu.midnightdust.midnightcontrols.client.util.platform.NetworkUtil;
import eu.midnightdust.midnightcontrols.packet.ControlsModePayload; import eu.midnightdust.midnightcontrols.packet.ControlsModePayload;
import eu.midnightdust.midnightcontrols.packet.HelloPayload; import eu.midnightdust.midnightcontrols.packet.HelloPayload;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.resource.DirectoryResourcePack; import net.minecraft.resource.DirectoryResourcePack;
import net.minecraft.resource.ResourcePackInfo; import net.minecraft.resource.ResourcePackInfo;
import net.minecraft.resource.ResourcePackPosition; import net.minecraft.resource.ResourcePackPosition;
@@ -22,7 +21,6 @@ import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent; import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent;
import net.neoforged.neoforge.client.event.ClientTickEvent; import net.neoforged.neoforge.client.event.ClientTickEvent;
import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent;
import net.neoforged.neoforge.client.event.ScreenEvent;
import net.neoforged.neoforge.event.AddPackFindersEvent; import net.neoforged.neoforge.event.AddPackFindersEvent;
import net.neoforged.neoforgespi.locating.IModFile; import net.neoforged.neoforgespi.locating.IModFile;
@@ -36,8 +34,6 @@ import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.BIN
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.BINDING_LOOK_UP; import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.BINDING_LOOK_UP;
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.BINDING_RING; import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.BINDING_RING;
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.client; import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.client;
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.clickInterceptor;
@Mod(value = NAMESPACE, dist = Dist.CLIENT) @Mod(value = NAMESPACE, dist = Dist.CLIENT)
public class MidnightControlsClientNeoforge { public class MidnightControlsClientNeoforge {
@@ -94,15 +90,5 @@ public class MidnightControlsClientNeoforge {
public static void startClientTick(ClientTickEvent.Pre event) { public static void startClientTick(ClientTickEvent.Pre event) {
MidnightControlsClient.onTick(client); MidnightControlsClient.onTick(client);
} }
@SubscribeEvent
public static void onMouseButtonPressed(ScreenEvent.MouseButtonPressed.Pre event) {
if (MidnightControlsConfig.virtualKeyboard && !event.isCanceled()) {
Screen screen = event.getScreen();
double mouseX = event.getMouseX();
double mouseY = event.getMouseY();
clickInterceptor.intercept(screen, mouseX, mouseY);
}
}
} }
} }