From e27100c00174311d765e1b5b62bee2efc80efacc Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Wed, 13 Dec 2023 20:49:02 +0000 Subject: [PATCH 1/5] Move disconnect handler to Freecam --- common/src/main/java/net/xolt/freecam/Freecam.java | 7 +++++++ .../net/xolt/freecam/mixins/ClientConnectionMixin.java | 5 +---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/net/xolt/freecam/Freecam.java b/common/src/main/java/net/xolt/freecam/Freecam.java index b6aaaca1..48210802 100644 --- a/common/src/main/java/net/xolt/freecam/Freecam.java +++ b/common/src/main/java/net/xolt/freecam/Freecam.java @@ -80,6 +80,13 @@ public static void init() { }); } + public static void onDisconnect() { + if (isEnabled()) { + toggle(); + } + clearTripods(); + } + public static void toggle() { if (tripodEnabled) { toggleTripod(activeTripod); diff --git a/common/src/main/java/net/xolt/freecam/mixins/ClientConnectionMixin.java b/common/src/main/java/net/xolt/freecam/mixins/ClientConnectionMixin.java index d7812ca3..cce44073 100644 --- a/common/src/main/java/net/xolt/freecam/mixins/ClientConnectionMixin.java +++ b/common/src/main/java/net/xolt/freecam/mixins/ClientConnectionMixin.java @@ -13,9 +13,6 @@ public class ClientConnectionMixin { // Disables freecam if the player disconnects. @Inject(method = "handleDisconnection", at = @At("HEAD")) private void onHandleDisconnection(CallbackInfo ci) { - if (Freecam.isEnabled()) { - Freecam.toggle(); - } - Freecam.clearTripods(); + Freecam.onDisconnect(); } } From 01143ecd54ea46480977154c525b77972de0546b Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Wed, 13 Dec 2023 18:05:20 +0000 Subject: [PATCH 2/5] Refactor tick handlers Extract the `ClientTickEvent.CLIENT_POST` handler into its own method `postTick` and clean up the code a little. Replace preTick mixin with a `ClientTickEvent` listener, which uses Fabric's `START_CLIENT_TICK`[1] and Forge's `ClientTickEvent` with `Phase.START`[2]. This is functionally equivalent. [1]: https://maven.fabricmc.net/docs/fabric-api-0.91.1+1.20.2/net/fabricmc/fabric/api/client/event/lifecycle/v1/ClientTickEvents.html#START_CLIENT_TICK [2]: https://nekoyue.github.io/ForgeJavaDocs-NG/javadoc/1.19.3/net/minecraftforge/event/TickEvent.ClientTickEvent.html#%3Cinit%3E(net.minecraftforge.event.TickEvent.Phase) --- .../main/java/net/xolt/freecam/Freecam.java | 67 ++++++++++++------- .../freecam/mixins/MinecraftClientMixin.java | 22 ------ 2 files changed, 44 insertions(+), 45 deletions(-) diff --git a/common/src/main/java/net/xolt/freecam/Freecam.java b/common/src/main/java/net/xolt/freecam/Freecam.java index 48210802..ecbd5102 100644 --- a/common/src/main/java/net/xolt/freecam/Freecam.java +++ b/common/src/main/java/net/xolt/freecam/Freecam.java @@ -47,37 +47,58 @@ public class Freecam { public static void init() { ModConfig.init(); Stream.of(KEY_TOGGLE, KEY_PLAYER_CONTROL, KEY_TRIPOD_RESET, KEY_CONFIG_GUI).forEach(KeyMappingRegistry::register); + ClientTickEvent.CLIENT_PRE.register(Freecam::preTick); + ClientTickEvent.CLIENT_POST.register(Freecam::postTick); + } - ClientTickEvent.CLIENT_POST.register(client -> { - if (KEY_TRIPOD_RESET.isPressed()) { - for (KeyBinding hotbarKey : MC.options.hotbarKeys) { - while (hotbarKey.wasPressed()) { - resetCamera(hotbarKey.getDefaultKey().getCode()); - while (KEY_TRIPOD_RESET.wasPressed()) {} - } - } + private static void preTick(MinecraftClient mc) { + if (isEnabled()) { + // Disable if the previous tick asked us to + if (disableNextTick()) { + toggle(); + disableNextTick = false; } - if (KEY_TOGGLE.isPressed()) { - for (KeyBinding hotbarKey : MC.options.hotbarKeys) { - while (hotbarKey.wasPressed()) { - toggleTripod(hotbarKey.getDefaultKey().getCode()); - while (KEY_TOGGLE.wasPressed()) {} - } - } - } else if (KEY_TOGGLE.wasPressed()) { - toggle(); - while (KEY_TOGGLE.wasPressed()) {} + // Prevent player from being controlled when freecam is enabled + if (mc.player != null && mc.player.input instanceof KeyboardInput && !isPlayerControlEnabled()) { + Input input = new Input(); + input.sneaking = mc.player.input.sneaking; // Makes player continue to sneak after freecam is enabled. + mc.player.input = input; } - while (KEY_PLAYER_CONTROL.wasPressed()) { - switchControls(); + mc.gameRenderer.setRenderHand(ModConfig.INSTANCE.visual.showHand); + } + } + + private static void postTick(MinecraftClient mc) { + if (KEY_TRIPOD_RESET.isPressed()) { + for (KeyBinding hotbarKey : mc.options.hotbarKeys) { + while (hotbarKey.wasPressed()) { + resetCamera(hotbarKey.getDefaultKey().getCode()); + while (KEY_TRIPOD_RESET.wasPressed()) {} + } } + } - while (KEY_CONFIG_GUI.wasPressed()) { - MC.setScreen(AutoConfig.getConfigScreen(ModConfig.class, MC.currentScreen).get()); + if (KEY_TOGGLE.isPressed()) { + for (KeyBinding hotbarKey : mc.options.hotbarKeys) { + while (hotbarKey.wasPressed()) { + toggleTripod(hotbarKey.getDefaultKey().getCode()); + while (KEY_TOGGLE.wasPressed()) {} + } } - }); + } else if (KEY_TOGGLE.wasPressed()) { + toggle(); + while (KEY_TOGGLE.wasPressed()) {} + } + + while (KEY_PLAYER_CONTROL.wasPressed()) { + switchControls(); + } + + while (KEY_CONFIG_GUI.wasPressed()) { + mc.setScreen(AutoConfig.getConfigScreen(ModConfig.class, mc.currentScreen).get()); + } } public static void onDisconnect() { diff --git a/common/src/main/java/net/xolt/freecam/mixins/MinecraftClientMixin.java b/common/src/main/java/net/xolt/freecam/mixins/MinecraftClientMixin.java index dcf00d60..60f3fadb 100644 --- a/common/src/main/java/net/xolt/freecam/mixins/MinecraftClientMixin.java +++ b/common/src/main/java/net/xolt/freecam/mixins/MinecraftClientMixin.java @@ -1,8 +1,6 @@ package net.xolt.freecam.mixins; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.input.Input; -import net.minecraft.client.input.KeyboardInput; import net.xolt.freecam.Freecam; import net.xolt.freecam.config.ModConfig; import org.spongepowered.asm.mixin.Mixin; @@ -11,29 +9,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import static net.xolt.freecam.Freecam.MC; - @Mixin(MinecraftClient.class) public class MinecraftClientMixin { - // Prevents player from being controlled when freecam is enabled. - @Inject(method = "tick", at = @At("HEAD")) - private void onTick(CallbackInfo ci) { - if (Freecam.isEnabled()) { - if (MC.player != null && MC.player.input instanceof KeyboardInput && !Freecam.isPlayerControlEnabled()) { - Input input = new Input(); - input.sneaking = MC.player.input.sneaking; // Makes player continue to sneak after freecam is enabled. - MC.player.input = input; - } - MC.gameRenderer.setRenderHand(ModConfig.INSTANCE.visual.showHand); - - if (Freecam.disableNextTick()) { - Freecam.toggle(); - Freecam.setDisableNextTick(false); - } - } - } - // Prevents attacks when allowInteract is disabled. @Inject(method = "doAttack", at = @At("HEAD"), cancellable = true) private void onDoAttack(CallbackInfoReturnable cir) { From fb2584be2265cfd2970b7de840b2805fe01bad16 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Fri, 15 Dec 2023 18:28:46 +0000 Subject: [PATCH 3/5] fixup! Refactor tick handlers --- common/src/main/java/net/xolt/freecam/Freecam.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/net/xolt/freecam/Freecam.java b/common/src/main/java/net/xolt/freecam/Freecam.java index ecbd5102..f0bcf458 100644 --- a/common/src/main/java/net/xolt/freecam/Freecam.java +++ b/common/src/main/java/net/xolt/freecam/Freecam.java @@ -51,7 +51,7 @@ public static void init() { ClientTickEvent.CLIENT_POST.register(Freecam::postTick); } - private static void preTick(MinecraftClient mc) { + public static void preTick(MinecraftClient mc) { if (isEnabled()) { // Disable if the previous tick asked us to if (disableNextTick()) { @@ -70,7 +70,7 @@ private static void preTick(MinecraftClient mc) { } } - private static void postTick(MinecraftClient mc) { + public static void postTick(MinecraftClient mc) { if (KEY_TRIPOD_RESET.isPressed()) { for (KeyBinding hotbarKey : mc.options.hotbarKeys) { while (hotbarKey.wasPressed()) { From 3ff4648f13ad8cab7c6e717891ad82feb81935ac Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Fri, 15 Dec 2023 16:55:45 +0000 Subject: [PATCH 4/5] Remove Architectury API --- common/build.gradle | 3 -- .../main/java/net/xolt/freecam/Freecam.java | 29 ++++++-------- fabric/build.gradle | 3 -- .../xolt/freecam/fabric/FreecamFabric.java | 8 +++- forge/build.gradle | 3 -- .../net/xolt.freecam/forge/FreecamForge.java | 38 +++++++++++++++---- gradle.properties | 2 - 7 files changed, 48 insertions(+), 38 deletions(-) diff --git a/common/build.gradle b/common/build.gradle index c3c84a3e..12c3ccf4 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -8,9 +8,6 @@ loom { dependencies { modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" - - modApi "dev.architectury:architectury:${rootProject.architectury_version}" - modApi "me.shedaniel.cloth:cloth-config:${rootProject.cloth_version}" } diff --git a/common/src/main/java/net/xolt/freecam/Freecam.java b/common/src/main/java/net/xolt/freecam/Freecam.java index f0bcf458..a9240097 100644 --- a/common/src/main/java/net/xolt/freecam/Freecam.java +++ b/common/src/main/java/net/xolt/freecam/Freecam.java @@ -1,7 +1,5 @@ package net.xolt.freecam; -import dev.architectury.event.events.client.ClientTickEvent; -import dev.architectury.registry.client.keymappings.KeyMappingRegistry; import me.shedaniel.autoconfig.AutoConfig; import net.minecraft.client.MinecraftClient; import net.minecraft.client.input.Input; @@ -17,21 +15,23 @@ import org.lwjgl.glfw.GLFW; import java.util.HashMap; -import java.util.stream.Stream; +import java.util.List; public class Freecam { public static final MinecraftClient MC = MinecraftClient.getInstance(); public static final String MOD_ID = "freecam"; - public static final KeyBinding KEY_TOGGLE = new KeyBinding( - "key.freecam.toggle", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_F4, "category.freecam.freecam"); - public static final KeyBinding KEY_PLAYER_CONTROL = new KeyBinding( - "key.freecam.playerControl", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN, "category.freecam.freecam"); - public static final KeyBinding KEY_TRIPOD_RESET = new KeyBinding( - "key.freecam.tripodReset", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN, "category.freecam.freecam"); - public static final KeyBinding KEY_CONFIG_GUI = new KeyBinding( - "key.freecam.configGui", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN, "category.freecam.freecam"); + public static final KeyBinding KEY_TOGGLE; + public static final KeyBinding KEY_PLAYER_CONTROL; + public static final KeyBinding KEY_TRIPOD_RESET; + public static final KeyBinding KEY_CONFIG_GUI; + public static final List ALL_KEYS = List.of( + KEY_TOGGLE = new KeyBinding("key.freecam.toggle", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_F4, "category.freecam.freecam"), + KEY_PLAYER_CONTROL = new KeyBinding("key.freecam.playerControl", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN, "category.freecam.freecam"), + KEY_TRIPOD_RESET = new KeyBinding("key.freecam.tripodReset", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN, "category.freecam.freecam"), + KEY_CONFIG_GUI = new KeyBinding("key.freecam.configGui", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN, "category.freecam.freecam") + ); private static boolean freecamEnabled = false; private static boolean tripodEnabled = false; @@ -44,13 +44,6 @@ public class Freecam { private static HashMap end_tripods = new HashMap<>(); private static Perspective rememberedF5 = null; - public static void init() { - ModConfig.init(); - Stream.of(KEY_TOGGLE, KEY_PLAYER_CONTROL, KEY_TRIPOD_RESET, KEY_CONFIG_GUI).forEach(KeyMappingRegistry::register); - ClientTickEvent.CLIENT_PRE.register(Freecam::preTick); - ClientTickEvent.CLIENT_POST.register(Freecam::postTick); - } - public static void preTick(MinecraftClient mc) { if (isEnabled()) { // Disable if the previous tick asked us to diff --git a/fabric/build.gradle b/fabric/build.gradle index db14d27a..61d7be60 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -23,9 +23,6 @@ dependencies { modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" - modApi "dev.architectury:architectury-fabric:${rootProject.architectury_version}" - include "dev.architectury:architectury-fabric:${rootProject.architectury_version}" - modImplementation ("com.terraformersmc:modmenu:${rootProject.modmenu_version}") { exclude module: "fabric-api" } diff --git a/fabric/src/main/java/net/xolt/freecam/fabric/FreecamFabric.java b/fabric/src/main/java/net/xolt/freecam/fabric/FreecamFabric.java index bd357600..7316a7ae 100644 --- a/fabric/src/main/java/net/xolt/freecam/fabric/FreecamFabric.java +++ b/fabric/src/main/java/net/xolt/freecam/fabric/FreecamFabric.java @@ -1,11 +1,17 @@ package net.xolt.freecam.fabric; import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.xolt.freecam.Freecam; +import net.xolt.freecam.config.ModConfig; public class FreecamFabric implements ClientModInitializer { @Override public void onInitializeClient() { - Freecam.init(); + ModConfig.init(); + Freecam.ALL_KEYS.forEach(KeyBindingHelper::registerKeyBinding); + ClientTickEvents.START_CLIENT_TICK.register(Freecam::preTick); + ClientTickEvents.END_CLIENT_TICK.register(Freecam::postTick); } } diff --git a/forge/build.gradle b/forge/build.gradle index bdb7d2f8..2bb72e6e 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -30,9 +30,6 @@ configurations { dependencies { forge "net.minecraftforge:forge:${rootProject.forge_version}" - modApi "dev.architectury:architectury-forge:${rootProject.architectury_version}" - include "dev.architectury:architectury-forge:${rootProject.architectury_version}" - modApi "me.shedaniel.cloth:cloth-config-forge:${rootProject.cloth_version}" include "me.shedaniel.cloth:cloth-config-forge:${rootProject.cloth_version}" diff --git a/forge/src/main/java/net/xolt.freecam/forge/FreecamForge.java b/forge/src/main/java/net/xolt.freecam/forge/FreecamForge.java index cfbae9fa..06157366 100644 --- a/forge/src/main/java/net/xolt.freecam/forge/FreecamForge.java +++ b/forge/src/main/java/net/xolt.freecam/forge/FreecamForge.java @@ -1,26 +1,48 @@ package net.xolt.freecam.forge; -import dev.architectury.platform.forge.EventBuses; import me.shedaniel.autoconfig.AutoConfig; +import net.minecraft.client.MinecraftClient; +import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.ConfigScreenHandler; +import net.minecraftforge.client.event.RegisterKeyMappingsEvent; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.eventbus.api.EventPriority; +import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.xolt.freecam.Freecam; import net.xolt.freecam.config.ModConfig; @Mod(Freecam.MOD_ID) +@Mod.EventBusSubscriber(bus = Bus.MOD, value = Dist.CLIENT) public class FreecamForge { - public FreecamForge() { - // Register our event bus with Architectury - EventBuses.registerModEventBus(Freecam.MOD_ID, FMLJavaModLoadingContext.get().getModEventBus()); + + @SubscribeEvent + public static void clientSetup(FMLClientSetupEvent event) { + ModConfig.init(); // Register our config screen with Forge ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, () -> new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> - AutoConfig.getConfigScreen(ModConfig.class, parent).get() + AutoConfig.getConfigScreen(ModConfig.class, parent).get() )); + } + + @SubscribeEvent + public static void registerKeymappings(RegisterKeyMappingsEvent event) { + Freecam.ALL_KEYS.forEach(event::register); + } - // Call our init - Freecam.init(); + @Mod.EventBusSubscriber(bus = Bus.FORGE, value = Dist.CLIENT) + public static class GlobalEventHandler { + @SubscribeEvent(priority = EventPriority.HIGH) + public static void onTick(TickEvent.ClientTickEvent event) { + final MinecraftClient client = MinecraftClient.getInstance(); + switch (event.phase) { + case START -> Freecam.preTick(client); + case END -> Freecam.postTick(client); + } + } } } diff --git a/gradle.properties b/gradle.properties index a070c377..97586372 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,8 +9,6 @@ archives_base_name=freecam mod_version=1.2.1.1 maven_group=net.xolt.freecam -architectury_version=10.0.16 - fabric_loader_version=0.14.25 fabric_api_version=0.91.1+1.20.2 From 07d64dc703810358560b28517d3c340809abb3a4 Mon Sep 17 00:00:00 2001 From: Matt Sturgeon Date: Fri, 15 Dec 2023 19:05:02 +0000 Subject: [PATCH 5/5] Store keybinds as an enum - Move keybind declarations out of `Freecam` - Removes the need for a `ALL_KEYS` list, (registering is more robust). - Constructor overloads allow more readable declarations. - Used a lazy constructor as recommended by forge docs. --- .../main/java/net/xolt/freecam/Freecam.java | 15 +-- .../net/xolt/freecam/config/ModBindings.java | 100 ++++++++++++++++++ .../freecam/mixins/MinecraftClientMixin.java | 5 +- .../xolt/freecam/fabric/FreecamFabric.java | 3 +- .../net/xolt.freecam/forge/FreecamForge.java | 3 +- 5 files changed, 110 insertions(+), 16 deletions(-) create mode 100644 common/src/main/java/net/xolt/freecam/config/ModBindings.java diff --git a/common/src/main/java/net/xolt/freecam/Freecam.java b/common/src/main/java/net/xolt/freecam/Freecam.java index a9240097..354c862c 100644 --- a/common/src/main/java/net/xolt/freecam/Freecam.java +++ b/common/src/main/java/net/xolt/freecam/Freecam.java @@ -6,7 +6,6 @@ import net.minecraft.client.input.KeyboardInput; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.option.Perspective; -import net.minecraft.client.util.InputUtil; import net.minecraft.text.Text; import net.minecraft.util.math.ChunkPos; import net.xolt.freecam.config.ModConfig; @@ -15,24 +14,14 @@ import org.lwjgl.glfw.GLFW; import java.util.HashMap; -import java.util.List; + +import static net.xolt.freecam.config.ModBindings.*; public class Freecam { public static final MinecraftClient MC = MinecraftClient.getInstance(); public static final String MOD_ID = "freecam"; - public static final KeyBinding KEY_TOGGLE; - public static final KeyBinding KEY_PLAYER_CONTROL; - public static final KeyBinding KEY_TRIPOD_RESET; - public static final KeyBinding KEY_CONFIG_GUI; - public static final List ALL_KEYS = List.of( - KEY_TOGGLE = new KeyBinding("key.freecam.toggle", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_F4, "category.freecam.freecam"), - KEY_PLAYER_CONTROL = new KeyBinding("key.freecam.playerControl", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN, "category.freecam.freecam"), - KEY_TRIPOD_RESET = new KeyBinding("key.freecam.tripodReset", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN, "category.freecam.freecam"), - KEY_CONFIG_GUI = new KeyBinding("key.freecam.configGui", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_UNKNOWN, "category.freecam.freecam") - ); - private static boolean freecamEnabled = false; private static boolean tripodEnabled = false; private static boolean playerControlEnabled = false; diff --git a/common/src/main/java/net/xolt/freecam/config/ModBindings.java b/common/src/main/java/net/xolt/freecam/config/ModBindings.java new file mode 100644 index 00000000..21c45897 --- /dev/null +++ b/common/src/main/java/net/xolt/freecam/config/ModBindings.java @@ -0,0 +1,100 @@ +package net.xolt.freecam.config; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import net.minecraft.client.option.KeyBinding; +import net.minecraft.client.util.InputUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.Objects; +import java.util.Spliterator; +import java.util.function.Consumer; + +import static org.lwjgl.glfw.GLFW.GLFW_KEY_F4; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_UNKNOWN; + +public enum ModBindings { + + KEY_TOGGLE("toggle", GLFW_KEY_F4), + KEY_PLAYER_CONTROL("playerControl"), + KEY_TRIPOD_RESET("tripodReset"), + KEY_CONFIG_GUI("configGui"); + + private final Supplier lazyBinding; + + ModBindings(String translationKey) { + this(translationKey, InputUtil.Type.KEYSYM, GLFW_KEY_UNKNOWN); + } + + ModBindings(String translationKey, int code) { + this(translationKey, InputUtil.Type.KEYSYM, code); + } + + ModBindings(String translationKey, InputUtil.Type type) { + this(translationKey, type, GLFW_KEY_UNKNOWN); + } + + ModBindings(String translationKey, InputUtil.Type type, int code) { + this.lazyBinding = Suppliers.memoize(() -> + new KeyBinding("key.freecam." + translationKey, type, code, "category.freecam.freecam")); + } + + /** + * @return the result of calling {@link KeyBinding#isPressed()} on the represented {@link KeyBinding}. + * @see KeyBinding#isPressed() + */ + public boolean isPressed() { + return get().isPressed(); + } + + /** + * @return the result of calling {@link KeyBinding#wasPressed()} on the represented {@link KeyBinding}. + * @see KeyBinding#wasPressed() + */ + public boolean wasPressed() { + return get().wasPressed(); + } + + /** + * Lazily get the actual {@link KeyBinding} represented by this enum value. + *

+ * Values are constructed if they haven't been already. + * + * @return the actual {@link KeyBinding}. + */ + public KeyBinding get() { + return lazyBinding.get(); + } + + /** + * Calls {@code action} using each {@link KeyBinding} owned by this enum. + *

+ * Values are constructed if they haven't been already. + *

+ * Static implementation of {@link Iterable#forEach(Consumer)}. + */ + public static void forEach(@NotNull Consumer action) { + Objects.requireNonNull(action); + iterator().forEachRemaining(action); + } + + /** + * Static implementation of {@link Iterable#iterator()}. + */ + public static @NotNull Iterator iterator() { + return Arrays.stream(values()) + .map(ModBindings::get) + .iterator(); + } + + /** + * Static implementation of {@link Iterable#spliterator()}. + */ + public static @NotNull Spliterator spliterator() { + return Arrays.stream(values()) + .map(ModBindings::get) + .spliterator(); + } +} diff --git a/common/src/main/java/net/xolt/freecam/mixins/MinecraftClientMixin.java b/common/src/main/java/net/xolt/freecam/mixins/MinecraftClientMixin.java index 60f3fadb..56cc1cb8 100644 --- a/common/src/main/java/net/xolt/freecam/mixins/MinecraftClientMixin.java +++ b/common/src/main/java/net/xolt/freecam/mixins/MinecraftClientMixin.java @@ -9,6 +9,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import static net.xolt.freecam.config.ModBindings.KEY_TOGGLE; +import static net.xolt.freecam.config.ModBindings.KEY_TRIPOD_RESET; + @Mixin(MinecraftClient.class) public class MinecraftClientMixin { @@ -39,7 +42,7 @@ private void onHandleBlockBreaking(CallbackInfo ci) { // Prevents hotbar keys from changing selected slot when freecam key is held @Inject(method = "handleInputEvents", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/option/KeyBinding;wasPressed()Z", ordinal = 2), cancellable = true) private void onHandleInputEvents(CallbackInfo ci) { - if (Freecam.KEY_TOGGLE.isPressed() || Freecam.KEY_TRIPOD_RESET.isPressed()) { + if (KEY_TOGGLE.isPressed() || KEY_TRIPOD_RESET.isPressed()) { ci.cancel(); } } diff --git a/fabric/src/main/java/net/xolt/freecam/fabric/FreecamFabric.java b/fabric/src/main/java/net/xolt/freecam/fabric/FreecamFabric.java index 7316a7ae..5a7a979c 100644 --- a/fabric/src/main/java/net/xolt/freecam/fabric/FreecamFabric.java +++ b/fabric/src/main/java/net/xolt/freecam/fabric/FreecamFabric.java @@ -4,13 +4,14 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.xolt.freecam.Freecam; +import net.xolt.freecam.config.ModBindings; import net.xolt.freecam.config.ModConfig; public class FreecamFabric implements ClientModInitializer { @Override public void onInitializeClient() { ModConfig.init(); - Freecam.ALL_KEYS.forEach(KeyBindingHelper::registerKeyBinding); + ModBindings.forEach(KeyBindingHelper::registerKeyBinding); ClientTickEvents.START_CLIENT_TICK.register(Freecam::preTick); ClientTickEvents.END_CLIENT_TICK.register(Freecam::postTick); } diff --git a/forge/src/main/java/net/xolt.freecam/forge/FreecamForge.java b/forge/src/main/java/net/xolt.freecam/forge/FreecamForge.java index 06157366..33850bce 100644 --- a/forge/src/main/java/net/xolt.freecam/forge/FreecamForge.java +++ b/forge/src/main/java/net/xolt.freecam/forge/FreecamForge.java @@ -13,6 +13,7 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.xolt.freecam.Freecam; +import net.xolt.freecam.config.ModBindings; import net.xolt.freecam.config.ModConfig; @Mod(Freecam.MOD_ID) @@ -31,7 +32,7 @@ public static void clientSetup(FMLClientSetupEvent event) { @SubscribeEvent public static void registerKeymappings(RegisterKeyMappingsEvent event) { - Freecam.ALL_KEYS.forEach(event::register); + ModBindings.forEach(event::register); } @Mod.EventBusSubscriber(bus = Bus.FORGE, value = Dist.CLIENT)