Current non compilable status of all patches - THIS IS NOT READY
THERE IS STILL NO ETA. GOBLINS WILL EAT YOU.
This commit is contained in:
parent
939690baea
commit
014b7f115d
171 changed files with 814 additions and 1122 deletions
|
@ -0,0 +1,101 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: JellySquid <jellysquid+atwork@protonmail.com>
|
||||
Date: Sat, 9 May 2020 16:25:21 -0400
|
||||
Subject: [PATCH] Implement JellySquid's Entity Collision optimisations patch
|
||||
|
||||
Optimizes Full Block voxel collisions, and removes streams from Entity collisions
|
||||
|
||||
Original code by JellySquid, licensed under GNU Lesser General Public License v3.0
|
||||
you can find the original code on https://github.com/jellysquid3/lithium-fabric/tree/1.15.x/fabric (Yarn mappings)
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java
|
||||
index 3eefbf4d5f10b53f930759a0afa5661253b92c60..5e20dba0d011d20b714d784cb4a545a05bbf6f9c 100644
|
||||
--- a/src/main/java/net/minecraft/server/ICollisionAccess.java
|
||||
+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
|
||||
@@ -115,11 +115,24 @@ public interface ICollisionAccess extends IBlockAccess {
|
||||
|
||||
if ((j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) {
|
||||
VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) ICollisionAccess.this, blockposition_mutableblockposition, voxelshapecollision);
|
||||
- VoxelShape voxelshape3 = voxelshape2.a((double) k1, (double) l1, (double) i2);
|
||||
|
||||
- if (VoxelShapes.c(voxelshape, voxelshape3, OperatorBoolean.AND)) {
|
||||
- consumer.accept(voxelshape3);
|
||||
- return true;
|
||||
+ // Paper start - Lithium Collision Optimizations
|
||||
+ if (voxelshape2 == VoxelShapes.empty()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (voxelshape2 == VoxelShapes.fullCube()) {
|
||||
+ if (axisalignedbb.intersects(x, y, z, x + 1.0D, y + 1.0D, z + 1.0D)) {
|
||||
+ consumer.accept(voxelshape2.offset(x, y, z));
|
||||
+ return true;
|
||||
+ }
|
||||
+ } else {
|
||||
+ VoxelShape shape = voxelshape2.offset(x, y, z);
|
||||
+ if (VoxelShapes.applyOperation(shape, voxelshape, OperatorBoolean.AND)) {
|
||||
+ consumer.accept(shape);
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java
|
||||
index 5135308fb6137a34ed6fd061f0a210de6de4e81c..d434aaaaf0ab6a18ab0fe5ad0bf8ed4662f49120 100644
|
||||
--- a/src/main/java/net/minecraft/server/IEntityAccess.java
|
||||
+++ b/src/main/java/net/minecraft/server/IEntityAccess.java
|
||||
@@ -52,20 +52,41 @@ public interface IEntityAccess {
|
||||
// Paper end - optimise hard collision
|
||||
|
||||
default Stream<VoxelShape> b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
|
||||
- if (axisalignedbb.a() < 1.0E-7D) {
|
||||
+ // Paper start - remove streams from entity collision
|
||||
+ if (axisalignedbb.getAverageSideLength() < 1.0E-7D) {
|
||||
return Stream.empty();
|
||||
- } else {
|
||||
- AxisAlignedBB axisalignedbb1 = axisalignedbb.g(1.0E-7D);
|
||||
- Stream<AxisAlignedBB> stream = ((entity != null && entity.hardCollides()) ? this.getEntities(entity, axisalignedbb) : this.getHardCollidingEntities(entity, axisalignedbb1)).stream().filter((entity1) -> { // Paper - decompile fix // Paper - optimise hard collision
|
||||
- return !set.contains(entity1);
|
||||
- }).filter((entity1) -> {
|
||||
- return entity == null || !entity.isSameVehicle(entity1);
|
||||
- }).flatMap((entity1) -> {
|
||||
- return Stream.of(entity1.au(), entity == null ? null : entity.j(entity1)); // Paper - optimise hard collision - diff on change, these are the methods that only hard colliding entities override
|
||||
- }).filter(Objects::nonNull);
|
||||
-
|
||||
- return stream.filter(axisalignedbb1::c).map(VoxelShapes::a);
|
||||
+
|
||||
}
|
||||
+ AxisAlignedBB selection = axisalignedbb.grow(1.0E-7D);
|
||||
+ List<Entity> entities = entity != null && entity.hardCollides() ? getEntities(entity, selection) : getHardCollidingEntities(entity, selection);
|
||||
+ List<VoxelShape> shapes = new java.util.ArrayList<>();
|
||||
+
|
||||
+ for (Entity otherEntity : entities) {
|
||||
+ if (!set.isEmpty() && set.contains(otherEntity)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (entity != null && entity.isSameVehicle(otherEntity)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ AxisAlignedBB otherEntityBox = otherEntity.getCollisionBox();
|
||||
+
|
||||
+ if (otherEntityBox != null && selection.intersects(otherEntityBox)) {
|
||||
+ shapes.add(VoxelShapes.of(otherEntityBox));
|
||||
+ }
|
||||
+
|
||||
+ if (entity != null) {
|
||||
+ AxisAlignedBB otherEntityHardBox = entity.getHardCollisionBox(otherEntity);
|
||||
+
|
||||
+ if (otherEntityHardBox != null && selection.intersects(otherEntityHardBox)) {
|
||||
+ shapes.add(VoxelShapes.of(otherEntityHardBox));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return shapes.stream();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Nullable
|
|
@ -0,0 +1,178 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 9 May 2020 18:36:27 -0400
|
||||
Subject: [PATCH] Remove some Streams usage in Entity Collision
|
||||
|
||||
While there is more down the collision system, remove some of the wrapping
|
||||
Spliterator stuff as even this wrapper stream has shown up in profiling.
|
||||
|
||||
With other collision optimizations, we might also even avoid inner streams too.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/GeneratorAccess.java b/src/main/java/net/minecraft/server/GeneratorAccess.java
|
||||
index e865a5694f78fb9273a0625ab2c30b87d0711a90..5648ba73c533f622c35c808decdb305f8a1cf6b0 100644
|
||||
--- a/src/main/java/net/minecraft/server/GeneratorAccess.java
|
||||
+++ b/src/main/java/net/minecraft/server/GeneratorAccess.java
|
||||
@@ -52,6 +52,7 @@ public interface GeneratorAccess extends IEntityAccess, IWorldReader, VirtualLev
|
||||
this.a((EntityHuman) null, i, blockposition, j);
|
||||
}
|
||||
|
||||
+ @Override default java.util.List<VoxelShape> getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set, boolean returnFast) {return IEntityAccess.super.getEntityCollisions(entity, axisalignedbb, set, returnFast); } // Paper
|
||||
@Override
|
||||
default Stream<VoxelShape> b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
|
||||
return IEntityAccess.super.b(entity, axisalignedbb, set);
|
||||
diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java
|
||||
index 5e20dba0d011d20b714d784cb4a545a05bbf6f9c..5a21205a49606b294de4cd27b60438c6a5b3c526 100644
|
||||
--- a/src/main/java/net/minecraft/server/ICollisionAccess.java
|
||||
+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
|
||||
@@ -44,19 +44,40 @@ public interface ICollisionAccess extends IBlockAccess {
|
||||
|
||||
default boolean a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
|
||||
try { if (entity != null) entity.collisionLoadChunks = true; // Paper
|
||||
- return this.c(entity, axisalignedbb, set).allMatch(VoxelShape::isEmpty);
|
||||
+ // Paper start - reduce stream usage
|
||||
+ java.util.List<VoxelShape> blockCollisions = getBlockCollision(entity, axisalignedbb, true);
|
||||
+ for (int i = 0; i < blockCollisions.size(); i++) {
|
||||
+ VoxelShape blockCollision = blockCollisions.get(i);
|
||||
+ if (!blockCollision.isEmpty()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ return getEntityCollisions(entity, axisalignedbb, set, true).isEmpty();
|
||||
+ // Paper end
|
||||
} finally { if (entity != null) entity.collisionLoadChunks = false; } // Paper
|
||||
}
|
||||
|
||||
+ default java.util.List<VoxelShape> getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set, boolean returnFast) { return java.util.Collections.emptyList(); } // Paper
|
||||
default Stream<VoxelShape> b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
default Stream<VoxelShape> c(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
|
||||
- return Streams.concat(new Stream[]{this.b(entity, axisalignedbb), this.b(entity, axisalignedbb, set)});
|
||||
+ // Paper start - reduce stream usage
|
||||
+ java.util.List<VoxelShape> blockCollisions = getBlockCollision(entity, axisalignedbb, false);
|
||||
+ java.util.List<VoxelShape> entityCollisions = getEntityCollisions(entity, axisalignedbb, set, false);
|
||||
+ return Stream.concat(blockCollisions.stream(), entityCollisions.stream());
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
default Stream<VoxelShape> b(@Nullable final Entity entity, AxisAlignedBB axisalignedbb) {
|
||||
+ // Paper start - reduce stream usage
|
||||
+ java.util.List<VoxelShape> collision = getBlockCollision(entity, axisalignedbb, false);
|
||||
+ return !collision.isEmpty() ? collision.stream() : Stream.empty();
|
||||
+ }
|
||||
+
|
||||
+ default java.util.List<VoxelShape> getBlockCollision(@Nullable final Entity entity, AxisAlignedBB axisalignedbb, boolean returnFast) {
|
||||
+ // Paper end
|
||||
int i = MathHelper.floor(axisalignedbb.minX - 1.0E-7D) - 1;
|
||||
int j = MathHelper.floor(axisalignedbb.maxX + 1.0E-7D) + 1;
|
||||
int k = MathHelper.floor(axisalignedbb.minY - 1.0E-7D) - 1;
|
||||
@@ -68,19 +89,19 @@ public interface ICollisionAccess extends IBlockAccess {
|
||||
final BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
|
||||
final VoxelShape voxelshape = VoxelShapes.a(axisalignedbb);
|
||||
|
||||
- return StreamSupport.stream(new AbstractSpliterator<VoxelShape>(Long.MAX_VALUE, 1280) {
|
||||
- boolean a = entity == null;
|
||||
-
|
||||
- public boolean tryAdvance(Consumer<? super VoxelShape> consumer) {
|
||||
- if (!this.a) {
|
||||
- this.a = true;
|
||||
+ // Paper start - reduce stream usage (this part done by Aikar)
|
||||
+ java.util.List<VoxelShape> collisions = new java.util.ArrayList<>();
|
||||
+ if (true) {//return StreamSupport.stream(new AbstractSpliterator<VoxelShape>(Long.MAX_VALUE, 1280) {
|
||||
+ if (true) { //public boolean tryAdvance(Consumer<? super VoxelShape> consumer) {*/ // Paper
|
||||
+ if (entity != null) {
|
||||
+ // Paper end
|
||||
VoxelShape voxelshape1 = ICollisionAccess.this.getWorldBorder().a();
|
||||
boolean flag = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().shrink(1.0E-7D)), OperatorBoolean.AND);
|
||||
boolean flag1 = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().g(1.0E-7D)), OperatorBoolean.AND);
|
||||
|
||||
if (!flag && flag1) {
|
||||
- consumer.accept(voxelshape1);
|
||||
- return true;
|
||||
+ collisions.add(voxelshape1);// Paper
|
||||
+ if (returnFast) return collisions;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,9 +125,8 @@ public interface ICollisionAccess extends IBlockAccess {
|
||||
);
|
||||
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;
|
||||
+ collisions.add(VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z))));
|
||||
+ if (returnFast) return collisions;
|
||||
}
|
||||
} else {
|
||||
//blockposition_mutableblockposition.d(k1, l1, i2); // moved up
|
||||
@@ -123,14 +143,14 @@ public interface ICollisionAccess extends IBlockAccess {
|
||||
|
||||
if (voxelshape2 == VoxelShapes.fullCube()) {
|
||||
if (axisalignedbb.intersects(x, y, z, x + 1.0D, y + 1.0D, z + 1.0D)) {
|
||||
- consumer.accept(voxelshape2.offset(x, y, z));
|
||||
- return true;
|
||||
+ collisions.add(voxelshape2.offset(x, y, z));
|
||||
+ if (returnFast) return collisions;
|
||||
}
|
||||
} else {
|
||||
VoxelShape shape = voxelshape2.offset(x, y, z);
|
||||
if (VoxelShapes.applyOperation(shape, voxelshape, OperatorBoolean.AND)) {
|
||||
- consumer.accept(shape);
|
||||
- return true;
|
||||
+ collisions.add(shape);
|
||||
+ if (returnFast) return collisions;
|
||||
}
|
||||
// Paper end
|
||||
}
|
||||
@@ -139,8 +159,9 @@ public interface ICollisionAccess extends IBlockAccess {
|
||||
}
|
||||
}
|
||||
|
||||
- return false;
|
||||
+ //return false; // Paper
|
||||
}
|
||||
- }, false);
|
||||
+ } //}, false);
|
||||
+ return collisions; // Paper
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java
|
||||
index d434aaaaf0ab6a18ab0fe5ad0bf8ed4662f49120..3bc57ef91d557383178533b0cc87a71a521d6b3e 100644
|
||||
--- a/src/main/java/net/minecraft/server/IEntityAccess.java
|
||||
+++ b/src/main/java/net/minecraft/server/IEntityAccess.java
|
||||
@@ -55,8 +55,10 @@ public interface IEntityAccess {
|
||||
// Paper start - remove streams from entity collision
|
||||
if (axisalignedbb.getAverageSideLength() < 1.0E-7D) {
|
||||
return Stream.empty();
|
||||
-
|
||||
}
|
||||
+ return getEntityCollisions(entity, axisalignedbb, set, false).stream();
|
||||
+ }
|
||||
+ default List<VoxelShape> getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set, boolean returnFast) {
|
||||
AxisAlignedBB selection = axisalignedbb.grow(1.0E-7D);
|
||||
List<Entity> entities = entity != null && entity.hardCollides() ? getEntities(entity, selection) : getHardCollidingEntities(entity, selection);
|
||||
List<VoxelShape> shapes = new java.util.ArrayList<>();
|
||||
@@ -74,6 +76,7 @@ public interface IEntityAccess {
|
||||
|
||||
if (otherEntityBox != null && selection.intersects(otherEntityBox)) {
|
||||
shapes.add(VoxelShapes.of(otherEntityBox));
|
||||
+ if (returnFast) return shapes;
|
||||
}
|
||||
|
||||
if (entity != null) {
|
||||
@@ -81,11 +84,12 @@ public interface IEntityAccess {
|
||||
|
||||
if (otherEntityHardBox != null && selection.intersects(otherEntityHardBox)) {
|
||||
shapes.add(VoxelShapes.of(otherEntityHardBox));
|
||||
+ if (returnFast) return shapes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- return shapes.stream();
|
||||
+ return shapes;
|
||||
// Paper end
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 10 May 2020 22:12:46 -0400
|
||||
Subject: [PATCH] Ensure Entity AABB's are never invalid
|
||||
|
||||
If anything used setPositionRaw, it left potential for an AABB
|
||||
to be left stale at their old location, which could cause massive
|
||||
AABB boxes if movement ever then got called on the new position.
|
||||
|
||||
This guarantees any time we set the entities position, we also
|
||||
update their AABB.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
||||
index b176dc26d15065aebc91c75e8a96745f589c0b87..c81b9d814d50a026872d2711f76649c00d65888b 100644
|
||||
--- a/src/main/java/net/minecraft/server/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/server/Entity.java
|
||||
@@ -416,10 +416,11 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
||||
|
||||
public void setPosition(double d0, double d1, double d2) {
|
||||
this.setPositionRaw(d0, d1, d2);
|
||||
- float f = this.size.width / 2.0F;
|
||||
- float f1 = this.size.height;
|
||||
-
|
||||
- this.a(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f));
|
||||
+ // Paper start - move into setPositionRaw
|
||||
+ //float f = this.size.width / 2.0F;
|
||||
+ //float f1 = this.size.height;
|
||||
+ //this.a(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f));
|
||||
+ // Paper end
|
||||
if (valid) ((WorldServer) world).chunkCheck(this); // CraftBukkit
|
||||
}
|
||||
|
||||
@@ -2981,6 +2982,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
||||
return new AxisAlignedBB(vec3d, vec3d1);
|
||||
}
|
||||
|
||||
+ public final void setBoundingBox(AxisAlignedBB axisalignedbb) { a(axisalignedbb); } // Paper - OBFHELPER
|
||||
public void a(AxisAlignedBB axisalignedbb) {
|
||||
// CraftBukkit start - block invalid bounding boxes
|
||||
double minX = axisalignedbb.minX,
|
||||
@@ -3439,6 +3441,14 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
||||
}
|
||||
|
||||
public void setPositionRaw(double d0, double d1, double d2) {
|
||||
+ // Paper start - never allow AABB to become desynced from position
|
||||
+ // hanging has its own special logic
|
||||
+ if (!(this instanceof EntityHanging) && (locX != d0 || locY != d1 || locZ != d2)) {
|
||||
+ float f = this.size.width / 2.0F;
|
||||
+ float f1 = this.size.height;
|
||||
+ this.setBoundingBox(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f));
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.locX = d0;
|
||||
this.locY = d1;
|
||||
this.locZ = d2;
|
|
@ -0,0 +1,61 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sun, 10 May 2020 22:49:05 -0400
|
||||
Subject: [PATCH] Optimize WorldBorder collision checks and air
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
||||
index c81b9d814d50a026872d2711f76649c00d65888b..e0ab058bf947ea10b37eadf6122292e708bd3809 100644
|
||||
--- a/src/main/java/net/minecraft/server/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/server/Entity.java
|
||||
@@ -845,7 +845,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
||||
AxisAlignedBB axisalignedbb = this.getBoundingBox();
|
||||
VoxelShapeCollision voxelshapecollision = VoxelShapeCollision.a(this);
|
||||
VoxelShape voxelshape = this.world.getWorldBorder().a();
|
||||
- Stream<VoxelShape> stream = VoxelShapes.c(voxelshape, VoxelShapes.a(axisalignedbb.shrink(1.0E-7D)), OperatorBoolean.AND) ? Stream.empty() : Stream.of(voxelshape);
|
||||
+ Stream<VoxelShape> stream = !this.world.getWorldBorder().isInBounds(axisalignedbb) ? Stream.empty() : Stream.of(this.world.getWorldBorder().a()); // Paper
|
||||
Stream<VoxelShape> stream1 = this.world.b(this, axisalignedbb.a(vec3d), (Set) ImmutableSet.of());
|
||||
StreamAccumulator<VoxelShape> streamaccumulator = new StreamAccumulator<>(Stream.concat(stream1, stream));
|
||||
Vec3D vec3d1 = vec3d.g() == 0.0D ? vec3d : a(this, vec3d, axisalignedbb, this.world, voxelshapecollision, streamaccumulator);
|
||||
diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java
|
||||
index 5a21205a49606b294de4cd27b60438c6a5b3c526..63dd5e98b6af1d9a9fa9d01621ce5bc33c0d7502 100644
|
||||
--- a/src/main/java/net/minecraft/server/ICollisionAccess.java
|
||||
+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
|
||||
@@ -95,12 +95,12 @@ public interface ICollisionAccess extends IBlockAccess {
|
||||
if (true) { //public boolean tryAdvance(Consumer<? super VoxelShape> consumer) {*/ // Paper
|
||||
if (entity != null) {
|
||||
// Paper end
|
||||
- VoxelShape voxelshape1 = ICollisionAccess.this.getWorldBorder().a();
|
||||
- boolean flag = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().shrink(1.0E-7D)), OperatorBoolean.AND);
|
||||
- boolean flag1 = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().g(1.0E-7D)), OperatorBoolean.AND);
|
||||
+ //VoxelShape voxelshape1 = ICollisionAccess.this.getWorldBorder().a(); // Paper - only make if collides
|
||||
+ boolean flag = !ICollisionAccess.this.getWorldBorder().isInBounds(entity.getBoundingBox().shrink(1.0E-7D)); // Paper
|
||||
+ boolean flag1 = !ICollisionAccess.this.getWorldBorder().isInBounds(entity.getBoundingBox().g(1.0E-7D)); // Paper
|
||||
|
||||
if (!flag && flag1) {
|
||||
- collisions.add(voxelshape1);// Paper
|
||||
+ collisions.add(ICollisionAccess.this.getWorldBorder().a());// Paper
|
||||
if (returnFast) return collisions;
|
||||
}
|
||||
}
|
||||
@@ -133,7 +133,7 @@ public interface ICollisionAccess extends IBlockAccess {
|
||||
//IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); // moved up
|
||||
// Paper end
|
||||
|
||||
- if ((j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) {
|
||||
+ if (!iblockdata.isAir() && (j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { // Paper - fast track air
|
||||
VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) ICollisionAccess.this, blockposition_mutableblockposition, voxelshapecollision);
|
||||
|
||||
// Paper start - Lithium Collision Optimizations
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldBorder.java b/src/main/java/net/minecraft/server/WorldBorder.java
|
||||
index 4c20db5a3f9e159997a9851691aca421241d6d95..535d08ffb1d20570b19307c8619cfd39b4541356 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldBorder.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldBorder.java
|
||||
@@ -40,6 +40,7 @@ public class WorldBorder {
|
||||
return (double) chunkcoordintpair.f() > this.c() && (double) chunkcoordintpair.d() < this.e() && (double) chunkcoordintpair.g() > this.d() && (double) chunkcoordintpair.e() < this.f();
|
||||
}
|
||||
|
||||
+ public final boolean isInBounds(AxisAlignedBB aabb) { return this.a(aabb); } // Paper - OBFHELPER
|
||||
public boolean a(AxisAlignedBB axisalignedbb) {
|
||||
return axisalignedbb.maxX > this.c() && axisalignedbb.minX < this.e() && axisalignedbb.maxZ > this.d() && axisalignedbb.minZ < this.f();
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 11 May 2020 04:18:54 -0400
|
||||
Subject: [PATCH] Optimize Pathfinder - Remove Streams / Optimized collections
|
||||
|
||||
I utilized the IDE to convert streams to non streams code, so shouldn't
|
||||
be any risk of behavior change. Only did minor optimization of the
|
||||
generated code set to remove unnecessary things.
|
||||
|
||||
I expect us to just drop this patch on next major update and re-apply
|
||||
it with the IDE again and re-apply the collections optimization.
|
||||
|
||||
Optimize collection by creating a list instead of a set of the key and value.
|
||||
|
||||
This lets us get faster foreach iteration, as well as avoids map lookups on
|
||||
the values when needed.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/Pathfinder.java b/src/main/java/net/minecraft/server/Pathfinder.java
|
||||
index 67c63cfe333e328cbd00ada970bd81efebfe30b6..71b96943d865105f279dda613b7ac6b3ffed793b 100644
|
||||
--- a/src/main/java/net/minecraft/server/Pathfinder.java
|
||||
+++ b/src/main/java/net/minecraft/server/Pathfinder.java
|
||||
@@ -31,9 +31,15 @@ public class Pathfinder {
|
||||
this.a.a();
|
||||
this.e.a(chunkcache, entityinsentient);
|
||||
PathPoint pathpoint = this.e.b();
|
||||
- Map<PathDestination, BlockPosition> map = (Map) set.stream().collect(Collectors.toMap((blockposition) -> {
|
||||
- return this.e.a((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ());
|
||||
- }, Function.identity()));
|
||||
+ // Paper start - remove streams - and optimize collection
|
||||
+ List<Map.Entry<PathDestination, BlockPosition>> map = new java.util.ArrayList<>();
|
||||
+ for (BlockPosition blockposition : set) {
|
||||
+ // cast is important
|
||||
+ //noinspection RedundantCast
|
||||
+ PathDestination path = this.e.a((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ());
|
||||
+ map.add(new java.util.AbstractMap.SimpleEntry<>(path, blockposition));
|
||||
+ }
|
||||
+ // Paper end
|
||||
PathEntity pathentity = this.a(pathpoint, map, f, i, f1);
|
||||
|
||||
this.e.a();
|
||||
@@ -41,11 +47,11 @@ public class Pathfinder {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
- private PathEntity a(PathPoint pathpoint, Map<PathDestination, BlockPosition> map, float f, int i, float f1) {
|
||||
- Set<PathDestination> set = map.keySet();
|
||||
+ private PathEntity a(PathPoint pathpoint, java.util.List<java.util.Map.Entry<PathDestination, BlockPosition>> list, float f, int i, float f1) { // Paper - list instead of set
|
||||
+ //Set<PathDestination> set = map.keySet(); // Paper
|
||||
|
||||
pathpoint.e = 0.0F;
|
||||
- pathpoint.f = this.a(pathpoint, set);
|
||||
+ pathpoint.f = this.a(pathpoint, list); // Paper - list instead of map
|
||||
pathpoint.g = pathpoint.f;
|
||||
this.a.a();
|
||||
this.b.clear();
|
||||
@@ -62,10 +68,23 @@ public class Pathfinder {
|
||||
PathPoint pathpoint1 = this.a.c();
|
||||
|
||||
pathpoint1.i = true;
|
||||
- set.stream().filter((pathdestination) -> {
|
||||
- return pathpoint1.c((PathPoint) pathdestination) <= (float) i;
|
||||
- }).forEach(PathDestination::e);
|
||||
- if (set.stream().anyMatch(PathDestination::f)) {
|
||||
+ // Paper start - remove streams
|
||||
+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
|
||||
+ PathDestination pathdestination = list.get(i1).getKey();
|
||||
+ if (pathpoint1.c(pathdestination) <= (float) i) {
|
||||
+ pathdestination.e();
|
||||
+ }
|
||||
+ }
|
||||
+ boolean result = false;
|
||||
+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
|
||||
+ PathDestination pathdestination = list.get(i1).getKey();
|
||||
+ if (pathdestination.f()) {
|
||||
+ result = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (result) {
|
||||
+ // Paper end
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -82,7 +101,7 @@ public class Pathfinder {
|
||||
if (pathpoint2.j < f && (!pathpoint2.c() || f3 < pathpoint2.e)) {
|
||||
pathpoint2.h = pathpoint1;
|
||||
pathpoint2.e = f3;
|
||||
- pathpoint2.f = this.a(pathpoint2, set) * 1.5F;
|
||||
+ pathpoint2.f = this.a(pathpoint2, list) * 1.5F; // Paper - use list instead of map
|
||||
if (pathpoint2.c()) {
|
||||
this.a.a(pathpoint2, pathpoint2.e + pathpoint2.f);
|
||||
} else {
|
||||
@@ -94,36 +113,49 @@ public class Pathfinder {
|
||||
}
|
||||
}
|
||||
|
||||
- Stream stream;
|
||||
|
||||
- if (set.stream().anyMatch(PathDestination::f)) {
|
||||
- stream = set.stream().filter(PathDestination::f).map((pathdestination) -> {
|
||||
- return this.a(pathdestination.d(), (BlockPosition) map.get(pathdestination), true);
|
||||
- }).sorted(Comparator.comparingInt(PathEntity::e));
|
||||
- } else {
|
||||
- stream = set.stream().map((pathdestination) -> {
|
||||
- return this.a(pathdestination.d(), (BlockPosition) map.get(pathdestination), false);
|
||||
- }).sorted(Comparator.comparingDouble(PathEntity::l).thenComparingInt(PathEntity::e));
|
||||
+ // Paper start - remove streams
|
||||
+ boolean result = false;
|
||||
+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
|
||||
+ PathDestination pathDestination = list.get(i1).getKey(); // Paper
|
||||
+ if (pathDestination.f()) {
|
||||
+ result = true;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
-
|
||||
- Optional<PathEntity> optional = stream.findFirst();
|
||||
-
|
||||
- if (!optional.isPresent()) {
|
||||
- return null;
|
||||
+ List<PathEntity> candidates = new java.util.ArrayList<>();
|
||||
+ if (result) {
|
||||
+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
|
||||
+ Map.Entry<PathDestination, BlockPosition> entry = list.get(i1);
|
||||
+ PathDestination pathdestination = entry.getKey();
|
||||
+ if (pathdestination.f()) {
|
||||
+ PathEntity pathEntity = this.a(pathdestination.d(), entry.getValue(), true);
|
||||
+ candidates.add(pathEntity);
|
||||
+ }
|
||||
+ }
|
||||
+ if (candidates.isEmpty()) return null;
|
||||
+ candidates.sort(Comparator.comparingInt(PathEntity::e));
|
||||
} else {
|
||||
- PathEntity pathentity = (PathEntity) optional.get();
|
||||
-
|
||||
- return pathentity;
|
||||
+ for (int i1 = 0, listSize = list.size(); i1 < listSize; i1++) {
|
||||
+ Map.Entry<PathDestination, BlockPosition> entry = list.get(i1);
|
||||
+ PathDestination pathdestination = entry.getKey();
|
||||
+ PathEntity pathEntity = this.a(pathdestination.d(), entry.getValue(), false);
|
||||
+ candidates.add(pathEntity);
|
||||
+ }
|
||||
+ if (candidates.isEmpty()) return null;
|
||||
+ candidates.sort(Comparator.comparingDouble(PathEntity::l).thenComparingInt(PathEntity::e));
|
||||
}
|
||||
+ return candidates.get(0);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
- private float a(PathPoint pathpoint, Set<PathDestination> set) {
|
||||
+ private float a(PathPoint pathpoint, java.util.List<java.util.Map.Entry<PathDestination, BlockPosition>> list) {
|
||||
float f = Float.MAX_VALUE;
|
||||
|
||||
float f1;
|
||||
|
||||
- for (Iterator iterator = set.iterator(); iterator.hasNext(); f = Math.min(f1, f)) {
|
||||
- PathDestination pathdestination = (PathDestination) iterator.next();
|
||||
+ for (int i = 0, listSize = list.size(); i < listSize; f = Math.min(f1, f), i++) { // Paper
|
||||
+ PathDestination pathdestination = list.get(i).getKey(); // Paper
|
||||
|
||||
f1 = pathpoint.a(pathdestination);
|
||||
pathdestination.a(f1, pathpoint);
|
79
removed/1.16/0524-Add-permission-for-command-blocks.patch
Normal file
79
removed/1.16/0524-Add-permission-for-command-blocks.patch
Normal file
|
@ -0,0 +1,79 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mariell Hoversholm <proximyst@proximyst.com>
|
||||
Date: Sat, 16 May 2020 10:05:30 +0200
|
||||
Subject: [PATCH] Add permission for command blocks
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/BlockCommand.java b/src/main/java/net/minecraft/server/BlockCommand.java
|
||||
index d0f75c8f93d3ceb1ee358baeb51f64e7e575bbc0..48cc48bd999c02268fa3270401c0df77a327ab13 100644
|
||||
--- a/src/main/java/net/minecraft/server/BlockCommand.java
|
||||
+++ b/src/main/java/net/minecraft/server/BlockCommand.java
|
||||
@@ -110,7 +110,7 @@ public class BlockCommand extends BlockTileEntity {
|
||||
public EnumInteractionResult interact(IBlockData iblockdata, World world, BlockPosition blockposition, EntityHuman entityhuman, EnumHand enumhand, MovingObjectPositionBlock movingobjectpositionblock) {
|
||||
TileEntity tileentity = world.getTileEntity(blockposition);
|
||||
|
||||
- if (tileentity instanceof TileEntityCommand && entityhuman.isCreativeAndOp()) {
|
||||
+ if (tileentity instanceof TileEntityCommand && (entityhuman.isCreativeAndOp() || (entityhuman.isCreative() && entityhuman.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission
|
||||
entityhuman.a((TileEntityCommand) tileentity);
|
||||
return EnumInteractionResult.SUCCESS;
|
||||
} else {
|
||||
diff --git a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
|
||||
index ef2a496eda45ae5ee8fe52ef09e77c2906069d2e..6a0d70033b4eec384795b5cccd76bce2265ffbfc 100644
|
||||
--- a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
|
||||
+++ b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
|
||||
@@ -178,7 +178,7 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener {
|
||||
}
|
||||
|
||||
public boolean a(EntityHuman entityhuman) {
|
||||
- if (!entityhuman.isCreativeAndOp()) {
|
||||
+ if (!entityhuman.isCreativeAndOp() && !entityhuman.isCreative() && !entityhuman.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission
|
||||
return false;
|
||||
} else {
|
||||
if (entityhuman.getWorld().isClientSide) {
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
|
||||
index 1f9d231fb93e30286205f7a0a4c898a0e153bd95..d52fbda79fe1c52d3ddb53c0f1c1f521d7620702 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
|
||||
@@ -612,7 +612,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
|
||||
PlayerConnectionUtils.ensureMainThread(packetplayinsetcommandblock, this, this.player.getWorldServer());
|
||||
if (!this.minecraftServer.getEnableCommandBlock()) {
|
||||
this.player.sendMessage(new ChatMessage("advMode.notEnabled", new Object[0]));
|
||||
- } else if (!this.player.isCreativeAndOp()) {
|
||||
+ } else if (!this.player.isCreativeAndOp() && !this.player.isCreative() && !this.player.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission
|
||||
this.player.sendMessage(new ChatMessage("advMode.notAllowed", new Object[0]));
|
||||
} else {
|
||||
CommandBlockListenerAbstract commandblocklistenerabstract = null;
|
||||
@@ -675,7 +675,7 @@ public class PlayerConnection implements PacketListenerPlayIn {
|
||||
PlayerConnectionUtils.ensureMainThread(packetplayinsetcommandminecart, this, this.player.getWorldServer());
|
||||
if (!this.minecraftServer.getEnableCommandBlock()) {
|
||||
this.player.sendMessage(new ChatMessage("advMode.notEnabled", new Object[0]));
|
||||
- } else if (!this.player.isCreativeAndOp()) {
|
||||
+ } else if (!this.player.isCreativeAndOp() && !this.player.isCreative() && !this.player.getBukkitEntity().hasPermission("minecraft.commandblock")) { // Paper - command block permission
|
||||
this.player.sendMessage(new ChatMessage("advMode.notAllowed", new Object[0]));
|
||||
} else {
|
||||
CommandBlockListenerAbstract commandblocklistenerabstract = packetplayinsetcommandminecart.a(this.player.world);
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java
|
||||
index f11ef84df85c1e7ada9c62247b7882f19ae32089..6df8434612d4afe411b2c435f4c847b9183570f8 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerInteractManager.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java
|
||||
@@ -350,7 +350,7 @@ public class PlayerInteractManager {
|
||||
TileEntity tileentity = this.world.getTileEntity(blockposition);
|
||||
Block block = iblockdata.getBlock();
|
||||
|
||||
- if ((block instanceof BlockCommand || block instanceof BlockStructure || block instanceof BlockJigsaw) && !this.player.isCreativeAndOp()) {
|
||||
+ if ((block instanceof BlockCommand || block instanceof BlockStructure || block instanceof BlockJigsaw) && !this.player.isCreativeAndOp() && !(block instanceof BlockCommand && (this.player.isCreative() && this.player.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission
|
||||
this.world.notify(blockposition, iblockdata, iblockdata, 3);
|
||||
return false;
|
||||
} else if (this.player.a((World) this.world, blockposition, this.gamemode)) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
|
||||
index 525ebf961e5da0687183a5e2ead23ed92cbd9d79..a4a809f302c5ff9c76cde5fc0add2ceec1bdf9b5 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java
|
||||
@@ -16,6 +16,7 @@ public final class CraftDefaultPermissions {
|
||||
DefaultPermissions.registerPermission(ROOT + ".nbt.copy", "Gives the user the ability to copy NBT in creative", org.bukkit.permissions.PermissionDefault.TRUE, parent);
|
||||
DefaultPermissions.registerPermission(ROOT + ".debugstick", "Gives the user the ability to use the debug stick in creative", org.bukkit.permissions.PermissionDefault.OP, parent);
|
||||
DefaultPermissions.registerPermission(ROOT + ".debugstick.always", "Gives the user the ability to use the debug stick in all game modes", org.bukkit.permissions.PermissionDefault.FALSE, parent);
|
||||
+ DefaultPermissions.registerPermission(ROOT + ".commandblock", "Gives the user the ability to use command blocks.", org.bukkit.permissions.PermissionDefault.OP, parent); // Paper
|
||||
// Spigot end
|
||||
parent.recalculatePermissibles();
|
||||
}
|
273
removed/1.16/0530-Optimize-Villagers.patch
Normal file
273
removed/1.16/0530-Optimize-Villagers.patch
Normal file
|
@ -0,0 +1,273 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 26 May 2020 21:32:05 -0400
|
||||
Subject: [PATCH] Optimize Villagers
|
||||
|
||||
This change reimplements the entire BehaviorFindPosition method to
|
||||
get rid of all of the streams, and implement the logic in a more sane way.
|
||||
|
||||
We keep vanilla behavior 100% the same with this change, just wrote more
|
||||
optimal, as we can abort iterating POI's as soon as we find a match....
|
||||
|
||||
One slight change is that Minecraft adds a random delay before a POI is
|
||||
attempted again. I've increased the amount of that delay based on the distance
|
||||
to said POI, so farther POI's will not be attempted as often.
|
||||
|
||||
Additionally, we spiral out, so we favor local POI's before we ever favor farther POI's.
|
||||
|
||||
We also try to pathfind 1 POI at a time instead of collecting multiple POI's then tossing them
|
||||
all to the pathfinder, so that once we get a match we can return before even looking at other
|
||||
POI's.
|
||||
|
||||
This benefits us in that ideally, a villager will constantly find the near POI's and
|
||||
not even try to pathfind to the farther POI. Trying to pathfind to distant POI's is
|
||||
what causes significant lag.
|
||||
|
||||
Other improvements here is to stop spamming the POI manager with empty nullables.
|
||||
Vanilla used them to represent if they needed to load POI data off disk or not.
|
||||
|
||||
Well, we load POI data async on chunk load, so we have it, and we surely do not ever
|
||||
want to load POI data sync either for unloaded chunks!
|
||||
|
||||
So this massively reduces object count in the POI hashmaps, resulting in less hash collions,
|
||||
and also less memory use.
|
||||
|
||||
Additionally, unemployed villagers were using significant time due to major ineffeciency in
|
||||
the code rebuilding data that is static every single invocation for every POI type...
|
||||
|
||||
So we cache that and only rebuild it if professions change, which should be never unless
|
||||
a plugin manipulates and adds custom professions, which it will handle by rebuilding.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/BehaviorFindPosition.java b/src/main/java/net/minecraft/server/BehaviorFindPosition.java
|
||||
index 35eb3a5a61145e94d5b0c77c0eb13bfa46fac23b..6861b1a345496a83900b0ef702ba34315a030ef6 100644
|
||||
--- a/src/main/java/net/minecraft/server/BehaviorFindPosition.java
|
||||
+++ b/src/main/java/net/minecraft/server/BehaviorFindPosition.java
|
||||
@@ -29,8 +29,55 @@ public class BehaviorFindPosition extends Behavior<EntityCreature> {
|
||||
|
||||
protected void a(WorldServer worldserver, EntityCreature entitycreature, long i) {
|
||||
this.f = 0;
|
||||
- this.d = worldserver.getTime() + (long) worldserver.getRandom().nextInt(20);
|
||||
+ this.d = worldserver.getTime() + (long) java.util.concurrent.ThreadLocalRandom.current().nextInt(20); // Paper
|
||||
VillagePlace villageplace = worldserver.B();
|
||||
+
|
||||
+ // Paper start - replace implementation completely
|
||||
+ BlockPosition blockposition2 = new BlockPosition(entitycreature);
|
||||
+ int dist = 48;
|
||||
+ int requiredDist = dist * dist;
|
||||
+ int cdist = Math.floorDiv(dist, 16);
|
||||
+ Predicate<VillagePlaceType> predicate = this.a.c();
|
||||
+ int maxPoiAttempts = 4;
|
||||
+ int poiAttempts = 0;
|
||||
+ OUT:
|
||||
+ for (ChunkCoordIntPair chunkcoordintpair : MCUtil.getSpiralOutChunks(blockposition2, cdist)) {
|
||||
+ for (int i1 = 0; i1 < 16; i1++) {
|
||||
+ java.util.Optional<VillagePlaceSection> section = villageplace.getSection(SectionPosition.a(chunkcoordintpair, i1).v());
|
||||
+ if (section == null || !section.isPresent()) continue;
|
||||
+ for (java.util.Map.Entry<VillagePlaceType, java.util.Set<VillagePlaceRecord>> e : section.get().getRecords().entrySet()) {
|
||||
+ if (!predicate.test(e.getKey())) continue;
|
||||
+ for (VillagePlaceRecord record : e.getValue()) {
|
||||
+ if (!record.hasVacancy()) continue;
|
||||
+
|
||||
+ BlockPosition pos = record.getPosition();
|
||||
+ long key = pos.asLong();
|
||||
+ if (this.e.containsKey(key)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ double poiDist = pos.distanceSquared(blockposition2);
|
||||
+ if (poiDist <= (double) requiredDist) {
|
||||
+ this.e.put(key, (long) (this.d + Math.sqrt(poiDist) * 4)); // use dist instead of 40 to blacklist longer if farther distance
|
||||
+ ++poiAttempts;
|
||||
+ PathEntity pathentity = entitycreature.getNavigation().a(com.google.common.collect.ImmutableSet.of(pos), 8, false, this.a.d());
|
||||
+
|
||||
+ if (pathentity != null && pathentity.h()) {
|
||||
+ record.decreaseVacancy();
|
||||
+ GlobalPos globalPos = GlobalPos.create(worldserver.getWorldProvider().getDimensionManager(), pos);
|
||||
+ entitycreature.getBehaviorController().setMemory(this.b, globalPos);
|
||||
+ break OUT;
|
||||
+ }
|
||||
+ if (poiAttempts >= maxPoiAttempts) {
|
||||
+ break OUT;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Clean up - vanilla does this only when it runs out, but that would push it to try farther POI's...
|
||||
+ this.e.long2LongEntrySet().removeIf((entry) -> entry.getLongValue() < this.d);
|
||||
+ /*
|
||||
Predicate<BlockPosition> predicate = (blockposition) -> {
|
||||
long j = blockposition.asLong();
|
||||
|
||||
@@ -61,6 +108,6 @@ public class BehaviorFindPosition extends Behavior<EntityCreature> {
|
||||
return entry.getLongValue() < this.d;
|
||||
});
|
||||
}
|
||||
-
|
||||
+ */ // Paper end
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/RegionFileSection.java b/src/main/java/net/minecraft/server/RegionFileSection.java
|
||||
index a6d8ef5eb44f3f851a3a1be4032ca21ab1d7f2b2..c3e8a0145d63843736d2060f978cdf38df359563 100644
|
||||
--- a/src/main/java/net/minecraft/server/RegionFileSection.java
|
||||
+++ b/src/main/java/net/minecraft/server/RegionFileSection.java
|
||||
@@ -51,29 +51,15 @@ public class RegionFileSection<R extends MinecraftSerializable> extends RegionFi
|
||||
|
||||
@Nullable
|
||||
protected Optional<R> c(long i) {
|
||||
- return (Optional) this.c.get(i);
|
||||
+ return this.c.getOrDefault(i, Optional.empty()); // Paper
|
||||
}
|
||||
|
||||
+ protected final Optional<R> getSection(long i) { return d(i); } // Paper - OBFHELPER
|
||||
protected Optional<R> d(long i) {
|
||||
- SectionPosition sectionposition = SectionPosition.a(i);
|
||||
-
|
||||
- if (this.b(sectionposition)) {
|
||||
- return Optional.empty();
|
||||
- } else {
|
||||
- Optional<R> optional = this.c(i);
|
||||
-
|
||||
- if (optional != null) {
|
||||
- return optional;
|
||||
- } else {
|
||||
- this.b(sectionposition.u());
|
||||
- optional = this.c(i);
|
||||
- if (optional == null) {
|
||||
- throw (IllegalStateException) SystemUtils.c(new IllegalStateException());
|
||||
- } else {
|
||||
- return optional;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ // Paper start - replace method - never load POI data sync, we load this in chunk load already, reduce ops
|
||||
+ // If it's an unloaded chunk, well too bad.
|
||||
+ return this.c(i);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
protected boolean b(SectionPosition sectionposition) {
|
||||
@@ -117,7 +103,7 @@ public class RegionFileSection<R extends MinecraftSerializable> extends RegionFi
|
||||
private <T> void a(ChunkCoordIntPair chunkcoordintpair, DynamicOps<T> dynamicops, @Nullable T t0) {
|
||||
if (t0 == null) {
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
- this.c.put(SectionPosition.a(chunkcoordintpair, i).v(), Optional.empty());
|
||||
+ //this.c.put(SectionPosition.a(chunkcoordintpair, i).v(), Optional.empty()); // Paper - NO!!!
|
||||
}
|
||||
} else {
|
||||
Dynamic<T> dynamic = new Dynamic(dynamicops, t0);
|
||||
@@ -135,7 +121,7 @@ public class RegionFileSection<R extends MinecraftSerializable> extends RegionFi
|
||||
}, dynamic2);
|
||||
});
|
||||
|
||||
- this.c.put(i1, optional);
|
||||
+ if (optional.isPresent()) this.c.put(i1, optional); // Paper - NO!!!
|
||||
optional.ifPresent((minecraftserializable) -> {
|
||||
this.b(i1);
|
||||
if (flag) {
|
||||
@@ -199,7 +185,7 @@ public class RegionFileSection<R extends MinecraftSerializable> extends RegionFi
|
||||
if (optional != null && optional.isPresent()) {
|
||||
this.d.add(i);
|
||||
} else {
|
||||
- RegionFileSection.LOGGER.warn("No data for position: {}", SectionPosition.a(i));
|
||||
+ //RegionFileSection.LOGGER.warn("No data for position: {}", SectionPosition.a(i)); // Paper - hush
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/VillagePlaceRecord.java b/src/main/java/net/minecraft/server/VillagePlaceRecord.java
|
||||
index 1e9d7a3f902eb4571b93bb0e58cba966365f07b8..44535a3e2c3320aac472c5a7ee557fac7bab2530 100644
|
||||
--- a/src/main/java/net/minecraft/server/VillagePlaceRecord.java
|
||||
+++ b/src/main/java/net/minecraft/server/VillagePlaceRecord.java
|
||||
@@ -32,6 +32,7 @@ public class VillagePlaceRecord implements MinecraftSerializable {
|
||||
return dynamicops.createMap(ImmutableMap.of(dynamicops.createString("pos"), this.a.a(dynamicops), dynamicops.createString("type"), dynamicops.createString(IRegistry.POINT_OF_INTEREST_TYPE.getKey(this.b).toString()), dynamicops.createString("free_tickets"), dynamicops.createInt(this.c)));
|
||||
}
|
||||
|
||||
+ protected final boolean decreaseVacancy() { return b(); } // Paper - OBFHELPER
|
||||
protected boolean b() {
|
||||
if (this.c <= 0) {
|
||||
return false;
|
||||
@@ -42,6 +43,7 @@ public class VillagePlaceRecord implements MinecraftSerializable {
|
||||
}
|
||||
}
|
||||
|
||||
+ protected final boolean increaseVacancy() { return c(); } // Paper - OBFHELPER
|
||||
protected boolean c() {
|
||||
if (this.c >= this.b.b()) {
|
||||
return false;
|
||||
@@ -52,14 +54,17 @@ public class VillagePlaceRecord implements MinecraftSerializable {
|
||||
}
|
||||
}
|
||||
|
||||
+ public final boolean hasVacancy() { return d(); } // Paper - OBFHELPER
|
||||
public boolean d() {
|
||||
return this.c > 0;
|
||||
}
|
||||
|
||||
+ public final boolean isOccupied() { return e(); } // Paper - OBFHELPER
|
||||
public boolean e() {
|
||||
return this.c != this.b.b();
|
||||
}
|
||||
|
||||
+ public final BlockPosition getPosition() { return f(); } // Paper
|
||||
public BlockPosition f() {
|
||||
return this.a;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/VillagePlaceSection.java b/src/main/java/net/minecraft/server/VillagePlaceSection.java
|
||||
index 3f2602dbe0995f8d01d4a1428d919405d711a205..436b064c3b277143075386fc9a71027fb5962681 100644
|
||||
--- a/src/main/java/net/minecraft/server/VillagePlaceSection.java
|
||||
+++ b/src/main/java/net/minecraft/server/VillagePlaceSection.java
|
||||
@@ -23,7 +23,7 @@ public class VillagePlaceSection implements MinecraftSerializable {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private final Short2ObjectMap<VillagePlaceRecord> b = new Short2ObjectOpenHashMap();
|
||||
- private final Map<VillagePlaceType, Set<VillagePlaceRecord>> c = Maps.newHashMap();
|
||||
+ private final Map<VillagePlaceType, Set<VillagePlaceRecord>> c = Maps.newHashMap(); public final Map<VillagePlaceType, Set<VillagePlaceRecord>> getRecords() { return c; } // Paper - OBFHELPER
|
||||
private final Runnable d;
|
||||
private boolean e;
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/VillagePlaceType.java b/src/main/java/net/minecraft/server/VillagePlaceType.java
|
||||
index ab3e054cd2f38756a5d802d4d981022318ab047d..c1f293fc98d3efb4665cfb9036f208b842fc8e36 100644
|
||||
--- a/src/main/java/net/minecraft/server/VillagePlaceType.java
|
||||
+++ b/src/main/java/net/minecraft/server/VillagePlaceType.java
|
||||
@@ -12,8 +12,14 @@ import java.util.stream.Stream;
|
||||
|
||||
public class VillagePlaceType {
|
||||
|
||||
+ static Set<VillagePlaceType> professionCache; // Paper
|
||||
private static final Predicate<VillagePlaceType> v = (villageplacetype) -> {
|
||||
- return ((Set) IRegistry.VILLAGER_PROFESSION.d().map(VillagerProfession::b).collect(Collectors.toSet())).contains(villageplacetype);
|
||||
+ // Paper start
|
||||
+ if (professionCache == null) {
|
||||
+ professionCache = IRegistry.VILLAGER_PROFESSION.d().map(VillagerProfession::b).collect(Collectors.toSet());
|
||||
+ }
|
||||
+ return professionCache.contains(villageplacetype);
|
||||
+ // Paper end
|
||||
};
|
||||
public static final Predicate<VillagePlaceType> a = (villageplacetype) -> {
|
||||
return true;
|
||||
@@ -89,11 +95,11 @@ public class VillagePlaceType {
|
||||
}
|
||||
|
||||
private static VillagePlaceType a(String s, Set<IBlockData> set, int i, int j) {
|
||||
- return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (Object) (new VillagePlaceType(s, set, i, j))));
|
||||
+ return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (new VillagePlaceType(s, set, i, j)))); // Paper - decompile error
|
||||
}
|
||||
|
||||
private static VillagePlaceType a(String s, Set<IBlockData> set, int i, Predicate<VillagePlaceType> predicate, int j) {
|
||||
- return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (Object) (new VillagePlaceType(s, set, i, predicate, j))));
|
||||
+ return a((VillagePlaceType) IRegistry.POINT_OF_INTEREST_TYPE.a(new MinecraftKey(s), (new VillagePlaceType(s, set, i, predicate, j)))); // Paper - decompile error
|
||||
}
|
||||
|
||||
private static VillagePlaceType a(VillagePlaceType villageplacetype) {
|
||||
diff --git a/src/main/java/net/minecraft/server/VillagerProfession.java b/src/main/java/net/minecraft/server/VillagerProfession.java
|
||||
index c38296165b33698bc15fe49a2de0d0d19cfb910a..f9d7a16c79a4e3ffe8b6e7ed469236a93892f01d 100644
|
||||
--- a/src/main/java/net/minecraft/server/VillagerProfession.java
|
||||
+++ b/src/main/java/net/minecraft/server/VillagerProfession.java
|
||||
@@ -61,6 +61,7 @@ public class VillagerProfession {
|
||||
}
|
||||
|
||||
static VillagerProfession a(String s, VillagePlaceType villageplacetype, ImmutableSet<Item> immutableset, ImmutableSet<Block> immutableset1, @Nullable SoundEffect soundeffect) {
|
||||
+ VillagePlaceType.professionCache = null; // Paper
|
||||
return (VillagerProfession) IRegistry.a((IRegistry) IRegistry.VILLAGER_PROFESSION, new MinecraftKey(s), (Object) (new VillagerProfession(s, villageplacetype, immutableset, immutableset1, soundeffect)));
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue