From 86dd3c2b220440adbd6e2a333b14f942f33ce6af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A4seToatz?= Date: Sun, 28 Dec 2025 19:37:26 +0100 Subject: [PATCH] Add max anvil cost config and EnchantCommand mixin Introduces a configurable max anvil cost via the config and enforces it in AnvilScreenHandlerMixin. Adds EnchantCommandMixin to support custom enchantment levels in the /enchant command. Updates mod version to 1.10 and registers the new mixin in the mixins config. --- gradle.properties | 2 +- .../superenchants/config/Config.java | 6 +++ .../mixin/AnvilScreenHandlerMixin.java | 45 ++++++++++++++++++- .../mixin/EnchantCommandMixin.java | 20 +++++++++ src/main/resources/superenchants.mixins.json | 1 + 5 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/kasetoatz/superenchants/mixin/EnchantCommandMixin.java diff --git a/gradle.properties b/gradle.properties index 5a579c9..c7ed36c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ yarn_mappings=1.21.11+build.2 loader_version=0.18.2 loom_version=1.14-SNAPSHOT # Mod Properties -mod_version=1.9 +mod_version=1.10 maven_group=com.kasetoatz archives_base_name=SuperEnchants # Dependencies diff --git a/src/main/java/com/kasetoatz/superenchants/config/Config.java b/src/main/java/com/kasetoatz/superenchants/config/Config.java index 9b91c5c..2a051ad 100644 --- a/src/main/java/com/kasetoatz/superenchants/config/Config.java +++ b/src/main/java/com/kasetoatz/superenchants/config/Config.java @@ -32,6 +32,7 @@ public class Config public static boolean NO_PRIOR_WORK_PENALTY = true; public static boolean ENABLE_CUSTOM_ENCHANT_LEVELS = true; public static boolean CUSTOM_LEVELS_IN_LOOT_TABLE = false; + public static int MAX_ANVIL_COST = -1; public static Map LEVELS = new HashMap<>(Map.ofEntries( Map.entry(Identifier.of("minecraft:unbreaking"), 5), @@ -148,6 +149,10 @@ public class Config { CUSTOM_LEVELS_IN_LOOT_TABLE = data.get("custom-levels-in-loot-table").getAsBoolean(); } + if (data.has("max-anvil-cost")) + { + MAX_ANVIL_COST = data.get("max-anvil-cost").getAsInt(); + } if (data.has("custom-levels")) { JsonObject levels = data.get("custom-levels").getAsJsonObject(); @@ -182,6 +187,7 @@ public class Config data.addProperty("no-prior-work-penalty", NO_PRIOR_WORK_PENALTY); data.addProperty("enable-custom-enchant-levels", ENABLE_CUSTOM_ENCHANT_LEVELS); data.addProperty("custom-levels-in-loot-table", CUSTOM_LEVELS_IN_LOOT_TABLE); + data.addProperty("max-anvil-cost", MAX_ANVIL_COST); JsonObject levels = new JsonObject(); LEVELS.forEach((id, level) -> levels.addProperty(id.toString(), level)); data.add("custom-levels", levels); diff --git a/src/main/java/com/kasetoatz/superenchants/mixin/AnvilScreenHandlerMixin.java b/src/main/java/com/kasetoatz/superenchants/mixin/AnvilScreenHandlerMixin.java index d16fa2a..4daa6ea 100644 --- a/src/main/java/com/kasetoatz/superenchants/mixin/AnvilScreenHandlerMixin.java +++ b/src/main/java/com/kasetoatz/superenchants/mixin/AnvilScreenHandlerMixin.java @@ -1,16 +1,59 @@ package com.kasetoatz.superenchants.mixin; import net.minecraft.enchantment.Enchantment; -import net.minecraft.screen.AnvilScreenHandler; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.screen.*; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.lang.reflect.Field; +import java.util.List; + +import static com.kasetoatz.superenchants.config.Config.MAX_ANVIL_COST; import static com.kasetoatz.superenchants.util.Util.getCustomLevel; @Mixin(AnvilScreenHandler.class) public class AnvilScreenHandlerMixin { + @Unique private Field properties; + @Unique private Field syncHandler; + + @Inject(method="(ILnet/minecraft/entity/player/PlayerInventory;Lnet/minecraft/screen/ScreenHandlerContext;)V", at=@At("TAIL")) + public void init(int syncId, PlayerInventory inventory, ScreenHandlerContext context, CallbackInfo ci) + { + try + { + properties = ScreenHandler.class.getDeclaredField("properties"); + properties.setAccessible(true); + syncHandler = ScreenHandler.class.getDeclaredField("syncHandler"); + syncHandler.setAccessible(true); + } + catch (NoSuchFieldException ignored) {} + } + + @Redirect(method="updateResult", at=@At(value="INVOKE", target="Lnet/minecraft/screen/Property;get()I")) + public int getLevel(Property levelCost) + { + if (MAX_ANVIL_COST > -1 && levelCost.get() > MAX_ANVIL_COST) + { + levelCost.set(MAX_ANVIL_COST); + try + { + @SuppressWarnings("unchecked") + int index = ((List)properties.get(this)).indexOf(levelCost); + @SuppressWarnings("DataFlowIssue") + AnvilScreenHandler handler = (AnvilScreenHandler)(Object)this; + ((ScreenHandlerSyncHandler)syncHandler.get(this)).updateProperty(handler, index, levelCost.get()); + } + catch (IllegalAccessException ignored) {} + } + return levelCost.get(); + } + @Redirect(method="updateResult", at=@At(value="INVOKE", target="Lnet/minecraft/enchantment/Enchantment;getMaxLevel()I")) public int getMaxLevel(Enchantment enchant) { diff --git a/src/main/java/com/kasetoatz/superenchants/mixin/EnchantCommandMixin.java b/src/main/java/com/kasetoatz/superenchants/mixin/EnchantCommandMixin.java new file mode 100644 index 0000000..6135775 --- /dev/null +++ b/src/main/java/com/kasetoatz/superenchants/mixin/EnchantCommandMixin.java @@ -0,0 +1,20 @@ +package com.kasetoatz.superenchants.mixin; + +import net.minecraft.enchantment.Enchantment; +import net.minecraft.server.command.EnchantCommand; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import static com.kasetoatz.superenchants.util.Util.getCustomLevel; + +@Mixin(EnchantCommand.class) +public class EnchantCommandMixin +{ + @Redirect(method="execute", at= @At(value = "INVOKE", target = "Lnet/minecraft/enchantment/Enchantment;getMaxLevel()I")) + private static int execute(Enchantment enchant) + { + int custom = getCustomLevel(enchant); + return (custom > 0) ? custom : enchant.getMaxLevel(); + } +} diff --git a/src/main/resources/superenchants.mixins.json b/src/main/resources/superenchants.mixins.json index 78cf8a3..4d1051e 100644 --- a/src/main/resources/superenchants.mixins.json +++ b/src/main/resources/superenchants.mixins.json @@ -9,6 +9,7 @@ "ChangeItemDamageEnchantmentEffectMixin", "ComponentHolderMixin", "CrossbowItemMixin", + "EnchantCommandMixin", "EnchantmentMixin", "MerchantEntityMixin", "PersistentProjectileMixin",