From e87ed5348521a854a0107f8826cffbec001ff688 Mon Sep 17 00:00:00 2001 From: Motschen Date: Sat, 23 Jul 2022 13:47:57 +0200 Subject: [PATCH] Push 1.4.2 progress to GitHub (not finished yet) --- build.gradle | 6 +- gradle.properties | 3 +- .../client/MidnightControlsClient.java | 8 +- .../client/MidnightControlsConfig.java | 6 +- .../client/MidnightInput.java | 105 ++++++++++++++---- .../client/compat/LibGuiCompat.java | 25 +++++ .../client/controller/InputHandlers.java | 2 +- .../client/controller/MovementHandler.java | 24 +++- .../client/mixin/ClickableWidgetAccessor.java | 2 + .../client/mixin/ScreenAccessor.java | 17 +++ src/main/resources/fabric.mod.json | 3 +- .../resources/midnightcontrols.mixins.json | 3 +- .../resources/resourcepacks/legacy/CREDITS | 4 + .../textures/gui/controller_axis.png | Bin 0 -> 2605 bytes .../textures/gui/controller_buttons.png | Bin 0 -> 7943 bytes .../resourcepacks/legacy/pack.mcmeta | 6 + .../resources/resourcepacks/legacy/pack.png | Bin 0 -> 14372 bytes 17 files changed, 178 insertions(+), 36 deletions(-) create mode 100644 src/main/java/eu/midnightdust/midnightcontrols/client/compat/LibGuiCompat.java create mode 100644 src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ScreenAccessor.java create mode 100644 src/main/resources/resourcepacks/legacy/CREDITS create mode 100644 src/main/resources/resourcepacks/legacy/assets/midnightcontrols/textures/gui/controller_axis.png create mode 100644 src/main/resources/resourcepacks/legacy/assets/midnightcontrols/textures/gui/controller_buttons.png create mode 100644 src/main/resources/resourcepacks/legacy/pack.mcmeta create mode 100644 src/main/resources/resourcepacks/legacy/pack.png diff --git a/build.gradle b/build.gradle index 49aeede..f33e346 100644 --- a/build.gradle +++ b/build.gradle @@ -68,8 +68,8 @@ repositories { url 'https://maven.gegy.dev' } maven { - name 'CottonMC' - url 'https://server.bbkr.space/artifactory/libs-snapshot' + name = "CottonMC" + url = "https://server.bbkr.space/artifactory/libs-release" } maven { url "https://maven.terraformersmc.com/releases/" } maven { url 'https://maven.kosmx.dev' } @@ -109,6 +109,7 @@ dependencies { // modImplementation("maven.modrinth:ok-zoomer:${project.ok_zoomer_version}") // modImplementation "io.github.ennuil:LibZoomer:${project.libzoomer_version}" + modImplementation "io.github.cottonmc:LibGui:${project.libgui_version}" modImplementation "org.quiltmc:quilt-json5:1.0.0" modCompileOnly "maven.modrinth:sodium:${project.sodium_version}" modImplementation("maven.modrinth:emi:${project.emi_version}") @@ -120,6 +121,7 @@ dependencies { shadow 'com.electronwill.night-config:core:3.6.3' shadow 'com.electronwill.night-config:toml:3.6.3' + apply plugin: 'java-library' } loom { accessWidenerPath = file("src/main/resources/midnightcontrols.accesswidener") diff --git a/gradle.properties b/gradle.properties index 254642e..ad32238 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ yarn_mappings=1.19+build.1 loader_version=0.14.7 # Mod Properties -mod_version = 1.4.1 +mod_version = 1.4.2 maven_group = eu.midnightdust archives_base_name = midnightcontrols modrinth_id=bXX9h73M @@ -23,6 +23,7 @@ modmenu_version=4.0.0 emotecraft_version=2.1.3-SNAPSHOT-build.29-MC1.19-fabric bendylib_version=2.0.+ emi_version=0.2.0+1.19 +libgui_version=6.0.0+1.19 # Ok Zoomer and LibZoomer are temporarily disabled for the time being, as we are currently using Reflection at runtime instead in OkZoomerCompat due to there being two major, completely incompatible API versions. # ok_zoomer_version=5.0.0-beta.3+1.17.1 diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java index 3c344bb..054ae39 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsClient.java @@ -119,8 +119,10 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo }); HudManager.register(this.hud = new MidnightControlsHud(this)); - FabricLoader.getInstance().getModContainer("midnightcontrols").ifPresent(modContainer -> - ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","bedrock"), modContainer, ResourcePackActivationType.NORMAL)); + FabricLoader.getInstance().getModContainer("midnightcontrols").ifPresent(modContainer -> { + ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","bedrock"), modContainer, ResourcePackActivationType.NORMAL); + ResourceManagerHelper.registerBuiltinResourcePack(new Identifier("midnightcontrols","legacy"), modContainer, ResourcePackActivationType.NORMAL); + }); } /** @@ -192,7 +194,7 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo // } } public void onRender(MinecraftClient client) { - this.input.onRender(client.getTickDelta(), client); + this.input.onRender(client); } /** diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java index 5cfd05d..e206e44 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightControlsConfig.java @@ -61,7 +61,11 @@ public class MidnightControlsConfig extends MidnightConfig { @Entry(name = "Controller ID") public static Object controllerID = 0; @Entry(name = "2nd Controller ID") public static Object secondControllerID = -1; @Entry(name = "midnightcontrols.menu.controller_type") public static ControllerType controllerType = ControllerType.DEFAULT; - @Entry(name = "Mouse screens") public static List mouseScreens = Lists.newArrayList("me.jellysquid.mods.sodium.client.gui", "net.coderbot.iris.gui", "net.minecraft.client.gui.screen.advancement", "net.minecraft.client.gui.screen.pack.PackScreen", "net.minecraft.class_5375", "net.minecraft.class_457", "net.minecraft.class_408", "me.flashyreese.mods.reeses_sodium_options.client.gui", "dev.emi.emi.screen", "hardcorequesting.client.interfaces.GuiQuestBook", "hardcorequesting.client.interfaces.GuiReward", "hardcorequesting.client.interfaces.EditTrackerScreen"); + @Entry(name = "Mouse screens") public static List mouseScreens = Lists.newArrayList("me.jellysquid.mods.sodium.client.gui", + "net.coderbot.iris.gui", "net.minecraft.client.gui.screen.advancement", "net.minecraft.client.gui.screen.pack.PackScreen", "net.minecraft.class_5375", + "net.minecraft.class_457", "net.minecraft.class_408", "me.flashyreese.mods.reeses_sodium_options.client.gui", "dev.emi.emi.screen", + "hardcorequesting.client.interfaces.GuiQuestBook", "hardcorequesting.client.interfaces.GuiReward", "hardcorequesting.client.interfaces.EditTrackerScreen", + "io.github.kosmx.emotes.arch.gui.screen.ingame.FastChosseScreen"); @Entry(name = "Keybindings") public static Map BINDINGS = new HashMap<>(); private static final Pattern BUTTON_BINDING_PATTERN = Pattern.compile("(-?\\d+)\\+?"); diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java index 093dcb0..49c6abb 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/MidnightInput.java @@ -10,9 +10,12 @@ package eu.midnightdust.midnightcontrols.client; import com.google.common.collect.ImmutableSet; +import dev.lambdaurora.spruceui.widget.AbstractSpruceWidget; import dev.lambdaurora.spruceui.widget.container.SpruceEntryListWidget; +import dev.lambdaurora.spruceui.widget.container.SpruceOptionListWidget; import eu.midnightdust.midnightcontrols.MidnightControls; import eu.midnightdust.midnightcontrols.client.compat.EMICompat; +import eu.midnightdust.midnightcontrols.client.compat.LibGuiCompat; import eu.midnightdust.midnightcontrols.client.compat.MidnightControlsCompat; import eu.midnightdust.midnightcontrols.client.compat.SodiumCompat; import eu.midnightdust.midnightcontrols.client.controller.ButtonBinding; @@ -20,9 +23,7 @@ import eu.midnightdust.midnightcontrols.client.controller.Controller; import eu.midnightdust.midnightcontrols.client.controller.InputManager; import eu.midnightdust.midnightcontrols.client.gui.TouchscreenOverlay; import eu.midnightdust.midnightcontrols.client.gui.widget.ControllerControlsWidget; -import eu.midnightdust.midnightcontrols.client.mixin.AdvancementsScreenAccessor; -import eu.midnightdust.midnightcontrols.client.mixin.CreativeInventoryScreenAccessor; -import eu.midnightdust.midnightcontrols.client.mixin.EntryListWidgetAccessor; +import eu.midnightdust.midnightcontrols.client.mixin.*; import eu.midnightdust.midnightcontrols.client.util.HandledScreenAccessor; import eu.midnightdust.midnightcontrols.client.util.MouseAccessor; import dev.lambdaurora.spruceui.navigation.NavigationDirection; @@ -45,10 +46,7 @@ import net.minecraft.client.gui.screen.ingame.MerchantScreen; import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget; import net.minecraft.client.gui.screen.world.WorldListWidget; -import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget; -import net.minecraft.client.gui.widget.EntryListWidget; -import net.minecraft.client.gui.widget.PressableWidget; -import net.minecraft.client.gui.widget.SliderWidget; +import net.minecraft.client.gui.widget.*; import net.minecraft.screen.slot.Slot; import net.minecraft.util.math.MathHelper; import org.aperlambda.lambdacommon.utils.Pair; @@ -82,6 +80,7 @@ public class MidnightInput { private float mouseSpeedX = 0.f; private float mouseSpeedY = 0.f; public int inventoryInteractionCooldown = 0; + public int screenCloseCooldown = 0; private ControllerControlsWidget controlsInput = null; @@ -122,6 +121,8 @@ public class MidnightInput { // Decreases the cooldown for GUI actions. if (this.actionGuiCooldown > 0) --this.actionGuiCooldown; + if (this.screenCloseCooldown > 0) + --this.screenCloseCooldown; InputManager.updateStates(); @@ -176,7 +177,7 @@ public class MidnightInput { * * @param client the client instance */ - public void onRender(float tickDelta, @NotNull MinecraftClient client) { + public void onRender(@NotNull MinecraftClient client) { if (!(client.currentScreen == null || client.currentScreen instanceof TouchscreenOverlay)) return; @@ -185,8 +186,8 @@ public class MidnightInput { return; if (this.targetYaw != 0.f || this.targetPitch != 0.f) { - float rotationYaw = (float) (player.prevYaw + (this.targetYaw / 0.10) * tickDelta); - float rotationPitch = (float) (player.prevPitch + (this.targetPitch / 0.10) * tickDelta); + float rotationYaw = (float) (player.prevYaw + (this.targetYaw / 0.10) * client.getTickDelta()); + float rotationPitch = (float) (player.prevPitch + (this.targetPitch / 0.10) * client.getTickDelta()); client.player.setYaw(rotationYaw); client.player.setPitch(MathHelper.clamp(rotationPitch, -90.f, 90.f)); if (client.player.isRiding() && client.player.getVehicle() != null) { @@ -302,6 +303,7 @@ public class MidnightInput { return; } } + else if (FabricLoader.getInstance().isModLoaded("libgui")) LibGuiCompat.handlePress(client.currentScreen); } } @@ -330,7 +332,7 @@ public class MidnightInput { Screen.wrapScreenError(() -> client.currentScreen.mouseReleased(mouseX, mouseY, GLFW.GLFW_MOUSE_BUTTON_1), "mouseReleased event handler", client.currentScreen.getClass().getCanonicalName()); } - //this.actionGuiCooldown = 5; + this.screenCloseCooldown = 5; } else { this.ignoreNextARelease = false; } @@ -472,6 +474,14 @@ public class MidnightInput { } else if (client.currentScreen != null) { if (axis == GLFW_GAMEPAD_AXIS_RIGHT_Y && absValue >= deadZone) { float finalValue = value; + client.currentScreen.children().stream().filter(element -> element instanceof SpruceEntryListWidget) + .map(element -> (SpruceEntryListWidget) element) + .filter(AbstractSpruceWidget::isFocusedOrHovered) + .anyMatch(element -> { + MidnightControls.get().log(String.valueOf(finalValue)); + element.mouseScrolled(0.0, 0.0, -finalValue); + return true; + }); client.currentScreen.children().stream().filter(element -> element instanceof EntryListWidget) .map(element -> (EntryListWidget) element) .filter(element -> element.getType().isFocused()) @@ -479,14 +489,6 @@ public class MidnightInput { element.mouseScrolled(0.0, 0.0, -finalValue); return true; }); - client.currentScreen.children().stream().filter(element -> element instanceof SpruceEntryListWidget) - .map(element -> (SpruceEntryListWidget) element) - .filter(element -> element.getType().isFocused()) - .anyMatch(element -> { - MidnightControls.get().log(String.valueOf(finalValue)); - element.mouseScrolled(0.0, 0.0, -finalValue); - return true; - }); return; } } @@ -621,7 +623,7 @@ public class MidnightInput { this.actionGuiCooldown = 2; // Prevent to press too quickly the focused element, so we have to skip 5 ticks. return false; } else if (element instanceof AlwaysSelectedEntryListWidget) { - ((EntryListWidgetAccessor) element).midnightcontrols$moveSelection(right ? EntryListWidget.MoveDirection.UP : EntryListWidget.MoveDirection.DOWN); + ((EntryListWidgetAccessor) element).midnightcontrols$moveSelection(right ? EntryListWidget.MoveDirection.DOWN : EntryListWidget.MoveDirection.UP); return false; } else if (element instanceof ParentElement entryList) { var focused = entryList.getFocused(); @@ -672,6 +674,69 @@ public class MidnightInput { } if (FabricLoader.getInstance().isModLoaded("sodium")) SodiumCompat.handleInput(screen, direction.isLookingForward()); + // This still needs some work +// ScreenAccessor accessor = (ScreenAccessor) screen; +// if (accessor.getSelected() != null && accessor.getSelected() instanceof ClickableWidget selected && accessor.getSelectables() != null) { +// //System.out.println(direction); +// if (accessor.getSelectables().size() >= 2) { +// //System.out.println(direction + " 2"); +// int xDifference = Integer.MAX_VALUE; +// int yDifference = Integer.MAX_VALUE; +// ClickableWidget newWidget = null; +// for (int i = 0; i < accessor.getSelectables().size(); ++i) { +// if (accessor.getSelectables().get(i) instanceof ClickableWidget candidate) { +// if (!(candidate.x == selected.x && candidate.y == selected.y)) { +// int canXDifference = Math.abs(candidate.x - selected.x); +// int canYDifference = Math.abs(candidate.y - selected.y); +// if (direction.isHorizontal()) { +// if (direction.isLookingForward()) { +// if (candidate.x >= selected.x && canYDifference <= yDifference && canXDifference <= xDifference) { +// System.out.println(direction + " forward horizontal " + candidate); +// newWidget = candidate; +// xDifference = canXDifference; +// yDifference = canYDifference; +// } +// } else { +// if (candidate.x <= selected.x && canYDifference <= yDifference && canXDifference >= xDifference) { +// System.out.println(direction + " backward horizontal " + candidate); +// newWidget = candidate; +// xDifference = canXDifference; +// yDifference = canYDifference; +// } +// } +// } else { +// if (direction.isLookingForward()) { +// if (candidate.y >= selected.y && canYDifference <= yDifference && canXDifference <= xDifference) { +// System.out.println(direction + " forward vertical " + candidate); +// newWidget = candidate; +// xDifference = canXDifference; +// yDifference = canYDifference; +// } +// } else { +// if (candidate.y <= selected.y && canYDifference >= yDifference && canXDifference <= xDifference) { +// System.out.println(direction + " backward vertical " + candidate); +// newWidget = candidate; +// xDifference = canXDifference; +// yDifference = canYDifference; +// } +// } +// } +// } +// } +// } +// if (newWidget != null) { +// //selected.changeFocus(true); +// ((ClickableWidgetAccessor) selected).setFocused(false); +// ((ClickableWidgetAccessor) newWidget).setFocused(true); +// screen.setFocused(newWidget); +// screen.changeFocus(false); +// screen.changeFocus(true); +// this.actionGuiCooldown = 5; +// return true; +// } +// +// } +// } if (!screen.changeFocus(direction.isLookingForward())) { if (screen.changeFocus(direction.isLookingForward())) { this.actionGuiCooldown = 5; diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/compat/LibGuiCompat.java b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/LibGuiCompat.java new file mode 100644 index 0000000..270fd9d --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/compat/LibGuiCompat.java @@ -0,0 +1,25 @@ +package eu.midnightdust.midnightcontrols.client.compat; + +import io.github.cottonmc.cotton.gui.impl.client.CottonScreenImpl; +import io.github.cottonmc.cotton.gui.widget.WButton; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.sound.PositionedSoundInstance; +import net.minecraft.sound.SoundEvents; +import org.jetbrains.annotations.NotNull; + +@SuppressWarnings("UnstableApiUsage") +public class LibGuiCompat { + public static boolean handlePress(@NotNull Screen screen) { + if (screen instanceof CottonScreenImpl cottonScreen) { + if (cottonScreen.getDescription() != null && cottonScreen.getDescription().getFocus() != null) { + if (cottonScreen.getDescription().getFocus() instanceof WButton button && button.getOnClick() != null) { + button.getOnClick().run(); + MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F)); + return true; + } + } + } + return false; + } +} diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java index 4885c4e..c37c9e3 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/InputHandlers.java @@ -328,7 +328,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; + return client.currentScreen == null && MidnightControlsClient.get().input.screenCloseCooldown <= 0; } /** diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/MovementHandler.java b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/MovementHandler.java index 04d653e..3d47a28 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/controller/MovementHandler.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/controller/MovementHandler.java @@ -13,7 +13,17 @@ import eu.midnightdust.midnightcontrols.client.ButtonState; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.input.Input; import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.client.tutorial.MovementTutorialStepHandler; +import net.minecraft.client.util.InputUtil; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.enchantment.Enchantments; +import net.minecraft.enchantment.SoulSpeedEnchantment; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.NbtList; +import net.minecraft.nbt.scanner.SimpleNbtScanner; +import net.minecraft.util.math.MathHelper; import org.jetbrains.annotations.NotNull; /** @@ -79,18 +89,20 @@ public final class MovementHandler implements PressAction { this.pressingBack = direction < 0; this.movementForward = direction * value; - // Slowing down if sneaking. - if (client.player.input.sneaking) - this.movementForward *= 0.3D; + // Slowing down if sneaking or crawling. + if (client.player.shouldSlowDown()) { + this.movementForward *= MathHelper.clamp(0.3F + EnchantmentHelper.getSwiftSneakSpeedBoost(client.player), 0.0F, 1.0F); + } } else { // Handle sideways movement. this.pressingLeft = direction > 0; this.pressingRight = direction < 0; this.movementSideways = direction * value; - // Slowing down if sneaking. - if (client.player.input.sneaking) - this.movementSideways *= 0.3D; + // Slowing down if sneaking or crawling. + if (client.player.shouldSlowDown()) { + this.movementSideways *= MathHelper.clamp(0.3F + EnchantmentHelper.getSwiftSneakSpeedBoost(client.player), 0.0F, 1.0F); + } } return this.shouldOverrideMovement; diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ClickableWidgetAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ClickableWidgetAccessor.java index f94af4c..0457c00 100644 --- a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ClickableWidgetAccessor.java +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ClickableWidgetAccessor.java @@ -17,4 +17,6 @@ import org.spongepowered.asm.mixin.gen.Accessor; public interface ClickableWidgetAccessor { @Accessor("height") int getHeight(); + @Accessor("focused") + void setFocused(boolean value); } diff --git a/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ScreenAccessor.java b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ScreenAccessor.java new file mode 100644 index 0000000..f9b2b01 --- /dev/null +++ b/src/main/java/eu/midnightdust/midnightcontrols/client/mixin/ScreenAccessor.java @@ -0,0 +1,17 @@ +package eu.midnightdust.midnightcontrols.client.mixin; + +import net.minecraft.client.gui.Selectable; +import net.minecraft.client.gui.screen.Screen; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.List; + +@Mixin(Screen.class) +public interface ScreenAccessor { + @Accessor + List getSelectables(); + @Accessor @Nullable + Selectable getSelected(); +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 8f087aa..2276825 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -12,6 +12,7 @@ "akemin-dayo", "DioEgizio", "Ivanoks", + "KiskaUWU", "FlashyReese", "Hambaka", "joaoh1", @@ -53,7 +54,7 @@ "modmenu": ">=1.12.2" }, "suggests": { - "quilt_loader": "*" + "kontrolo": "*" }, "breaks": { "lambdacontrols": "*", diff --git a/src/main/resources/midnightcontrols.mixins.json b/src/main/resources/midnightcontrols.mixins.json index bec043d..6e78115 100644 --- a/src/main/resources/midnightcontrols.mixins.json +++ b/src/main/resources/midnightcontrols.mixins.json @@ -17,7 +17,8 @@ "MouseMixin", "RecipeBookWidgetAccessor", "WorldRendererMixin", - "KeyBindingRegistryImplAccessor" + "KeyBindingRegistryImplAccessor", + "ScreenAccessor" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/resources/resourcepacks/legacy/CREDITS b/src/main/resources/resourcepacks/legacy/CREDITS new file mode 100644 index 0000000..ddea80e --- /dev/null +++ b/src/main/resources/resourcepacks/legacy/CREDITS @@ -0,0 +1,4 @@ +Some of the textures in this Resourcepack are directly taken from the Console Edition assets and are therefore © Mojang Studios. +Credits go to Ivanoks for redrawing the Console Generic, Dualshock, DualSense, Switch, Xbox 360 and XBox One controller icons in 15x15, +Motschen for creating the assets for the other controllers +and LambdAurora for the original assets, part of which are also included. diff --git a/src/main/resources/resourcepacks/legacy/assets/midnightcontrols/textures/gui/controller_axis.png b/src/main/resources/resourcepacks/legacy/assets/midnightcontrols/textures/gui/controller_axis.png new file mode 100644 index 0000000000000000000000000000000000000000..fccf05b888ac0a41d5bd553cde6ef728b00598d9 GIT binary patch literal 2605 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