fix issues related to airborne positioning
This commit is contained in:
+41
-4
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user