mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-18 20:53:09 +01:00
c6aa61ee18
Updated Upstream (Bukkit/CraftBukkit/Spigot) Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: b9df8e9f SPIGOT-7933: Improve custom Minecart max speed fc496179 Fix InstrumentTest 7c0ec598 PR-1075: Make Art an interface c389f5a4 PR-1074: Make Sound an interface CraftBukkit Changes: df1efc0bb SPIGOT-7945: `Bukkit#dispatchCommand` throws `UnsupportedOperationException` 285df6e85 SPIGOT-7933: Improve custom Minecart max speed a0f3d4e50 SPIGOT-7940: Recipe book errors after reload 9e0618ec2 SPIGOT-7937: Cannot spawn minecart during world generation with minecart_improvements enabled 1eb4d28da SPIGOT-7941: Fix resistance over 4 amplify causing issues in damage 52b99158a PR-1504: Make Art an interface e18ae35f1 PR-1502: Make Sound an interface Spigot Changes: e65d67a7 SPIGOT-7934: Item entities start "bouncing" under certain conditions
108 lines
7.2 KiB
Diff
108 lines
7.2 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/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
index 3e03d65ac4ef267de67684d24c6f9c303b1a0bf0..b451842d6848af883cc3abf200f03c9a4680106c 100644
|
|
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
@@ -826,6 +826,7 @@ public abstract class PlayerList {
|
|
Vec3 vec3d = teleporttransition.position();
|
|
|
|
entityplayer1.forceSetPositionRotation(vec3d.x, vec3d.y, vec3d.z, teleporttransition.yRot(), teleporttransition.xRot());
|
|
+ worldserver.getChunkSource().addRegionTicket(net.minecraft.server.level.TicketType.POST_TELEPORT, new net.minecraft.world.level.ChunkPos(net.minecraft.util.Mth.floor(vec3d.x()) >> 4, net.minecraft.util.Mth.floor(vec3d.z()) >> 4), 1, entityplayer.getId()); // Paper
|
|
// CraftBukkit end
|
|
if (teleporttransition.missingRespawnBlock()) {
|
|
entityplayer1.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F));
|
|
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
|
index 72dbee3795eb634b3ff3f063a226a1965bc988fb..430addbb5c3d84f4354a89a9ec8fa15bca4d2a60 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
|
@@ -259,6 +259,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
// Paper end - Share random for entities to make them more random
|
|
public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason
|
|
|
|
+ public boolean collisionLoadChunks = false; // Paper
|
|
private CraftEntity bukkitEntity;
|
|
|
|
public CraftEntity getBukkitEntity() {
|
|
diff --git a/src/main/java/net/minecraft/world/level/BlockCollisions.java b/src/main/java/net/minecraft/world/level/BlockCollisions.java
|
|
index 12a14b8fdb079fd8c367e51299486761ebdaeb5b..b360594424118d9d11d00ea140160485048591ca 100644
|
|
--- a/src/main/java/net/minecraft/world/level/BlockCollisions.java
|
|
+++ b/src/main/java/net/minecraft/world/level/BlockCollisions.java
|
|
@@ -72,16 +72,37 @@ public class BlockCollisions<T> extends AbstractIterator<T> {
|
|
@Override
|
|
protected T computeNext() {
|
|
while (this.cursor.advance()) {
|
|
- int i = this.cursor.nextX();
|
|
- int j = this.cursor.nextY();
|
|
- int k = this.cursor.nextZ();
|
|
+ int i = this.cursor.nextX(); final int x = i; // Paper - OBFHELPER
|
|
+ int j = this.cursor.nextY(); final int y = j; // Paper - OBFHELPER
|
|
+ int k = this.cursor.nextZ(); final int z = k; // Paper - OBFHELPER
|
|
int l = this.cursor.getNextType();
|
|
if (l != 3) {
|
|
- BlockGetter blockGetter = this.getChunk(i, k);
|
|
- if (blockGetter != null) {
|
|
- this.pos.set(i, j, k);
|
|
- BlockState blockState = blockGetter.getBlockState(this.pos);
|
|
- if ((!this.onlySuffocatingBlocks || blockState.isSuffocating(blockGetter, this.pos))
|
|
+ // Paper start - ensure we don't load chunks
|
|
+ // BlockGetter blockGetter = this.getChunk(i, k);
|
|
+ if (true) {
|
|
+ final @Nullable Entity source = this.context instanceof net.minecraft.world.phys.shapes.EntityCollisionContext entityContext ? entityContext.getEntity() : null;
|
|
+ boolean far = source != null && io.papermc.paper.util.MCUtil.distanceSq(source.getX(), y, source.getZ(), x, y, z) > 14;
|
|
+ this.pos.set(x, y, z);
|
|
+ BlockState blockState;
|
|
+ if (this.collisionGetter instanceof net.minecraft.server.level.WorldGenRegion) {
|
|
+ BlockGetter blockGetter = this.getChunk(x, z);
|
|
+ if (blockGetter == null) {
|
|
+ continue;
|
|
+ }
|
|
+ blockState = blockGetter.getBlockState(this.pos);
|
|
+ } else if ((!far && source instanceof net.minecraft.server.level.ServerPlayer) || (source != null && source.collisionLoadChunks)) {
|
|
+ blockState = this.collisionGetter.getBlockState(this.pos);
|
|
+ } else {
|
|
+ blockState = this.collisionGetter.getBlockStateIfLoaded(this.pos);
|
|
+ }
|
|
+ if (blockState == null) {
|
|
+ if (!(source instanceof net.minecraft.server.level.ServerPlayer) || source.level().paperConfig().chunks.preventMovingIntoUnloadedChunks) {
|
|
+ return this.resultProvider.apply(new BlockPos.MutableBlockPos(x, y, z), Shapes.create(far ? source.getBoundingBox() : new AABB(new BlockPos(x, y, z))));
|
|
+ }
|
|
+ continue;
|
|
+ }
|
|
+ if (true // onlySuffocatingBlocks is only true on the client, so we don't care about it here
|
|
+ // Paper end - ensure we don't load chunks
|
|
&& (l != 1 || blockState.hasLargeCollisionShape())
|
|
&& (l != 2 || blockState.is(Blocks.MOVING_PISTON))) {
|
|
VoxelShape voxelShape = this.context.getCollisionShape(blockState, this.collisionGetter, this.pos);
|
|
diff --git a/src/main/java/net/minecraft/world/level/CollisionGetter.java b/src/main/java/net/minecraft/world/level/CollisionGetter.java
|
|
index 6b63dc10c0a4db8a484588a6d67911ea1023457e..f4c251c2bcfa96ba22e338b97a1de7f0abac5a6f 100644
|
|
--- a/src/main/java/net/minecraft/world/level/CollisionGetter.java
|
|
+++ b/src/main/java/net/minecraft/world/level/CollisionGetter.java
|
|
@@ -50,11 +50,13 @@ public interface CollisionGetter extends BlockGetter {
|
|
}
|
|
|
|
default boolean noCollision(@Nullable Entity entity, AABB box, boolean checkFluid) {
|
|
- for (VoxelShape voxelShape : checkFluid ? this.getBlockAndLiquidCollisions(entity, box) : this.getBlockCollisions(entity, box)) {
|
|
+ try { if (entity != null) entity.collisionLoadChunks = true; // Paper
|
|
+ for (VoxelShape voxelShape : checkFluid ? this.getBlockAndLiquidCollisions(entity, box) : this.getBlockCollisions(entity, box)) {
|
|
if (!voxelShape.isEmpty()) {
|
|
return false;
|
|
}
|
|
}
|
|
+ } finally { if (entity != null) entity.collisionLoadChunks = false; } // Paper
|
|
|
|
if (!this.getEntityCollisions(entity, box).isEmpty()) {
|
|
return false;
|