diff --git a/src/main/java/ch/njol/skript/expressions/ExprSkullOwner.java b/src/main/java/ch/njol/skript/expressions/ExprSkullOwner.java index bc102126022..204354bf567 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprSkullOwner.java +++ b/src/main/java/ch/njol/skript/expressions/ExprSkullOwner.java @@ -1,5 +1,6 @@ package ch.njol.skript.expressions; +import ch.njol.skript.aliases.ItemType; import ch.njol.skript.bukkitutil.ItemUtils; import ch.njol.skript.classes.Changer.ChangeMode; import ch.njol.skript.doc.Description; @@ -7,39 +8,48 @@ import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; import ch.njol.skript.expressions.base.SimplePropertyExpression; +import ch.njol.skript.util.slot.Slot; import ch.njol.util.coll.CollectionUtils; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.block.Block; -import org.bukkit.block.BlockState; import org.bukkit.block.Skull; import org.bukkit.event.Event; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.profile.PlayerProfile; import org.jetbrains.annotations.Nullable; +import java.util.function.Consumer; + @Name("Skull Owner") @Description("The skull owner of a player skull.") @Examples({ "set {_owner} to the skull owner of event-block", - "set skull owner of {_block} to \"Njol\" parsed as offlineplayer" + "set skull owner of {_block} to \"Njol\" parsed as offlineplayer", + "set head owner of player's tool to {_player}" }) -@Since("2.9.0") -public class ExprSkullOwner extends SimplePropertyExpression { +@Since("2.9.0, INSERT VERSION (of items)") +public class ExprSkullOwner extends SimplePropertyExpression { static { - register(ExprSkullOwner.class, OfflinePlayer.class, "(head|skull) owner", "blocks"); + register(ExprSkullOwner.class, OfflinePlayer.class, "(head|skull) owner", "slots/itemtypes/itemstacks/blocks"); } @Override - public @Nullable OfflinePlayer convert(Block block) { - BlockState state = block.getState(); - if (!(state instanceof Skull)) - return null; - return ((Skull) state).getOwningPlayer(); + public @Nullable OfflinePlayer convert(Object object) { + if (object instanceof Block block && block.getState() instanceof Skull skull) { + return skull.getOwningPlayer(); + } else { + ItemStack skullItem = ItemUtils.asItemStack(object); + if (skullItem == null || !(skullItem.getItemMeta() instanceof SkullMeta skullMeta)) + return null; + return skullMeta.getOwningPlayer(); + } } @Override - @Nullable - public Class[] acceptChange(ChangeMode mode) { + public Class @Nullable [] acceptChange(ChangeMode mode) { if (mode == ChangeMode.SET) return CollectionUtils.array(OfflinePlayer.class); return null; @@ -48,25 +58,55 @@ public Class[] acceptChange(ChangeMode mode) { @Override public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { OfflinePlayer offlinePlayer = (OfflinePlayer) delta[0]; - for (Block block : getExpr().getArray(event)) { - BlockState state = block.getState(); - if (!(state instanceof Skull)) - continue; - - Skull skull = (Skull) state; - if (offlinePlayer.getName() != null) { - skull.setOwningPlayer(offlinePlayer); - } else if (ItemUtils.CAN_CREATE_PLAYER_PROFILE) { - //noinspection deprecation - skull.setOwnerProfile(Bukkit.createPlayerProfile(offlinePlayer.getUniqueId(), "")); + Consumer blockChanger = getBlockChanger(offlinePlayer); + Consumer metaChanger = getMetaChanger(offlinePlayer); + for (Object object : getExpr().getArray(event)) { + if (object instanceof Block block && block.getState() instanceof Skull skull) { + blockChanger.accept(skull); + skull.update(true, false); } else { - //noinspection deprecation - skull.setOwner(""); + ItemStack skullItem = ItemUtils.asItemStack(object); + if (skullItem == null || !(skullItem.getItemMeta() instanceof SkullMeta skullMeta)) + continue; + metaChanger.accept(skullMeta); + if (object instanceof Slot slot) { + skullItem.setItemMeta(skullMeta); + slot.setItem(skullItem); + } else if (object instanceof ItemType itemType) { + itemType.setItemMeta(skullMeta); + } else if (object instanceof ItemStack itemStack) { + itemStack.setItemMeta(skullMeta); + } } - skull.update(true, false); } } + private Consumer getBlockChanger(OfflinePlayer offlinePlayer) { + if (offlinePlayer.getName() != null) { + return skull -> skull.setOwningPlayer(offlinePlayer); + } else if (ItemUtils.CAN_CREATE_PLAYER_PROFILE) { + //noinspection deprecation + PlayerProfile profile = Bukkit.createPlayerProfile(offlinePlayer.getUniqueId(), ""); + //noinspection deprecation + return skull -> skull.setOwnerProfile(profile); + } + //noinspection deprecation + return skull -> skull.setOwner(""); + } + + private Consumer getMetaChanger(OfflinePlayer offlinePlayer) { + if (offlinePlayer.getName() != null) { + return skullMeta -> skullMeta.setOwningPlayer(offlinePlayer); + } else if (ItemUtils.CAN_CREATE_PLAYER_PROFILE) { + //noinspection deprecation + PlayerProfile profile = Bukkit.createPlayerProfile(offlinePlayer.getUniqueId(), ""); + //noinspection deprecation + return skullMeta -> skullMeta.setOwnerProfile(profile); + } + //noinspection deprecation + return skullMeta -> skullMeta.setOwner(""); + } + @Override public Class getReturnType() { return OfflinePlayer.class; diff --git a/src/test/skript/tests/syntaxes/expressions/ExprSkullOwner.sk b/src/test/skript/tests/syntaxes/expressions/ExprSkullOwner.sk new file mode 100644 index 00000000000..4369944c01e --- /dev/null +++ b/src/test/skript/tests/syntaxes/expressions/ExprSkullOwner.sk @@ -0,0 +1,16 @@ +test "skull owner - block": + set {_loc} to test-location + set {_old} to block at {_loc} + set block at {_loc} to player head + assert skull owner of (block at {_loc}) is not set with "Block Skull Owner should not be set" + set {_player} to "Sovde" parsed as offline player + set skull owner of (block at {_loc}) to {_player} + assert skull owner of (block at {_loc}) is {_player} with "Block Skull Owner did not change" + set block at {_loc} to {_old} + +test "skull owner - item": + set {_skull} to a player head + assert skull owner of {_skull} is not set with "Item Skull Owner should not be set" + set {_player} to "Sovde" parsed as offline player + set skull owner of {_skull} to {_player} + assert skull owner of {_skull} is {_player} with "Item Skull Owner did not change"