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

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

Discussion in 'Разработка плагинов для новичков' started by sashabelii, Oct 19, 2014.

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

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

    Trophy Points:
    123
    Имя в Minecraft:
    sashabelii
    Доброго времени суток.

    Просчитываю необходимые для регенерации чанки в отдельном потоке, из него же регистрирую задание:
    Code:
    Bukkit.getServer().getScheduler().runTask(WorldCleaner.plugin, new ChunkWorker(world, chunks));
    Само задание:
    Code:
    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 Старожил Пользователь

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

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

    Trophy Points:
    123
    Имя в Minecraft:
    sashabelii
    Чем мобы могут мешать бесшовной регенерации?
    WorldEdit каким-то образом таки справляется, хотя и использует ванильный метод ванильного класса World.
    Code:
        @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 для регенерации выделенной территории:
    Code:
        /**
         * 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 Старожил Пользователь

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

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

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

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

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

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

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

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

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

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

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

    Trophy Points:
    123
    Имя в Minecraft:
    sashabelii
    Метод WE я уже кидал выше, никаких доп. манипуляций там не производится. В моем случае чанки добавляются в очередь хаотично, скорее всего где-то в самом Minecraft-сервере алгоритм регенерации рассчитан на чанки, расположенные рядом друг с другом.
    У кого-нибудь остались сырцы CraftBukkit'а 1.6.4?[DOUBLEPOST=1413746936,1413745986][/DOUBLEPOST]Судя по всему оно:
    Code:
      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 Старожил Пользователь Заблокирован

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

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

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

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

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

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

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

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

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

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

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

Share This Page