Code/net/minecraft/world/entity/ai/goal/GoalSelector.java

131 lines
4.4 KiB
Java

package net.minecraft.world.entity.ai.goal;
import com.google.common.annotations.VisibleForTesting;
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.function.Predicate;
import net.minecraft.util.profiling.Profiler;
import net.minecraft.util.profiling.ProfilerFiller;
public class GoalSelector {
private static final WrappedGoal NO_GOAL = new WrappedGoal(Integer.MAX_VALUE, new Goal() {
@Override
public boolean canUse() {
return false;
}
}) {
@Override
public boolean isRunning() {
return false;
}
};
private final Map<Goal.Flag, WrappedGoal> lockedFlags = new EnumMap<>(Goal.Flag.class);
private final Set<WrappedGoal> availableGoals = new ObjectLinkedOpenHashSet<>();
private final EnumSet<Goal.Flag> disabledFlags = EnumSet.noneOf(Goal.Flag.class);
public void addGoal(int p_25353_, Goal p_25354_) {
this.availableGoals.add(new WrappedGoal(p_25353_, p_25354_));
}
@VisibleForTesting
public void removeAllGoals(Predicate<Goal> p_262575_) {
this.availableGoals.removeIf(p_262564_ -> p_262575_.test(p_262564_.getGoal()));
}
public void removeGoal(Goal p_25364_) {
for (WrappedGoal wrappedgoal : this.availableGoals) {
if (wrappedgoal.getGoal() == p_25364_ && wrappedgoal.isRunning()) {
wrappedgoal.stop();
}
}
this.availableGoals.removeIf(p_25378_ -> p_25378_.getGoal() == p_25364_);
}
private static boolean goalContainsAnyFlags(WrappedGoal p_186076_, EnumSet<Goal.Flag> p_186077_) {
for (Goal.Flag goal$flag : p_186076_.getFlags()) {
if (p_186077_.contains(goal$flag)) {
return true;
}
}
return false;
}
private static boolean goalCanBeReplacedForAllFlags(WrappedGoal p_186079_, Map<Goal.Flag, WrappedGoal> p_186080_) {
for (Goal.Flag goal$flag : p_186079_.getFlags()) {
if (!p_186080_.getOrDefault(goal$flag, NO_GOAL).canBeReplacedBy(p_186079_)) {
return false;
}
}
return true;
}
public void tick() {
ProfilerFiller profilerfiller = Profiler.get();
profilerfiller.push("goalCleanup");
for (WrappedGoal wrappedgoal : this.availableGoals) {
if (wrappedgoal.isRunning() && (goalContainsAnyFlags(wrappedgoal, this.disabledFlags) || !wrappedgoal.canContinueToUse())) {
wrappedgoal.stop();
}
}
this.lockedFlags.entrySet().removeIf(p_326929_ -> !p_326929_.getValue().isRunning());
profilerfiller.pop();
profilerfiller.push("goalUpdate");
for (WrappedGoal wrappedgoal2 : this.availableGoals) {
if (!wrappedgoal2.isRunning() && !goalContainsAnyFlags(wrappedgoal2, this.disabledFlags) && goalCanBeReplacedForAllFlags(wrappedgoal2, this.lockedFlags) && wrappedgoal2.canUse()) {
for (Goal.Flag goal$flag : wrappedgoal2.getFlags()) {
WrappedGoal wrappedgoal1 = this.lockedFlags.getOrDefault(goal$flag, NO_GOAL);
wrappedgoal1.stop();
this.lockedFlags.put(goal$flag, wrappedgoal2);
}
wrappedgoal2.start();
}
}
profilerfiller.pop();
this.tickRunningGoals(true);
}
public void tickRunningGoals(boolean p_186082_) {
ProfilerFiller profilerfiller = Profiler.get();
profilerfiller.push("goalTick");
for (WrappedGoal wrappedgoal : this.availableGoals) {
if (wrappedgoal.isRunning() && (p_186082_ || wrappedgoal.requiresUpdateEveryTick())) {
wrappedgoal.tick();
}
}
profilerfiller.pop();
}
public Set<WrappedGoal> getAvailableGoals() {
return this.availableGoals;
}
public void disableControlFlag(Goal.Flag p_25356_) {
this.disabledFlags.add(p_25356_);
}
public void enableControlFlag(Goal.Flag p_25375_) {
this.disabledFlags.remove(p_25375_);
}
public void setControlFlag(Goal.Flag p_25361_, boolean p_25362_) {
if (p_25362_) {
this.enableControlFlag(p_25361_);
} else {
this.disableControlFlag(p_25361_);
}
}
}