From 3f559012b47704a9b56e9f61fa8919d9d1a361df Mon Sep 17 00:00:00 2001 From: jhqwqmc Date: Sat, 25 Oct 2025 22:48:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=81=E8=AE=B8=E4=BC=A0=E9=80=92=20null=20?= =?UTF-8?q?=E7=8E=A9=E5=AE=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/item/ComponentItemWrapper.java | 33 ++++++++++++++++--- .../bukkit/item/LegacyItemWrapper.java | 31 +++++++++++++++-- .../craftengine/core/item/AbstractItem.java | 2 +- .../craftengine/core/item/Item.java | 2 +- .../craftengine/core/item/ItemWrapper.java | 3 +- 5 files changed, 60 insertions(+), 11 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentItemWrapper.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentItemWrapper.java index 1ad99450a..019941f0d 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentItemWrapper.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ComponentItemWrapper.java @@ -14,12 +14,12 @@ import net.momirealms.craftengine.bukkit.util.KeyUtils; import net.momirealms.craftengine.core.entity.EquipmentSlot; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.ItemWrapper; -import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.Key; +import net.momirealms.craftengine.core.util.RandomUtils; import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.sparrow.nbt.Tag; +import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Objects; @@ -142,7 +142,7 @@ public class ComponentItemWrapper implements ItemWrapper { } public void setNBTComponent(Object type, Object value) { - setComponentInternal(type, MRegistryOps.NBT, value); + setComponentInternal(type, MRegistryOps.NBT, value); } public void setSparrowNBTComponent(Object type, Tag value) { @@ -209,7 +209,14 @@ public class ComponentItemWrapper implements ItemWrapper { } @Override - public void hurtAndBreak(int amount, @NotNull Player player, @Nullable EquipmentSlot slot) { + public void hurtAndBreak(int amount, @Nullable Player player, @Nullable EquipmentSlot slot) { + if (player == null) { + if (this.hurt(amount)) { + this.shrink(1); + this.setJavaComponent(DataComponentTypes.DAMAGE, 0); + } + return; + } FastNMS.INSTANCE.method$ItemStack$hurtAndBreak( this.handle, amount, @@ -217,4 +224,22 @@ public class ComponentItemWrapper implements ItemWrapper { slot != null ? EquipmentSlotUtils.toNMSEquipmentSlot(slot) : null ); } + + private boolean hurt(int amount) { + if (!this.hasComponent(DataComponentTypes.MAX_DAMAGE) || this.hasComponent(DataComponentTypes.UNBREAKABLE) || !this.hasComponent(DataComponentTypes.DAMAGE)) return false; + if (amount > 0) { + int level = this.item.getEnchantmentLevel(Enchantment.UNBREAKING); + int ignoredDamage = 0; + for (int i = 0; level > 0 && i < amount; ++i) { + if (RandomUtils.generateRandomInt(0, level + 1) > 0) ++ignoredDamage; + } + amount -= ignoredDamage; + if (amount <= 0) return false; + } + Optional optionalDamage = this.getJavaComponent(DataComponentTypes.DAMAGE); + int damage = optionalDamage.orElse(0) + amount; + this.setJavaComponent(DataComponentTypes.DAMAGE, damage); + Optional optionalMaxDamage = this.getJavaComponent(DataComponentTypes.MAX_DAMAGE); + return damage >= optionalMaxDamage.orElseGet(() -> (int) this.item.getType().getMaxDurability()); + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyItemWrapper.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyItemWrapper.java index d9dcfbe97..dd26bd3b2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyItemWrapper.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyItemWrapper.java @@ -8,9 +8,10 @@ import net.momirealms.craftengine.bukkit.util.ItemStackUtils; import net.momirealms.craftengine.core.entity.EquipmentSlot; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.ItemWrapper; +import net.momirealms.craftengine.core.util.RandomUtils; import net.momirealms.sparrow.nbt.Tag; +import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class LegacyItemWrapper implements ItemWrapper { @@ -27,7 +28,7 @@ public class LegacyItemWrapper implements ItemWrapper { if (value instanceof Tag tag) { finalNMSTag = MRegistryOps.SPARROW_NBT.convertTo(MRegistryOps.NBT, tag); } else if (CoreReflections.clazz$Tag.isInstance(value)) { - finalNMSTag = value; + finalNMSTag = value; } else { finalNMSTag = MRegistryOps.JAVA.convertTo(MRegistryOps.NBT, value); } @@ -157,7 +158,14 @@ public class LegacyItemWrapper implements ItemWrapper { } @Override - public void hurtAndBreak(int amount, @NotNull Player player, @Nullable EquipmentSlot slot) { + public void hurtAndBreak(int amount, @Nullable Player player, @Nullable EquipmentSlot slot) { + if (player == null) { + if (this.hurt(amount)) { + this.shrink(1); + this.setTag(0, "Damage"); + } + return; + } FastNMS.INSTANCE.method$ItemStack$hurtAndBreak( this.nmsStack, amount, @@ -165,4 +173,21 @@ public class LegacyItemWrapper implements ItemWrapper { slot != null ? EquipmentSlotUtils.toNMSEquipmentSlot(slot) : null ); } + + private boolean hurt(int amount) { + if (ItemStackUtils.isEmpty(itemStack) || itemStack.getType().getMaxDurability() <= 0 || !hasTag("Unbreakable") || (boolean) getJavaTag("Unbreakable")) return false; + if (amount > 0) { + int level = this.itemStack.getEnchantmentLevel(Enchantment.UNBREAKING); + int ignoredDamage = 0; + for (int i = 0; level > 0 && i < amount; ++i) { + if (RandomUtils.generateRandomInt(0, level + 1) > 0) ++ignoredDamage; + } + amount -= ignoredDamage; + if (amount <= 0) return false; + } + int damage = this.hasTag("Damage") ? this.getJavaTag("Damage") : 0; + damage += amount; + this.setTag(damage, "Damage"); + return damage >= this.itemStack.getType().getMaxDurability(); + } } \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java index 0d99ac953..94f5fcee3 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java @@ -504,7 +504,7 @@ public class AbstractItem, I> implements Item { } @Override - public void hurtAndBreak(int amount, @NotNull Player player, @Nullable EquipmentSlot slot) { + public void hurtAndBreak(int amount, @Nullable Player player, @Nullable EquipmentSlot slot) { this.item.hurtAndBreak(amount, player, slot); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/Item.java b/core/src/main/java/net/momirealms/craftengine/core/item/Item.java index d14825f97..d1e32bc46 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/Item.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/Item.java @@ -216,7 +216,7 @@ public interface Item { void shrink(int amount); - void hurtAndBreak(int amount, @NotNull Player player, @Nullable EquipmentSlot slot); + void hurtAndBreak(int amount, @Nullable Player player, @Nullable EquipmentSlot slot); default Item transmuteCopy(Key another) { return transmuteCopy(another, this.count()); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemWrapper.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemWrapper.java index ca1d2da73..6f40da2dd 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemWrapper.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemWrapper.java @@ -2,7 +2,6 @@ package net.momirealms.craftengine.core.item; import net.momirealms.craftengine.core.entity.EquipmentSlot; import net.momirealms.craftengine.core.entity.player.Player; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public interface ItemWrapper { @@ -19,5 +18,5 @@ public interface ItemWrapper { void shrink(int amount); - void hurtAndBreak(int amount, @NotNull Player player, @Nullable EquipmentSlot slot); + void hurtAndBreak(int amount, @Nullable Player player, @Nullable EquipmentSlot slot); }