diff --git a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/util/SimpleFlowableFluid.java b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/util/SimpleFlowableFluid.java index 59afd97e..2c2b7fcb 100644 --- a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/util/SimpleFlowableFluid.java +++ b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/util/SimpleFlowableFluid.java @@ -22,6 +22,10 @@ import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; +/** + * Use {@link io.github.fabricators_of_create.porting_lib.fluids.BaseFlowingFluid} in the fluid module instead. + */ +@Deprecated(forRemoval = true) public abstract class SimpleFlowableFluid extends FlowingFluid { private final Supplier flowing; private final Supplier still; diff --git a/modules/fluids/src/main/java/io/github/fabricators_of_create/porting_lib/fluids/BaseFlowingFluid.java b/modules/fluids/src/main/java/io/github/fabricators_of_create/porting_lib/fluids/BaseFlowingFluid.java new file mode 100644 index 00000000..3377d9b6 --- /dev/null +++ b/modules/fluids/src/main/java/io/github/fabricators_of_create/porting_lib/fluids/BaseFlowingFluid.java @@ -0,0 +1,217 @@ +package io.github.fabricators_of_create.porting_lib.fluids; + +import java.util.Optional; + +import io.github.fabricators_of_create.porting_lib.fluids.extensions.ConvertToSourceFluid; +import io.github.fabricators_of_create.porting_lib.fluids.sound.SoundActions; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.LiquidBlock; +import net.minecraft.world.level.material.FlowingFluid; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.core.Direction; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Supplier; + +public abstract class BaseFlowingFluid extends FlowingFluid implements ConvertToSourceFluid { + private final Supplier fluidType; + private final Supplier flowing; + private final Supplier still; + @Nullable + private final Supplier bucket; + @Nullable + private final Supplier block; + private final int slopeFindDistance; + private final int levelDecreasePerBlock; + private final float explosionResistance; + private final int tickRate; + + protected BaseFlowingFluid(Properties properties) { + this.fluidType = properties.fluidType; + this.flowing = properties.flowing; + this.still = properties.still; + this.bucket = properties.bucket; + this.block = properties.block; + this.slopeFindDistance = properties.slopeFindDistance; + this.levelDecreasePerBlock = properties.levelDecreasePerBlock; + this.explosionResistance = properties.explosionResistance; + this.tickRate = properties.tickRate; + } + + @Override + public FluidType getFluidType() { + return this.fluidType.get(); + } + + @Override + public Fluid getFlowing() { + return flowing.get(); + } + + @Override + public Fluid getSource() { + return still.get(); + } + + @Override + protected boolean canConvertToSource(Level level) { + return false; + } + + @Override + public boolean canConvertToSource(FluidState state, Level level, BlockPos pos) { + return this.getFluidType().canConvertToSource(state, level, pos); + } + + @Override + protected void beforeDestroyingBlock(LevelAccessor worldIn, BlockPos pos, BlockState state) { + BlockEntity blockEntity = state.hasBlockEntity() ? worldIn.getBlockEntity(pos) : null; + Block.dropResources(state, worldIn, pos, blockEntity); + } + + @Override + protected int getSlopeFindDistance(LevelReader worldIn) { + return slopeFindDistance; + } + + @Override + protected int getDropOff(LevelReader worldIn) { + return levelDecreasePerBlock; + } + + @Override + public Item getBucket() { + return bucket != null ? bucket.get() : Items.AIR; + } + + @Override + protected boolean canBeReplacedWith(FluidState state, BlockGetter level, BlockPos pos, Fluid fluidIn, Direction direction) { + // Based on the water implementation, may need to be overriden for mod fluids that shouldn't behave like water. + return direction == Direction.DOWN && !isSame(fluidIn); + } + + @Override + public int getTickDelay(LevelReader level) { + return tickRate; + } + + @Override + protected float getExplosionResistance() { + return explosionResistance; + } + + @Override + protected BlockState createLegacyBlock(FluidState state) { + if (block != null) + return block.get().defaultBlockState().setValue(LiquidBlock.LEVEL, getLegacyLevel(state)); + return Blocks.AIR.defaultBlockState(); + } + + @Override + public boolean isSame(Fluid fluidIn) { + return fluidIn == still.get() || fluidIn == flowing.get(); + } + + @NotNull + @Override + public Optional getPickupSound() { + return Optional.ofNullable(getFluidType().getSound(SoundActions.BUCKET_FILL)); + } + + public static class Flowing extends BaseFlowingFluid { + public Flowing(Properties properties) { + super(properties); + registerDefaultState(getStateDefinition().any().setValue(LEVEL, 7)); + } + + protected void createFluidStateDefinition(StateDefinition.Builder builder) { + super.createFluidStateDefinition(builder); + builder.add(LEVEL); + } + + public int getAmount(FluidState state) { + return state.getValue(LEVEL); + } + + public boolean isSource(FluidState state) { + return false; + } + } + + public static class Source extends BaseFlowingFluid { + public Source(Properties properties) { + super(properties); + } + + public int getAmount(FluidState state) { + return 8; + } + + public boolean isSource(FluidState state) { + return true; + } + } + + public static class Properties { + private Supplier fluidType; + private Supplier still; + private Supplier flowing; + private Supplier bucket; + private Supplier block; + private int slopeFindDistance = 4; + private int levelDecreasePerBlock = 1; + private float explosionResistance = 1; + private int tickRate = 5; + + public Properties(Supplier fluidType, Supplier still, Supplier flowing) { + this.fluidType = fluidType; + this.still = still; + this.flowing = flowing; + } + + public Properties bucket(Supplier bucket) { + this.bucket = bucket; + return this; + } + + public Properties block(Supplier block) { + this.block = block; + return this; + } + + public Properties slopeFindDistance(int slopeFindDistance) { + this.slopeFindDistance = slopeFindDistance; + return this; + } + + public Properties levelDecreasePerBlock(int levelDecreasePerBlock) { + this.levelDecreasePerBlock = levelDecreasePerBlock; + return this; + } + + public Properties explosionResistance(float explosionResistance) { + this.explosionResistance = explosionResistance; + return this; + } + + public Properties tickRate(int tickRate) { + this.tickRate = tickRate; + return this; + } + } +} diff --git a/modules/fluids/src/main/java/io/github/fabricators_of_create/porting_lib/fluids/extensions/ConvertToSourceFluid.java b/modules/fluids/src/main/java/io/github/fabricators_of_create/porting_lib/fluids/extensions/ConvertToSourceFluid.java new file mode 100644 index 00000000..afd775c8 --- /dev/null +++ b/modules/fluids/src/main/java/io/github/fabricators_of_create/porting_lib/fluids/extensions/ConvertToSourceFluid.java @@ -0,0 +1,15 @@ +package io.github.fabricators_of_create.porting_lib.fluids.extensions; + +import io.github.fabricators_of_create.porting_lib.fluids.mixin.FlowingFluidAccessor; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.material.FluidState; + +/** + * Must be implemented on {@link net.minecraft.world.level.material.FlowingFluid} + */ +public interface ConvertToSourceFluid { + default boolean canConvertToSource(FluidState state, Level level, BlockPos pos) { + return ((FlowingFluidAccessor) this).callCanConvertToSource(level); + } +} diff --git a/modules/fluids/src/main/java/io/github/fabricators_of_create/porting_lib/fluids/mixin/FlowingFluidAccessor.java b/modules/fluids/src/main/java/io/github/fabricators_of_create/porting_lib/fluids/mixin/FlowingFluidAccessor.java new file mode 100644 index 00000000..1967e353 --- /dev/null +++ b/modules/fluids/src/main/java/io/github/fabricators_of_create/porting_lib/fluids/mixin/FlowingFluidAccessor.java @@ -0,0 +1,13 @@ +package io.github.fabricators_of_create.porting_lib.fluids.mixin; + +import net.minecraft.world.level.Level; +import net.minecraft.world.level.material.FlowingFluid; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(FlowingFluid.class) +public interface FlowingFluidAccessor { + @Invoker + boolean callCanConvertToSource(Level level); +} diff --git a/modules/fluids/src/main/java/io/github/fabricators_of_create/porting_lib/fluids/mixin/FlowingFluidMixin.java b/modules/fluids/src/main/java/io/github/fabricators_of_create/porting_lib/fluids/mixin/FlowingFluidMixin.java new file mode 100644 index 00000000..7ea5d6c1 --- /dev/null +++ b/modules/fluids/src/main/java/io/github/fabricators_of_create/porting_lib/fluids/mixin/FlowingFluidMixin.java @@ -0,0 +1,20 @@ +package io.github.fabricators_of_create.porting_lib.fluids.mixin; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; + +import com.llamalad7.mixinextras.sugar.Local; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.material.FlowingFluid; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(FlowingFluid.class) +public class FlowingFluidMixin { +// @ModifyExpressionValue(method = "getNewLiquid", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/material/FluidState;isSource()Z")) TODO: implement +// private boolean canConvertToSource(boolean original, @Local(index = 8) BlockPos pos) { +// +// return original; +// } +} diff --git a/modules/fluids/src/main/resources/porting_lib_fluids.mixins.json b/modules/fluids/src/main/resources/porting_lib_fluids.mixins.json index d819b7d3..a1f969ee 100644 --- a/modules/fluids/src/main/resources/porting_lib_fluids.mixins.json +++ b/modules/fluids/src/main/resources/porting_lib_fluids.mixins.json @@ -7,6 +7,8 @@ "defaultRequire": 1 }, "mixins": [ + "FlowingFluidAccessor", + "FlowingFluidMixin", "FluidMixin", "FluidStateMixin", "LiquidBlockMixin"