Paper
Paper copied to clipboard
Added AI goals cannot be removed.
Expected behavior
I'm trying to use goal API to remove/add them as it suits me. For example:
- remove look_at_player goal and save it to a variable
- add it back in
- remove it again
- and so on
Observed/Actual behavior
After adding the goal back and removing it, it isn't removed.
Steps/models to reproduce
- Get a goal -
Bukkit.getMobGoals().getGoal(mob, goalKey); - Remove it -
Bukkit.getMobGoals().removeGoal(mob, goal); - Add it back -
Bukkit.getMobGoals().addGoal(mob, 1, goal); - Remove it again -
Bukkit.getMobGoals().removeGoal(mob, goal); - See that it hasn't been removed -
Bukkit.getMobGoals().hasGoal(mob, goalKey);
Plugin and Datapack List
Paper version
> ver
[13:39:01 INFO]: Checking version, please wait...
[13:39:02 INFO]: This server is running Paper version 1.20.6-81-master@5a9afbe (2024-05-17T21:45:46Z) (Implementing API version 1.20.6-R0.1-SNAPSHOT)
You are running the latest version
Other
This is the code I used to test this:
public class TestCommand implements CommandExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (!(sender instanceof Player p)) return false;
List<Entity> entities = p.getNearbyEntities(5, 5, 5);
System.out.println("Looking for an entity...");
Entity testEntity = null;
for (Entity entity : entities) {
if (entity.getType().equals(EntityType.SHEEP)) {
testEntity = entity;
break;
}
}
if (testEntity == null) return false;
System.out.println("Found a sheep.");
GoalKey<Mob> LOOK_GOAL_KEY = VanillaGoal.LOOK_AT_PLAYER;
Mob mob = (Mob) testEntity;
Goal<Mob> lookGoal = Bukkit.getMobGoals().getGoal(mob, LOOK_GOAL_KEY);
if (lookGoal == null) {
System.out.println("Look goal not found");
return true;
}
System.out.println("Found a look goal");
Bukkit.getMobGoals().removeGoal(mob, lookGoal);
System.out.println("Removed it");
Goal<Mob> testGoal = Bukkit.getMobGoals().getGoal(mob, LOOK_GOAL_KEY);
if (testGoal == null) System.out.println("It's still removed");
else System.out.println("It's still there");
Bukkit.getMobGoals().addGoal(mob, 1, lookGoal);
System.out.println("Added it back in, testing...");
lookGoal = Bukkit.getMobGoals().getGoal(mob, LOOK_GOAL_KEY);
if (lookGoal == null) System.out.println("Nope, it's not there");
else System.out.println("Yep it's added");
Bukkit.getMobGoals().removeGoal(mob, lookGoal);
System.out.println("Removed it again, testing...");
testGoal = Bukkit.getMobGoals().getGoal(mob, LOOK_GOAL_KEY);
if (testGoal == null) System.out.println("And everything is great, it's removed");
else System.out.println("And it wasn't removed, why not?");
return true;
}
}
And that's the result of running the test command:
The issue here is that we're always rewrapping stuff into a VanillaCustomGoal
Can this be fixed fairly easy or would it require much work?
Trivial fix, just need to not wrap if we don't need to wrap