package net.shadowfacts.extrahoppers.mixin; import net.minecraft.block.BlockState; import net.minecraft.fluid.BaseFluid; import net.minecraft.fluid.FluidState; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.BlockView; import net.minecraft.world.WorldView; 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.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import net.shadowfacts.extrahoppers.util.FluidFlowControllable; import net.shadowfacts.extrahoppers.util.PositionedFluidStateProvider; /** * @author shadowfacts */ @Mixin(BaseFluid.class) public abstract class MixinBaseFluid { @ModifyVariable( method = "getUpdatedState(Lnet/minecraft/world/WorldView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Lnet/minecraft/fluid/FluidState;", at = @At(value = "INVOKE", target = "Lnet/minecraft/fluid/FluidState;isEmpty()Z", shift = At.Shift.BEFORE), index = 8, ordinal = 0, require = 1 ) private FluidState getUpdatedState(FluidState initial, WorldView world, BlockPos pos, BlockState state) { BlockPos up = pos.up(); BlockState upState = world.getBlockState(up); if (upState.getBlock() instanceof PositionedFluidStateProvider) { return ((PositionedFluidStateProvider)upState.getBlock()).getFluidState(upState, world, up); } return initial; } @Inject( method = "receivesFlow(Lnet/minecraft/util/math/Direction;Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Z", at = @At("HEAD"), cancellable = true ) private void receivesFlow(Direction direction, BlockView world, BlockPos pos, BlockState state, BlockPos fromPos, BlockState fromState, CallbackInfoReturnable cir) { FluidFlowControllable.Result result = FluidFlowControllable.Result.DEFAULT; if (state.getBlock() instanceof FluidFlowControllable) { result = ((FluidFlowControllable)state.getBlock()).allowsFlow(direction, state, world, pos); } if (result != FluidFlowControllable.Result.DENY && fromState.getBlock() instanceof FluidFlowControllable) { result = ((FluidFlowControllable)fromState.getBlock()).allowsFlow(direction, fromState, world, fromPos); } if (result != FluidFlowControllable.Result.DEFAULT) { cir.setReturnValue(result == FluidFlowControllable.Result.ALLOW); } } }