diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerEntityEvents.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerEntityEvents.java index dfc1cd7696..503dd4cefc 100644 --- a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerEntityEvents.java +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/api/event/lifecycle/v1/ServerEntityEvents.java @@ -18,7 +18,9 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.ItemEntity; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.server.world.ServerWorld; @@ -63,6 +65,28 @@ private ServerEntityEvents() { } }); + /** + * Called during {@link ItemEntity#tick()} on the logical server if an entity tries to pick up any {@link ItemEntity}. + * + *

Picking up of an item is determined by {@link ItemEntity#onPlayerCollision(PlayerEntity)}. + * + *

Returning {@code false} prevents vanilla from handling the pick-up. + */ + public static final Event ITEM_PICKUP = EventFactory.createArrayBacked( + ItemPickup.class, + (callbacks) -> (playerEntity, itemEntity, itemStack) -> { + for (ItemPickup callback : callbacks) { + boolean shouldContinue = callback.onPickup(playerEntity, itemEntity, itemStack); + + if (!shouldContinue) { + return false; + } + } + + return true; + } + ); + @FunctionalInterface public interface Load { void onLoad(Entity entity, ServerWorld world); @@ -77,4 +101,9 @@ public interface Unload { public interface EquipmentChange { void onChange(LivingEntity livingEntity, EquipmentSlot equipmentSlot, ItemStack previousStack, ItemStack currentStack); } + + @FunctionalInterface + public interface ItemPickup { + boolean onPickup(PlayerEntity playerEntity, ItemEntity itemEntity, ItemStack itemStack); + } } diff --git a/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle/ItemEntityMixin.java b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle/ItemEntityMixin.java new file mode 100644 index 0000000000..c3cc3e5748 --- /dev/null +++ b/fabric-lifecycle-events-v1/src/main/java/net/fabricmc/fabric/mixin/event/lifecycle/ItemEntityMixin.java @@ -0,0 +1,40 @@ +/* + * 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.event.lifecycle; + +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.CallbackInfo; + +import net.minecraft.entity.ItemEntity; +import net.minecraft.entity.player.PlayerEntity; + +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents; + +@Mixin(ItemEntity.class) +public class ItemEntityMixin { + @Inject(method = "onPlayerCollision", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerInventory;insertStack(Lnet/minecraft/item/ItemStack;)Z"), cancellable = true) + private void onPlayerPickup(PlayerEntity playerEntity, CallbackInfo ci) { + ItemEntity itemEntity = (ItemEntity) (Object) this; + boolean allowPickup = ServerEntityEvents.ITEM_PICKUP.invoker().onPickup(playerEntity, itemEntity, itemEntity.getStack()); + + if (!allowPickup) { + ci.cancel(); + } + } +} diff --git a/fabric-lifecycle-events-v1/src/main/resources/fabric-lifecycle-events-v1.mixins.json b/fabric-lifecycle-events-v1/src/main/resources/fabric-lifecycle-events-v1.mixins.json index 3beeeae11e..b1532d62f0 100644 --- a/fabric-lifecycle-events-v1/src/main/resources/fabric-lifecycle-events-v1.mixins.json +++ b/fabric-lifecycle-events-v1/src/main/resources/fabric-lifecycle-events-v1.mixins.json @@ -6,6 +6,7 @@ "ChunkGeneratingMixin", "ChunkHolderMixin", "DataPackContentsMixin", + "ItemEntityMixin", "LivingEntityMixin", "MinecraftServerMixin", "PlayerManagerMixin",