|
| 1 | +package com.mmodding.mmodding_lib.library.items; |
| 2 | + |
| 3 | +import net.minecraft.entity.player.PlayerEntity; |
| 4 | +import net.minecraft.fluid.FluidState; |
| 5 | +import net.minecraft.item.Item; |
| 6 | +import net.minecraft.item.ItemStack; |
| 7 | +import net.minecraft.item.ItemUsage; |
| 8 | +import net.minecraft.sound.SoundCategory; |
| 9 | +import net.minecraft.sound.SoundEvents; |
| 10 | +import net.minecraft.stat.Stats; |
| 11 | +import net.minecraft.util.Hand; |
| 12 | +import net.minecraft.util.TypedActionResult; |
| 13 | +import net.minecraft.util.hit.BlockHitResult; |
| 14 | +import net.minecraft.util.hit.HitResult; |
| 15 | +import net.minecraft.util.math.BlockPos; |
| 16 | +import net.minecraft.world.RaycastContext; |
| 17 | +import net.minecraft.world.World; |
| 18 | +import net.minecraft.world.event.GameEvent; |
| 19 | + |
| 20 | +import java.util.concurrent.atomic.AtomicBoolean; |
| 21 | + |
| 22 | +public class CustomFluidInteractableItem extends Item implements ItemRegistrable { |
| 23 | + |
| 24 | + private final AtomicBoolean registered = new AtomicBoolean(false); |
| 25 | + |
| 26 | + private final FluidPickup fluidPickup; |
| 27 | + |
| 28 | + public CustomFluidInteractableItem(FluidPickup fluidPickup, Settings settings) { |
| 29 | + super(settings); |
| 30 | + this.fluidPickup = fluidPickup; |
| 31 | + } |
| 32 | + |
| 33 | + @Override |
| 34 | + public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) { |
| 35 | + BlockHitResult hitResult = CustomFluidInteractableItem.raycast(world, user, RaycastContext.FluidHandling.SOURCE_ONLY); |
| 36 | + if (hitResult.getType() == HitResult.Type.BLOCK) { |
| 37 | + BlockPos pos = hitResult.getBlockPos(); |
| 38 | + if (!world.canPlayerModifyAt(user, pos)) { |
| 39 | + ItemStack stack = this.fluidPickup.getFilledStack(user.getStackInHand(hand), world.getFluidState(pos), world, pos); |
| 40 | + if (!stack.isEmpty()) { |
| 41 | + world.playSound(user, user.getX(), user.getY(), user.getZ(), SoundEvents.ITEM_BOTTLE_FILL, SoundCategory.NEUTRAL, 1.0f, 1.0f); |
| 42 | + world.emitGameEvent(user, GameEvent.FLUID_PICKUP, pos); |
| 43 | + user.incrementStat(Stats.USED.getOrCreateStat(this)); |
| 44 | + ItemUsage.exchangeStack(user.getStackInHand(hand), user, stack); |
| 45 | + return TypedActionResult.success(stack, world.isClient()); |
| 46 | + } |
| 47 | + } |
| 48 | + } |
| 49 | + return TypedActionResult.pass(user.getStackInHand(hand)); |
| 50 | + } |
| 51 | + |
| 52 | + @Override |
| 53 | + public boolean isNotRegistered() { |
| 54 | + return !this.registered.get(); |
| 55 | + } |
| 56 | + |
| 57 | + @Override |
| 58 | + public void setRegistered() { |
| 59 | + this.registered.set(true); |
| 60 | + } |
| 61 | + |
| 62 | + public interface FluidPickup { |
| 63 | + |
| 64 | + /** |
| 65 | + * Gets the filled stack after the action of the player. |
| 66 | + * @param stack the current stack |
| 67 | + * @param state the fluid state |
| 68 | + * @param world the world |
| 69 | + * @param pos the fluid pos |
| 70 | + * @return the filled stack |
| 71 | + * @apiNote To prevent the action from happening, simply return {@link ItemStack#EMPTY}. |
| 72 | + */ |
| 73 | + ItemStack getFilledStack(ItemStack stack, FluidState state, World world, BlockPos pos); |
| 74 | + } |
| 75 | +} |
0 commit comments