From 5ca7c01fcdf11bc3c18b64b244b8e1b116d26ba1 Mon Sep 17 00:00:00 2001 From: PseudoDistant Date: Thu, 28 Dec 2023 09:32:15 -0500 Subject: [PATCH] Fix crash when attempting to close title menu --- build.gradle | 2 +- gradle.properties | 2 +- .../minifabric_api/impl/MenuDuck.java | 5 - .../minifabric_api/impl/ModsDisplay.java | 233 ++++++------------ .../minifabric_api/impl/SingleModDisplay.java | 47 +++- .../mixin/SelectControlMenuMixin.java | 25 -- .../mixin/TitleDisplayMixin.java | 104 +++++--- src/main/resources/fabric.mod.json | 4 +- src/main/resources/modmenu.mixins.json | 4 +- 9 files changed, 185 insertions(+), 241 deletions(-) delete mode 100644 src/main/java/io/github/minifabric/minifabric_api/impl/MenuDuck.java delete mode 100644 src/main/java/io/github/minifabric/minifabric_api/mixin/SelectControlMenuMixin.java diff --git a/build.gradle b/build.gradle index 6f4a90c..d62106c 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ repositories { } dependencies { - implementation files("libs/minicraft_delux.jar") + implementation files("libs/ld22.jar") implementation 'io.github.pseudodistant:MinicraftGameProvider:1.2.0' implementation "net.fabricmc:fabric-loader:${project.loader_version}" implementation "net.fabricmc:sponge-mixin:0.11.0+mixin.0.8.5" diff --git a/gradle.properties b/gradle.properties index f3808b4..b2edfe5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1G loader_version=0.15.3 # Mod Properties - mod_version = 1.2.0-delux + mod_version = 1.2.0-ld22 maven_group = io.github.minifabric archives_base_name = minifabric-modmenu diff --git a/src/main/java/io/github/minifabric/minifabric_api/impl/MenuDuck.java b/src/main/java/io/github/minifabric/minifabric_api/impl/MenuDuck.java deleted file mode 100644 index 2569494..0000000 --- a/src/main/java/io/github/minifabric/minifabric_api/impl/MenuDuck.java +++ /dev/null @@ -1,5 +0,0 @@ -package io.github.minifabric.minifabric_api.impl; - -public interface MenuDuck { - int minifabric_modmenu$selectionGetter(); -} diff --git a/src/main/java/io/github/minifabric/minifabric_api/impl/ModsDisplay.java b/src/main/java/io/github/minifabric/minifabric_api/impl/ModsDisplay.java index fc6973c..de47b0e 100644 --- a/src/main/java/io/github/minifabric/minifabric_api/impl/ModsDisplay.java +++ b/src/main/java/io/github/minifabric/minifabric_api/impl/ModsDisplay.java @@ -1,133 +1,75 @@ package io.github.minifabric.minifabric_api.impl; -import com.mojang.ld22.GameControl; -import com.mojang.ld22.GameState; -import com.mojang.ld22.InputHandler; import com.mojang.ld22.gfx.Color; import com.mojang.ld22.gfx.Font; import com.mojang.ld22.gfx.Screen; -import com.mojang.ld22.gfx.SpriteSheet; -import com.mojang.ld22.screen.controlmenu.*; +import com.mojang.ld22.screen.AboutMenu; +import com.mojang.ld22.screen.InstructionsMenu; +import com.mojang.ld22.screen.Menu; import com.mojang.ld22.sound.Sound; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Objects; -public class ModsDisplay extends SelectControlMenu { - //private static final String[] defaultOptions = new String[]{"Highscore", "Load game", "Save game", "Start new game", "Resume game", "Respawn"}; +public class ModsDisplay extends Menu { private static String[] defaultOptions; + + private int selected = 0; public static final int titleColor = Color.get(0, 8, 131, 551); + private Menu parent; private final Collection modsList = FabricLoader.getInstance().getAllMods(); - private static String modName = ""; - - public static String getModName() { return modName; } private static ArrayList modNames; - private static final ArrayList modVersions = new ArrayList<>(); + private static ArrayList modVersions; + + private static ArrayList modDescriptions; - public ModsDisplay(SelectControlMenu parent) { - super(parent); + public ModsDisplay(Menu parent) { this.parent = parent; } - private static ArrayList getModNames() { - Collection modsList = FabricLoader.getInstance().getAllMods(); - ArrayList modNames = new ArrayList<>(); + //TODO: Scrolling - if(ModsDisplay.modNames != null) { - modNames.addAll(ModsDisplay.modNames); - return modNames; + @Override + public void tick() { + if (this.input.up.clicked) { + --this.selected; } - if(modsList.isEmpty()) { - System.err.println("ERROR: No mods are detected by Fabric Loader somehow..."); - return new ArrayList<>(); + if (this.input.down.clicked) { + ++this.selected; } - modVersions.clear(); - - // Iterate between every mod loaded by Fabric. - for (ModContainer container : modsList) { - if (container != null) { - String name = container.getMetadata().getName(); - if (!container.getMetadata().getId().equals("java")) { - modNames.add(name); - modVersions.add(container.getMetadata().getVersion().toString()); - } - } + int len = modNames.size(); + if (this.selected < 0) { + this.selected += len; } - if(ModsDisplay.modNames == null) - ModsDisplay.modNames = new ArrayList<>(); - else - ModsDisplay.modNames.clear(); - - ModsDisplay.modNames.addAll(modNames); - - return modNames; - } - - public void init(GameControl gameControl, InputHandler input) { - defaultOptions = getModNames().toArray(new String[0]); - super.init(gameControl, input); - int[] new_selectable = new int[defaultOptions.length]; - - int amount; - for(amount = 0; amount < defaultOptions.length; ++amount) { - new_selectable[amount] = 1; + if (this.selected >= len) { + this.selected -= len; } - amount = defaultOptions.length; - - this.setOptions(Arrays.copyOf(defaultOptions, amount)); - this.selected = this.options.length - 1; - } + if (this.input.attack.clicked || this.input.menu.clicked) { + if (this.selected == modNames.size() - 1) { + this.game.setMenu(parent); + } else { + String description = modDescriptions.get(selected) == null ? + "" : modDescriptions.get(selected); + this.game.setMenu(new SingleModDisplay(this, modNames.get(selected), description, modVersions.get(selected))); - public void optionSelected(int selected) { - String description = modsList.stream() - .filter(mod -> Objects.equals(mod.getMetadata().getName(), defaultOptions[selected])) - .findFirst().get().getMetadata().getDescription() == null ? - "" : modsList.stream() - .filter(mod -> Objects.equals(mod.getMetadata().getName(), defaultOptions[selected])) - .findFirst().get().getMetadata().getDescription(); - this.gameControl.setMenu(new SingleModDisplay(this, defaultOptions[selected], description, modVersions.get(selected))); - - } - - public void render(Screen screen) { - screen.clear(0); - int h = 2; - int w = 13; - int xo = (screen.w - w * SpriteSheet.spriteSize) / 2; - int yo = 1; - screen.renderSprite(xo, yo * SpriteSheet.spriteSize, 0, 28, titleColor, 0, w * SpriteSheet.spriteSize, h * SpriteSheet.spriteSize); - xo = (screen.w - 4 * SpriteSheet.spriteSize) / 2; - yo += h; - screen.renderSprite(xo, yo * SpriteSheet.spriteSize, 13, 28, titleColor, 0, 4 * SpriteSheet.spriteSize, SpriteSheet.spriteSize); - this.menuTop = yo + h + 1; - super.render(screen, false); - Font.draw(GameControl.VERSION, screen, screen.w - GameControl.VERSION.length() * SpriteSheet.spriteSize, screen.h - SpriteSheet.spriteSize, infoCol); + } + } } -} -/* - private final Collection modsList = FabricLoader.getInstance().getAllMods(); - private static String modName = ""; - - public static String getModName() { return modName; } - - private static ArrayList modNames = null; - private static final ArrayList modVersions = new ArrayList<>(); - - ControlMenu parent; private static ArrayList getModNames() { Collection modsList = FabricLoader.getInstance().getAllMods(); ArrayList modNames = new ArrayList<>(); + ArrayList modDescs = new ArrayList<>(); + ArrayList versions = new ArrayList<>(); if(ModsDisplay.modNames != null) { modNames.addAll(ModsDisplay.modNames); @@ -139,92 +81,75 @@ private static ArrayList getModNames() { return new ArrayList<>(); } - modVersions.clear(); - // Iterate between every mod loaded by Fabric. for (ModContainer container : modsList) { if (container != null) { String name = container.getMetadata().getName(); if (!container.getMetadata().getId().equals("java")) { modNames.add(name); - modVersions.add(container.getMetadata().getVersion().toString()); + versions.add(container.getMetadata().getVersion().toString()); + modDescs.add(container.getMetadata().getDescription()); } } } + modNames.add("Back to menu"); + versions.add(""); + modDescs.add(""); - if(ModsDisplay.modNames == null) + if(ModsDisplay.modNames == null || ModsDisplay.modVersions == null || ModsDisplay.modDescriptions == null) { ModsDisplay.modNames = new ArrayList<>(); - else + ModsDisplay.modDescriptions = new ArrayList<>(); + ModsDisplay.modVersions = new ArrayList<>(); + } else { ModsDisplay.modNames.clear(); + ModsDisplay.modDescriptions.clear(); + ModsDisplay.modVersions.clear(); + } + ModsDisplay.modNames.addAll(modNames); + ModsDisplay.modVersions.addAll(versions); + ModsDisplay.modDescriptions.addAll(modDescs); return modNames; } - public ModsDisplay(ControlMenu parent) { - super(parent); - this.parent = parent; - } - - @Override - public void init(GameControl gameControl, InputHandler input) { - super.init(gameControl, input); - modName = ""; - - ArrayList modNames = getModNames(); - - int[] entries = new int[modNames.size()]; - - for(int i = 0; i < entries.length; i++) { - entries[i] = 1; - String name = modNames.get(i); - final String version = modVersions.get(i); - String description = modsList.stream() - .filter(mod -> Objects.equals(mod.getMetadata().getName(), name)) - .findFirst().get().getMetadata().getDescription() == null ? - "" : modsList.stream() - .filter(mod -> Objects.equals(mod.getMetadata().getName(), name)) - .findFirst().get().getMetadata().getDescription(); - + public void init() { + defaultOptions = getModNames().toArray(new String[0]); + int[] new_selectable = new int[defaultOptions.length]; - entries[i] = new SelectEntry(modNames.get(i), () -> { - Game.setDisplay(new BookDisplay(description, false)); - }, false) {}; + int amount; + amount = modNames.size(); + for(amount = 0; amount < defaultOptions.length; ++amount) { + new_selectable[amount] = 1; } - - - - menus = new Menu[] { - new Menu.Builder(false, 0, RelPos.CENTER, entries) - .setDisplayLength(5) - .setScrollPolicies(1, true) - .createMenu() - }; } - @Override public void render(Screen screen) { - super.render(screen); - - int sel = ((MenuDuck)menus[0]).minifabric_modmenu$selectionGetter(); - if(sel >= 0 && sel < modVersions.size()) { - String name = modNames.get(sel); - String version = modVersions.get(sel); - int col = Color.WHITE; - Font.drawCentered(Localization.getLocalized("Name:") + " " + name, screen, Font.textHeight() * 2, col); - Font.drawCentered(Localization.getLocalized("Mod version:") + " " + version, screen, Font.textHeight() * 7/2, col); + screen.clear(0); + int h = 2; + int w = 13; + int titleColor = Color.get(0, 8, 131, 551); + int xo = (screen.w - w * 8) / 2; + int yo = 24; + + int i; + for(i = 0; i < h; ++i) { + for(int x = 0; x < w; ++x) { + screen.render(xo + x * 8, yo + i * 8, x + (i + 6) * 32, titleColor, 0); + } } - Font.drawCentered(Game.input.getMapping("select") + Localization.getLocalized(" to confirm"), screen, Screen.h - 60, Color.GRAY); - Font.drawCentered(Game.input.getMapping("exit") + Localization.getLocalized(" to return"), screen, Screen.h - 40, Color.GRAY); - - String title = Localization.getLocalized("Fabric Mod Menu"); - int color = Color.WHITE; - - int y = Screen.h - Font.textHeight(); + for(i = 0; i < getModNames().size(); ++i) { + String msg = getModNames().get(i); + int col = Color.get(0, 222, 222, 222); + //if (i == this.selected) { + if (i == selected) { + msg = "> " + msg + " <"; + col = Color.get(0, 555, 555, 555); + } - Font.drawCentered(title, screen, 0, color); + Font.draw(msg, screen, (screen.w - msg.length() * 8) / 2, (8 + i) * 8, col); + } } -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/java/io/github/minifabric/minifabric_api/impl/SingleModDisplay.java b/src/main/java/io/github/minifabric/minifabric_api/impl/SingleModDisplay.java index 7bc7a93..bc74a01 100644 --- a/src/main/java/io/github/minifabric/minifabric_api/impl/SingleModDisplay.java +++ b/src/main/java/io/github/minifabric/minifabric_api/impl/SingleModDisplay.java @@ -1,7 +1,8 @@ package io.github.minifabric.minifabric_api.impl; -import com.mojang.ld22.screen.controlmenu.ControlMenu; -import com.mojang.ld22.screen.controlmenu.TextControlMenu; +import com.mojang.ld22.gfx.Font; +import com.mojang.ld22.gfx.Screen; +import com.mojang.ld22.screen.Menu; import com.mojang.ld22.gfx.Color; import java.util.ArrayList; @@ -9,20 +10,42 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -public class SingleModDisplay extends TextControlMenu { - public SingleModDisplay(ControlMenu parent, String mod_name, String content, String version) { - super(parent); +public class SingleModDisplay extends Menu { + private Menu parent; + private String title; + private String version; + ArrayList desc = new ArrayList<>(); + + + @Override + public void tick() { + if (this.input.attack.clicked || this.input.menu.clicked) { + this.game.setMenu(this.parent); + } + + } + public SingleModDisplay(Menu parent, String mod_name, String content, String version) { + this.parent = parent; this.title = mod_name; - List matchList = new ArrayList(); - Pattern regex = Pattern.compile("(.{1,24}(?:\\s|$))|(.{0,10})", Pattern.DOTALL); + this.version = version; + + Pattern regex = Pattern.compile("(.{1,20}(?:\\s|$))|(.{0,10})", Pattern.DOTALL); Matcher regexMatcher = regex.matcher(content); while (regexMatcher.find()) { - matchList.add(regexMatcher.group()); + desc.add(regexMatcher.group()); + } + } + + @Override + public void render(Screen screen) { + int screenPos = 24; + screen.clear(0); + Font.draw(title, screen, 4, 8, Color.get(0, 333, 333, 333)); + for (String s : desc) { + Font.draw(s, screen, 0, screenPos, Color.get(0, 333, 333, 333)); + screenPos += 8; } - matchList.forEach(phrase -> { - this.addTextLine((String) phrase, Color.get(0, 333, 333, 333)); - }); - this.addTextLine(version, Color.get(0, 50, 50, 50)); + Font.draw(version, screen, 4, screenPos, Color.get(0, 50, 50, 50)); } } diff --git a/src/main/java/io/github/minifabric/minifabric_api/mixin/SelectControlMenuMixin.java b/src/main/java/io/github/minifabric/minifabric_api/mixin/SelectControlMenuMixin.java deleted file mode 100644 index bbf165b..0000000 --- a/src/main/java/io/github/minifabric/minifabric_api/mixin/SelectControlMenuMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package io.github.minifabric.minifabric_api.mixin; - -import com.mojang.ld22.screen.controlmenu.ControlMenu; -import com.mojang.ld22.screen.controlmenu.SelectControlMenu; -import com.mojang.ld22.screen.controlmenu.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(SelectControlMenu.class) -public class SelectControlMenuMixin extends ControlMenu { - @Shadow protected int selected; - public SelectControlMenuMixin(ControlMenu parent) { - super(parent); - } - @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lcom/mojang/ld22/screen/controlmenu/SelectControlMenu;optionSelected(I)V")) - public void removeClose(SelectControlMenu instance, int i) { - if (this.input.attack.clicked || this.input.menu.clicked) { - ((SelectControlMenu)(Object)this).optionSelected(selected); - } else if (this.input.close.clicked && !((SelectControlMenu)(Object) this instanceof TitleMenu)) { - this.gameControl.setMenu(this.parent); - } - } -} diff --git a/src/main/java/io/github/minifabric/minifabric_api/mixin/TitleDisplayMixin.java b/src/main/java/io/github/minifabric/minifabric_api/mixin/TitleDisplayMixin.java index 3fca0dd..170371d 100644 --- a/src/main/java/io/github/minifabric/minifabric_api/mixin/TitleDisplayMixin.java +++ b/src/main/java/io/github/minifabric/minifabric_api/mixin/TitleDisplayMixin.java @@ -1,73 +1,101 @@ package io.github.minifabric.minifabric_api.mixin; -import com.mojang.ld22.GameState; -import com.mojang.ld22.screen.controlmenu.*; +import com.mojang.ld22.gfx.Color; +import com.mojang.ld22.gfx.Font; +import com.mojang.ld22.gfx.Screen; +import com.mojang.ld22.screen.AboutMenu; +import com.mojang.ld22.screen.InstructionsMenu; +import com.mojang.ld22.screen.Menu; +import com.mojang.ld22.screen.TitleMenu; import com.mojang.ld22.sound.Sound; import io.github.minifabric.minifabric_api.impl.ModsDisplay; import org.apache.commons.lang3.ArrayUtils; import org.spongepowered.asm.mixin.*; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArg; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(TitleMenu.class) -public class TitleDisplayMixin extends SelectControlMenu { - @Final @Mutable @Shadow private static String[] defaultOptions; - - public TitleDisplayMixin(ControlMenu parent) { - super(parent); - } +public class TitleDisplayMixin extends Menu { + @Shadow @Final @Mutable private static String[] options; + @Shadow private int selected; /** * @author PseudoDistant * @reason Fuck it, not like anyone else would edit this. */ @Overwrite - public void optionSelected(int selected) { - if (selected == 8) { - this.gameControl.gameState.respawn(); - this.gameControl.setMenu((ControlMenu)null); + public void tick() { + if (this.input.up.clicked) { + --this.selected; } - if (selected == 7) { - this.gameControl.setMenu((ControlMenu)null); + if (this.input.down.clicked) { + ++this.selected; } - if (selected == 6) { - Sound.test.play(); - this.gameControl.gameState = new GameState(this.gameControl); - this.gameControl.gameState.resetGame(); - this.gameControl.setMenu((ControlMenu)null); + int len = options.length; + if (this.selected < 0) { + this.selected += len; } - if (selected == 5) { - this.gameControl.setMenu(new SaveMenu(this)); + if (this.selected >= len) { + this.selected -= len; } - if (selected == 4) { - this.gameControl.setMenu(new LoadMenu(this)); - } + if (this.input.attack.clicked || this.input.menu.clicked) { + if (this.selected == 0) { + Sound.test.play(); + this.game.resetGame(); + this.game.setMenu((Menu) null); + } - if (selected == 3) { - this.gameControl.setMenu(new HighScoreMenu(this)); - } + if (this.selected == 1) { + this.game.setMenu(new InstructionsMenu(this)); + } + + if (this.selected == 2) { + this.game.setMenu(new AboutMenu(this)); + } - if (selected == 2) { - this.gameControl.setMenu(new InstructionsMenu(this)); + if (this.selected == 3) { + this.game.setMenu(new ModsDisplay(this)); + } } + } - if (selected == 1) { - this.gameControl.setMenu(new AboutMenu(this)); + /** + * @author PseudoDistant + * @reason See tick + */ + @Overwrite + public void render(Screen screen) { + screen.clear(0); + int h = 2; + int w = 13; + int titleColor = Color.get(0, 8, 131, 551); + int xo = (screen.w - w * 8) / 2; + int yo = 24; + + int i; + for(i = 0; i < h; ++i) { + for(int x = 0; x < w; ++x) { + screen.render(xo + x * 8, yo + i * 8, x + (i + 6) * 32, titleColor, 0); + } } - if (selected == 0) { - this.gameControl.setMenu(new ModsDisplay(this)); + for(i = 0; i < 4; ++i) { + String msg = options[i]; + int col = Color.get(0, 222, 222, 222); + if (i == this.selected) { + msg = "> " + msg + " <"; + col = Color.get(0, 555, 555, 555); + } + + Font.draw(msg, screen, (screen.w - msg.length() * 8) / 2, (8 + i) * 8, col); } + Font.draw("(Arrow keys,X and C)", screen, 0, screen.h - 8, Color.get(0, 111, 111, 111)); } static { - defaultOptions = ArrayUtils.add(defaultOptions,0, "Mods"); + options = ArrayUtils.add(options, "Mods"); } } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 90f25b2..e8ac6f8 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -21,8 +21,8 @@ "modmenu.mixins.json" ], "depends": { - "minicraft-delux": [ - "1.20" + "minicraft": [ + "0.0.0" ] } } diff --git a/src/main/resources/modmenu.mixins.json b/src/main/resources/modmenu.mixins.json index 9aaef5d..ff6022d 100644 --- a/src/main/resources/modmenu.mixins.json +++ b/src/main/resources/modmenu.mixins.json @@ -4,11 +4,9 @@ "package": "io.github.minifabric.minifabric_api.mixin", "compatibilityLevel": "JAVA_16", "mixins": [ - "TitleDisplayMixin", - "SelectControlMenuMixin" + "TitleDisplayMixin" ], "client": [ - ], "injectors": { "defaultRequire": 1