geforkt von Mirrors/Paper
c894ddfd38
Obscure detail in that if you teleport right on a chunk line, it adds +1 to your collision check and will check the unloaded neighbor. but the call to load the chunk then returned null if it was pending unload, such as the load we did in Player List However we want gen=true for players here anyways, so use getType
90 Zeilen
6.0 KiB
Diff
90 Zeilen
6.0 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
Date: Thu, 2 Apr 2020 02:37:57 -0400
|
|
Subject: [PATCH] Optimize Collision to not load chunks
|
|
|
|
The collision code takes an AABB and generates a cuboid of checks rather
|
|
than a cylinder, so at high velocity this can generate a lot of chunk checks.
|
|
|
|
Treat an unloaded chunk as a collision for entities, and also for players if
|
|
the "prevent moving into unloaded chunks" setting is enabled.
|
|
|
|
If that serting is not enabled, collisions will be ignored for players, since
|
|
movement will load only the chunk the player enters anyways and avoids loading
|
|
massive amounts of surrounding chunks due to large AABB lookups.
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java
|
|
index f851ed11df14fd9aa8017f44d82fb6cfc3bde345..948b86012bc604d3b1ba5a9e0c3b5b10ef529228 100644
|
|
--- a/src/main/java/net/minecraft/server/ICollisionAccess.java
|
|
+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
|
|
@@ -83,19 +83,33 @@ public interface ICollisionAccess extends IBlockAccess {
|
|
}
|
|
|
|
while (cursorposition.a()) {
|
|
- int k1 = cursorposition.b();
|
|
- int l1 = cursorposition.c();
|
|
- int i2 = cursorposition.d();
|
|
+ int k1 = cursorposition.b();int x = k1; // Paper
|
|
+ int l1 = cursorposition.c();int y = l1; // Paper
|
|
+ int i2 = cursorposition.d();int z = i2; // Paper
|
|
int j2 = cursorposition.e();
|
|
|
|
if (j2 != 3) {
|
|
- int k2 = k1 >> 4;
|
|
- int l2 = i2 >> 4;
|
|
- IBlockAccess iblockaccess = ICollisionAccess.this.c(k2, l2);
|
|
-
|
|
- if (iblockaccess != null) {
|
|
- blockposition_mutableblockposition.d(k1, l1, i2);
|
|
- IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition);
|
|
+ // Paper start - ensure we don't load chunks
|
|
+ //int k2 = k1 >> 4;
|
|
+ //int l2 = i2 >> 4;
|
|
+ boolean far = entity != null && MCUtil.distanceSq(entity.locX(), y, entity.locZ(), x, y, z) > 8;
|
|
+ blockposition_mutableblockposition.setValues(x, y, z);
|
|
+
|
|
+ boolean isRegionLimited = ICollisionAccess.this instanceof RegionLimitedWorldAccess;
|
|
+ IBlockData iblockdata = isRegionLimited ? Blocks.VOID_AIR.getBlockData() : (!far && entity instanceof EntityPlayer
|
|
+ ? ICollisionAccess.this.getType(blockposition_mutableblockposition)
|
|
+ : ICollisionAccess.this.getTypeIfLoaded(blockposition_mutableblockposition)
|
|
+ );
|
|
+ if (iblockdata == null) {
|
|
+ if (!(entity instanceof EntityPlayer) || entity.world.paperConfig.preventMovingIntoUnloadedChunks) {
|
|
+ VoxelShape voxelshape3 = VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z)));
|
|
+ consumer.accept(voxelshape3);
|
|
+ return true;
|
|
+ }
|
|
+ } else {
|
|
+ //blockposition_mutableblockposition.d(k1, l1, i2); // moved up
|
|
+ //IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); // moved up
|
|
+ // Paper end
|
|
|
|
if ((j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) {
|
|
VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) ICollisionAccess.this, blockposition_mutableblockposition, voxelshapecollision);
|
|
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
|
|
index 909d86e14c7860cd6d8a6f38ef4aedb183acae3f..fddd92677db06aa9fc41437f34719d9ae6e44c93 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerList.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerList.java
|
|
@@ -677,6 +677,7 @@ public abstract class PlayerList {
|
|
entityplayer1.forceSetPositionRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
|
// CraftBukkit end
|
|
|
|
+ location.getChunk(); // Paper - force load chunk to be sure getCubes works
|
|
while (avoidSuffocation && !worldserver.getCubes(entityplayer1) && entityplayer1.locY() < 256.0D) {
|
|
entityplayer1.setPosition(entityplayer1.locX(), entityplayer1.locY() + 1.0D, entityplayer1.locZ());
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/VoxelShapes.java b/src/main/java/net/minecraft/server/VoxelShapes.java
|
|
index 335142ec0dfad822cfe40877e99dec0f307e1a58..e641d4b8d8b4ac5d539e6d9c0eaf345601e0b499 100644
|
|
--- a/src/main/java/net/minecraft/server/VoxelShapes.java
|
|
+++ b/src/main/java/net/minecraft/server/VoxelShapes.java
|
|
@@ -239,7 +239,8 @@ public final class VoxelShapes {
|
|
|
|
if (k2 < 3) {
|
|
blockposition_mutableblockposition.a(enumaxiscycle1, i2, j2, l1);
|
|
- IBlockData iblockdata = iworldreader.getType(blockposition_mutableblockposition);
|
|
+ IBlockData iblockdata = iworldreader.getTypeIfLoaded(blockposition_mutableblockposition); // Paper
|
|
+ if (iblockdata == null) return 0.0D; // Paper
|
|
|
|
if ((k2 != 1 || iblockdata.f()) && (k2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) {
|
|
d0 = iblockdata.b((IBlockAccess) iworldreader, blockposition_mutableblockposition, voxelshapecollision).a(enumdirection_enumaxis2, axisalignedbb.d((double) (-blockposition_mutableblockposition.getX()), (double) (-blockposition_mutableblockposition.getY()), (double) (-blockposition_mutableblockposition.getZ())), d0);
|