Помогите Получение чанка на границе

  • Автор темы Автор темы SergK35
  • Дата начала Дата начала

SergK35

Активный участник
Пользователь
Баллы
76
Имя в Minecraft
Sergk35
Доброго времени суток. Подскажите пожалуйста, как можно проверить, чанк, на котором находится игрок, содержит границу мира или нет? (worldborder)

P.S Плагин с worldborder'ом связал
 
Пишу плагин, получаю чанк, на котором стоит игрок, надо проверить, есть ли граница из worldborder'а в этом чанке
Примерно так, наверно.
Код:
public static boolean containsBorder(Chunk chunk) {
    BorderData border = Config.Border(chunk.getWorld().getName());
    if (border == null) return false;
    Block block = chunk.getBlock(0, 0, 0);
    int x = block.getX(); int z = block.getZ();
    boolean round = Config.ShapeRound();
    return border.insideBorder(x, z, round) ||
            border.insideBorder(x + 15, z, round) ||
            border.insideBorder(x + 15, z + 15, round) ||
            border.insideBorder(x, z + 15, round);
}
Config - класс из WorldBorder'а
 
Примерно так, наверно.
Код:
public static boolean containsBorder(Chunk chunk) {
    BorderData border = Config.Border(chunk.getWorld().getName());
    if (border == null) return false;
    Block block = chunk.getBlock(0, 0, 0);
    int x = block.getX(); int z = block.getZ();
    boolean round = Config.ShapeRound();
    return border.insideBorder(x, z, round) ||
            border.insideBorder(x + 15, z, round) ||
            border.insideBorder(x + 15, z + 15, round) ||
            border.insideBorder(x, z + 15, round);
}
Config - класс из WorldBorder'а
Странно, но любой чанк, который я отправляю, является границей
 
Странно, но любой чанк, который я отправляю, является границей
А, ну да. Borderdata#insideBorder проверяет, находится ли координата в пределах границы. Попробуй так.
Код:
    return border.insideBorder(x, z, round) &&
            border.insideBorder(x + 15, z, round) &&
            border.insideBorder(x + 15, z + 15, round) &&
            border.insideBorder(x, z + 15, round);
 
А, ну да. Borderdata#insideBorder проверяет, находится ли координата в пределах границы. Попробуй так.
Код:
    return border.insideBorder(x, z, round) &&
            border.insideBorder(x + 15, z, round) &&
            border.insideBorder(x + 15, z + 15, round) &&
            border.insideBorder(x, z + 15, round);
Так будет возвращать true для всех чанков, которые находятся внутри (а не только на границе)
 
Так будет возвращать true для всех чанков, которые находятся внутри (а не только на границе)
И то верно. Тогда, два счетчика, которые будут проверять наличие хотя бы одного угла в пределах границы и одного за ней?
 
Да этого достаточно будет, чтоб узнать что игрок за границей.
Причём тут игрок, если речь о чанке?
Чанк - это 4 точки на плоскости и 8 точек в пространстве.
И то верно. Тогда, два счетчика, которые будут проверять наличие хотя бы одного угла в пределах границы и одного за ней?
Так?
PHP:
public static boolean isChunkOnBorder(Chunk chunk) {
    BorderData border = Config.Border(chunk.getWorld().getName());
    boolean round = Config.ShapeRound();
    return isAreaSplitsChunk(chunk, (x, z) -> border.insideBorder(point.getKey(), point.getValue(), round));
}

public static boolean isAreaSplitsChunk(Chunk chunk, BiPredicate<Integer, Integer> isPointInArea) {
    int minX = chunk.getX() << 4;
    int minZ = chunk.getZ() << 4;
    int maxX = minX + 15;
    int maxZ = minZ + 15;
    Collection<Pair<Integer, Integer>> points = new ArrayList<>();
    points.add(new Pair<>(minX, minZ));
    points.add(new Pair<>(minX, maxZ));
    points.add(new Pair<>(maxX, minZ));
    points.add(new Pair<>(maxX, maxZ));
    boolean inside = false;
    boolean outside = false;
    for (Pair<Integer, Integer> point : points) {
        if (isPointInArea.test(point.getKey(), point.getValue())) inside = true;
        else outside = true;
    }
    return inside && outside;
}
 
Последнее редактирование:
Так?
PHP:
public static boolean isChunkOnBorder(Chunk chunk) {
    BorderData border = Config.Border(chunk.getWorld().getName());
    boolean round = Config.ShapeRound();
    return isAreaSplitsChunk(chunk, (x, z) -> border.insideBorder(point.getKey(), point.getValue(), round));
}

