射弹伤害未被取消
Projectile damage not being cancelled
如果玩家的名字在列表中,我正在尝试取消箭的伤害 noPVP
。
@EventHandler
public void playerDamagesWhenToggledOff(EntityDamageByEntityEvent e) {
Player victim = (Player) e.getEntity();
Player damager = (Player) e.getDamager();
if (getter.noPVP.contains(victim.getName()) || getter.noPVP.contains(damager.getName())) {
e.setCancelled(true);
}
else if (e.getCause() == DamageCause.PROJECTILE && getter.noPVP.contains(victim.getName()) || getter.noPVP.contains(damager.getName())) {
e.setCancelled(true);
}
}
这似乎行不通,即使 if
语句没问题。
尽管玩家在 noPVP
列表中,但仍会受到射弹伤害的原因是您施放实体的方式。请注意 e.getEntity()
和 e.getDamager()
return 都是 Entity
对象而不是 Player
对象。通过始终转换这些变量,您告诉插件它们是 Player
class 的实例,而不知道它们到底是什么类型的实体,这通常是错误的,因为损坏者和损坏的实体可能是其他的实体类型(箭、动物、生物等)。
要解决此问题,您可以使用 instanceof
关键字确保在调用事件的特定情况下,破坏者或受损实体确实是玩家的实例。以下是您应该可以使用的代码的更新版本:
@EventHandler
public void playerDamagesWhenToggledOff(EntityDamageByEntityEvent e) {
if (e.getEntity() instanceof Player) { // If damaged entity is a player
Player victim = (Player) e.getEntity(); // Cast
if (e.getDamager() instanceof Player) { // If the damager is also a player
Player damager = (Player) e.getDamager();
// Check if either of them are in the list, if so -> cancel damage
if (getter.noPVP.contains(victim.getName()) || getter.noPVP.contains(damager.getName())) {
e.setCancelled(true);
}
// If the damager was not a player, we can check if it was a projectile using the damage cause
// Still check whether damaged player is in noPVP list
} else if (e.getCause() == EntityDamageEvent.DamageCause.PROJECTILE && getter.noPVP.contains(victim.getName())) {
e.setCancelled(true);
}
}
}
在您的原始代码中,如果一个玩家向另一个玩家射箭,您的插件会尝试将箭(伤害实体)投向玩家,这是不可能的(Player
class 不是 Arrow
class) 的子 class,从而导致 ClassCastException
并导致 else-if 语句后的其他正确代码无法执行。
这是当牛被实体损坏时的 ClassCastException,您的原始代码:
我在转换实体后添加了两个用于调试的打印语句。请注意,在抛出 ClassCastException 的情况下永远不会到达(因此永远不会显示)这些语句,但如果两个实体恰好都是玩家并且没有抛出异常,则会显示这些语句。
使用我上面发布的代码片段,如果玩家的名字在 noPVP 列表中,则任何射弹伤害都会被取消:
请注意,如果受伤的玩家在 noPVP 列表中,这将取消所有射弹的伤害。如果只取消箭的伤害,你可以检查伤害实体是否是 Arrow
class 的实例。一旦你将破坏者实体投射到箭上,你甚至可以使用arrow.getShooter()
检查箭是由玩家还是由骷髅等实体射出的。
如果玩家的名字在列表中,我正在尝试取消箭的伤害 noPVP
。
@EventHandler
public void playerDamagesWhenToggledOff(EntityDamageByEntityEvent e) {
Player victim = (Player) e.getEntity();
Player damager = (Player) e.getDamager();
if (getter.noPVP.contains(victim.getName()) || getter.noPVP.contains(damager.getName())) {
e.setCancelled(true);
}
else if (e.getCause() == DamageCause.PROJECTILE && getter.noPVP.contains(victim.getName()) || getter.noPVP.contains(damager.getName())) {
e.setCancelled(true);
}
}
这似乎行不通,即使 if
语句没问题。
尽管玩家在 noPVP
列表中,但仍会受到射弹伤害的原因是您施放实体的方式。请注意 e.getEntity()
和 e.getDamager()
return 都是 Entity
对象而不是 Player
对象。通过始终转换这些变量,您告诉插件它们是 Player
class 的实例,而不知道它们到底是什么类型的实体,这通常是错误的,因为损坏者和损坏的实体可能是其他的实体类型(箭、动物、生物等)。
要解决此问题,您可以使用 instanceof
关键字确保在调用事件的特定情况下,破坏者或受损实体确实是玩家的实例。以下是您应该可以使用的代码的更新版本:
@EventHandler
public void playerDamagesWhenToggledOff(EntityDamageByEntityEvent e) {
if (e.getEntity() instanceof Player) { // If damaged entity is a player
Player victim = (Player) e.getEntity(); // Cast
if (e.getDamager() instanceof Player) { // If the damager is also a player
Player damager = (Player) e.getDamager();
// Check if either of them are in the list, if so -> cancel damage
if (getter.noPVP.contains(victim.getName()) || getter.noPVP.contains(damager.getName())) {
e.setCancelled(true);
}
// If the damager was not a player, we can check if it was a projectile using the damage cause
// Still check whether damaged player is in noPVP list
} else if (e.getCause() == EntityDamageEvent.DamageCause.PROJECTILE && getter.noPVP.contains(victim.getName())) {
e.setCancelled(true);
}
}
}
在您的原始代码中,如果一个玩家向另一个玩家射箭,您的插件会尝试将箭(伤害实体)投向玩家,这是不可能的(Player
class 不是 Arrow
class) 的子 class,从而导致 ClassCastException
并导致 else-if 语句后的其他正确代码无法执行。
这是当牛被实体损坏时的 ClassCastException,您的原始代码:
我在转换实体后添加了两个用于调试的打印语句。请注意,在抛出 ClassCastException 的情况下永远不会到达(因此永远不会显示)这些语句,但如果两个实体恰好都是玩家并且没有抛出异常,则会显示这些语句。
使用我上面发布的代码片段,如果玩家的名字在 noPVP 列表中,则任何射弹伤害都会被取消:
请注意,如果受伤的玩家在 noPVP 列表中,这将取消所有射弹的伤害。如果只取消箭的伤害,你可以检查伤害实体是否是 Arrow
class 的实例。一旦你将破坏者实体投射到箭上,你甚至可以使用arrow.getShooter()
检查箭是由玩家还是由骷髅等实体射出的。