mirror of
https://github.com/Samsuik/Sakura.git
synced 2025-12-23 08:49:25 +00:00
The player velocity was not being talied correctly, and velocity was not sent when explosion effects were disabled in fps settings.
1269 lines
66 KiB
Diff
1269 lines
66 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 86dee868320531e0fa076b6a78f3ea476c64b376..faadb4075bc1fddb7a55349907ee2b8c45ccd320 100644
|
|
--- a/src/main/java/io/papermc/paper/util/CollisionUtil.java
|
|
+++ b/src/main/java/io/papermc/paper/util/CollisionUtil.java
|
|
@@ -1457,7 +1457,15 @@ public final class CollisionUtil {
|
|
return new Vec3(x, y, z);
|
|
}
|
|
|
|
+ // Sakura start - physics version api
|
|
public static Vec3 performAABBCollisions(final Vec3 moveVector, AABB axisalignedbb, final List<AABB> potentialCollisions) {
|
|
+ return performAABBCollisions(moveVector, axisalignedbb, potentialCollisions, null);
|
|
+ }
|
|
+ public static Vec3 performAABBCollisions(final Vec3 moveVector,
|
|
+ AABB axisalignedbb,
|
|
+ final List<AABB> potentialCollisions,
|
|
+ final me.samsuik.sakura.physics.PhysicsVersion physics) {
|
|
+ // Sakura end - physics version api
|
|
double x = moveVector.x;
|
|
double y = moveVector.y;
|
|
double z = moveVector.z;
|
|
@@ -1469,7 +1477,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.isLegacy() && Math.abs(x) > Math.abs(z);
|
|
+ // Sakura end - physics version api
|
|
|
|
if (xSmaller && z != 0.0) {
|
|
z = performAABBCollisionsZ(axisalignedbb, z, potentialCollisions);
|
|
@@ -1495,9 +1506,17 @@ public final class CollisionUtil {
|
|
public static Vec3 performCollisions(final Vec3 moveVector, AABB axisalignedbb,
|
|
final List<VoxelShape> voxels,
|
|
final List<AABB> aabbs) {
|
|
+ // Sakura start - physics version api
|
|
+ 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) {
|
|
if (voxels.isEmpty()) {
|
|
// fast track only AABBs
|
|
- return performAABBCollisions(moveVector, axisalignedbb, aabbs);
|
|
+ return performAABBCollisions(moveVector, axisalignedbb, aabbs, physics);
|
|
+ // Sakura end - physics version api
|
|
}
|
|
|
|
double x = moveVector.x;
|
|
@@ -1512,7 +1531,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.isLegacy() && Math.abs(x) > Math.abs(z);
|
|
+ // Sakura end - physics version api
|
|
|
|
if (xSmaller && z != 0.0) {
|
|
z = performAABBCollisionsZ(axisalignedbb, z, aabbs);
|
|
diff --git a/src/main/java/me/samsuik/sakura/explosion/special/SpecialisedExplosion.java b/src/main/java/me/samsuik/sakura/explosion/special/SpecialisedExplosion.java
|
|
index ce676a021dd375959e9403b237bad864cd2b7da2..7d3431dc41246e4967bc11e5605611c78a3153bf 100644
|
|
--- a/src/main/java/me/samsuik/sakura/explosion/special/SpecialisedExplosion.java
|
|
+++ b/src/main/java/me/samsuik/sakura/explosion/special/SpecialisedExplosion.java
|
|
@@ -173,9 +173,15 @@ public abstract class SpecialisedExplosion<T extends Entity> extends Explosion {
|
|
|
|
if (distanceFromBottom <= 1.0) {
|
|
double x = entity.getX() - pos.x;
|
|
- double y = (entity instanceof PrimedTnt ? entity.getY() : entity.getEyeY()) - this.y;
|
|
+ double y = entity.getEyeY() - pos.y; // Sakura - physics version api
|
|
double z = entity.getZ() - pos.z;
|
|
double distance = Math.sqrt(x * x + y * y + z * z);
|
|
+ // Sakura start - physics version api
|
|
+ if (this.physics.before(1_17_0)) {
|
|
+ distanceFromBottom = (float) distanceFromBottom;
|
|
+ distance = (float) distance;
|
|
+ }
|
|
+ // Sakura end - physics version api
|
|
|
|
if (distance != 0.0D) {
|
|
x /= distance;
|
|
diff --git a/src/main/java/me/samsuik/sakura/explosion/special/TntExplosion.java b/src/main/java/me/samsuik/sakura/explosion/special/TntExplosion.java
|
|
index 6bcef992766b901db34494a4d359ba335705b689..f25cbe7a1b79a6ac346a665074dce3239127b181 100644
|
|
--- a/src/main/java/me/samsuik/sakura/explosion/special/TntExplosion.java
|
|
+++ b/src/main/java/me/samsuik/sakura/explosion/special/TntExplosion.java
|
|
@@ -37,6 +37,13 @@ public final class TntExplosion extends SpecialisedExplosion<PrimedTnt> {
|
|
this.bounds = new AABB(x, y, z, x, y, z);
|
|
}
|
|
|
|
+ // Sakura start - physics version api
|
|
+ @Override
|
|
+ protected double getExplosionOffset() {
|
|
+ return this.physics.before(1_10_0) ? (double) 0.49f : super.getExplosionOffset();
|
|
+ }
|
|
+ // Sakura end - physics version api
|
|
+
|
|
@Override
|
|
protected void startExplosion() {
|
|
for (int i = this.calculateExplosionPotential() - 1; i >= 0; --i) {
|
|
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
|
index 035071ff75fe682f3cdb8b7dbf17697beb7500c3..b336fe34b8d3e54dd300509812a6c4886105b299 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
|
@@ -381,7 +381,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
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;
|
|
@@ -719,6 +719,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
}
|
|
// Sakura end - cannon entity merging
|
|
public boolean pushedByFluid = true; // Sakura - entity pushed by fluid api
|
|
+ // Sakura start - physics version api
|
|
+ protected me.samsuik.sakura.physics.PhysicsVersion physics = me.samsuik.sakura.physics.PhysicsVersion.LATEST;
|
|
+
|
|
+ public final me.samsuik.sakura.physics.PhysicsVersion physics() {
|
|
+ return this.physics;
|
|
+ }
|
|
+ // Sakura end - physics version api
|
|
|
|
public Entity(EntityType<?> type, Level world) {
|
|
this.id = Entity.ENTITY_COUNTER.incrementAndGet();
|
|
@@ -1226,7 +1233,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
}
|
|
|
|
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);
|
|
@@ -1288,7 +1295,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
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;
|
|
@@ -1306,10 +1313,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
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) {
|
|
@@ -1345,6 +1352,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
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);
|
|
}
|
|
|
|
@@ -1386,7 +1399,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
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);
|
|
@@ -1413,8 +1426,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
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) {
|
|
@@ -1450,6 +1463,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
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);
|
|
}
|
|
|
|
@@ -1764,7 +1783,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
} else {
|
|
final AABB bb = currBoundingBox.expandTowards(movement.x, movement.y, movement.z);
|
|
collectCollisions(bb, potentialCollisionsVoxel, potentialCollisionsBB);
|
|
- return io.papermc.paper.util.CollisionUtil.performCollisions(movement, currBoundingBox, potentialCollisionsVoxel, potentialCollisionsBB);
|
|
+ return io.papermc.paper.util.CollisionUtil.performCollisions(movement, currBoundingBox, potentialCollisionsVoxel, potentialCollisionsBB, this.physics); // Sakura - physics version api
|
|
}
|
|
}
|
|
|
|
@@ -1773,7 +1792,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
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.isLegacy() && Math.abs(x) > Math.abs(z);
|
|
+ // Sakura end - physics version api
|
|
|
|
if (y != 0.0) {
|
|
y = scanY(currBoundingBox, y, voxelList, bbList);
|
|
@@ -1889,7 +1911,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
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))
|
|
@@ -2005,8 +2027,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
|
|
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 f682495067c1424bcf403e9e9b1f73e66f5e6c71..7500cd7647216d0101804d4442b1fd8b4c816aed 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
|
@@ -90,6 +90,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) {
|
|
@@ -102,7 +104,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;
|
|
}
|
|
@@ -191,13 +197,50 @@ 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 final 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(EntityRemoveEvent.Cause.DESPAWN);
|
|
+ }
|
|
+ }
|
|
+ // Sakura end - physics version api
|
|
|
|
@Override
|
|
protected double getDefaultGravity() {
|
|
- return 0.04D;
|
|
+ return this.physics.before(1_14_0) ? 0.04F : 0.04D; // Sakura - physics version api
|
|
}
|
|
|
|
@Override
|
|
@@ -207,6 +250,11 @@ 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);
|
|
+ }
|
|
+ // Sakura end - physics version api
|
|
++this.time;
|
|
this.applyGravity();
|
|
this.moveBasic(MoverType.SELF, this.getDeltaMovement()); // Sakura - optimise simple entity movement
|
|
@@ -220,8 +268,15 @@ public class FallingBlockEntity extends Entity {
|
|
return;
|
|
}
|
|
// Paper end - Configurable falling blocks height nerf
|
|
+ // 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 - physics version api
|
|
boolean flag = this.blockState.getBlock() instanceof ConcretePowderBlock;
|
|
boolean flag1 = flag && this.level().getFluidState(blockposition).is(FluidTags.WATER);
|
|
double d0 = this.getDeltaMovement().lengthSqr();
|
|
@@ -246,8 +301,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 - physics version api
|
|
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);
|
|
@@ -314,7 +372,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 - physics version api
|
|
}
|
|
}
|
|
|
|
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 df2a37e57012333a618937e61cb5a99c3ef4a0f9..62d40333c42f673479db5e6312343161aacf7078 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
|
@@ -58,6 +58,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 - physics version api
|
|
}
|
|
|
|
@Override
|
|
@@ -105,10 +112,26 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
|
}
|
|
}
|
|
// Sakura end
|
|
+ // Sakura start - physics version api
|
|
+ @Override
|
|
+ public final double getEyeY() {
|
|
+ return this.physics.isLegacy() ? super.getEyeY() : this.getY();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public final 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 - physics version api
|
|
|
|
@Override
|
|
protected double getDefaultGravity() {
|
|
- return 0.04D;
|
|
+ return this.physics.before(1_14_0) ? 0.04F : 0.04D; // Sakura - physics version api
|
|
}
|
|
|
|
@Override
|
|
@@ -122,15 +145,19 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
|
return;
|
|
}
|
|
// Paper end - Configurable TNT height nerf
|
|
- this.scaleDeltaMovement(0.98D); // Sakura - reduce movement allocations
|
|
+ // Sakura start - physics version api
|
|
+ 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
|
|
@@ -183,7 +210,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
|
|
}
|
|
@@ -237,7 +267,7 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
|
// Paper start - Option to 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 - Option to prevent TNT from moving in water
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
|
|
index d882b2b8b860932d648d54c6d1a1ca68597dde09..77f528bca7d8b4f17ec5319bc6f029111a2afae1 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Explosion.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
|
|
@@ -76,6 +76,7 @@ public class Explosion {
|
|
public float yield;
|
|
// CraftBukkit end
|
|
private final boolean consistentRadius; // Sakura - consistent explosion radius
|
|
+ protected final me.samsuik.sakura.physics.PhysicsVersion physics; // Sakura - physics version api
|
|
|
|
public static DamageSource getDefaultDamageSource(Level world, @Nullable Entity source) {
|
|
return world.damageSources().explosion(source, Explosion.getIndirectSourceEntityInternal(source));
|
|
@@ -114,6 +115,7 @@ public class Explosion {
|
|
this.explosionSound = soundEvent;
|
|
this.yield = this.blockInteraction == Explosion.BlockInteraction.DESTROY_WITH_DECAY ? 1.0F / this.radius : 1.0F; // CraftBukkit
|
|
this.consistentRadius = world.localConfig().config(BlockPos.containing(x, y, z)).consistentRadius; // Sakura - consistent explosion radius
|
|
+ this.physics = entity != null ? entity.physics() : world.localConfig().config(BlockPos.containing(x, y, z)).physicsVersion; // Sakura - physics version api
|
|
}
|
|
|
|
// Sakura start - optimise paper explosions
|
|
@@ -507,8 +509,12 @@ public class Explosion {
|
|
final float density = entity.level().densityCache.getKnownDensity(vec3d1);
|
|
if (density != me.samsuik.sakura.explosion.density.BlockDensityCache.UNKNOWN_DENSITY) {
|
|
hitResult = density != 0.0f ? net.minecraft.world.phys.HitResult.Type.MISS : net.minecraft.world.phys.HitResult.Type.BLOCK;
|
|
+ // Sakura start - physics version api
|
|
+ } else if (entity.physics().before(1_14_0)) {
|
|
+ hitResult = entity.level().rayTrace(vec3d1, source);
|
|
} else {
|
|
- hitResult = entity.level().clip(new ClipContext(vec3d1, source, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, entity)).getType();
|
|
+ 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();
|
|
+ // Sakura end - physics version api
|
|
}
|
|
if (hitResult == HitResult.Type.MISS) {
|
|
// Sakura end - replace density cache
|
|
@@ -613,6 +619,14 @@ public class Explosion {
|
|
}
|
|
|
|
if (cachedBlock.outOfWorld) {
|
|
+ // Sakura start - physics version api
|
|
+ if (this.physics.before(1_17_0)) {
|
|
+ d4 += d0;
|
|
+ d5 += d1;
|
|
+ d6 += d2;
|
|
+ continue;
|
|
+ }
|
|
+ // Sakura end - physics version api
|
|
break;
|
|
}
|
|
|
|
@@ -718,9 +732,15 @@ 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 - physics version api
|
|
double d10 = entity.getZ() - this.z;
|
|
double d11 = Math.sqrt(d8 * d8 + d9 * d9 + d10 * d10);
|
|
+ // Sakura start - physics version api
|
|
+ if (this.physics.before(1_17_0)) {
|
|
+ d7 = (float) d7;
|
|
+ d11 = (float) d11;
|
|
+ }
|
|
+ // Sakura end - physics version api
|
|
|
|
if (d11 != 0.0D) {
|
|
d8 /= d11;
|
|
@@ -1050,7 +1070,7 @@ public class Explosion {
|
|
// Sakura start - replace density cache
|
|
float blockDensity = this.level.densityCache.getDensity(vec3d, entity);
|
|
if (blockDensity == me.samsuik.sakura.explosion.density.BlockDensityCache.UNKNOWN_DENSITY) {
|
|
- blockDensity = this.getSeenFraction(vec3d, entity, blockCache, blockPos); // Paper - optimise explosions;
|
|
+ blockDensity = this.getSeenPercent(vec3d, entity, blockCache, blockPos); // Sakura - physics version api // Paper - optimise explosions;
|
|
this.level.densityCache.putDensity(vec3d, entity, blockDensity);
|
|
// Sakura end - replace density cache
|
|
}
|
|
@@ -1058,6 +1078,17 @@ public class Explosion {
|
|
return blockDensity;
|
|
}
|
|
|
|
+ // Sakura start - physics version api
|
|
+ private float getSeenPercent(Vec3 vec3d, Entity entity, ExplosionBlockCache[] blockCache, BlockPos.MutableBlockPos blockPos) {
|
|
+ if (this.physics.afterOrEqual(1_16_0)) {
|
|
+ // Papers impl is untouched, intended to be used as a fast path.
|
|
+ return this.getSeenFraction(vec3d, entity, blockCache, blockPos);
|
|
+ } else {
|
|
+ return getSeenPercent(vec3d, entity);
|
|
+ }
|
|
+ }
|
|
+ // Sakura end - physics version api
|
|
+
|
|
static class CacheKey {
|
|
private final Level world;
|
|
private final double posX, posY, posZ;
|
|
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
|
index ef37c34036bc79505786ee38ab5472a45effa4a3..6f7aa220d13a1135dde24012544bf3b978af7e50 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
|
@@ -255,6 +255,205 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
|
return this.getLimitedEntities(except, box, net.minecraft.world.entity.EntitySelector.NO_SPECTATORS, limit, search);
|
|
}
|
|
// Sakura end - add entity retrival methods with search limits
|
|
+ // Sakura start - physics version api
|
|
+ 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 - physics version api
|
|
|
|
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 - sakura configuration files // Paper - create paper world config; 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 1ea1232a5ba3e48eef3a139d6487c9a190155ebd..71364fe94cfeefa07fac3ee6359f7abd9bb58106 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
|
|
protected 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 79df73d352e7c72efb4b0b3ae567b60d19e2150e..7c434d7c55bec4ba1d6013109ed8fd769e8b12f0 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, (Holder) (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 4b402a7222f78617ef7d28d329f4daac74954347..54781ea0771327f93a7cf672bb4b2945700c47e5 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.0, 0.0, 0.0, 16.0, 16.0, 16.0);
|
|
protected static final VoxelShape SOUTH_AABB = Block.box(0.0, 0.0, 0.0, 16.0, 16.0, 3.0);
|
|
protected static final VoxelShape NORTH_AABB = Block.box(0.0, 0.0, 13.0, 16.0, 16.0, 16.0);
|
|
+ // Sakura start - physics version api
|
|
+ protected static final VoxelShape LEGACY_EAST_AABB = Block.box(0.0, 0.0, 0.0, 2.0, 16.0, 16.0);
|
|
+ protected static final VoxelShape LEGACY_WEST_AABB = Block.box(14.0, 0.0, 0.0, 16.0, 16.0, 16.0);
|
|
+ protected static final VoxelShape LEGACY_SOUTH_AABB = Block.box(0.0, 0.0, 0.0, 16.0, 16.0, 2.0);
|
|
+ protected static final VoxelShape LEGACY_NORTH_AABB = Block.box(0.0, 0.0, 14.0, 16.0, 16.0, 16.0);
|
|
+
|
|
+ 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 - physics version api
|
|
|
|
@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 - physics version api
|
|
+ @Override
|
|
+ public final boolean hasDynamicShape() {
|
|
+ return true;
|
|
+ }
|
|
+
|
|
@Override
|
|
protected 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 - physics version api
|
|
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 84623c632d8c2f0fa7ec939c711316d757117d23..baf791608420198493df24c68144fd29ec9fad7f 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
|
@@ -190,8 +190,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 88ddd1747d9786210e8faf412b3b0363df4bab43..a6f0ded367341e6b9f9c7b1c4254dd696ead2f8d 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java
|
|
@@ -699,6 +699,10 @@ public class RedStoneWireBlock extends Block {
|
|
protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, 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 932831bb5632ead5850842fc77192c841571162e..fdf07b8aa7a10da15a9473bcb12e8cb0404654f8 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
|
|
protected 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 f970fca8a8b479f2d2b927bcee2d73f02bfcd1b3..ff31e517a5f2eb51acef070d6455a0f86e40dd9f 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
|
|
@@ -110,6 +110,17 @@ public class MovingPistonBlock extends BaseEntityBlock {
|
|
@Override
|
|
protected 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 e0c62227b279a5fe0f3868fbf9ce8c78c515a09c..3f840b82827b803a5fc594f6008cddb09926ca2d 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
|
|
@@ -171,6 +171,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 bf58f33a5dc11b9e36cb9a26a73558c675a429df..755cbe2925fb5230fdff6c14b94dbafb924ba2c2 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
|
|
@@ -138,6 +138,11 @@ public class PistonHeadBlock extends DirectionalBlock {
|
|
@Override
|
|
protected 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);
|
|
}
|
|
|
|
@@ -145,6 +150,10 @@ public class PistonHeadBlock extends DirectionalBlock {
|
|
protected 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 d555ad1dd2f648b84920eceec6cc99e8801334b3..b2ecc615379856f661ba87bdeb28f75aa7d61602 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
|
|
@@ -164,6 +164,12 @@ public class PistonMovingBlockEntity extends BlockEntity {
|
|
|
|
double i = 0.0;
|
|
|
|
+ // Sakura start - physics version api
|
|
+ if (entity.physics().before(1_11_0)) {
|
|
+ moveEntityByPistonFromDirection(direction, entity, aABB);
|
|
+ return;
|
|
+ }
|
|
+ // Sakura end - physics version api
|
|
for (AABB aABB2 : list2) {
|
|
AABB aABB3 = PistonMath.getMovementArea(moveByPositionAndProgress(pos, aABB2, blockEntity), direction, d);
|
|
AABB aABB4 = entity.getBoundingBox();
|
|
@@ -293,14 +299,167 @@ 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 this.fixZeroWidthBB(new AABB(minX, minY, minZ, maxX, maxY, maxZ), dir);
|
|
+ }
|
|
+
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ private AABB fixZeroWidthBB(AABB bb, Direction dir) {
|
|
+ // Legacy behaviour relied on entities being able to collide with zero width shapes
|
|
+ // This is no longer possible, so we have to create a difference here for it to work
|
|
+ double expandX = bb.getXsize() == 0.0 ? 1.0e-5 * dir.getStepX() : 0;
|
|
+ double expandY = bb.getYsize() == 0.0 ? 1.0e-5 * dir.getStepY() : 0;
|
|
+ double expandZ = bb.getZsize() == 0.0 ? 1.0e-5 * dir.getStepZ() : 0;
|
|
+
|
|
+ if (expandX != 0 || expandY != 0 || expandZ != 0) {
|
|
+ bb = bb.expandTowards(expandX, expandY, expandZ);
|
|
+ }
|
|
+
|
|
+ return bb;
|
|
+ }
|
|
+
|
|
+ public final 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);
|
|
+ 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 - physics version api
|
|
|
|
public static void tick(Level world, BlockPos pos, BlockState state, PistonMovingBlockEntity blockEntity) {
|
|
+ me.samsuik.sakura.physics.PhysicsVersion physicsVersion = world.localConfig().config(pos).physicsVersion; // Sakura - physics version api
|
|
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 - physics version api
|
|
world.removeBlockEntity(pos);
|
|
blockEntity.setRemoved();
|
|
if (world.getBlockState(pos).is(Blocks.MOVING_PISTON)) {
|
|
@@ -320,12 +479,23 @@ 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 - physics version api
|
|
}
|
|
}
|
|
|
|
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 5ad6880845ed699077ad355ef1edcfb1c6c7bee4..e6acf6c4bcdb8d2548aa6a8b8d9af7c56877cfd4 100644
|
|
--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
|
|
+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
|
|
@@ -525,7 +525,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 3bb4a9a1a6249e8ba2de237f801210e7f4fd5825..8dfa05a586bd21ef8aeab713cad4628166982bfa 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 109f71401c65f476ccf6813137386fc9fef10254..786aba3810b71a543469dab6b2b2c1ff4ca2edd5 100644
|
|
--- a/src/main/java/net/minecraft/world/level/material/WaterFluid.java
|
|
+++ b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
|
|
@@ -120,7 +120,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
|