public static boolean isAreaSplitsChunk(Chunk chunk, BiPredicate<Integer, Integer> isPointInArea) {
    int minX = chunk.getX() << 4;
    int minZ = chunk.getZ() << 4;
    int maxX = minX + 15;
    int maxZ = minZ + 15;
    Collection<Pair<Integer, Integer>> points = new ArrayList<>();
    points.add(new Pair<>(minX, minZ));
    points.add(new Pair<>(minX, maxZ));
    points.add(new Pair<>(maxX, minZ));
    points.add(new Pair<>(maxX, maxZ));
    boolean inside = false;
    boolean outside = false;
    for (Pair<Integer, Integer> point : points) {
        if (isPointInArea.test(point.getKey(), point.getValue())) inside = true;
        else outside = true;
    }
    return inside && outside;
}
Угу. Только, на мой взгляд такой вариант выглядит несколько излишне усложненным. Впрочем, не мне судить.
 
Угу. Только, на мой взгляд такой вариант выглядит несколько излишне усложненным. Впрочем, не мне судить.
Окей.
PHP:
    public static boolean containsBorder(Chunk chunk) {
        BorderData border = Config.Border(chunk.getWorld().getName());
        boolean round = Config.ShapeRound();
        int minX = chunk.getX() << 4;
        int minZ = chunk.getZ() << 4;
        int maxX = minX + 15;
        int maxZ = minZ + 15;
        int[] pointsXZ = new int[]{
                minX, minZ,
                minX, maxZ,
                maxX, minZ,
                maxX, maxZ
        };
        boolean inside = false;
        boolean outside = false;
        for (int i = 0; i < pointsXZ.length; i++) {
            if (border.insideBorder(pointsXZ[i++], pointsXZ[i], round)) inside = true;
            else outside = true;
        }
        return inside && outside;
    }
PHP:
public static boolean containsBorder(Chunk chunk) {
    BorderData border = Config.Border(chunk.getWorld().getName());
    boolean round = Config.ShapeRound();
    return is2DAreaSplitPoints((x, z) -> border.insideBorder(x, z, round), getChunk2DPoints(chunk));
}

private static int[] getChunk2DPoints(Chunk chunk) {
    int minX = chunk.getX() << 4;
    int minZ = chunk.getZ() << 4;
    int maxX = minX + 15;
    int maxZ = minZ + 15;
    return new int[]{
            minX, minZ,
            minX, maxZ,
            maxX, minZ,
            maxX, maxZ
    };
}

private static Location[] getChunk3DPoints(Chunk chunk) {
    return getChunk3DPoints(chunk, 0, 255);
}

private static Location[] getChunk3DPoints(Chunk chunk, int minY, int maxY) {
    World world = chunk.getWorld();
    int minX = chunk.getX() << 4;
    int minZ = chunk.getZ() << 4;
    int maxX = minX + 15;
    int maxZ = minZ + 15;
    return new Location[]{
            new Location(world, minX, minY, minZ),
            new Location(world, minX, minY, maxZ),
            new Location(world, maxX, minY, minZ),
            new Location(world, maxX, minY, maxZ),
            new Location(world, minX, maxY, minZ),
            new Location(world, minX, maxY, maxZ),
            new Location(world, maxX, maxY, minZ),
            new Location(world, maxX, maxY, maxZ)
    };
}

public static boolean is2DAreaSplitPoints(BiPredicate<Integer, Integer> isPointInArea, int... pointsXZ) {
    boolean inside = false;
    boolean outside = false;
    for (int i = 0; i < pointsXZ.length; i++) {
        if (isPointInArea.test(pointsXZ[i++], pointsXZ[i])) inside = true;
        else outside = true;
        if (inside && outside) return true;
    }
    return false;
}

public static boolean is3DAreaSplitPoints(Predicate<Location> isPointInArea, Location... points) {
    boolean inside = false;
    boolean outside = false;
    for (Location point : points.) {
        if (isPointInArea.test(point)) inside = true;
        else outside = true;
        if (inside && outside) return true;
    }
    return false;
}
😁
 
