From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: tsao chi Date: Sun, 2 Aug 2020 12:25:52 -0500 Subject: [PATCH] Akarin updated Async Path Finding Co-Author: Bud Gidiere diff --git a/src/main/java/net/minecraft/server/EntityBee.java b/src/main/java/net/minecraft/server/EntityBee.java index e6868e2b65e3c2bde7696272b242a47e7394e27f..c4c3ef500b9b8465644a0b7712f43ba35ad3acc1 100644 --- a/src/main/java/net/minecraft/server/EntityBee.java +++ b/src/main/java/net/minecraft/server/EntityBee.java @@ -445,9 +445,9 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB } @Override - public void c() { + public void tickAsync() { if (!EntityBee.this.bJ.k()) { - super.c(); + super.tickAsync(); } } }; diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java index 027a55223c660f25b0b52f99efed5b0c037ae658..09f332aa02604dd86224a6f66ec4f84d7bf99318 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -757,7 +757,7 @@ public abstract class EntityInsentient extends EntityLiving { this.goalSelector.doTick(); //this.world.getMethodProfiler().exit(); // Akarin - remove caller //this.world.getMethodProfiler().enter("navigation"); // Akarin - remove caller - this.navigation.c(); + this.navigation.tickAsync(); // Akarin - Async pathfinder //this.world.getMethodProfiler().exit(); // Akarin - remove caller //this.world.getMethodProfiler().enter("mob tick"); // Akarin - remove caller this.mobTick(); diff --git a/src/main/java/net/minecraft/server/Navigation.java b/src/main/java/net/minecraft/server/Navigation.java index 681465d8a74831461dce4615d2d19c7ed46bc299..f04411a2a295d2a982dca5851ae76a80a6a83585 100644 --- a/src/main/java/net/minecraft/server/Navigation.java +++ b/src/main/java/net/minecraft/server/Navigation.java @@ -183,7 +183,7 @@ public class Navigation extends NavigationAbstract { double d3 = (double) j2 + 0.5D - vec3d.z; if (d2 * d0 + d3 * d1 >= 0.0D) { - PathType pathtype = this.o.a(this.b, i2, j - 1, j2, this.a, l, i1, j1, true, true); + PathType pathtype = this.o.a(this.o.a, i2, j - 1, j2, this.a, l, i1, j1, true, true); // Akarin - use chunk cache if (!this.a(pathtype)) { return false; diff --git a/src/main/java/net/minecraft/server/NavigationAbstract.java b/src/main/java/net/minecraft/server/NavigationAbstract.java index 2405dc5e9a6a971a565c37710b61d5fc4737bdf8..2dac507e9e0044a32ae54ea57eada0de04c1467d 100644 --- a/src/main/java/net/minecraft/server/NavigationAbstract.java +++ b/src/main/java/net/minecraft/server/NavigationAbstract.java @@ -28,6 +28,15 @@ public abstract class NavigationAbstract { private int q; private float r; private final Pathfinder s; public Pathfinder getPathfinder() { return this.s; } // Paper - OBFHELPER + // Akarin start - Async pathfinder + private long lastPathfindAsync; + private static final java.util.concurrent.ExecutorService pathfindExecutor = + java.util.concurrent.Executors.newSingleThreadExecutor( + new com.google.common.util.concurrent.ThreadFactoryBuilder() + .setDaemon(true) + .setNameFormat("StarLink Pathfinder - %d") + .build()); + // Akarin end // Tuinity start public boolean isViableForPathRecalculationChecking() { @@ -83,7 +92,40 @@ public abstract class NavigationAbstract { } } + // Akarin start - Async pathfinder, copied from above with modification + public void doPathfindAsync() { + if (this.b.getTime() - this.lastPathfindAsync > 20L) { + if (this.p != null) { + this.lastPathfindAsync = this.b.getTime(); + + // Bake chunk cache + float f = (float) this.a.b(GenericAttributes.FOLLOW_RANGE);; + BlockPosition blockposition = this.a.getChunkCoordinates(); + int k = (int) (f + (float) 8); + ChunkCache cache = new ChunkCache(this.b, blockposition.b(-k, -k, -k), blockposition.b(k, k, k)); + + // Execute directly if we already have a path entity, or compute one + if (this.c != null && !this.c.b()) { + doTickAsync(this.c); + return; + } + pathfindExecutor.execute(() -> { + PathEntity result = findPathAsync(cache, java.util.Collections.singleton(this.p), this.q); + NavigationAbstract.this.b.getMinecraftServer().processQueue.add(() -> { + if (result != null && result.m() != null) + this.p = result.m(); + + NavigationAbstract.this.c = result; + }); + }); + } + } else { + // Execute directly, keep behaviour with vanilla, see the original doTick method + doTickAsync(this.c); + } + } + // Akarin end @Nullable public final PathEntity calculateDestination(double d0, double d1, double d2) { return a(d0, d1, d2, 0); } public final PathEntity a(double d0, double d1, double d2, int i) { // Paper - OBFHELPER return this.a(new BlockPosition(d0, d1, d2), i); @@ -164,7 +206,17 @@ public abstract class NavigationAbstract { return pathentity; } } - + // Akarin start - Async pathfinder, copied and edited from above with only pathfinding + protected PathEntity findPathAsync(ChunkCache cache, Set set, int j) { + if (this.a.locY() < 0.0D) { + return null; + } else if (!this.a()) { + return null; + } else { + return this.s.a(cache, this.a, set, f, j, this.r); + } + } + // Akarin end public boolean a(double d0, double d1, double d2, double d3) { return this.a(this.a(d0, d1, d2, 1), d3); } @@ -228,7 +280,7 @@ public abstract class NavigationAbstract { return this.c; } - public void c() { +/* public void c() { ++this.e; if (this.m) { this.j(); @@ -238,7 +290,7 @@ public abstract class NavigationAbstract { Vec3D vec3d; if (this.a()) { - this.l(); + //this.l(); } else if (this.c != null && this.c.f() < this.c.e()) { vec3d = this.b(); Vec3D vec3d1 = this.c.a(this.a, this.c.f()); @@ -256,9 +308,44 @@ public abstract class NavigationAbstract { this.a.getControllerMove().a(vec3d.x, this.b.getType(blockposition.down()).isAir() ? vec3d.y : PathfinderNormal.a((IBlockAccess) this.b, blockposition), vec3d.z, this.d); } } + }*/ + //Yatopia Start + public void c() { + this.tickAsync(); + } + //Yatopia End + // Akarin start - Async pathfinder, copied from above + public void tickAsync() { + ++this.e; + this.doPathfindAsync(); } - protected void l() { + // This was copied from above partly with param + public void doTickAsync(PathEntity pathEntity) { + if (shouldContinuePathfind(pathEntity)) + return; + + Vec3D vec3d; + if (this.a()) { + this.applyPath(pathEntity); + } else if (pathEntity.f() < pathEntity.e()) { + vec3d = this.b(); + Vec3D vec3d1 = pathEntity.a(this.a, pathEntity.f()); + + if (vec3d.y > vec3d1.y && !this.a.isOnGround() && MathHelper.floor(vec3d.x) == MathHelper.floor(vec3d1.x) && MathHelper.floor(vec3d.z) == MathHelper.floor(vec3d1.z)) { + pathEntity.c(pathEntity.f() + 1); + } + } + + if (shouldContinuePathfind(pathEntity)) + return; + //PacketDebug.a(this.b, this.a, pathEntity, this.l); + vec3d = pathEntity.a((Entity) this.a); + BlockPosition blockposition = new BlockPosition(vec3d); + + this.a.getControllerMove().a(vec3d.x, this.b.getType(blockposition.down()).isAir() ? vec3d.y : PathfinderNormal.a((IBlockAccess) this.b, blockposition), vec3d.z, this.d); + } +/* protected void l() { Vec3D vec3d = this.b(); this.l = this.a.getWidth() > 0.75F ? this.a.getWidth() / 2.0F : 0.75F - this.a.getWidth() / 2.0F; @@ -273,8 +360,26 @@ public abstract class NavigationAbstract { } this.a(vec3d); - } + }*/ + + // Akarin start - Async pathfinder, copied from above with param + protected void applyPath(PathEntity pathEntity) { + Vec3D vec3d = this.b(); + + this.l = this.a.getWidth() > 0.75F ? this.a.getWidth() / 2.0F : 0.75F - this.a.getWidth() / 2.0F; + BaseBlockPosition baseblockposition = pathEntity.g(); + double d0 = Math.abs(this.a.locX() - ((double) baseblockposition.getX() + 0.5D)); + double d1 = Math.abs(this.a.locY() - (double) baseblockposition.getY()); + double d2 = Math.abs(this.a.locZ() - ((double) baseblockposition.getZ() + 0.5D)); + boolean flag = d0 < (double) this.l && d2 < (double) this.l && d1 < 1.0D; + if (flag || this.a.b(pathEntity.h().l) && this.b(vec3d)) { + pathEntity.c(pathEntity.f() + 1); + } + + this.applyPath0(pathEntity, vec3d); + } + // Akarin end private boolean b(Vec3D vec3d) { if (this.c.e() <= this.c.f() + 1) { return false; @@ -324,7 +429,39 @@ public abstract class NavigationAbstract { } } + // Akarin start - Async pathfinder, copied from above with param + protected void applyPath0(PathEntity pathEntity, Vec3D vec3d) { + if (this.e - this.f > 100) { + if (vec3d.distanceSquared(this.g) < 2.25D) { + this.o(); + } + + this.f = this.e; + this.g = vec3d; + } + + if (!pathEntity.b()) { + BaseBlockPosition baseblockposition = pathEntity.g(); + + if (baseblockposition.equals(this.h)) { + this.i += SystemUtils.getMonotonicMillis() - this.j; + } else { + this.h = baseblockposition; + double d0 = vec3d.f(Vec3D.c(this.h)); + + this.k = this.a.dM() > 0.0F ? d0 / (double) this.a.dM() * 1000.0D : 0.0D; + } + + if (this.k > 0.0D && (double) this.i > this.k * 3.0D) { + this.e(); + this.o(); + } + + this.j = SystemUtils.getMonotonicMillis(); + } + } + // Akarin end private void e() { this.h = BaseBlockPosition.ZERO; this.i = 0L; @@ -389,7 +526,11 @@ public abstract class NavigationAbstract { public boolean r() { return this.o.e(); } - + // Akarin start - Async pathfinder, copied from above with param + public static boolean shouldContinuePathfind(PathEntity pathEntity) { + return pathEntity == null || pathEntity.b(); + } + // Akarin end public void b(BlockPosition blockposition) { if (this.c != null && !this.c.b() && this.c.e() != 0) { // Tuinity - diff on change - needed for isViableForPathRecalculationChecking() PathPoint pathpoint = this.c.c(); diff --git a/src/main/java/net/minecraft/server/NavigationFlying.java b/src/main/java/net/minecraft/server/NavigationFlying.java index 0c33a0c9d59d79a39826b5ee14144604717ffebe..cf3f4c1a2a89cce0345566a62faa34ef7e93c603 100644 --- a/src/main/java/net/minecraft/server/NavigationFlying.java +++ b/src/main/java/net/minecraft/server/NavigationFlying.java @@ -28,7 +28,7 @@ public class NavigationFlying extends NavigationAbstract { return this.a(entity.getChunkCoordinates(), entity, i); // Paper - Forward target entity } - @Override +/* @Override public void c() { ++this.e; if (this.m) { @@ -53,6 +53,31 @@ public class NavigationFlying extends NavigationAbstract { this.a.getControllerMove().a(vec3d.x, vec3d.y, vec3d.z, this.d); } } + }*/ + + // This was copied from above partly with param + @Override + public void doTickAsync(PathEntity pathEntity) { + if (shouldContinuePathfind(pathEntity)) + return; + + Vec3D vec3d; + if (this.a()) { + this.applyPath(pathEntity); + } else if (pathEntity != null && pathEntity.f() < pathEntity.e()) { + vec3d = pathEntity.a(this.a, pathEntity.f()); + if (MathHelper.floor(this.a.locX()) == MathHelper.floor(vec3d.x) && MathHelper.floor(this.a.locY()) == MathHelper.floor(vec3d.y) && MathHelper.floor(this.a.locZ()) == MathHelper.floor(vec3d.z)) { + pathEntity.c(pathEntity.f() + 1); + } + } + + if (shouldContinuePathfind(pathEntity)) + return; + //PacketDebug.a(this.b, this.a, pathEntity, this.l); + vec3d = pathEntity.a((Entity) this.a); + BlockPosition blockposition = new BlockPosition(vec3d); + + this.a.getControllerMove().a(vec3d.x, vec3d.y, vec3d.z, this.d); } @Override diff --git a/src/main/java/net/minecraft/server/Pathfinder.java b/src/main/java/net/minecraft/server/Pathfinder.java index 1c3a8043e735ec4605635efcfc5deb08a35ea1fd..bf2ac046eebd7f88fcb1d953f37952e791e6ea83 100644 --- a/src/main/java/net/minecraft/server/Pathfinder.java +++ b/src/main/java/net/minecraft/server/Pathfinder.java @@ -26,7 +26,7 @@ public class Pathfinder { } @Nullable - public PathEntity a(ChunkCache chunkcache, EntityInsentient entityinsentient, Set set, float f, int i, float f1) { + public synchronized PathEntity a(ChunkCache chunkcache, EntityInsentient entityinsentient, Set set, float f, int i, float f1) { // Akarin - synchronized this.d.a(); this.c.a(chunkcache, entityinsentient); PathPoint pathpoint = this.c.b(); diff --git a/src/main/java/net/minecraft/server/PathfinderTurtle.java b/src/main/java/net/minecraft/server/PathfinderTurtle.java index cea160885783e8666b616375eac44ba6d1880e1f..9598563b4f97500fd3fba0165813d564d9c96c4f 100644 --- a/src/main/java/net/minecraft/server/PathfinderTurtle.java +++ b/src/main/java/net/minecraft/server/PathfinderTurtle.java @@ -148,7 +148,7 @@ public class PathfinderTurtle extends PathfinderNormal { if (pathtype == PathType.OPEN) { AxisAlignedBB axisalignedbb = new AxisAlignedBB((double) i - d2 + 0.5D, (double) j + 0.001D, (double) k - d2 + 0.5D, (double) i + d2 + 0.5D, (double) ((float) j + this.b.getHeight()), (double) k + d2 + 0.5D); - if (!this.b.world.getCubes(this.b, axisalignedbb)) { + if (!this.a.getCubes(this.b, axisalignedbb)) { // Akarin - use chunk cache return null; } diff --git a/src/main/java/net/minecraft/server/PathfinderWater.java b/src/main/java/net/minecraft/server/PathfinderWater.java index fba6692a1e537b90e20aa448567c0ad6db653332..d576edc8c30288e98aeda8f1cb561b22c6b37536 100644 --- a/src/main/java/net/minecraft/server/PathfinderWater.java +++ b/src/main/java/net/minecraft/server/PathfinderWater.java @@ -63,7 +63,7 @@ public class PathfinderWater extends PathfinderAbstract { @Override protected PathPoint a(int i, int j, int k) { PathPoint pathpoint = null; - PathType pathtype = this.a(this.b.world, i, j, k); + PathType pathtype = this.a(this.a, i, j, k); // Akarin - use chunk cache float f = this.b.a(pathtype); if (f >= 0.0F) {