From 3f3a3088fa03a6e3c43b5d8e1f0b4790fba3ba6a Mon Sep 17 00:00:00 2001 From: Erica Marigold Date: Tue, 21 May 2024 15:12:19 +0530 Subject: [PATCH] feat: configuration & HUD indicator --- build.gradle | 32 +++++++++++----- gradle.properties | 4 +- .../xyz/devcomp/elytralock/ElytraLock.java | 24 +++++++++--- .../elytralock/config/ConfigHandler.java | 37 +++++++++++++++++++ .../elytralock/config/ConfigModel.java | 11 ++++++ .../xyz/devcomp/elytralock/config/Util.java | 9 +++++ .../elytralock/events/ClientTickEndEvent.java | 10 +++++ .../elytralock/events/HudRenderHandler.java | 24 ++++++++++++ .../integrations/ModMenuIntegration.java | 18 +++++++++ .../ClientPlayerInteractionManagerMixin.java | 2 + .../assets/elytra-lock/lang/en_us.json | 6 ++- .../assets/elytra-lock/textures/gui/.gitkeep | 0 src/main/resources/fabric.mod.json | 15 ++++++-- 13 files changed, 172 insertions(+), 20 deletions(-) create mode 100644 src/main/java/xyz/devcomp/elytralock/config/ConfigHandler.java create mode 100644 src/main/java/xyz/devcomp/elytralock/config/ConfigModel.java create mode 100644 src/main/java/xyz/devcomp/elytralock/config/Util.java create mode 100644 src/main/java/xyz/devcomp/elytralock/events/ClientTickEndEvent.java create mode 100644 src/main/java/xyz/devcomp/elytralock/events/HudRenderHandler.java create mode 100644 src/main/java/xyz/devcomp/elytralock/integrations/ModMenuIntegration.java create mode 100644 src/main/resources/assets/elytra-lock/textures/gui/.gitkeep diff --git a/build.gradle b/build.gradle index 990379b..91813a5 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { id 'maven-publish' } -version = project.mod_version +version = "${project.mod_version}+${project.minecraft_version}" group = project.maven_group base { @@ -11,11 +11,24 @@ base { } repositories { - // Add repositories to retrieve artifacts from in here. - // You should only use this when depending on other mods because - // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. - // See https://docs.gradle.org/current/userguide/declaring_repositories.html - // for more information about repositories. + mavenCentral() + maven { + // For ImageIO + name "SonaType Maven" + url "https://oss.sonatype.org/content/repositories/snapshots" + } + + maven { + // For YACL + name "Xander Maven" + url "https://maven.isxander.dev/releases" + } + + maven { + // For modmenu + name "TerraformersMC Maven" + url "https://maven.terraformersmc.com/releases" + } } loom { @@ -30,12 +43,13 @@ loom { dependencies { // To change the versions see the gradle.properties file minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - + + modImplementation "dev.isxander.yacl:yet-another-config-lib-fabric:${project.yacl_version}" + modImplementation "com.terraformersmc:modmenu:${project.modmenu_version}" } processResources { diff --git a/gradle.properties b/gradle.properties index 60b7dcb..50c2d30 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,4 +14,6 @@ maven_group=xyz.devcomp archives_base_name=elytra-lock # Dependencies -fabric_version=0.97.0+1.20.4 \ No newline at end of file +fabric_version=0.97.0+1.20.4 +yacl_version=3.3.2+1.20.4 +modmenu_version=9.0.0 \ No newline at end of file diff --git a/src/main/java/xyz/devcomp/elytralock/ElytraLock.java b/src/main/java/xyz/devcomp/elytralock/ElytraLock.java index 03f16c4..e8eab6e 100644 --- a/src/main/java/xyz/devcomp/elytralock/ElytraLock.java +++ b/src/main/java/xyz/devcomp/elytralock/ElytraLock.java @@ -1,5 +1,9 @@ package xyz.devcomp.elytralock; +import xyz.devcomp.elytralock.config.ConfigHandler; +import xyz.devcomp.elytralock.config.Util; +import xyz.devcomp.elytralock.events.HudRenderHandler; + import org.lwjgl.glfw.GLFW; import org.slf4j.Logger; @@ -7,16 +11,19 @@ import org.slf4j.LoggerFactory; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; +import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; +import net.fabricmc.loader.api.FabricLoader; + import net.minecraft.client.MinecraftClient; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.util.InputUtil; -import net.minecraft.text.Text; public class ElytraLock implements ClientModInitializer { public static final Logger LOGGER = LoggerFactory.getLogger("Elytra Lock"); + public static final FabricLoader LOADER = FabricLoader.getInstance(); private static KeyBinding lockKeybind; private static boolean locked = false; - private static MinecraftClient client; + public static MinecraftClient client; @Override public void onInitializeClient() { @@ -24,9 +31,18 @@ public class ElytraLock implements ClientModInitializer { lockKeybind = KeyBindingHelper.registerKeyBinding( new KeyBinding("key.elytralock.lock", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_J, "category.elytralock")); - LOGGER.info("Registered keybind for elytra lock"); + LOGGER.info("Registered keybind for locking elytra"); client = MinecraftClient.getInstance(); + + if (Util.isYaclLoaded()) { + LOGGER.info("YACL_v3 is loaded, loading elytra toggle"); + locked = new ConfigHandler().getInstance().toggle; + } else { + LOGGER.warn("YACL_v3 is not loaded, not persisting elytra toggle"); + } + + HudRenderCallback.EVENT.register(new HudRenderHandler()); } public static boolean isLocked() { @@ -34,8 +50,6 @@ public class ElytraLock implements ClientModInitializer { locked = !locked; } - client.inGameHud.getChatHud().addMessage(Text.translatable("elytralock.chat.lockedMessage")); - return locked; } } \ No newline at end of file diff --git a/src/main/java/xyz/devcomp/elytralock/config/ConfigHandler.java b/src/main/java/xyz/devcomp/elytralock/config/ConfigHandler.java new file mode 100644 index 0000000..a504338 --- /dev/null +++ b/src/main/java/xyz/devcomp/elytralock/config/ConfigHandler.java @@ -0,0 +1,37 @@ +package xyz.devcomp.elytralock.config; + +import xyz.devcomp.elytralock.ElytraLock; + +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.util.Identifier; + +import dev.isxander.yacl3.config.v2.api.ConfigClassHandler; +import dev.isxander.yacl3.config.v2.api.serializer.GsonConfigSerializerBuilder; + +public class ConfigHandler { + private boolean isLoaded = false; + public static final ConfigClassHandler HANDLER = ConfigClassHandler.createBuilder(ConfigModel.class) + .id(new Identifier("elytralock", "config")) + .serializer(config -> GsonConfigSerializerBuilder.create(config) + .setPath(ElytraLock.LOADER.getConfigDir().resolve("elytra-lock.json")) + .setJson5(true) + .build()) + .build(); + + private void loadConfig() { + if (!this.isLoaded) { + ElytraLock.LOGGER.info("ElytraLock config not loaded, loading"); + this.isLoaded = HANDLER.load(); + } + } + + public Screen showGui(Screen parent) { + this.loadConfig(); + return HANDLER.generateGui().generateScreen(parent); + } + + public ConfigModel getInstance() { + this.loadConfig(); + return HANDLER.instance(); + } +} \ No newline at end of file diff --git a/src/main/java/xyz/devcomp/elytralock/config/ConfigModel.java b/src/main/java/xyz/devcomp/elytralock/config/ConfigModel.java new file mode 100644 index 0000000..b2640a1 --- /dev/null +++ b/src/main/java/xyz/devcomp/elytralock/config/ConfigModel.java @@ -0,0 +1,11 @@ +package xyz.devcomp.elytralock.config; + +import dev.isxander.yacl3.config.v2.api.SerialEntry; +import dev.isxander.yacl3.config.v2.api.autogen.*; + +public class ConfigModel { + @SerialEntry(comment = "The status of the lock toggle") + @AutoGen(category = "elytralock") + @TickBox + public boolean toggle = false; +} \ No newline at end of file diff --git a/src/main/java/xyz/devcomp/elytralock/config/Util.java b/src/main/java/xyz/devcomp/elytralock/config/Util.java new file mode 100644 index 0000000..ad5635d --- /dev/null +++ b/src/main/java/xyz/devcomp/elytralock/config/Util.java @@ -0,0 +1,9 @@ +package xyz.devcomp.elytralock.config; + +import xyz.devcomp.elytralock.ElytraLock; + +public class Util { + public static boolean isYaclLoaded() { + return ElytraLock.LOADER.isModLoaded("yet_another_config_lib_v3"); + } +} diff --git a/src/main/java/xyz/devcomp/elytralock/events/ClientTickEndEvent.java b/src/main/java/xyz/devcomp/elytralock/events/ClientTickEndEvent.java new file mode 100644 index 0000000..1c23308 --- /dev/null +++ b/src/main/java/xyz/devcomp/elytralock/events/ClientTickEndEvent.java @@ -0,0 +1,10 @@ +package xyz.devcomp.elytralock.events; + +import net.minecraft.client.MinecraftClient; + +public class ClientTickEndEvent { + public void callbackHandler(MinecraftClient client) { + // Check if guy wearing elytra, if so, then remove + + } +} diff --git a/src/main/java/xyz/devcomp/elytralock/events/HudRenderHandler.java b/src/main/java/xyz/devcomp/elytralock/events/HudRenderHandler.java new file mode 100644 index 0000000..6d2270a --- /dev/null +++ b/src/main/java/xyz/devcomp/elytralock/events/HudRenderHandler.java @@ -0,0 +1,24 @@ +package xyz.devcomp.elytralock.events; + +import xyz.devcomp.elytralock.ElytraLock; + +import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.util.Window; +import net.minecraft.util.Identifier; + +public class HudRenderHandler implements HudRenderCallback { + public static final int WIDTH = 16; + public static final int HEIGHT = 16; + + public void onHudRender(DrawContext context, float delta) { + // FIXME: Perhaps don't check whether the elytra is locked on every frame + Identifier icon = new Identifier("elytra-lock", + "textures/gui/" + (ElytraLock.isLocked() ? "locked" : "unlocked") + ".png"); + + Window window = ElytraLock.client.getWindow(); + int width = window.getScaledWidth(), height = window.getScaledHeight(); + + context.drawGuiTexture(icon, (width / 2) + 95, height - HEIGHT - 3, WIDTH, HEIGHT); + } +} \ No newline at end of file diff --git a/src/main/java/xyz/devcomp/elytralock/integrations/ModMenuIntegration.java b/src/main/java/xyz/devcomp/elytralock/integrations/ModMenuIntegration.java new file mode 100644 index 0000000..2877b5d --- /dev/null +++ b/src/main/java/xyz/devcomp/elytralock/integrations/ModMenuIntegration.java @@ -0,0 +1,18 @@ +package xyz.devcomp.elytralock.integrations; + +import xyz.devcomp.elytralock.config.ConfigHandler; +import xyz.devcomp.elytralock.config.Util; + +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; + +public class ModMenuIntegration implements ModMenuApi { + @Override + public ConfigScreenFactory getModConfigScreenFactory() { + return (parent) -> { + if (!Util.isYaclLoaded()) + return parent; + return new ConfigHandler().showGui(parent); + }; + } +} diff --git a/src/main/java/xyz/devcomp/elytralock/mixin/ClientPlayerInteractionManagerMixin.java b/src/main/java/xyz/devcomp/elytralock/mixin/ClientPlayerInteractionManagerMixin.java index 7ac0844..591b3b0 100644 --- a/src/main/java/xyz/devcomp/elytralock/mixin/ClientPlayerInteractionManagerMixin.java +++ b/src/main/java/xyz/devcomp/elytralock/mixin/ClientPlayerInteractionManagerMixin.java @@ -17,6 +17,7 @@ import net.minecraft.client.network.ClientPlayerInteractionManager; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; +import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; @@ -28,6 +29,7 @@ public class ClientPlayerInteractionManagerMixin { ItemStack itemStack = player.getStackInHand(hand); if (itemStack.isOf(Items.ELYTRA) && ElytraLock.isLocked()) { ElytraLock.LOGGER.info("Skipping sending PlayerInteractItemC2SPacket for locked elytra"); + ElytraLock.client.inGameHud.getChatHud().addMessage(Text.translatable("elytralock.chat.lockedMessage")); mutableObject.setValue(ActionResult.FAIL); info.setReturnValue((ActionResult) mutableObject.getValue()); diff --git a/src/main/resources/assets/elytra-lock/lang/en_us.json b/src/main/resources/assets/elytra-lock/lang/en_us.json index 2578f8e..39beb77 100644 --- a/src/main/resources/assets/elytra-lock/lang/en_us.json +++ b/src/main/resources/assets/elytra-lock/lang/en_us.json @@ -1,5 +1,9 @@ { "category.elytralock": "Elytra Lock Keybinds", "key.elytralock.lock": "Lock elytra", - "elytralock.chat.lockedMessage": "[elytra-lock] Elytra is locked!" + + "elytralock.chat.lockedMessage": "[elytra-lock] Elytra is locked!", + + "yacl3.config.elytralock:config.toggle": "Toggle Elytra Lock", + "yacl3.config.elytralock:config.category.elytralock": "Elytra Lock" } \ No newline at end of file diff --git a/src/main/resources/assets/elytra-lock/textures/gui/.gitkeep b/src/main/resources/assets/elytra-lock/textures/gui/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index d233777..b236032 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -5,7 +5,7 @@ "name": "elytra-lock", "description": "A simple mod which registers a keybind to lock your elytra from usage when not required.", "authors": [ - "CompeyDev " + "DevComp" ], "contact": { "homepage": "https://fabricmc.net/", @@ -17,15 +17,22 @@ "entrypoints": { "client": [ "xyz.devcomp.elytralock.ElytraLock" + ], + "modmenu": [ + "xyz.devcomp.elytralock.integrations.ModMenuIntegration" ] }, "mixins": [ "elytra-lock.mixins.json" ], "depends": { - "fabricloader": "${loader_version}", - "minecraft": "${minecraft_version}", "java": "${java_version}", - "fabric-api": "*" + + "minecraft": "${minecraft_version}", + + "fabricloader": "${loader_version}", + "fabric-api": "*", + + "yet_another_config_lib_v3": "*" } } \ No newline at end of file