aliveMobs = new HashSet<>();
+ protected int mobCap;
+ protected Player linkedTo;
+ protected WaveEnding endCallback;
+ protected BossBar bossBar;
+
+ public Wave(Player linkedTo, WaveEnding endCallback, int mobCap, BarStyle seg){
+ this.linkedTo = linkedTo;
+ this.endCallback = endCallback;
+ this.mobCap = mobCap;
+ this.bossBar = Bukkit.createBossBar(String.format("Yet Another Wave"), BarColor.GREEN, seg);
+ }
+
+ public Wave(Player linkedTo, WaveEnding endCallback, int mobCap, BarStyle seg, BarColor barColor){
+ this.linkedTo = linkedTo;
+ this.endCallback = endCallback;
+ this.mobCap = mobCap;
+ this.bossBar = Bukkit.createBossBar(String.format("Yet Another Wave"), barColor, seg);
+ }
+
+ public void addMob(Entity e){
+ aliveMobs.add(e.getUniqueId());
+ this.bossBar.setProgress(aliveMobs.size() / (float) this.mobCap);
+ }
+
+ public void removeMob(Entity e){
+ aliveMobs.remove(e.getUniqueId());
+ this.bossBar.setProgress(aliveMobs.size() / (float) this.mobCap);
+ }
+
+ public int getAliveNumber(Entity e){
+ return aliveMobs.size();
+ }
+
+ public boolean isWaveFinished(){
+ return aliveMobs.isEmpty();
+ }
+
+ public boolean isWaveActive(){
+ return !aliveMobs.isEmpty();
+ }
+
+ public boolean isWaveMob(Entity e){
+ return aliveMobs.contains(e.getUniqueId());
+ }
+
+ public void perform(){}
+
+ public void clear(World world){
+ for(UUID uuid: aliveMobs){
+ Entity e = world.getEntity(uuid);
+ if (e != null && !e.isDead()) {
+ world.playSound(e.getLocation(), Sound.BLOCK_AMETHYST_BLOCK_BREAK,1.0f, ThreadLocalRandom.current().nextFloat(0.0f,1.0f));
+ e.remove();
+ }
+ }
+ this.bossBar.removePlayer(linkedTo);
+ }
+
+ public void begin(){
+ this.bossBar.addPlayer(linkedTo);
+ }
+
+}
diff --git a/src/main/java/ru/joutak/template/WaveEnding.java b/src/main/java/ru/joutak/template/WaveEnding.java
new file mode 100644
index 0000000..dcde4ec
--- /dev/null
+++ b/src/main/java/ru/joutak/template/WaveEnding.java
@@ -0,0 +1,5 @@
+package ru.joutak.template;
+
+public interface WaveEnding {
+ public void perform();
+}
diff --git a/src/main/java/ru/joutak/template/commands/Command.java b/src/main/java/ru/joutak/template/commands/Command.java
new file mode 100644
index 0000000..1723ae8
--- /dev/null
+++ b/src/main/java/ru/joutak/template/commands/Command.java
@@ -0,0 +1,38 @@
+package ru.joutak.template.commands;
+
+/**
+ * Базовый интерфейс для всех команд приложения.
+ *
+ * Определяет контракт, который должна реализовать каждая команда.
+ * Все команды поддерживают выполнение, вывод описания и указание
+ * количества требуемых аргументов.
+ *
+ */
+public interface Command {
+ /**
+ * Выполняет команду.
+ *
+ * Метод содержит основную логику работы команды.
+ * Реализация зависит от конкретной команды.
+ *
+ */
+ public void execute();
+
+ /**
+ * Возвращает описание команды в консоль.
+ *
+ * Описание включает синтаксис вызова команды
+ * и краткое пояснение её назначения.
+ *
+ *
+ * @return description
+ */
+ public String describe();
+
+ /**
+ * Возвращает количество аргументов, требуемых команде.
+ *
+ * @return количество аргументов командной строки
+ */
+ public int numberArgsRequired();
+}
diff --git a/src/main/java/ru/joutak/template/commands/CommandInvoker.java b/src/main/java/ru/joutak/template/commands/CommandInvoker.java
new file mode 100644
index 0000000..2c40a41
--- /dev/null
+++ b/src/main/java/ru/joutak/template/commands/CommandInvoker.java
@@ -0,0 +1,119 @@
+package ru.joutak.template.commands;
+
+import org.bukkit.command.defaults.HelpCommand;
+import org.bukkit.entity.Player;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Scanner;
+
+/**
+ * Класс для управления и выполнения команд приложения.
+ *
+ * Служит центральным диспетчером команд, предоставляя возможность
+ * их регистрации, вызова и выполнения. Поддерживает интерактивный режим
+ * работы с консолью и выполнение команд из скриптов.
+ *
+ *
+ * При запуске автоматически регистрирует все доступные команды
+ * и предоставляет интерактивный интерфейс для их вызова.
+ *
+ */
+public class CommandInvoker {
+ /** Сканер для чтения пользовательского ввода из консоли */
+ private static Scanner sc = new Scanner(System.in);
+ private static HashMap commands = new HashMap();
+
+ /**
+ * Создаёт новый invoking и регистрирует все доступные команды.
+ *
+ * В конструкторе выполняется регистрация следующих команд:
+ *
+ * - help — вывод справки по командам
+ * - clear — очистка коллекции
+ * - info — информация о коллекции
+ * - show — отображение всех элементов
+ * - exit — завершение работы
+ * - execute_file — выполнение команд из файла
+ * - insert — добавление элемента
+ * - update — обновление элемента по id
+ * - print_unique_author — вывод уникальных авторов
+ * - save — сохранение коллекции в файл
+ * - remove_key — удаление элемента по ключу
+ * - print_field_descending_difficulty — вывод сложности по убыванию
+ * - group_counting_by_maximum_point — группировка по максимальному баллу
+ * - remove_lower_key — удаление элементов с меньшими ключами
+ * - replace_if_greater — замена при большем значении
+ * - replace_if_lower — замена при меньшем значении
+ *
+ */
+ public CommandInvoker(Player p) {
+ commands.put("help", new HelpCommand());
+
+ }
+
+ /**
+ * Запускает интерактивный режим работы приложения.
+ *
+ * Читает команды из стандартного ввода построчно и передаёт их
+ * на выполнение до завершения работы программы.
+ *
+ */
+ public void run() {
+ while (sc.hasNext()) {
+ String line = sc.nextLine();
+ runParticularCommand(line);
+ }
+ }
+
+ /**
+ * Выполняет конкретную команду с заданными аргументами.
+ *
+ * Парсит строку команды, разделяя её на имя и аргументы.
+ * Проверяет существование команды и корректность количества аргументов.
+ * Для команд, реализующих {@link Modable}, устанавливает аргументы перед выполнением.
+ *
+ *
+ * @param line строка с именем команды и её аргументами
+ */
+ private static void runParticularCommand(String line){
+ String[] tokens = line.trim().replace("\n", "").split(" ");
+
+ String commandName = tokens[0];
+ ArrayList args = new ArrayList<>();
+ if (tokens.length > 1) {
+ for (int i = 1; i < tokens.length; i++) {
+ args.add(tokens[i]);
+ }
+ }
+
+ Command command = commands.get(commandName);
+ if (command == null) {
+ System.out.println("Неизвестная команда: " + commandName);
+ return;
+ }
+
+
+
+ if (command instanceof Modable) {
+ if(args.size()==command.numberArgsRequired())
+ ((Modable) command).setArguments(args);
+ else {
+ System.out.println("Слишком мало/много аргументов. Нужно " + command.numberArgsRequired() + " аргументов.");
+ return;
+ }
+ }
+
+ if(tokens[0] == ""){
+ return;
+ }
+
+ command.execute();
+ }
+}
diff --git a/src/main/java/ru/joutak/template/commands/HelpCommand.java b/src/main/java/ru/joutak/template/commands/HelpCommand.java
new file mode 100644
index 0000000..57fdc65
--- /dev/null
+++ b/src/main/java/ru/joutak/template/commands/HelpCommand.java
@@ -0,0 +1,22 @@
+package ru.joutak.template.commands;
+
+import java.util.Hashtable;
+
+public class HelpCommand implements Command{
+ @Override
+ public void execute() {
+ Hashtable commands = new Hashtable<>();
+ commands.put("help", new HelpCommand());
+
+ }
+
+ @Override
+ public String describe() {
+ return "/help - помощь (вывести все команды)";
+ }
+
+ @Override
+ public int numberArgsRequired() {
+ return 0;
+ }
+}
diff --git a/src/main/java/ru/joutak/template/commands/Modable.java b/src/main/java/ru/joutak/template/commands/Modable.java
new file mode 100644
index 0000000..bd125ff
--- /dev/null
+++ b/src/main/java/ru/joutak/template/commands/Modable.java
@@ -0,0 +1,20 @@
+package ru.joutak.template.commands;
+
+import java.util.ArrayList;
+
+/**
+ * Интерфейс для команд, требующих аргументы.
+ *
+ * Расширяет базовый интерфейс {@link Command}, добавляя возможность
+ * передачи аргументов командной строки. Команды, реализующие этот интерфейс,
+ * могут принимать дополнительные параметры при вызове.
+ *
+ */
+public interface Modable extends Command {
+ /**
+ * Устанавливает аргументы командной строки для выполнения команды.
+ *
+ * @param args список строковых аргументов, переданных команде
+ */
+ public void setArguments(ArrayList args);
+}
diff --git a/src/main/java/ru/joutak/template/commands/StopCommand.java b/src/main/java/ru/joutak/template/commands/StopCommand.java
new file mode 100644
index 0000000..a17b1c0
--- /dev/null
+++ b/src/main/java/ru/joutak/template/commands/StopCommand.java
@@ -0,0 +1,17 @@
+package ru.joutak.template.commands;
+
+public class StopCommand implements Command{
+ @Override
+ public void execute() {
+
+ }
+ @Override
+ public String describe(){
+
+ }
+
+ @Override
+ public int numberArgsRequired() {
+ return 0;
+ }
+}
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 4428874..d3c3917 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,12 +1,18 @@
-name: ${NAME}
-version: ${VERSION}
-api-version: ${MINECRAFT_VERSION}
-main: ru.joutak.template.EmptyPlugin
-description: 'A template plugin'
-authors: ['EnderDissa', 'Stunnerer', 's4dnex']
-contributors: ['technosimp']
-website: ${WEBSITE}
-
-depend: []
-libraries:
- - 'org.projectlombok:lombok:${LOMBOK_VERSION}'
\ No newline at end of file
+name: ${NAME}
+version: ${VERSION}
+api-version: ${MINECRAFT_VERSION}
+main: ru.joutak.template.SomeCoolPlugin
+description: 'A cool plugin'
+authors: ['V7Zeee']
+contributors: []
+website: ${WEBSITE}
+
+depend: []
+libraries:
+ - 'org.projectlombok:lombok:${LOMBOK_VERSION}'
+
+commands:
+ coolplugin:
+ description: General command of the coolest plugin ever
+ usage: /coolplugin
+
diff --git a/src/test/java/ru/joutak/test/ExampleTest.java b/src/test/java/ru/joutak/test/ExampleTest.java
index 3d24ac1..3a85916 100644
--- a/src/test/java/ru/joutak/test/ExampleTest.java
+++ b/src/test/java/ru/joutak/test/ExampleTest.java
@@ -1,36 +1,36 @@
-package ru.joutak.test;
-
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-public class ExampleTest {
- @BeforeAll
- static void setup() {
- System.out.println("@BeforeAll executed");
- }
-
- @BeforeEach
- void setupThis() {
- System.out.println("@BeforeEach executed");
- }
-
- @AfterEach
- void tearThis() {
- System.out.println("@AfterEach executed");
- }
-
- @Test
- void test() {
- Assertions.assertTrue(true);
- System.out.println("@Test executed");
- }
-
- @AfterAll
- static void tear() {
- System.out.println("@AfterAll executed");
- }
-}
+package ru.joutak.test;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class ExampleTest {
+ @BeforeAll
+ static void setup() {
+ System.out.println("@BeforeAll executed");
+ }
+
+ @BeforeEach
+ void setupThis() {
+ System.out.println("@BeforeEach executed");
+ }
+
+ @AfterEach
+ void tearThis() {
+ System.out.println("@AfterEach executed");
+ }
+
+ @Test
+ void test() {
+ Assertions.assertTrue(true);
+ System.out.println("@Test executed");
+ }
+
+ @AfterAll
+ static void tear() {
+ System.out.println("@AfterAll executed");
+ }
+}