diff --git a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/block/NeighborChangeListeningBlock.java b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/block/NeighborChangeListeningBlock.java
index cd8f1b03..83c5aa66 100644
--- a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/block/NeighborChangeListeningBlock.java
+++ b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/block/NeighborChangeListeningBlock.java
@@ -5,5 +5,24 @@
import net.minecraft.world.level.block.state.BlockState;
public interface NeighborChangeListeningBlock {
+
+ /**
+ * Used by the neighbouring blocks to notify this block that that neighbour updated
+ * @param state Block state at position pos
+ * @param world The world
+ * @param pos Block position
+ * @param neighbor Neighbour position
+ */
void onNeighborChange(BlockState state, LevelReader world, BlockPos pos, BlockPos neighbor);
+
+ /**
+ * Check if this block should be notified of weak changes.
+ * Weak changes are changes 1 block away through a solid block. Similar to comparators.
+ * @param level The world
+ * @param pos Block position
+ * @return true if there are weak changes to check. False otherwise
+ */
+ default boolean getWeakChanges(BlockState state, LevelReader level, BlockPos pos) {
+ return false;
+ }
}
diff --git a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/extensions/ComparatorBlockExtension.java b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/extensions/ComparatorBlockExtension.java
new file mode 100644
index 00000000..b0ba46b2
--- /dev/null
+++ b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/extensions/ComparatorBlockExtension.java
@@ -0,0 +1,6 @@
+package io.github.fabricators_of_create.porting_lib.extensions;
+
+import io.github.fabricators_of_create.porting_lib.block.NeighborChangeListeningBlock;
+
+public interface ComparatorBlockExtension extends NeighborChangeListeningBlock {
+}
diff --git a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/common/ComparatorBlockMixin.java b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/common/ComparatorBlockMixin.java
new file mode 100644
index 00000000..ceefca5e
--- /dev/null
+++ b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/common/ComparatorBlockMixin.java
@@ -0,0 +1,27 @@
+package io.github.fabricators_of_create.porting_lib.mixin.common;
+
+import io.github.fabricators_of_create.porting_lib.extensions.ComparatorBlockExtension;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.LevelReader;
+import net.minecraft.world.level.block.Blocks;
+import net.minecraft.world.level.block.ComparatorBlock;
+
+import net.minecraft.world.level.block.state.BlockState;
+
+import org.spongepowered.asm.mixin.Mixin;
+
+@Mixin(ComparatorBlock.class)
+public class ComparatorBlockMixin implements ComparatorBlockExtension {
+ @Override
+ public void onNeighborChange(BlockState state, LevelReader world, BlockPos pos, BlockPos neighbor) {
+ if (pos.getY() == neighbor.getY() && world instanceof Level && !world.isClientSide()) {
+ state.neighborChanged((Level)world, pos, world.getBlockState(neighbor).getBlock(), neighbor, false);
+ }
+ }
+
+ @Override
+ public boolean getWeakChanges(BlockState state, LevelReader level, BlockPos pos) {
+ return state.is(Blocks.COMPARATOR);
+ }
+}
diff --git a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/common/LevelMixin.java b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/common/LevelMixin.java
index f693515c..5a1ee202 100644
--- a/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/common/LevelMixin.java
+++ b/modules/base/src/main/java/io/github/fabricators_of_create/porting_lib/mixin/common/LevelMixin.java
@@ -7,25 +7,22 @@
import java.util.LinkedList;
import java.util.List;
-import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
-import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import com.llamalad7.mixinextras.sugar.Local;
-import io.github.fabricators_of_create.porting_lib.block.LightEmissiveBlock;
import io.github.fabricators_of_create.porting_lib.core.PortingLib;
import io.github.fabricators_of_create.porting_lib.event.common.BlockEvents;
import io.github.fabricators_of_create.porting_lib.event.common.ExplosionEvents;
import io.github.fabricators_of_create.porting_lib.extensions.extensions.BlockEntityExtensions;
import io.github.fabricators_of_create.porting_lib.extensions.extensions.LevelExtensions;
import net.fabricmc.fabric.api.transfer.v1.transaction.base.SnapshotParticipant;
-import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.FullChunkStatus;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
-import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.ExplosionDamageCalculator;
+import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.chunk.LevelChunk;
@@ -43,7 +40,6 @@
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import io.github.fabricators_of_create.porting_lib.block.NeighborChangeListeningBlock;
-import io.github.fabricators_of_create.porting_lib.block.WeakPowerCheckingBlock;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -155,25 +151,45 @@ public SnapshotParticipant snapshotParticipant() {
}
}
- @Inject(
- method = "updateNeighbourForOutputSignal",
- at = @At(
- value = "INVOKE",
- target = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;",
- shift = Shift.BY,
- by = 2,
- ordinal = 0
- ),
- locals = LocalCapture.CAPTURE_FAILHARD
+ /** Force cancel check for comparator and always say it is not. The comparator now implements
+ * NeighborChangeListeningBlock so code specific for comparators in {@link Level#updateNeighbourForOutputSignal(BlockPos, Block)}
+ * should be unreachable and instead handled via {@link LevelMixin#port_lib$updateNeighbourForOutputSignal(BlockPos, Block, CallbackInfo, BlockPos, BlockState)}
+ * and {@link LevelMixin#port_lib$updateNeighbourForOutputSignal2(BlockPos, Block, CallbackInfo, BlockPos, BlockState)}
+ * which call {@link NeighborChangeListeningBlock#onNeighborChange(BlockState, LevelReader, BlockPos, BlockPos)}
+ */
+ @Redirect(method = "updateNeighbourForOutputSignal",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;is(Lnet/minecraft/world/level/block/Block;)Z")
)
- public void port_lib$updateNeighbourForOutputSignal(BlockPos pos, Block block, CallbackInfo ci,
- Iterator> var3, Direction direction, BlockPos offset,
- BlockState state) {
+ public boolean port_lib$updateNeighbourForOutputSignalCancelCompChk(BlockState instance, Block block) {
+ return false;
+ }
+
+ /** Runs on first invocation of {@link Level#getBlockState(BlockPos)} in {@link Level#updateNeighbourForOutputSignal(BlockPos, Block)}
+ */
+ @Inject(method = "updateNeighbourForOutputSignal",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;",
+ shift = Shift.BY, by = 2, ordinal = 0)
+ )
+ public void port_lib$updateNeighbourForOutputSignal(BlockPos pos, Block block, CallbackInfo ci, @Local(ordinal = 1) BlockPos offset, @Local BlockState state) {
if (state.getBlock() instanceof NeighborChangeListeningBlock listener) {
listener.onNeighborChange(state, this, offset, pos);
}
}
+ /** Runs on second invocation of {@link Level#getBlockState(BlockPos)} in {@link Level#updateNeighbourForOutputSignal(BlockPos, Block)}
+ * (i.e. the one checking for changes through a block. So should only update for weak change listeners only
+ * (see {@link NeighborChangeListeningBlock#getWeakChanges(BlockState, LevelReader, BlockPos)}))
+ */
+ @Inject(method = "updateNeighbourForOutputSignal",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;",
+ shift = Shift.BY, by = 2, ordinal = 1)
+ )
+ public void port_lib$updateNeighbourForOutputSignal2(BlockPos pos, Block block, CallbackInfo ci, @Local(ordinal = 1) BlockPos offset, @Local BlockState state) {
+ if (state.getBlock() instanceof NeighborChangeListeningBlock listener && listener.getWeakChanges(state, this, pos)) {
+ listener.onNeighborChange(state, this, offset, pos);
+ }
+ }
+
@Inject(
method = "explode(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/damagesource/DamageSource;Lnet/minecraft/world/level/ExplosionDamageCalculator;DDDFZLnet/minecraft/world/level/Level$ExplosionInteraction;Z)Lnet/minecraft/world/level/Explosion;",
at = @At(
diff --git a/modules/base/src/main/resources/fabric.mod.json b/modules/base/src/main/resources/fabric.mod.json
index 0838ac7c..f708abe7 100644
--- a/modules/base/src/main/resources/fabric.mod.json
+++ b/modules/base/src/main/resources/fabric.mod.json
@@ -15,7 +15,8 @@
"custom": {
"loom:injected_interfaces": {
"net/minecraft/class_3283": ["io/github/fabricators_of_create/porting_lib/extensions/PackRepositoryExtension"],
- "net/minecraft/class_2680": ["io/github/fabricators_of_create/porting_lib/extensions/BaseBlockStateExtension"]
+ "net/minecraft/class_2680": ["io/github/fabricators_of_create/porting_lib/extensions/BaseBlockStateExtension"],
+ "net/minecraft/class_2286": ["io/github/fabricators_of_create/porting_lib/extensions/ComparatorBlockExtension"]
}
}
}
diff --git a/modules/base/src/main/resources/porting_lib_base.mixins.json b/modules/base/src/main/resources/porting_lib_base.mixins.json
index 6910643a..73102334 100644
--- a/modules/base/src/main/resources/porting_lib_base.mixins.json
+++ b/modules/base/src/main/resources/porting_lib_base.mixins.json
@@ -29,6 +29,7 @@
"common.ChunkMapMixin",
"common.ChunkStatusMixin",
"common.ClipContextMixin",
+ "common.ComparatorBlockMixin",
"common.ConnectionMixin",
"common.DeadBushBlockMixin",
"common.DiodeBlockMixin",
diff --git a/modules/entity/build.gradle b/modules/entity/build.gradle
index efb9d82b..3d034ba6 100644
--- a/modules/entity/build.gradle
+++ b/modules/entity/build.gradle
@@ -1,4 +1,5 @@
portingLib {
addModuleDependency("mixin_extensions")
+ addModuleDependency("fluids")
enableTestMod()
}
diff --git a/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/extensions/EntityExtensions.java b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/extensions/EntityExtensions.java
index 48c6a0f7..933beccd 100644
--- a/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/extensions/EntityExtensions.java
+++ b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/extensions/EntityExtensions.java
@@ -1,6 +1,8 @@
package io.github.fabricators_of_create.porting_lib.entity.extensions;
import io.github.fabricators_of_create.porting_lib.entity.ITeleporter;
+import io.github.fabricators_of_create.porting_lib.fluids.FluidType;
+import io.github.fabricators_of_create.porting_lib.fluids.PortingLibFluids;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
@@ -34,4 +36,12 @@ default boolean canRiderInteract() {
default Entity changeDimension(ServerLevel p_20118_, ITeleporter teleporter) {
throw new RuntimeException("this should be overridden via mixin. what?");
}
+
+ default FluidType getEyeInFluidType() {
+ throw new RuntimeException("This should be overridden in the EntityMixin");
+ }
+
+ default boolean isEyeInFluidType(FluidType type) {
+ return type == this.getEyeInFluidType();
+ }
}
diff --git a/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/extensions/LivingEntityExtensions.java b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/extensions/LivingEntityExtensions.java
new file mode 100644
index 00000000..eb048961
--- /dev/null
+++ b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/extensions/LivingEntityExtensions.java
@@ -0,0 +1,24 @@
+package io.github.fabricators_of_create.porting_lib.entity.extensions;
+
+import io.github.fabricators_of_create.porting_lib.fluids.FluidType;
+import net.minecraft.world.entity.LivingEntity;
+
+import io.github.fabricators_of_create.porting_lib.fluids.PortingLibFluids;
+
+public interface LivingEntityExtensions {
+ default LivingEntity self() {
+ return (LivingEntity) this;
+ }
+
+ /**
+ * Returns whether the entity can drown in the fluid.
+ *
+ * @param type the type of the fluid
+ * @return {@code true} if the entity can drown in the fluid, {@code false} otherwise
+ */
+ default boolean canDrownInFluidType(FluidType type) {
+ if (type == PortingLibFluids.WATER_TYPE) return !self().canBreatheUnderwater();
+ return type.canDrownIn(self());
+ }
+}
+
diff --git a/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/EntityMixin.java b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/EntityMixin.java
index 14a9e013..d378571b 100644
--- a/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/EntityMixin.java
+++ b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/EntityMixin.java
@@ -2,6 +2,13 @@
import java.util.Collection;
+import io.github.fabricators_of_create.porting_lib.fluids.FluidType;
+import io.github.fabricators_of_create.porting_lib.fluids.PortingLibFluids;
+import net.minecraft.core.BlockPos;
+import net.minecraft.tags.FluidTags;
+import net.minecraft.world.entity.vehicle.Boat;
+import net.minecraft.world.level.material.FluidState;
+
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -41,6 +48,8 @@
import net.minecraft.world.level.Level;
import net.minecraft.world.level.portal.PortalInfo;
+import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
+
@Mixin(Entity.class)
public abstract class EntityMixin implements EntityExtensions {
@Unique
@@ -124,6 +133,9 @@ public Collection captureDrops(Collection value) {
@Shadow
private Level level;
+ @Shadow
+ protected boolean wasEyeInWater;
+
@Shadow
public abstract void unRide();
@@ -158,6 +170,24 @@ public Collection captureDrops(Collection value) {
@Shadow
public abstract float getEyeHeight();
+ @Shadow
+ public abstract double getX();
+
+ @Shadow
+ public abstract double getY();
+
+ @Shadow
+ public abstract double getZ();
+
+ @Shadow
+ public abstract double getEyeY();
+
+ @Shadow
+ public abstract Entity getVehicle();
+
+ @Shadow
+ public abstract Level level();
+
@Inject(
method = "startRiding(Lnet/minecraft/world/entity/Entity;Z)Z",
at = @At(
@@ -275,4 +305,22 @@ public void afterSave(CompoundTag nbt, CallbackInfoReturnable cir)
public void afterLoad(CompoundTag nbt, CallbackInfo ci) {
EntityDataEvents.LOAD.invoker().onLoad((Entity) (Object) this, nbt);
}
+
+ @Unique
+ private FluidType fluidTypeOnEyes = PortingLibFluids.EMPTY_TYPE;
+
+ @Inject(method = "updateFluidOnEyes", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/material/FluidState;getTags()Ljava/util/stream/Stream;"))
+ private void updateFluidOnEyesSetFluidTypeOnEyes(CallbackInfo ci, @Local FluidState fluidState) {
+ this.fluidTypeOnEyes = fluidState.getFluidType();
+ }
+
+ @Inject(method = "updateFluidOnEyes", at = @At("HEAD"))
+ private void updateFluidOnEyesResetFluidTypeOnEyes(CallbackInfo ci) {
+ this.fluidTypeOnEyes = PortingLibFluids.EMPTY_TYPE;
+ }
+
+ @Override
+ public FluidType getEyeInFluidType() {
+ return this.fluidTypeOnEyes;
+ }
}
diff --git a/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/LivingEntityMixin.java b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/LivingEntityMixin.java
index 6c3ad5b2..5f79ec49 100644
--- a/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/LivingEntityMixin.java
+++ b/modules/entity/src/main/java/io/github/fabricators_of_create/porting_lib/entity/mixin/common/LivingEntityMixin.java
@@ -21,6 +21,7 @@
import io.github.fabricators_of_create.porting_lib.entity.events.living.LivingHurtEvent;
import io.github.fabricators_of_create.porting_lib.entity.events.living.MobEffectEvent;
+import io.github.fabricators_of_create.porting_lib.entity.extensions.LivingEntityExtensions;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
@@ -57,7 +58,7 @@
import net.minecraft.world.level.Level;
@Mixin(LivingEntity.class)
-public abstract class LivingEntityMixin extends Entity implements EntityExtensions {
+public abstract class LivingEntityMixin extends Entity implements LivingEntityExtensions {
@Shadow
protected int lastHurtByPlayerTime;
@Shadow
diff --git a/modules/entity/src/main/resources/fabric.mod.json b/modules/entity/src/main/resources/fabric.mod.json
index a425bca1..8a790e64 100644
--- a/modules/entity/src/main/resources/fabric.mod.json
+++ b/modules/entity/src/main/resources/fabric.mod.json
@@ -20,7 +20,8 @@
"net/minecraft/class_1657": ["io/github/fabricators_of_create/porting_lib/entity/extensions/PlayerExtension"],
"net/minecraft/class_1688": ["io/github/fabricators_of_create/porting_lib/entity/extensions/AbstractMinecartExtensions"],
"net/minecraft/class_1792": ["io/github/fabricators_of_create/porting_lib/entity/extensions/ItemExtensions"],
- "net/minecraft/class_1937": ["io/github/fabricators_of_create/porting_lib/entity/extensions/LevelExtensions"]
+ "net/minecraft/class_1937": ["io/github/fabricators_of_create/porting_lib/entity/extensions/LevelExtensions"],
+ "net/minecraft/class_1309": ["io/github/fabricators_of_create/porting_lib/entity/extensions/LivingEntityExtensions"]
}
}
}