User:     @Override
    public void run() {
            double angleIncrement = 360.0 / data.getPositionColors().size();
            double materialAngleIncrement = 360.0 / (items.size() + itemsAddProcess.size());

            currentAngleItems += data.getItemsSpeed();

            for (ArmorStand armorStand : items) {
                double angle = a++ * materialAngleIncrement + currentAngleItems;

                double nextX = data.getRadius() * Math.sin(Math.toRadians(angle));
                double nextY = data.getRadius() * Math.cos(Math.toRadians(angle));

                Location armorStandLocation = data.getLocation().clone().add(nextX, nextY - yOffSetArmorStand(armorStand.isSmall()), 0);
                armorStand.teleport(armorStandLocation);
            }
        }
    }

Добавь сюда интерполяцию для ArmorStand, для плавного перемещения предмета на следующую armorStandLocation от текущего armorStand.getLocation()

Реализация: начинаем цикл for, создаём интерполяцию для ArmorStand и плавно перемещаем предмет к его следующей точке armorStandLocation
Важно: по оси Z не перемещаем, только X и Y 
Assistant: Чтобы добавить интерполяцию к перемещению объектов типа `ArmorStand`, вам нужно будет использовать линейную интерполяцию (lerp) для плавного перемещения от текущей позиции к целевой позиции. Ниже приведённый код показывает, как это можно сделать. Мы будем использовать некоторый коэффициент `delta`, который будет определять скорость интерполяции.

Вот исправленный код:

```java
@Override
public void run() {
    double angleIncrement = 360.0 / data.getPositionColors().size();
    double materialAngleIncrement = 360.0 / (items.size() + itemsAddProcess.size());
    
    currentAngleItems += data.getItemsSpeed();

    for (ArmorStand armorStand : items) {
        double angle = a++ * materialAngleIncrement + currentAngleItems;

        double nextX = data.getRadius() * Math.sin(Math.toRadians(angle));
        double nextY = data.getRadius() * Math.cos(Math.toRadians(angle));
        
        Location targetLocation = data.getLocation().clone().add(nextX, nextY - yOffSetArmorStand(armorStand.isSmall()), 0);
        
        // Текущая позиция ArmorStand
        Location currentLocation = armorStand.getLocation();
        
        // Коэффициент интерполяции
        double delta = 0.1; // Измените на желаемое значение для скорости перемещения

        // Линейная интерполяция по осям X и Y
        double newX = currentLocation.getX() + (targetLocation.getX() - currentLocation.getX()) * delta;
        double newY = currentLocation.getY() + (targetLocation.getY() - currentLocation.getY()) * delta;

        // Создайте новую локацию, чтобы сохранить Z-координату
        Location newLocation = new Location(currentLocation.getWorld(), newX, newY, currentLocation.getZ());

        // Телепортируйте ArmorStand на новое место
        armorStand.teleport(newLocation);
    }
}
```

### Объяснение кода:
1. **Целевая локация:** Мы создаём `targetLocation`, основываясь на вычисленных значениях `nextX` и `nextY`.
2. **Текущая локация:** Получаем текущую позицию `armorStand`.
3. **Коэффициент интерполяции:** Задаём коэффициент `delta`, который определяет, насколько быстро `armorStand` будет двигаться к своей целевой позиции. Значение `0.1` можно изменить на большее, если хотите, чтобы движение было быстрее или меньше для медленного перемещения.
4. **Линейная интерполяция:** Мы вычисляем новые координаты `newX` и `newY`, которые будут находиться между текущей позицией и целевой.
5. **Создание новой локации:** Мы создаём новую `Location` на основе новых координат, сохраняя при этом координату Z.
6. **Телепортация:** Наконец, вызываем `armorStand.teleport(newLocation)` для перемещения `armorStand`.

Таким образом, данный код обеспечивает плавное перемещение `ArmorStand` к новой позиции по осям X и Y.
User: Не работает, все блоки прилипают просто к data.getLocation() и крутяться вокруг него и плавной нет
Нужно внутри цикла for добавить BukkitRunnable который будет перемещать поэтапно все это
Assistant: Чтобы реализовать плавное перемещение `ArmorStand` к новым позициям в каждом кадре, вам нужно использовать `BukkitRunnable`. Это позволит вам анимировать перемещение `ArmorStand` за несколько обновлений, что создаст эффект интерполяции. 

Ниже приведен пример, как можно интегрировать `BukkitRunnable` для анимации перемещения `ArmorStand` к его целевой позиции:

```java
@Override
public void run() {
    double angleIncrement = 360.0 / data.getPositionColors().size();
    double materialAngleIncrement = 360.0 / (items.size() + itemsAddProcess.size());
    
    currentAngleItems += data.getItemsSpeed();

    for (ArmorStand armorStand : items) {
        double angle = a++ * materialAngleIncrement + currentAngleItems;

        double nextX = data.getRadius() * Math.sin(Math.toRadians(angle));
        double nextY = data.getRadius() * Math.cos(Math.toRadians(angle));
        
        Location targetLocation = data.getLocation().clone().add(nextX, nextY - yOffSetArmorStand(armorStand.isSmall()), 0);
        Location currentLocation = armorStand.getLocation();

        // Запускаем новую задачу для плавной анимации
        new BukkitRunnable() {
            double delta = 0.1; // скорость интерполяции
            int steps = 10; // количество шагов анимации
            int currentStep = 0;

            @Override
            public void run() {
                if (currentStep < steps) {
                    // Линейная интерполяция по осям X и Y
                    double newX = currentLocation.getX() + (targetLocation.getX() - currentLocation.getX()) * (currentStep / (double) steps);
                    double newY = currentLocation.getY() + (targetLocation.getY() - currentLocation.getY()) * (currentStep / (double) steps);

                    // Создайте новую локацию, чтобы сохранить Z-координату
                    Location newLocation = new Location(currentLocation.getWorld(), newX, newY, currentLocation.getZ());

                    // Телепортируйте ArmorStand на новое место
                    armorStand.teleport(newLocation);

                    currentStep++;
                } else {
                    // Остановить задачу, когда все шаги завершены
                    this.cancel();
                }
            }
        }.runTaskTimer(plugin, 0, 1); // `plugin` - это ваш экземпляр плагина
    }
}
```

### Объяснение изменений:
1. **Запуск `BukkitRunnable`:** Внутри цикла `for`, для каждого `ArmorStand` создается новая задача `BukkitRunnable`, чтобы управлять анимацией плавного перемещения.
2. **Количество шагов:** Переменная `steps` определяет, на сколько шагов будет разбито перемещение. Вы можете настроить это значение, чтобы сделать анимацию более или менее плавной.
3. **Счетчик шагов:** Используется переменная `currentStep` для отслеживания текущего шага анимации.
4. **Интерполяция:** Внутри `run` нового `BukkitRunnable`, `ArmorStand` будет плавно перемещаться из `currentLocation` в `targetLocation` на основе номера текущего шага.
5. **Завершение задачи:** Когда все шаги завершены, задача отменяется с помощью `this.cancel()`.

Этот подход позволит каждому `ArmorStand` двигаться к своим новым позициям плавно и независимо друг от друга.
User: Все блоки просто вставли на месте и не перемещаются
Assistant: Похоже, что у вас возникли проблемы с перемещением блоков. Могу ли я узнать больше о том, в каком контексте вы работаете с блоками? Это может быть связано с программированием, веб-дизайном или чем-то другим? Пожалуйста, предоставьте больше информации, чтобы я мог лучше помочь вам.
User: @Override
public void run() {
    double angleIncrement = 360.0 / data.getPositionColors().size();
    double materialAngleIncrement = 360.0 / (items.size() + itemsAddProcess.size());
    
    currentAngleItems += data.getItemsSpeed();

    for (ArmorStand armorStand : items) {
        double angle = a++ * materialAngleIncrement + currentAngleItems;

        double nextX = data.getRadius() * Math.sin(Math.toRadians(angle));
        double nextY = data.getRadius() * Math.cos(Math.toRadians(angle));
        
        Location targetLocation = data.getLocation().clone().add(nextX, nextY - yOffSetArmorStand(armorStand.isSmall()), 0);
        Location currentLocation = armorStand.getLocation();

        // Запускаем новую задачу для плавной анимации
        new BukkitRunnable() {
            double delta = 0.1; // скорость интерполяции
            int steps = 10; // количество шагов анимации
            int currentStep = 0;

            @Override
            public void run() {
                if (currentStep < steps) {
                    // Линейная интерполяция по осям X и Y
                    double newX = currentLocation.getX() + (targetLocation.getX() - currentLocation.getX()) * (currentStep / (double) steps);
                    double newY = currentLocation.getY() + (targetLocation.getY() - currentLocation.getY()) * (currentStep / (double) steps);

                    // Создайте новую локацию, чтобы сохранить Z-координату
                    Location newLocation = new Location(currentLocation.getWorld(), newX, newY, currentLocation.getZ());

                    // Телепортируйте ArmorStand на новое место
                    armorStand.teleport(newLocation);

                    currentStep++;
                } else {
                    // Остановить задачу, когда все шаги завершены
                    this.cancel();
                }
            }
        }.runTaskTimer(plugin, 0, 1); // `plugin` - это ваш экземпляр плагина
    }
}

ArmorStand просто стоят на месте и не двигаются, а должны плавно перемещаться
Assistant: