Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Скрыть объявление

Помогите Почанковая регенерация мира

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

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

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

    Баллы:
    123
    Имя в Minecraft:
    sashabelii
    Доброго времени суток.

    Просчитываю необходимые для регенерации чанки в отдельном потоке, из него же регистрирую задание:
    Код:
    Bukkit.getServer().getScheduler().runTask(WorldCleaner.plugin, new ChunkWorker(world, chunks));
    Само задание:
    Код:
    public class ChunkWorker implements Runnable {
    
        private Queue<Point> chunks;
        private World world;
    
        public ChunkWorker(World world, Queue<Point> chunks) {
            this.world = world;
            this.chunks = chunks;
        }
    
        @Override
        public void run() {
            while(!chunks.isEmpty()) {
                Point chunkPoint = chunks.remove();
                Chunk chunk = world.getChunkAt((int) chunkPoint.getX(), (int) chunkPoint.getY());
    
                world.regenerateChunk((int) chunk.getX(), (int) chunk.getZ());
              
                WorldCleaner.log.info("Chunks left: " + chunks.size() + ", current chunk: " + world.getChunkAt((int) chunk.getX(), (int) chunk.getZ()));
                //world.spawnArrow(new Location(world, chunk.getX(), 100, chunk.getY()), new Vector(chunk.getX(), 100, chunk.getY()), 20, 20);
            }
            WorldCleaner.regeneratorsMng.continueRegenerating();
        }
    }
    
    Чанки отчищаются, но криво. Ниже примеры.

    Не верное наложение снега/растительности:
    [​IMG]

    До регенерации:
    [​IMG]

    После под другим углом:
    [​IMG]

    Что я делаю не так?
     
  2. Хостинг MineCraft
    <
  3. ptnk

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

    Баллы:
    173
    Это ядро так само по себе ведёт, если на сервере ещё присутсвуют моды, то можно сразу забывать о бесшовной регенерации чанков.
     
    Последнее редактирование: 19 окт 2014
  4. Автор темы
    sashabelii

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

    Баллы:
    123
    Имя в Minecraft:
    sashabelii
    Чем мобы могут мешать бесшовной регенерации?
    WorldEdit каким-то образом таки справляется, хотя и использует ванильный метод ванильного класса World.
    Код:
        @Command(
            aliases = { "/regen" },
            usage = "",
            desc = "Regenerates the contents of the selection",
            help =
                "Regenerates the contents of the current selection.\n" +
                "This command might affect things outside the selection,\n" +
                "if they are within the same chunk.",
            min = 0,
            max = 0
        )
        @CommandPermissions("worldedit.regen")
        @Logging(REGION)
        public void regenerateChunk(CommandContext args, LocalSession session, LocalPlayer player,
                EditSession editSession) throws WorldEditException {
    
            Region region = session.getSelection(player.getWorld());
            Mask mask = session.getMask();
            session.setMask(null);
            player.getWorld().regenerate(region, editSession);
            session.setMask(mask);
            player.print("Region regenerated.");
        }
    
    Метод класса BukkitWorld который судя по всему и используется WE для регенерации выделенной территории:
    Код:
        /**
         * Regenerate an area.
         *
         * @param region
         * @param editSession
         * @return
         */
        @Override
        public boolean regenerate(Region region, EditSession editSession) {
            BaseBlock[] history = new BaseBlock[16 * 16 * (getMaxY() + 1)];
    
            for (Vector2D chunk : region.getChunks()) {
                Vector min = new Vector(chunk.getBlockX() * 16, 0, chunk.getBlockZ() * 16);
    
                // First save all the blocks inside
                for (int x = 0; x < 16; ++x) {
                    for (int y = 0; y < (getMaxY() + 1); ++y) {
                        for (int z = 0; z < 16; ++z) {
                            Vector pt = min.add(x, y, z);
                            int index = y * 16 * 16 + z * 16 + x;
                            history[index] = editSession.getBlock(pt);
                        }
                    }
                }
    
                try {
                    world.regenerateChunk(chunk.getBlockX(), chunk.getBlockZ());
                } catch (Throwable t) {
                    t.printStackTrace();
                }
    
                // Then restore
                for (int x = 0; x < 16; ++x) {
                    for (int y = 0; y < (getMaxY() + 1); ++y) {
                        for (int z = 0; z < 16; ++z) {
                            Vector pt = min.add(x, y, z);
                            int index = y * 16 * 16 + z * 16 + x;
    
                            // We have to restore the block if it was outside
                            if (!region.contains(pt)) {
                                editSession.smartSetBlock(pt, history[index]);
                            } else { // Otherwise fool with history
                                editSession.rememberChange(pt, history[index],
                                        editSession.rawGetBlock(pt));
                            }
                        }
                    }
                }
            }
    
            return true;
        }
    
    [DOUBLEPOST=1413712324,1413708730][/DOUBLEPOST]Хотя нет, вру. WE так же не справляется с бесшовной регенерацией.
     
  5. ptnk

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

    Баллы:
    173
    Извини, опечатался. моДы.

    Регенерация в WE точно так же происходит.
     
  6. Автор темы
    sashabelii

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

    Баллы:
    123
    Имя в Minecraft:
    sashabelii
    Верю, метод команды //regen выше.
    Тем не менее, генерация происходит более гладко, да и с учетом структур, чем если бы я вызвал world.regenerateChunk(...). Что странно, нужно будет поковыряться.
     
  7. ptnk

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

    Баллы:
    173
    А что ковыряться? Если несколько чанков выгрузить и отгенерировать, то между ними "шва" быть не должно, поэтому и кажется, что //regen работает лучше, у него что-то такое там и происходит.
     
  8. CraftCoder

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

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    А почему так, майн же по сиду всегда одинаковые чанки генерит? Это же по идее обычный генератор рандома.
     
  9. ptnk

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

    Баллы:
    173
    Изначально сид так и работал, ктобы его не ввёл - увсех одинаковые миры возникают. А после этого приходят в майнкрафт всякие недокодеры, чувствую, что многие вещи из модов генерируются на основании своих собственных случайных величин и никак не отталкиваются от сида мира.
     
  10. Автор темы
    sashabelii

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

    Баллы:
    123
    Имя в Minecraft:
    sashabelii
    Метод WE я уже кидал выше, никаких доп. манипуляций там не производится. В моем случае чанки добавляются в очередь хаотично, скорее всего где-то в самом Minecraft-сервере алгоритм регенерации рассчитан на чанки, расположенные рядом друг с другом.
    У кого-нибудь остались сырцы CraftBukkit'а 1.6.4?[DOUBLEPOST=1413746936,1413745986][/DOUBLEPOST]Судя по всему оно:
    Код:
      public boolean regenerateChunk(int x, int z)
      {
        unloadChunk(x, z, false, false);
       
        this.world.chunkProviderServer.unloadQueue.remove(x, z);
       
        net.minecraft.server.v1_6_R3.Chunk chunk = null;
        if (this.world.chunkProviderServer.chunkProvider == null) {
          chunk = this.world.chunkProviderServer.emptyChunk;
        } else {
          chunk = this.world.chunkProviderServer.chunkProvider.getOrCreateChunk(x, z);
        }
        chunkLoadPostProcess(chunk, x, z);
       
        refreshChunk(x, z);
       
        return chunk != null;
      }
    
    Попробую удалять чанки, дабы генератор мира работал с ними сам.
     
  11. saharin94

    saharin94 Старожил Пользователь Заблокирован

    Баллы:
    173
    Skype:
    RikkiLooh
    Имя в Minecraft:
    RubukkitDniwe
    Так и должно быть. Единственное, что корректно регенерируется - это ландшафт. Деревья и структуры (деревни, шахты и др.) размещаются случайным образом.
     
  12. CraftCoder

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

    Баллы:
    108
    Имя в Minecraft:
    CraftCoderr
    Не знаю, не знаю, помню использовал сид на котором играли одни ЛП'шники и у меня все было также деревня, дома в деревне и даже вещи в кузнице.
     
  13. saharin94

    saharin94 Старожил Пользователь Заблокирован

    Баллы:
    173
    Skype:
    RikkiLooh
    Имя в Minecraft:
    RubukkitDniwe
    Идентичность карты примерно 90%
     
  14. Shevchik

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

    Баллы:
    173
    Имя в Minecraft:
    _Shevchik_
    Идентичность карты без модов - 100%.
    А сама трабла в том что надо отгружать чанки надо сначала все которые хочешь регенерировать, причём котёл не отгрузит их сразу, так что придётся ждать, и уже после этого их только регенить. Тогда более-менее работает, не считая некоторой уёюищности модов.
     
  15. ptnk

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

    Баллы:
    173
    Выгрузка чанков не даёт полной бесшовной регенерации. Всё это будет видно по деревьям.
     
  16. Автор темы
    sashabelii

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

    Баллы:
    123
    Имя в Minecraft:
    sashabelii
    А что если выпилить неугодные чанки, дабы те сгенерировались автоматически по приближению к ним игрока? Тут сработает мировой генератор и как минимум близлежащие чанки будут бесшовны, по идее.
     

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