Войти или зарегистрироваться

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

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();
    }
}

Чанки отчищаются, но криво. Ниже примеры.

Не верное наложение снега/растительности:
7f41e9d86b79.png


До регенерации:
75353c5f107a.png


После под другим углом:
bac4fff87979.png


Что я делаю не так?
 
Это ядро так само по себе ведёт, если на сервере ещё присутсвуют моды, то можно сразу забывать о бесшовной регенерации чанков.
 
Последнее редактирование:
Это ядро так само по себе ведёт, если на сервере ещё присутсвуют мобы, то можно сразу забывать о бесшовной регенерации чанков.
Чем мобы могут мешать бесшовной регенерации?
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;
    }

Хотя нет, вру. WE так же не справляется с бесшовной регенерацией.
 
Извини, опечатался. моДы.

Регенерация в WE точно так же происходит.
 
Регенерация в WE точно так же происходит.
Верю, метод команды //regen выше.
Тем не менее, генерация происходит более гладко, да и с учетом структур, чем если бы я вызвал world.regenerateChunk(...). Что странно, нужно будет поковыряться.
 
А что ковыряться? Если несколько чанков выгрузить и отгенерировать, то между ними "шва" быть не должно, поэтому и кажется, что //regen работает лучше, у него что-то такое там и происходит.
 
Это ядро так само по себе ведёт, если на сервере ещё присутсвуют моды, то можно сразу забывать о бесшовной регенерации чанков.
А почему так, майн же по сиду всегда одинаковые чанки генерит? Это же по идее обычный генератор рандома.
 
А почему так, майн же по сиду всегда одинаковые чанки генерит? Это же по идее обычный генератор рандома.

Изначально сид так и работал, ктобы его не ввёл - увсех одинаковые миры возникают. А после этого приходят в майнкрафт всякие недокодеры, чувствую, что многие вещи из модов генерируются на основании своих собственных случайных величин и никак не отталкиваются от сида мира.
 
Если несколько чанков выгрузить и отгенерировать, то между ними "шва" быть не должно, поэтому и кажется, что //regen работает лучше, у него что-то такое там и происходит.
Метод WE я уже кидал выше, никаких доп. манипуляций там не производится. В моем случае чанки добавляются в очередь хаотично, скорее всего где-то в самом Minecraft-сервере алгоритм регенерации рассчитан на чанки, расположенные рядом друг с другом.
У кого-нибудь остались сырцы CraftBukkit'а 1.6.4?
Судя по всему оно:
Код:
  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;
  }
Попробую удалять чанки, дабы генератор мира работал с ними сам.
 
Так и должно быть. Единственное, что корректно регенерируется - это ландшафт. Деревья и структуры (деревни, шахты и др.) размещаются случайным образом.
 
Так и должно быть. Единственное, что корректно регенерируется - это ландшафт. Деревья и структуры (деревни, шахты и др.) размещаются случайным образом.
Не знаю, не знаю, помню использовал сид на котором играли одни ЛП'шники и у меня все было также деревня, дома в деревне и даже вещи в кузнице.
 
Не знаю, не знаю, помню использовал сид на котором играли одни ЛП'шники и у меня все было также деревня, дома в деревне и даже вещи в кузнице.
Идентичность карты примерно 90%
 
Идентичность карты примерно 90%
Идентичность карты без модов - 100%.
А сама трабла в том что надо отгружать чанки надо сначала все которые хочешь регенерировать, причём котёл не отгрузит их сразу, так что придётся ждать, и уже после этого их только регенить. Тогда более-менее работает, не считая некоторой уёюищности модов.
 
Выгрузка чанков не даёт полной бесшовной регенерации. Всё это будет видно по деревьям.
 
А что если выпилить неугодные чанки, дабы те сгенерировались автоматически по приближению к ним игрока? Тут сработает мировой генератор и как минимум близлежащие чанки будут бесшовны, по идее.
 
Назад
Верх