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

Восстановление блоков

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

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

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

    Баллы:
    96
    Есть задача
    BlockBreakEvent -> event#getBlock() -> block.setType(Material.BEDROCK) -> after N seconds block.setType(material)

    Если сломался условный блок, то превратить его в бедрок и после N секунд восстановить в первоначальный тип.


    Handler: https://pastebin.com/hPLtXMhb
    RestoreManager -> https://pastebin.com/hefH8qWF

    RestoreManager тикает каждые 20 тиков.

    Проблема в том, что если я добавляю задачу на возобновление блока в методе, куда пришёл эвент, то блок никогда не превратится в бедрок.
    Ибо сразу после эвента он становится воздухом. Понятное дело, что нужно выполнить setType(bedrock) спустя тик(после эвента).

    Смысл RestoreManager в том, что восстанавливать все блоки в одном потоке,а не делать для каждого runTaskLater.
    Но если решать проблему с бедроком, то получается половина задачи всё равно будет решаться runTask, что как по мне не очень.

    Может подскажите решение получше ?
     
  2. HunterGaming

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

    Баллы:
    96
    Имя в Minecraft:
    sqdFendy
    Map<Material, Long> materialDelays при каждом тике
    materialDelay = ...getOrDefault{Material.BEDROCK, 0};
    ...put{Material.BEDROCK, materialDelay++};
     
  3. alexandrage

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

    Баллы:
    173
    Код:
    package Example.task;
    
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.block.data.BlockData;
    
    public class Data {
        private BlockData data;
        private Location loc;
        private boolean place;
        private long time;
    
        public Data(Block block, long time) {
            this.data = block.getBlockData();
            this.loc = block.getLocation();
            this.time = time;
        }
    
        public boolean tick() {
            if (!this.place) {
                this.loc.getWorld().getBlockAt(this.loc).setType(Material.BEDROCK);
                this.place = true;
            }
            if (this.time == 0) {
                this.loc.getWorld().getBlockAt(this.loc).setBlockData(this.data);
                return true;
            }
            this.time--;
            return false;
        }
    
        public boolean stop() {
            this.loc.getWorld().getBlockAt(this.loc).setBlockData(this.data);
            return true;
        }
    }
    Код:
    package Example.task;
    
    import java.util.ArrayList;
    import java.util.List;
    import org.bukkit.block.Block;
    import org.bukkit.plugin.Plugin;
    import org.bukkit.scheduler.BukkitRunnable;
    
    public class SchedulerBlock extends BukkitRunnable {
        private List<Data> blocks = new ArrayList<Data>();
    
        public SchedulerBlock(Plugin plugin) {
            this.runTaskTimer(plugin, 1, 1);
        }
    
        @Override
        public void run() {
            this.blocks.removeIf(data -> data.tick());
        }
    
        public void put(Block block, long time) {
            this.blocks.add(new Data(block, time));
        }
    
        @Override
        public void cancel() {
            this.cancel();
            this.blocks.removeIf(data -> data.stop());
        }
    }
     
Статус темы:
Закрыта.

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