package com.example.auraplugin;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Плагин AuraPlugin добавляет падающие изумруды вокруг выбранных игроков.
 */
public class AuraPlugin extends JavaPlugin {

    // Набор игроков, у которых включена аура
    private final Set<Player> auraPlayers = ConcurrentHashMap.newKeySet();

    // Карта для хранения аур игроков и их изумрудов
    private final Map<UUID, PlayerAura> playerAuras = new ConcurrentHashMap<>();

    // Количество изумрудов в ауре
    private final int emeraldCount = 20; // Увеличено количество изумрудов

    @Override
    public void onEnable() {
        getLogger().info("AuraPlugin включен!");
        // Регистрация команды
        Objects.requireNonNull(getCommand("aura")).setExecutor(this);
        // Запуск задачи для обновления аур
        startAuraUpdateTask();
    }

    @Override
    public void onDisable() {
        getLogger().info("AuraPlugin выключен.");
        // Удаление всех аур при выключении плагина
        for (PlayerAura aura : playerAuras.values()) {
            aura.removeAura();
        }
        playerAuras.clear();
        auraPlayers.clear();
    }

    /**
     * Обработка команды /aura.
     * Использование: /aura <on|off> <игрок>
     */
    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (command.getName().equalsIgnoreCase("aura")) {
            if (!sender.hasPermission("aura.use")) {
                sender.sendMessage(ChatColor.RED + "У вас нет прав использовать эту команду.");
                return true;
            }

            if (args.length != 2) {
                sender.sendMessage(ChatColor.RED + "Использование: /aura <on|off> <игрок>");
                return true;
            }

            String action = args[0];
            String playerName = args[1];
            Player target = Bukkit.getPlayerExact(playerName);

            if (target == null) {
                sender.sendMessage(ChatColor.RED + "Игрок не найден.");
                return true;
            }

            if (action.equalsIgnoreCase("on")) {
                if (auraPlayers.contains(target)) {
                    sender.sendMessage(ChatColor.YELLOW + "Аура уже включена для " + target.getName() + ".");
                } else {
                    auraPlayers.add(target);
                    PlayerAura aura = new PlayerAura(target);
                    playerAuras.put(target.getUniqueId(), aura);
                    sender.sendMessage(ChatColor.GREEN + "Аура включена для " + target.getName() + ".");
                }
            } else if (action.equalsIgnoreCase("off")) {
                if (!auraPlayers.contains(target)) {
                    sender.sendMessage(ChatColor.YELLOW + "У этого игрока не была включена аура.");
                } else {
                    auraPlayers.remove(target);
                    PlayerAura aura = playerAuras.remove(target.getUniqueId());
                    if (aura != null) {
                        aura.removeAura();
                    }
                    sender.sendMessage(ChatColor.GREEN + "Аура отключена для " + target.getName() + ".");
                }
            } else {
                sender.sendMessage(ChatColor.RED + "Неизвестное действие. Используйте on или off.");
            }
            return true;
        }
        return false;
    }

    /**
     * Внутренний класс для управления аурой игрока.
     */
    private static class PlayerAura {
        private final Player player;
        private final List<Item> emeralds = new ArrayList<>();
        private final double spawnHeight = 3.0; // Высота спауна над игроком
        private final double horizontalRadius = 2.0; // Горизонтальный радиус спауна
        private final Random random = new Random();
        private final List<Double> angles = new ArrayList<>(); // Углы для изумрудов

        PlayerAura(Player player) {
            this.player = player;
            initializeAngles();
            spawnEmeralds();
        }

        /**
         * Инициализация углов для равномерного распределения изумрудов.
         */
        private void initializeAngles() {
            for (int i = 0; i < 360; i += 360 / 20) { // 20 изумрудов
                angles.add(Math.toRadians(i + random.nextDouble() * 360 / 20));
            }
        }

        /**
         * Спауним все изумруды вокруг игрока.
         */
        private void spawnEmeralds() {
            Location baseLocation = player.getLocation().clone().add(0, spawnHeight, 0);

            for (int i = 0; i < emeraldsCount(); i++) {
                double angle = angles.get(i);
                double x = horizontalRadius * Math.cos(angle);
                double z = horizontalRadius * Math.sin(angle);
                Location spawnLocation = baseLocation.clone().add(x, 0, z);

                // Создание изумруда
                Item emerald = player.getWorld().dropItemNaturally(spawnLocation, new ItemStack(Material.EMERALD));
                emerald.setPickupDelay(Integer.MAX_VALUE); // Запрет на подбор
                emerald.setVelocity(new org.bukkit.util.Vector(0, -0.05, 0)); // Медленная скорость вниз
                emerald.setGravity(true); // Включена гравитация

                emeralds.add(emerald);
            }
        }

        /**
         * Обновление позиции изумрудов: изумруды падают вниз и исчезают под игроком.
         */
        public void updateAura() {
            Iterator<Item> iterator = emeralds.iterator();
            while (iterator.hasNext()) {
                Item emerald = iterator.next();
                if (emerald.isDead() || !emerald.isValid()) {
                    iterator.remove();
                    continue;
                }

                Location emeraldLocation = emerald.getLocation();
                Location playerLocation = player.getLocation();

                // Если изумруд ниже уровня ног игрока, удалить его и спаунить заново
                if (emeraldLocation.getY() < playerLocation.getY()) {
                    emerald.remove();
                    iterator.remove();
                    spawnSingleEmerald();
                }
            }
        }

        /**
         * Спауним один изумруд над игроком в случайном направлении.
         */
        private void spawnSingleEmerald() {
            Location baseLocation = player.getLocation().clone().add(0, spawnHeight, 0);
            double angle = random.nextDouble() * 2 * Math.PI;
            double x = horizontalRadius * Math.cos(angle);
            double z = horizontalRadius * Math.sin(angle);
            Location spawnLocation = baseLocation.clone().add(x, 0, z);

            // Создание изумруда
            Item emerald = player.getWorld().dropItemNaturally(spawnLocation, new ItemStack(Material.EMERALD));
            emerald.setPickupDelay(Integer.MAX_VALUE); // Запрет на подбор
            emerald.setVelocity(new org.bukkit.util.Vector(0, -0.05, 0)); // Медленная скорость вниз
            emerald.setGravity(true); // Включена гравитация

            emeralds.add(emerald);
        }

        /**
         * Удаление всех изумрудов ауры.
         */
        public void removeAura() {
            for (Item emerald : emeralds) {
                if (emerald != null && !emerald.isDead()) {
                    emerald.remove();
                }
            }
            emeralds.clear();
        }

        /**
         * Возвращает количество изумрудов в ауре.
         */
        private int emeraldsCount() {
            return 20; // Увеличено количество изумрудов
        }
    }

    /**
     * Запуск периодической задачи для обновления аур.
     */
    private void startAuraUpdateTask() {
        new BukkitRunnable() {
            @Override
            public void run() {
                for (PlayerAura aura : new ArrayList<>(playerAuras.values())) {
                    if (!aura.player.isOnline()) {
                        removeAura(aura.player);
                        continue;
                    }
                    aura.updateAura();
                }
            }
        }.runTaskTimer(this, 0L, 1L); // Запуск каждые 1 тик (~0.05 сек) для более частого обновления
    }

    /**
     * Метод для удаления ауры у игрока.
     *
     * @param player Игрок, у которого нужно удалить ауру.
     */
    private void removeAura(Player player) {
        auraPlayers.remove(player);
        PlayerAura aura = playerAuras.remove(player.getUniqueId());
        if (aura != null) {
            aura.removeAura();
        }
    }
}

name: AuraPlugin
main: com.example.auraplugin.AuraPlugin
version: 1.0
api-version: 1.20
description: Плагин добавляет ауру изумрудов вокруг выбранных игроков.
commands:
  aura:
    description: Включить или отключить ауру для игрока.
    usage: /aura <on|off> <игрок>
    permission: aura.use
permissions:
  aura.use:
    description: Позволяет использовать команду /aura
    default: op


Улучши сверх глобально по оптимизации, красоте ауры (чтобы она была очень крутая, анимированная, вместо изумрудов золото)