From 71e3337a91904bda2c19cfb5dfb38a3c43a354ac Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Mon, 7 Jul 2025 20:27:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E9=93=81=E7=A0=A7=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bukkit/paper-loader/build.gradle.kts | 1 - .../item/recipe/RecipeEventListener.java | 80 ++++++++++++------- .../craftengine/core/item/ItemSettings.java | 15 ++++ 3 files changed, 67 insertions(+), 29 deletions(-) diff --git a/bukkit/paper-loader/build.gradle.kts b/bukkit/paper-loader/build.gradle.kts index ab8645de3..734d68c50 100644 --- a/bukkit/paper-loader/build.gradle.kts +++ b/bukkit/paper-loader/build.gradle.kts @@ -76,7 +76,6 @@ paper { // external models register("ModelEngine") { required = false } register("BetterModel") { required = false } - register("FreeMinecraftModels") { required = false } // external items register("NeigeItems") { required = false } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java index 35a822401..6aee0052b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/recipe/RecipeEventListener.java @@ -453,80 +453,102 @@ public class RecipeEventListener implements Listener { } @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) - public void onAnvilCombineItems(PrepareAnvilEvent event) { + public void onAnvilEvent(PrepareAnvilEvent event) { + preProcess(event); + processRepairable(event); + processRename(event); + } + + /* + 预处理会阻止一些不合理的原版材质造成的合并问题 + */ + private void preProcess(PrepareAnvilEvent event) { AnvilInventory inventory = event.getInventory(); ItemStack first = inventory.getFirstItem(); ItemStack second = inventory.getSecondItem(); if (first == null || second == null) return; Item wrappedFirst = BukkitItemManager.instance().wrap(first); - boolean firstCustom = wrappedFirst.isCustomItem(); + Optional> firstCustom = wrappedFirst.getCustomItem(); Item wrappedSecond = BukkitItemManager.instance().wrap(second); - boolean secondCustom = wrappedSecond.isCustomItem(); - // both are vanilla items - if (!firstCustom && !secondCustom) { + Optional> secondCustom = wrappedFirst.getCustomItem(); + // 两个都是原版物品 + if (firstCustom.isEmpty() && secondCustom.isEmpty()) { return; } - - // both of them are custom items - // if the second is an enchanted book, then apply it + // 如果第二个物品是附魔书,那么忽略 if (wrappedSecond.vanillaId().equals(ItemKeys.ENCHANTED_BOOK)) { return; } - // one of them is vanilla item - if (!firstCustom || !secondCustom) { - if (second.canRepair(first)) return; // 这里需要考虑原版逻辑 - // block "vanilla + custom" recipes - event.setResult(null); - return; + // 被修的是自定义,材料不是自定义 + if (firstCustom.isPresent() && secondCustom.isEmpty()) { + if (firstCustom.get().settings().respectRepairableComponent()) { + if (second.canRepair(first)) return; // 尊重原版的repairable + } else { + event.setResult(null); + return; + } } - // not the same item + // 被修的是原版,材料是自定义 + if (firstCustom.isEmpty() && secondCustom.isPresent()) { + if (secondCustom.get().settings().respectRepairableComponent()) { + if (second.canRepair(first)) return; + } else { + event.setResult(null); + return; + } + } + + // 如果两个物品id不同,不能合并 if (!wrappedFirst.customId().equals(wrappedSecond.customId())) { event.setResult(null); return; } - // can not repair - wrappedFirst.getCustomItem().ifPresent(it -> { + // 如果禁止在铁砧使用两个相同物品修复 + firstCustom.ifPresent(it -> { if (!it.settings().canRepair()) { event.setResult(null); } }); } + /* + 处理item settings中repair item属性。如果修补材料不是自定义物品,则不会参与后续逻辑。 + 这会忽略preprocess里event.setResult(null); + */ @SuppressWarnings("UnstableApiUsage") - @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) - public void onAnvilRepairItems(PrepareAnvilEvent event) { + private void processRepairable(PrepareAnvilEvent event) { AnvilInventory inventory = event.getInventory(); ItemStack first = inventory.getFirstItem(); ItemStack second = inventory.getSecondItem(); if (first == null || second == null) return; Item wrappedSecond = BukkitItemManager.instance().wrap(second); - // if the second slot is not a custom item, ignore it - Optional> customItemOptional = plugin.itemManager().getCustomItem(wrappedSecond.id()); + // 如果材料不是自定义的,那么忽略 + Optional> customItemOptional = this.plugin.itemManager().getCustomItem(wrappedSecond.id()); if (customItemOptional.isEmpty()) { return; } CustomItem customItem = customItemOptional.get(); List repairItems = customItem.settings().repairItems(); - // if the second slot is not a repair item, ignore it + // 如果材料不支持修复物品,则忽略 if (repairItems.isEmpty()) { return; } + // 后续均为修复逻辑 Item wrappedFirst = BukkitItemManager.instance().wrap(first.clone()); - int maxDamage = wrappedFirst.maxDamage(); int damage = wrappedFirst.damage().orElse(0); - // not a repairable item + // 物品无damage属性 if (damage == 0 || maxDamage == 0) return; Key firstId = wrappedFirst.id(); Optional> optionalCustomTool = wrappedFirst.getCustomItem(); - // can not repair + // 物品无法被修复 if (optionalCustomTool.isPresent() && !optionalCustomTool.get().settings().canRepair()) { return; } @@ -551,7 +573,7 @@ public class RecipeEventListener implements Listener { } } - // no repair item matching + // 找不到匹配的修复 if (repairItem == null) { return; } @@ -649,9 +671,11 @@ public class RecipeEventListener implements Listener { } } + /* + 如果物品不可被重命名,则在最后处理。 + */ @SuppressWarnings("UnstableApiUsage") - @EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL) - public void onAnvilRenameItem(PrepareAnvilEvent event) { + private void processRename(PrepareAnvilEvent event) { AnvilInventory inventory = event.getInventory(); ItemStack first = inventory.getFirstItem(); if (ItemUtils.isEmpty(first)) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java index 89ae2db4b..9295d1745 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java @@ -38,6 +38,7 @@ public class ItemSettings { List invulnerable = List.of(); boolean canEnchant = true; float compostProbability= 0.5f; + boolean respectRepairableComponent = false; @Nullable ItemEquipment equipment; @@ -97,6 +98,7 @@ public class ItemSettings { newSettings.invulnerable = settings.invulnerable; newSettings.canEnchant = settings.canEnchant; newSettings.compostProbability = settings.compostProbability; + newSettings.respectRepairableComponent = settings.respectRepairableComponent; return newSettings; } @@ -148,6 +150,10 @@ public class ItemSettings { return anvilRepairItems; } + public boolean respectRepairableComponent() { + return respectRepairableComponent; + } + @Nullable public FoodData foodData() { return foodData; @@ -256,6 +262,11 @@ public class ItemSettings { return this; } + public ItemSettings respectRepairableComponent(boolean respectRepairableComponent) { + this.respectRepairableComponent = respectRepairableComponent; + return this; + } + public ItemSettings invulnerable(List invulnerable) { this.invulnerable = invulnerable; return this; @@ -375,6 +386,10 @@ public class ItemSettings { boolean bool = ResourceConfigUtils.getAsBoolean(value, "dyeable"); return settings -> settings.dyeable(bool); })); + registerFactory("respect-repairable-component", (value -> { + boolean bool = ResourceConfigUtils.getAsBoolean(value, "respect-repairable-component"); + return settings -> settings.respectRepairableComponent(bool); + })); registerFactory("food", (value -> { Map args = MiscUtils.castToMap(value, false); FoodData data = new FoodData(