Merge pull request #20 from Minestom/smooth-pathfinding

Smooth pathfinding
This commit is contained in:
TheMode 2020-07-31 21:13:08 +02:00 committed by GitHub
commit aada943f91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 9 deletions

View File

@ -53,7 +53,7 @@ public class SimpleCommand implements CommandProcessor {
Instance instance = player.getInstance(); Instance instance = player.getInstance();
ChickenCreature chickenCreature = new ChickenCreature(new Position(-10, 40, -10)); ChickenCreature chickenCreature = new ChickenCreature(new Position(-10, 43, -10));
chickenCreature.setInstance(instance); chickenCreature.setInstance(instance);
chickenCreature.setPathTo(player.getPosition()); chickenCreature.setPathTo(player.getPosition());

View File

@ -428,7 +428,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
sendSynchronization(); sendSynchronization();
if (shouldSendVelocityUpdate(time)) { if (shouldSendVelocityUpdate(time)) {
sendPacketToViewersAndSelf(getVelocityPacket()); sendVelocityPacket();
lastVelocityUpdateTime = time; lastVelocityUpdateTime = time;
} }
} }
@ -482,6 +482,13 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
} }
} }
/**
* Equivalent to <code>sendPacketsToViewers(getVelocityPacket());</code>
*/
public void sendVelocityPacket() {
sendPacketsToViewers(getVelocityPacket());
}
/** /**
* Get the number of ticks this entity has been active for * Get the number of ticks this entity has been active for
* *

View File

@ -2,6 +2,7 @@ package net.minestom.server.entity;
import com.extollit.gaming.ai.path.HydrazinePathFinder; import com.extollit.gaming.ai.path.HydrazinePathFinder;
import com.extollit.gaming.ai.path.model.PathObject; import com.extollit.gaming.ai.path.model.PathObject;
import net.minestom.server.MinecraftServer;
import net.minestom.server.attribute.Attribute; import net.minestom.server.attribute.Attribute;
import net.minestom.server.collision.CollisionUtils; import net.minestom.server.collision.CollisionUtils;
import net.minestom.server.entity.pathfinding.PFPathingEntity; import net.minestom.server.entity.pathfinding.PFPathingEntity;
@ -50,8 +51,6 @@ public abstract class EntityCreature extends LivingEntity {
@Override @Override
public void update(long time) { public void update(long time) {
super.update(time);
// Path finding // Path finding
path = pathFinder.update(); path = pathFinder.update();
if (path != null) { if (path != null) {
@ -61,12 +60,11 @@ public abstract class EntityCreature extends LivingEntity {
} else { } else {
final float speed = getAttributeValue(Attribute.MOVEMENT_SPEED); final float speed = getAttributeValue(Attribute.MOVEMENT_SPEED);
Position targetPosition = pathingEntity.getTargetPosition(); Position targetPosition = pathingEntity.getTargetPosition();
//targetPosition = new Position(-5.5f, 40f, -5.5f);
//System.out.println("target: " + targetPosition + " : " + (System.currentTimeMillis() - time));
//System.out.println("current: " + getPosition());
moveTowards(targetPosition, speed); moveTowards(targetPosition, speed);
} }
} }
super.update(time);
} }
@Override @Override
@ -82,6 +80,7 @@ public abstract class EntityCreature extends LivingEntity {
* @param updateView should the entity move its head toward the position? * @param updateView should the entity move its head toward the position?
*/ */
public void move(float x, float y, float z, boolean updateView) { public void move(float x, float y, float z, boolean updateView) {
// TODO: remove ? Entity#tick already performs this behaviour, and syncs it properly
final Position position = getPosition(); final Position position = getPosition();
Position newPosition = new Position(); Position newPosition = new Position();
// Calculate collisions boxes // Calculate collisions boxes
@ -296,6 +295,7 @@ public abstract class EntityCreature extends LivingEntity {
/** /**
* Used to move the entity toward {@code direction} in the X and Z axis * Used to move the entity toward {@code direction} in the X and Z axis
* Gravity is still applied but the entity will not attempt to jump * Gravity is still applied but the entity will not attempt to jump
* Also update the yaw/pitch of the entity to look along 'direction'
* *
* @param direction the targeted position * @param direction the targeted position
* @param speed define how far the entity will move * @param speed define how far the entity will move
@ -306,12 +306,34 @@ public abstract class EntityCreature extends LivingEntity {
final float currentZ = position.getZ(); final float currentZ = position.getZ();
final float targetX = direction.getX(); final float targetX = direction.getX();
final float targetZ = direction.getZ(); final float targetZ = direction.getZ();
final float dz = targetZ - currentZ;
final float dx = targetX - currentX;
final float radians = (float) Math.atan2(targetZ - currentZ, targetX - currentX); // the purpose of these few lines is to slow down entities when they reach their destination
float distSquared = dx * dx + dz * dz;
if(speed > distSquared) {
speed = distSquared;
}
final float radians = (float) Math.atan2(dz, dx);
final float speedX = (float) (Math.cos(radians) * speed); final float speedX = (float) (Math.cos(radians) * speed);
final float speedZ = (float) (Math.sin(radians) * speed); final float speedZ = (float) (Math.sin(radians) * speed);
move(speedX, 0, speedZ, true); lookAlong(dx, direction.getY(), dz);
// TODO: is a hard set an issue if there are other external forces at play?
final float tps = MinecraftServer.TICK_PER_SECOND;
velocity.setX(speedX * tps);
velocity.setZ(speedZ * tps);
}
private void lookAlong(float dx, float dy, float dz) {
final float horizontalAngle = (float) Math.atan2(dz, dx);
final float yaw = (float) (horizontalAngle * (180.0 / Math.PI)) - 90;
final float pitch = (float) Math.atan2(dy, Math.max(Math.abs(dx), Math.abs(dz)));
getPosition().setYaw(yaw);
getPosition().setPitch(pitch);
} }
private ItemStack getEquipmentItem(ItemStack itemStack, ArmorEquipEvent.ArmorSlot armorSlot) { private ItemStack getEquipmentItem(ItemStack itemStack, ArmorEquipEvent.ArmorSlot armorSlot) {