diff --git a/src/main/java/dev/mangojellypudding/independenttech/IndependentTech.java b/src/main/java/dev/mangojellypudding/independenttech/IndependentTech.java index 56a7a9b..d3a20a6 100644 --- a/src/main/java/dev/mangojellypudding/independenttech/IndependentTech.java +++ b/src/main/java/dev/mangojellypudding/independenttech/IndependentTech.java @@ -1,6 +1,7 @@ package dev.mangojellypudding.independenttech; import com.mojang.logging.LogUtils; +import dev.mangojellypudding.independenttech.cookingforblockheads.block.entity.SinkBlockEntity; import dev.mangojellypudding.independenttech.register.ITBlockEntityTypes; import dev.mangojellypudding.independenttech.register.ITBlocks; import dev.mangojellypudding.independenttech.register.ITCreativeModeTabs; @@ -20,5 +21,7 @@ public IndependentTech(IEventBus modEventBus, ModContainer modContainer) { ITItems.ITEMS.register(modEventBus); ITCreativeModeTabs.CREATIVE_MODE_TABS.register(modEventBus); ITBlockEntityTypes.BLOCK_ENTITY_TYPES.register(modEventBus); + + modEventBus.addListener(SinkBlockEntity::registerCapability); // 注册方块实体能力 } } diff --git a/src/main/java/dev/mangojellypudding/independenttech/cookingforblockheads/block/SinkBlock.java b/src/main/java/dev/mangojellypudding/independenttech/cookingforblockheads/block/SinkBlock.java index 84bfe13..5b5ce3b 100644 --- a/src/main/java/dev/mangojellypudding/independenttech/cookingforblockheads/block/SinkBlock.java +++ b/src/main/java/dev/mangojellypudding/independenttech/cookingforblockheads/block/SinkBlock.java @@ -84,7 +84,7 @@ protected ItemInteractionResult useItemOn(ItemStack itemStack, BlockState state, return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; } - FluidActionResult result = FluidUtil.tryFillContainerAndStow(itemStack, sink.sinkTank, new InvWrapper(player.getInventory()), Integer.MAX_VALUE, player, true); + FluidActionResult result = FluidUtil.tryFillContainerAndStow(itemStack, SinkBlockEntity.fluidHandler, new InvWrapper(player.getInventory()), Integer.MAX_VALUE, player, true); // if (result.success) { // diff --git a/src/main/java/dev/mangojellypudding/independenttech/cookingforblockheads/block/entity/SinkBlockEntity.java b/src/main/java/dev/mangojellypudding/independenttech/cookingforblockheads/block/entity/SinkBlockEntity.java index aa9a82d..e37087b 100644 --- a/src/main/java/dev/mangojellypudding/independenttech/cookingforblockheads/block/entity/SinkBlockEntity.java +++ b/src/main/java/dev/mangojellypudding/independenttech/cookingforblockheads/block/entity/SinkBlockEntity.java @@ -7,34 +7,93 @@ import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.Fluids; +import net.neoforged.neoforge.capabilities.Capabilities; +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.capability.IFluidHandler; -import net.neoforged.neoforge.fluids.capability.templates.FluidTank; +import org.jetbrains.annotations.NotNull; public class SinkBlockEntity extends BlockEntity { private static final int SYNC_INTERVAL = 10; - public final FluidTank sinkTank = new FluidTank(16000) { + // 这里水槽不包含实际内部状态,所以提供一个静态字段即可,不需要setChange和序列化保存 + public static final IFluidHandler fluidHandler = new IFluidHandler() + { + private static FluidStack WATER_STACK = new FluidStack(Fluids.WATER, Integer.MAX_VALUE); + + // 防止有时被外界修改 + private void verifyStack() + { + if(WATER_STACK.getFluid() != Fluids.WATER || WATER_STACK.getAmount() != Integer.MAX_VALUE) + WATER_STACK = new FluidStack(Fluids.WATER, Integer.MAX_VALUE); + } + + @Override + public int getTanks() + { + return 1; + } + @Override - public FluidStack getFluid() { - return new FluidStack(Fluids.WATER, Integer.MAX_VALUE); + public @NotNull FluidStack getFluidInTank(int tank) + { + // 每次get都返回新实例有点耗性能,所以用个静态量 + verifyStack(); + return WATER_STACK; } @Override - public int getCapacity() { + public int getTankCapacity(int tank) + { return Integer.MAX_VALUE; } @Override - public FluidStack drain(FluidStack resource, IFluidHandler.FluidAction action) { - return this.drain(resource.getAmount(), action); + public boolean isFluidValid(int tank, @NotNull FluidStack fluidStack) + { + return true; + } + + // 返回实际填充量 + // fluidAction在这里用来检查是不是模拟操作 + // 如果是模拟操作,则不改变容器内状态,但是此处水槽本身无实际的内部状态,因此可以不管 + @Override + public int fill(FluidStack fluidStack, @NotNull FluidAction fluidAction) + { + return fluidStack.getAmount(); // 如果想把它当流体垃圾桶 + //return 0; 不接受任何流体输入 + } + + // 返回实际排出量 + @Override + public @NotNull FluidStack drain(FluidStack fluidStack, @NotNull FluidAction fluidAction) + { + if(fluidStack.getFluid() == Fluids.WATER) + return fluidStack.copy(); // 总是返回请求量 + return FluidStack.EMPTY; } - public FluidStack drain(int maxDrain, IFluidHandler.FluidAction action) { - return getFluid(); + @Override + public @NotNull FluidStack drain(int amount, FluidAction fluidAction) + { + if(amount > 0) + return new FluidStack(Fluids.WATER, amount); + return FluidStack.EMPTY; } }; + // 注册能力,这里给你放到mod主类去注册了,回头你自己整理一下就行 + public static void registerCapability(RegisterCapabilitiesEvent event) { + event.registerBlockEntity( + Capabilities.FluidHandler.BLOCK, + ITBlockEntityTypes.SINK.get(), + (be, side) -> SinkBlockEntity.fluidHandler + ); + } + + // 如果需要主动输出能力,则在tick中自己使用level.getCapability获取对面的流体能力 + // 然后自行操作对方的流体容器,记得最好不要直接修改getFluidInTank拿到的实例,应该用fill和drain + private int ticksSinceSync; public SinkBlockEntity(BlockEntityType type, BlockPos pos, BlockState blockState) {