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

Помогите Шкала жажды и кислорода

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

  1. Автор темы
    fx8320e

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

    Баллы:
    66
    Приветствую! Взялся за написание плагина, привносящего в игру систему жажды. Тема избитая, но в моих планах использовать для отображения уровня жажды стандартную шкалу воздуха, а кислород же переложить на bossbar. Собственно, вопросы:
    1) Как сделать шкалу воздуха видимой не только в воде?
    2) Как убавлять значение шкалы с течением времени?
    3) Как убрать механику убавление шкалы воздуха в воде?*
    * Пока есть такой костыльный вариант, однако, он работает только прим перемещении игрока. То есть, если игрок стоит на месте, кислород перестает восполняться.
    PHP:
     @EventHandler(priority EventPriority.LOWESTignoreCancelled false)
            public 
    void waterair(PlayerMoveEvent p) {
             
            
    Player e p.getPlayer();
            
    int x = (int) e.getLocation().getX();
            
    int y = (int) e.getLocation().getY();
            
    int z = (int) e.getLocation().getZ(); 
           
            if (
    e.getWorld().getBlockAt(xy+1z).getType().equals(Material.WATER) && e.getRemainingAir() < 300) {
                
    int a e.getRemainingAir();
                
    e.setRemainingAir(a+20);       
        }
        } 
    Если знаете решение, подскажите, пожалуйста. Заранее благодарю!
     
  2. imDaniX

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

    Баллы:
    96
    Имя в Minecraft:
    imDaniX
    Скорее всего достаточно держать уровень воздуха на player.getMaximumAir() - 1 через EntityAirChangeEvent, но неуверен, пытается ли клиент сам восстановить воздух. Если да - возможно, стоит установить максимальное количество воздуха на какое-то большое значение и разницу оставить побольше, если воздухом все равно собираешься управлять сам.
    Опять же EntityAirChangeEvent.
     
  3. Автор темы
    fx8320e

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

    Баллы:
    66
    Спасибо! Но не могли бы вы подробней расписать. Не вижу никаких функций EntityAirChangeEven, которые могли бы мне помочь.
     
  4. imDaniX

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

    Баллы:
    96
    Имя в Minecraft:
    imDaniX
    Достаточно слушать событие и исправлять его поведение как то требуется. Событие в любом случае будет производиться, если игрок в воде, или же вышел на воздух. Если player.getRemainAir() < event.getAmount(), значит игрок вышел на воздух; если наоборот, значит он в воде. В зависимости от ситуации нужно устанавливать event.setAmount(int). Также стоит запустить шедулер, который будет раз в несколько секунд проверять, чтоб значение player.getRemainAir() всегда было меньше player.getMaximumAir() - на случай первого входа, смерти, или чего непредвиденного.
     
  5. Автор темы
    fx8320e

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

    Баллы:
    66
    Как мне кажется для чистоты измерения следует проверять среду в которой находится игрок не расходом воздуха (ведь он будет убавляться и на суше, если мы переделаем его под жажду), а проверять блок, в котором находится голова игрока, и если это вода, то что-то делать. Выше я привел вариант, но он работает исключительно при движении игрока, в чем собственно и проблема. Потому, если вас не затруднит, расскажите в чем проблема данного подхода. И еще раз, как сделать шкалу воздуха видимой не только в воде?
     
  6. Автор темы
    fx8320e

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

    Баллы:
    66
    c while вместо if в этой строчке if (e.getWorld().getBlockAt(x, y+1, z).getType().equals(Material.WATER) && e.getRemainingAir() < 300) происходит то же самое...
     
  7. imDaniX

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

    Баллы:
    96
    Имя в Minecraft:
    imDaniX
    Если хочется получить полный контроль - тогда событие следует отменять в принципе - таким боком изменяться оно без твоего воздействия не будет.
    Далее через шедулер проверять проверять, находится ли голова в воде. Опять же, чтобы пузырьки не пропадали, следует держать уровень кислорода несколько меньше, чем максимальное количество.
    Код:
    private static final int TICKS_PER_CHECK = 5; // Как часто проверять игроков?
    
    Bukkit.getScheduler().runTaskTimer(plugin, () -> {
        for (Player player : Bukkit.getOnlinePlayers()) {
            Material type = player.getEyeLocation().getBlock().getType();
            if (type == Material.WATER) {
                int newAir = Math.min(player.getRemainingAir() + TICKS_PER_CHECK, player.getMaximumAir() - 80); // Если игрок в воде, добавить TICKS_PER_CHECK воздуха, вплоть до (максимум_игрока - 80)
                player.setRemainingAir(newAir);
            } else if (player.getRemainingAir() > 0) {
                int newAir = Math.max(player.getRemainingAir() - TICKS_PER_CHECK, 0); // Если игрок не в воде, забрать TICKS_PER_CHECK воздуха, вплоть до 0
                player.setRemainingAir(newAir);
            }
        }
    }, TICKS_PER_CHECK, TICKS_PER_CHECK);
     

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