您可以使用内置的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。