Hydrazine fix + basic pathfinding api

This commit is contained in:
Felix Cravic 2020-07-24 02:31:10 +02:00
parent 2ea4c2d996
commit 7b5107f59d
8 changed files with 79 additions and 98 deletions

View File

@ -26,9 +26,7 @@ import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.item.metadata.MapMeta;
import net.minestom.server.network.ConnectionManager;
import net.minestom.server.network.packet.server.play.MapDataPacket;
import net.minestom.server.ping.ResponseDataConsumer;
import net.minestom.server.timer.TaskRunnable;
import net.minestom.server.utils.MathUtils;
@ -54,7 +52,7 @@ public class PlayerInit {
//instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(storageFolder);
instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(DimensionType.OVERWORLD);
instanceContainer.enableAutoChunkLoad(true);
instanceContainer.setChunkGenerator(chunkGeneratorDemo);
instanceContainer.setChunkGenerator(noiseTestGenerator);
netherTest = MinecraftServer.getInstanceManager().createInstanceContainer(DimensionType.NETHER);
netherTest.enableAutoChunkLoad(true);
@ -247,7 +245,7 @@ public class PlayerInit {
player.getInventory().setItemStack(i, new ItemStack(Material.STONE, (byte) 127));
}*/
ItemStack map = new ItemStack(Material.FILLED_MAP, (byte) 1);
/*ItemStack map = new ItemStack(Material.FILLED_MAP, (byte) 1);
MapMeta mapMeta = (MapMeta) map.getItemMeta();
mapMeta.setMapId(1);
player.getInventory().setItemStack(0, map);
@ -275,7 +273,7 @@ public class PlayerInit {
player.getPlayerConnection().sendPacket(mapDataPacket);
}
}*/
ItemStack item = new ItemStack(Material.STONE_SWORD, (byte) 1);

View File

@ -1,17 +1,11 @@
package fr.themode.demo.commands;
import com.extollit.gaming.ai.path.HydrazinePathFinder;
import com.extollit.gaming.ai.path.model.PathObject;
import com.extollit.linalg.immutable.Vec3i;
import fr.themode.demo.entity.ChickenCreature;
import net.minestom.server.command.CommandProcessor;
import net.minestom.server.command.CommandSender;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.pathfinding.hydrazine.PFInstanceSpace;
import net.minestom.server.entity.pathfinding.hydrazine.PFPathingEntity;
import net.minestom.server.instance.Instance;
import java.util.Iterator;
import net.minestom.server.utils.Position;
public class SimpleCommand implements CommandProcessor {
@Override
@ -59,24 +53,10 @@ public class SimpleCommand implements CommandProcessor {
Instance instance = player.getInstance();
ChickenCreature chickenCreature = new ChickenCreature(player.getPosition());
ChickenCreature chickenCreature = new ChickenCreature(new Position(-10, 42, -10));
chickenCreature.setInstance(instance);
PFPathingEntity pathingEntity = new PFPathingEntity(chickenCreature);
PFInstanceSpace instanceSpace = new PFInstanceSpace(instance);
final HydrazinePathFinder pathFinder = new HydrazinePathFinder(pathingEntity, instanceSpace);
final PathObject path = pathFinder.initiatePathTo(-10, 40, -10);
System.out.println("path: " + path);
for (Iterator<Vec3i> it = path.iterator(); it.hasNext(); ) {
Vec3i ite = it.next();
System.out.println("test: " + ite);
}
chickenCreature.setPathTo(player.getPosition());
return true;
}

View File

@ -1,28 +1,26 @@
package net.minestom.server.entity;
import net.minestom.server.attribute.Attribute;
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.EntityPathFinder;
import net.minestom.server.entity.pathfinding.hydrazine.PFPathingEntity;
import net.minestom.server.event.entity.EntityAttackEvent;
import net.minestom.server.event.item.ArmorEquipEvent;
import net.minestom.server.instance.Instance;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.packet.server.play.*;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Vector;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.utils.item.ItemStackUtils;
import net.minestom.server.utils.time.TimeUnit;
import java.util.LinkedList;
import java.util.function.Consumer;
public abstract class EntityCreature extends LivingEntity {
private EntityPathFinder pathFinder = new EntityPathFinder(this);
private LinkedList<BlockPosition> blockPositions;
private Position targetPosition;
private PFPathingEntity pathingEntity = new PFPathingEntity(this);
private HydrazinePathFinder pathFinder;
private PathObject path;
// Equipments
private ItemStack mainHandItem;
@ -53,7 +51,15 @@ public abstract class EntityCreature extends LivingEntity {
super.update(time);
// Path finding
pathProgress();
path = pathFinder.update();
if (path != null)
path.update(pathingEntity);
}
@Override
public void setInstance(Instance instance) {
super.setInstance(instance);
this.pathFinder = new HydrazinePathFinder(pathingEntity, instance.getInstanceSpace());
}
/**
@ -128,7 +134,7 @@ public abstract class EntityCreature extends LivingEntity {
@Override
public boolean addViewer(Player player) {
boolean result = super.addViewer(player);
final boolean result = super.addViewer(player);
if (!result)
return false;
@ -251,34 +257,13 @@ public abstract class EntityCreature extends LivingEntity {
public void jump(float height) {
// FIXME magic value
Vector velocity = new Vector(0, height * 5, 0);
final Vector velocity = new Vector(0, height * 5, 0);
setVelocity(velocity);
}
public void setPathTo(Position position, int maxCheck, Consumer<Boolean> resultConsumer) {
pathFinder.getPath(position, maxCheck, blockPositions -> {
if (blockPositions == null || blockPositions.isEmpty()) {
// Didn't find path
if (resultConsumer != null)
resultConsumer.accept(false);
return;
}
blockPositions.pollFirst(); // Remove first entry (where the entity is)
this.blockPositions = blockPositions;
setNextPathPosition();
if (resultConsumer != null)
resultConsumer.accept(true);
});
}
public void setPathTo(Position position, int maxCheck) {
setPathTo(position, maxCheck, null);
}
public void setPathTo(Position position) {
setPathTo(position, 1000, null);
position = position.clone();
this.path = pathFinder.initiatePathTo(position.getX(), position.getY(), position.getZ());
}
/**
@ -295,37 +280,6 @@ public abstract class EntityCreature extends LivingEntity {
move(speedX, 0, speedZ, true);
}
private void setNextPathPosition() {
final BlockPosition blockPosition = blockPositions.pollFirst();
if (blockPosition == null) {
this.blockPositions = null;
this.targetPosition = null;
return;
}
this.targetPosition = blockPosition.toPosition();//.add(0.5f, 0, 0.5f);
if (blockPosition.getY() > getPosition().getY())
jump(1);
}
private void pathProgress() {
if (blockPositions != null) {
if (targetPosition != null) {
final float distance = getPosition().getDistance(targetPosition);
//System.out.println("test: "+distance);
if (distance < 1f) {
setNextPathPosition();
pathProgress();
//System.out.println("END TARGET");
} else {
moveTowards(targetPosition, getAttributeValue(Attribute.MOVEMENT_SPEED));
//System.out.println("MOVE TOWARD " + targetPosition);
}
}
}
}
private ItemStack getEquipmentItem(ItemStack itemStack, ArmorEquipEvent.ArmorSlot armorSlot) {
itemStack = ItemStackUtils.notNull(itemStack);
@ -333,4 +287,15 @@ public abstract class EntityCreature extends LivingEntity {
callEvent(ArmorEquipEvent.class, armorEquipEvent);
return armorEquipEvent.getArmorItem();
}
/**
* Get the pathfinding entity
* <p>
* Used internally by the pathfinder
*
* @return the pathfinding entity
*/
public PFPathingEntity getPathingEntity() {
return pathingEntity;
}
}

View File

@ -28,7 +28,7 @@ public class PFBlockDescription implements IBlockDescription {
@Override
public boolean isImpeding() {
return false;
return block.isSolid();
}
@Override

View File

@ -37,7 +37,7 @@ public class PFBlockObject implements IBlockObject {
@Override
public boolean isImpeding() {
return false;
return block.isSolid();
}
@Override

View File

@ -73,8 +73,16 @@ public class PFPathingEntity implements IPathingEntity {
@Override
public void moveTo(Vec3d position) {
float speed = entity.getAttributeValue(Attribute.MOVEMENT_SPEED);
entity.moveTowards(new Position((float) position.x, (float) position.y, (float) position.z), speed);
final Position entityPosition = entity.getPosition();
final float entityY = entityPosition.getY();
final float speed = entity.getAttributeValue(Attribute.MOVEMENT_SPEED) / 5;
final float x = (float) position.x;
final float y = (float) position.y;
final float z = (float) position.z;
entity.moveTowards(new Position(x, y, z), speed);
if (entityY < y) {
entity.jump(1);
}
}
@Override

View File

@ -5,6 +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.event.Event;
import net.minestom.server.event.EventCallback;
import net.minestom.server.event.handler.EventHandler;
@ -75,6 +76,9 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
private Data data;
private ExplosionSupplier explosionSupplier;
// Pathfinder
private PFInstanceSpace instanceSpace = new PFInstanceSpace(this);
public Instance(UUID uniqueId, DimensionType dimensionType) {
this.uniqueId = uniqueId;
this.dimensionType = dimensionType;
@ -824,4 +828,15 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
public void setExplosionSupplier(ExplosionSupplier supplier) {
this.explosionSupplier = supplier;
}
/**
* Get the instance space
* <p>
* Used by the pathfinder for entities
*
* @return the instance space
*/
public PFInstanceSpace getInstanceSpace() {
return instanceSpace;
}
}

View File

@ -9,12 +9,17 @@ import java.util.Map;
public class BlockManager {
// custom block id -> custom block
private Short2ObjectMap<CustomBlock> customBlocksInternalId = new Short2ObjectOpenHashMap<>();
// custom block identifier -> custom block
private Map<String, CustomBlock> customBlocksId = new HashMap<>();
// block id -> block placement rule
private Short2ObjectOpenHashMap<BlockPlacementRule> placementRules = new Short2ObjectOpenHashMap<>();
/**
* Register a custom block
*
* @param customBlock the custom block to register
*/
public void registerCustomBlock(CustomBlock customBlock) {
@ -25,6 +30,8 @@ public class BlockManager {
}
/**
* Register a block placement rule
*
* @param blockPlacementRule the block placement rule to register
*/
public void registerBlockPlacementRule(BlockPlacementRule blockPlacementRule) {
@ -32,6 +39,8 @@ public class BlockManager {
}
/**
* Get the block placement rule of the specific block
*
* @param blockId the block id to check
* @return the block placement rule associated with the id, null if not any
*/
@ -42,6 +51,8 @@ public class BlockManager {
}
/**
* Get the block placement rule of the specific block
*
* @param block the block to check
* @return the block placement rule associated with the block, null if not any
*/
@ -50,6 +61,8 @@ public class BlockManager {
}
/**
* Get the CustomBlock with the specific identifier {@link CustomBlock#getIdentifier()}
*
* @param identifier the custom block identifier
* @return the {@link CustomBlock} associated with the identifier, null if not any
*/
@ -58,6 +71,8 @@ public class BlockManager {
}
/**
* Get the CustomBlock with the specific custom block id {@link CustomBlock#getCustomBlockId()}
*
* @param id the custom block id
* @return the {@link CustomBlock} associated with the id, null if not any
*/