diff --git a/src/main/java/com/kasetoatz/superenchants/config/Config.java b/src/main/java/com/kasetoatz/superenchants/config/Config.java index fb2e700..b2967d5 100644 --- a/src/main/java/com/kasetoatz/superenchants/config/Config.java +++ b/src/main/java/com/kasetoatz/superenchants/config/Config.java @@ -28,6 +28,7 @@ public class Config public static boolean ENABLE_INFINITY_WITHOUT_ARROW = true; public static boolean ENABLE_CROSSBOW_INFINITY = true; public static boolean TRIDENT_RETURN_TO_SAME_SLOT = true; + public static boolean ONLY_BEST_VILLAGER_TRADES = false; public static boolean ENABLE_CUSTOM_ENCHANT_LEVELS = true; public static Map LEVELS = new HashMap<>(Map.ofEntries( @@ -42,6 +43,7 @@ public class Config Map.entry(Identifier.of("minecraft:fire_protection"), 10), Map.entry(Identifier.of("minecraft:blast_protection"), 10), Map.entry(Identifier.of("minecraft:depth_strider"), 5), + Map.entry(Identifier.of("minecraft:frost_walker"), 3), Map.entry(Identifier.of("minecraft:fire_aspect"), 3), Map.entry(Identifier.of("minecraft:looting"), 5), Map.entry(Identifier.of("minecraft:knockback"), 3), @@ -127,6 +129,10 @@ public class Config { TRIDENT_RETURN_TO_SAME_SLOT = data.get("trident-return-to-same-slot").getAsBoolean(); } + if (data.has("only-best-villager-trades")) + { + ONLY_BEST_VILLAGER_TRADES = data.get("only-best-villager-trades").getAsBoolean(); + } if (data.has("enable-custom-enchant-levels")) { ENABLE_CUSTOM_ENCHANT_LEVELS = data.get("enable-custom-enchant-levels").getAsBoolean(); @@ -161,6 +167,7 @@ public class Config data.addProperty("enable-infinity-without-arrow", ENABLE_INFINITY_WITHOUT_ARROW); data.addProperty("enable-crossbow-infinity", ENABLE_CROSSBOW_INFINITY); data.addProperty("trident-return-to-same-slot", TRIDENT_RETURN_TO_SAME_SLOT); + data.addProperty("only-best-villager-trades", ONLY_BEST_VILLAGER_TRADES); data.addProperty("enable-custom-enchant-levels", ENABLE_CUSTOM_ENCHANT_LEVELS); JsonObject levels = new JsonObject(); LEVELS.forEach((id, level) -> levels.addProperty(id.toString(), level)); diff --git a/src/main/java/com/kasetoatz/superenchants/mixin/MerchantEntityMixin.java b/src/main/java/com/kasetoatz/superenchants/mixin/MerchantEntityMixin.java new file mode 100644 index 0000000..18ad57e --- /dev/null +++ b/src/main/java/com/kasetoatz/superenchants/mixin/MerchantEntityMixin.java @@ -0,0 +1,58 @@ +package com.kasetoatz.superenchants.mixin; + +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.ItemEnchantmentsComponent; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.entity.passive.MerchantEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.village.TradeOffer; +import net.minecraft.village.TradedItem; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +import java.util.Optional; + +import static com.kasetoatz.superenchants.config.Config.ONLY_BEST_VILLAGER_TRADES; +import static com.kasetoatz.superenchants.util.Util.getCustomLevel; + +@Mixin(MerchantEntity.class) +public class MerchantEntityMixin +{ + @ModifyArg(method="fillRecipesFromPool", at= @At(value = "INVOKE", target = "Lnet/minecraft/village/TradeOfferList;add(Ljava/lang/Object;)Z")) + public Object tradeOffers(Object obj) + { + if (ONLY_BEST_VILLAGER_TRADES && obj instanceof TradeOffer offer && offer.getSellItem().getItem() == Items.ENCHANTED_BOOK) + { + ItemStack stack = offer.getSellItem(); + ItemEnchantmentsComponent component = stack.get(DataComponentTypes.STORED_ENCHANTMENTS); + if (component == null) + { + return obj; + } + Optional> entry = component.getEnchantments().stream().findFirst(); + if (entry.isEmpty()) + { + return obj; + } + int level = getCustomLevel(entry.get().value()); + if (level == 0) + { + level = entry.get().value().definition().maxLevel(); + } + int price = 5 + 3 * (Math.clamp((int)Math.round(level / (level / (double)entry.get().value().definition().maxLevel())), 1, 5) - 1); + stack.addEnchantment(entry.get(), level); + return new TradeOffer( + new TradedItem(Items.EMERALD, price), + Optional.of(new TradedItem(Items.BOOK)), + stack, + offer.getMaxUses(), + offer.getMerchantExperience(), + offer.getPriceMultiplier() + ); + } + return obj; + } +} diff --git a/src/main/resources/superenchants.mixins.json b/src/main/resources/superenchants.mixins.json index 4dbbe2b..c19ef06 100644 --- a/src/main/resources/superenchants.mixins.json +++ b/src/main/resources/superenchants.mixins.json @@ -11,6 +11,7 @@ "PersistentProjectileMixin", "TridentEntityMixin", "TridentItemMixin", + "MerchantEntityMixin", "WeatherCheckLootConditionMixin" ], "client": [