Циклические методы

Версия Minecraft
1.10.2
4,167
68
693
Всем привет!
Отмечу переход в высшую лигу вопросом :)
Можете подсказать где ошибка?
Пытаюсь удалить озёра, соприкасающиеся с определённым биомом.
Делаю это через IWorldGenerator. Проверяю все соседние блоки, и соседние блоки соседних блоков ))) И так, пока вся вода не исчезнет... По логике должно работать, но по факту убирается только ближайший к биому блок воды...
Что не так?
Код:
Код:
public class RemoveWaterGenerator implements IWorldGenerator {
 
 private IBlockState waterUp = Blocks.WATER.getDefaultState();

 @Override
 public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) {
 if (world.provider.getDimension() == 69) removeLakes(world, chunkX*16, chunkZ*16);
 }
 
 public void removeLakes(World world, int chunkX, int chunkZ) {
 for (int x = 0; x < 16; ++x) {
 for (int z = 0; z < 16; ++z) {
 BlockPos pos = new BlockPos(chunkX + x, 63, chunkZ + z);
 Biome biome = world.getBiomeGenForCoords(pos);
 if (biome instanceof BiomeMistBorder) { 
    if (world.getBlockState(pos.east()) == waterUp) removeWater(world, pos.east());
    if (world.getBlockState(pos.north()) == waterUp) removeWater(world, pos.north());
    if (world.getBlockState(pos.south()) == waterUp) removeWater(world, pos.south());
    if (world.getBlockState(pos.west()) == waterUp) removeWater(world, pos.west());
 }
 }
 }
 }

 private void removeWater(World world, BlockPos pos) {
    world.setBlockToAir(pos);
     if (world.getBlockState(pos.down()) == waterUp) removeWater(world, pos.down());
     if (world.getBlockState(pos.east()) == waterUp) removeWater(world, pos.east());
     if (world.getBlockState(pos.north()) == waterUp) removeWater(world, pos.north());
     if (world.getBlockState(pos.south()) == waterUp) removeWater(world, pos.south());
     if (world.getBlockState(pos.west()) == waterUp) removeWater(world, pos.west());
 }
}

P.S. На счёт зависания данной системы не волнуюсь, океанов в мире нет.
 
Решение
Дак а в таком ключе не пробовал?
Код:
private void removeWater(World world, BlockPos pos) {
    BlockPos newPos;
    if (world.getBlockState(newPos = pos.down()) == waterUp) {
        world.setBlockState(newPos, Blocks.AIR.getDefaultState());
        // здесь можно войти в рекурсию. но можно и циклом сделать.
    }
    ...
}


Возможно, когда удаляешь блок воды, у окружающий водяных блоков не dafault state. Но это предположение, код не могу посмотреть. Еще могу посоветовать на всякий случай сравнивать equals'ом


А нельзя сравнивать просто блоки?
Дак а в таком ключе не пробовал?
Код:
private void removeWater(World world, BlockPos pos) {
    BlockPos newPos;
    if (world.getBlockState(newPos = pos.down()) == waterUp) {
        world.setBlockState(newPos, Blocks.AIR.getDefaultState());
        // здесь можно войти в рекурсию. но можно и циклом сделать.
    }
    ...
}


Возможно, когда удаляешь блок воды, у окружающий водяных блоков не dafault state. Но это предположение, код не могу посмотреть. Еще могу посоветовать на всякий случай сравнивать equals'ом


А нельзя сравнивать просто блоки?
 
Ох... И так пробовал, и блоки сравнивать тоже пробовал...
Чо-та бред какой-то.
Он как будто бы при первом же изменении мира вообще выходит из цикла. Попробовал вместо воздуха заменять на бедрок, так он даже полной границы не формирует... Как-то через блок срабатывает О_о


А кстати!
Слушай! Да ты гений! Ведь вода при изменении окружающих блоков заменяет свой блок со статического на динамический... Столкнулся с этой проблемой, когда прописывал црен в солёном моде...
Это кое что объясняет... Ща попробую.


О да! Всё работает! )))
Проверять нужно так:
Код:
if (world.getBlockState(pos.west()).getBlock() instanceof BlockLiquid)
Всем спасибо за помощь!
Описание причины глюка чуть выше )
 
Всем снова привет!
Раз уж это всё таки моя тема, разрешите немного пофилософствовать. Возможно, знающие люди разъяснят мне ситуацию и помогут решить задачу.

Первым делом, хочу сказать, что переделал таки рекурсию в цикл и игра вылетать перестала ))) Спасибо всем, кто это советовал.

А теперь к сути вопроса (текста будет много, приготовьтесь):
Пытаюсь я понять в какой момент начинают работать генераторы типа IWorldGenerator.
Возьмём тот же самый код, с которого тема и начинается. В нём есть следующие условия:
Код:
if (world.getBlockState(pos.east()).getBlock() instanceof BlockLiquid) ...
if (world.getBlockState(pos.north()).getBlock() instanceof BlockLiquid) ...
if (world.getBlockState(pos.south()).getBlock() instanceof BlockLiquid) ...
if (world.getBlockState(pos.west()).getBlock() instanceof BlockLiquid) ...
Данную проверку я делаю в каждом блоке чанка, а следовательно крайние блоки проверяют и соседние чанки тоже. Однако! Это не заставляет эти чанки грузится и запускать работу своих IWorldGenerator-в. Иначе игра бы надолго зависала ибо биом проверки достаточно обширный.
Исходя из этого я могу сделать два выводы:
  1. Либо данные генераторы начинают срабатывать только, когда соседние чанки уже загружены (то есть радиус загрузки чанков больше, чем радиую работы генераторов).
  2. Либо генераторы заставляют соседний чанк загрузится, но при этом не начинают в нём работать.
Это был пример №1!

Приведу пример №2:
Если нужный мне биом (возле которого я не хотел бы видеть озёр (читай 1-е сообщение в теме)) находит на своей границе озеро, игра немного подвисает, и озеро благополучно осушается целиком! Даже если часть этого озера находится в ещё незагруженной области...
Из этого я делаю ещё один вывод:
  1. Замена блоков в чанке заставляет грузится и соседние чанки тоже. Заставляет ли это работать в этих чанках генераторы? ХЗ...
Пример №3 и суть моей проблемы:
Допустим, что озеро у меня достаточно большое. Часть его уже загрузилась. Я уже успел насыпать под ним песочек, посадил камыши, заселил лягушек... В общем, оформил берег как мне надо.
И тут вдруг! Дальняя часть озера загружает чанк, в котором находится мой биом. В итоге озеро осушается, камыши остаются О_о (это пока только предположение, но такой исход вполне может быть).

Ну а теперь вопрос: В какой же момент начинают работать IWorldGenerator-ы и как можно заставить озёра грузится сразу целиком, чтобы заранее выяснить, нет ли рядом неподходящего биома?

Всем спасибо за внимание )))

Сразу отвечу тем, кто скажет, что такие проблемы нужно решать на этапе распределения биомов.

Увы нет! Ландшафт везде разный. Заполнение водоёмов сами знаете как происходит (от определённой высоты и ниже)... Так или иначе, на границе моего биома будут оставаться неаккуратные участки висящей в воздухе воды.
 
Назад
Сверху