Вопрос Как сделать топ по алмазам?

Версия Minecraft
1.16.X

Mikita

Заблокирован
Сообщения
57
Решения
3
Хочу создать голограмму с топами по алмазами. То есть когда игрок положил алмаз в бочку ему начисляется +1 к баллу в голограмме. Как это можно релиазавать?
 
Это действительно тяжело. В Bukkit API нет удобного способа отслеживать, как игроки кладут\забирают вещи в контейнеры
Объединено

Как вариант, сканировать все контейнеры в регионе, принадлежащем игроку, и смотреть там общее количество алмазов
 
сканировать все контейнеры в регионе
Время на выполнение кода будет огромным на столько, что обновление топов можно будет сделать только раз в день

offtop Помочь по вопросу мелкой подсказкой невозможно, говорю на основе написания LksShards, вместе с отслеживанием и подсчитыванием предметов, необходимо реализовать хранение, самое рациональное решение использовать sql или mysql, при большом количестве онлайна база данных упадет, а значит нужно писать кеш память. Подсчитывание для топа можно реализовать циклом по данным в базе

По итогу, чтобы помочь с вопросом, нужно скидывать исходный код готового плагина
 
Время на выполнение кода будет огромным на столько, что обновление топов можно будет сделать только раз в день

offtop Помочь по вопросу мелкой подсказкой невозможно, говорю на основе написания LksShards, вместе с отслеживанием и подсчитыванием предметов, необходимо реализовать хранение, самое рациональное решение использовать sql или mysql, при большом количестве онлайна база данных упадет, а значит нужно писать кеш память. Подсчитывание для топа можно реализовать циклом по данным в базе

По итогу, чтобы помочь с вопросом, нужно скидывать исходный код готового плагина
Чет желание сделать топы пропало...
 
Время на выполнение кода будет огромным на столько, что обновление топов можно будет сделать только раз в день
Это не так. Задача в этом плане не так страшна, как кажется. Однако, соглашусь, тут подсказать тяжело, ибо нужно прям целый плагин скидывать, а это вряд ли кто-то сделает
 
Хочу создать голограмму с топами по алмазами. То есть когда игрок положил алмаз в бочку ему начисляется +1 к баллу в голограмме. Как это можно релиазавать?
Java:
@EventHandler
public void onClose(InventoryCloseEvent e) {
HashMap<Location, UUID> chestOwner = new HashMap<>();
    UUID uuid = e.getPlayer().getUniqueId();
    Location location = e.getInventory().getLocation();
if(e.getInventory().getType() == InventoryType.CHEST && chestOwner.containsKey(location)) {
Player owner = Bukkit.getPlayer(chestOwner.get(location));
if(owner!=null&&owner.getUniqueId()==uuid) {
 return;
        }
HashMap<UUID, Integer> database = new HashMap<>();
 if (!database.containsKey(uuid)) {
database.put(uuid, 0);
        }
Arrays.stream(e.getInventory().getContents())
.map(s -> s.getType() == Material.DIAMOND)
.forEach(s -> database.put(uuid, database.get(uuid) + 1));
Arrays.stream(e.getInventory().getContents())
.map(s -> s.getType() == Material.DIAMOND)
.forEach(s -> database.put(owner.getUniqueId(), database.get(owner.getUniqueId()) - 1));
        chestOwner.put(location,uuid);
    }
}
хэшмапу замени на базу данных (h2,sql,mysql) либо yml файл

Там ещё уничтожение сундуков обработай и всё.
 
Java:
@EventHandler
public void onClose(InventoryCloseEvent e) {
HashMap<Location, UUID> chestOwner = new HashMap<>();
    UUID uuid = e.getPlayer().getUniqueId();
    Location location = e.getInventory().getLocation();
if(e.getInventory().getType() == InventoryType.CHEST && chestOwner.containsKey(location)) {
Player owner = Bukkit.getPlayer(chestOwner.get(location));
if(owner!=null&&owner.getUniqueId()==uuid) {
 return;
        }
HashMap<UUID, Integer> database = new HashMap<>();
 if (!database.containsKey(uuid)) {
database.put(uuid, 0);
        }
Arrays.stream(e.getInventory().getContents())
.map(s -> s.getType() == Material.DIAMOND)
.forEach(s -> database.put(uuid, database.get(uuid) + 1));
Arrays.stream(e.getInventory().getContents())
.map(s -> s.getType() == Material.DIAMOND)
.forEach(s -> database.put(owner.getUniqueId(), database.get(owner.getUniqueId()) - 1));
        chestOwner.put(location,uuid);
    }
}
хэшмапу замени на базу данных (h2,sql,mysql) либо yml файл

