While зависает

Версия Minecraft
1.19.2
API
Forge
37
1
1
У меня есть код который ждет когда нпс дойдет до цели:
Java:
public static void moveNPC(NpcEntity npc, double x, double y, double z){
        npc.setMoveTarget(x, y, z);
        boolean test = false;
        double speed = NpcEntity.setAttributes().getBaseValue(MOVEMENT_SPEED);
        double currentX = npc.getX();
        double currentY = npc.getY();
        double currentZ = npc.getZ();
        double distance =  Math.sqrt((x- currentX) *(x- currentX)) + ((y - currentY) *(y - currentY)) + ((z - currentZ) *(z - currentZ));
        System.out.println("Npc speed = " + speed);
        System.out.println("A distance to b = " + distance);
        while (!test) {
            currentX = npc.getX();
            currentY = npc.getY();
            currentZ = npc.getZ();
            distance =  Math.sqrt((x- currentX) *(x- currentX)) + ((y - currentY) *(y - currentY)) + ((z - currentZ) *(z - currentZ));
            if (distance < 1) {
                System.out.println(npc.getName() + " has reached the target position.");
                Interpreter(Player, World, line);
                test = true;
            } else if (npc.getDeltaMovement().lengthSqr() < 0.01) {
                //System.out.println(npc.getName() + " has stopped moving.");
            }
        }
    }
И как я понял из за while все зависает т.к. он все время получает данные, как его можно заменить? буду очень благодарен даже маленькой помощи)
 
182
14
27
Каков смысл этого метода?
Если он используется в контексте движения NPC каждый тик... То что тут делает while ?

movment:
public void moveNPC(NpcEntity npc, double targetX, double targetY, double targetZ) {
    npc.setMoveTarget(targetX, targetY, targetZ);

    double currentX = npc.getX();
    double currentY = npc.getY();
    double currentZ = npc.getZ();

    double distanceToTarget = calculateDistance(currentX, currentY, currentZ, targetX, targetY, targetZ);

    if (distanceToTarget < 1) {
        System.out.println(npc.getName() + " has reached the target position.");
        Interpreter(Player, World, line);
    } else if (npc.getDeltaMovement().lengthSqr() < 0.01) {
        System.out.println(npc.getName() + " has stopped moving.");
    }
}

private static double calculateDistance(double x1, double y1, double z1, double x2, double y2, double z2) {
    return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2) + Math.pow(z2 - z1, 2));
}
 
37
1
1
вот все нужное, если что говорите что скинуть.
Откуда идет вызов:
private static void executeCommand(String command, int commandCount, Player player, Level world) {
        if (command.startsWith("moveTo(") && command.endsWith(")")) {
            String parameters = command.substring("moveTo(".length(), command.length() - 1);
            String[] parts = parameters.split(",");
            if (parts.length == 4) {
                String name = parts[0].trim().replace("\"", "");
                NpcEntity npc = NPCManager.getNPCByName(name);
                Double x = Double.parseDouble(parts[1].trim());
                Double y = Double.parseDouble(parts[2].trim());
                Double z = Double.parseDouble(parts[3].trim());
                NPCManager.moveNPC(npc, x, y, z);
            }
NPCManager:
уже кидал :)
NpcEntity:
public class NpcEntity extends Monster implements IAnimatable {
    private AnimationFactory factory = GeckoLibUtil.createFactory(this);
    private UUID uniqueId;
    private String name;
    private double moveTargetX = -1;
    private double moveTargetY = -1;
    private double moveTargetZ = -1;
    private boolean shouldMove = false;

    public void setMoveTarget(double x, double y, double z) {
        this.moveTargetX = x;
        this.moveTargetY = y;
        this.moveTargetZ = z;
        this.shouldMove = true;
    }

    @Override
    public void registerControllers(AnimationData data) {
        AnimationController<NpcEntity> controller = new AnimationController<>(this, "controller", 0, this::predicate);
        data.addAnimationController(controller);
    }

    @Override
    public void baseTick() {
        super.baseTick();
        if (shouldMove) {
            this.getNavigation().moveTo(this.moveTargetX, this.moveTargetY, this.moveTargetZ, 1.0);
            if (this.position().closerThan(new Vec3(moveTargetX, moveTargetY, moveTargetZ), 1.0)) {
                this.shouldMove = false;
            }
        }
        this.refreshDimensions();
    }
}
//если что здесь не весь код а "нужная" часть
 
1,526
138
281
Если ты его не менял (с сообщения @PeTcHeNyShOhKa ), то оно и будет виснуть.

Double x = Double.parseDouble(parts[1].trim());
Странное решение, мог бы просто располагать даблы на стеке, меньше проблем будет.

if (this.position().closerThan(new Vec3(moveTargetX, moveTargetY, moveTargetZ), 1.0)) {
И зачем тебе проверки (и while, из-за которого всё и виснет, если я всё правильно понимаю) в NPCManager, если в самом NPC ты уже проверяешь на расстояние и пр.?

И (могу ошибаться) нпц не будет двигаться к твоей точке, т.к. коорды moveTargetX, ..Y, ..Z не записываются в NBT, из-за чего они теряются при апдейтах. По крайней мере, с прожектайлами так работает.
 
182
14
27
Судя по команде.... В правильном кейсе задачи... у тебя должно запускать AI-ТАСКУ (Задачу на перемещение) для твоего моба(ов)....
А не то, что у тебя происходит с корявым "телепортированием" сущности (я не знаю, что у тебя там в Interpreter(Player, World, line); и что там делает класс игрока..)
 
182
14
27
Тем более, не знаю как на новых версиях, но на старых в AI-таске (EntityAIMovingPath) есть что-то типа
this.npc.getNavigator().tryMoveToXYZ(x, y, z)

Сидишь кастомишь для своих целей... И вуаля.
Зачем придумывать костыли - не понятно. Мб на новых версиях успели нагадить по этому поводу... не проверял.
 
Сверху