1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
  2. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

(Решено)Сделать получение урона без блока на голове

Тема в разделе "Разработка плагинов для новичков", создана пользователем reZero, 21 июн 2019.

Статус темы:
Закрыта.
  1. Автор темы
    reZero

    reZero Активный участник Пользователь

    Баллы:
    76
    Всем привет!
    Есть небольшая задумка с космосом..
    Хочу сделать некий шлем, без которого игрок будет получать урон и сообщения в стиле "У Вас нет воздуха".
    Сама проблема в том, что я не знаю, как можно отслеживать, когда игрок со шлемом, а когда без. Также, хотелось бы узнать, можно ли ко всему этому еще проверять есть ли блок на голове? Не уверен, что его можно надеть на голову...
    Надеюсь на Вашу помощь, спасибо!
     
  2. HunterGaming

    HunterGaming Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    sqdFendy
    Ты можешь исользовать Runnable + player -> getInventory -> getHelmet -> getType
     
  3. TheSkiffSailor

    TheSkiffSailor Новичок Пользователь

    Баллы:
    21
    Имя в Minecraft:
    TheSkiffSailor
    Берешь код, его в шедулер вставляешь. Предварительно сделав ему `пузырьки` как при нырянии в воду
    PHP:
    Player p;

    if(
    p.getInventory().getSlot(103).getItem().getType() == Material.GLASS && p.getInventory().getSlot(103).getItem() != null) {
    p.setHealth(p.getHealth() - 1);
    }
     
  4. Автор темы
    reZero

    reZero Активный участник Пользователь

    Баллы:
    76
    Это все понятно. Мне непонятно другое.. Чтобы запустить ранебл, нужно какое-то действие от игрока, не так ли?
    Вот сама и проблема в этом. Я не знаю, как ловить данный момент.. Как проверять есть ли на нем шлем или нет чтоб соответственно дамаг ему наносить
     
  5. TheSkiffSailor

    TheSkiffSailor Новичок Пользователь

    Баллы:
    21
    Имя в Minecraft:
    TheSkiffSailor
    Просто запусти ранейбл в onEnable
     
  6. Автор темы
    reZero

    reZero Активный участник Пользователь

    Баллы:
    76
    А что по нагрузке? Ты имеешь ввиду в ранебле перебирать онлайн игроков и делать что мне нужно?)
     
  7. TheSkiffSailor

    TheSkiffSailor Новичок Пользователь

    Баллы:
    21
    Имя в Minecraft:
    TheSkiffSailor
    Код:
    public class Main {
        public void runR(Player p, int delay, int period) {
            BukkitRunnable r = new BukkitRunnable() {
              
                @Override
                public void run() {
                    if (p.getInventory().getHelmet().getType() == Material.GLASS) {
                        p.damage(1);
                    }
                }
            };
            r.runTaskTimer((Plugin) this, delay, period);
        }
      
        public void onEnable() {
            Bukkit.getOnlinePlayers().forEach(p -> runR(p, 20, 20));
        }
    }

    //EDIT: А вообще делай эт ов join евенте
     
  8. Автор темы
    reZero

    reZero Активный участник Пользователь

    Баллы:
    76
    Не уверен, что данный образец кода самый лучший вариант в плане оптимизации.
    Подожду людей опытнее, без обид.
    В любом случае, спасибо!)
     
  9. NyanGuyMF

    NyanGuyMF Активный участник Пользователь

    Баллы:
    76
    Лучше не сделать, тебе всё равно придется отслеживать всех онлайн игроков. Тут главное сразу отсеивать всех и, возможно, переложить это всё в отдельные потоки (например, обрабатывать с помощью parallelStream — runTaskTimer -> parallelStream -> forEach)
     
  10. LuckyZeeRo

    LuckyZeeRo Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    i0xHeX
    И все равно потом обратно складывать в один придется, обойдется дороже чем обычная итерация
     
  11. LuckyZeeRo

    LuckyZeeRo Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    i0xHeX
    Да тут то других вариантов особо и нет. Допустим ты будешь отслеживать (даже в идеальном случае одним событием) снятие и одевание шлема и пихать игроков в коллекцию, все равно тебе нужен как минимум один тикер, который будет пробегать по этим игрокам и дамажить. Получается тот же O(N) в худшем случае. Так что пожалуй один шедулер-тикер с перебором всех игроков и проверкой на шлем самый оптимальный вариант решения задачи.

    Сервер за тик выполняет в задачи в сотни раз сложнее чем эта мелкая итерация. Так что, подведя итоги и цитируя одного бывалого здесь человека, хочу сказать, что "передоза на этой почве" точно не будет и сервер "от такой экcзекуции" не "двинет кони" :)
     
  12. TheZefirrkka

    TheZefirrkka Активный участник Пользователь

    Баллы:
    76
    Даже если ты сделаешь 100 таких раннейблов, то тпс сервера не упадет, данный код никак не нагружает сервер
     
  13. hyndorik

    hyndorik Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    hyndo
    Ой ну и жестб посоветовал) на кой черт параллельные стримы тут?

    Ну а так да, че выше написали, вполне сойдет
     
  14. NyanGuyMF

    NyanGuyMF Активный участник Пользователь

    Баллы:
    76
    Самый ублюдский и простой вариант обработки в многопотоке
     
  15. TheSkiffSailor

    TheSkiffSailor Новичок Пользователь

    Баллы:
    21
    Имя в Minecraft:
    TheSkiffSailor
    Крч, тебе думаю понятно как реализовать, если да закрой тему :O
     
  16. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Вот держи.

    Код:
    public class PlayerRunnable extends BukkitRunnable {
    
        @Override
        public void run() {
            Bukkit.getOnlinePlayers().forEach(player -> {
                if(player.getInventory().getHelmet().getType() != Material.GLASS) {
                    player.damage(1);
                }
            });
        }
    }
    Код:
    public class Main extends JavaPlugin {
    
        @Override
        public void onEnable() {
            new PlayerRunnable(this).runTaskTimer(plugin, 20, 20);;
        }
    }
     
    Последнее редактирование: 22 июн 2019
  17. hyndorik

    hyndorik Активный участник Пользователь

    Баллы:
    98
    Имя в Minecraft:
    hyndo
    Для чего многопоток на этот мелкий цикл))
     
  18. AbstractCoder

    AbstractCoder Активный участник Пользователь

    Баллы:
    76
    Имя в Minecraft:
    AbstractCoder
    Умно, StackOverflowException тебе в е*ало
     
  19. alexandrage

    alexandrage Старожил Пользователь

    Баллы:
    173
    Виноват :D
     
  20. Автор темы
    reZero

    reZero Активный участник Пользователь

    Баллы:
    76
    Спасибо всем)
     
Статус темы:
Закрыта.

Поделиться этой страницей