package dev.halbear1.supernova.custom.fluid; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.FlowingFluidBlock; import net.minecraft.fluid.FlowingFluid; import net.minecraft.fluid.Fluid; import net.minecraft.fluid.FluidState; import net.minecraft.item.Item; import net.minecraft.item.Items; import net.minecraft.state.Property; import net.minecraft.state.StateContainer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorld; import net.minecraft.world.IWorldReader; import net.minecraftforge.fluids.FluidAttributes; import net.minecraftforge.fluids.ForgeFlowingFluid; import javax.annotation.Nullable; import java.util.function.Supplier; public abstract class SupernovaFlowingFluid extends FlowingFluid { private final Supplier flowing; private final Supplier still; private final FluidAttributes.Builder FluidBuilder; private final SupernovaFluidAttributes.SupernovaFluidBuilder ExtendedBuilder; @Nullable private final Supplier bucket; @Nullable private final Supplier block; private final boolean canMultiply; private final int slopeFindDistance; private final int levelDecreasePerBlock; private final float explosionResistance; private final int tickRate; protected SupernovaFlowingFluid(Properties properties) { this.FluidBuilder = properties.attributes; this.flowing = properties.flowing; this.still = properties.still; this.canMultiply = properties.canMultiply; this.bucket = properties.bucket; this.block = properties.block; this.slopeFindDistance = properties.slopeFindDistance; this.levelDecreasePerBlock = properties.levelDecreasePerBlock; this.explosionResistance = properties.explosionResistance; this.tickRate = properties.tickRate; this.ExtendedBuilder = properties.extended_attributes; } public Fluid getFlowingFluid() { return (Fluid)this.flowing.get(); } public Fluid getStillFluid() { return (Fluid)this.still.get(); } protected boolean canSourcesMultiply() { return this.canMultiply; } protected void beforeReplacingBlock(IWorld worldIn, BlockPos pos, BlockState state) { TileEntity tileentity = state.getBlock().hasTileEntity(state) ? worldIn.getTileEntity(pos) : null; Block.spawnDrops(state, worldIn, pos, tileentity); } protected int getSlopeFindDistance(IWorldReader worldIn) { return this.slopeFindDistance; } protected int getLevelDecreasePerBlock(IWorldReader worldIn) { return this.levelDecreasePerBlock; } public Item getFilledBucket() { return this.bucket != null ? (Item)this.bucket.get() : Items.AIR; } protected boolean canDisplace(FluidState state, IBlockReader world, BlockPos pos, Fluid fluidIn, Direction direction) { return direction == Direction.DOWN && !this.isEquivalentTo(fluidIn); } public int getTickRate(IWorldReader world) { return this.tickRate; } protected float getExplosionResistance() { return this.explosionResistance; } protected BlockState getBlockState(FluidState state) { return this.block != null ? (BlockState)((FlowingFluidBlock)this.block.get()).getDefaultState().with(FlowingFluidBlock.LEVEL, getLevelFromState(state)) : Blocks.AIR.getDefaultState(); } public boolean isEquivalentTo(Fluid fluidIn) { return fluidIn == this.still.get() || fluidIn == this.flowing.get(); } protected FluidAttributes createAttributes() { return this.FluidBuilder.build(this); } public static class Properties { private Supplier still; private Supplier flowing; private FluidAttributes.Builder attributes; private SupernovaFluidAttributes.SupernovaFluidBuilder extended_attributes; private boolean canMultiply; private Supplier bucket; private Supplier block; private int slopeFindDistance = 4; private int levelDecreasePerBlock = 1; private float explosionResistance = 1.0F; private int tickRate = 5; public Properties(Supplier still, Supplier flowing, FluidAttributes.Builder attributes, SupernovaFluidAttributes.SupernovaFluidBuilder extended_attributes) { this.still = still; this.flowing = flowing; this.attributes = attributes; this.extended_attributes = extended_attributes; } public SupernovaFlowingFluid.Properties canMultiply() { this.canMultiply = true; return this; } public SupernovaFlowingFluid.Properties bucket(Supplier bucket) { this.bucket = bucket; return this; } public SupernovaFlowingFluid.Properties block(Supplier block) { this.block = block; return this; } public SupernovaFlowingFluid.Properties slopeFindDistance(int slopeFindDistance) { this.slopeFindDistance = slopeFindDistance; return this; } public SupernovaFlowingFluid.Properties levelDecreasePerBlock(int levelDecreasePerBlock) { this.levelDecreasePerBlock = levelDecreasePerBlock; return this; } public SupernovaFlowingFluid.Properties explosionResistance(float explosionResistance) { this.explosionResistance = explosionResistance; return this; } public SupernovaFlowingFluid.Properties tickRate(int tickRate) { this.tickRate = tickRate; return this; } } public static class Source extends SupernovaFlowingFluid { public Source(Properties properties) { super(properties); } public int getLevel(FluidState state) { return 8; } public boolean isSource(FluidState state) { return true; } } public static class Flowing extends SupernovaFlowingFluid { public Flowing(Properties properties) { super(properties); this.setDefaultState((FluidState)((FluidState)this.getStateContainer().getBaseState()).with(LEVEL_1_8, 7)); } protected void fillStateContainer(StateContainer.Builder builder) { super.fillStateContainer(builder); builder.add(new Property[]{LEVEL_1_8}); } public int getLevel(FluidState state) { return (Integer)state.get(LEVEL_1_8); } public boolean isSource(FluidState state) { return false; } } }