From bb21fbf160a30a113f682628f499bbbab1db94d2 Mon Sep 17 00:00:00 2001 From: Notenoughmail <78008321+Notenoughmail@users.noreply.github.com> Date: Sun, 17 Sep 2023 14:39:46 -0700 Subject: [PATCH] PipeCollisionEvents -Add Flow and Spill events to allow for easy custom fluid collision results --- .../create/api/event/PipeCollisionEvent.java | 79 +++++++++++++++++++ .../create/content/fluids/FluidReactions.java | 52 ++++-------- .../foundation/events/CommonEvents.java | 52 ++++++++++++ 3 files changed, 145 insertions(+), 38 deletions(-) create mode 100644 src/main/java/com/simibubi/create/api/event/PipeCollisionEvent.java diff --git a/src/main/java/com/simibubi/create/api/event/PipeCollisionEvent.java b/src/main/java/com/simibubi/create/api/event/PipeCollisionEvent.java new file mode 100644 index 000000000..98f20ca73 --- /dev/null +++ b/src/main/java/com/simibubi/create/api/event/PipeCollisionEvent.java @@ -0,0 +1,79 @@ +package com.simibubi.create.api.event; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluid; +import net.minecraftforge.eventbus.api.Event; + +import org.jetbrains.annotations.Nullable; + +/** + * Event that is fired when a two fluids meet in a pipe ({@link Flow})
+ * or when a fluid in a pipe meets with a fluid in the world ({@link Spill}).
+ *
+ * If it is not null, the event's BlockState will be placed in world after firing. + */ +public class PipeCollisionEvent extends Event { + + private final Level level; + private final BlockPos pos; + protected final Fluid fluid0, fluid1; + @Nullable + private BlockState state; + + protected PipeCollisionEvent(Level level, BlockPos pos, Fluid fluid0, Fluid fluid1, @Nullable BlockState defaultState) { + this.level = level; + this.pos = pos; + this.fluid0 = fluid0; + this.fluid1 =fluid1; + this.state = defaultState; + } + + public Level getLevel() { + return level; + } + + public BlockPos getPos() { + return pos; + } + + @Nullable + public BlockState getState() { + return state; + } + + public void setState(@Nullable BlockState state) { + this.state = state; + } + + public static class Flow extends PipeCollisionEvent { + + public Flow(Level level, BlockPos pos, Fluid firstFluid, Fluid secondFluid, @Nullable BlockState defaultState) { + super(level, pos, firstFluid, secondFluid, defaultState); + } + + public Fluid getFirstFluid() { + return fluid0; + } + + public Fluid getSecondFluid() { + return fluid1; + } + } + + public static class Spill extends PipeCollisionEvent { + + public Spill(Level level, BlockPos pos, Fluid worldFluid, Fluid pipeFluid, @Nullable BlockState defaultState) { + super(level, pos, worldFluid, pipeFluid, defaultState); + } + + public Fluid getWorldFluid() { + return fluid0; + } + + public Fluid getPipeFluid() { + return fluid1; + } + } +} diff --git a/src/main/java/com/simibubi/create/content/fluids/FluidReactions.java b/src/main/java/com/simibubi/create/content/fluids/FluidReactions.java index 254e3476d..c1f03ecb7 100644 --- a/src/main/java/com/simibubi/create/content/fluids/FluidReactions.java +++ b/src/main/java/com/simibubi/create/content/fluids/FluidReactions.java @@ -1,66 +1,42 @@ package com.simibubi.create.content.fluids; -import com.simibubi.create.AllFluids; +import com.simibubi.create.api.event.PipeCollisionEvent; import com.simibubi.create.foundation.advancement.AdvancementBehaviour; import com.simibubi.create.foundation.advancement.AllAdvancements; import com.simibubi.create.foundation.fluid.FluidHelper; import com.simibubi.create.foundation.utility.BlockHelper; import net.minecraft.core.BlockPos; -import net.minecraft.tags.FluidTags; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fluids.FluidStack; public class FluidReactions { - public static void handlePipeFlowCollision(Level world, BlockPos pos, FluidStack fluid, FluidStack fluid2) { + public static void handlePipeFlowCollision(Level level, BlockPos pos, FluidStack fluid, FluidStack fluid2) { Fluid f1 = fluid.getFluid(); Fluid f2 = fluid2.getFluid(); - AdvancementBehaviour.tryAward(world, pos, AllAdvancements.CROSS_STREAMS); - BlockHelper.destroyBlock(world, pos, 1); + AdvancementBehaviour.tryAward(level, pos, AllAdvancements.CROSS_STREAMS); + BlockHelper.destroyBlock(level, pos, 1); - if (f1 == Fluids.WATER && f2 == Fluids.LAVA || f2 == Fluids.WATER && f1 == Fluids.LAVA) - world.setBlockAndUpdate(pos, Blocks.COBBLESTONE.defaultBlockState()); - else if (f1 == Fluids.LAVA && FluidHelper.hasBlockState(f2)) { - BlockState lavaInteraction = AllFluids.getLavaInteraction(FluidHelper.convertToFlowing(f2) - .defaultFluidState()); - if (lavaInteraction != null) - world.setBlockAndUpdate(pos, lavaInteraction); - } else if (f2 == Fluids.LAVA && FluidHelper.hasBlockState(f1)) { - BlockState lavaInteraction = AllFluids.getLavaInteraction(FluidHelper.convertToFlowing(f1) - .defaultFluidState()); - if (lavaInteraction != null) - world.setBlockAndUpdate(pos, lavaInteraction); + PipeCollisionEvent.Flow event = new PipeCollisionEvent.Flow(level, pos, f1, f2, null); + MinecraftForge.EVENT_BUS.post(event); + if (event.getState() != null) { + level.setBlockAndUpdate(pos, event.getState()); } } - public static void handlePipeSpillCollision(Level world, BlockPos pos, Fluid pipeFluid, FluidState worldFluid) { + public static void handlePipeSpillCollision(Level level, BlockPos pos, Fluid pipeFluid, FluidState worldFluid) { Fluid pf = FluidHelper.convertToStill(pipeFluid); Fluid wf = worldFluid.getType(); - if (FluidHelper.isTag(pf, FluidTags.WATER) && wf == Fluids.LAVA) - world.setBlockAndUpdate(pos, Blocks.OBSIDIAN.defaultBlockState()); - else if (pf == Fluids.WATER && wf == Fluids.FLOWING_LAVA) - world.setBlockAndUpdate(pos, Blocks.COBBLESTONE.defaultBlockState()); - else if (pf == Fluids.LAVA && wf == Fluids.WATER) - world.setBlockAndUpdate(pos, Blocks.STONE.defaultBlockState()); - else if (pf == Fluids.LAVA && wf == Fluids.FLOWING_WATER) - world.setBlockAndUpdate(pos, Blocks.COBBLESTONE.defaultBlockState()); - if (pf == Fluids.LAVA) { - BlockState lavaInteraction = AllFluids.getLavaInteraction(worldFluid); - if (lavaInteraction != null) - world.setBlockAndUpdate(pos, lavaInteraction); - } else if (wf == Fluids.FLOWING_LAVA && FluidHelper.hasBlockState(pf)) { - BlockState lavaInteraction = AllFluids.getLavaInteraction(FluidHelper.convertToFlowing(pf) - .defaultFluidState()); - if (lavaInteraction != null) - world.setBlockAndUpdate(pos, lavaInteraction); + PipeCollisionEvent.Spill event = new PipeCollisionEvent.Spill(level, pos, wf, pf, null); + MinecraftForge.EVENT_BUS.post(event); + if (event.getState() != null) { + level.setBlockAndUpdate(pos, event.getState()); } } diff --git a/src/main/java/com/simibubi/create/foundation/events/CommonEvents.java b/src/main/java/com/simibubi/create/foundation/events/CommonEvents.java index e0ec36b06..d6a6cb8f1 100644 --- a/src/main/java/com/simibubi/create/foundation/events/CommonEvents.java +++ b/src/main/java/com/simibubi/create/foundation/events/CommonEvents.java @@ -2,6 +2,7 @@ package com.simibubi.create.foundation.events; import com.simibubi.create.AllFluids; import com.simibubi.create.Create; +import com.simibubi.create.api.event.PipeCollisionEvent; import com.simibubi.create.content.contraptions.ContraptionHandler; import com.simibubi.create.content.contraptions.actors.trainControls.ControlsServerHandler; import com.simibubi.create.content.contraptions.minecart.CouplingPhysics; @@ -35,8 +36,11 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent; import net.minecraftforge.event.AddPackFindersEvent; import net.minecraftforge.event.AddReloadListenerEvent; @@ -120,6 +124,54 @@ public class CommonEvents { } } + @SubscribeEvent + public static void whenPipeFluidsMeet(PipeCollisionEvent.Flow event) { + Fluid f1 = event.getFirstFluid(); + Fluid f2 = event.getSecondFluid(); + + if (f1 == Fluids.WATER && f2 == Fluids.LAVA || f2 == Fluids.WATER && f1 == Fluids.LAVA) { + event.setState(Blocks.COBBLESTONE.defaultBlockState()); + } else if (f1 == Fluids.LAVA && FluidHelper.hasBlockState(f2)) { + BlockState lavaInteraction = AllFluids.getLavaInteraction(FluidHelper.convertToFlowing(f2).defaultFluidState()); + if (lavaInteraction != null) { + event.setState(lavaInteraction); + } + } else if (f2 == Fluids.LAVA && FluidHelper.hasBlockState(f1)) { + BlockState lavaInteraction = AllFluids.getLavaInteraction(FluidHelper.convertToFlowing(f1).defaultFluidState()); + if (lavaInteraction != null) { + event.setState(lavaInteraction); + } + } + } + + @SubscribeEvent + public static void whenPipeSpillsIntoWorld(PipeCollisionEvent.Spill event) { + Fluid pf = event.getPipeFluid(); + Fluid wf = event.getWorldFluid(); + + if (FluidHelper.isTag(pf, FluidTags.WATER) && wf == Fluids.LAVA) { + event.setState(Blocks.OBSIDIAN.defaultBlockState()); + } else if (pf == Fluids.WATER && wf == Fluids.FLOWING_LAVA) { + event.setState(Blocks.COBBLESTONE.defaultBlockState()); + } else if (pf == Fluids.LAVA && wf == Fluids.WATER) { + event.setState(Blocks.STONE.defaultBlockState()); + } else if (pf == Fluids.LAVA && wf == Fluids.FLOWING_LAVA) { + event.setState(Blocks.COBBLESTONE.defaultBlockState()); + } + + if (pf == Fluids.LAVA) { + BlockState lavaInteraction = AllFluids.getLavaInteraction(wf.defaultFluidState()); + if (lavaInteraction != null) { + event.setState(lavaInteraction); + } + } else if (wf == Fluids.FLOWING_LAVA && FluidHelper.hasBlockState(pf)) { + BlockState lavaInteraction = AllFluids.getLavaInteraction(FluidHelper.convertToFlowing(pf).defaultFluidState()); + if (lavaInteraction != null) { + event.setState(lavaInteraction); + } + } + } + @SubscribeEvent public static void onServerWorldTick(WorldTickEvent event) { if (event.phase == Phase.START)