【问题标题】:BUKKIT - Check for block under playerBUKKIT - 检查玩家下方的阻挡
【发布时间】:2015-10-11 08:13:55
【问题描述】:

抱歉,代码已被删除。

我认为这个问题对其他人没有帮助,因为它基本上是关于布尔值而不是检查如何获取块材料。

【问题讨论】:

  • @zapl 没有帮助我...
  • 好吧,你发布的代码做错了。有点,因为它是少数几个有效的案例之一。该链接不应该告诉您如何解决您的问题,而是向您展示如何在 Java 中进行字符串比较。 (即不要使用someString == "whatever",因为它大部分时间都不起作用,请使用someString.equals("whatever")

标签: java bukkit


【解决方案1】:

您可以使用内置的boolean 数据类型,而不是使用String 来跟踪真/假值。

您将Entity 变量(event.getDamager()event.getEntity())都转换为Player 类型,这将导致ClassCastException 每当调用EntityDamageByEntityEvent 事件时不涉及两个玩家(生物、箭头、 ETC。)。检查实体是否实际上是 Player 类的实例可以使用 instanceof 关键字来完成。

请注意,虽然 for 循环中的 x 变量从 3 递减到 1,但循环中包含取消事件的代码的最后一个条件始终检查 x 是否等于 1,因此没有任何代码当 x 等于 2 或 3 时,将永远执行 if 语句。

如果您只删除最后一个 if 语句的 x == 1 部分,那么您的代码会在每次发现任一玩家下方的基岩块时(可能是 3 次)将消息发送给破坏者。现在设置循环的方式(没有x == 1 条件),两个玩家下方的所有六个块都需要是基岩才能造成伤害,因为找到的任何非基岩块都会导致取消。

我假设您只想检查每个玩家下方三个方块中的至少一个是否是基岩(“如果玩家下方有一个基岩块 1、2、 ") 所以你必须写得有点不同。

我们可以使用以下方法检查玩家下方的任何depth 块是否由material 类型组成(克隆玩家的位置很重要,因此我们不会修改玩家的实际位置):

public static boolean isMatBelow(Player player, Material material, int depth) {
    Location location = player.getLocation().clone(); // Cloned location
    for (int blocks = 1; blocks <= depth; blocks++) { // From 1 to depth
        location.subtract(0, 1, 0); // Move one block down
        if (location.getBlock().getType() == material) { // If this is the material -> return true (break/exit loop)
            return true;
        }
    }
    return false; // No such material was found in all blocks -> return false
}

然后我们可以使用这个方法来检查两个玩家下方是否至少有一块基岩,同时也只向破坏者发送一条消息:

@EventHandler
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
    // Check whether both entities are players
    if (event.getDamager() instanceof Player && event.getEntity() instanceof Player) {
        Player damager = (Player) event.getDamager(); // Player doing the damage
        Player hurt = (Player) event.getEntity(); // Player getting hurt

        int height = 3; // The height you want to check
        Material pvpMaterial = Material.BEDROCK; // The material we are checking for

        boolean belowDamager = isMatBelow(damager, pvpMaterial, height); // Boolean whether a bedrock block is below the damager
        boolean belowHurt = isMatBelow(hurt, pvpMaterial, height); // Boolean whether a bedrock block is below the hurt player
        if (!belowDamager || !belowHurt) { // If there is NO bedrock between the damager or the hurt player
            // Create message -> if there isn't bedrock below the damager, initialize with first string, otherwise use the second string
            String message = (!belowDamager) ? "You are in a no-PVP zone." : "That player is in a no-PVP zone.";
            damager.sendMessage(message);
            event.setCancelled(true);
        }
    }
}

如果您想检查所有三个块是否都是播放器下方的基岩,您可以修改 isMatBelow(...) 方法以仅在每个块都具有指定材料时才返回 true。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多