diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..52354a6 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,5 @@ +Pickaxe mod needs a couple mods added to the runtime manually while in development. Those mods are as folows: + +- https://modrinth.com/mod/auth-me (any version) +- https://modrinth.com/mod/replaymod/ (newest 1.20.4) (to check for regressions) +- https://modrinth.com/mod/imgui-mc/version/1.20.4-1.0.7 \ No newline at end of file diff --git a/README.md b/README.md index 29a6d9e..43f3602 100644 --- a/README.md +++ b/README.md @@ -3,20 +3,20 @@ A mod for the game ⛏️ on Minecraft Diamondfire. -I dont have any ideas for this mod. +I don't have any ideas for this mod. ## Features - @Help command -- Relative plot coords from spawn +- Relative plot cords from spawn - Coins covering the hunger bar - XP Bar can be any supported Boss bar - @up keybind (bound to R by default) - Sage Icon - Overclock icon - itemlock Icon -- Chest Cooldown Timer (CCT) - Forge Timer +- Note-taking (bound to N by default) - Plot ad hider - Chat Stacking @@ -29,16 +29,16 @@ I dont have any ideas for this mod. - Auto /c l (Disabled by default) - Icon x, y (0, 0) by default - Enable/disable icons (off by default) -- Keybinds +- Keybindings - @up (default R) -- Various CCT Options -- Enable / desable plot ads + - Notes (Default N) +- Enable / disable plot ads ## Acknowledgements - Sputt for creating Pickaxe - Heptor / baltdev for creating the mod before this - +- AlignedCookie88 for updating imgui-mc to 1.20.4 (and being a DF player!) ## Screenshots diff --git a/build.gradle b/build.gradle index 9734703..d8cde9a 100644 --- a/build.gradle +++ b/build.gradle @@ -18,6 +18,17 @@ repositories { // 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. + exclusiveContent { + forRepository { + maven { + name = "Modrinth" + url = "https://api.modrinth.com/maven" + } + } + filter { + includeGroup "maven.modrinth" + } + } maven { name 'Xander Maven' @@ -28,7 +39,6 @@ repositories { url 'https://maven.terraformersmc.com/releases/' } - } dependencies { @@ -48,7 +58,7 @@ dependencies { exclude(group: "com.twelvemonkeys.imageio") } modImplementation "com.terraformersmc:modmenu:${project.modmenu_version}" - + modImplementation "maven.modrinth:imgui-mc:1.20.4-1.0.7" // Uncomment the following line to enable the deprecated Fabric API modules. // These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time. diff --git a/gradle.properties b/gradle.properties index 0784349..a5e52a7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ org.gradle.parallel=true minecraft_version=1.20.4 yarn_mappings=1.20.4+build.3 -loader_version=0.15.9 +loader_version=0.15.11 # Mod Properties diff --git a/src/main/java/tech/showierdata/pickaxe/Pickaxe.java b/src/main/java/tech/showierdata/pickaxe/Pickaxe.java index 66b9672..afefbce 100644 --- a/src/main/java/tech/showierdata/pickaxe/Pickaxe.java +++ b/src/main/java/tech/showierdata/pickaxe/Pickaxe.java @@ -1,5 +1,6 @@ package tech.showierdata.pickaxe; +import imgui.ImGui; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; @@ -47,6 +48,8 @@ import tech.showierdata.pickaxe.server.CommandHelper; import tech.showierdata.pickaxe.server.Plot; import tech.showierdata.pickaxe.server.Regexps; +import tech.showierdata.pickaxe.ui.NoteEditor; +import xyz.breadloaf.imguimc.Imguimc; import java.awt.*; import java.util.ArrayList; @@ -70,6 +73,7 @@ public class Pickaxe implements ModInitializer { public static final Identifier COLORS = new Identifier("pickaxe", "textures/gui/colors.png"); + public NoteEditor noteEditor; public static Pickaxe getInstance() { return instance; @@ -245,6 +249,7 @@ public void onInitialize() { LOGGER.info(String.format("Starting %s....", Constants.PICKAXE_STRING)); + this.noteEditor = new NoteEditor(this); register_callbacks(); // send a get request to https://api.modrinth.com/v2/project/{id|slug}/version @@ -399,9 +404,13 @@ private void drawMDT(DrawContext context, TextRenderer renderer) { private void register_callbacks() { // @up keybind - KeyBinding keyBinding = KeyBindingHelper.registerKeyBinding( + KeyBinding upKeybind = KeyBindingHelper.registerKeyBinding( new KeyBinding("key.pickaxe.up", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_R, "category.pickaxe.keybinds")); + KeyBinding notesKeybind = KeyBindingHelper.registerKeyBinding( + new KeyBinding("key.pickaxe.notes", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_N, "category.pickaxe.keybinds") + ); + ClientTickEvents.END_CLIENT_TICK.register(client -> { if (!isInPickaxe()) { return; @@ -424,11 +433,13 @@ private void register_callbacks() { } - //disable keybind in all areas except main mine; mesa mine; and sputtrooms - while (keyBinding.wasPressed()) { + while (upKeybind.wasPressed()) { client.player.networkHandler.sendChatMessage("@up"); + } - + if (notesKeybind.wasPressed()) { + notesKeybind.setPressed(false); // prevent spam + noteEditor.flip(); } }); diff --git a/src/main/java/tech/showierdata/pickaxe/mixin/TextFieldMixin.java b/src/main/java/tech/showierdata/pickaxe/mixin/TextFieldMixin.java new file mode 100644 index 0000000..8fa5ad8 --- /dev/null +++ b/src/main/java/tech/showierdata/pickaxe/mixin/TextFieldMixin.java @@ -0,0 +1,20 @@ +package tech.showierdata.pickaxe.mixin; + +import net.minecraft.client.gui.widget.TextFieldWidget; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import tech.showierdata.pickaxe.Pickaxe; + +@Mixin(TextFieldWidget.class) +public class TextFieldMixin { + @Inject(method = "isActive", at = @At("HEAD"), cancellable = true) + protected void write(CallbackInfoReturnable cir) { + if (Pickaxe.getInstance().noteEditor.isFocused) { + cir.setReturnValue(false); + cir.cancel(); + } + } + +} diff --git a/src/main/java/tech/showierdata/pickaxe/ui/NoteEditor.java b/src/main/java/tech/showierdata/pickaxe/ui/NoteEditor.java new file mode 100644 index 0000000..1e2ae78 --- /dev/null +++ b/src/main/java/tech/showierdata/pickaxe/ui/NoteEditor.java @@ -0,0 +1,169 @@ +package tech.showierdata.pickaxe.ui; + +import imgui.ImGui; + +import imgui.ImVec2; +import imgui.extension.texteditor.TextEditor; +import imgui.flag.ImGuiCond; +import imgui.flag.ImGuiWindowFlags; +import net.minecraft.client.MinecraftClient; +import org.lwjgl.glfw.GLFW; +import tech.showierdata.pickaxe.Pickaxe; +import xyz.breadloaf.imguimc.interfaces.Renderable; +import xyz.breadloaf.imguimc.interfaces.Theme; +import xyz.breadloaf.imguimc.theme.ImGuiDarkTheme; +import xyz.breadloaf.imguimc.Imguimc; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public class NoteEditor implements Renderable { + private final TextEditor textEditor; + private final Pickaxe pickaxe; + public String text; + public boolean isOpen; + public boolean isFocused = false; + private boolean helpScreenOpen = false; + + public static Path SAVE_FILE_PATH = Path.of("./config/pickaxe.notes.txt"); + + public NoteEditor(Pickaxe pickaxe) { + if (Files.exists(SAVE_FILE_PATH)) { + try { + this.text = Files.readString(SAVE_FILE_PATH); + } catch (IOException e) { + this.text = "Failed to load saved notes!\n\n" + e; + Pickaxe.LOGGER.error("", e); + } + } else { + this.text = ""; + } + this.textEditor = new TextEditor(); + this.textEditor.setText(this.text); + this.pickaxe = pickaxe; + this.isOpen = false; + } + + @Override + public String getName() { + return "Note Editor - Pickaxe Mod"; + } + + public void flip() { + if (this.isOpen) { + Imguimc.pullRenderable(this); + } else { + Imguimc.pushRenderable(this); + MinecraftClient client = MinecraftClient.getInstance(); + ImGui.setNextWindowSize(client.getWindow().getHeight(), client.getWindow().getWidth() / 5f, ImGuiCond.Always); + ImGui.setNextWindowPos(0, 0, ImGuiCond.Always); + ImGui.setWindowFocus(); + this.textEditor.setHandleKeyboardInputs(true); + + } + this.isOpen = !this.isOpen; + } + + public void save() { + try { + if (Files.notExists(SAVE_FILE_PATH)) { + Files.createFile(SAVE_FILE_PATH); + } + Files.writeString(SAVE_FILE_PATH, this.text); + ImGui.text("Saved!"); + } catch (IOException e) { + Pickaxe.LOGGER.error("", e); + ImGui.text("Failed to save :( (check logs for details)"); + } + } + + public String getId() { + return "pickmod-notes"; + } + + @Override + public Theme getTheme() { + return new ImGuiDarkTheme(); + } + + private void renderHelpPage(int id) { + ImGui.begin("Help - Pickaxe Mod", ImGuiWindowFlags.AlwaysAutoResize); + String text = """ + Hi, Welcome to pickaxe mod's note editor! Make sure to save your data! + + Having the editor within the game screen is unsupported. + + This UI was made with imgui-java (v1.86.12) with imgui-mc (v1.0.7) + """; + ImVec2 textSize = ImGui.calcTextSize(text); + ImGui.text(text); + ImGui.end(); + } + + private void renderTabBar() { + if (ImGui.button("Help")) { + helpScreenOpen = !helpScreenOpen; + } + + if (ImGui.beginMenu("Edit")) { + if (ImGui.menuItem("Undo", "CTRL+Z")) + textEditor.undo(1); + if (ImGui.menuItem("Redo", "CTRL+Y")) + textEditor.redo(1); + ImGui.separator(); + if (ImGui.menuItem("Cut", "CTRL+X")) + textEditor.cut(); + if (ImGui.menuItem("Copy", "CTRL+C")) + textEditor.copy(); + if (ImGui.menuItem("Paste", "CTRL+V")) + textEditor.paste(); + ImGui.endMenu(); + } + if (ImGui.button("Save")) { + ImGui.openPopup("saved"); + } + if (ImGui.beginPopup("saved")) { + save(); + ImGui.endPopup(); + } + } + + @Override + public void render() { + + if (!this.pickaxe.isInPickaxe()) { + Imguimc.pullRenderableAfterRender(this); + this.isOpen = false; + } + + MinecraftClient client = MinecraftClient.getInstance(); + + + ImGui.begin(getName(), ImGuiWindowFlags.MenuBar); + this.isFocused = ImGui.isWindowFocused(ImGui.getID(getName())); + + if (ImGui.beginMenuBar()) { + renderTabBar(); + ImGui.endMenuBar(); + }; + this.textEditor.render(getName()); + + if (ImGui.isKeyPressed(GLFW.GLFW_KEY_BACKSPACE)) { + this.textEditor.delete(); + } + + if (this.textEditor.isTextChanged()) { + this.text = this.textEditor.getText(); + } + + int id = ImGui.getWindowDockID(); + ImGui.end(); + + + if (helpScreenOpen) renderHelpPage(id); + + + } + +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index afe97bf..f8d4112 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -28,12 +28,13 @@ "pickaxe.mixins.json" ], "depends": { - "fabricloader": ">=0.15.9", + "fabricloader": ">=0.15.11", "java": ">=17", "minecraft": "~1.20.4", "fabric-api": "*", - "yet_another_config_lib_v3": "*" + "yet_another_config_lib_v3": "*", + "imguimc": "1.20.4-1.0.7" }, "suggests": { "code-client": "*" diff --git a/src/main/resources/pickaxe.mixins.json b/src/main/resources/pickaxe.mixins.json index c2f99e3..c2c0541 100644 --- a/src/main/resources/pickaxe.mixins.json +++ b/src/main/resources/pickaxe.mixins.json @@ -7,15 +7,14 @@ "ClientPlayNetworkHandlerMixin", "HandledScreenMixin", "InGameHudMixin", - "PlayerHudListMixin" - ], - "injectors": { - "defaultRequire": 1 - }, - "client": [ + "PlayerHudListMixin", + "ChatHudMixin", + "TextFieldMixin", "OtherClientPlayerEntityMixin", "PlayerHudClassMixin", - "ChatHudMixin", "SoundMixin" - ] + ], + "injectors": { + "defaultRequire": 1 + } } \ No newline at end of file