BUKKIT - 检查玩家下方是否有障碍物
BUKKIT - Check for block under player
抱歉,代码已被删除。
我认为这个问题对其他人没有帮助,因为它基本上是关于布尔值而不是检查如何获得块 material。
您可以使用内置的 boolean
数据类型,而不是使用 String
来跟踪真/假值。
您正在将 Entity
变量(event.getDamager()
和 event.getEntity()
)转换为 Player
类型,这将在 [=19] 时导致 ClassCastException
=] 事件被称为不涉及两个玩家(小怪,箭头等)。检查实体是否实际上是 Player
class 的实例可以使用 instanceof
关键字来完成。
请注意,虽然 for 循环中的 x
变量从 3 递减到 1,但循环中包含取消事件代码的最后一个条件始终检查 x
是否等于 1,所以当 x
等于 2 或 3 时,if 语句中的代码 none 将永远被执行。
如果你只删除最后一个 if 语句的 x == 1
部分,你的代码会在每次发现任何玩家下方的基岩块时向破坏者发送消息(所以可能三次).你的循环现在设置的方式(没有 x == 1
条件),两个玩家下面的所有六个块都需要是基岩才能造成伤害,因为找到的任何非基岩块都会导致取消。
我假设您只想检查每个玩家下方的三个方块中是否至少有一个是基岩 ("if there is a bedrock block 1, 2, or 3 blocks below the player"),所以您必须稍微不同地写这个。
我们可以使用这个方法来检查玩家下方的任何 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(...)
方法修改为仅 return 如果每个方块都属于指定的 [=50] 则为真=].
抱歉,代码已被删除。
我认为这个问题对其他人没有帮助,因为它基本上是关于布尔值而不是检查如何获得块 material。
您可以使用内置的 boolean
数据类型,而不是使用 String
来跟踪真/假值。
您正在将 Entity
变量(event.getDamager()
和 event.getEntity()
)转换为 Player
类型,这将在 [=19] 时导致 ClassCastException
=] 事件被称为不涉及两个玩家(小怪,箭头等)。检查实体是否实际上是 Player
class 的实例可以使用 instanceof
关键字来完成。
请注意,虽然 for 循环中的 x
变量从 3 递减到 1,但循环中包含取消事件代码的最后一个条件始终检查 x
是否等于 1,所以当 x
等于 2 或 3 时,if 语句中的代码 none 将永远被执行。
如果你只删除最后一个 if 语句的 x == 1
部分,你的代码会在每次发现任何玩家下方的基岩块时向破坏者发送消息(所以可能三次).你的循环现在设置的方式(没有 x == 1
条件),两个玩家下面的所有六个块都需要是基岩才能造成伤害,因为找到的任何非基岩块都会导致取消。
我假设您只想检查每个玩家下方的三个方块中是否至少有一个是基岩 ("if there is a bedrock block 1, 2, or 3 blocks below the player"),所以您必须稍微不同地写这个。
我们可以使用这个方法来检查玩家下方的任何 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(...)
方法修改为仅 return 如果每个方块都属于指定的 [=50] 则为真=].