Последнее редактирование:
Окей.
PHP:
    public static boolean containsBorder(Chunk chunk) {
        BorderData border = Config.Border(chunk.getWorld().getName());
        boolean round = Config.ShapeRound();
        int minX = chunk.getX() << 4;
        int minZ = chunk.getZ() << 4;
        int maxX = minX + 15;
        int maxZ = minZ + 15;
        int[] pointsXZ = new int[]{
                minX, minZ,
                minX, maxZ,
                maxX, minZ,
                maxX, maxZ
        };
        boolean inside = false;
        boolean outside = false;
        for (int i = 0; i < pointsXZ.length; i++) {
            if (border.insideBorder(pointsXZ[i++], pointsXZ[i], round)) inside = true;
            else outside = true;
        }
        return inside && outside;
    }
PHP:
public static boolean containsBorder(Chunk chunk) {
    BorderData border = Config.Border(chunk.getWorld().getName());
    boolean round = Config.ShapeRound();
    return is2DAreaSplitPoints((x, z) -> border.insideBorder(x, z, round), getChunk2DPoints(chunk));
}

private static int[] getChunk2DPoints(Chunk chunk) {
    int minX = chunk.getX() << 4;
    int minZ = chunk.getZ() << 4;
    int maxX = minX + 15;
    int maxZ = minZ + 15;
    return new int[]{
            minX, minZ,
            minX, maxZ,
            maxX, minZ,
            maxX, maxZ
    };
}

private static Location[] getChunk3DPoints(Chunk chunk) {
    return getChunk3DPoints(chunk, 0, 255);
}

private static Location[] getChunk3DPoints(Chunk chunk, int minY, int maxY) {
    World world = chunk.getWorld();
    int minX = chunk.getX() << 4;
    int minZ = chunk.getZ() << 4;
    int maxX = minX + 15;
    int maxZ = minZ + 15;
    return new Location[]{
            new Location(world, minX, minY, minZ),
            new Location(world, minX, minY, maxZ),
            new Location(world, maxX, minY, minZ),
            new Location(world, maxX, minY, maxZ),
            new Location(world, minX, maxY, minZ),
            new Location(world, minX, maxY, maxZ),
            new Location(world, maxX, maxY, minZ),
            new Location(world, maxX, maxY, maxZ)
    };
}

public static boolean is2DAreaSplitPoints(BiPredicate<Integer, Integer> isPointInArea, int... pointsXZ) {
    boolean inside = false;
    boolean outside = false;
    for (int i = 0; i < pointsXZ.length; i++) {
        if (isPointInArea.test(pointsXZ[i++], pointsXZ[i])) inside = true;
        else outside = true;
        if (inside && outside) return true;
    }
    return false;
}

public static boolean is3DAreaSplitPoints(Predicate<Location> isPointInArea, Location... points) {
    boolean inside = false;
    boolean outside = false;
    for (Location point : points.) {
        if (isPointInArea.test(point)) inside = true;
        else outside = true;
        if (inside && outside) return true;
    }
    return false;
}
😁
Спасибо. Отправил несколько чанков на проверку, вроде все работает.

Можешь пожалуйста объяснить вот это действие
Код:
int minX = chunk.getX() << 4;

Понимаю, что идет сдвиг битов, но не совсем понимаю для чего
 
Можешь пожалуйста объяснить вот это действие
Код:
int minX = chunk.getX() << 4;

Понимаю, что идет сдвиг битов, но не совсем понимаю для чего
Получает координаты в мире по координатам чанка.
chunk.getBlock(x, y, z) работает по тому же принципу.
У меня просто уже привычка не использовать этот метод по некоторым причинам
 
Спасибо. Отправил несколько чанков на проверку, вроде все работает.

Можешь пожалуйста объяснить вот это действие
Код:
int minX = chunk.getX() << 4;

Понимаю, что идет сдвиг битов, но не совсем понимаю для чего
Простым языком - считай, что умножение на 16(это 2 в степени 4). В данном случае нужно потому что чанки - это участки 16 на 16 (на 256) блоков, и chunk.getX() и chunk.getZ() вернёт тебе координату чанка, а не крайнего блока чанка.
Более сложным - ты и сам ответил, а дальше достаточно посмотреть на двоичный код/двоичную систему счисления. Загляни сюда для примера, например.
 
Простым языком - считай, что умножение на 16(это 2 в степени 4). В данном случае нужно потому что чанки - это участки 16 на 16 (на 256) блоков, и chunk.getX() и chunk.getZ() вернёт тебе координату чанка, а не крайнего блока чанка.
Более сложным - ты и сам ответил, а дальше достаточно посмотреть на двоичный код/двоичную систему счисления. Загляни сюда для примера, например.
Спасибо
 
Назад
Верх