Code/net/minecraft/world/entity/ai/behavior/RandomStroll.java

85 lines
3.6 KiB
Java
Raw Permalink Normal View History

2025-07-01 06:20:03 +00:00
package net.minecraft.world.entity.ai.behavior;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder;
import net.minecraft.world.entity.ai.behavior.declarative.MemoryAccessor;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.ai.memory.WalkTarget;
import net.minecraft.world.entity.ai.util.AirAndWaterRandomPos;
import net.minecraft.world.entity.ai.util.LandRandomPos;
import net.minecraft.world.phys.Vec3;
public class RandomStroll {
private static final int MAX_XZ_DIST = 10;
private static final int MAX_Y_DIST = 7;
private static final int[][] SWIM_XY_DISTANCE_TIERS = new int[][]{{1, 1}, {3, 3}, {5, 5}, {6, 5}, {7, 7}, {10, 7}};
public static OneShot<PathfinderMob> stroll(float p_260304_) {
return stroll(p_260304_, true);
}
public static OneShot<PathfinderMob> stroll(float p_260303_, boolean p_259639_) {
return strollFlyOrSwim(p_260303_, p_258601_ -> LandRandomPos.getPos(p_258601_, 10, 7), p_259639_ ? p_258615_ -> true : p_390571_ -> !p_390571_.isInWater());
}
public static BehaviorControl<PathfinderMob> stroll(float p_260204_, int p_259502_, int p_259891_) {
return strollFlyOrSwim(p_260204_, p_258605_ -> LandRandomPos.getPos(p_258605_, p_259502_, p_259891_), p_258616_ -> true);
}
public static BehaviorControl<PathfinderMob> fly(float p_259119_) {
return strollFlyOrSwim(p_259119_, p_258614_ -> getTargetFlyPos(p_258614_, 10, 7), p_258602_ -> true);
}
public static BehaviorControl<PathfinderMob> swim(float p_259469_) {
return strollFlyOrSwim(p_259469_, RandomStroll::getTargetSwimPos, Entity::isInWater);
}
private static OneShot<PathfinderMob> strollFlyOrSwim(float p_260030_, Function<PathfinderMob, Vec3> p_259912_, Predicate<PathfinderMob> p_259088_) {
return BehaviorBuilder.create(
p_258620_ -> p_258620_.group(p_258620_.absent(MemoryModuleType.WALK_TARGET)).apply(p_258620_, p_258600_ -> (p_258610_, p_258611_, p_258612_) -> {
if (!p_259088_.test(p_258611_)) {
return false;
} else {
Optional<Vec3> optional = Optional.ofNullable(p_259912_.apply(p_258611_));
p_258600_.setOrErase(optional.map(p_258622_ -> new WalkTarget(p_258622_, p_260030_, 0)));
return true;
}
})
);
}
@Nullable
private static Vec3 getTargetSwimPos(PathfinderMob p_259491_) {
Vec3 vec3 = null;
Vec3 vec31 = null;
for (int[] aint : SWIM_XY_DISTANCE_TIERS) {
if (vec3 == null) {
vec31 = BehaviorUtils.getRandomSwimmablePos(p_259491_, aint[0], aint[1]);
} else {
vec31 = p_259491_.position().add(p_259491_.position().vectorTo(vec3).normalize().multiply(aint[0], aint[1], aint[0]));
}
if (vec31 == null || p_259491_.level().getFluidState(BlockPos.containing(vec31)).isEmpty()) {
return vec3;
}
vec3 = vec31;
}
return vec31;
}
@Nullable
private static Vec3 getTargetFlyPos(PathfinderMob p_260316_, int p_259038_, int p_259696_) {
Vec3 vec3 = p_260316_.getViewVector(0.0F);
return AirAndWaterRandomPos.getPos(p_260316_, p_259038_, p_259696_, -2, vec3.x, vec3.z, (float) (Math.PI / 2));
}
}