获得玩家正在寻找块的一面| bukkit

时间:2015-07-26 17:54:39

标签: bukkit

可以获得玩家实际看到的阻止。

p.getTargetBlock()

但是有没有办法让玩家看到的方块? ( 区块的顶部,下部,北部,南部,东部,西部 侧) 我还没有找到能够做到这一点的功能。它能给我一些东西,我可以用来找到这一面吗?

2 个答案:

答案 0 :(得分:3)

我已经实现了一个实用程序方法来实现这一点,因为玩家正在定位的Block为AxisAlignedBB(NMS)。可以通过问题中提到的Player#getTargetBlock()或自定义光线投射算法获取此块。

public static BlockFace blockFaceCollide(Vector startLocation, Vector direction, AxisAlignedBB objectBoundry){

    double constant = Double.MAX_VALUE;

    BlockFace blockFace = null;

    double directionX = direction.getX();
    double directionY = direction.getY();
    double directionZ = direction.getZ();


    if(directionY > 0){
        double b = objectBoundry.b - startLocation.getY();
        double tempConstant = b / directionY;
        if(tempConstant > 0 && tempConstant < constant){
            double xAtCollide = tempConstant * directionX + startLocation.getX();
            double zAtCollide = tempConstant * directionZ + startLocation.getZ();
            if (between(xAtCollide, objectBoundry.a, objectBoundry.d, 0)
                    && between(zAtCollide, objectBoundry.c, objectBoundry.f, 0)) {
                constant = tempConstant;
                blockFace = BlockFace.DOWN;
            }
        }
    }
    else {
        double e = objectBoundry.e - startLocation.getY();
        double tempConstant = e / directionY;
        if (tempConstant > 0 && tempConstant < constant) {
            double xAtCollide = tempConstant * directionX + startLocation.getX();
            double zAtCollide = tempConstant * directionZ + startLocation.getZ();
            if (between(xAtCollide, objectBoundry.a, objectBoundry.d, 0)
                    && between(zAtCollide, objectBoundry.c, objectBoundry.f, 0)) {
                constant = tempConstant;
                blockFace = BlockFace.UP;
            }
        }
    }

    if(directionX < 0) {
        double d = objectBoundry.d - startLocation.getX();
        double tempConstant = d / directionX;
        if (tempConstant > 0 && tempConstant < constant) {
            double yAtCollide = tempConstant * directionY + startLocation.getY();
            double zAtCollide = tempConstant * directionZ + startLocation.getZ();
            if (between(yAtCollide, objectBoundry.b, objectBoundry.e, 0)
                    && between(zAtCollide, objectBoundry.c, objectBoundry.f, 0)) {
                constant = tempConstant;
                blockFace = BlockFace.EAST;
            }
        }
    }
    else {
        double a = objectBoundry.a - startLocation.getX();
        double tempConstant = a / directionX;
        if (tempConstant > 0 && tempConstant < constant) {
            double yAtCollide = tempConstant * directionY + startLocation.getY();
            double zAtCollide = tempConstant * directionZ + startLocation.getZ();
            if (between(yAtCollide, objectBoundry.b, objectBoundry.e, 0)
                    && between(zAtCollide, objectBoundry.c, objectBoundry.f, 0)) {
                constant = tempConstant;
                blockFace = BlockFace.WEST;
            }
        }
    }

    if(directionZ > 0) {
        double c = objectBoundry.c - startLocation.getZ();
        double tempConstant = c / directionZ;
        if(tempConstant > 0 && tempConstant < constant) {
            double yAtCollide = tempConstant * directionY + startLocation.getY();
            double xAtCollide = tempConstant * directionX + startLocation.getX();
            if (between(yAtCollide, objectBoundry.b, objectBoundry.e, 0)
                    && between(xAtCollide, objectBoundry.a, objectBoundry.d, 0)) {
                blockFace = BlockFace.NORTH;
            }
        }
    }
    else {
        double f = objectBoundry.f - startLocation.getZ();
        double tempConstant = f / directionZ;
        if(tempConstant < constant) {
            double yAtCollide = tempConstant * directionY + startLocation.getY();
            double xAtCollide = tempConstant * directionX + startLocation.getX();
            if (between(yAtCollide, objectBoundry.b, objectBoundry.e, 0)
                    && between(xAtCollide, objectBoundry.a, objectBoundry.d, 0)) {
                blockFace = BlockFace.SOUTH;
            }
        }
    }
    return blockFace;
}

public static boolean between(double num, double a, double b, double EOF) {
    if (a <= b)
        return num + EOF >= a && num - EOF <= b;
    return num + EOF >= b && num - EOF <= a;
}

答案 1 :(得分:0)

我认为没有办法获得他们正在查看的区块,但是您可以使用PlayerInteractEvent及其getBlockFace()方法获取他们点击的区块。

编辑:查看bukkit论坛上的this帖子。

编辑2:或者如this帖子中所述,您可以尝试将其放入PlayerMoveEvent

List<Block> blocks = event.getPlayer().getLastTwoTargetBlocks(null, 10);
if (blocks.size() > 1) 
    face = blocks.get(1).getFace(blocks.get(0));