From ea4dedc758e8ac726d1705d40f57cf5ff4390581 Mon Sep 17 00:00:00 2001 From: Ollie <69084614+olijeffers0n@users.noreply.github.com> Date: Wed, 24 Jan 2024 22:18:35 +0000 Subject: [PATCH 1/5] Add initial docs for Entity Pathfinders and Mob Goal API --- config/sidebar.paper.ts | 2 + docs/paper/dev/api/entity-pathfinder.md | 62 ++++++++++++ docs/paper/dev/api/mob-goals.md | 126 ++++++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 docs/paper/dev/api/entity-pathfinder.md create mode 100644 docs/paper/dev/api/mob-goals.md diff --git a/config/sidebar.paper.ts b/config/sidebar.paper.ts index 888a851b..3394543b 100644 --- a/config/sidebar.paper.ts +++ b/config/sidebar.paper.ts @@ -139,6 +139,8 @@ const paper: SidebarsConfig = { "dev/api/scheduler", "dev/api/plugin-messaging", "dev/api/plugin-configs", + "dev/api/mob-goals", + "dev/api/entity-pathfinder", "dev/api/folia-support", ], }, diff --git a/docs/paper/dev/api/entity-pathfinder.md b/docs/paper/dev/api/entity-pathfinder.md new file mode 100644 index 00000000..4e8a0417 --- /dev/null +++ b/docs/paper/dev/api/entity-pathfinder.md @@ -0,0 +1,62 @@ +--- +slug: /dev/entity-pathfinder +description: A guide to the Entity Pathfinder API. +--- + +# Entity Pathfinder API + +The Entity Pathfinder API is a way of controlling the movement of entities in Minecraft. It allows you to set a path +for an entity to follow, such as moving to a location, or following a player. + +## Accessing the Pathfinder + +To access the pathfinder for a Mob, you need to call `getPathfinder()` on the Mob. This will return an instance of `Pathfinder`. + +:::important + +The pathfinder is only available for Mobs, not for all entities. + +::: + +Lets say that we have a `Cow` and we want it to move to a specific `Player`'s location. We can do this by getting the +pathfinder for the cow and then setting the path to the player's location: + +```java +Cow cow = ...; +Player player = ...; + +Pathfinder pathfinder = cow.getPathfinder(); +// moveTo returns a boolean indicating whether the path was set successfully +boolean success = pathfinder.moveTo(player.getLocation()); +``` + +If we want to access the current Path for the cow, we can call `getCurrentPath()` on the pathfinder: + +```java +PathResult path = pathfinder.getCurrentPath(); + +// A PathResult is essentially a wrapper around a List of Locations. These can be accessed with: +List locations = path.getPoints(); +// It is important to note that the list contains points that have already been passed, +// as well as future points. If you want to get the next point, you can use: +Location nextPoint = path.getNextPoint(); // Or locations.get(path.getNextPointIndex()) +// Finally, you can access the final destination with: +Location destination = path.getFinalPoint(); +``` + +## Pathfinding Rules + +Much of the way that the Pathfinder works is dictated by the limitations of the actual entity pathfinding in Minecraft. +For example, a Polar Bear cannot fly. This means that if you set a path for a Polar Bear to a location that is in the air, +it will not be able to reach it. + +There are some attributes that can be set on the pathfinder to change the way that the pathfinder works. These are: +- `setCanOpenDoors(boolean)`: Whether the entity can open doors. +- `setCanPassDoors(boolean)`: Whether the entity can pass through open doors. +- `setCanFloat(boolean)`: Whether the entity can float in water. +These all have respective getters as well. + +## Stopping the Pathfinder + +To stop the pathfinder, you can call `stopPathfinding()` on the pathfinder. This will stop the pathfinder and clear the +current path. You can use `hasPath()` to check if the pathfinder is currently running. diff --git a/docs/paper/dev/api/mob-goals.md b/docs/paper/dev/api/mob-goals.md new file mode 100644 index 00000000..ffda32c2 --- /dev/null +++ b/docs/paper/dev/api/mob-goals.md @@ -0,0 +1,126 @@ +--- +slug: /dev/mob-goals +description: A guide to the PDC API for storing data. +--- + +# Mob Goal API + +The Mob Goal API is a way of controlling the behaviour of mobs in Minecraft. It allows you to set a goal for a mob to perform, such as +attacking a player, or moving to a location. It also allows you to create your own custom goals. + +## Registering a Goal on an Entity + +To register a goal on an entity, you need to create an instance of the goal and then register it with the entity: + +```java +Cow cow = ...; +Goal goal = new ExampleGoal(); + +server.getMobGoals().addGoal(cow, 0, goal); // 0 is the priority, lower numbers are higher priority +``` + +:::tip + +You can access the Vanilla goals from the `VanillaGoal` class. These are the goals that are used by Vanilla Minecraft. +They are specific to each mob type, so you can't use a cow goal on a zombie for example. + +::: + +## Creating a Custom Goal + +To create a custom goal, you need to create a class that implements the `Goal` interface. This interface has several methods: +- `void start()`: Called when the goal is started. +- `void tick()`: Called every tick while the goal is running. +- `void stop()`: Called when the goal is stopped. +- `boolean shouldActivate()`: Called to determine if the goal should start. +- `boolean shouldStayActive()`: Called to determine if the goal should continue running. +- `GoalKey getKey()`: Called to get the key for the goal. +- `EnumSet getTypes()`: Called to get the types of the goal. + +:::note[types] + +The `getTypes()` method is used to determine what types of goal this is. The types are: +- `GoalType.MOVE`: The goal moves the entity. +- `GoalType.LOOK`: The goal changes the direction the entity is looking. +- `GoalType.JUMP`: The goal makes the entity jump. +- `GoalType.TARGET`: The goal changes the target of the entity. +- `GoalType.UNKNOWN_BEHAVIOR`: The goal does something else. Used for mapping Vanilla goals. + +::: + +Here is an example of a goal that makes a camel follow a player. This is essentially the same as the `FOLLOW_MOB` in Vanilla, +but it is a good example of how to create a goal. + +```java +public class CamelFollowPlayerGoal implements Goal { + + public static final GoalKey KEY = GoalKey.of(Camel.class, new NamespacedKey("testplugin", "camel_follow_player")); + + private final Player player; + private final Camel camel; + + public CamelFollowPlayerGoal(Player player, Camel camel) { + // The constructor takes the Player to follow and the Camel that is following + this.player = player; + this.camel = camel; + } + + @Override + public boolean shouldActivate() { + // This is whether or the goal should start. In this case, we want the goal to always start so we return true. + // You could also return false here if you wanted to only start the goal in certain situations. + return true; + } + + @Override + public void start() { + // This is called when the goal starts. In this case, we just send a message to the player. + player.sendMessage(text("I am following you!")); + } + + @Override + public void tick() { + // This is called every tick while the goal is running. In this case, we make the camel move towards the player + // using the Pathfinder API. The 5.0 is the speed of the camel. + camel.getPathfinder().moveTo(player, 5.0); + } + + @Override + public void stop() { + // This is called when the goal stops. In this case, we just send a message to the player. + player.sendMessage(text("I Stopped following you!")); + } + + @Override + public @NotNull GoalKey getKey() { + // This is the key for the goal. It is used to identify the goal and is used to determine if two goals are the same. + // It requires the class of the entity and a NamespacedKey. The NamespacedKey is used to identify the goal. + // You should use the plugin's namespace for the NamespacedKey, not Minecraft or Bukkit. + return KEY; + } + + @Override + public @NotNull EnumSet getTypes() { + // This is used to determine what types of goal this is. In this case, we are moving the entity and changing the + // direction it is looking, so we return MOVE and LOOK. Return as many types as you need. + return EnumSet.of(GoalType.MOVE, GoalType.LOOK); + } +} +``` + +## Stopping a Goal + +To stop a goal, you need to get the goal key and then call `stop()` on the goal: + +```java +Cow cow = ...; +// This works because our example has a public static `KEY` field +server.getMobGoals().removeGoal(cow, CamelFollowPlayerGoal.KEY); + +// You can also remove Vanilla goals +server.getMobGoals().removeGoal(cow, VanillaGoal.TEMPT); + +// You can also remove all goals +server.getMobGoals().removeAllGoals(cow); +server.getMobGoals().removeAllGoals(cow, GoalType.MOVE); // Remove all MOVE goals +``` From 7274f7b871095db78fdb6b2fee39a95c4be01ff3 Mon Sep 17 00:00:00 2001 From: Ollie <69084614+olijeffers0n@users.noreply.github.com> Date: Thu, 25 Jan 2024 15:15:30 +0000 Subject: [PATCH 2/5] Address Comments --- docs/paper/dev/api/entity-pathfinder.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/paper/dev/api/entity-pathfinder.md b/docs/paper/dev/api/entity-pathfinder.md index 4e8a0417..14654a45 100644 --- a/docs/paper/dev/api/entity-pathfinder.md +++ b/docs/paper/dev/api/entity-pathfinder.md @@ -14,11 +14,11 @@ To access the pathfinder for a Mob, you need to call `getPathfinder()` on the Mo :::important -The pathfinder is only available for Mobs, not for all entities. +The pathfinder is only available for entities that implement `Mob`. ::: -Lets say that we have a `Cow` and we want it to move to a specific `Player`'s location. We can do this by getting the +Let's say that we have a `Cow` and we want it to move to a specific `Player`'s location. We can do this by getting the pathfinder for the cow and then setting the path to the player's location: ```java @@ -50,7 +50,7 @@ Much of the way that the Pathfinder works is dictated by the limitations of the For example, a Polar Bear cannot fly. This means that if you set a path for a Polar Bear to a location that is in the air, it will not be able to reach it. -There are some attributes that can be set on the pathfinder to change the way that the pathfinder works. These are: +Some attributes can be set on the pathfinder to change the way that the pathfinder works. These are: - `setCanOpenDoors(boolean)`: Whether the entity can open doors. - `setCanPassDoors(boolean)`: Whether the entity can pass through open doors. - `setCanFloat(boolean)`: Whether the entity can float in water. @@ -58,5 +58,5 @@ These all have respective getters as well. ## Stopping the Pathfinder -To stop the pathfinder, you can call `stopPathfinding()` on the pathfinder. This will stop the pathfinder and clear the -current path. You can use `hasPath()` to check if the pathfinder is currently running. +You can call `stopPathfinding()` on the pathfinder to stop the pathfinder. This will stop the pathfinder and clear the +current path. You can use `hasPath()` to check if the pathfinder is running. From 1c27f8facf6e28e3083498c2b5f21e183230521c Mon Sep 17 00:00:00 2001 From: Ollie <69084614+olijeffers0n@users.noreply.github.com> Date: Sat, 27 Jan 2024 19:43:44 +0000 Subject: [PATCH 3/5] Address Comments --- docs/paper/dev/api/entity-pathfinder.md | 3 ++- docs/paper/dev/api/mob-goals.md | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/paper/dev/api/entity-pathfinder.md b/docs/paper/dev/api/entity-pathfinder.md index 14654a45..ec8b1bd5 100644 --- a/docs/paper/dev/api/entity-pathfinder.md +++ b/docs/paper/dev/api/entity-pathfinder.md @@ -51,7 +51,8 @@ For example, a Polar Bear cannot fly. This means that if you set a path for a Po it will not be able to reach it. Some attributes can be set on the pathfinder to change the way that the pathfinder works. These are: -- `setCanOpenDoors(boolean)`: Whether the entity can open doors. +- `setCanOpenDoors(boolean)`: Whether the entity can open doors. This is relevant for Zombies breaking down doors, and +Villagers opening doors. - `setCanPassDoors(boolean)`: Whether the entity can pass through open doors. - `setCanFloat(boolean)`: Whether the entity can float in water. These all have respective getters as well. diff --git a/docs/paper/dev/api/mob-goals.md b/docs/paper/dev/api/mob-goals.md index ffda32c2..36784500 100644 --- a/docs/paper/dev/api/mob-goals.md +++ b/docs/paper/dev/api/mob-goals.md @@ -22,7 +22,7 @@ server.getMobGoals().addGoal(cow, 0, goal); // 0 is the priority, lower numbers :::tip You can access the Vanilla goals from the `VanillaGoal` class. These are the goals that are used by Vanilla Minecraft. -They are specific to each mob type, so you can't use a cow goal on a zombie for example. +They are specific to each mob type, so you can't use `VanillaGoal.BEE_ATTACK` on a Zombie, for example. ::: @@ -108,9 +108,9 @@ public class CamelFollowPlayerGoal implements Goal { } ``` -## Stopping a Goal +## Removing a Goal -To stop a goal, you need to get the goal key and then call `stop()` on the goal: +To remove a goal, you need to get the goal key and then call the `removeGoal` method: ```java Cow cow = ...; From f4b89ebca28c818dbc89473abf0e9a7ce5fc8389 Mon Sep 17 00:00:00 2001 From: olijeffers0n <69084614+olijeffers0n@users.noreply.github.com> Date: Mon, 25 Nov 2024 16:31:28 +0000 Subject: [PATCH 4/5] Address Comments --- docs/paper/dev/api/entity-pathfinder.md | 16 ++++++++-------- docs/paper/dev/api/mob-goals.md | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/paper/dev/api/entity-pathfinder.md b/docs/paper/dev/api/entity-pathfinder.md index ec8b1bd5..789b7336 100644 --- a/docs/paper/dev/api/entity-pathfinder.md +++ b/docs/paper/dev/api/entity-pathfinder.md @@ -5,8 +5,8 @@ description: A guide to the Entity Pathfinder API. # Entity Pathfinder API -The Entity Pathfinder API is a way of controlling the movement of entities in Minecraft. It allows you to set a path -for an entity to follow, such as moving to a location, or following a player. +The Entity Pathfinder API is a way of controlling the movement of entities in Minecraft. It allows you to set a path +for an entity to follow, such as moving to a location, or following a player. ## Accessing the Pathfinder @@ -27,17 +27,17 @@ Player player = ...; Pathfinder pathfinder = cow.getPathfinder(); // moveTo returns a boolean indicating whether the path was set successfully -boolean success = pathfinder.moveTo(player.getLocation()); +boolean success = pathfinder.moveTo(player.getLocation()); ``` -If we want to access the current Path for the cow, we can call `getCurrentPath()` on the pathfinder: +If we want to access the current path for the cow, we can call `getCurrentPath()` on the pathfinder: ```java PathResult path = pathfinder.getCurrentPath(); // A PathResult is essentially a wrapper around a List of Locations. These can be accessed with: List locations = path.getPoints(); -// It is important to note that the list contains points that have already been passed, +// It is important to note that the list contains points that have already been passed, // as well as future points. If you want to get the next point, you can use: Location nextPoint = path.getNextPoint(); // Or locations.get(path.getNextPointIndex()) // Finally, you can access the final destination with: @@ -48,10 +48,10 @@ Location destination = path.getFinalPoint(); Much of the way that the Pathfinder works is dictated by the limitations of the actual entity pathfinding in Minecraft. For example, a Polar Bear cannot fly. This means that if you set a path for a Polar Bear to a location that is in the air, -it will not be able to reach it. +it will not be able to reach it. Some attributes can be set on the pathfinder to change the way that the pathfinder works. These are: -- `setCanOpenDoors(boolean)`: Whether the entity can open doors. This is relevant for Zombies breaking down doors, and +- `setCanOpenDoors(boolean)`: Whether the entity can open doors. This is relevant for Zombies breaking down doors, and Villagers opening doors. - `setCanPassDoors(boolean)`: Whether the entity can pass through open doors. - `setCanFloat(boolean)`: Whether the entity can float in water. @@ -60,4 +60,4 @@ These all have respective getters as well. ## Stopping the Pathfinder You can call `stopPathfinding()` on the pathfinder to stop the pathfinder. This will stop the pathfinder and clear the -current path. You can use `hasPath()` to check if the pathfinder is running. +current path. You can use `hasPath()` to check if the pathfinder is running. diff --git a/docs/paper/dev/api/mob-goals.md b/docs/paper/dev/api/mob-goals.md index 36784500..c4c44613 100644 --- a/docs/paper/dev/api/mob-goals.md +++ b/docs/paper/dev/api/mob-goals.md @@ -1,6 +1,6 @@ --- slug: /dev/mob-goals -description: A guide to the PDC API for storing data. +description: A guide to the mob goal API. --- # Mob Goal API @@ -48,7 +48,7 @@ The `getTypes()` method is used to determine what types of goal this is. The typ ::: -Here is an example of a goal that makes a camel follow a player. This is essentially the same as the `FOLLOW_MOB` in Vanilla, +Here is an example of a goal that makes a camel follow a player. This is essentially the same as the `FOLLOW_MOB` in Vanilla, but it is a good example of how to create a goal. ```java @@ -88,11 +88,11 @@ public class CamelFollowPlayerGoal implements Goal { @Override public void stop() { // This is called when the goal stops. In this case, we just send a message to the player. - player.sendMessage(text("I Stopped following you!")); + player.sendMessage(text("I stopped following you!")); } @Override - public @NotNull GoalKey getKey() { + public GoalKey getKey() { // This is the key for the goal. It is used to identify the goal and is used to determine if two goals are the same. // It requires the class of the entity and a NamespacedKey. The NamespacedKey is used to identify the goal. // You should use the plugin's namespace for the NamespacedKey, not Minecraft or Bukkit. From e7593064bd73c69d31559fd2acaa109cecd488c2 Mon Sep 17 00:00:00 2001 From: olijeffers0n <69084614+olijeffers0n@users.noreply.github.com> Date: Mon, 25 Nov 2024 16:32:38 +0000 Subject: [PATCH 5/5] Replace british spelling --- docs/paper/dev/api/mob-goals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/paper/dev/api/mob-goals.md b/docs/paper/dev/api/mob-goals.md index c4c44613..ba519028 100644 --- a/docs/paper/dev/api/mob-goals.md +++ b/docs/paper/dev/api/mob-goals.md @@ -5,7 +5,7 @@ description: A guide to the mob goal API. # Mob Goal API -The Mob Goal API is a way of controlling the behaviour of mobs in Minecraft. It allows you to set a goal for a mob to perform, such as +The Mob Goal API is a way of controlling the behavior of mobs in Minecraft. It allows you to set a goal for a mob to perform, such as attacking a player, or moving to a location. It also allows you to create your own custom goals. ## Registering a Goal on an Entity