-
-
Notifications
You must be signed in to change notification settings - Fork 9
Entity AI | Pathfinder Goals
Pathfinders are how Mobs/Creatures do regular actions (Floating on water, Attacking, Avoiding Entities, etc). This guide will show you how to use the built-in ones available in Vanilla Minecraft, or how to create your own.
Examples below will only include imports necessary for MobChip, not for anything else (e.g. Bukkit and Java Imports).
A Pathfinder is how entities normally move around and perform actions based on the environment around them. For example, they control which entities float in water, afraid of the sun, panic when damaged, and more.
The EntityAI
interface extends a Set<WrappedPathfinder>
. WrappedPathfinder
contains your Pathfinder class (which represents your actions), and the priority of the Pathfinder. Pathfinders will execute in their priority order, from least to greatest.
Here's how to fetch a Pathfinder from the Goal Selector:
import me.gamercoder215.mobchip.EntityBrain;
import me.gamercoder215.mobchip.ai.EntityAI;
import me.gamercoder215.mobchip.bukkit.BukkitBrain;
public class MyPlugin extends JavaPlugin {
public void getPathfinder(Mob m) {
EntityBrain brain = BukkitBrain.getBrain(m);
// Goal Selector
EntityAI goal = brain.getGoalAI();
// EntityAI Interface extends Set<WrappedPathfinder>
for (Pathfinder pathfinder : goal) {
System.out.println(pathfinder.getName());
}
// Gets all Pathfinders with the priority of 0
List<WrappedPathfinder> pathfinders0 = goal.stream().filter(wp -> wp.getPriority() == 0).toList();
}
}
The core feature of Pathfinders is being able to add them to the Entity's Goal Selector, or EntityAI. Here's an example of how to add the Pathfinder that makes one entity avoid another entity (PathfinderAvoidEntity):
import me.gamercoder215.mobchip.ai.goal.PathfinderAvoidEntity;
import me.gamercoder215.mobchip.ai.EntityAI;
import me.gamercoder215.mobchip.EntityBrain;
import me.gamercoder215.mobchip.bukkit.BukkitBrain;
// Bukkit Imports...
public class MyPlugin extends JavaPlugin {
public void addGoal(Mob m) {
EntityBrain brain = BukkitBrain.getBrain(m);
// GoalSelector AI
EntityAI goal = brain.getGoalAI();
// TargetSelector AI
EntityAI target = brain.getTargetAI();
/* We're going to avoid... Creepers.
* Pathfinders require passing the Entity Instance, and in this case, we need the Creeper class
* 3rd Argument - Max Distance - Maximum Distance needed to stop fleeing
* 4th Argument - Speed Modifier - Speed Modifier while Sprinting/Walking away
*
* We'll say we need to be 10 blocks away from creepers, with a speed modifier of 2.
*/
PathfinderAvoidEntity<Creeper> pathfinder = new PathfinderAvoidEntity<>(m, Creeper.class, 10, 2);
// Either selector does the same, however, it is generally common practice to add targeting goals
// to the target selector so that other important goals (floating, breathing, etc) don't get overridden.
// Has the highest priority
target.put(0, pathfinder);
}
}
Minecraft has a built-in method of creating your functionality for a pathfinder.
Say you want to have a custom pathfinder for your own Pet System? Custom Entity Attacks? MobChip contains a well-documented abstract class you can extend that shows you how to set it up.
import me.gamercoder215.mobchip.ai.goal.CustomPathfinder;
import me.gamercoder215.mobchip.ai.goal.CustomPathfinder.PathfinderFlag;
import me.gamercoder215.mobchip.bukkit.BukkitBrain;
// Bukkit Imports...
public class MyPathfinder extends CustomPathfinder {
public MyPathfinder(Mob m) {
super(m); // Pass Entity to super
}
// PathfinderFlags are indicators of what your Pathfinder Does. In this case, it's
// just going to move and jump the Entity.
@Override
public PathfinderFlag[] getFlags() {
return new PathfinderFlag[]{PathfinderFlag.MOVEMENT, PathfinderFlag.JUMPING};
}
// This method will make sure your Pathfinder can start.
// Entity & NMS Entity Parent Fields are available
@Override
public boolean canStart() {
return entity.getLocation().add(0, 2, 0).getBlock().getType() == Material.AIR;
}
// Automatically called on the first tick the pathfinder starts.
// In this case, We're using the EntityController (more on that below) to control the entity's movements.
@Override
public void start() {
BukkitBrain.getBrain(entity).getController().jump().moveTo(entity.getLocation().add(3, 0, 3));
}
// Automatically called in between start() and stop().
// We don't need to put down anything.
@Override
public void tick() {
// do nothing
}
// Automatically called on the last tick this can run on.
// We don need to put down anything in here either.
@Override
public void stop() {
}
// There's also canInterrupt(), canContinueToUse(), and updateEveryTick() boolean methods you can override.
// It is not recommended to override updateEveryTick().
// canContinueToUse() defaults to canUse(), but is useful if you have a different check after the first time canUse() is called.
}
Copyright © 2022-Present gmitch215. All Rights Reserved.
Licensed under GNU General Public License v3.0.