diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index 9f7507a2e..a4fc1140a 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -69,9 +69,6 @@ public class MinecraftServer { public static final String THREAD_NAME_BLOCK_BATCH = "Ms-BlockBatchPool"; public static final int THREAD_COUNT_BLOCK_BATCH = 2; - public static final String THREAD_NAME_ENTITIES_PATHFINDING = "Ms-EntitiesPathFinding"; - public static final int THREAD_COUNT_ENTITIES_PATHFINDING = 2; - public static final String THREAD_NAME_SCHEDULER = "Ms-SchedulerPool"; public static final int THREAD_COUNT_SCHEDULER = 1; diff --git a/src/main/java/net/minestom/server/attribute/Attribute.java b/src/main/java/net/minestom/server/attribute/Attribute.java index 96ff9d141..37fe8aaa7 100644 --- a/src/main/java/net/minestom/server/attribute/Attribute.java +++ b/src/main/java/net/minestom/server/attribute/Attribute.java @@ -5,7 +5,7 @@ public enum Attribute { MAX_HEALTH("generic.max_health", 20, 1024), FOLLOW_RANGE("generic.follow_range", 32, 2048), KNOCKBACK_RESISTANCE("generic.knockback_resistance", 0, 1), - MOVEMENT_SPEED("generic.movement_speed", 0.7f, 1024), + MOVEMENT_SPEED("generic.movement_speed", 0.2f, 1024), ATTACK_DAMAGE("generic.attack_damage", 2, 2048), ATTACK_SPEED("generic.attack_speed", 4, 1024), FLYING_SPEED("generic.flying_speed", 0.4f, 1024), diff --git a/src/main/java/net/minestom/server/benchmark/BenchmarkManager.java b/src/main/java/net/minestom/server/benchmark/BenchmarkManager.java index a7b7dad87..23b83fcb0 100644 --- a/src/main/java/net/minestom/server/benchmark/BenchmarkManager.java +++ b/src/main/java/net/minestom/server/benchmark/BenchmarkManager.java @@ -24,7 +24,6 @@ public class BenchmarkManager { threads.add(THREAD_NAME_MAIN_UPDATE); threads.add(THREAD_NAME_PACKET_WRITER); threads.add(THREAD_NAME_BLOCK_BATCH); - threads.add(THREAD_NAME_ENTITIES_PATHFINDING); threads.add(THREAD_NAME_SCHEDULER); threads.add(THREAD_NAME_TICK); } diff --git a/src/main/java/net/minestom/server/entity/EntityCreature.java b/src/main/java/net/minestom/server/entity/EntityCreature.java index 3b8dba6c5..23e26f237 100644 --- a/src/main/java/net/minestom/server/entity/EntityCreature.java +++ b/src/main/java/net/minestom/server/entity/EntityCreature.java @@ -3,7 +3,7 @@ package net.minestom.server.entity; import com.extollit.gaming.ai.path.HydrazinePathFinder; import com.extollit.gaming.ai.path.model.PathObject; import net.minestom.server.collision.CollisionUtils; -import net.minestom.server.entity.pathfinding.hydrazine.PFPathingEntity; +import net.minestom.server.entity.pathfinding.PFPathingEntity; import net.minestom.server.event.entity.EntityAttackEvent; import net.minestom.server.event.item.ArmorEquipEvent; import net.minestom.server.instance.Instance; @@ -52,8 +52,12 @@ public abstract class EntityCreature extends LivingEntity { // Path finding path = pathFinder.update(); - if (path != null) + if (path != null) { path.update(pathingEntity); + if (path.done()) { + pathFinder.reset(); + } + } } @Override @@ -261,6 +265,14 @@ public abstract class EntityCreature extends LivingEntity { setVelocity(velocity); } + /** + * Retrieve the path to {@code position} and ask the entity to follow the path + *

+ * The position is cloned, if you want the entity to continually follow this position object + * you need to call this when you want the path to update + * + * @param position the position to find the path to + */ public void setPathTo(Position position) { position = position.clone(); this.path = pathFinder.initiatePathTo(position.getX(), position.getY(), position.getZ()); diff --git a/src/main/java/net/minestom/server/entity/pathfinding/AStarPathfinder.java b/src/main/java/net/minestom/server/entity/pathfinding/AStarPathfinder.java deleted file mode 100644 index 7d04cfe8a..000000000 --- a/src/main/java/net/minestom/server/entity/pathfinding/AStarPathfinder.java +++ /dev/null @@ -1,187 +0,0 @@ -package net.minestom.server.entity.pathfinding; - -import net.minestom.server.instance.Instance; -import net.minestom.server.instance.block.Block; -import net.minestom.server.utils.BlockPosition; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -public class AStarPathfinder { - - // TODO ladder, jump, etc... - // TODO include BoundingBox support - - private boolean canClimbLadder; - private boolean canSwim; - private boolean canJump; - - public static LinkedList getPath(Instance instance, - BlockPosition start, BlockPosition end, - int maxCheck) { - long time = System.nanoTime(); - List open = new ArrayList<>(); - List closed = new ArrayList<>(); - - Node startNode = Node.fromBlockPosition(start); - Node endNode = Node.fromBlockPosition(end); - - open.add(startNode); - - int checkCount = 0; - - while (!open.isEmpty()) { - Node current = getCurrentNode(open); - open.remove(current); - closed.add(current); - - if (isTargetNode(end, current)) { - System.out.println("found in: " + (System.nanoTime() - time) + " ns"); - return buildPath(current); - } - - for (Node neighbor : getNeighbors(instance, current)) { - if (isInList(closed, neighbor)) - continue; - - boolean isInOpen = isInList(open, neighbor); - if (isShorter(neighbor, current) || !isInOpen) { - - neighbor.parent = current; - neighbor.g = getTentativeGScore(neighbor, current); - neighbor.f = neighbor.g + getDistance(neighbor, endNode); - if (!isInOpen) { - open.add(neighbor); - } - } - } - - // To do not check the whole world - checkCount++; - if (checkCount >= maxCheck) - break; - } - - return null; - } - - private static List getNeighbors(Instance instance, Node current) { - List result = new ArrayList<>(); - BlockPosition currentBlockPosition = current.getBlockPosition(); - - for (int x = -1; x < 2; x++) { - for (int y = -1; y < 2; y++) { - for (int z = -1; z < 2; z++) { - if (x == 0 && y == 0 && z == 0) - continue; - BlockPosition neighbor = currentBlockPosition.clone().add(x, y, z); - if (canAccessBlock(instance, currentBlockPosition, neighbor)) { - Node node = Node.fromBlockPosition(neighbor); - result.add(node); - } - } - } - } - - return result; - } - - private static Node getCurrentNode(List open) { - Node closest = null; - - for (Node node : open) { - if (closest == null || node.f < closest.f) { - closest = node; - } - } - - return closest; - } - - private static boolean isTargetNode(BlockPosition target, Node node) { - return target.getX() == node.getX() && - target.getY() == node.getY() && - target.getZ() == node.getZ(); - } - - private static boolean canAccessBlock(Instance instance, BlockPosition current, BlockPosition target) { - if (instance.getChunkAt(target) == null) - return false; - - Block targetBlock = Block.fromId(instance.getBlockId(target)); - Block belowBlock = Block.fromId(instance.getBlockId(target.clone().add(0, -1, 0))); - - boolean result = !targetBlock.isSolid() && belowBlock.isSolid(); - return result; - } - - private static boolean isInList(List list, Node node) { - for (Node close : list) { - if (close.getX() == node.getX() && - close.getY() == node.getY() && - close.getZ() == node.getZ()) - return true; - } - return false; - } - - private static int getDistance(Node node1, Node node2) { - return node1.blockPosition.getDistance(node2.blockPosition); - } - - private static int getTentativeGScore(Node neighbor, Node current) { - return neighbor.g + getDistance(neighbor, current); - } - - private static boolean isShorter(Node neighbor, Node current) { - return getTentativeGScore(neighbor, current) < neighbor.g; - } - private static LinkedList buildPath(Node finalNode) { - LinkedList result = new LinkedList<>(); - Node cache = finalNode; - while (cache != null) { - result.add(cache.blockPosition); - cache = cache.parent; - } - // Make the list start->end - Collections.reverse(result); - return result; - } - - private static class Node { - public int g, f; - public Node parent; - private int x, y, z; - private BlockPosition blockPosition; - - public Node(BlockPosition blockPosition) { - this.x = blockPosition.getX(); - this.y = blockPosition.getY(); - this.z = blockPosition.getZ(); - this.blockPosition = blockPosition.clone(); - } - - public static Node fromBlockPosition(BlockPosition blockPosition) { - Node node = new Node(blockPosition); - return node; - } - - public int getX() { - return x; - } - - public int getY() { - return y; - } - - public int getZ() { - return z; - } - - public BlockPosition getBlockPosition() { - return blockPosition; - } - } -} diff --git a/src/main/java/net/minestom/server/entity/pathfinding/EntityPathFinder.java b/src/main/java/net/minestom/server/entity/pathfinding/EntityPathFinder.java deleted file mode 100644 index 41b48e8b2..000000000 --- a/src/main/java/net/minestom/server/entity/pathfinding/EntityPathFinder.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.minestom.server.entity.pathfinding; - -import net.minestom.server.MinecraftServer; -import net.minestom.server.entity.Entity; -import net.minestom.server.instance.Instance; -import net.minestom.server.utils.BlockPosition; -import net.minestom.server.utils.Position; -import net.minestom.server.utils.thread.MinestomThread; - -import java.util.LinkedList; -import java.util.concurrent.ExecutorService; -import java.util.function.Consumer; - -public class EntityPathFinder { - - private static ExecutorService pathfindingPool = new MinestomThread(MinecraftServer.THREAD_COUNT_ENTITIES_PATHFINDING, MinecraftServer.THREAD_NAME_ENTITIES_PATHFINDING); - - - private Entity entity; - - public EntityPathFinder(Entity entity) { - this.entity = entity; - } - - public void getPath(Position target, int maxCheck, Consumer> consumer) { - pathfindingPool.execute(() -> { - Instance instance = entity.getInstance(); - BlockPosition start = entity.getPosition().toBlockPosition(); - BlockPosition end = target.toBlockPosition(); - - consumer.accept(AStarPathfinder.getPath(instance, start, end, maxCheck)); - }); - } - -} diff --git a/src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFBlockDescription.java b/src/main/java/net/minestom/server/entity/pathfinding/PFBlockDescription.java similarity index 94% rename from src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFBlockDescription.java rename to src/main/java/net/minestom/server/entity/pathfinding/PFBlockDescription.java index 9e583676b..0d2fa5dbe 100644 --- a/src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFBlockDescription.java +++ b/src/main/java/net/minestom/server/entity/pathfinding/PFBlockDescription.java @@ -1,4 +1,4 @@ -package net.minestom.server.entity.pathfinding.hydrazine; +package net.minestom.server.entity.pathfinding; import com.extollit.gaming.ai.path.model.IBlockDescription; import net.minestom.server.instance.block.Block; diff --git a/src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFBlockObject.java b/src/main/java/net/minestom/server/entity/pathfinding/PFBlockObject.java similarity index 95% rename from src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFBlockObject.java rename to src/main/java/net/minestom/server/entity/pathfinding/PFBlockObject.java index f58a07b4d..7a6e66864 100644 --- a/src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFBlockObject.java +++ b/src/main/java/net/minestom/server/entity/pathfinding/PFBlockObject.java @@ -1,4 +1,4 @@ -package net.minestom.server.entity.pathfinding.hydrazine; +package net.minestom.server.entity.pathfinding; import com.extollit.gaming.ai.path.model.IBlockObject; import com.extollit.linalg.immutable.AxisAlignedBBox; diff --git a/src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFColumnarSpace.java b/src/main/java/net/minestom/server/entity/pathfinding/PFColumnarSpace.java similarity index 95% rename from src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFColumnarSpace.java rename to src/main/java/net/minestom/server/entity/pathfinding/PFColumnarSpace.java index dfbadf46c..83f412aa3 100644 --- a/src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFColumnarSpace.java +++ b/src/main/java/net/minestom/server/entity/pathfinding/PFColumnarSpace.java @@ -1,4 +1,4 @@ -package net.minestom.server.entity.pathfinding.hydrazine; +package net.minestom.server.entity.pathfinding; import com.extollit.gaming.ai.path.model.ColumnarOcclusionFieldList; import com.extollit.gaming.ai.path.model.IBlockDescription; diff --git a/src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFInstanceSpace.java b/src/main/java/net/minestom/server/entity/pathfinding/PFInstanceSpace.java similarity index 95% rename from src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFInstanceSpace.java rename to src/main/java/net/minestom/server/entity/pathfinding/PFInstanceSpace.java index 5f014613e..c4d6ed69d 100644 --- a/src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFInstanceSpace.java +++ b/src/main/java/net/minestom/server/entity/pathfinding/PFInstanceSpace.java @@ -1,4 +1,4 @@ -package net.minestom.server.entity.pathfinding.hydrazine; +package net.minestom.server.entity.pathfinding; import com.extollit.gaming.ai.path.model.IBlockObject; import com.extollit.gaming.ai.path.model.IColumnarSpace; diff --git a/src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFPathingEntity.java b/src/main/java/net/minestom/server/entity/pathfinding/PFPathingEntity.java similarity index 97% rename from src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFPathingEntity.java rename to src/main/java/net/minestom/server/entity/pathfinding/PFPathingEntity.java index c2aac439d..45823942d 100644 --- a/src/main/java/net/minestom/server/entity/pathfinding/hydrazine/PFPathingEntity.java +++ b/src/main/java/net/minestom/server/entity/pathfinding/PFPathingEntity.java @@ -1,4 +1,4 @@ -package net.minestom.server.entity.pathfinding.hydrazine; +package net.minestom.server.entity.pathfinding; import com.extollit.gaming.ai.path.model.IPathingEntity; import com.extollit.linalg.immutable.Vec3d; @@ -75,7 +75,7 @@ public class PFPathingEntity implements IPathingEntity { public void moveTo(Vec3d position) { final Position entityPosition = entity.getPosition(); final float entityY = entityPosition.getY(); - final float speed = entity.getAttributeValue(Attribute.MOVEMENT_SPEED) / 5; + final float speed = entity.getAttributeValue(Attribute.MOVEMENT_SPEED); final float x = (float) position.x; final float y = (float) position.y; final float z = (float) position.z; diff --git a/src/main/java/net/minestom/server/instance/Instance.java b/src/main/java/net/minestom/server/instance/Instance.java index c1468aa4a..2c9d2bb19 100644 --- a/src/main/java/net/minestom/server/instance/Instance.java +++ b/src/main/java/net/minestom/server/instance/Instance.java @@ -5,7 +5,7 @@ import net.minestom.server.MinecraftServer; import net.minestom.server.data.Data; import net.minestom.server.data.DataContainer; import net.minestom.server.entity.*; -import net.minestom.server.entity.pathfinding.hydrazine.PFInstanceSpace; +import net.minestom.server.entity.pathfinding.PFInstanceSpace; import net.minestom.server.event.Event; import net.minestom.server.event.EventCallback; import net.minestom.server.event.handler.EventHandler;