Там ещё уничтожение сундуков обработай и всё.
я тут немного ошибся, ну концепцию думаю ты понял.
Java:
@EventHandler
    public void onClose(InventoryCloseEvent e) {
        HashMap<Location, UUID> chestOwner = new HashMap<>();
        UUID uuid = e.getPlayer().getUniqueId();
        Location location = e.getInventory().getLocation();
        if(e.getInventory().getType() == InventoryType.CHEST) {
            if(chestOwner.containsKey(location)) {
                if (chestOwner.get(location) == uuid) {
                    return;
                }
            }
            HashMap<UUID, Integer> database = new HashMap<>();
            if (!database.containsKey(uuid)) {
                database.put(uuid, 0);
            }
            Arrays.stream(e.getInventory().getContents())
                    .map(s -> s.getType() == Material.DIAMOND)
                    .forEach(s -> database.put(uuid, database.get(uuid) + 1));
            Arrays.stream(e.getInventory().getContents())
                    .map(s -> s.getType() == Material.DIAMOND)
                    .forEach(s -> database.put(chestOwner.get(location), database.get(chestOwner.get(location)) - 1));
            chestOwner.put(location,uuid);
        }
    }

вот поправил
Объединено

я тут немного ошибся, ну концепцию думаю ты понял.
Java:
@EventHandler
    public void onClose(InventoryCloseEvent e) {
        HashMap<Location, UUID> chestOwner = new HashMap<>();
        UUID uuid = e.getPlayer().getUniqueId();
        Location location = e.getInventory().getLocation();
        if(e.getInventory().getType() == InventoryType.CHEST) {
            if(chestOwner.containsKey(location)) {
                if (chestOwner.get(location) == uuid) {
                    return;
                }
            }
            HashMap<UUID, Integer> database = new HashMap<>();
            if (!database.containsKey(uuid)) {
                database.put(uuid, 0);
            }
            Arrays.stream(e.getInventory().getContents())
                    .map(s -> s.getType() == Material.DIAMOND)
                    .forEach(s -> database.put(uuid, database.get(uuid) + 1));
            Arrays.stream(e.getInventory().getContents())
                    .map(s -> s.getType() == Material.DIAMOND)
                    .forEach(s -> database.put(chestOwner.get(location), database.get(chestOwner.get(location)) - 1));
            chestOwner.put(location,uuid);
        }
    }

вот поправил
я тут забыл количество обработать, ну дальше сам
Объединено

я тут немного ошибся, ну концепцию думаю ты понял.
Java:
@EventHandler
    public void onClose(InventoryCloseEvent e) {
        HashMap<Location, UUID> chestOwner = new HashMap<>();
        UUID uuid = e.getPlayer().getUniqueId();
        Location location = e.getInventory().getLocation();
        if(e.getInventory().getType() == InventoryType.CHEST) {
            if(chestOwner.containsKey(location)) {
                if (chestOwner.get(location) == uuid) {
                    return;
                }
            }
            HashMap<UUID, Integer> database = new HashMap<>();
            if (!database.containsKey(uuid)) {
                database.put(uuid, 0);
            }
            Arrays.stream(e.getInventory().getContents())
                    .map(s -> s.getType() == Material.DIAMOND)
                    .forEach(s -> database.put(uuid, database.get(uuid) + 1));
            Arrays.stream(e.getInventory().getContents())
                    .map(s -> s.getType() == Material.DIAMOND)
                    .forEach(s -> database.put(chestOwner.get(location), database.get(chestOwner.get(location)) - 1));
            chestOwner.put(location,uuid);
        }
    }

вот поправил
Объединено


я тут забыл количество обработать, ну дальше сам
и наверное лучше 2 эвента обрабатывать - Close и Open (Опен для удаления алмазов из статы 2 человека)
 
Этот код будет засчитывать даже закрытие гуи с алмазами внутри. К тому же, если сломать сундук или забрать оттуда алмазы другим способом, в бд будет старое значение
Код:
.map(s -> s.getType() == Material.DIAMOND)
это вообще что? тут логичнее filter + count
 
Назад
Сверху Снизу