From ed973b9ead06ab0b714aa9957aa926f26e9bf2e3 Mon Sep 17 00:00:00 2001 From: trinsdar <30245301+Trinsdar@users.noreply.github.com> Date: Sun, 18 Dec 2022 17:59:07 -0500 Subject: [PATCH] added durability api --- felt-durability-item-api/build.gradle | 8 ++++ .../api/durabilityitem/IsDamageableItem.java | 30 ++++++++++++ .../api/durabilityitem/RepairableItem.java | 15 ++++++ .../mixin/durabilityitem/ItemMixin.java | 24 ++++++++++ .../mixin/durabilityitem/ItemStackMixin.java | 47 +++++++++++++++++++ .../durabilityitem/PacketByteBufMixin.java | 19 ++++++++ .../durabilityitem/RepairItemRecipeMixin.java | 26 ++++++++++ .../mixin/durabilityitem/TradeOfferMixin.java | 21 +++++++++ .../resources/durability-item.mixins.json | 16 +++++++ .../src/main/resources/fabric.mod.json | 31 ++++++++++++ 10 files changed, 237 insertions(+) create mode 100644 felt-durability-item-api/build.gradle create mode 100644 felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/api/durabilityitem/IsDamageableItem.java create mode 100644 felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/api/durabilityitem/RepairableItem.java create mode 100644 felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/ItemMixin.java create mode 100644 felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/ItemStackMixin.java create mode 100644 felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/PacketByteBufMixin.java create mode 100644 felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/RepairItemRecipeMixin.java create mode 100644 felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/TradeOfferMixin.java create mode 100644 felt-durability-item-api/src/main/resources/durability-item.mixins.json create mode 100644 felt-durability-item-api/src/main/resources/fabric.mod.json diff --git a/felt-durability-item-api/build.gradle b/felt-durability-item-api/build.gradle new file mode 100644 index 0000000..7566231 --- /dev/null +++ b/felt-durability-item-api/build.gradle @@ -0,0 +1,8 @@ +dependencies { + implementation("com.github.LlamaLad7:MixinExtras:0.1.1") + annotationProcessor("com.github.LlamaLad7:MixinExtras:0.1.1") + afterEvaluate { + implementation project(path: ":felt-mixin-extras-init", configuration: "namedElements") + include project(":felt-mixin-extras-init") + } +} \ No newline at end of file diff --git a/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/api/durabilityitem/IsDamageableItem.java b/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/api/durabilityitem/IsDamageableItem.java new file mode 100644 index 0000000..e3eb6bd --- /dev/null +++ b/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/api/durabilityitem/IsDamageableItem.java @@ -0,0 +1,30 @@ +package io.github.feltmc.feltapi.api.durabilityitem; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +public interface IsDamageableItem { + + /** + * Used to test if this item can be damaged, but with the ItemStack in question. + * Please note that in some cases no ItemStack is available, so the stack-less method will be used. + * + * @param stack ItemStack in the Chest slot of the entity. + */ + default boolean isDamageable(ItemStack stack) + { + return ((Item)this).isDamageable(); + } + + /** + * Return if this itemstack is damaged. Note only called if + * {@link ItemStack#isDamageable()} is true. + * + * @param stack the stack + * @return if the stack is damaged + */ + default boolean isDamaged(ItemStack stack) + { + return stack.getDamage() > 0; + } +} diff --git a/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/api/durabilityitem/RepairableItem.java b/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/api/durabilityitem/RepairableItem.java new file mode 100644 index 0000000..9340bb9 --- /dev/null +++ b/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/api/durabilityitem/RepairableItem.java @@ -0,0 +1,15 @@ +package io.github.feltmc.feltapi.api.durabilityitem; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +public interface RepairableItem { + /** + * Called by CraftingManager to determine if an item is reparable. + * + * @return True if reparable + */ + default boolean isRepairable(ItemStack stack){ + return ((Item)this).isDamageable(); + } +} diff --git a/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/ItemMixin.java b/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/ItemMixin.java new file mode 100644 index 0000000..cc240dc --- /dev/null +++ b/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/ItemMixin.java @@ -0,0 +1,24 @@ +package io.github.feltmc.feltapi.mixin.durabilityitem; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import io.github.feltmc.feltapi.api.durabilityitem.IsDamageableItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Item.class) +public abstract class ItemMixin { + + @WrapOperation(method = "isEnchantable", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isDamageable()Z")) + private boolean injectIsEnchantable(Item instance, Operation cir, ItemStack stack){ + if (this instanceof IsDamageableItem extension){ + return extension.isDamageable(stack); + } + return cir.call(instance); + } +} diff --git a/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/ItemStackMixin.java b/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/ItemStackMixin.java new file mode 100644 index 0000000..c51f05e --- /dev/null +++ b/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/ItemStackMixin.java @@ -0,0 +1,47 @@ +package io.github.feltmc.feltapi.mixin.durabilityitem; + +import io.github.feltmc.feltapi.api.durabilityitem.IsDamageableItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import org.jetbrains.annotations.Nullable; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ItemStack.class) +public abstract class ItemStackMixin { + @Shadow + public abstract Item getItem(); + + @Shadow public abstract boolean isDamageable(); + + @Shadow private boolean empty; + + @Shadow @Nullable + public abstract NbtCompound getNbt(); + + @Inject(method = "isDamaged", at = @At("HEAD"), cancellable = true) + private void injectIsDamaged(CallbackInfoReturnable cir){ + ItemStack stack = (ItemStack) (Object) this; + if (this.getItem() instanceof IsDamageableItem extension){ + cir.setReturnValue(this.isDamageable() && extension.isDamaged(stack)); + } + } + + //TODO figure out how to change this to just replace this: this.getItem().getMaxDamage() > 0 with this: extension.isDamageable(stack) + @Inject(method = "isDamageable", at = @At("HEAD"), cancellable = true) + private void injectIsDamageable(CallbackInfoReturnable cir){ + ItemStack stack = (ItemStack) (Object) this; + if (this.getItem() instanceof IsDamageableItem extension){ + if (!this.empty && extension.isDamageable(stack)){ + NbtCompound compoundtag = this.getNbt(); + cir.setReturnValue(compoundtag == null || !compoundtag.getBoolean("Unbreakable")); + } else { + cir.setReturnValue(false); + } + } + } +} diff --git a/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/PacketByteBufMixin.java b/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/PacketByteBufMixin.java new file mode 100644 index 0000000..98b894d --- /dev/null +++ b/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/PacketByteBufMixin.java @@ -0,0 +1,19 @@ +package io.github.feltmc.feltapi.mixin.durabilityitem; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import io.github.feltmc.feltapi.api.durabilityitem.IsDamageableItem; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketByteBuf; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(PacketByteBuf.class) +public class PacketByteBufMixin { + @ModifyExpressionValue(method = "writeItemStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isDamageable()Z")) + private boolean redirectIsDamageable(boolean old, ItemStack stack){ + if (stack.getItem() instanceof IsDamageableItem extension){ + return extension.isDamageable(stack); + } + return old; + } +} diff --git a/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/RepairItemRecipeMixin.java b/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/RepairItemRecipeMixin.java new file mode 100644 index 0000000..09524f6 --- /dev/null +++ b/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/RepairItemRecipeMixin.java @@ -0,0 +1,26 @@ +package io.github.feltmc.feltapi.mixin.durabilityitem; + +import io.github.feltmc.feltapi.api.durabilityitem.RepairableItem; +import net.minecraft.inventory.CraftingInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.RepairItemRecipe; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import java.util.List; + +@Mixin(RepairItemRecipe.class) +public class RepairItemRecipeMixin { + @Inject(method = "matches(Lnet/minecraft/inventory/CraftingInventory;Lnet/minecraft/world/World;)Z", at = @At(value = "INVOKE", target = "Ljava/util/List;get(I)Ljava/lang/Object;", shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true) + private void injectIsRepairable(CraftingInventory craftingInventory, World world, CallbackInfoReturnable cir, List list, int i, ItemStack itemStack){ + if (itemStack.getItem() instanceof RepairableItem containerItem){ + if (!containerItem.isRepairable(itemStack)){ + cir.setReturnValue(false); + } + } + } +} diff --git a/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/TradeOfferMixin.java b/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/TradeOfferMixin.java new file mode 100644 index 0000000..f8c89b4 --- /dev/null +++ b/felt-durability-item-api/src/main/java/io/github/feltmc/feltapi/mixin/durabilityitem/TradeOfferMixin.java @@ -0,0 +1,21 @@ +package io.github.feltmc.feltapi.mixin.durabilityitem; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import io.github.feltmc.feltapi.api.durabilityitem.IsDamageableItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.village.TradeOffer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(TradeOffer.class) +public class TradeOfferMixin { + @WrapOperation(method = "acceptsBuy", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isDamageable()Z")) + private boolean wrapAcceptsBuy(Item instance, Operation operation, ItemStack given, ItemStack sample){ + if (instance instanceof IsDamageableItem damageableItem){ + return damageableItem.isDamageable(given.copy()); + } + return operation.call(instance); + } +} diff --git a/felt-durability-item-api/src/main/resources/durability-item.mixins.json b/felt-durability-item-api/src/main/resources/durability-item.mixins.json new file mode 100644 index 0000000..c71b0bd --- /dev/null +++ b/felt-durability-item-api/src/main/resources/durability-item.mixins.json @@ -0,0 +1,16 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "io.github.feltmc.feltapi.mixin.durabilityitem", + "compatibilityLevel": "JAVA_17", + "injectors": { + "defaultRequire": 1 + }, + "mixins": [ + "ItemMixin", + "ItemStackMixin", + "PacketByteBufMixin", + "RepairItemRecipeMixin", + "TradeOfferMixin" + ] +} \ No newline at end of file diff --git a/felt-durability-item-api/src/main/resources/fabric.mod.json b/felt-durability-item-api/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..8778a5d --- /dev/null +++ b/felt-durability-item-api/src/main/resources/fabric.mod.json @@ -0,0 +1,31 @@ +{ + "schemaVersion": 1, + "id": "felt-durability-item-api", + "version": "${version}", + "name": "Felt Durability Item API", + "description": "A reimplementation of Fringe APIs on Fabric", + "authors": [ + "FeltMC", + "PseudoDistant", + "Trinsdar", + "Unix-Supremacist" + ], + "contact": { + "homepage": "", + "sources": "https://github.com/FeltMC/Felt-API" + }, + "license": "LGPL", + "icon": "assets/felt-api/icon.png", + + "environment": "*", + "mixins": [ + "durability-item.mixins.json" + ], + "depends": { + "fabricloader": "*", + "minecraft": "*" + }, + "recommends": { + "feltfabric": "*" + } +} \ No newline at end of file