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)