diff --git a/src/main/java/ch/njol/skript/conditions/CondIsWearing.java b/src/main/java/ch/njol/skript/conditions/CondIsWearing.java index ece4ba03a29..3b48d4eec2d 100644 --- a/src/main/java/ch/njol/skript/conditions/CondIsWearing.java +++ b/src/main/java/ch/njol/skript/conditions/CondIsWearing.java @@ -1,5 +1,6 @@ package ch.njol.skript.conditions; +import ch.njol.skript.Skript; import ch.njol.skript.aliases.ItemType; import ch.njol.skript.conditions.base.PropertyCondition; import ch.njol.skript.conditions.base.PropertyCondition.PropertyType; @@ -12,7 +13,7 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; -import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.*; import org.bukkit.event.Event; import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.EquipmentSlot; @@ -30,6 +31,9 @@ }) @Since("1.0") public class CondIsWearing extends Condition { + + private static final boolean HAS_CAN_USE_SLOT_METHOD = Skript.methodExists(LivingEntity.class, "canUseEquipmentSlot", EquipmentSlot.class); + private static final boolean HAS_BODY_SLOT = Skript.fieldExists(EquipmentSlot.class, "BODY"); static { PropertyCondition.register(CondIsWearing.class, "wearing %itemtypes%", "livingentities"); @@ -59,6 +63,21 @@ public boolean check(Event event) { return false; // spigot nullability, no identifier as to why this occurs ItemStack[] contents = Arrays.stream(EquipmentSlot.values()) + .filter(slot -> { + // this method was added in 1.20.6 + if (HAS_CAN_USE_SLOT_METHOD) + return entity.canUseEquipmentSlot(slot); + + // body slot was added in 1.20.5 + if (HAS_BODY_SLOT && slot == EquipmentSlot.BODY) + // this may change in the future, but for now this is the only way to figure out + // if the entity can use the body slot + return entity instanceof Horse + || entity instanceof Wolf + || entity instanceof Llama; + + return true; + }) .map(equipment::getItem) .toArray(ItemStack[]::new); diff --git a/src/test/java/org/skriptlang/skript/test/tests/regression/MissingCheckIfEntityCanUseSlot7524Test.java b/src/test/java/org/skriptlang/skript/test/tests/regression/MissingCheckIfEntityCanUseSlot7524Test.java new file mode 100644 index 00000000000..f0f4af67864 --- /dev/null +++ b/src/test/java/org/skriptlang/skript/test/tests/regression/MissingCheckIfEntityCanUseSlot7524Test.java @@ -0,0 +1,64 @@ +package org.skriptlang.skript.test.tests.regression; + +import ch.njol.skript.Skript; +import ch.njol.skript.lang.Condition; +import ch.njol.skript.lang.util.ContextlessEvent; +import ch.njol.skript.test.runner.SkriptJUnitTest; +import ch.njol.skript.variables.Variables; +import org.bukkit.Material; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class MissingCheckIfEntityCanUseSlot7524Test extends SkriptJUnitTest { + + private static final boolean HAS_CAN_USE_SLOT_METHOD = Skript.methodExists(LivingEntity.class, "canUseEquipmentSlot", EquipmentSlot.class); + + private Player player; + private EntityEquipment equipment; + private Condition isWearingCondition; + + @Before + public void setup() { + player = EasyMock.niceMock(Player.class); + equipment = EasyMock.niceMock(EntityEquipment.class); + + isWearingCondition = Condition.parse("{_player} is wearing diamond chestplate", null); + if (isWearingCondition == null) + throw new IllegalStateException(); + } + + @Test + public void test() { + ContextlessEvent event = ContextlessEvent.get(); + Variables.setVariable("player", player, event, true); + + EasyMock.expect(player.isValid()).andStubReturn(true); + EasyMock.expect(player.getEquipment()).andReturn(equipment); + + if (HAS_CAN_USE_SLOT_METHOD) { + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.CHEST)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.LEGS)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.FEET)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.HEAD)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.HAND)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.OFF_HAND)).andReturn(true); + EasyMock.expect(player.canUseEquipmentSlot(EquipmentSlot.BODY)).andReturn(false); + } + + EasyMock.expect(equipment.getItem(EquipmentSlot.CHEST)).andReturn(new ItemStack(Material.DIAMOND_CHESTPLATE)); + + EasyMock.replay(player, equipment); + + assert isWearingCondition.check(event); + + EasyMock.verify(player, equipment); + } + +}