diff --git a/patches/net/minecraft/world/entity/Entity.java.patch b/patches/net/minecraft/world/entity/Entity.java.patch index 15f8303a24..5b1edcdfbe 100644 --- a/patches/net/minecraft/world/entity/Entity.java.patch +++ b/patches/net/minecraft/world/entity/Entity.java.patch @@ -100,7 +100,7 @@ this.playSound(soundtype.getStepSound(), soundtype.getVolume() * 0.15F, soundtype.getPitch()); } -@@ -1294,20 +_,23 @@ +@@ -1294,20 +_,25 @@ public void updateSwimming() { if (this.isSwimming()) { @@ -118,8 +118,8 @@ this.fluidHeight.clear(); + this.forgeFluidTypeHeight.clear(); this.updateInWaterStateAndDoWaterCurrentPushing(); -- double d0 = this.level().dimensionType().ultraWarm() ? 0.007 : 0.0023333333333333335; -- boolean flag = this.updateFluidHeightAndDoFluidPushing(FluidTags.LAVA, d0); + double d0 = this.level().dimensionType().ultraWarm() ? 0.007 : 0.0023333333333333335; + boolean flag = this.updateFluidHeightAndDoFluidPushing(FluidTags.LAVA, d0); - return this.isInWater() || flag; + if (this.isInFluidType() && !(this.getVehicle() instanceof AbstractBoat)) { + this.fallDistance *= this.forgeFluidTypeHeight.object2DoubleEntrySet().stream().filter(e -> !e.getKey().isAir() && !e.getKey().isVanilla()).map(e -> this.getFluidFallDistanceModifier(e.getKey())).min(Float::compare).orElse(1F); @@ -129,6 +129,15 @@ } void updateInWaterStateAndDoWaterCurrentPushing() { +@@ -1316,7 +_,7 @@ + return; + } + +- if (this.updateFluidHeightAndDoFluidPushing(FluidTags.WATER, 0.014)) { ++ if (this.updateFluidHeightAndDoFluidPushing(FluidTags.WATER, 0.014) || this.isInFluidType((type, d) -> type.actsLikeWater())) { + if (!this.wasTouchingWater && !this.firstTick) { + this.doWaterSplashEffect(); + } @@ -1332,6 +_,7 @@ private void updateFluidOnEyes() { this.wasEyeInWater = this.isEyeInFluid(FluidTags.WATER); @@ -315,25 +324,21 @@ this.dimensions = entitydimensions1; this.eyeHeight = entitydimensions1.eyeHeight(); this.reapplyPosition(); -@@ -3265,9 +_,17 @@ +@@ -3265,7 +_,14 @@ return Mth.lerp(p_352259_, this.yRotO, this.yRot); } -+ @Deprecated // Forge: Use no parameter version instead, only for vanilla Tags ++ @Deprecated // Neo: Use type version instead public boolean updateFluidHeightAndDoFluidPushing(TagKey p_204032_, double p_204033_) { -+ this.updateFluidHeightAndDoFluidPushing(); -+ if(p_204032_ == FluidTags.WATER) return this.isInFluidType(net.neoforged.neoforge.common.NeoForgeMod.WATER_TYPE.value()); -+ else if (p_204032_ == FluidTags.LAVA) return this.isInFluidType(net.neoforged.neoforge.common.NeoForgeMod.LAVA_TYPE.value()); ++ if(p_204032_ == FluidTags.WATER) return this.updateFluidHeightAndDoFluidPushing(net.neoforged.neoforge.common.NeoForgeMod.WATER_TYPE.value()); ++ else if (p_204032_ == FluidTags.LAVA) return this.updateFluidHeightAndDoFluidPushing(net.neoforged.neoforge.common.NeoForgeMod.LAVA_TYPE.value()); + else return false; + } + -+ public void updateFluidHeightAndDoFluidPushing() { ++ public boolean updateFluidHeightAndDoFluidPushing(net.neoforged.neoforge.fluids.FluidType type) { if (this.touchingUnloadedChunk()) { -- return false; -+ return; + return false; } else { - AABB aabb = this.getBoundingBox().deflate(0.001); - int i = Mth.floor(aabb.minX); @@ -3282,25 +_,36 @@ Vec3 vec3 = Vec3.ZERO; int k1 = 0; @@ -352,7 +357,7 @@ FluidState fluidstate = this.level().getFluidState(blockpos$mutableblockpos); - if (fluidstate.is(p_204032_)) { + net.neoforged.neoforge.fluids.FluidType fluidType = fluidstate.getFluidType(); -+ if (!fluidType.isAir()) { ++ if (fluidType == type) { double d1 = (double)((float)i2 + fluidstate.getHeight(this.level(), blockpos$mutableblockpos)); if (d1 >= aabb.minY) { flag1 = true; @@ -378,7 +383,7 @@ } } } -@@ -3308,27 +_,30 @@ +@@ -3308,26 +_,30 @@ } } @@ -412,13 +417,12 @@ } - this.fluidHeight.put(p_204032_, d0); -- return flag1; + this.setFluidTypeHeight(fluidType, interim.fluidHeight); + }); + } + return flag1; } } - @@ -3341,7 +_,10 @@ return !this.level().hasChunksAt(i, k, j, l); } diff --git a/patches/net/minecraft/world/entity/LivingEntity.java.patch b/patches/net/minecraft/world/entity/LivingEntity.java.patch index 982040cc46..7e9bf2eaed 100644 --- a/patches/net/minecraft/world/entity/LivingEntity.java.patch +++ b/patches/net/minecraft/world/entity/LivingEntity.java.patch @@ -521,6 +521,17 @@ } protected float getWaterSlowDown() { +@@ -2184,8 +_,8 @@ + public void travel(Vec3 p_21280_) { + if (this.isControlledByLocalInstance()) { + FluidState fluidstate = this.level().getFluidState(this.blockPosition()); +- if ((this.isInWater() || this.isInLava()) && this.isAffectedByFluids() && !this.canStandOnFluid(fluidstate)) { +- this.travelInFluid(p_21280_); ++ if ((this.isInWater() || (this.isInFluidType(fluidstate) && fluidstate.getFluidType() != net.neoforged.neoforge.common.NeoForgeMod.LAVA_TYPE.value())) && this.isAffectedByFluids() && !this.canStandOnFluid(fluidstate)) { ++ this.travelInFluid(p_21280_, fluidstate); + } else if (this.isFallFlying()) { + this.travelFallFlying(); + } else { @@ -2196,7 +_,7 @@ private void travelInAir(Vec3 p_362457_) { @@ -559,6 +570,15 @@ this.moveRelative(f1, p_365480_); this.move(MoverType.SELF, this.getDeltaMovement()); Vec3 vec3 = this.getDeltaMovement(); +@@ -2249,7 +_,7 @@ + + vec3 = vec3.multiply((double)f, 0.8F, (double)f); + this.setDeltaMovement(this.getFluidFallingAdjustedMovement(d1, flag, vec3)); +- } else { ++ } else if (this.isInLava() && this.isAffectedByFluids() && !this.canStandOnFluid(fluidState)) { + this.moveRelative(0.02F, p_365480_); + this.move(MoverType.SELF, this.getDeltaMovement()); + if (this.getFluidHeight(FluidTags.LAVA) <= this.getFluidJumpThreshold()) { @@ -2389,7 +_,7 @@ double d0 = Mth.clamp(p_21298_.x, -0.15F, 0.15F); double d1 = Mth.clamp(p_21298_.z, -0.15F, 0.15F); diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java index b2a4298e12..19a9ea79ca 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java @@ -428,6 +428,7 @@ public void setItemMovement(ItemEntity entity) { .sound(SoundActions.BUCKET_EMPTY, SoundEvents.BUCKET_EMPTY) .sound(SoundActions.FLUID_VAPORIZE, SoundEvents.FIRE_EXTINGUISH) .canHydrate(true) + .actsLikeWater(true) .addDripstoneDripping(PointedDripstoneBlock.WATER_TRANSFER_PROBABILITY_PER_RANDOM_TICK, ParticleTypes.DRIPPING_DRIPSTONE_WATER, Blocks.WATER_CAULDRON, SoundEvents.POINTED_DRIPSTONE_DRIP_WATER_INTO_CAULDRON)) { @Override public boolean canConvertToSource(FluidState state, LevelReader reader, BlockPos pos) { diff --git a/src/main/java/net/neoforged/neoforge/fluids/FluidType.java b/src/main/java/net/neoforged/neoforge/fluids/FluidType.java index 169194c360..96f6b3dfd6 100644 --- a/src/main/java/net/neoforged/neoforge/fluids/FluidType.java +++ b/src/main/java/net/neoforged/neoforge/fluids/FluidType.java @@ -83,6 +83,7 @@ public class FluidType { @Nullable private final PathType pathType, adjacentPathType; private final boolean canHydrate; + private final boolean actsLikeWater; private final int lightLevel; private final int density; private final int temperature; @@ -115,6 +116,7 @@ public FluidType(final Properties properties) { this.adjacentPathType = properties.adjacentPathType; this.sounds = ImmutableMap.copyOf(properties.sounds); this.canHydrate = properties.canHydrate; + this.actsLikeWater = properties.actsLikeWater; this.lightLevel = properties.lightLevel; this.density = properties.density; this.temperature = properties.temperature; @@ -372,6 +374,17 @@ public boolean canHydrate(Entity entity) { return this.canHydrate; } + /** + * Returns whether a fluid should be treated like an entity is residing in water. + * + *

This sets {@link Entity#isInWater()} to return true, which is used for things like aquatic animal swimming, slowed minecart movement, and conduit functionality. + * + * @return {@code true} if this fluid acts like water, {@code false} otherwise + */ + public boolean actsLikeWater() { + return this.actsLikeWater; + } + /** * Returns a sound to play when a certain action is performed by the * entity in the fluid. If no sound is present, then the sound will be @@ -863,6 +876,7 @@ public static final class Properties { adjacentPathType = PathType.WATER_BORDER; private final Map sounds = new HashMap<>(); private boolean canHydrate = false; + private boolean actsLikeWater = false; private int lightLevel = 0, density = 1000, temperature = 300, @@ -1031,6 +1045,19 @@ public Properties canHydrate(boolean canHydrate) { return this; } + /** + * Returns whether a fluid should be treated like an entity is residing in water. + * + *

This sets {@link Entity#isInWater()} to return true when an entity is in this fluid, which is used for things like aquatic animal swimming, slowed minecart movement, and conduit functionality. + * + * @param actsLikeWater if the fluid acts like water + * @return the property holder instance + */ + public Properties actsLikeWater(boolean actsLikeWater) { + this.actsLikeWater = actsLikeWater; + return this; + } + /** * Sets the light level emitted by the fluid. *