package net.minecraft.world.entity.ai.goal; import java.util.EnumSet; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; public abstract class Goal { private final EnumSet flags = EnumSet.noneOf(Goal.Flag.class); /** * Returns whether execution should begin. You can also read and cache any state necessary for execution in this method as well. */ public abstract boolean canUse(); /** * @return whether the goal should continue executing */ public boolean canContinueToUse() { return this.canUse(); } public boolean isInterruptable() { return true; } /** * Called when the goal is about to start executing */ public void start() { } /** * Called when the goal stops executing, usually to reset the mob's state. */ public void stop() { } public boolean requiresUpdateEveryTick() { return false; } /** * Called every tick to update a goal that is in progress. */ public void tick() { } public void setFlags(EnumSet flagSet) { this.flags.clear(); this.flags.addAll(flagSet); } public String toString() { return this.getClass().getSimpleName(); } public EnumSet getFlags() { return this.flags; } protected int adjustedTickDelay(int adjustment) { return this.requiresUpdateEveryTick() ? adjustment : reducedTickDelay(adjustment); } protected static int reducedTickDelay(int reduction) { return Mth.positiveCeilDiv(reduction, 2); } protected static ServerLevel getServerLevel(Entity entity) { return (ServerLevel)entity.level(); } protected static ServerLevel getServerLevel(Level level) { return (ServerLevel)level; } public static enum Flag { MOVE, LOOK, JUMP, TARGET; } }