From f8e4710c59b42b9a72480d4b0514cb75d7f1eaf5 Mon Sep 17 00:00:00 2001 From: fretuks Date: Mon, 29 Jun 2026 16:25:05 +0200 Subject: [PATCH] fix issues related to airborne positioning --- .../AdaptiveAirbornePositioningGoal.java | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/fretux/adaptivemobs/ai/goals/AdaptiveAirbornePositioningGoal.java b/src/main/java/net/fretux/adaptivemobs/ai/goals/AdaptiveAirbornePositioningGoal.java index 3b0bd96..f7f4454 100644 --- a/src/main/java/net/fretux/adaptivemobs/ai/goals/AdaptiveAirbornePositioningGoal.java +++ b/src/main/java/net/fretux/adaptivemobs/ai/goals/AdaptiveAirbornePositioningGoal.java @@ -4,9 +4,11 @@ import net.fretux.adaptivemobs.ai.AdaptiveAIGoalUtils; import net.fretux.adaptivemobs.ai.AdaptivePositioningUtils; import net.fretux.adaptivemobs.ai.AdaptiveTargetingUtils; import net.fretux.adaptivemobs.config.AMConfig; +import net.minecraft.core.BlockPos; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import java.util.EnumSet; @@ -14,6 +16,8 @@ import java.util.function.IntSupplier; public class AdaptiveAirbornePositioningGoal extends Goal { + private static final double MIN_REPOSITION_DISTANCE_SQR = 4.0D; + private final Mob mob; private final IntSupplier tierSupplier; private final double range; @@ -25,7 +29,7 @@ public class AdaptiveAirbornePositioningGoal extends Goal { this.tierSupplier = tierSupplier; this.range = range; this.verticalOffset = verticalOffset; - setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK)); + setFlags(EnumSet.of(Flag.MOVE)); } @Override @@ -37,16 +41,49 @@ public class AdaptiveAirbornePositioningGoal extends Goal { public void start() { cooldown = AdaptiveAIGoalUtils.nextCooldown(mob); LivingEntity target = mob.getTarget(); - if (target == null) { + if (target == null || !target.isAlive()) { return; } int tier = tierSupplier.getAsInt(); boolean spread = tier >= 4 && AdaptiveTargetingUtils.nearbyAttackers(mob, target, range) > 1; double lead = tier >= 5 ? AMConfig.tierValue(AMConfig.AI_INTERCEPTION_STRENGTH.get(), tier) : 0.0D; - Vec3 dest = AdaptivePositioningUtils.sidePosition(mob, target, range, + Vec3 preferred = AdaptivePositioningUtils.sidePosition(mob, target, range, spread && mob.getRandom().nextBoolean() ? -1.0D : 1.0D, lead).add(0.0D, verticalOffset, 0.0D); + Vec3 dest = safeDestination(preferred); + if (dest == null || mob.position().distanceToSqr(dest) < MIN_REPOSITION_DISTANCE_SQR) { + return; + } mob.getMoveControl().setWantedPosition(dest.x, dest.y, dest.z, 1.0D); - mob.getLookControl().setLookAt(target, 30.0F, 30.0F); AdaptiveAIGoalUtils.debug(mob, tierSupplier, "airborne reposition"); } + + private Vec3 safeDestination(Vec3 preferred) { + double minY = mob.level().getMinBuildHeight() + 1.0D; + double maxY = mob.level().getMaxBuildHeight() - Math.max(1.0D, mob.getBbHeight()); + double y = Math.max(minY, Math.min(maxY, preferred.y)); + Vec3 base = new Vec3(preferred.x, y, preferred.z); + if (isClear(base)) { + return base; + } + for (int offset = 1; offset <= 4; offset++) { + Vec3 above = base.add(0.0D, offset, 0.0D); + if (above.y <= maxY && isClear(above)) { + return above; + } + Vec3 below = base.add(0.0D, -offset, 0.0D); + if (below.y >= minY && isClear(below)) { + return below; + } + } + return null; + } + + private boolean isClear(Vec3 pos) { + BlockPos blockPos = BlockPos.containing(pos); + if (!mob.level().getWorldBorder().isWithinBounds(blockPos)) { + return false; + } + AABB movedBox = mob.getBoundingBox().move(pos.subtract(mob.position())); + return mob.level().noCollision(mob, movedBox); + } }