fix issues related to airborne positioning

This commit is contained in:
2026-06-29 16:25:05 +02:00
parent 7fe5ab4e24
commit f8e4710c59
@@ -4,9 +4,11 @@ import net.fretux.adaptivemobs.ai.AdaptiveAIGoalUtils;
import net.fretux.adaptivemobs.ai.AdaptivePositioningUtils; import net.fretux.adaptivemobs.ai.AdaptivePositioningUtils;
import net.fretux.adaptivemobs.ai.AdaptiveTargetingUtils; import net.fretux.adaptivemobs.ai.AdaptiveTargetingUtils;
import net.fretux.adaptivemobs.config.AMConfig; import net.fretux.adaptivemobs.config.AMConfig;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.goal.Goal; import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import java.util.EnumSet; import java.util.EnumSet;
@@ -14,6 +16,8 @@ import java.util.function.IntSupplier;
public class AdaptiveAirbornePositioningGoal extends Goal { public class AdaptiveAirbornePositioningGoal extends Goal {
private static final double MIN_REPOSITION_DISTANCE_SQR = 4.0D;
private final Mob mob; private final Mob mob;
private final IntSupplier tierSupplier; private final IntSupplier tierSupplier;
private final double range; private final double range;
@@ -25,7 +29,7 @@ public class AdaptiveAirbornePositioningGoal extends Goal {
this.tierSupplier = tierSupplier; this.tierSupplier = tierSupplier;
this.range = range; this.range = range;
this.verticalOffset = verticalOffset; this.verticalOffset = verticalOffset;
setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK)); setFlags(EnumSet.of(Flag.MOVE));
} }
@Override @Override
@@ -37,16 +41,49 @@ public class AdaptiveAirbornePositioningGoal extends Goal {
public void start() { public void start() {
cooldown = AdaptiveAIGoalUtils.nextCooldown(mob); cooldown = AdaptiveAIGoalUtils.nextCooldown(mob);
LivingEntity target = mob.getTarget(); LivingEntity target = mob.getTarget();
if (target == null) { if (target == null || !target.isAlive()) {
return; return;
} }
int tier = tierSupplier.getAsInt(); int tier = tierSupplier.getAsInt();
boolean spread = tier >= 4 && AdaptiveTargetingUtils.nearbyAttackers(mob, target, range) > 1; boolean spread = tier >= 4 && AdaptiveTargetingUtils.nearbyAttackers(mob, target, range) > 1;
double lead = tier >= 5 ? AMConfig.tierValue(AMConfig.AI_INTERCEPTION_STRENGTH.get(), tier) : 0.0D; 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); 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.getMoveControl().setWantedPosition(dest.x, dest.y, dest.z, 1.0D);
mob.getLookControl().setLookAt(target, 30.0F, 30.0F);
AdaptiveAIGoalUtils.debug(mob, tierSupplier, "airborne reposition"); 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);
}
} }