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 все зависает т.к. он все время получает данные, как его можно заменить? буду очень благодарен даже маленькой помощи)
 
Каков смысл этого метода?
Если он используется в контексте движения 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));
}
 
вот все нужное, если что говорите что скинуть.
Откуда идет вызов:
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();
    }
}
//если что здесь не весь код а "нужная" часть
 
Если ты его не менял (с сообщения @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, из-за чего они теряются при апдейтах. По крайней мере, с прожектайлами так работает.
 
Судя по команде.... В правильном кейсе задачи... у тебя должно запускать AI-ТАСКУ (Задачу на перемещение) для твоего моба(ов)....
А не то, что у тебя происходит с корявым "телепортированием" сущности (я не знаю, что у тебя там в Interpreter(Player, World, line); и что там делает класс игрока..)
 
Тем более, не знаю как на новых версиях, но на старых в AI-таске (EntityAIMovingPath) есть что-то типа
this.npc.getNavigator().tryMoveToXYZ(x, y, z)

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