mirror of
https://github.com/Samsuik/Sakura.git
synced 2025-12-22 00:09:20 +00:00
1226 lines
62 KiB
Diff
1226 lines
62 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Samsuik <40902469+Samsuik@users.noreply.github.com>
|
|
Date: Tue, 21 Nov 2023 17:03:08 +0000
|
|
Subject: [PATCH] Configure cannon physics by version
|
|
|
|
|
|
diff --git a/src/main/java/io/papermc/paper/util/CollisionUtil.java b/src/main/java/io/papermc/paper/util/CollisionUtil.java
|
|
index 57ca8212991d0660dd41b70350f59830d4fd09f3..39085c2a356f575f0ef6acaa3de7d9ff560b5a87 100644
|
|
--- a/src/main/java/io/papermc/paper/util/CollisionUtil.java
|
|
+++ b/src/main/java/io/papermc/paper/util/CollisionUtil.java
|
|
@@ -1495,6 +1495,14 @@ public final class CollisionUtil {
|
|
public static Vec3 performCollisions(final Vec3 moveVector, AABB axisalignedbb,
|
|
final List<VoxelShape> voxels,
|
|
final List<AABB> aabbs) {
|
|
+ // Sakura start
|
|
+ return performCollisions(moveVector, axisalignedbb, voxels, aabbs, null);
|
|
+ }
|
|
+ public static Vec3 performCollisions(final Vec3 moveVector, AABB axisalignedbb,
|
|
+ final List<VoxelShape> voxels,
|
|
+ final List<AABB> aabbs,
|
|
+ final me.samsuik.sakura.physics.PhysicsVersion physics) {
|
|
+ // Sakura end
|
|
if (voxels.isEmpty()) {
|
|
// fast track only AABBs
|
|
return performAABBCollisions(moveVector, axisalignedbb, aabbs);
|
|
@@ -1512,7 +1520,10 @@ public final class CollisionUtil {
|
|
}
|
|
}
|
|
|
|
- final boolean xSmaller = Math.abs(x) < Math.abs(z);
|
|
+ // Sakura start - physics version api
|
|
+ final boolean xSmaller = physics == null || physics.afterOrEqual(1_14_0) ? Math.abs(x) < Math.abs(z)
|
|
+ : physics.is(1_7_0) && Math.abs(x) > Math.abs(z);
|
|
+ // Sakura end
|
|
|
|
if (xSmaller && z != 0.0) {
|
|
z = performAABBCollisionsZ(axisalignedbb, z, aabbs);
|
|
diff --git a/src/main/java/me/samsuik/sakura/explosion/SakuraExplosion.java b/src/main/java/me/samsuik/sakura/explosion/SakuraExplosion.java
|
|
index b87748ae90863abe8f85dcbdc5a202cb3c9e2037..a291516ec7bdb9d8b840f41ca52e6bbaf8e2e08a 100644
|
|
--- a/src/main/java/me/samsuik/sakura/explosion/SakuraExplosion.java
|
|
+++ b/src/main/java/me/samsuik/sakura/explosion/SakuraExplosion.java
|
|
@@ -163,7 +163,7 @@ public class SakuraExplosion extends Explosion {
|
|
|
|
// update explosion position
|
|
x = source.getX();
|
|
- y = source.getY(0.0625D);
|
|
+ y = physics.before(1_10_0) ? source.getY() + (double) 0.49f : source.getY(0.0625D);
|
|
z = source.getZ();
|
|
}
|
|
|
|
@@ -256,10 +256,17 @@ public class SakuraExplosion extends Explosion {
|
|
if (distanceFromBottom > 1.0) continue;
|
|
|
|
double x = entity.getX() - pos.x;
|
|
- double y = (entity instanceof PrimedTnt ? entity.getY() : entity.getEyeY()) - pos.y;
|
|
+ double y = entity.getEyeY() - pos.y; // Sakura - remove tnt special case
|
|
double z = entity.getZ() - pos.z;
|
|
double distance = Math.sqrt(x * x + y * y + z * z);
|
|
|
|
+ // Sakura start
|
|
+ if (this.physics.before(1_17_0)) {
|
|
+ distanceFromBottom = (float) distanceFromBottom;
|
|
+ distance = (float) distance;
|
|
+ }
|
|
+ // Sakura end
|
|
+
|
|
if (distance == 0.0D) continue;
|
|
|
|
x /= distance;
|
|
@@ -304,10 +311,17 @@ public class SakuraExplosion extends Explosion {
|
|
|
|
if (distanceFromBottom <= 1.0) {
|
|
double x = entity.getX() - pos.x;
|
|
- double y = (entity instanceof PrimedTnt ? entity.getY() : entity.getEyeY()) - pos.y;
|
|
+ double y = entity.getEyeY() - pos.y; // Sakura - remove tnt special case
|
|
double z = entity.getZ() - pos.z;
|
|
double distance = Math.sqrt(x * x + y * y + z * z);
|
|
|
|
+ // Sakura start
|
|
+ if (this.physics.before(1_17_0)) {
|
|
+ distanceFromBottom = (float) distanceFromBottom;
|
|
+ distance = (float) distance;
|
|
+ }
|
|
+ // Sakura end
|
|
+
|
|
if (distance != 0.0D) {
|
|
x /= distance;
|
|
y /= distance;
|
|
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
|
index 4c55fe458378f2f376a8c31cec57e4751aa3d290..852276d9bedc51c3c8a28b60c85fdb23cf9cf818 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
|
@@ -378,7 +378,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
|
private final double[] pistonDeltas;
|
|
private long pistonDeltasGameTime;
|
|
private EntityDimensions dimensions;
|
|
- private float eyeHeight;
|
|
+ protected float eyeHeight; // Sakura - physics version
|
|
public boolean isInPowderSnow;
|
|
public boolean wasInPowderSnow;
|
|
public boolean wasOnFire;
|
|
@@ -680,6 +680,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
|
}
|
|
// Sakura end
|
|
public boolean pushedByFluid = true; // Sakura
|
|
+ // Sakura start - physics version
|
|
+ protected me.samsuik.sakura.physics.PhysicsVersion physics = me.samsuik.sakura.physics.PhysicsVersion.LATEST;
|
|
+
|
|
+ public me.samsuik.sakura.physics.PhysicsVersion physics() {
|
|
+ return this.physics;
|
|
+ }
|
|
+ // Sakura end
|
|
|
|
public boolean isLegacyTrackingEntity = false;
|
|
|
|
@@ -1162,7 +1169,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
|
}
|
|
|
|
protected void checkSupportingBlock(boolean onGround, @Nullable Vec3 movement) {
|
|
- if (onGround) {
|
|
+ if (onGround && this.physics.afterOrEqual(1_20_0)) { // Sakura - physics version
|
|
AABB axisalignedbb = this.getBoundingBox();
|
|
AABB axisalignedbb1 = new AABB(axisalignedbb.minX, axisalignedbb.minY - 1.0E-6D, axisalignedbb.minZ, axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.maxZ);
|
|
Optional<BlockPos> optional = this.level.findSupportingBlock(this, axisalignedbb1);
|
|
@@ -1224,7 +1231,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
|
if (this.noPhysics) {
|
|
this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z);
|
|
} else {
|
|
- if (movementType == MoverType.PISTON) { // Paper
|
|
+ if (movementType == MoverType.PISTON && this.physics.afterOrEqual(1_11_0)) { // Sakura - physics version api // Paper
|
|
movement = this.limitPistonMovement(movement);
|
|
if (movement.equals(Vec3.ZERO)) {
|
|
return;
|
|
@@ -1242,10 +1249,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
|
Vec3 vec3d1 = this.collideScan(movement);
|
|
double d0 = vec3d1.lengthSqr();
|
|
|
|
- if (d0 > 1.0E-7D) {
|
|
+ if (d0 > 1.0E-7D || this.physics.before(1_14_0)) { // Sakura - physics version api
|
|
// NOTE: if there are any blocks in the future that rely on fall distance make sure this is correct.
|
|
// The only block I am aware of is powdered snow that has a special case for falling blocks.
|
|
- if (this.fallDistance != 0.0F && d0 >= 1.0D && !isFallingBlock) {
|
|
+ if (this.fallDistance != 0.0F && d0 >= 1.0D && !isFallingBlock && this.physics.afterOrEqual(1_18_2)) { // Sakura - physics version api
|
|
BlockHitResult movingobjectpositionblock = this.level().clip(new ClipContext(this.position(), this.position().add(vec3d1), ClipContext.Block.FALLDAMAGE_RESETTING, ClipContext.Fluid.WATER, this));
|
|
|
|
if (movingobjectpositionblock.getType() != HitResult.Type.MISS) {
|
|
@@ -1281,6 +1288,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
|
if (this.horizontalCollision) {
|
|
Vec3 vec3d2 = this.getDeltaMovement();
|
|
|
|
+ // Sakura start - physics version api
|
|
+ if (flag && flag1 && this.physics.isWithin(1_14_0, 1_18_1)) {
|
|
+ flag = false;
|
|
+ }
|
|
+ // Sakura end
|
|
+
|
|
this.setDeltaMovement(flag ? 0.0D : vec3d2.x, vec3d2.y, flag1 ? 0.0D : vec3d2.z);
|
|
}
|
|
|
|
@@ -1321,7 +1334,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
|
this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z);
|
|
} else {
|
|
this.wasOnFire = this.isOnFire();
|
|
- if (movementType == MoverType.PISTON) {
|
|
+ if (movementType == MoverType.PISTON && this.physics.afterOrEqual(1_11_0)) { // Sakura - physics version api
|
|
this.activatedTick = Math.max(this.activatedTick, MinecraftServer.currentTick + 20); // Paper
|
|
this.activatedImmunityTick = Math.max(this.activatedImmunityTick, MinecraftServer.currentTick + 20); // Paper
|
|
movement = this.limitPistonMovement(movement);
|
|
@@ -1348,8 +1361,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
|
Vec3 vec3d1 = this.collide(movement);
|
|
double d0 = vec3d1.lengthSqr();
|
|
|
|
- if (d0 > 1.0E-7D) {
|
|
- if (this.fallDistance != 0.0F && d0 >= 1.0D) {
|
|
+ if (d0 > 1.0E-7D || this.physics.before(1_14_0)) { // Sakura - physics version api
|
|
+ if (this.fallDistance != 0.0F && d0 >= 1.0D && this.physics.afterOrEqual(1_18_2)) { // Sakura - physics version api
|
|
BlockHitResult movingobjectpositionblock = this.level().clip(new ClipContext(this.position(), this.position().add(vec3d1), ClipContext.Block.FALLDAMAGE_RESETTING, ClipContext.Fluid.WATER, this));
|
|
|
|
if (movingobjectpositionblock.getType() != HitResult.Type.MISS) {
|
|
@@ -1385,6 +1398,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
|
if (this.horizontalCollision) {
|
|
Vec3 vec3d2 = this.getDeltaMovement();
|
|
|
|
+ // Sakura start - physics version api
|
|
+ if (flag && flag1 && this.physics.isWithin(1_14_0, 1_18_1)) {
|
|
+ flag = false;
|
|
+ }
|
|
+ // Sakura end
|
|
+
|
|
this.setDeltaMovement(flag ? 0.0D : vec3d2.x, vec3d2.y, flag1 ? 0.0D : vec3d2.z);
|
|
}
|
|
|
|
@@ -1708,7 +1727,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
|
double y = movement.y;
|
|
double z = movement.z;
|
|
|
|
- final boolean xSmaller = Math.abs(x) < Math.abs(z);
|
|
+ // Sakura start - physics version api
|
|
+ final boolean xSmaller = this.physics == null || this.physics.afterOrEqual(1_14_0) ? Math.abs(x) < Math.abs(z)
|
|
+ : this.physics.is(1_7_0) && Math.abs(x) > Math.abs(z);
|
|
+ // Sakura end
|
|
|
|
if (y != 0.0) {
|
|
y = scanY(currBoundingBox, y, voxelList, bbList);
|
|
@@ -1824,7 +1846,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
|
return movement;
|
|
}
|
|
|
|
- final Vec3 limitedMoveVector = io.papermc.paper.util.CollisionUtil.performCollisions(movement, currBoundingBox, potentialCollisionsVoxel, potentialCollisionsBB);
|
|
+ final Vec3 limitedMoveVector = io.papermc.paper.util.CollisionUtil.performCollisions(movement, currBoundingBox, potentialCollisionsVoxel, potentialCollisionsBB, this.physics); // Sakura - physics version api
|
|
|
|
if (stepHeight > 0.0
|
|
&& (onGround || (limitedMoveVector.y != movement.y && movement.y < 0.0))
|
|
@@ -1940,8 +1962,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S
|
|
|
|
protected void checkInsideBlocks() {
|
|
AABB axisalignedbb = this.getBoundingBox();
|
|
- BlockPos blockposition = BlockPos.containing(axisalignedbb.minX + 1.0E-7D, axisalignedbb.minY + 1.0E-7D, axisalignedbb.minZ + 1.0E-7D);
|
|
- BlockPos blockposition1 = BlockPos.containing(axisalignedbb.maxX - 1.0E-7D, axisalignedbb.maxY - 1.0E-7D, axisalignedbb.maxZ - 1.0E-7D);
|
|
+ // Sakura start - physics version
|
|
+ double offset = this.physics.afterOrEqual(1_19_3) ? 1.0E-7D : 0.001D;
|
|
+ BlockPos blockposition = BlockPos.containing(axisalignedbb.minX + offset, axisalignedbb.minY + offset, axisalignedbb.minZ + offset);
|
|
+ BlockPos blockposition1 = BlockPos.containing(axisalignedbb.maxX - offset, axisalignedbb.maxY - offset, axisalignedbb.maxZ - offset);
|
|
+ // Sakura end
|
|
|
|
if (this.level().hasChunksAt(blockposition, blockposition1)) {
|
|
BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
|
|
diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
|
index 6274c005f4f53f3cec0c94b7d40cdb7070b190e0..586c957d33a4ffbdc584267e1f10c8e5b37d6b0a 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
|
@@ -89,6 +89,8 @@ public class FallingBlockEntity extends Entity {
|
|
this.yo = y;
|
|
this.zo = z;
|
|
this.setStartPos(this.blockPosition());
|
|
+ this.physics = world.localConfig().config(this.blockPosition()).physicsVersion; // Sakura
|
|
+ this.eyeHeight = this.physics.isLegacy() ? 0.49f : this.eyeHeight; // Sakura
|
|
}
|
|
|
|
public static FallingBlockEntity fall(Level world, BlockPos pos, BlockState state) {
|
|
@@ -101,7 +103,11 @@ public class FallingBlockEntity extends Entity {
|
|
FallingBlockEntity entityfallingblock = new FallingBlockEntity(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, iblockdata.hasProperty(BlockStateProperties.WATERLOGGED) ? (BlockState) iblockdata.setValue(BlockStateProperties.WATERLOGGED, false) : iblockdata);
|
|
if (!CraftEventFactory.callEntityChangeBlockEvent(entityfallingblock, blockposition, iblockdata.getFluidState().createLegacyBlock())) return entityfallingblock; // CraftBukkit
|
|
|
|
- world.setBlock(blockposition, iblockdata.getFluidState().createLegacyBlock(), 3);
|
|
+ // Sakura start - physics version api
|
|
+ if (entityfallingblock.physics.afterOrEqual(1_18_2)) {
|
|
+ world.setBlock(blockposition, iblockdata.getFluidState().createLegacyBlock(), 3);
|
|
+ }
|
|
+ // Sakura end
|
|
world.addFreshEntity(entityfallingblock, spawnReason); // CraftBukkit
|
|
return entityfallingblock;
|
|
}
|
|
@@ -188,7 +194,44 @@ public class FallingBlockEntity extends Entity {
|
|
// Sakura start
|
|
@Override
|
|
public final double getEyeY() {
|
|
- return heightParity ? getY() : super.getEyeY();
|
|
+ return heightParity ? this.getY() : super.getEyeY();
|
|
+ }
|
|
+ // Sakura end
|
|
+ // Sakura start - physics version api
|
|
+ @Override
|
|
+ public double distanceToSqr(Vec3 vector) {
|
|
+ if (!this.physics.isLegacy())
|
|
+ return super.distanceToSqr(vector);
|
|
+ double x = this.getX() - vector.x;
|
|
+ double y = this.getEyeY() - vector.y;
|
|
+ double z = this.getZ() - vector.z;
|
|
+ return x * x + y * y + z * z;
|
|
+ }
|
|
+
|
|
+ private BlockPos patchedBlockPosition() {
|
|
+ // mitigate the floating point issue for sand breaking below y-0
|
|
+ // 1.0e-12 allows tech that uses indirect collision clipping to still function
|
|
+ return BlockPos.containing(this.getX(), this.getY() + 1.0e-12, this.getZ());
|
|
+ }
|
|
+
|
|
+ private boolean isAbleToStackOnBlock() {
|
|
+ BlockPos pos = BlockPos.containing(this.getX(), this.getY() - 0.001f, this.getZ());
|
|
+ BlockState state = this.level().getBlockState(pos);
|
|
+ return !FallingBlock.isFree(state);
|
|
+ }
|
|
+
|
|
+ private void removeBlockOnFall(Block block) {
|
|
+ BlockPos blockposition = this.blockPosition();
|
|
+ BlockState blockstate = this.level().getBlockState(blockposition);
|
|
+
|
|
+ if (blockstate.is(block) && CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, Blocks.AIR.defaultBlockState())) {
|
|
+ this.level().removeBlock(blockposition, false);
|
|
+ } else {
|
|
+ if (blockstate.is(block)) {
|
|
+ ((ServerLevel) level()).getChunkSource().blockChanged(blockposition);
|
|
+ }
|
|
+ this.discard();
|
|
+ }
|
|
}
|
|
// Sakura end
|
|
|
|
@@ -204,9 +247,16 @@ public class FallingBlockEntity extends Entity {
|
|
} else {
|
|
Block block = this.blockState.getBlock();
|
|
|
|
+ // Sakura start - physics version api
|
|
+ if (this.time == 0 && this.physics.before(1_18_2)) {
|
|
+ this.removeBlockOnFall(block);
|
|
+ }
|
|
+
|
|
++this.time;
|
|
if (!this.isNoGravity()) {
|
|
- this.addDeltaMovement(0.0D, -0.04D, 0.0D); // Sakura - reduce movement allocations
|
|
+ double gravity = this.physics.before(1_14_0) ? 0.04F : 0.04D;
|
|
+ this.addDeltaMovement(0.0D, -gravity, 0.0D); // Sakura - reduce movement allocations
|
|
+ // Sakura end
|
|
}
|
|
|
|
this.moveBasic(MoverType.SELF, this.getDeltaMovement()); // Sakura
|
|
@@ -227,8 +277,16 @@ public class FallingBlockEntity extends Entity {
|
|
return;
|
|
}
|
|
// Paper end
|
|
+ // Sakura start - physics version api
|
|
+ if (this.physics.before(1_12_0)) {
|
|
+ this.scaleDeltaMovement(0.98F);
|
|
+ }
|
|
if (!this.level().isClientSide) {
|
|
- BlockPos blockposition = this.blockPosition();
|
|
+ // Patching the floating point issue on modern versions can break some cannons that rely on it.
|
|
+ // However, it makes sense for legacy versions pre-1.17 before the world height change.
|
|
+ BlockPos blockposition = this.physics.before(1_17_0) ? this.patchedBlockPosition() : this.blockPosition();
|
|
+ // Sakura end
|
|
+
|
|
boolean flag = this.blockState.getBlock() instanceof ConcretePowderBlock;
|
|
boolean flag1 = flag && this.level().getFluidState(blockposition).is(FluidTags.WATER);
|
|
double d0 = this.getDeltaMovement().lengthSqr();
|
|
@@ -253,8 +311,11 @@ public class FallingBlockEntity extends Entity {
|
|
} else {
|
|
BlockState iblockdata = this.level().getBlockState(blockposition);
|
|
|
|
- this.multiplyDeltaMovement(0.7D, -0.5D, 0.7D); // Sakura - reduce movement allocations
|
|
- if (!iblockdata.is(Blocks.MOVING_PISTON)) {
|
|
+ // Sakura start - physics version api
|
|
+ double friction = this.physics.before(1_14_0) ? 0.7F : 0.7D;
|
|
+ this.multiplyDeltaMovement(friction, -0.5D, friction); // Sakura - reduce movement allocations
|
|
+ if (!iblockdata.is(Blocks.MOVING_PISTON) && (flag1 || !this.physics.isWithin(1_9_0, 1_12_0) || this.isAbleToStackOnBlock())) {
|
|
+ // Sakura end
|
|
if (!this.cancelDrop) {
|
|
boolean flag2 = iblockdata.canBeReplaced((BlockPlaceContext) (new DirectionalPlaceContext(this.level(), blockposition, Direction.DOWN, ItemStack.EMPTY, Direction.UP)));
|
|
boolean flag3 = FallingBlock.isFree(this.level().getBlockState(blockposition.below())) && (!flag || !flag1);
|
|
@@ -321,7 +382,12 @@ public class FallingBlockEntity extends Entity {
|
|
}
|
|
}
|
|
|
|
- this.scaleDeltaMovement(0.98D); // Sakura - reduce movement allocations
|
|
+ // Sakura start - physics version api
|
|
+ if (physics.afterOrEqual(1_12_0)) {
|
|
+ double drag = physics.before(1_14_0) ? 0.98F : 0.98D;
|
|
+ this.scaleDeltaMovement(drag); // Sakura - reduce movement allocations
|
|
+ }
|
|
+ // Sakura end
|
|
}
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
|
index 8ee03ac1c824fd2476339202c073239292ef62a2..5e588332f5916355293553012c73a647b1f4bd89 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
|
@@ -59,6 +59,13 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
|
case Y -> multiplyDeltaMovement(0, 1, 0);
|
|
}
|
|
// Sakura end
|
|
+ // Sakura start - physics version api
|
|
+ this.physics = world.localConfig().config(this.blockPosition()).physicsVersion;
|
|
+ this.eyeHeight = this.physics.isLegacy() ? 0.49f : this.eyeHeight;
|
|
+ if (this.physics.isLegacy()) {
|
|
+ multiplyDeltaMovement(0, 1, 0);
|
|
+ }
|
|
+ // Sakura end
|
|
}
|
|
|
|
@Override
|
|
@@ -129,12 +136,30 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
|
}
|
|
}
|
|
// Sakura end
|
|
+ // Sakura start - physics version api
|
|
+ @Override
|
|
+ public double getEyeY() {
|
|
+ return this.physics.isLegacy() ? super.getEyeY() : this.getY();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public double distanceToSqr(net.minecraft.world.phys.Vec3 vector) {
|
|
+ if (!this.physics.isLegacy())
|
|
+ return super.distanceToSqr(vector);
|
|
+ double x = this.getX() - vector.x;
|
|
+ double y = this.getEyeY() - vector.y;
|
|
+ double z = this.getZ() - vector.z;
|
|
+ return x * x + y * y + z * z;
|
|
+ }
|
|
+ // Sakura end
|
|
|
|
@Override
|
|
public void tick() {
|
|
// Sakura - remove max tnt per tick
|
|
if (!this.isNoGravity()) {
|
|
- this.addDeltaMovement(0.0D, -0.04D, 0.0D); // Sakura - reduce movement allocations
|
|
+ // Sakura start - physics version api
|
|
+ double gravity = this.physics.before(1_14_0) ? 0.04F : 0.04D;
|
|
+ this.addDeltaMovement(0.0D, -gravity, 0.0D); // Sakura - reduce movement allocations
|
|
}
|
|
|
|
this.moveBasic(MoverType.SELF, this.getDeltaMovement()); // Sakura
|
|
@@ -144,15 +169,18 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
|
return;
|
|
}
|
|
// Paper end
|
|
- this.scaleDeltaMovement(0.98D); // Sakura - reduce movement allocations
|
|
+ double drag = this.physics.before(1_14_0) ? 0.98F : 0.98D;
|
|
+ this.scaleDeltaMovement(drag); // Sakura - reduce movement allocations
|
|
if (this.onGround()) {
|
|
- this.multiplyDeltaMovement(0.7D, -0.5D, 0.7D); // Sakura - reduce movement allocations
|
|
+ double friction = this.physics.before(1_14_0) ? 0.7F : 0.7D;
|
|
+ this.multiplyDeltaMovement(friction, -0.5D, friction); // Sakura - reduce movement allocations
|
|
+ // Sakura end - physics version api
|
|
}
|
|
|
|
int i = this.getFuse() - 1;
|
|
|
|
this.setFuse(i);
|
|
- if (i <= 0) {
|
|
+ if (this.physics.before(1_9_0) ? (i < 0) : (i <= 0)) { // Sakura - physics version api
|
|
// CraftBukkit start - Need to reverse the order of the explosion and the entity death so we have a location for the event
|
|
// this.discard();
|
|
this.respawnMerged(); // Sakura
|
|
@@ -205,7 +233,10 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
|
ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent((org.bukkit.entity.Explosive)this.getBukkitEntity());
|
|
|
|
if (!event.isCancelled()) {
|
|
- this.level().explode(this, this.getX(), this.getY(0.0625D), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.TNT);
|
|
+ // Sakura start - physics version api
|
|
+ double pos = this.physics.before(1_10_0) ? this.getY() + (double) 0.49f : this.getY(0.0625D);
|
|
+ this.level().explode(this, this.getX(), pos, this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.TNT);
|
|
+ // Sakura end
|
|
}
|
|
// CraftBukkit end
|
|
}
|
|
@@ -274,7 +305,7 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
|
// Paper start - Optional prevent TNT from moving in water
|
|
@Override
|
|
public boolean isPushedByFluid() {
|
|
- return !level().paperConfig().fixes.preventTntFromMovingInWater && level().sakuraConfig().cannons.mechanics.tntFlowsInWater && super.isPushedByFluid(); // Sakura - convenience
|
|
+ return !level().paperConfig().fixes.preventTntFromMovingInWater && !this.physics.isLegacy() && level().sakuraConfig().cannons.mechanics.tntFlowsInWater && super.isPushedByFluid(); // Sakura - physics version // Sakura - convenience
|
|
}
|
|
// Paper end
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
|
|
index 5a10afb92fd62f433be9be6751e5222f3666c9f3..d92798d848754bb02f2de9ee91e1342ceb8e150c 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Explosion.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
|
|
@@ -74,6 +74,7 @@ public class Explosion {
|
|
public boolean wasCanceled = false;
|
|
public float yield;
|
|
// CraftBukkit end
|
|
+ protected final me.samsuik.sakura.physics.PhysicsVersion physics; // Sakura - physics version
|
|
|
|
public static DamageSource getDefaultDamageSource(Level world, @Nullable Entity source) {
|
|
return world.damageSources().explosion(source, Explosion.getIndirectSourceEntityInternal(source));
|
|
@@ -111,6 +112,7 @@ public class Explosion {
|
|
this.largeExplosionParticles = emitterParticle;
|
|
this.explosionSound = soundEvent;
|
|
this.yield = this.blockInteraction == Explosion.BlockInteraction.DESTROY_WITH_DECAY ? 1.0F / this.radius : 1.0F; // CraftBukkit
|
|
+ this.physics = entity != null ? entity.physics() : world.localConfig().config(BlockPos.containing(x, y, z)).physicsVersion; // Sakura
|
|
}
|
|
|
|
// Paper start - optimise collisions
|
|
@@ -489,9 +491,17 @@ public class Explosion {
|
|
Vec3 vec3d1 = new Vec3(d8 + d3, d9, d10 + d4);
|
|
|
|
// Sakura start
|
|
+ final net.minecraft.world.phys.HitResult.Type hitResult;
|
|
if (data != null && data.isExpandable() && data.has(vec3d1)) {
|
|
- i += (int) data.density();
|
|
- } else if (entity.level().clip(new ClipContext(vec3d1, source, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, entity)).getType() == HitResult.Type.MISS) {
|
|
+ hitResult = data.density() == 1.0 ? net.minecraft.world.phys.HitResult.Type.MISS : net.minecraft.world.phys.HitResult.Type.BLOCK;
|
|
+ } else {
|
|
+ if (entity.physics().afterOrEqual(1_14_0)) {
|
|
+ hitResult = entity.level().rayTrace(vec3d1, source);
|
|
+ } else {
|
|
+ hitResult = entity.level().clip(new ClipContext(vec3d1, source, entity.physics().afterOrEqual(1_16_0) ? ClipContext.Block.COLLIDER : ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, entity)).getType();
|
|
+ }
|
|
+ }
|
|
+ if (hitResult == net.minecraft.world.phys.HitResult.Type.MISS) {
|
|
// Sakura end
|
|
++i;
|
|
}
|
|
@@ -605,6 +615,10 @@ public class Explosion {
|
|
}
|
|
|
|
if (cachedBlock.outOfWorld) {
|
|
+ // Sakura start - physics version api
|
|
+ if (this.physics.before(1_17_0))
|
|
+ continue;
|
|
+ // Sakura end
|
|
break;
|
|
}
|
|
|
|
@@ -675,10 +689,17 @@ public class Explosion {
|
|
|
|
if (d7 <= 1.0D) {
|
|
double d8 = entity.getX() - this.x;
|
|
- double d9 = (entity instanceof PrimedTnt ? entity.getY() : entity.getEyeY()) - this.y;
|
|
+ double d9 = entity.getEyeY() - this.y; // Sakura - remove tnt special case
|
|
double d10 = entity.getZ() - this.z;
|
|
double d11 = Math.sqrt(d8 * d8 + d9 * d9 + d10 * d10);
|
|
|
|
+ // Sakura start
|
|
+ if (this.physics.before(1_17_0)) {
|
|
+ d7 = (float) d7;
|
|
+ d11 = (float) d11;
|
|
+ }
|
|
+ // Sakura end
|
|
+
|
|
if (d11 != 0.0D) {
|
|
d8 /= d11;
|
|
d9 /= d11;
|
|
@@ -986,7 +1007,14 @@ public class Explosion {
|
|
return data.density();
|
|
}
|
|
|
|
- float blockDensity = this.getSeenFraction(vec3d, entity, data, blockCache, blockPos); // Paper - optimise explosions;
|
|
+ // Sakura start - physics version api
|
|
+ final float blockDensity;
|
|
+ if (this.physics.afterOrEqual(1_16_0)) {
|
|
+ blockDensity = this.getSeenFraction(vec3d, entity, data, blockCache, blockPos); // Paper - optimise explosions;
|
|
+ } else {
|
|
+ blockDensity = this.getSeenPercent(vec3d, entity, data);
|
|
+ }
|
|
+ // Sakura end
|
|
|
|
if (data == null || !data.isExpandable() && (blockDensity == 0.0f || blockDensity == 1.0f)) {
|
|
level.densityCache.createCache(key, entity, vec3d, blockDensity);
|
|
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
|
index 09ff77ec8967645df0de253f6e8ee8cb6b998c0d..5afbdbd07afc671c3c6db491a713abfa467fffa3 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
|
@@ -274,6 +274,205 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
|
return this.getLimitedEntities(except, box, net.minecraft.world.entity.EntitySelector.NO_SPECTATORS, limit, search);
|
|
}
|
|
// Sakura end
|
|
+ // Sakura start - physics version
|
|
+ public net.minecraft.world.phys.BlockHitResult.Type rayTrace(net.minecraft.world.phys.Vec3 vec3d, net.minecraft.world.phys.Vec3 vec3d1) {
|
|
+ // May deviate from vanilla here; I remember noticing a bug and there's no fix commit.
|
|
+ int i = Mth.floor(vec3d1.x);
|
|
+ int j = Mth.floor(vec3d1.y);
|
|
+ int k = Mth.floor(vec3d1.z);
|
|
+ int l = Mth.floor(vec3d.x);
|
|
+ int i1 = Mth.floor(vec3d.y);
|
|
+ int j1 = Mth.floor(vec3d.z);
|
|
+ BlockPos.MutableBlockPos blockposition = new BlockPos.MutableBlockPos(l, i1, j1);
|
|
+ LevelChunk chunk = this.getChunkIfLoaded(l >> 4, j1 >> 4);
|
|
+
|
|
+ // probably a bad idea to copy this over so we don't need to do a null check
|
|
+ if (chunk == null) {
|
|
+ return net.minecraft.world.phys.BlockHitResult.Type.MISS;
|
|
+ }
|
|
+
|
|
+ BlockState iblockdata = chunk.getBlockState(blockposition);
|
|
+ net.minecraft.world.phys.shapes.VoxelShape shape = iblockdata.getShape(this, blockposition);
|
|
+
|
|
+ for (AABB bb : shape.toAabbs()) {
|
|
+ if (clip(bb, blockposition, vec3d, vec3d1)) {
|
|
+ return net.minecraft.world.phys.BlockHitResult.Type.BLOCK;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ int k1 = 200;
|
|
+
|
|
+ while (k1-- >= 0) {
|
|
+ if (l == i && i1 == j && j1 == k) {
|
|
+ return net.minecraft.world.phys.BlockHitResult.Type.MISS;
|
|
+ }
|
|
+
|
|
+ boolean flag3 = true;
|
|
+ boolean flag4 = true;
|
|
+ boolean flag5 = true;
|
|
+ double d0 = 999.0D;
|
|
+ double d1 = 999.0D;
|
|
+ double d2 = 999.0D;
|
|
+
|
|
+ if (i > l) {
|
|
+ d0 = (double) l + 1.0D;
|
|
+ } else if (i < l) {
|
|
+ d0 = (double) l + 0.0D;
|
|
+ } else {
|
|
+ flag3 = false;
|
|
+ }
|
|
+
|
|
+ if (j > i1) {
|
|
+ d1 = (double) i1 + 1.0D;
|
|
+ } else if (j < i1) {
|
|
+ d1 = (double) i1 + 0.0D;
|
|
+ } else {
|
|
+ flag4 = false;
|
|
+ }
|
|
+
|
|
+ if (k > j1) {
|
|
+ d2 = (double) j1 + 1.0D;
|
|
+ } else if (k < j1) {
|
|
+ d2 = (double) j1 + 0.0D;
|
|
+ } else {
|
|
+ flag5 = false;
|
|
+ }
|
|
+
|
|
+ double d3 = 999.0D;
|
|
+ double d4 = 999.0D;
|
|
+ double d5 = 999.0D;
|
|
+ double d6 = vec3d1.x - vec3d.x;
|
|
+ double d7 = vec3d1.y - vec3d.y;
|
|
+ double d8 = vec3d1.z - vec3d.z;
|
|
+
|
|
+ if (flag3) {
|
|
+ d3 = (d0 - vec3d.x) / d6;
|
|
+ }
|
|
+
|
|
+ if (flag4) {
|
|
+ d4 = (d1 - vec3d.y) / d7;
|
|
+ }
|
|
+
|
|
+ if (flag5) {
|
|
+ d5 = (d2 - vec3d.z) / d8;
|
|
+ }
|
|
+
|
|
+ if (d3 == -0.0D) {
|
|
+ d3 = -1.0E-4D;
|
|
+ }
|
|
+
|
|
+ if (d4 == -0.0D) {
|
|
+ d4 = -1.0E-4D;
|
|
+ }
|
|
+
|
|
+ if (d5 == -0.0D) {
|
|
+ d5 = -1.0E-4D;
|
|
+ }
|
|
+
|
|
+ Direction enumdirection;
|
|
+
|
|
+ if (d3 < d4 && d3 < d5) {
|
|
+ enumdirection = i > l ? Direction.WEST : Direction.EAST;
|
|
+ vec3d = new net.minecraft.world.phys.Vec3(d0, vec3d.y + d7 * d3, vec3d.z + d8 * d3);
|
|
+ } else if (d4 < d5) {
|
|
+ enumdirection = j > i1 ? Direction.DOWN : Direction.UP;
|
|
+ vec3d = new net.minecraft.world.phys.Vec3(vec3d.x + d6 * d4, d1, vec3d.z + d8 * d4);
|
|
+ } else {
|
|
+ enumdirection = k > j1 ? Direction.NORTH : Direction.SOUTH;
|
|
+ vec3d = new net.minecraft.world.phys.Vec3(vec3d.x + d6 * d5, vec3d.y + d7 * d5, d2);
|
|
+ }
|
|
+
|
|
+ l = Mth.floor(vec3d.x) - (enumdirection == Direction.EAST ? 1 : 0);
|
|
+ i1 = Mth.floor(vec3d.y) - (enumdirection == Direction.UP ? 1 : 0);
|
|
+ j1 = Mth.floor(vec3d.z) - (enumdirection == Direction.SOUTH ? 1 : 0);
|
|
+ blockposition.set(l, i1, j1);
|
|
+
|
|
+ int chunkX = l >> 4;
|
|
+ int chunkZ = j1 >> 4;
|
|
+
|
|
+ if (chunkX != chunk.locX || chunkZ != chunk.locZ) {
|
|
+ chunk = this.getChunkIfLoaded(chunkX, chunkZ);
|
|
+ }
|
|
+
|
|
+ if (chunk == null) {
|
|
+ return net.minecraft.world.phys.BlockHitResult.Type.MISS;
|
|
+ }
|
|
+
|
|
+ iblockdata = chunk.getBlockState(blockposition);
|
|
+ shape = iblockdata.getShape(this, blockposition);
|
|
+
|
|
+ for (AABB bb : shape.toAabbs()) {
|
|
+ if (clip(bb, blockposition, vec3d, vec3d1)) {
|
|
+ return net.minecraft.world.phys.BlockHitResult.Type.BLOCK;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return net.minecraft.world.phys.BlockHitResult.Type.MISS;
|
|
+ }
|
|
+
|
|
+ private boolean clip(AABB bb, BlockPos blockposition, net.minecraft.world.phys.Vec3 vec3d, net.minecraft.world.phys.Vec3 vec3d1) {
|
|
+ vec3d = vec3d.subtract(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
|
+ vec3d1 = vec3d1.subtract(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
|
+
|
|
+ double x = vec3d1.x - vec3d.x;
|
|
+ double y = vec3d1.y - vec3d.y;
|
|
+ double z = vec3d1.z - vec3d.z;
|
|
+
|
|
+ double minXd = clip(bb.minX, x, vec3d.x);
|
|
+ double minYd = clip(bb.minY, y, vec3d.y);
|
|
+ double minZd = clip(bb.minZ, z, vec3d.z);
|
|
+ double maxXd = clip(bb.maxX, x, vec3d.x);
|
|
+ double maxYd = clip(bb.maxY, y, vec3d.y);
|
|
+ double maxZd = clip(bb.maxZ, z, vec3d.z);
|
|
+
|
|
+ return clipX(vec3d, bb, minXd, y, z) || clipY(vec3d, bb, minYd, x, z) || clipZ(vec3d, bb, minZd, x, y)
|
|
+ || clipX(vec3d, bb, maxXd, y, z) || clipY(vec3d, bb, maxYd, x, z) || clipZ(vec3d, bb, maxZd, x, y);
|
|
+ }
|
|
+
|
|
+ private double clip(double bound, double axisD, double axisN) {
|
|
+ // This is my friend jerry, he was an epsilon. Unfortunately, once day
|
|
+ // he was cast to a float. Now he's spending his retirement here as a double.
|
|
+ if (axisD * axisD < 1.0000000116860974E-7D) {
|
|
+ return -1.0;
|
|
+ }
|
|
+
|
|
+ return (bound - axisN) / axisD;
|
|
+ }
|
|
+
|
|
+ private boolean clipX(net.minecraft.world.phys.Vec3 vec3d, AABB bb, double n, double y, double z) {
|
|
+ if (n < 0.0 || n > 1.0) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ y = vec3d.y + y * n;
|
|
+ z = vec3d.z + z * n;
|
|
+
|
|
+ return y >= bb.minY && y <= bb.maxY && z >= bb.minZ && z <= bb.maxZ;
|
|
+ }
|
|
+
|
|
+ private boolean clipY(net.minecraft.world.phys.Vec3 vec3d, AABB bb, double n, double x, double z) {
|
|
+ if (n < 0.0 || n > 1.0) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ x = vec3d.x + x * n;
|
|
+ z = vec3d.z + z * n;
|
|
+
|
|
+ return x >= bb.minX && x <= bb.maxX && z >= bb.minZ && z <= bb.maxZ;
|
|
+ }
|
|
+
|
|
+ private boolean clipZ(net.minecraft.world.phys.Vec3 vec3d, AABB bb, double n, double x, double y) {
|
|
+ if (n < 0.0 || n > 1.0) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ x = vec3d.x + x * n;
|
|
+ y = vec3d.y + y * n;
|
|
+
|
|
+ return x >= bb.minX && x <= bb.maxX && y >= bb.minY && y <= bb.maxY;
|
|
+ }
|
|
+ // Sakura end
|
|
|
|
protected Level(WritableLevelData worlddatamutable, ResourceKey<Level> resourcekey, RegistryAccess iregistrycustom, Holder<DimensionType> holder, Supplier<ProfilerFiller> supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function<org.spigotmc.SpigotWorldConfig, io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator, Supplier<me.samsuik.sakura.configuration.WorldConfiguration> sakuraWorldConfigCreator, java.util.concurrent.Executor executor) { // Sakura // Paper - Async-Anti-Xray - Pass executor
|
|
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/FallingBlock.java b/src/main/java/net/minecraft/world/level/block/FallingBlock.java
|
|
index 1079a99d6a6c9fba36414a863e1454bb2a7f298a..4ee105548df2a730f192d4b511a399d129824df6 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/FallingBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/FallingBlock.java
|
|
@@ -35,6 +35,15 @@ public abstract class FallingBlock extends Block implements Fallable {
|
|
return super.updateShape(state, direction, neighborState, world, pos, neighborPos);
|
|
}
|
|
|
|
+ // Sakura start - physics version api
|
|
+ @Override
|
|
+ public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean notify) {
|
|
+ if (world.localConfig().config(pos).physicsVersion.before(1_18_2)) {
|
|
+ world.scheduleTick(pos, this, this.getDelayAfterPlace());
|
|
+ }
|
|
+ }
|
|
+ // Sakura end
|
|
+
|
|
@Override
|
|
public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
|
if (isFree(world.getBlockState(pos.below())) && pos.getY() >= world.getMinBuildHeight()) {
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/FenceGateBlock.java b/src/main/java/net/minecraft/world/level/block/FenceGateBlock.java
|
|
index 6524272aab5a876e2a2164181da72c765959b550..4c242b501e7e5c7af6676b9554b00405838c4eb0 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/FenceGateBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/FenceGateBlock.java
|
|
@@ -180,8 +180,13 @@ public class FenceGateBlock extends HorizontalDirectionalBlock {
|
|
}
|
|
// CraftBukkit end
|
|
|
|
- if ((Boolean) state.getValue(FenceGateBlock.POWERED) != flag1) {
|
|
- world.setBlock(pos, (BlockState) ((BlockState) state.setValue(FenceGateBlock.POWERED, flag1)).setValue(FenceGateBlock.OPEN, flag1), 2);
|
|
+ // Sakura start
|
|
+ final boolean legacy = world.localConfig().config(pos).physicsVersion.before(1_11_0);
|
|
+ final boolean powered = state.getValue(FenceGateBlock.POWERED);
|
|
+ if (legacy ? (flag1 || sourceBlock.defaultBlockState().isSignalSource()) : powered != flag1) {
|
|
+ final boolean openGate = legacy && (flag1 == powered || state.getValue(FenceGateBlock.OPEN) != powered) ? state.getValue(OPEN) : flag1;
|
|
+ world.setBlock(pos, (BlockState) ((BlockState) state.setValue(FenceGateBlock.POWERED, flag1)).setValue(FenceGateBlock.OPEN, openGate), 2);
|
|
+ // Sakura end
|
|
if ((Boolean) state.getValue(FenceGateBlock.OPEN) != flag1) {
|
|
world.playSound((Player) null, pos, flag1 ? this.type.fenceGateOpen() : this.type.fenceGateClose(), SoundSource.BLOCKS, 1.0F, world.getRandom().nextFloat() * 0.1F + 0.9F);
|
|
world.gameEvent((Entity) null, flag1 ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, pos);
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/LadderBlock.java b/src/main/java/net/minecraft/world/level/block/LadderBlock.java
|
|
index de87b54895d5a63d32c1734ccdac63246c9f2c5f..79bced0e284430d57d4a7ec80a57d717249e7e36 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/LadderBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/LadderBlock.java
|
|
@@ -28,6 +28,21 @@ public class LadderBlock extends Block implements SimpleWaterloggedBlock {
|
|
protected static final VoxelShape WEST_AABB = Block.box(13.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D);
|
|
protected static final VoxelShape SOUTH_AABB = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 3.0D);
|
|
protected static final VoxelShape NORTH_AABB = Block.box(0.0D, 0.0D, 13.0D, 16.0D, 16.0D, 16.0D);
|
|
+ // Sakura start
|
|
+ protected static final VoxelShape LEGACY_EAST_AABB = Block.box(0.0D, 0.0D, 0.0D, 2.0D, 16.0D, 16.0D);
|
|
+ protected static final VoxelShape LEGACY_WEST_AABB = Block.box(14.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D);
|
|
+ protected static final VoxelShape LEGACY_SOUTH_AABB = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 2.0D);
|
|
+ protected static final VoxelShape LEGACY_NORTH_AABB = Block.box(0.0D, 0.0D, 14.0D, 16.0D, 16.0D, 16.0D);
|
|
+
|
|
+ private static VoxelShape legacyShape(Direction facing) {
|
|
+ return switch (facing) {
|
|
+ case NORTH -> LEGACY_NORTH_AABB;
|
|
+ case SOUTH -> LEGACY_SOUTH_AABB;
|
|
+ case WEST -> LEGACY_WEST_AABB;
|
|
+ default -> LEGACY_EAST_AABB;
|
|
+ };
|
|
+ }
|
|
+ // Sakura end
|
|
|
|
@Override
|
|
public MapCodec<LadderBlock> codec() {
|
|
@@ -39,8 +54,18 @@ public class LadderBlock extends Block implements SimpleWaterloggedBlock {
|
|
this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(WATERLOGGED, Boolean.valueOf(false)));
|
|
}
|
|
|
|
+ // Sakura start
|
|
+ @Override
|
|
+ public final boolean hasDynamicShape() {
|
|
+ return true;
|
|
+ }
|
|
+
|
|
@Override
|
|
public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
|
|
+ if (world instanceof net.minecraft.world.level.Level level && level.localConfig().config(pos).physicsVersion.before(1_9_0)) {
|
|
+ return legacyShape(state.getValue(FACING));
|
|
+ }
|
|
+ // Sakura end
|
|
switch ((Direction)state.getValue(FACING)) {
|
|
case NORTH:
|
|
return NORTH_AABB;
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
|
index 2bd097203f1e92d3fc343f91dc37220e09dd5066..2fe44dae063eb0cd7d4813fb6b2937830d432e51 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
|
@@ -192,8 +192,26 @@ public class LiquidBlock extends Block implements BucketPickup {
|
|
BlockPos blockposition1 = pos.relative(enumdirection.getOpposite());
|
|
|
|
if (world.getFluidState(blockposition1).is(FluidTags.WATER)) {
|
|
- Block block = world.getFluidState(pos).isSource() ? Blocks.OBSIDIAN : Blocks.COBBLESTONE;
|
|
-
|
|
+ // Sakura start
|
|
+ final FluidState fluidState = state.getFluidState();
|
|
+ final Block block;
|
|
+
|
|
+ if (fluidState.isSource()) {
|
|
+ block = Blocks.OBSIDIAN;
|
|
+ } else {
|
|
+ final me.samsuik.sakura.physics.PhysicsVersion physics = world.localConfig().config(pos).physicsVersion;
|
|
+
|
|
+ // SANITY: In legacy a patch by paper removes the fluid level condition from vanilla.
|
|
+ if (physics.afterOrEqual(1_16_0) || physics.isLegacy()
|
|
+ || physics.afterOrEqual(1_13_0) && fluidState.getHeight(world, pos) >= 0.44444445f
|
|
+ || physics.before(1_13_0) && FlowingFluid.getLegacyLevel(fluidState) <= 4
|
|
+ ) {
|
|
+ block = Blocks.COBBLESTONE;
|
|
+ } else {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ // Sakura end
|
|
// CraftBukkit start
|
|
if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world, pos, block.defaultBlockState())) {
|
|
this.fizz(world, pos);
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
|
|
index 82bde0e37971e806b19d17fbf48c663c82399739..570694ba570135542d4184ac9d03f29132b28df8 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
|
|
@@ -685,6 +685,10 @@ public class RedStoneWireBlock extends Block {
|
|
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
|
|
if (!player.getAbilities().mayBuild) {
|
|
return InteractionResult.PASS;
|
|
+ // Sakura start
|
|
+ } else if (world.localConfig().config(pos).physicsVersion.before(1_16_0)) {
|
|
+ return InteractionResult.PASS;
|
|
+ // Sakura end
|
|
} else {
|
|
if (RedStoneWireBlock.isCross(state) || RedStoneWireBlock.isDot(state)) {
|
|
BlockState iblockdata1 = RedStoneWireBlock.isCross(state) ? this.defaultBlockState() : this.crossState;
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java b/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java
|
|
index b6105d178778b326c11b7d29c5e4d8aa2c3a3875..7ff78fb671dc2791378802cda89c358eda15f2ae 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java
|
|
@@ -21,6 +21,7 @@ public class WaterlilyBlock extends BushBlock {
|
|
|
|
public static final MapCodec<WaterlilyBlock> CODEC = simpleCodec(WaterlilyBlock::new);
|
|
protected static final VoxelShape AABB = Block.box(1.0D, 0.0D, 1.0D, 15.0D, 1.5D, 15.0D);
|
|
+ protected static final VoxelShape LEGACY_AABB = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 0.25D, 16.0D); // Sakura
|
|
|
|
@Override
|
|
public MapCodec<WaterlilyBlock> codec() {
|
|
@@ -46,8 +47,18 @@ public class WaterlilyBlock extends BushBlock {
|
|
|
|
}
|
|
|
|
+ // Sakura start
|
|
+ @Override
|
|
+ public final boolean hasDynamicShape() {
|
|
+ return true;
|
|
+ }
|
|
+
|
|
@Override
|
|
public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
|
|
+ if (world instanceof net.minecraft.world.level.Level level && level.localConfig().config(pos).physicsVersion.before(1_9_0)) {
|
|
+ return LEGACY_AABB;
|
|
+ }
|
|
+ // Sakura end
|
|
return WaterlilyBlock.AABB;
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/piston/MovingPistonBlock.java b/src/main/java/net/minecraft/world/level/block/piston/MovingPistonBlock.java
|
|
index d3d1ad7901411574b85b0febd1c7ddaa8ad7c9f4..cc2c601032b2a2d94aa74cc3ad7169c202b354ab 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/piston/MovingPistonBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/piston/MovingPistonBlock.java
|
|
@@ -111,6 +111,17 @@ public class MovingPistonBlock extends BaseEntityBlock {
|
|
@Override
|
|
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
|
|
PistonMovingBlockEntity pistonMovingBlockEntity = this.getBlockEntity(world, pos);
|
|
+ // Sakura start - physics version api
|
|
+ if (pistonMovingBlockEntity != null && world instanceof Level level && level.localConfig().config(pos).physicsVersion.before(1_9_0)) {
|
|
+ VoxelShape shape = pistonMovingBlockEntity.getCollisionShapeFromProgress(level, pos);
|
|
+
|
|
+ if (context.isAbove(shape, pos, false)) {
|
|
+ return shape;
|
|
+ } else {
|
|
+ return pistonMovingBlockEntity.getMovedState().getCollisionShape(world, pos);
|
|
+ }
|
|
+ }
|
|
+ // Sakura end
|
|
return pistonMovingBlockEntity != null ? pistonMovingBlockEntity.getCollisionShape(world, pos) : Shapes.empty();
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
|
index b9025fcc6a4db9533cdc42034c9e77323d0785fa..fd7563a8b6ab8165c1ba7b4959a3bf9369d20e75 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
|
@@ -170,6 +170,11 @@ public class PistonBaseBlock extends DirectionalBlock {
|
|
// }
|
|
// PAIL: checkME - what happened to setTypeAndData?
|
|
// CraftBukkit end
|
|
+ // Sakura start - physics version api
|
|
+ if (world.localConfig().config(pos).physicsVersion.before(1_9_0)) {
|
|
+ world.setBlock(pos, state.setValue(PistonBaseBlock.EXTENDED, false), 18);
|
|
+ }
|
|
+ // Sakura end
|
|
world.blockEvent(pos, this, b0, enumdirection.get3DDataValue());
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonHeadBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonHeadBlock.java
|
|
index 5301095fa3baac1bde3767153ee2343026596688..1ef830d5e34f25c08d53d693db99a6eb641ebbe5 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonHeadBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonHeadBlock.java
|
|
@@ -139,6 +139,11 @@ public class PistonHeadBlock extends DirectionalBlock {
|
|
@Override
|
|
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
|
BlockState blockState = world.getBlockState(pos.relative(state.getValue(FACING).getOpposite()));
|
|
+ // Sakura start - physics version api
|
|
+ if (world instanceof Level level && level.localConfig().config(pos).physicsVersion.before(1_9_0)) {
|
|
+ return this.isFittingBase(state, blockState);
|
|
+ }
|
|
+ // Sakura end
|
|
return this.isFittingBase(state, blockState) || blockState.is(Blocks.MOVING_PISTON) && blockState.getValue(FACING) == state.getValue(FACING);
|
|
}
|
|
|
|
@@ -146,6 +151,10 @@ public class PistonHeadBlock extends DirectionalBlock {
|
|
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
|
|
if (state.canSurvive(world, pos)) {
|
|
world.neighborChanged(pos.relative(state.getValue(FACING).getOpposite()), sourceBlock, sourcePos);
|
|
+ // Sakura start - physics version api
|
|
+ } else if (world.localConfig().config(pos).physicsVersion.before(1_9_0)) {
|
|
+ world.setBlock(pos, Blocks.AIR.defaultBlockState(), 19);
|
|
+ // Sakura end
|
|
}
|
|
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
|
index a971bb30ef8620f016a5968a9da40187ee31a3ef..68bac9ea693f4457a8ced072cae85aef076eeb71 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
|
@@ -159,6 +159,13 @@ public class PistonMovingBlockEntity extends BlockEntity {
|
|
|
|
double i = 0.0D;
|
|
|
|
+ // Sakura start - physics version api
|
|
+ if (entity.physics().before(1_11_0)) {
|
|
+ moveEntityByPistonFromDirection(direction, entity, aABB);
|
|
+ return;
|
|
+ }
|
|
+ // Sakura end
|
|
+
|
|
for(AABB aABB2 : list2) {
|
|
AABB aABB3 = PistonMath.getMovementArea(moveByPositionAndProgress(pos, aABB2, blockEntity), direction, d);
|
|
AABB aABB4 = entity.getBoundingBox();
|
|
@@ -280,14 +287,154 @@ public class PistonMovingBlockEntity extends BlockEntity {
|
|
}
|
|
|
|
}
|
|
+
|
|
+ // Sakura start - physics version api
|
|
+ @javax.annotation.Nullable
|
|
+ private AABB getBoundsFromProgress(Level level, BlockPos pos, BlockState state, float progress, Direction dir, boolean absolute) {
|
|
+ if (!state.is(Blocks.MOVING_PISTON) && !state.isAir()) {
|
|
+ VoxelShape shape = this.movedState.getCollisionShape(level, pos);
|
|
+ // bounds on an empty shape causes an exception
|
|
+ if (shape.isEmpty()) return null;
|
|
+ if (absolute) shape = shape.move(pos.getX(), pos.getY(), pos.getZ());
|
|
+ AABB bounds = shape.bounds();
|
|
+
|
|
+ double minX = bounds.minX;
|
|
+ double minY = bounds.minY;
|
|
+ double minZ = bounds.minZ;
|
|
+ double maxX = bounds.maxX;
|
|
+ double maxY = bounds.maxY;
|
|
+ double maxZ = bounds.maxZ;
|
|
+
|
|
+ if (dir.getStepX() < 0) {
|
|
+ minX -= (float) dir.getStepX() * progress;
|
|
+ } else {
|
|
+ maxX -= (float) dir.getStepX() * progress;
|
|
+ }
|
|
+
|
|
+ if (dir.getStepY() < 0) {
|
|
+ minY -= (float) dir.getStepY() * progress;
|
|
+ } else {
|
|
+ maxY -= (float) dir.getStepY() * progress;
|
|
+ }
|
|
+
|
|
+ if (dir.getStepZ() < 0) {
|
|
+ minZ -= (float) dir.getStepZ() * progress;
|
|
+ } else {
|
|
+ maxZ -= (float) dir.getStepZ() * progress;
|
|
+ }
|
|
+
|
|
+ return new AABB(minX, minY, minZ, maxX, maxY, maxZ);
|
|
+ }
|
|
+
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ public VoxelShape getCollisionShapeFromProgress(Level level, BlockPos pos) {
|
|
+ float progress = this.getProgress(0.0f);
|
|
+
|
|
+ if (this.extending) {
|
|
+ progress = 1.0F - progress;
|
|
+ }
|
|
+
|
|
+ AABB bb = this.getBoundsFromProgress(level, pos, this.movedState, progress, this.direction, false);
|
|
+ // will never be null, but ide seems to think so hmm thinkge
|
|
+ return bb == null ? Shapes.empty() : Shapes.create(bb);
|
|
+ }
|
|
+
|
|
+ private void moveEntities(Level level, float f1) {
|
|
+ float f = this.progress;
|
|
+
|
|
+ if (this.extending) {
|
|
+ f = 1.0F - f;
|
|
+ } else {
|
|
+ --f;
|
|
+ }
|
|
+
|
|
+ AABB bb = this.getBoundsFromProgress(level, this.worldPosition, this.movedState, f, this.direction, true);
|
|
+
|
|
+ if (bb == null || bb.getSize() == 0.0) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ List<Entity> entities = level.getEntities(null, bb);
|
|
+
|
|
+ if (entities.isEmpty()) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ for (Entity entity : entities) {
|
|
+ if (this.movedState.is(Blocks.SLIME_BLOCK) && this.extending) {
|
|
+ Vec3 movement = entity.getDeltaMovement();
|
|
+ double x = movement.x;
|
|
+ double y = movement.y;
|
|
+ double z = movement.z;
|
|
+
|
|
+ switch (this.direction.getAxis()) {
|
|
+ case X -> x = direction.getStepX();
|
|
+ case Y -> y = direction.getStepY();
|
|
+ case Z -> z = direction.getStepZ();
|
|
+ }
|
|
+
|
|
+ entity.setDeltaMovement(x, y, z);
|
|
+ } else {
|
|
+ entity.move(MoverType.PISTON, new Vec3(f1 * (float) this.direction.getStepX(), f1 * (float) this.direction.getStepY(), f1 * (float) this.direction.getStepZ()));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static void moveEntityByPistonFromDirection(Direction direction, Entity entity, AABB blockBB) {
|
|
+ AABB entityBB = entity.getBoundingBox();
|
|
+ double movX = 0.0;
|
|
+ double movY = 0.0;
|
|
+ double movZ = 0.0;
|
|
+
|
|
+ switch (direction.getAxis()) {
|
|
+ case X -> {
|
|
+ if (direction.getAxisDirection() == Direction.AxisDirection.POSITIVE) {
|
|
+ movX = blockBB.maxX - entityBB.minX;
|
|
+ } else {
|
|
+ movX = entityBB.maxX - blockBB.minX;
|
|
+ }
|
|
+ movX += 0.01D;
|
|
+ }
|
|
+ case Y -> {
|
|
+ if (direction.getAxisDirection() == Direction.AxisDirection.POSITIVE) {
|
|
+ movY = blockBB.maxY - entityBB.minY;
|
|
+ } else {
|
|
+ movY = entityBB.maxY - blockBB.minY;
|
|
+ }
|
|
+ movY += 0.01D;
|
|
+ }
|
|
+ case Z -> {
|
|
+ if (direction.getAxisDirection() == Direction.AxisDirection.POSITIVE) {
|
|
+ movZ = blockBB.maxZ - entityBB.minZ;
|
|
+ } else {
|
|
+ movZ = entityBB.maxZ - blockBB.minZ;
|
|
+ }
|
|
+ movZ += 0.01D;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ entity.move(MoverType.PISTON, new Vec3(movX * direction.getStepX(), movY * direction.getStepY(), movZ * direction.getStepZ()));
|
|
+ }
|
|
+ // Sakura end
|
|
|
|
public static void tick(Level world, BlockPos pos, BlockState state, PistonMovingBlockEntity blockEntity) {
|
|
+ me.samsuik.sakura.physics.PhysicsVersion physicsVersion = world.localConfig().config(pos).physicsVersion; // Sakura
|
|
blockEntity.lastTicked = world.getGameTime();
|
|
blockEntity.progressO = blockEntity.progress;
|
|
if (blockEntity.progressO >= 1.0F) {
|
|
if (world.isClientSide && blockEntity.deathTicks < 5) {
|
|
++blockEntity.deathTicks;
|
|
} else {
|
|
+ // Sakura start - physics version api
|
|
+ if (physicsVersion.isWithin(1_9_0, 1_10_0)) {
|
|
+ moveCollidedEntities(world, pos, 1.0f, blockEntity);
|
|
+ moveStuckEntities(world, pos, 1.0f, blockEntity);
|
|
+ } else if (physicsVersion.before(1_9_0)) {
|
|
+ blockEntity.moveEntities(world, 0.25f);
|
|
+ }
|
|
+ // Sakura end
|
|
world.removeBlockEntity(pos);
|
|
blockEntity.setRemoved();
|
|
if (world.getBlockState(pos).is(Blocks.MOVING_PISTON)) {
|
|
@@ -308,13 +455,25 @@ public class PistonMovingBlockEntity extends BlockEntity {
|
|
}
|
|
} else {
|
|
float f = blockEntity.progress + 0.5F;
|
|
+ // Sakura start - physics version api
|
|
+ if (physicsVersion.afterOrEqual(1_11_0)) {
|
|
moveCollidedEntities(world, pos, f, blockEntity);
|
|
moveStuckEntities(world, pos, f, blockEntity);
|
|
+ }
|
|
+
|
|
blockEntity.progress = f;
|
|
if (blockEntity.progress >= 1.0F) {
|
|
blockEntity.progress = 1.0F;
|
|
}
|
|
|
|
+ if (physicsVersion.isWithin(1_9_0, 1_10_0)) {
|
|
+ moveCollidedEntities(world, pos, f, blockEntity);
|
|
+ moveStuckEntities(world, pos, f, blockEntity);
|
|
+ } else if (blockEntity.extending && physicsVersion.before(1_9_0)) {
|
|
+ blockEntity.moveEntities(world, blockEntity.progress - blockEntity.progressO + 0.0625f);
|
|
+ }
|
|
+ // Sakura end
|
|
+
|
|
}
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
|
|
index 6d59f8b68d644cb43939bcdf5239fa1caf54ed47..96ccad764cb6424ffe561c558cd11200d89ff541 100644
|
|
--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
|
|
+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
|
|
@@ -528,7 +528,7 @@ public abstract class FlowingFluid extends Fluid {
|
|
this.spread(world, pos, state);
|
|
}
|
|
|
|
- protected static int getLegacyLevel(FluidState state) {
|
|
+ public static int getLegacyLevel(FluidState state) { // Sakura - protected -> public
|
|
return state.isSource() ? 0 : 8 - Math.min(state.getAmount(), 8) + ((Boolean) state.getValue(FlowingFluid.FALLING) ? 8 : 0);
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/material/LavaFluid.java b/src/main/java/net/minecraft/world/level/material/LavaFluid.java
|
|
index c3f8e1e2dd89c168b8b4a15b589109db486bc8d7..1dab5318d8693d15ee879456dff3a1916cfad335 100644
|
|
--- a/src/main/java/net/minecraft/world/level/material/LavaFluid.java
|
|
+++ b/src/main/java/net/minecraft/world/level/material/LavaFluid.java
|
|
@@ -175,7 +175,10 @@ public abstract class LavaFluid extends FlowingFluid {
|
|
|
|
@Override
|
|
public boolean canBeReplacedWith(FluidState state, BlockGetter world, BlockPos pos, Fluid fluid, Direction direction) {
|
|
- return state.getHeight(world, pos) >= 0.44444445F && fluid.is(FluidTags.WATER);
|
|
+ // Sakura start
|
|
+ return state.getHeight(world, pos) >= 0.44444445F && fluid.is(FluidTags.WATER)
|
|
+ && world instanceof Level level && level.localConfig().config(pos).physicsVersion.afterOrEqual(1_13_0);
|
|
+ // Sakura end
|
|
}
|
|
|
|
@Override
|
|
diff --git a/src/main/java/net/minecraft/world/level/material/WaterFluid.java b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
|
|
index d280c98aed5262c4ce39526c917de884f25a8584..521b8084e490d5f3ecacd1d7368dddee22647aa9 100644
|
|
--- a/src/main/java/net/minecraft/world/level/material/WaterFluid.java
|
|
+++ b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
|
|
@@ -104,7 +104,10 @@ public abstract class WaterFluid extends FlowingFluid {
|
|
|
|
@Override
|
|
public boolean canBeReplacedWith(FluidState state, BlockGetter world, BlockPos pos, Fluid fluid, Direction direction) {
|
|
- return direction == Direction.DOWN && !fluid.is(FluidTags.WATER);
|
|
+ // Sakura start
|
|
+ return direction == Direction.DOWN && !fluid.is(FluidTags.WATER)
|
|
+ || fluid.is(FluidTags.LAVA) && world instanceof Level level && level.localConfig().config(pos).physicsVersion.before(1_13_0);
|
|
+ // Sakura end
|
|
}
|
|
|
|
@Override
|