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

  • Автор темы Автор темы reZero
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

reZero

Активный участник
Пользователь
Баллы
76
Всем привет!
Есть небольшая задумка с космосом..
Хочу сделать некий шлем, без которого игрок будет получать урон и сообщения в стиле "У Вас нет воздуха".
Сама проблема в том, что я не знаю, как можно отслеживать, когда игрок со шлемом, а когда без. Также, хотелось бы узнать, можно ли ко всему этому еще проверять есть ли блок на голове? Не уверен, что его можно надеть на голову...
Надеюсь на Вашу помощь, спасибо!
 
Всем привет!
Есть небольшая задумка с космосом..
Хочу сделать некий шлем, без которого игрок будет получать урон и сообщения в стиле "У Вас нет воздуха".
Сама проблема в том, что я не знаю, как можно отслеживать, когда игрок со шлемом, а когда без. Также, хотелось бы узнать, можно ли ко всему этому еще проверять есть ли блок на голове? Не уверен, что его можно надеть на голову...
Надеюсь на Вашу помощь, спасибо!
Ты можешь исользовать Runnable + player -> getInventory -> getHelmet -> getType
 
Берешь код, его в шедулер вставляешь. Предварительно сделав ему `пузырьки` как при нырянии в воду
PHP:
Player p;

if(p.getInventory().getSlot(103).getItem().getType() == Material.GLASS && p.getInventory().getSlot(103).getItem() != null) {
p.setHealth(p.getHealth() - 1);
}
 
Ты можешь исользовать Runnable + player -> getInventory -> getHelmet -> getType
Берешь код, его в шедулер вставляешь. Предварительно сделав ему `пузырьки` как при нырянии в воду
PHP:
Player p;

if(p.getInventory().getSlot(103).getItem().getType() == Material.GLASS && p.getInventory().getSlot(103).getItem() != null) {
p.setHealth(p.getHealth() - 1);
}
Это все понятно. Мне непонятно другое.. Чтобы запустить ранебл, нужно какое-то действие от игрока, не так ли?
Вот сама и проблема в этом. Я не знаю, как ловить данный момент.. Как проверять есть ли на нем шлем или нет чтоб соответственно дамаг ему наносить
 
Это все понятно. Мне непонятно другое.. Чтобы запустить ранебл, нужно какое-то действие от игрока, не так ли?
Вот сама и проблема в этом. Я не знаю, как ловить данный момент.. Как проверять есть ли на нем шлем или нет чтоб соответственно дамаг ему наносить
Просто запусти ранейбл в onEnable
 
Это все понятно. Мне непонятно другое.. Чтобы запустить ранебл, нужно какое-то действие от игрока, не так ли?
Вот сама и проблема в этом. Я не знаю, как ловить данный момент.. Как проверять есть ли на нем шлем или нет чтоб соответственно дамаг ему наносить
Код:
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 евенте
 
Код:
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 евенте
Не уверен, что данный образец кода самый лучший вариант в плане оптимизации.
Подожду людей опытнее, без обид.
В любом случае, спасибо!)
 
Не уверен, что данный образец кода самый лучший вариант в плане оптимизации.
Подожду людей опытнее, без обид.
В любом случае, спасибо!)
Лучше не сделать, тебе всё равно придется отслеживать всех онлайн игроков. Тут главное сразу отсеивать всех и, возможно, переложить это всё в отдельные потоки (например, обрабатывать с помощью parallelStream — runTaskTimer -> parallelStream -> forEach)
 
Лучше не сделать, тебе всё равно придется отслеживать всех онлайн игроков. Тут главное сразу отсеивать всех и, возможно, переложить это всё в отдельные потоки (например, обрабатывать с помощью parallelStream — runTaskTimer -> parallelStream -> forEach)
И все равно потом обратно складывать в один придется, обойдется дороже чем обычная итерация
 
Не уверен, что данный образец кода самый лучший вариант в плане оптимизации.
Подожду людей опытнее, без обид.
В любом случае, спасибо!)
Да тут то других вариантов особо и нет. Допустим ты будешь отслеживать (даже в идеальном случае одним событием) снятие и одевание шлема и пихать игроков в коллекцию, все равно тебе нужен как минимум один тикер, который будет пробегать по этим игрокам и дамажить. Получается тот же O(N) в худшем случае. Так что пожалуй один шедулер-тикер с перебором всех игроков и проверкой на шлем самый оптимальный вариант решения задачи.

Сервер за тик выполняет в задачи в сотни раз сложнее чем эта мелкая итерация. Так что, подведя итоги и цитируя одного бывалого здесь человека, хочу сказать, что "передоза на этой почве" точно не будет и сервер "от такой экcзекуции" не "двинет кони" 🙂
 
Не уверен, что данный образец кода самый лучший вариант в плане оптимизации.
Подожду людей опытнее, без обид.
В любом случае, спасибо!)
Даже если ты сделаешь 100 таких раннейблов, то тпс сервера не упадет, данный код никак не нагружает сервер
 
Лучше не сделать, тебе всё равно придется отслеживать всех онлайн игроков. Тут главное сразу отсеивать всех и, возможно, переложить это всё в отдельные потоки (например, обрабатывать с помощью parallelStream — runTaskTimer -> parallelStream -> forEach)
Ой ну и жестб посоветовал) на кой черт параллельные стримы тут?

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

Код:
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);;
    }
}
 
Последнее редактирование:
Статус
Закрыто для дальнейших ответов.
Назад
Верх