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;