Причина, по которой игрок получает урон снаряда, несмотря на то, что он находится в списке noPVP
, - это способ, которым вы бросаете объекты. Обратите внимание, что как, так и e.getDamager()
возвращают объект Entity
, а не объект Player
. Всегда добавляя эти переменные, вы сообщаете плагину, что они являются экземплярами класса Player
, не зная, какой тип сущности они действительно есть, что часто неверно, потому что повреждение и поврежденный объект могут быть другими типами сущностей (стрелки, животные, мобы и т. д.).
Чтобы исправить это, вы можете убедиться, что в определенном случае вызванного события повреждение или поврежденный объект действительно являются экземплярами игроков, используя ключевое слово 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);
}
}
}
В исходном коде, если игрок стрелял из лука в другой игрок, ваш плагин пытался бросить стрелку (Damager лица) к игроку, что невозможно (класс Player
не является подклассом класса Arrow
), тем самым вызывая ClassCastException
и вызывая свой иначе правильный код после того, как инструкция else-if не будет выполнена.
Вот ClassCastException, когда корова повреждена субъектом с исходным кодом:
Я добавил два заявления печати для целей отладки после заливки объектов. Обратите внимание, что эти утверждения никогда не достигаются (поэтому никогда не отображаются) в случае генерируемого ClassCastException, но отображаются, если оба объекта являются игроками, и никакое исключение не выбрасывается.
С фрагментом кодом я написал выше, если имя игрока в списке noPVP любого повреждение снаряда отменяется:
Обратите внимание, что это отменяет повреждение всех снарядов, если поврежденный игрок находится в списке noPVP. Чтобы только отменить повреждение в случае стрелки, вы можете проверить, является ли объект damager экземпляром класса Arrow
. Вы даже можете проверить, была ли стрелка снята игроком или сущностью, такой как скелет, с использованием arrow.getShooter()
, после того как вы нанесли объект damager стрелке.
Я голосующий, чтобы закрыть этот вопрос как не относящийся к теме, поскольку ему не хватает конкретной проблемы или ошибки и кратчайшего кода, необходимого для его воспроизведения./Ваш ответ в другом замке. – Unihedron
Блестящий. Повезло тебе! Просто потому, что ваш ответ неверен, вы закрываете сообщение. StackOverflow так же плох, как говорят люди. –
Он работает только с повреждением в ближнем бою, как описано в описании. Это просто не работает для повреждения стрелы. Как это непонятно? –