diff --git a/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/FabricItem.java b/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/FabricItem.java index a029eb09f7..8b5fb55b3d 100644 --- a/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/FabricItem.java +++ b/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/FabricItem.java @@ -18,12 +18,15 @@ import net.minecraft.component.type.AttributeModifiersComponent; import net.minecraft.enchantment.Enchantment; +import net.minecraft.entity.ItemEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.Hand; +import net.minecraft.world.World; import net.fabricmc.fabric.impl.item.FabricItemInternals; +import net.fabricmc.fabric.mixin.item.ItemEntityAccessor; /** * General-purpose Fabric-provided extensions for {@link Item} subclasses. @@ -119,15 +122,29 @@ default ItemStack getRecipeRemainder(ItemStack stack) { *
Note that this method is only called after the {@link EnchantmentEvents#ALLOW_ENCHANTING} event, and * only if none of the listeners to that event override the result.
* - * @param stack the current stack + * @param stack the current stack * @param enchantment the enchantment to check - * @param context the context in which the enchantment is being checked + * @param context the context in which the enchantment is being checked * @return whether the enchantment is allowed to apply to the stack */ default boolean canBeEnchantedWith(ItemStack stack, Enchantment enchantment, EnchantingContext context) { return enchantment.isAcceptableItem(stack); } + /** + * Retrieves the {@link ItemEntityAccessor#getDespawnAge() default spawn age} of 6000 ticks or 5 minutes of this item when it is dropped on the ground + * as an {@link ItemEntity}. + *+ * This is in ticks. + * + * @param stack the current {@link ItemStack} + * @param world the world the entity is in + * @return the normal lifespan in ticks + */ + default int getEntityLifespan(ItemStack stack, ItemEntity entity, World world) { + return ItemEntityAccessor.getDespawnAge(); + } + /** * Fabric-provided extensions for {@link Item.Settings}. * This interface is automatically implemented on all item settings via Mixin and interface injection. diff --git a/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/FabricItemStack.java b/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/FabricItemStack.java index 50c3959a25..ddbf6f94a2 100644 --- a/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/FabricItemStack.java +++ b/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/api/item/v1/FabricItemStack.java @@ -17,8 +17,10 @@ package net.fabricmc.fabric.api.item.v1; import net.minecraft.enchantment.Enchantment; +import net.minecraft.entity.ItemEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.world.World; import net.fabricmc.fabric.api.util.TriState; @@ -47,7 +49,7 @@ default ItemStack getRecipeRemainder() { * {@link Enchantment#isAcceptableItem(ItemStack)}
* * @param enchantment the enchantment to check - * @param context the context in which the enchantment is being checked + * @param context the context in which the enchantment is being checked * @return whether the enchantment is allowed to apply to the stack * @see FabricItem#canBeEnchantedWith(ItemStack, Enchantment, EnchantingContext) */ @@ -59,4 +61,15 @@ default boolean canBeEnchantedWith(Enchantment enchantment, EnchantingContext co ); return result.orElseGet(() -> ((ItemStack) this).getItem().canBeEnchantedWith((ItemStack) this, enchantment, context)); } + + /** + * Retrieves the normal 'lifespan' of this item when it is dropped on the ground + * as an {@link net.minecraft.entity.ItemEntity}. This is in ticks. The standard result is 6000 ticks, or 5 minutes. + * + * @param world the world the entity is in + * @return the normal lifespan in ticks + */ + default int getEntityLifespan(ItemEntity entity, World world) { + return ((ItemStack) this).getItem().getEntityLifespan(((ItemStack) this), entity, world); + } } diff --git a/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/mixin/item/ItemEntityAccessor.java b/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/mixin/item/ItemEntityAccessor.java new file mode 100644 index 0000000000..bcd63cf9b7 --- /dev/null +++ b/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/mixin/item/ItemEntityAccessor.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.item; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import net.minecraft.entity.ItemEntity; + +@Mixin(ItemEntity.class) +public interface ItemEntityAccessor { + @Accessor("DESPAWN_AGE") + static int getDespawnAge() { + throw new AssertionError(); + } +} diff --git a/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/mixin/item/ItemEntityMixin.java b/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/mixin/item/ItemEntityMixin.java new file mode 100644 index 0000000000..c5f50cff6e --- /dev/null +++ b/fabric-item-api-v1/src/main/java/net/fabricmc/fabric/mixin/item/ItemEntityMixin.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.item; + +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.CallbackInfo; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.ItemEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +@Mixin(ItemEntity.class) +public abstract class ItemEntityMixin extends Entity { + + @Shadow + private int itemAge; + + private ItemEntityMixin(EntityType> type, World world) { + super(type, world); + } + + @Inject(at = @At("TAIL"), method = "setDespawnImmediately") + private void modifyDespawnImmediately(CallbackInfo ci) { + this.itemAge = getStack().getEntityLifespan((ItemEntity) ((Entity) this), this.getWorld()); + } + + @Shadow + abstract ItemStack getStack(); +} diff --git a/fabric-item-api-v1/src/main/resources/fabric-item-api-v1.mixins.json b/fabric-item-api-v1/src/main/resources/fabric-item-api-v1.mixins.json index 845c30509d..18169f6ffb 100644 --- a/fabric-item-api-v1/src/main/resources/fabric-item-api-v1.mixins.json +++ b/fabric-item-api-v1/src/main/resources/fabric-item-api-v1.mixins.json @@ -9,6 +9,8 @@ "EnchantCommandMixin", "EnchantmentHelperMixin", "EnchantRandomlyLootFunctionMixin", + "ItemEntityAccessor", + "ItemEntityMixin", "ItemAccessor", "ItemMixin", "ItemSettingsMixin", diff --git a/gradle.properties b/gradle.properties index 7263a3ab20..c2393194dc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -60,4 +60,4 @@ fabric-transfer-api-v1-version=5.1.6 fabric-transitive-access-wideners-v1-version=6.0.10 fabric-convention-tags-v1-version=2.0.4 fabric-convention-tags-v2-version=2.1.0 -fabric-client-tags-api-v1-version=1.1.12 +fabric-client-tags-api-v1-version=1.1.12 \ No newline at end of file