ExtraHoppers/src/main/java/net/shadowfacts/extrahoppers/mixin/MixinBaseFluid.java

79 lines
3.7 KiB
Java

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.IWorld;
import net.minecraft.world.World;
import net.minecraft.world.WorldView;
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.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.shadowfacts.extrahoppers.util.DynamicFluidStateProvider;
/**
* @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 DynamicFluidStateProvider) {
return ((DynamicFluidStateProvider)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<Boolean> cir) {
DynamicFluidStateProvider.FlowResult result = DynamicFluidStateProvider.FlowResult.DEFAULT;
if (state.getBlock() instanceof DynamicFluidStateProvider) {
result = ((DynamicFluidStateProvider)state.getBlock()).allowsFlow(direction, state, world, pos);
}
if (result != DynamicFluidStateProvider.FlowResult.DENY && fromState.getBlock() instanceof DynamicFluidStateProvider) {
result = ((DynamicFluidStateProvider)fromState.getBlock()).allowsFlow(direction, fromState, world, fromPos);
}
if (result != DynamicFluidStateProvider.FlowResult.DEFAULT) {
cir.setReturnValue(result == DynamicFluidStateProvider.FlowResult.ALLOW);
}
}
@Inject(
method = "onScheduledTick(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/fluid/FluidState;)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"),
cancellable = true
)
private void onScheduledTick(World world, BlockPos pos, FluidState fluidState, CallbackInfo ci) {
BlockState state = world.getBlockState(pos);
if (state.getBlock() instanceof DynamicFluidStateProvider) {
((DynamicFluidStateProvider)state.getBlock()).setEmptyFluid(world, pos);
this.tryFlow(world, pos, fluidState);
ci.cancel();
}
}
@Shadow
protected abstract void tryFlow(IWorld world, BlockPos pos, FluidState state);
}