diff --git a/src/main/java/ch/njol/skript/effects/Delay.java b/src/main/java/ch/njol/skript/effects/Delay.java index 72e1a0dd786..89a4d36d694 100644 --- a/src/main/java/ch/njol/skript/effects/Delay.java +++ b/src/main/java/ch/njol/skript/effects/Delay.java @@ -37,28 +37,25 @@ public class Delay extends Effect { Skript.registerEffect(Delay.class, "(wait|halt) [for] %timespan%"); } - @SuppressWarnings("NotNullFieldNotInitialized") protected Expression duration; - @SuppressWarnings({"unchecked", "null"}) @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { getParser().setHasDelayBefore(Kleenean.TRUE); duration = (Expression) exprs[0]; if (duration instanceof Literal) { // If we can, do sanity check for delays long millis = ((Literal) duration).getSingle().getAs(Timespan.TimePeriod.MILLISECOND); - if (millis < 50) { + if (millis < 50) Skript.warning("Delays less than one tick are not possible, defaulting to one tick."); - } } return true; } @Override - @Nullable - protected TriggerItem walk(Event event) { + protected @Nullable TriggerItem walk(Event event) { debug(event, true); long start = Skript.debug() ? System.nanoTime() : 0; TriggerItem next = getNext(); diff --git a/src/main/java/ch/njol/skript/effects/EffActionBar.java b/src/main/java/ch/njol/skript/effects/EffActionBar.java index 07647482d3c..375077346a4 100644 --- a/src/main/java/ch/njol/skript/effects/EffActionBar.java +++ b/src/main/java/ch/njol/skript/effects/EffActionBar.java @@ -1,10 +1,7 @@ package ch.njol.skript.effects; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -17,24 +14,29 @@ import ch.njol.util.Kleenean; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.BaseComponent; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Action Bar") @Description("Sends an action bar message to the given player(s).") @Examples("send action bar \"Hello player!\" to player") @Since("2.3") -public class EffActionBar extends Effect { +public class EffActionBar extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffActionBar.class, "send [the] action[ ]bar [with text] %string% [to %players%]"); } + private Node node; private Expression message; - private Expression recipients; @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); message = (Expression) exprs[0]; recipients = (Expression) exprs[1]; return true; @@ -44,13 +46,20 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @SuppressWarnings("deprecation") protected void execute(Event event) { String msg = message.getSingle(event); - if (msg == null) + if (msg == null) { + error("The provided message was not set.", message.toString()); return; + } BaseComponent[] components = BungeeConverter.convert(ChatMessages.parseToArray(msg)); for (Player player : recipients.getArray(event)) player.spigot().sendMessage(ChatMessageType.ACTION_BAR, components); } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { return "send action bar " + message.toString(event, debug) + " to " + recipients.toString(event, debug); diff --git a/src/main/java/ch/njol/skript/effects/EffApplyBoneMeal.java b/src/main/java/ch/njol/skript/effects/EffApplyBoneMeal.java index 1a1712eedbf..d9d21d99e8f 100644 --- a/src/main/java/ch/njol/skript/effects/EffApplyBoneMeal.java +++ b/src/main/java/ch/njol/skript/effects/EffApplyBoneMeal.java @@ -1,39 +1,37 @@ package ch.njol.skript.effects; import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.config.Node; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; -import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Apply Bone Meal") @Description("Applies bone meal to a crop, sapling, or composter") @Examples("apply 3 bone meal to event-block") -@RequiredPlugins("MC 1.16.2+") +@RequiredPlugins("Minecraft 1.16.2+") @Since("2.8.0") -public class EffApplyBoneMeal extends Effect { +public class EffApplyBoneMeal extends Effect implements SyntaxRuntimeErrorProducer { static { - if (Skript.isRunningMinecraft(1, 16, 2)) - Skript.registerEffect(EffApplyBoneMeal.class, "apply [%-number%] bone[ ]meal[s] [to %blocks%]"); + Skript.registerEffect(EffApplyBoneMeal.class, "apply [%-number%] bone[ ]meal[s] [to %blocks%]"); } - @Nullable - private Expression amount; + private Node node; + private @Nullable Expression amount; private Expression blocks; @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); amount = (Expression) exprs[0]; blocks = (Expression) exprs[1]; return true; @@ -42,8 +40,15 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override protected void execute(Event event) { int times = 1; - if (amount != null) - times = amount.getOptionalSingle(event).orElse(0).intValue(); + if (amount != null) { + Number amount = this.amount.getSingle(event); + if (amount == null) { + warning("The provided amount of bone meal was not set, so defaulted to 1.", this.amount.toString()); + } else { + times = amount.intValue(); + } + } + for (Block block : blocks.getArray(event)) { for (int i = 0; i < times; i++) { block.applyBoneMeal(BlockFace.UP); @@ -51,9 +56,14 @@ protected void execute(Event event) { } } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { - return "apply " + (amount != null ? amount.toString(event, debug) + " " : "" + "bone meal to " + blocks.toString(event, debug)); + return "apply " + (amount != null ? amount.toString(event, debug) + " " : "") + "bone meal to " + blocks.toString(event, debug); } } diff --git a/src/main/java/ch/njol/skript/effects/EffBan.java b/src/main/java/ch/njol/skript/effects/EffBan.java index 02fd79af8d2..9eb2c1e2c60 100644 --- a/src/main/java/ch/njol/skript/effects/EffBan.java +++ b/src/main/java/ch/njol/skript/effects/EffBan.java @@ -22,19 +22,28 @@ import java.util.Date; @Name("Ban") -@Description({"Bans or unbans a player or an IP address.", +@Description({ + "Bans or unbans a player or an IP address.", "If a reason is given, it will be shown to the player when they try to join the server while banned.", "A length of ban may also be given to apply a temporary ban. If it is absent for any reason, a permanent ban will be used instead.", "We recommend that you test your scripts so that no accidental permanent bans are applied.", "", "Note that banning people does not kick them from the server.", - "You can optionally use 'and kick' or consider using the kick effect after applying a ban."}) -@Examples({"unban player", + "You can optionally use 'and kick' or consider using the kick effect after applying a ban." +}) +@Examples({ + "unban player", "ban \"127.0.0.1\"", "IP-ban the player because \"he is an idiot\"", "ban player due to \"inappropriate language\" for 2 days", - "ban and kick player due to \"inappropriate language\" for 2 days"}) -@Since("1.4, 2.1.1 (ban reason), 2.5 (timespan), 2.9.0 (kick)") + "ban and kick player due to \"inappropriate language\" for 2 days" +}) +@Since({ + "1.4", + "2.1.1 (ban reason)", + "2.5 (timespan)", + "2.9.0 (kick)" +}) public class EffBan extends Effect { static { @@ -47,20 +56,14 @@ public class EffBan extends Effect { "(IP(-| )unban|un[-]IP[-]ban) %players%"); } - @SuppressWarnings("null") private Expression players; - @Nullable - private Expression reason; - @Nullable - private Expression expires; + private @Nullable Expression reason; + private @Nullable Expression expires; + private boolean ban, ipBan, kick; - private boolean ban; - private boolean ipBan; - private boolean kick; - - @SuppressWarnings({"null", "unchecked"}) @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { players = exprs[0]; reason = exprs.length > 1 ? (Expression) exprs[1] : null; expires = exprs.length > 1 ? (Expression) exprs[2] : null; @@ -70,21 +73,19 @@ public boolean init(final Expression[] exprs, final int matchedPattern, final return true; } - @SuppressWarnings("null") @Override - protected void execute(final Event e) { - final String reason = this.reason != null ? this.reason.getSingle(e) : null; // don't check for null, just ignore an invalid reason - Timespan ts = this.expires != null ? this.expires.getSingle(e) : null; - final Date expires = ts != null ? new Date(System.currentTimeMillis() + ts.getAs(Timespan.TimePeriod.MILLISECOND)) : null; - final String source = "Skript ban effect"; - for (final Object o : players.getArray(e)) { - if (o instanceof Player) { - Player player = (Player) o; + protected void execute(Event event) { + String reason = this.reason != null ? this.reason.getSingle(event) : null; // don't check for null, just ignore an invalid reason + Timespan timespan = this.expires != null ? this.expires.getSingle(event) : null; + Date expires = timespan != null ? new Date(System.currentTimeMillis() + timespan.getAs(Timespan.TimePeriod.MILLISECOND)) : null; + String source = "Skript ban effect"; + for (Object object : players.getArray(event)) { + if (object instanceof Player player) { if (ipBan) { InetSocketAddress addr = player.getAddress(); if (addr == null) return; // Can't ban unknown IP - final String ip = addr.getAddress().getHostAddress(); + String ip = addr.getAddress().getHostAddress(); if (ban) Bukkit.getBanList(BanList.Type.IP).addBan(ip, reason, expires, source); else @@ -97,22 +98,21 @@ protected void execute(final Event e) { } if (kick) player.kickPlayer(reason); - } else if (o instanceof OfflinePlayer) { - String name = ((OfflinePlayer) o).getName(); + } else if (object instanceof OfflinePlayer offlinePlayer) { + String name = offlinePlayer.getName(); if (name == null) return; // Can't ban, name unknown if (ban) Bukkit.getBanList(BanList.Type.NAME).addBan(name, reason, expires, source); else Bukkit.getBanList(BanList.Type.NAME).pardon(name); - } else if (o instanceof String) { - final String s = (String) o; + } else if (object instanceof String string) { if (ban) { - Bukkit.getBanList(BanList.Type.IP).addBan(s, reason, expires, source); - Bukkit.getBanList(BanList.Type.NAME).addBan(s, reason, expires, source); + Bukkit.getBanList(BanList.Type.IP).addBan(string, reason, expires, source); + Bukkit.getBanList(BanList.Type.NAME).addBan(string, reason, expires, source); } else { - Bukkit.getBanList(BanList.Type.IP).pardon(s); - Bukkit.getBanList(BanList.Type.NAME).pardon(s); + Bukkit.getBanList(BanList.Type.IP).pardon(string); + Bukkit.getBanList(BanList.Type.NAME).pardon(string); } } else { assert false; diff --git a/src/main/java/ch/njol/skript/effects/EffBlockUpdate.java b/src/main/java/ch/njol/skript/effects/EffBlockUpdate.java index 90b24a2fcb8..84588d5a526 100644 --- a/src/main/java/ch/njol/skript/effects/EffBlockUpdate.java +++ b/src/main/java/ch/njol/skript/effects/EffBlockUpdate.java @@ -1,6 +1,7 @@ package ch.njol.skript.effects; import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -8,12 +9,14 @@ import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.SyntaxStringBuilder; import ch.njol.util.Kleenean; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.event.Event; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Update Block") @Description({ @@ -28,13 +31,14 @@ }) @Since("2.10") // Originally sourced from SkBee by ShaneBee (https://github.com/ShaneBeee/SkBee/blob/master/src/main/java/com/shanebeestudios/skbee/elements/other/effects/EffBlockstateUpdate.java) -public class EffBlockUpdate extends Effect { +public class EffBlockUpdate extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffBlockUpdate.class, "update %blocks% (as|to be) %blockdata% [physics:without [neighbo[u]r[ing]|adjacent] [physic[s]] update[s]]"); } + private Node node; private boolean physics; private Expression blocks; private Expression blockData; @@ -42,6 +46,7 @@ public class EffBlockUpdate extends Effect { @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + this.node = getParser().getNode(); this.physics = !parseResult.hasTag("physics"); this.blocks = (Expression) exprs[0]; this.blockData = (Expression) exprs[1]; @@ -51,17 +56,28 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override protected void execute(Event event) { BlockData data = this.blockData.getSingle(event); - if (data == null) + if (data == null) { + error("The provided blockdata was not set.", this.blockData.toString()); return; + } + for (Block block : this.blocks.getArray(event)) { block.setBlockData(data, this.physics); } } + @Override + public Node getNode() { + return node; + } + @Override public @NotNull String toString(@Nullable Event event, boolean debug) { - return "update " + this.blocks.toString(event, debug) + " as " - + this.blockData.toString(event, debug) + (this.physics ? "without neighbour updates" : ""); + SyntaxStringBuilder builder = new SyntaxStringBuilder(event, debug); + builder.append("update", blocks, "as", blockData); + if (physics) + builder.append("without adjacent updates"); + return builder.toString(); } } diff --git a/src/main/java/ch/njol/skript/effects/EffBreakNaturally.java b/src/main/java/ch/njol/skript/effects/EffBreakNaturally.java index 2b1cce956dc..6b20db5581a 100644 --- a/src/main/java/ch/njol/skript/effects/EffBreakNaturally.java +++ b/src/main/java/ch/njol/skript/effects/EffBreakNaturally.java @@ -1,66 +1,94 @@ package ch.njol.skript.effects; -import org.bukkit.block.Block; -import org.bukkit.event.Event; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.aliases.ItemType; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.SkriptParser; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.SyntaxStringBuilder; import ch.njol.util.Kleenean; +import org.bukkit.block.Block; +import org.bukkit.event.Event; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Break Block") -@Description({"Breaks the block and spawns items as if a player had mined it", - "\nYou can add a tool, which will spawn items based on how that tool would break the block ", - "(ie: When using a hand to break stone, it drops nothing, whereas with a pickaxe it drops cobblestone)"}) -@Examples({"on right click:", "\tbreak clicked block naturally", - "loop blocks in radius 10 around player:", "\tbreak loop-block using player's tool", - "loop blocks in radius 10 around player:", "\tbreak loop-block naturally using diamond pickaxe"}) +@Description({ + "Breaks the block and spawns items as if a player had mined it", + "You can add a tool, which will spawn items based on how that tool would break the block " + + "(i.e. using a hand to break stone drops nothing, whereas using a pickaxe drops cobblestone)"}) +@Examples({ + "on right click:", + "\tbreak clicked block naturally", + "loop blocks in radius 10 around player:", + "\tbreak loop-block using player's tool", + "loop blocks in radius 10 around player:", + "\tbreak loop-block naturally using diamond pickaxe" +}) @Since("2.4") -public class EffBreakNaturally extends Effect { +public class EffBreakNaturally extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffBreakNaturally.class, "break %blocks% [naturally] [using %-itemtype%]"); } - - @SuppressWarnings("null") + + private Node node; private Expression blocks; - @Nullable - private Expression tool; - - @SuppressWarnings({"unchecked", "null"}) + private @Nullable Expression tool; + @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final SkriptParser.ParseResult parser) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parser) { + node = getParser().getNode(); blocks = (Expression) exprs[0]; tool = (Expression) exprs[1]; return true; } @Override - protected void execute(final Event e) { - ItemType tool = this.tool != null ? this.tool.getSingle(e) : null; - for (Block block : this.blocks.getArray(e)) { - if (tool != null) { - ItemStack is = tool.getRandom(); - if (is != null) - block.breakNaturally(is); - else + protected void execute(Event event) { + ItemType itemType = null; + if (this.tool != null) { + ItemType tool = this.tool.getSingle(event); + if (tool == null) { + warning("The provided tool was not set, so defaulted to nothing."); + } else { + itemType = tool; + } + } + + for (Block block : this.blocks.getArray(event)) { + if (itemType != null) { + ItemStack itemStack = itemType.getRandom(); + if (itemStack != null) { + block.breakNaturally(itemStack); + } else { block.breakNaturally(); + } } else { block.breakNaturally(); } } } + + @Override + public Node getNode() { + return node; + } @Override - public String toString(final @Nullable Event e, final boolean debug) { - return "break " + blocks.toString(e, debug) + " naturally" + (tool != null ? " using " + tool.toString(e, debug) : ""); + public String toString(@Nullable Event event, boolean debug) { + SyntaxStringBuilder builder = new SyntaxStringBuilder(event, debug); + builder.append("break", blocks, "naturally"); + if (tool != null) + builder.append("using", tool); + return builder.toString(); } + } diff --git a/src/main/java/ch/njol/skript/effects/EffBroadcast.java b/src/main/java/ch/njol/skript/effects/EffBroadcast.java index 7b41e1f41fd..c8c1944796e 100644 --- a/src/main/java/ch/njol/skript/effects/EffBroadcast.java +++ b/src/main/java/ch/njol/skript/effects/EffBroadcast.java @@ -1,12 +1,5 @@ package ch.njol.skript.effects; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.regex.Pattern; - import ch.njol.skript.Skript; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -35,6 +28,13 @@ import org.bukkit.event.server.BroadcastMessageEvent; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + @Name("Broadcast") @Description("Broadcasts a message to the server.") @Examples({ @@ -50,12 +50,9 @@ public class EffBroadcast extends Effect { Skript.registerEffect(EffBroadcast.class, "broadcast %objects% [(to|in) %-worlds%]"); } - @SuppressWarnings("NotNullFieldNotInitialized") private Expression messageExpr; - @SuppressWarnings("NotNullFieldNotInitialized") private Expression[] messages; - @Nullable - private Expression worlds; + private @Nullable Expression worlds; @Override @SuppressWarnings("unchecked") diff --git a/src/main/java/ch/njol/skript/effects/EffCancelCooldown.java b/src/main/java/ch/njol/skript/effects/EffCancelCooldown.java index a8706029d00..56136005e15 100644 --- a/src/main/java/ch/njol/skript/effects/EffCancelCooldown.java +++ b/src/main/java/ch/njol/skript/effects/EffCancelCooldown.java @@ -1,64 +1,74 @@ package ch.njol.skript.effects; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.command.ScriptCommandEvent; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.SkriptParser; +import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.log.ErrorQuality; import ch.njol.util.Kleenean; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Cancel Command Cooldown") -@Description({"Only usable in commands. Makes it so the current command usage isn't counted towards the cooldown."}) +@Description("Only usable in commands. Makes it so the current command usage isn't counted towards the cooldown.") @Examples({ - "command /nick <text>:", + "command /nick <text>:", "\texecutable by: players", "\tcooldown: 10 seconds", "\ttrigger:", - "\t\tif length of arg-1 is more than 16:", - "\t\t\t# Makes it so that invalid arguments don't make you wait for the cooldown again", - "\t\t\tcancel the cooldown", - "\t\t\tsend \"Your nickname may be at most 16 characters.\"", - "\t\t\tstop", - "\t\tset the player's display name to arg-1"}) + "\t\tif length of arg-1 is more than 16:", + "\t\t\t# Makes it so that invalid arguments don't make you wait for the cooldown again", + "\t\t\tcancel the cooldown", + "\t\t\tsend \"Your nickname may be at most 16 characters.\"", + "\t\t\tstop", + "\t\tset the player's display name to arg-1"}) @Since("2.2-dev34") -public class EffCancelCooldown extends Effect { +public class EffCancelCooldown extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffCancelCooldown.class, - "(cancel|ignore) [the] [current] [command] cooldown", - "un(cancel|ignore) [the] [current] [command] cooldown"); + "(cancel|ignore) [the] [current] [command] cooldown", + "un(cancel|ignore) [the] [current] [command] cooldown"); } + private Node node; private boolean cancel; @Override - public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { if (!getParser().isCurrentEvent(ScriptCommandEvent.class)) { Skript.error("The cancel cooldown effect may only be used in a command", ErrorQuality.SEMANTIC_ERROR); return false; } + node = getParser().getNode(); cancel = matchedPattern == 0; return true; } @Override - protected void execute(Event e) { - if (!(e instanceof ScriptCommandEvent)) + protected void execute(Event event) { + if (!(event instanceof ScriptCommandEvent scriptCommandEvent)) { + error("The 'cancel cooldown' effect can only be used in a command."); return; + } + + scriptCommandEvent.setCooldownCancelled(cancel); + } - ((ScriptCommandEvent) e).setCooldownCancelled(cancel); + @Override + public Node getNode() { + return node; } @Override - public String toString(@Nullable Event e, boolean debug) { + public String toString(@Nullable Event event, boolean debug) { return (cancel ? "" : "un") + "cancel the command cooldown"; } diff --git a/src/main/java/ch/njol/skript/effects/EffCancelDrops.java b/src/main/java/ch/njol/skript/effects/EffCancelDrops.java index 685b2d4e046..1128920c047 100644 --- a/src/main/java/ch/njol/skript/effects/EffCancelDrops.java +++ b/src/main/java/ch/njol/skript/effects/EffCancelDrops.java @@ -1,34 +1,32 @@ package ch.njol.skript.effects; -import org.bukkit.event.Event; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.entity.EntityDeathEvent; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Events; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.event.Event; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.jetbrains.annotations.Nullable; @Name("Cancel Drops") -@Description("Cancels drops of items or experiences in a death or block break event. " + - "Please note that this doesn't keep items or experiences of a dead player. If you want to do that, " + - "use the Keep Inventory / Experience effect.") -@Examples({"on death of a zombie:", +@Description({ + "Cancels drops of items or experiences in a death or block break event.", + "Please note that this doesn't keep items or experiences of a dead player. If you want to do that, " + + "use the Keep Inventory / Experience effect." +}) +@Examples({ + "on death of a zombie:", "\tif name of the entity is \"&cSpecial\":", - "\t\tcancel drops of items", - "", - "on break of a coal ore:", - "\tcancel the experience drops"}) + "\t\tcancel drops of items", + "", + "on break of a coal ore:", + "\tcancel the experience drops" +}) @Since("2.4") -@RequiredPlugins("1.12.2 or newer (cancelling item drops of blocks)") +@RequiredPlugins("1.12.2+ (cancelling item drops of blocks)") @Events({"death", "break / mine"}) public class EffCancelDrops extends Effect { @@ -64,24 +62,22 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - protected void execute(Event e) { - if (e instanceof EntityDeathEvent) { - EntityDeathEvent event = (EntityDeathEvent) e; + protected void execute(Event event) { + if (event instanceof EntityDeathEvent deathEvent) { if (cancelItems) - event.getDrops().clear(); + deathEvent.getDrops().clear(); if (cancelExps) - event.setDroppedExp(0); - } else if (e instanceof BlockBreakEvent) { - BlockBreakEvent event = (BlockBreakEvent) e; + deathEvent.setDroppedExp(0); + } else if (event instanceof BlockBreakEvent blockBreakEvent) { if (cancelItems) - event.setDropItems(false); + blockBreakEvent.setDropItems(false); if (cancelExps) - event.setExpToDrop(0); + blockBreakEvent.setExpToDrop(0); } } @Override - public String toString(@Nullable Event e, boolean debug) { + public String toString(@Nullable Event event, boolean debug) { if (cancelItems && !cancelExps) return "cancel the drops of items"; else if (cancelExps && !cancelItems) diff --git a/src/main/java/ch/njol/skript/effects/EffCancelEvent.java b/src/main/java/ch/njol/skript/effects/EffCancelEvent.java index 3343f032cdf..25e5da75daa 100644 --- a/src/main/java/ch/njol/skript/effects/EffCancelEvent.java +++ b/src/main/java/ch/njol/skript/effects/EffCancelEvent.java @@ -42,8 +42,7 @@ public class EffCancelEvent extends Effect { private boolean cancel; @Override - public boolean init(Expression[] expressions, int matchedPattern, - Kleenean isDelayed, ParseResult parseResult) { + public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { if (isDelayed == Kleenean.TRUE) { Skript.error("An event cannot be cancelled after it has already passed", ErrorQuality.SEMANTIC_ERROR); return false; @@ -74,18 +73,18 @@ public boolean init(Expression[] expressions, int matchedPattern, @Override public void execute(Event event) { - if (event instanceof Cancellable) - ((Cancellable) event).setCancelled(cancel); - if (event instanceof PlayerInteractEvent) { + if (event instanceof Cancellable cancellable) + cancellable.setCancelled(cancel); + if (event instanceof PlayerInteractEvent playerInteractEvent) { EvtClick.interactTracker.eventModified((Cancellable) event); - ((PlayerInteractEvent) event).setUseItemInHand(cancel ? Event.Result.DENY : Event.Result.DEFAULT); - ((PlayerInteractEvent) event).setUseInteractedBlock(cancel ? Event.Result.DENY : Event.Result.DEFAULT); - } else if (event instanceof BlockCanBuildEvent) { - ((BlockCanBuildEvent) event).setBuildable(!cancel); - } else if (event instanceof PlayerDropItemEvent) { - PlayerUtils.updateInventory(((PlayerDropItemEvent) event).getPlayer()); - } else if (event instanceof InventoryInteractEvent) { - PlayerUtils.updateInventory(((Player) ((InventoryInteractEvent) event).getWhoClicked())); + playerInteractEvent.setUseItemInHand(cancel ? Event.Result.DENY : Event.Result.DEFAULT); + playerInteractEvent.setUseInteractedBlock(cancel ? Event.Result.DENY : Event.Result.DEFAULT); + } else if (event instanceof BlockCanBuildEvent canBuildEvent) { + canBuildEvent.setBuildable(!cancel); + } else if (event instanceof PlayerDropItemEvent dropItemEvent) { + PlayerUtils.updateInventory(dropItemEvent.getPlayer()); + } else if (event instanceof InventoryInteractEvent inventoryInteractEvent) { + PlayerUtils.updateInventory(((Player) inventoryInteractEvent.getWhoClicked())); } } diff --git a/src/main/java/ch/njol/skript/effects/EffCancelItemUse.java b/src/main/java/ch/njol/skript/effects/EffCancelItemUse.java index dc3013686fc..5d49baaa884 100644 --- a/src/main/java/ch/njol/skript/effects/EffCancelItemUse.java +++ b/src/main/java/ch/njol/skript/effects/EffCancelItemUse.java @@ -1,11 +1,7 @@ package ch.njol.skript.effects; import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; @@ -31,8 +27,7 @@ public class EffCancelItemUse extends Effect { static { if (Skript.methodExists(LivingEntity.class, "clearActiveItem")) Skript.registerEffect(EffCancelItemUse.class, - "(cancel|interrupt) [the] us[ag]e of %livingentities%'[s] [active|current] item" - ); + "(cancel|interrupt) [the] us[ag]e of %livingentities%'[s] [active|current] item"); } private Expression entities; diff --git a/src/main/java/ch/njol/skript/effects/EffChange.java b/src/main/java/ch/njol/skript/effects/EffChange.java index 0a755e24f57..e6bd5d23e89 100644 --- a/src/main/java/ch/njol/skript/effects/EffChange.java +++ b/src/main/java/ch/njol/skript/effects/EffChange.java @@ -1,14 +1,5 @@ package ch.njol.skript.effects; -import java.util.Arrays; -import java.util.logging.Level; - -import ch.njol.skript.expressions.ExprParse; -import ch.njol.skript.lang.*; -import org.skriptlang.skript.lang.script.ScriptWarning; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.SkriptConfig; import ch.njol.skript.classes.Changer; @@ -18,6 +9,8 @@ import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; +import ch.njol.skript.expressions.ExprParse; +import ch.njol.skript.lang.*; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.log.CountingLogHandler; import ch.njol.skript.log.ErrorQuality; @@ -27,71 +20,77 @@ import ch.njol.skript.util.Patterns; import ch.njol.skript.util.Utils; import ch.njol.util.Kleenean; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.lang.script.ScriptWarning; + +import java.util.Arrays; +import java.util.logging.Level; -/** - * @author Peter Güttinger - */ @Name("Change: Set/Add/Remove/Delete/Reset") -@Description("A very general effect that can change many expressions. Many expressions can only be set and/or deleted, while some can have things added to or removed from them.") -@Examples({"# set:", - "Set the player's display name to \"<red>%name of player%\"", - "set the block above the victim to lava", - "# add:", - "add 2 to the player's health # preferably use 'heal' for this", - "add argument to {blacklist::*}", - "give a diamond pickaxe of efficiency 5 to the player", - "increase the data value of the clicked block by 1", - "# remove:", - "remove 2 pickaxes from the victim", - "subtract 2.5 from {points::%uuid of player%}", - "# remove all:", - "remove every iron tool from the player", - "remove all minecarts from {entitylist::*}", - "# delete:", - "delete the block below the player", - "clear drops", - "delete {variable}", - "# reset:", - "reset walk speed of player", - "reset chunk at the targeted block"}) -@Since("1.0 (set, add, remove, delete), 2.0 (remove all)") +@Description({ + "A very general effect that can change many expressions.", + "Many expressions can only be set and/or deleted, while some can have things added to or removed from them." +}) +@Examples({ + "# set:", + "Set the player's display name to \"<red>%name of player%\"", + "set the block above the victim to lava", + "# add:", + "add 2 to the player's health # preferably use 'heal' for this", + "add argument to {blacklist::*}", + "give a diamond pickaxe of efficiency 5 to the player", + "increase the data value of the clicked block by 1", + "# remove:", + "remove 2 pickaxes from the victim", + "subtract 2.5 from {points::%uuid of player%}", + "# remove all:", + "remove every iron tool from the player", + "remove all minecarts from {entitylist::*}", + "# delete:", + "delete the block below the player", + "clear drops", + "delete {variable}", + "# reset:", + "reset walk speed of player", + "reset chunk at the targeted block" +}) +@Since({ + "1.0 (set, add, remove, delete)", + "2.0 (remove all)" +}) public class EffChange extends Effect { - private static Patterns patterns = new Patterns<>(new Object[][] { - {"(add|give) %objects% to %~objects%", ChangeMode.ADD}, - {"increase %~objects% by %objects%", ChangeMode.ADD}, - {"give %~objects% %objects%", ChangeMode.ADD}, + private static final Patterns patterns = new Patterns<>(new Object[][] { + {"(add|give) %objects% to %~objects%", ChangeMode.ADD}, + {"increase %~objects% by %objects%", ChangeMode.ADD}, + {"give %~objects% %objects%", ChangeMode.ADD}, - {"set %~objects% to %objects%", ChangeMode.SET}, + {"set %~objects% to %objects%", ChangeMode.SET}, - {"remove (all|every) %objects% from %~objects%", ChangeMode.REMOVE_ALL}, + {"remove (all|every) %objects% from %~objects%", ChangeMode.REMOVE_ALL}, - {"(remove|subtract) %objects% from %~objects%", ChangeMode.REMOVE}, - {"(reduce|decrease) %~objects% by %objects%", ChangeMode.REMOVE}, + {"(remove|subtract) %objects% from %~objects%", ChangeMode.REMOVE}, + {"(reduce|decrease) %~objects% by %objects%", ChangeMode.REMOVE}, - {"(delete|clear) %~objects%", ChangeMode.DELETE}, + {"(delete|clear) %~objects%", ChangeMode.DELETE}, - {"reset %~objects%", ChangeMode.RESET} + {"reset %~objects%", ChangeMode.RESET} }); static { Skript.registerEffect(EffChange.class, patterns.getPatterns()); } - @SuppressWarnings("null") private Expression changed; - @Nullable - private Expression changer = null; - - @SuppressWarnings("null") + private @Nullable Expression changer = null; private ChangeMode mode; - private boolean single; // private Changer c = null; - @SuppressWarnings({"unchecked", "null"}) @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parser) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parser) { mode = patterns.getInfo(matchedPattern); switch (mode) { @@ -121,14 +120,12 @@ public boolean init(final Expression[] exprs, final int matchedPattern, final changed = exprs[0]; } break; - case DELETE: + case DELETE, RESET: changed = exprs[0]; break; - case RESET: - changed = exprs[0]; } - CountingLogHandler h = new CountingLogHandler(Level.SEVERE).start(); + CountingLogHandler handler = new CountingLogHandler(Level.SEVERE).start(); Class[] rs; String what; try { @@ -137,10 +134,10 @@ public boolean init(final Expression[] exprs, final int matchedPattern, final Changer changer = c.getChanger(); what = changer == null || !Arrays.equals(changer.acceptChange(mode), rs) ? changed.toString(null, false) : c.getName().withIndefiniteArticle(); } finally { - h.stop(); + handler.stop(); } if (rs == null) { - if (h.getCount() > 0) + if (handler.getCount() > 0) return false; switch (mode) { case SET: @@ -171,17 +168,17 @@ public boolean init(final Expression[] exprs, final int matchedPattern, final return false; } - final Class[] rs2 = new Class[rs.length]; + Class[] rs2 = new Class[rs.length]; for (int i = 0; i < rs.length; i++) rs2[i] = rs[i].isArray() ? rs[i].getComponentType() : rs[i]; - final boolean allSingle = Arrays.equals(rs, rs2); + boolean allSingle = Arrays.equals(rs, rs2); Expression ch = changer; if (ch != null) { Expression v = null; - final ParseLogHandler log = SkriptLogger.startParseLogHandler(); + ParseLogHandler log = SkriptLogger.startParseLogHandler(); try { - for (final Class r : rs) { + for (Class r : rs) { log.clear(); if ((r.isArray() ? r.getComponentType() : r).isAssignableFrom(ch.getReturnType())) { v = ch.getConvertedExpression(Object.class); @@ -197,7 +194,7 @@ public boolean init(final Expression[] exprs, final int matchedPattern, final } log.clear(); log.stop(); - final Class[] r = new Class[rs.length]; + Class[] r = new Class[rs.length]; for (int i = 0; i < rs.length; i++) r[i] = rs[i].isArray() ? rs[i].getComponentType() : rs[i]; if (r.length == 1 && r[0] == Object.class) @@ -246,7 +243,7 @@ else if (mode == ChangeMode.SET) } if (changed instanceof Variable && !((Variable) changed).isLocal() && (mode == ChangeMode.SET || ((Variable) changed).isList() && mode == ChangeMode.ADD)) { - final ClassInfo ci = Classes.getSuperClassInfo(ch.getReturnType()); + ClassInfo ci = Classes.getSuperClassInfo(ch.getReturnType()); if (ci.getC() != Object.class && ci.getSerializer() == null && ci.getSerializeAs() == null && !SkriptConfig.disableObjectCannotBeSavedWarnings.value()) { if (getParser().isActive() && !getParser().getCurrentScript().suppressesWarning(ScriptWarning.VARIABLE_SAVE)) { Skript.warning(ci.getName().withIndefiniteArticle() + " cannot be saved, i.e. the contents of the variable " + changed + " will be lost when the server stops."); @@ -278,28 +275,28 @@ protected void execute(Event event) { } @Override - public String toString(final @Nullable Event e, final boolean debug) { - final Expression changer = this.changer; - switch (mode) { - case ADD: + public String toString(@Nullable Event event, boolean debug) { + Expression changer = this.changer; + return switch (mode) { + case ADD -> { assert changer != null; - return "add " + changer.toString(e, debug) + " to " + changed.toString(e, debug); - case SET: + yield "add " + changer.toString(event, debug) + " to " + changed.toString(event, debug); + } + case SET -> { assert changer != null; - return "set " + changed.toString(e, debug) + " to " + changer.toString(e, debug); - case REMOVE: + yield "set " + changed.toString(event, debug) + " to " + changer.toString(event, debug); + } + case REMOVE -> { assert changer != null; - return "remove " + changer.toString(e, debug) + " from " + changed.toString(e, debug); - case REMOVE_ALL: + yield "remove " + changer.toString(event, debug) + " from " + changed.toString(event, debug); + } + case REMOVE_ALL -> { assert changer != null; - return "remove all " + changer.toString(e, debug) + " from " + changed.toString(e, debug); - case DELETE: - return "delete/clear " + changed.toString(e, debug); - case RESET: - return "reset " + changed.toString(e, debug); - } - assert false; - return ""; + yield "remove all " + changer.toString(event, debug) + " from " + changed.toString(event, debug); + } + case DELETE -> "delete/clear " + changed.toString(event, debug); + case RESET -> "reset " + changed.toString(event, debug); + }; } } diff --git a/src/main/java/ch/njol/skript/effects/EffCharge.java b/src/main/java/ch/njol/skript/effects/EffCharge.java index 45563cf9d8d..6a6e205b13a 100644 --- a/src/main/java/ch/njol/skript/effects/EffCharge.java +++ b/src/main/java/ch/njol/skript/effects/EffCharge.java @@ -1,6 +1,7 @@ package ch.njol.skript.effects; import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -14,29 +15,34 @@ import org.bukkit.entity.WitherSkull; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Charge Entity") -@Description("Charges or uncharges a creeper or wither skull. A creeper is charged when it has been struck by lightning.") +@Description({ + "Charges or uncharges a creeper or wither skull.", + "A creeper is charged when it has been struck by lightning." +}) @Examples({ "on spawn of creeper:", "\tcharge the event-entity" }) @Since("2.5, 2.10 (wither skulls)") -public class EffCharge extends Effect { +public class EffCharge extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffCharge.class, - "make %entities% [un:(un|not |non[-| ])](charged|powered)", - "[:un](charge|power) %entities%"); + "make %entities% [un:(un|not |non[-| ])](charged|powered)", + "[:un](charge|power) %entities%"); } - @SuppressWarnings("NotNullFieldNotInitialized") + private Node node; private Expression entities; private boolean charge; - @SuppressWarnings({"unchecked", "null"}) @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); entities = (Expression) exprs[0]; charge = !parseResult.hasTag("un"); return true; @@ -49,10 +55,17 @@ protected void execute(Event event) { creeper.setPowered(charge); } else if (entity instanceof WitherSkull witherSkull) { witherSkull.setCharged(charge); - } + } else { + warning("An entity passed to the 'charge' effect was not a creeper, nor a wither skull, and was thus unaffected.", entities.toString()); + } } } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { return "make " + entities.toString(event, debug) + (charge ? " charged" : " not charged"); diff --git a/src/main/java/ch/njol/skript/effects/EffColorItems.java b/src/main/java/ch/njol/skript/effects/EffColorItems.java index 6f2fc81dce1..65bfed78ba7 100644 --- a/src/main/java/ch/njol/skript/effects/EffColorItems.java +++ b/src/main/java/ch/njol/skript/effects/EffColorItems.java @@ -1,14 +1,8 @@ package ch.njol.skript.effects; -import org.bukkit.event.Event; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.LeatherArmorMeta; -import org.bukkit.inventory.meta.MapMeta; -import org.bukkit.inventory.meta.PotionMeta; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.aliases.ItemType; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -21,33 +15,41 @@ import ch.njol.skript.util.ColorRGB; import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; +import org.bukkit.event.Event; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.inventory.meta.MapMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Color Items") -@Description("Colors items in a given color. " + - "You can also use RGB codes if you feel limited with the 16 default colors. " + - "RGB codes are three numbers from 0 to 255 in the order (red, green, blue), where (0,0,0) is black and (255,255,255) is white. " + - "Armor is colorable for all Minecraft versions. With Minecraft 1.11 or newer you can also color potions and maps. Note that the colors might not look exactly how you'd expect.") -@Examples({"dye player's helmet blue", - "color the player's tool red"}) +@Description({ + "Colors items in a given color.", + "You can also use RGB codes if you feel limited with the 16 default colors.", + "Armor is colorable for all Minecraft versions. With Minecraft 1.11+ you can also color potions and maps. Note that the colors might not look exactly how you'd expect." +}) +@Examples({ + "dye player's helmet blue", + "color the player's tool red" +}) @Since("2.0, 2.2-dev26 (maps and potions)") -public class EffColorItems extends Effect { - - private static final boolean MAPS_AND_POTIONS_COLORS = Skript.methodExists(PotionMeta.class, "setColor", org.bukkit.Color.class); +public class EffColorItems extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffColorItems.class, - "(dye|colo[u]r|paint) %itemtypes% %color%", - "(dye|colo[u]r|paint) %itemtypes% \\(%number%, %number%, %number%\\)"); + "(dye|colo[u]r|paint) %itemtypes% %color%", + "(dye|colo[u]r|paint) %itemtypes% \\(%number%, %number%, %number%\\)"); } - - @SuppressWarnings("null") + + private Node node; private Expression items; - @SuppressWarnings("null") private Expression color; - - @SuppressWarnings({"unchecked", "null"}) + @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parser) { + node = getParser().getNode(); items = (Expression) exprs[0]; if (matchedPattern == 0) { color = (Expression) exprs[1]; @@ -100,41 +102,40 @@ public String toString(@Nullable Event e, boolean debug) { } @Override - protected void execute(Event e) { - Color color = this.color.getSingle(e); - ItemType[] items = this.items.getArray(e); - org.bukkit.Color c; - + protected void execute(Event event) { + Color color = this.color.getSingle(event); if (color == null) { + error("The provided color was not set.", this.color.toString()); return; } + org.bukkit.Color bukkitColor = color.asBukkitColor(); - c = color.asBukkitColor(); - - for (ItemType item : items) { + for (ItemType item : this.items.getArray(event)) { ItemMeta meta = item.getItemMeta(); - if (meta instanceof LeatherArmorMeta) { - final LeatherArmorMeta m = (LeatherArmorMeta) meta; - m.setColor(c); - item.setItemMeta(m); - } else if (MAPS_AND_POTIONS_COLORS) { - - if (meta instanceof MapMeta) { - final MapMeta m = (MapMeta) meta; - m.setColor(c); - item.setItemMeta(m); - } else if (meta instanceof PotionMeta) { - final PotionMeta m = (PotionMeta) meta; - m.setColor(c); - item.setItemMeta(m); - } + if (meta instanceof LeatherArmorMeta leatherArmorMeta) { + leatherArmorMeta.setColor(bukkitColor); + item.setItemMeta(leatherArmorMeta); + } else if (meta instanceof MapMeta mapMeta) { + mapMeta.setColor(bukkitColor); + item.setItemMeta(mapMeta); + } else if (meta instanceof PotionMeta potionMeta) { + potionMeta.setColor(bukkitColor); + item.setItemMeta(potionMeta); + } else { + warning("An item passed to the 'color items' effect wasn't colorable, and was thus unaffected."); } } } + + @Override + public Node getNode() { + return node; + } @Override - public String toString(@Nullable Event e, boolean debug) { - return "dye " + items.toString(e, debug) + " " + color.toString(e, debug); + public String toString(@Nullable Event event, boolean debug) { + return "dye " + items.toString(event, debug) + " " + color.toString(event, debug); } + } diff --git a/src/main/java/ch/njol/skript/effects/EffCommand.java b/src/main/java/ch/njol/skript/effects/EffCommand.java index 22f16cbe01a..48bdf2a0631 100644 --- a/src/main/java/ch/njol/skript/effects/EffCommand.java +++ b/src/main/java/ch/njol/skript/effects/EffCommand.java @@ -1,11 +1,5 @@ package ch.njol.skript.effects; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -18,12 +12,16 @@ import ch.njol.skript.util.StringMode; import ch.njol.skript.util.Utils; import ch.njol.util.Kleenean; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; @Name("Command") @Description({ "Executes a command. This can be useful to use other plugins in triggers.", - "If the command is a bungeecord side command, " + - "you can use the [bungeecord] option to execute command on the proxy." + "If the command is a bungeecord side command, you can use the [bungeecord] option to execute command on the proxy." }) @Examples({ "make player execute command \"/home\"", @@ -37,26 +35,20 @@ public class EffCommand extends Effect { static { Skript.registerEffect(EffCommand.class, - "[execute] [the] [bungee:bungee[cord]] command[s] %strings% [by %-commandsenders%]", - "[execute] [the] %commandsenders% [bungee:bungee[cord]] command[s] %strings%", - "(let|make) %commandsenders% execute [[the] [bungee:bungee[cord]] command[s]] %strings%"); + "[execute] [the] [bungee:bungee[cord]] command[s] %strings% [by %-commandsenders%]", + "[execute] [the] %commandsenders% [bungee:bungee[cord]] command[s] %strings%", + "(let|make) %commandsenders% execute [[the] [bungee:bungee[cord]] command[s]] %strings%"); } - @Nullable - private Expression senders; + private @Nullable Expression senders; private Expression commands; private boolean bungeecord; @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { - if (matchedPattern == 0) { - commands = (Expression) exprs[0]; - senders = (Expression) exprs[1]; - } else { - senders = (Expression) exprs[0]; - commands = (Expression) exprs[1]; - } + commands = (Expression) exprs[matchedPattern]; + senders = (Expression) exprs[matchedPattern ^ 1]; bungeecord = parseResult.hasTag("bungee"); if (bungeecord && senders == null) { Skript.error("The commandsenders expression cannot be omitted when using the bungeecord option"); @@ -71,13 +63,12 @@ public void execute(Event event) { for (String command : commands.getArray(event)) { assert command != null; if (command.startsWith("/")) - command = "" + command.substring(1); + command = command.substring(1); if (senders != null) { for (CommandSender sender : senders.getArray(event)) { if (bungeecord) { - if (!(sender instanceof Player)) + if (!(sender instanceof Player player)) continue; - Player player = (Player) sender; Utils.sendPluginMessage(player, EffConnect.BUNGEE_CHANNEL, MESSAGE_CHANNEL, player.getName(), "/" + command); continue; } diff --git a/src/main/java/ch/njol/skript/effects/EffConnect.java b/src/main/java/ch/njol/skript/effects/EffConnect.java index 53b0b20ffcc..84c55090056 100644 --- a/src/main/java/ch/njol/skript/effects/EffConnect.java +++ b/src/main/java/ch/njol/skript/effects/EffConnect.java @@ -1,9 +1,7 @@ package ch.njol.skript.effects; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; - import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -13,7 +11,10 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.util.Utils; import ch.njol.util.Kleenean; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Connect") @Description({ @@ -28,7 +29,7 @@ "transfer player to server \"localhost\" on port 25566" }) @Since("2.3, 2.10 (transfer)") -public class EffConnect extends Effect { +public class EffConnect extends Effect implements SyntaxRuntimeErrorProducer { public static final String BUNGEE_CHANNEL = "BungeeCord"; public static final String GET_SERVERS_CHANNEL = "GetServers"; @@ -37,18 +38,21 @@ public class EffConnect extends Effect { static { Skript.registerEffect(EffConnect.class, - "(send|connect) %players% to [proxy|bungeecord] [server] %string%", - "transfer %players% to server %string% [on port %-number%]" + "(send|connect) %players% to [proxy|bungeecord] [server] %string%", + "transfer %players% to server %string% [on port %-number%]" ); } + private Node node; private Expression players; private Expression server; private Expression port; private boolean transfer; @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); players = (Expression) exprs[0]; server = (Expression) exprs[1]; transfer = matchedPattern == 1; @@ -66,28 +70,31 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override protected void execute(Event event) { String server = this.server.getSingle(event); + if (server == null) { + error("The provided server string was not set.", this.server.toString()); + return; + } + Player[] players = this.players.stream(event) .filter(Player::isOnline) .toArray(Player[]::new); - - if (server == null || players.length == 0) + if (players.length == 0) { + error("There were no valid players passed through.", this.players.toString()); return; + } if (transfer) { + int port = 25565; if (this.port != null) { Number portNum = this.port.getSingle(event); if (portNum == null) { + error("The provided port number was not set.", this.port.toString()); return; } - int port = portNum.intValue(); - for (Player player : players) { - player.transfer(server, port); - } - } else { - int defaultPort = 25565; - for (Player player : players) { - player.transfer(server, defaultPort); - } + port = portNum.intValue(); + } + for (Player player : players) { + player.transfer(server, port); } } else { // the message channel is case-sensitive, so let's fix that @@ -105,6 +112,11 @@ protected void execute(Event event) { } } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { if (transfer) { diff --git a/src/main/java/ch/njol/skript/effects/EffContinue.java b/src/main/java/ch/njol/skript/effects/EffContinue.java index 3c3fb33a407..a79a1470a88 100644 --- a/src/main/java/ch/njol/skript/effects/EffContinue.java +++ b/src/main/java/ch/njol/skript/effects/EffContinue.java @@ -18,15 +18,17 @@ import java.util.List; @Name("Continue") -@Description("Moves the loop to the next iteration. You may also continue an outer loop from an inner one." + - " The loops are labelled from 1 until the current loop, starting with the outermost one.") +@Description({ + "Moves the loop to the next iteration. You may also continue an outer loop from an inner one.", + "The loops are labelled from 1 until the current loop, starting with the outermost one." +}) @Examples({ "# Broadcast online moderators", "loop all players:", "\tif loop-value does not have permission \"moderator\":", "\t\tcontinue # filter out non moderators", "\tbroadcast \"%loop-player% is a moderator!\" # Only moderators get broadcast", - " ", + "", "# Game starting counter", "set {_counter} to 11", "while {_counter} > 0:", @@ -46,12 +48,9 @@ public class EffContinue extends Effect { ); } - // Used for toString - private int level; - private @UnknownNullability LoopSection loop; private @UnknownNullability List sectionsToExit; - private int breakLevels; + private int level, breakLevels; // level used for toString @Override public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { diff --git a/src/main/java/ch/njol/skript/effects/EffCopy.java b/src/main/java/ch/njol/skript/effects/EffCopy.java index c792cf8925f..ba7ea97ebbc 100644 --- a/src/main/java/ch/njol/skript/effects/EffCopy.java +++ b/src/main/java/ch/njol/skript/effects/EffCopy.java @@ -2,11 +2,7 @@ import ch.njol.skript.Skript; import ch.njol.skript.classes.Changer.ChangeMode; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Keywords; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.Since; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ExpressionList; @@ -18,7 +14,11 @@ import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @Name("Copy Into Variable") @Description({ @@ -103,8 +103,7 @@ public String toString(@Nullable Event event, boolean debug) { } @SuppressWarnings("unchecked") - @Nullable - private static Map copyMap(@Nullable Map map) { + private static @Nullable Map copyMap(@Nullable Map map) { if (map == null) return null; Map copy = new HashMap<>(map.size()); diff --git a/src/main/java/ch/njol/skript/effects/EffCustomName.java b/src/main/java/ch/njol/skript/effects/EffCustomName.java index b83b2f9886d..fd9ceaa6d7c 100644 --- a/src/main/java/ch/njol/skript/effects/EffCustomName.java +++ b/src/main/java/ch/njol/skript/effects/EffCustomName.java @@ -32,6 +32,7 @@ public class EffCustomName extends Effect { private Expression entities; @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { showCustomName = parseResult.hasTag("show"); entities = (Expression) exprs[0]; diff --git a/src/main/java/ch/njol/skript/effects/EffDetonate.java b/src/main/java/ch/njol/skript/effects/EffDetonate.java index df374e4b598..9ad123ee382 100644 --- a/src/main/java/ch/njol/skript/effects/EffDetonate.java +++ b/src/main/java/ch/njol/skript/effects/EffDetonate.java @@ -1,14 +1,7 @@ package ch.njol.skript.effects; -import org.bukkit.entity.Entity; -import org.bukkit.entity.WindCharge; -import org.bukkit.entity.minecart.ExplosiveMinecart; -import org.bukkit.entity.Firework; -import org.bukkit.entity.Creeper; -import org.bukkit.entity.TNTPrimed; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -17,12 +10,24 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Firework; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.entity.WindCharge; +import org.bukkit.entity.minecart.ExplosiveMinecart; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Detonate Entities") -@Description("Immediately detonates an entity. Accepted entities are fireworks, TNT minecarts, primed TNT, wind charges and creepers.") +@Description({ + "Immediately detonates an entity.", + "Accepted entities are fireworks, TNT minecarts, primed TNT, wind charges and creepers." +}) @Examples("detonate last launched firework") @Since("2.10") -public class EffDetonate extends Effect { +public class EffDetonate extends Effect implements SyntaxRuntimeErrorProducer { private static final boolean HAS_WINDCHARGE = Skript.classExists("org.bukkit.entity.WindCharge"); @@ -30,11 +35,13 @@ public class EffDetonate extends Effect { Skript.registerEffect(EffDetonate.class, "detonate %entities%"); } + private Node node; private Expression entities; @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); entities = (Expression) exprs[0]; return true; } @@ -52,10 +59,17 @@ protected void execute(Event event) { creeper.explode(); } else if (entity instanceof TNTPrimed tntPrimed) { tntPrimed.setFuseTicks(0); + } else { + warning("An entity passed in wasn't detonate-able, and was thus unaffected.", entities.toString()); } } } + @Override + public Node getNode() { + return node; + } + public String toString(@Nullable Event event, boolean debug) { return "detonate " + entities.toString(event, debug); } diff --git a/src/main/java/ch/njol/skript/effects/EffDoIf.java b/src/main/java/ch/njol/skript/effects/EffDoIf.java index 0b0cc219177..750abf05519 100644 --- a/src/main/java/ch/njol/skript/effects/EffDoIf.java +++ b/src/main/java/ch/njol/skript/effects/EffDoIf.java @@ -1,24 +1,22 @@ package ch.njol.skript.effects; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; -import ch.njol.skript.lang.Condition; -import ch.njol.skript.lang.Effect; -import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.SkriptParser; -import ch.njol.skript.lang.TriggerItem; +import ch.njol.skript.lang.*; +import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; @Name("Do If") @Description("Execute an effect if a condition is true.") -@Examples({"on join:", - "\tgive a diamond to the player if the player has permission \"rank.vip\""}) +@Examples({ + "on join:", + "\tgive a diamond to the player if the player has permission \"rank.vip\"" +}) @Since("2.3") public class EffDoIf extends Effect { @@ -26,15 +24,11 @@ public class EffDoIf extends Effect { Skript.registerEffect(EffDoIf.class, "<.+> if <.+>"); } - @SuppressWarnings("null") private Effect effect; - - @SuppressWarnings("null") private Condition condition; - @SuppressWarnings("null") @Override - public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { String eff = parseResult.regexes.get(0).group(); String cond = parseResult.regexes.get(1).group(); effect = Effect.parse(eff, "Can't understand this effect: " + eff); @@ -47,12 +41,12 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - protected void execute(Event e) {} + protected void execute(Event event) {} @Nullable @Override - public TriggerItem walk(Event e) { - if (condition.check(e)) { + public TriggerItem walk(Event event) { + if (condition.check(event)) { effect.setParent(getParent()); effect.setNext(getNext()); return effect; @@ -61,8 +55,8 @@ public TriggerItem walk(Event e) { } @Override - public String toString(@Nullable Event e, boolean debug) { - return effect.toString(e, debug) + " if " + condition.toString(e, debug); + public String toString(@Nullable Event event, boolean debug) { + return effect.toString(event, debug) + " if " + condition.toString(event, debug); } } \ No newline at end of file diff --git a/src/main/java/ch/njol/skript/effects/EffDrop.java b/src/main/java/ch/njol/skript/effects/EffDrop.java index 29fb211b9ad..78630946117 100644 --- a/src/main/java/ch/njol/skript/effects/EffDrop.java +++ b/src/main/java/ch/njol/skript/effects/EffDrop.java @@ -25,23 +25,21 @@ @Name("Drop") @Description("Drops one or more items.") -@Examples({"on death of creeper:", - " drop 1 TNT"}) +@Examples({ + "on death of creeper:", + "\tdrop 1 TNT" +}) @Since("1.0") public class EffDrop extends Effect { static { - Skript.registerEffect(EffDrop.class, "drop %itemtypes/experiences% [%directions% %locations%] [(1¦without velocity)]"); + Skript.registerEffect(EffDrop.class, "drop %itemtypes/experiences% [%directions% %locations%] [(1:without velocity)]"); } - @Nullable - public static Entity lastSpawned = null; + public static @Nullable Entity lastSpawned = null; - @SuppressWarnings("NotNullFieldNotInitialized") private Expression drops; - @SuppressWarnings("NotNullFieldNotInitialized") private Expression locations; - private boolean useVelocity; @Override @@ -54,25 +52,25 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - public void execute(Event e) { - Object[] os = drops.getArray(e); - for (Location l : locations.getArray(e)) { - Location itemDropLoc = l.clone().subtract(0.5, 0.5, 0.5); // dropItemNaturally adds 0.15 to 0.85 randomly to all coordinates - for (Object o : os) { - if (o instanceof Experience) { - ExperienceOrb orb = l.getWorld().spawn(l, ExperienceOrb.class); - orb.setExperience(((Experience) o).getXP() + orb.getExperience()); // ensure we maintain previous experience, due to spigot xp merging behavior + public void execute(Event event) { + Object[] drops = this.drops.getArray(event); + for (Location loc : locations.getArray(event)) { + Location itemDropLoc = loc.clone().subtract(0.5, 0.5, 0.5); // dropItemNaturally adds 0.15 to 0.85 randomly to all coordinates + for (Object drop : drops) { + if (drop instanceof Experience experience) { + ExperienceOrb orb = loc.getWorld().spawn(loc, ExperienceOrb.class); + orb.setExperience(experience.getXP() + orb.getExperience()); // ensure we maintain previous experience, due to spigot xp merging behavior EffSecSpawn.lastSpawned = orb; } else { - if (o instanceof ItemStack) - o = new ItemType((ItemStack) o); - for (ItemStack is : ((ItemType) o).getItem().getAll()) { - if (!ItemUtils.isAir(is.getType()) && is.getAmount() > 0) { + if (drop instanceof ItemStack iS) + drop = new ItemType(iS); + for (ItemStack itemStack : ((ItemType) drop).getItem().getAll()) { + if (!ItemUtils.isAir(itemStack.getType()) && itemStack.getAmount() > 0) { if (useVelocity) { - lastSpawned = l.getWorld().dropItemNaturally(itemDropLoc, is); + lastSpawned = loc.getWorld().dropItemNaturally(itemDropLoc, itemStack); } else { - Item item = l.getWorld().dropItem(l, is); - item.teleport(l); + Item item = loc.getWorld().dropItem(loc, itemStack); + item.teleport(loc); item.setVelocity(new Vector(0, 0, 0)); lastSpawned = item; } @@ -84,8 +82,8 @@ public void execute(Event e) { } @Override - public String toString(@Nullable Event e, boolean debug) { - return "drop " + drops.toString(e, debug) + " " + locations.toString(e, debug); + public String toString(@Nullable Event event, boolean debug) { + return "drop " + drops.toString(event, debug) + " " + locations.toString(event, debug); } } diff --git a/src/main/java/ch/njol/skript/effects/EffDropLeash.java b/src/main/java/ch/njol/skript/effects/EffDropLeash.java index a57a7dafc22..b4f9816566c 100644 --- a/src/main/java/ch/njol/skript/effects/EffDropLeash.java +++ b/src/main/java/ch/njol/skript/effects/EffDropLeash.java @@ -1,15 +1,16 @@ package ch.njol.skript.effects; -import org.bukkit.event.Event; -import org.bukkit.event.entity.EntityUnleashEvent; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser; import ch.njol.util.Kleenean; +import org.bukkit.event.Event; +import org.bukkit.event.entity.EntityUnleashEvent; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Allow / Prevent Leash Drop") @Description("Allows or prevents the leash from being dropped in an unleash event.") @@ -23,15 +24,15 @@ @Keywords("lead") @Events("Unleash") @Since("2.10") -public class EffDropLeash extends Effect { +public class EffDropLeash extends Effect implements SyntaxRuntimeErrorProducer { static { - Skript.registerEffect(EffDropLeash.class, - "(force|allow) [the] (lead|leash) [item] to drop", - "(block|disallow|prevent) [the] (lead|leash) [item] from dropping" - ); + Skript.registerEffect(EffDropLeash.class, + "(force|allow) [the] (lead|leash) [item] to drop", + "(block|disallow|prevent) [the] (lead|leash) [item] from dropping"); } + private Node node; private boolean allowLeashDrop; @Override @@ -40,17 +41,26 @@ public boolean init(Expression[] expressions, int matchedPattern, Kleenean is Skript.error("The 'drop leash' effect can only be used in an 'unleash' event"); return false; } + node = getParser().getNode(); allowLeashDrop = matchedPattern == 0; return true; } @Override protected void execute(Event event) { - if (!(event instanceof EntityUnleashEvent unleashEvent)) + if (!(event instanceof EntityUnleashEvent unleashEvent)) { + error("The 'drop leash' effect can only be used in an 'unleash' event."); return; + } + unleashEvent.setDropLeash(allowLeashDrop); } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { return allowLeashDrop ? "allow the leash to drop" : "prevent the leash from dropping"; diff --git a/src/main/java/ch/njol/skript/effects/EffElytraBoostConsume.java b/src/main/java/ch/njol/skript/effects/EffElytraBoostConsume.java index 39b697e4646..c282a4cb63a 100644 --- a/src/main/java/ch/njol/skript/effects/EffElytraBoostConsume.java +++ b/src/main/java/ch/njol/skript/effects/EffElytraBoostConsume.java @@ -1,6 +1,7 @@ package ch.njol.skript.effects; import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; @@ -9,9 +10,10 @@ import com.destroystokyo.paper.event.player.PlayerElytraBoostEvent; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Consume Boosting Firework") -@Description("Prevent the firework used in an 'elytra boost' event to be consumed.") +@Description("Prevent the firework used in an 'elytra boost' event from being consumed.") @Examples({ "on elytra boost:", "\tif the used firework will be consumed:", @@ -19,7 +21,7 @@ }) @RequiredPlugins("Paper") @Since("2.10") -public class EffElytraBoostConsume extends Effect { +public class EffElytraBoostConsume extends Effect implements SyntaxRuntimeErrorProducer { static { if (Skript.classExists("com.destroystokyo.paper.event.player.PlayerElytraBoostEvent")) { @@ -29,6 +31,7 @@ public class EffElytraBoostConsume extends Effect { } } + private Node node; private boolean consume; @Override @@ -37,17 +40,26 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye Skript.error("This effect can only be used in an 'elytra boost' event."); return false; } + node = getParser().getNode(); consume = matchedPattern == 1; return true; } @Override protected void execute(Event event) { - if (!(event instanceof PlayerElytraBoostEvent boostEvent)) + if (!(event instanceof PlayerElytraBoostEvent boostEvent)){ + error("The 'elytra boost consume' effect can only be used in an 'elytra boost' event."); return; + } + boostEvent.setShouldConsume(consume); } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { if (consume) diff --git a/src/main/java/ch/njol/skript/effects/EffEnchant.java b/src/main/java/ch/njol/skript/effects/EffEnchant.java index 8f41e27c5d0..564f5579ce6 100644 --- a/src/main/java/ch/njol/skript/effects/EffEnchant.java +++ b/src/main/java/ch/njol/skript/effects/EffEnchant.java @@ -4,6 +4,7 @@ import ch.njol.skript.aliases.ItemType; import ch.njol.skript.classes.Changer.ChangeMode; import ch.njol.skript.classes.Changer.ChangerUtils; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -16,32 +17,32 @@ import org.bukkit.event.Event; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; import java.util.function.Function; -/** - * @author Peter Güttinger - */ @Name("Enchant/Disenchant") @Description("Enchant or disenchant an existing item.") -@Examples({"enchant the player's tool with sharpness 5", - "disenchant the player's tool"}) +@Examples({ + "enchant the player's tool with sharpness 5", + "disenchant the player's tool" +}) @Since("2.0") -public class EffEnchant extends Effect { +public class EffEnchant extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffEnchant.class, - "enchant %~itemtypes% with %enchantmenttypes%", - "disenchant %~itemtypes%"); + "enchant %~itemtypes% with %enchantmenttypes%", + "disenchant %~itemtypes%"); } - - @SuppressWarnings("null") + + private Node node; private Expression items; - @Nullable - private Expression enchantments; + private @Nullable Expression enchantments; @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); items = (Expression) exprs[0]; if (!ChangerUtils.acceptsChange(items, ChangeMode.SET, ItemStack.class)) { Skript.error(items + " cannot be changed, thus it cannot be (dis)enchanted"); @@ -58,8 +59,10 @@ protected void execute(Event event) { if (enchantments != null) { EnchantmentType[] types = enchantments.getArray(event); - if (types.length == 0) + if (types.length == 0) { + error("There were no enchantments passed through.", enchantments.toString()); return; + } changeFunction = item -> { item.addEnchantments(types); return item; @@ -74,9 +77,14 @@ protected void execute(Event event) { this.items.changeInPlace(event, changeFunction); } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { return enchantments == null ? "disenchant " + items.toString(event, debug) : "enchant " + items.toString(event, debug) + " with " + enchantments; } - + } diff --git a/src/main/java/ch/njol/skript/effects/EffEnforceWhitelist.java b/src/main/java/ch/njol/skript/effects/EffEnforceWhitelist.java index 7b5b2cca22d..769c6e8334c 100644 --- a/src/main/java/ch/njol/skript/effects/EffEnforceWhitelist.java +++ b/src/main/java/ch/njol/skript/effects/EffEnforceWhitelist.java @@ -1,5 +1,12 @@ package ch.njol.skript.effects; +import ch.njol.skript.Skript; +import ch.njol.skript.doc.*; +import ch.njol.skript.lang.Effect; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.util.Utils; +import ch.njol.util.Kleenean; import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -8,18 +15,6 @@ import java.io.File; -import ch.njol.skript.Skript; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Since; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.lang.Effect; -import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.SkriptParser.ParseResult; -import ch.njol.skript.util.Utils; -import ch.njol.util.Kleenean; - @Name("Enforce Whitelist") @Description({ "Enforces or un-enforce a server's whitelist.", @@ -30,19 +25,17 @@ "unenforce the whitelist" }) @Since("2.9.0") -@RequiredPlugins("MC 1.17+") +@RequiredPlugins("Minecraft 1.17+") public class EffEnforceWhitelist extends Effect { private static String NOT_WHITELISTED_MESSAGE = "You are not whitelisted on this server!"; static { - if (Skript.methodExists(Bukkit.class, "setWhitelistEnforced", boolean.class)) { - try { - YamlConfiguration spigotYml = YamlConfiguration.loadConfiguration(new File("spigot.yml")); - NOT_WHITELISTED_MESSAGE = spigotYml.getString("messages.whitelist", NOT_WHITELISTED_MESSAGE); - } catch (Exception ignored) {} - Skript.registerEffect(EffEnforceWhitelist.class, "[:un]enforce [the] [server] white[ ]list"); - } + try { + YamlConfiguration spigotYml = YamlConfiguration.loadConfiguration(new File("spigot.yml")); + NOT_WHITELISTED_MESSAGE = spigotYml.getString("messages.whitelist", NOT_WHITELISTED_MESSAGE); + } catch (Exception ignored) {} + Skript.registerEffect(EffEnforceWhitelist.class, "[:un]enforce [the] [server] white[ ]list"); } private boolean enforce; @@ -71,7 +64,7 @@ public static void reloadWhitelist() { } @Override - public String toString(@Nullable Event e, boolean debug) { + public String toString(@Nullable Event event, boolean debug) { return (!enforce ? "un" : "") + "enforce the whitelist"; } diff --git a/src/main/java/ch/njol/skript/effects/EffEntityVisibility.java b/src/main/java/ch/njol/skript/effects/EffEntityVisibility.java index 7352204d24c..49d6ea9228f 100644 --- a/src/main/java/ch/njol/skript/effects/EffEntityVisibility.java +++ b/src/main/java/ch/njol/skript/effects/EffEntityVisibility.java @@ -38,16 +38,14 @@ public class EffEntityVisibility extends Effect { static { Skript.registerEffect(EffEntityVisibility.class, - "hide %entities% [(from|for) %-players%]", - "reveal %entities% [(to|for|from) %-players%]"); + "hide %entities% [(from|for) %-players%]", + "reveal %entities% [(to|for|from) %-players%]"); } private boolean reveal; - @UnknownNullability - private Expression hidden; - @UnknownNullability - private Expression viewers; + private @UnknownNullability Expression hidden; + private @UnknownNullability Expression viewers; @Override @SuppressWarnings("unchecked") diff --git a/src/main/java/ch/njol/skript/effects/EffEquip.java b/src/main/java/ch/njol/skript/effects/EffEquip.java index 04baeed397a..0f523cd0cff 100644 --- a/src/main/java/ch/njol/skript/effects/EffEquip.java +++ b/src/main/java/ch/njol/skript/effects/EffEquip.java @@ -1,7 +1,6 @@ package ch.njol.skript.effects; import ch.njol.skript.Skript; -import ch.njol.skript.aliases.ItemData; import ch.njol.skript.aliases.ItemType; import ch.njol.skript.bukkitutil.PlayerUtils; import ch.njol.skript.doc.Description; @@ -14,21 +13,9 @@ import ch.njol.util.Kleenean; import org.bukkit.Material; import org.bukkit.Tag; -import org.bukkit.entity.AbstractHorse; -import org.bukkit.entity.ChestedHorse; -import org.bukkit.entity.Horse; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Llama; -import org.bukkit.entity.Player; -import org.bukkit.entity.Steerable; -import org.bukkit.entity.Wolf; +import org.bukkit.entity.*; import org.bukkit.event.Event; -import org.bukkit.inventory.AbstractHorseInventory; -import org.bukkit.inventory.EntityEquipment; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.inventory.HorseInventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.LlamaInventory; +import org.bukkit.inventory.*; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnknownNullability; @@ -72,7 +59,7 @@ public class EffEquip extends Effect { Material.GOLDEN_CHESTPLATE, Material.IRON_CHESTPLATE, Material.DIAMOND_CHESTPLATE, - Material.NETHERITE_CHESTPLATE, + Material.NETHERITE_CHESTPLATE, Material.ELYTRA ); @@ -82,7 +69,7 @@ public class EffEquip extends Effect { Material.GOLDEN_LEGGINGS, Material.IRON_LEGGINGS, Material.DIAMOND_LEGGINGS, - Material.NETHERITE_LEGGINGS + Material.NETHERITE_LEGGINGS ); BOOTS = new ItemType( @@ -91,7 +78,7 @@ public class EffEquip extends Effect { Material.GOLDEN_BOOTS, Material.IRON_BOOTS, Material.DIAMOND_BOOTS, - Material.NETHERITE_BOOTS + Material.NETHERITE_BOOTS ); } } @@ -100,16 +87,14 @@ public class EffEquip extends Effect { static { Skript.registerEffect(EffEquip.class, - "equip [%livingentities%] with %itemtypes%", - "make %livingentities% wear %itemtypes%", - "unequip %itemtypes% [from %livingentities%]", - "unequip %livingentities%'[s] (armo[u]r|equipment)"); + "equip [%livingentities%] with %itemtypes%", + "make %livingentities% wear %itemtypes%", + "unequip %itemtypes% [from %livingentities%]", + "unequip %livingentities%'[s] (armo[u]r|equipment)"); } - @SuppressWarnings("NotNullFieldNotInitialized") private Expression entities; private @UnknownNullability Expression itemTypes; - private boolean equip = true; @Override diff --git a/src/main/java/ch/njol/skript/effects/EffExceptionDebug.java b/src/main/java/ch/njol/skript/effects/EffExceptionDebug.java index af2f6480ca7..8e653660a46 100644 --- a/src/main/java/ch/njol/skript/effects/EffExceptionDebug.java +++ b/src/main/java/ch/njol/skript/effects/EffExceptionDebug.java @@ -1,14 +1,13 @@ package ch.njol.skript.effects; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.doc.NoDoc; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; @NoDoc public class EffExceptionDebug extends Effect { @@ -24,12 +23,12 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override - protected void execute(Event e) { + protected void execute(Event event) { Skript.exception("Created by a script (debugging)..."); } @Override - public String toString(@Nullable Event e, boolean debug) { + public String toString(@Nullable Event event, boolean debug) { return "cause exception"; } diff --git a/src/main/java/ch/njol/skript/effects/EffExplodeCreeper.java b/src/main/java/ch/njol/skript/effects/EffExplodeCreeper.java index c9937916d14..5879bd47d79 100644 --- a/src/main/java/ch/njol/skript/effects/EffExplodeCreeper.java +++ b/src/main/java/ch/njol/skript/effects/EffExplodeCreeper.java @@ -1,47 +1,40 @@ package ch.njol.skript.effects; -import org.bukkit.entity.Creeper; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.log.ErrorQuality; import ch.njol.util.Kleenean; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; @Name("Explode Creeper") @Description("Starts the explosion process of a creeper or instantly explodes it.") -@Examples({"start explosion of the last spawned creeper", - "stop ignition of the last spawned creeper"}) +@Examples({ + "start explosion of the last spawned creeper", + "stop ignition of the last spawned creeper" +}) @Since("2.5") -@RequiredPlugins("Paper 1.13 or newer/Spigot 1.14 or newer. Ignition can be stopped on Paper 1.13 or newer.") +@RequiredPlugins("Paper 1.13+/Spigot 1.14+, Paper 1.13+ for stopping ignition") public class EffExplodeCreeper extends Effect { static { if (Skript.methodExists(Creeper.class, "explode")) { Skript.registerEffect(EffExplodeCreeper.class, - "instantly explode [creeper[s]] %livingentities%", - "explode [creeper[s]] %livingentities% instantly", - "ignite creeper[s] %livingentities%", - "start (ignition|explosion) [process] of [creeper[s]] %livingentities%", - "stop (ignition|explosion) [process] of [creeper[s]] %livingentities%"); + "instantly explode [creeper[s]] %livingentities%", + "explode [creeper[s]] %livingentities% instantly", + "ignite creeper[s] %livingentities%", + "start (ignition|explosion) [process] of [creeper[s]] %livingentities%", + "stop (ignition|explosion) [process] of [creeper[s]] %livingentities%"); } } - @SuppressWarnings("null") private Expression entities; - - private boolean instant; - - private boolean stop; + private boolean instant, stop; /* * setIgnited() was added in Paper 1.13 @@ -50,9 +43,9 @@ public class EffExplodeCreeper extends Effect { */ private final boolean paper = Skript.methodExists(Creeper.class, "setIgnited", boolean.class); - @SuppressWarnings({"unchecked", "null"}) @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { if (matchedPattern == 4) { if (!paper) { Skript.error("Stopping the ignition process is only possible on Paper 1.13+", ErrorQuality.SEMANTIC_ERROR); @@ -66,18 +59,18 @@ public boolean init(final Expression[] exprs, final int matchedPattern, final } @Override - protected void execute(final Event e) { - for (final LivingEntity le : entities.getArray(e)) { - if (le instanceof Creeper) { + protected void execute(Event event) { + for (LivingEntity entity : entities.getArray(event)) { + if (entity instanceof Creeper creeper) { if (instant) { - ((Creeper) le).explode(); + creeper.explode(); } else if (stop) { - ((Creeper) le).setIgnited(false); + creeper.setIgnited(false); } else { if (paper) { - ((Creeper) le).setIgnited(true); + creeper.setIgnited(true); } else { - ((Creeper) le).ignite(); + creeper.ignite(); } } } @@ -85,8 +78,8 @@ protected void execute(final Event e) { } @Override - public String toString(final @Nullable Event e, final boolean debug) { - return (instant == true ? "instantly explode " : "start the explosion process of ") + entities.toString(e, debug); + public String toString(@Nullable Event event, boolean debug) { + return (instant ? "instantly explode " : "start the explosion process of ") + entities.toString(event, debug); } } diff --git a/src/main/java/ch/njol/skript/effects/EffExplosion.java b/src/main/java/ch/njol/skript/effects/EffExplosion.java index 93c413aa47d..f253b550a01 100644 --- a/src/main/java/ch/njol/skript/effects/EffExplosion.java +++ b/src/main/java/ch/njol/skript/effects/EffExplosion.java @@ -1,10 +1,7 @@ package ch.njol.skript.effects; -import org.bukkit.Location; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -14,40 +11,42 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.util.Direction; import ch.njol.util.Kleenean; +import org.bukkit.Location; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; -/** - * @author Peter Güttinger - */ @Name("Explosion") -@Description({"Creates an explosion of a given force. The Minecraft Wiki has an article on explosions " + - "which lists the explosion forces of TNT, creepers, etc.", - "Hint: use a force of 0 to create a fake explosion that does no damage whatsoever, or use the explosion effect introduced in Skript 2.0.", - "Starting with Bukkit 1.4.5 and Skript 2.0 you can use safe explosions which will damage entities but won't destroy any blocks."}) -@Examples({"create an explosion of force 10 at the player", - "create an explosion of force 0 at the victim"}) +@Description({ + "Creates an explosion of a given force. The Minecraft Wiki has an article on explosions " + + "which lists the explosion forces of TNT, creepers, etc.", + "Hint: use a force of 0 to create a fake explosion that does no damage whatsoever, or use the explosion effect introduced in Skript 2.0.", + "Starting with Bukkit 1.4.5 and Skript 2.0 you can use safe explosions which will damage entities but won't destroy any blocks." +}) +@Examples({ + "create an explosion of force 10 at the player", + "create an explosion of force 0 at the victim" +}) @Since("1.0") -public class EffExplosion extends Effect { +public class EffExplosion extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffExplosion.class, - "[(create|make)] [an] explosion (of|with) (force|strength|power) %number% [%directions% %locations%] [(1¦with fire)]", - "[(create|make)] [a] safe explosion (of|with) (force|strength|power) %number% [%directions% %locations%]", - "[(create|make)] [a] fake explosion [%directions% %locations%]", - "[(create|make)] [an] explosion[ ]effect [%directions% %locations%]"); + "[(create|make)] [an] explosion (of|with) (force|strength|power) %number% [%directions% %locations%] [(1¦with fire)]", + "[(create|make)] [a] safe explosion (of|with) (force|strength|power) %number% [%directions% %locations%]", + "[(create|make)] [a] fake explosion [%directions% %locations%]", + "[(create|make)] [an] explosion[ ]effect [%directions% %locations%]"); } - @Nullable - private Expression force; - @SuppressWarnings("null") + private Node node; + private @Nullable Expression force; private Expression locations; + private boolean blockDamage, setFire; - private boolean blockDamage; - - private boolean setFire; - - @SuppressWarnings({"unchecked", "null"}) @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parser) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parser) { + node = getParser().getNode(); force = matchedPattern <= 1 ? (Expression) exprs[0] : null; blockDamage = matchedPattern != 1; setFire = parser.mark == 1; @@ -56,26 +55,38 @@ public boolean init(final Expression[] exprs, final int matchedPattern, final } @Override - public void execute(final Event e) { - final Number power = force != null ? force.getSingle(e) : 0; - if (power == null) - return; - for (Location location : locations.getArray(e)) { - if (location.getWorld() == null) + public void execute(Event event) { + float power = 0; + if (force != null) { + Number force = this.force.getSingle(event); + if (force == null) { + error("The provided force was not set.", this.force.toString()); + return; + } + power = force.floatValue(); + } + for (Location location : locations.getArray(event)) { + if (location.getWorld() == null) { + warning("One of the locations didn't have a world, and was skipped.", locations.toString()); continue; + } if (!blockDamage) - location.getWorld().createExplosion(location.getX(), location.getY(), location.getZ(), power.floatValue(), false, false); + location.getWorld().createExplosion(location.getX(), location.getY(), location.getZ(), power, false, false); else - location.getWorld().createExplosion(location, power.floatValue(), setFire); + location.getWorld().createExplosion(location, power, setFire); } } @Override - public String toString(final @Nullable Event e, final boolean debug) { + public Node getNode() { + return node; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { if (force != null) - return "create explosion of force " + force.toString(e, debug) + " " + locations.toString(e, debug); - else - return "create explosion effect " + locations.toString(e, debug); + return "create explosion of force " + force.toString(event, debug) + " " + locations.toString(event, debug); + return "create explosion effect " + locations.toString(event, debug); } } diff --git a/src/main/java/ch/njol/skript/effects/EffFeed.java b/src/main/java/ch/njol/skript/effects/EffFeed.java index 4ca51be1bbd..7a83b57ce20 100644 --- a/src/main/java/ch/njol/skript/effects/EffFeed.java +++ b/src/main/java/ch/njol/skript/effects/EffFeed.java @@ -1,59 +1,68 @@ package ch.njol.skript.effects; import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.SkriptParser; +import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; import org.bukkit.entity.Player; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Feed") @Description("Feeds the specified players.") @Examples({"feed all players", "feed the player by 5 beefs"}) @Since("2.2-dev34") -public class EffFeed extends Effect { +public class EffFeed extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffFeed.class, "feed [the] %players% [by %-number% [beef[s]]]"); } - @SuppressWarnings("null") + private Node node; private Expression players; - @Nullable - private Expression beefs; + private @Nullable Expression beefs; @Override - public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); players = (Expression) exprs[0]; beefs = (Expression) exprs[1]; return true; } @Override - protected void execute(Event e) { + protected void execute(Event event) { int level = 20; - if (beefs != null) { - Number n = beefs.getSingle(e); - if (n == null) - return; - level = n.intValue(); + Number beefs = this.beefs.getSingle(event); + if (beefs == null) { + error("The provided amount was not set.", this.beefs.toString()); + return; + } + level = beefs.intValue(); } - for (Player player : players.getArray(e)) { + + for (Player player : players.getArray(event)) { player.setFoodLevel(player.getFoodLevel() + level); } } + @Override + public Node getNode() { + return node; + } + @Override - public String toString(@Nullable Event e, boolean debug) { - return "feed " + players.toString(e, debug) + (beefs != null ? " by " + beefs.toString(e, debug) : ""); + public String toString(@Nullable Event event, boolean debug) { + return "feed " + players.toString(event, debug) + (beefs != null ? " by " + beefs.toString(event, debug) : ""); } - } diff --git a/src/main/java/ch/njol/skript/effects/EffFireResistant.java b/src/main/java/ch/njol/skript/effects/EffFireResistant.java index 26560eb1699..4b11ce0afbb 100644 --- a/src/main/java/ch/njol/skript/effects/EffFireResistant.java +++ b/src/main/java/ch/njol/skript/effects/EffFireResistant.java @@ -2,11 +2,7 @@ import ch.njol.skript.Skript; import ch.njol.skript.aliases.ItemType; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; @@ -30,7 +26,6 @@ public class EffFireResistant extends Effect { Skript.registerEffect(EffFireResistant.class, "make %itemtypes% [:not] (fire resistant|resistant to fire)"); } - @SuppressWarnings("NotNullFieldNotInitialized") private Expression items; private boolean not; diff --git a/src/main/java/ch/njol/skript/effects/EffFireworkLaunch.java b/src/main/java/ch/njol/skript/effects/EffFireworkLaunch.java index 1f44850104a..654a1a6c78c 100644 --- a/src/main/java/ch/njol/skript/effects/EffFireworkLaunch.java +++ b/src/main/java/ch/njol/skript/effects/EffFireworkLaunch.java @@ -1,15 +1,7 @@ package ch.njol.skript.effects; -import org.bukkit.FireworkEffect; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Firework; -import org.bukkit.event.Event; -import org.bukkit.inventory.meta.FireworkMeta; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -17,31 +9,41 @@ import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.SyntaxStringBuilder; import ch.njol.util.Kleenean; +import ch.njol.util.Math2; +import org.bukkit.FireworkEffect; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Firework; +import org.bukkit.event.Event; +import org.bukkit.inventory.meta.FireworkMeta; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Launch firework") @Description("Launch firework effects at the given location(s).") @Examples("launch ball large colored red, purple and white fading to light green and black at player's location with duration 1") @Since("2.4") -public class EffFireworkLaunch extends Effect { +public class EffFireworkLaunch extends Effect implements SyntaxRuntimeErrorProducer { static { - Skript.registerEffect(EffFireworkLaunch.class, "(launch|deploy) [[a] firework [with effect[s]]] %fireworkeffects% at %locations% [([with] (duration|power)|timed) %number%]"); + Skript.registerEffect(EffFireworkLaunch.class, + "(launch|deploy) [[a] firework [with effect[s]]] %fireworkeffects% at %locations% [([with] (duration|power)|timed) %number%]"); } - @Nullable - public static Entity lastSpawned = null; + public static @Nullable Entity lastSpawned = null; - @SuppressWarnings("NotNullFieldNotInitialized") + private Node node; private Expression effects; - @SuppressWarnings("NotNullFieldNotInitialized") private Expression locations; - @SuppressWarnings("NotNullFieldNotInitialized") private Expression lifetime; @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); effects = (Expression) exprs[0]; locations = (Expression) exprs[1]; lifetime = (Expression) exprs[2]; @@ -51,12 +53,23 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override protected void execute(Event event) { FireworkEffect[] effects = this.effects.getArray(event); - int power = lifetime.getOptionalSingle(event).orElse(1).intValue(); - power = Math.min(127, Math.max(0, power)); + int power = 1; + if (lifetime != null) { + Number lifetime = this.lifetime.getSingle(event); + if (lifetime == null) { + warning("The provided duration was not set, so defaulted to 1.", this.lifetime.toString()); + } else { + power = lifetime.intValue(); + } + } + power = Math2.fit(0, power, 127); + for (Location location : locations.getArray(event)) { World world = location.getWorld(); - if (world == null) + if (world == null) { + warning("One of the locations didn't have a world, and was skipped.", locations.toString()); continue; + } Firework firework = world.spawn(location, Firework.class); FireworkMeta meta = firework.getFireworkMeta(); meta.addEffects(effects); @@ -65,12 +78,17 @@ protected void execute(Event event) { lastSpawned = firework; } } + + @Override + public Node getNode() { + return node; + } @Override public String toString(@Nullable Event event, boolean debug) { - return "Launch firework(s) " + effects.toString(event, debug) + - " at location(s) " + locations.toString(event, debug) + - " timed " + lifetime.toString(event, debug); + return new SyntaxStringBuilder(event, debug) + .append("launch firework(s)", effects, "at location(s)", locations, "timed", lifetime) + .toString(); } } diff --git a/src/main/java/ch/njol/skript/effects/EffForceAttack.java b/src/main/java/ch/njol/skript/effects/EffForceAttack.java index dc8f19cc02a..28f5538b6dd 100644 --- a/src/main/java/ch/njol/skript/effects/EffForceAttack.java +++ b/src/main/java/ch/njol/skript/effects/EffForceAttack.java @@ -1,28 +1,27 @@ package ch.njol.skript.effects; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.config.Node; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Force Attack") @Description("Makes a living entity attack an entity with a melee attack.") -@Examples({"spawn a wolf at player's location", - "make last spawned wolf attack player"}) +@Examples({ + "spawn a wolf at player's location", + "make last spawned wolf attack player" +}) @Since("2.5.1") @RequiredPlugins("Minecraft 1.15.2+") -public class EffForceAttack extends Effect { +public class EffForceAttack extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffForceAttack.class, @@ -31,37 +30,45 @@ public class EffForceAttack extends Effect { } private static final boolean ATTACK_IS_SUPPORTED = Skript.methodExists(LivingEntity.class, "attack", Entity.class); - - @SuppressWarnings("null") + + private Node node; private Expression entities; - @SuppressWarnings("null") private Expression target; - - @SuppressWarnings("unchecked") + @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { if (!ATTACK_IS_SUPPORTED) { - Skript.error("The force attack effect requires Minecraft 1.15.2 or newer"); + Skript.error("The force attack effect requires Minecraft 1.15.2+"); return false; } + node = getParser().getNode(); entities = (Expression) exprs[0]; target = (Expression) exprs[1]; return true; } @Override - protected void execute(Event e) { - Entity target = this.target.getSingle(e); - if (target != null) { - for (LivingEntity entity : entities.getArray(e)) { - entity.attack(target); - } + protected void execute(Event event) { + Entity target = this.target.getSingle(event); + if (target == null) { + error("The provided target entity was not set.", this.target.toString()); + return; + } + + for (LivingEntity entity : entities.getArray(event)) { + entity.attack(target); } } - + @Override - public String toString(@Nullable Event e, boolean debug) { - return "make " + entities.toString(e, debug) + " attack " + target.toString(e, debug); + public Node getNode() { + return node; } + @Override + public String toString(@Nullable Event event, boolean debug) { + return "make " + entities.toString(event, debug) + " attack " + target.toString(event, debug); + } + } diff --git a/src/main/java/ch/njol/skript/effects/EffForceEnchantmentGlint.java b/src/main/java/ch/njol/skript/effects/EffForceEnchantmentGlint.java index 24f14e6ac7c..1b0244cf472 100644 --- a/src/main/java/ch/njol/skript/effects/EffForceEnchantmentGlint.java +++ b/src/main/java/ch/njol/skript/effects/EffForceEnchantmentGlint.java @@ -1,9 +1,5 @@ package ch.njol.skript.effects; -import org.bukkit.event.Event; -import org.bukkit.inventory.meta.ItemMeta; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.aliases.ItemType; import ch.njol.skript.doc.*; @@ -11,6 +7,9 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.event.Event; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.Nullable; @Name("Force Enchantment Glint") @Description("Forces the items to glint or not, or removes its existing enchantment glint enforcement.") @@ -25,10 +24,10 @@ public class EffForceEnchantmentGlint extends Effect { static { if (Skript.methodExists(ItemMeta.class, "setEnchantmentGlintOverride", Boolean.class)) Skript.registerEffect(EffForceEnchantmentGlint.class, - "(force|make) %itemtypes% [to] [start] glint[ing]", - "(force|make) %itemtypes% [to] (not|stop) glint[ing]", - "(clear|delete|reset) [the] enchantment glint override of %itemtypes%", - "(clear|delete|reset) %itemtypes%'s enchantment glint override"); + "(force|make) %itemtypes% [to] [start] glint[ing]", + "(force|make) %itemtypes% [to] (not|stop) glint[ing]", + "(clear|delete|reset) [the] enchantment glint override of %itemtypes%", + "(clear|delete|reset) %itemtypes%'s enchantment glint override"); } private Expression itemTypes; @@ -46,17 +45,11 @@ public boolean init(Expression[] expressions, int matchedPattern, Kleenean is protected void execute(Event event) { for (ItemType itemType : itemTypes.getArray(event)) { ItemMeta meta = itemType.getItemMeta(); - Boolean glint; - if (pattern == 0) { - // Pattern: forced to glint - glint = true; - } else if (pattern == 1) { - // Pattern: forced to not glint - glint = false; - } else { - // Pattern: Clear glint override - glint = null; - } + Boolean glint = switch (pattern) { + case 0 -> true; + case 1 -> false; + default -> null; + }; meta.setEnchantmentGlintOverride(glint); itemType.setItemMeta(meta); } diff --git a/src/main/java/ch/njol/skript/effects/EffGlowingText.java b/src/main/java/ch/njol/skript/effects/EffGlowingText.java index 8cd0b84da86..3c92f7104ce 100644 --- a/src/main/java/ch/njol/skript/effects/EffGlowingText.java +++ b/src/main/java/ch/njol/skript/effects/EffGlowingText.java @@ -10,7 +10,6 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; - import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; @@ -28,15 +27,13 @@ public class EffGlowingText extends Effect { static { if (Skript.methodExists(Sign.class, "setGlowingText", boolean.class)) { Skript.registerEffect(EffGlowingText.class, - "make %blocks/itemtypes% have glowing text", - "make %blocks/itemtypes% have (normal|non[-| ]glowing) text" + "make %blocks/itemtypes% have glowing text", + "make %blocks/itemtypes% have (normal|non[-| ]glowing) text" ); } } - @SuppressWarnings("NotNullFieldNotInitialized") private Expression objects; - private boolean glowing; @Override @@ -49,25 +46,23 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override protected void execute(Event event) { for (Object obj : objects.getArray(event)) { - if (obj instanceof Block) { - BlockState state = ((Block) obj).getState(); - if (state instanceof Sign) { - ((Sign) state).setGlowingText(glowing); + if (obj instanceof Block block) { + BlockState state = block.getState(); + if (state instanceof Sign sign) { + sign.setGlowingText(glowing); state.update(); } - } else if (obj instanceof ItemType) { - ItemType item = (ItemType) obj; - ItemMeta meta = item.getItemMeta(); - if (!(meta instanceof BlockStateMeta)) - return; - BlockStateMeta blockMeta = (BlockStateMeta) meta; + } else if (obj instanceof ItemType itemType) { + ItemMeta meta = itemType.getItemMeta(); + if (!(meta instanceof BlockStateMeta blockMeta)) + return; // this looks like it should continue instead of return BlockState state = blockMeta.getBlockState(); - if (!(state instanceof Sign)) - return; - ((Sign) state).setGlowingText(glowing); + if (!(state instanceof Sign sign)) + return; // same here + sign.setGlowingText(glowing); state.update(); blockMeta.setBlockState(state); - item.setItemMeta(meta); + itemType.setItemMeta(meta); } } } diff --git a/src/main/java/ch/njol/skript/effects/EffHandedness.java b/src/main/java/ch/njol/skript/effects/EffHandedness.java index b93e6302e61..3392ada8bb1 100644 --- a/src/main/java/ch/njol/skript/effects/EffHandedness.java +++ b/src/main/java/ch/njol/skript/effects/EffHandedness.java @@ -1,11 +1,7 @@ package ch.njol.skript.effects; import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; @@ -36,6 +32,7 @@ public class EffHandedness extends Effect { private Expression livingEntities; @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { leftHanded = parseResult.hasTag("left"); livingEntities = (Expression) exprs[0]; @@ -45,9 +42,8 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override protected void execute(Event event) { for (LivingEntity livingEntity : livingEntities.getArray(event)) { - if (livingEntity instanceof Mob) { - ((Mob) livingEntity).setLeftHanded(leftHanded); - } + if (livingEntity instanceof Mob mob) + mob.setLeftHanded(leftHanded); } } diff --git a/src/main/java/ch/njol/skript/effects/EffHealth.java b/src/main/java/ch/njol/skript/effects/EffHealth.java index 28d21dd87b9..3a79e742c44 100644 --- a/src/main/java/ch/njol/skript/effects/EffHealth.java +++ b/src/main/java/ch/njol/skript/effects/EffHealth.java @@ -5,11 +5,8 @@ import ch.njol.skript.bukkitutil.DamageUtils; import ch.njol.skript.bukkitutil.HealthUtils; import ch.njol.skript.bukkitutil.ItemUtils; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.config.Node; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; @@ -22,6 +19,7 @@ import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnknownNullability; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Damage/Heal/Repair") @Description({ @@ -36,7 +34,8 @@ }) @Since("1.0, 2.10 (damage cause)") @RequiredPlugins("Spigot 1.20.4+ (for damage cause)") -public class EffHealth extends Effect { +public class EffHealth extends Effect implements SyntaxRuntimeErrorProducer { + private static final boolean SUPPORTS_DAMAGE_SOURCE = Skript.classExists("org.bukkit.damage.DamageSource"); static { @@ -46,6 +45,7 @@ public class EffHealth extends Effect { "repair %itemtypes/slots% [by %-number%]"); } + private Node node; private Expression damageables; private @UnknownNullability Expression amount; private boolean isHealing, isRepairing; @@ -58,7 +58,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye Skript.error("Using the fake cause extension in effect 'damage' requires Spigot 1.20.4+"); return false; } - + this.node = getParser().getNode(); this.damageables = exprs[0]; this.isHealing = matchedPattern >= 1; this.isRepairing = matchedPattern == 2; @@ -73,8 +73,10 @@ protected void execute(Event event) { double amount = 0; if (this.amount != null) { Number amountPostCheck = this.amount.getSingle(event); - if (amountPostCheck == null) + if (amountPostCheck == null) { + error("The provided " + getSyntaxType() + " amount was not set.", this.amount.toString()); return; + } amount = amountPostCheck.doubleValue(); } @@ -122,17 +124,20 @@ protected void execute(Event event) { } } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { - String prefix = "damage "; - if (isRepairing) { - prefix = "repair "; - } else if (isHealing) { - prefix = "heal "; - } - return prefix + damageables.toString(event, debug) + return getSyntaxType() + damageables.toString(event, debug) + (amount != null ? " by " + amount.toString(event, debug) : "") + (exprCause != null && event != null ? " with damage cause " + exprCause.getSingle(event) : ""); } + private String getSyntaxType() { + return isRepairing ? "repair" : isHealing ? "heal" : "damage"; + } + } diff --git a/src/main/java/ch/njol/skript/effects/EffHidePlayerFromServerList.java b/src/main/java/ch/njol/skript/effects/EffHidePlayerFromServerList.java index f2307e42517..a62a35d5467 100644 --- a/src/main/java/ch/njol/skript/effects/EffHidePlayerFromServerList.java +++ b/src/main/java/ch/njol/skript/effects/EffHidePlayerFromServerList.java @@ -1,16 +1,7 @@ package ch.njol.skript.effects; -import java.util.Arrays; -import java.util.Iterator; - -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.server.ServerListPingEvent; -import org.jetbrains.annotations.Nullable; - -import com.destroystokyo.paper.event.server.PaperServerListPingEvent; -import com.google.common.collect.Iterators; import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -19,28 +10,43 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import com.destroystokyo.paper.event.server.PaperServerListPingEvent; +import com.google.common.collect.Iterators; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.server.ServerListPingEvent; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; + +import java.util.Arrays; +import java.util.Iterator; @Name("Hide Player from Server List") -@Description({"Hides a player from the hover list " + - "and decreases the online players count (only if the player count wasn't changed before)."}) -@Examples({"on server list ping:", - " hide {vanished::*} from the server list"}) +@Description({ + "Hides a player from the hover list " + + "and decreases the online players count " + + "(only if the player count wasn't changed before)." +}) +@Examples({ + "on server list ping:", + "\thide {vanished::*} from the server list" +}) @Since("2.3") -public class EffHidePlayerFromServerList extends Effect { +public class EffHidePlayerFromServerList extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffHidePlayerFromServerList.class, - "hide %players% (in|on|from) [the] server list", - "hide %players%'[s] info[rmation] (in|on|from) [the] server list"); + "hide %players% (in|on|from) [the] server list", + "hide %players%'[s] info[rmation] (in|on|from) [the] server list"); } private static final boolean PAPER_EVENT_EXISTS = Skript.classExists("com.destroystokyo.paper.event.server.PaperServerListPingEvent"); - @SuppressWarnings("null") + private Node node; private Expression players; - @SuppressWarnings({"unchecked", "null"}) @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { boolean isServerPingEvent = getParser().isCurrentEvent(ServerListPingEvent.class) || (PAPER_EVENT_EXISTS && getParser().isCurrentEvent(PaperServerListPingEvent.class)); @@ -51,23 +57,31 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye Skript.error("Can't hide players from the server list anymore after the server list ping event has already passed"); return false; } + node = getParser().getNode(); players = (Expression) exprs[0]; return true; } @Override @SuppressWarnings("removal") - protected void execute(Event e) { - if (!(e instanceof ServerListPingEvent)) + protected void execute(Event event) { + if (!(event instanceof ServerListPingEvent serverListPingEvent)) { + error("The 'hide player from server list' effect can only be used in a 'server list ping' event."); return; + } - Iterator it = ((ServerListPingEvent) e).iterator(); - Iterators.removeAll(it, Arrays.asList(players.getArray(e))); + Iterator iterator = serverListPingEvent.iterator(); + Iterators.removeAll(iterator, Arrays.asList(players.getArray(event))); + } + + @Override + public Node getNode() { + return node; } @Override - public String toString(@Nullable Event e, boolean debug) { - return "hide " + players.toString(e, debug) + " from the server list"; + public String toString(@Nullable Event event, boolean debug) { + return "hide " + players.toString(event, debug) + " from the server list"; } } diff --git a/src/main/java/ch/njol/skript/effects/EffIgnite.java b/src/main/java/ch/njol/skript/effects/EffIgnite.java index 20392f897d3..98508ade5f3 100644 --- a/src/main/java/ch/njol/skript/effects/EffIgnite.java +++ b/src/main/java/ch/njol/skript/effects/EffIgnite.java @@ -1,13 +1,7 @@ package ch.njol.skript.effects; -import org.bukkit.Bukkit; -import org.bukkit.entity.Entity; -import org.bukkit.event.Event; -import org.bukkit.event.entity.EntityCombustEvent; -import org.bukkit.event.entity.EntityDamageEvent; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -17,6 +11,13 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.util.Timespan; import ch.njol.util.Kleenean; +import org.bukkit.Bukkit; +import org.bukkit.entity.Entity; +import org.bukkit.event.Event; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Ignite/Extinguish") @Description("Lights entities on fire or extinguishes them.") @@ -25,25 +26,26 @@ "extinguish the player" }) @Since("1.4") -public class EffIgnite extends Effect { +public class EffIgnite extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffIgnite.class, - "(ignite|set fire to) %entities% [for %-timespan%]", "(set|light) %entities% on fire [for %-timespan%]", - "extinguish %entities%"); + "(ignite|set fire to) %entities% [for %-timespan%]", + "(set|light) %entities% on fire [for %-timespan%]", + "extinguish %entities%"); } private static final int DEFAULT_DURATION = 8 * 20; // default is 8 seconds for lava and fire. - @Nullable - private Expression duration; - + private Node node; + private @Nullable Expression duration; private Expression entities; private boolean ignite; @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); entities = (Expression) exprs[0]; ignite = exprs.length > 1; if (ignite) @@ -53,31 +55,35 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override protected void execute(Event event) { - int duration; - if (this.duration == null) { - duration = ignite ? DEFAULT_DURATION : 0; - } else { + int duration = 0; + if (this.duration == null && ignite) { + duration = DEFAULT_DURATION; + } else if (this.duration != null) { Timespan timespan = this.duration.getSingle(event); - if (timespan == null) + if (timespan == null) { + error("The provided timespan was not set.", this.duration.toString()); return; + } duration = (int) timespan.getAs(Timespan.TimePeriod.TICK); } + for (Entity entity : entities.getArray(event)) { - if (event instanceof EntityDamageEvent && ((EntityDamageEvent) event).getEntity() == entity && !Delay.isDelayed(event)) { - Bukkit.getScheduler().scheduleSyncDelayedTask(Skript.getInstance(), new Runnable() { - @Override - public void run() { - entity.setFireTicks(duration); - } - }); + if (event instanceof EntityDamageEvent damageEvent && damageEvent.getEntity() == entity && !Delay.isDelayed(event)) { + int finalDuration = duration; + Bukkit.getScheduler().scheduleSyncDelayedTask(Skript.getInstance(), () -> entity.setFireTicks(finalDuration)); } else { - if (event instanceof EntityCombustEvent && ((EntityCombustEvent) event).getEntity() == entity && !Delay.isDelayed(event)) - ((EntityCombustEvent) event).setCancelled(true);// can't change the duration, thus simply cancel the event (and create a new one) + if (event instanceof EntityCombustEvent combustEvent && combustEvent.getEntity() == entity && !Delay.isDelayed(event)) + combustEvent.setCancelled(true);// can't change the duration, thus simply cancel the event (and create a new one) entity.setFireTicks(duration); } } } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { if (ignite) diff --git a/src/main/java/ch/njol/skript/effects/EffIncendiary.java b/src/main/java/ch/njol/skript/effects/EffIncendiary.java index 181444137cf..a04a60058bf 100644 --- a/src/main/java/ch/njol/skript/effects/EffIncendiary.java +++ b/src/main/java/ch/njol/skript/effects/EffIncendiary.java @@ -1,12 +1,7 @@ package ch.njol.skript.effects; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Explosive; -import org.bukkit.event.Event; -import org.bukkit.event.entity.ExplosionPrimeEvent; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -16,37 +11,43 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.log.ErrorQuality; import ch.njol.util.Kleenean; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Explosive; +import org.bukkit.event.Event; +import org.bukkit.event.entity.ExplosionPrimeEvent; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Make Incendiary") @Description("Sets if an entity's explosion will leave behind fire. This effect is also usable in an explosion prime event.") -@Examples({"on explosion prime:", - "\tmake the explosion fiery"}) +@Examples({ + "on explosion prime:", + "\tmake the explosion fiery" +}) @Since("2.5") -public class EffIncendiary extends Effect { +public class EffIncendiary extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffIncendiary.class, - "make %entities% [(1¦not)] incendiary", - "make %entities%'[s] explosion [(1¦not)] (incendiary|fiery)", - "make [the] [event(-| )]explosion [(1¦not)] (incendiary|fiery)" + "make %entities% [(1:not)] incendiary", + "make %entities%'[s] explosion [(1:not)] (incendiary|fiery)", + "make [the] [event(-| )]explosion [(1:not)] (incendiary|fiery)" ); } - @SuppressWarnings("null") + private Node node; private Expression entities; - - private boolean causeFire; - - private boolean isEvent; + private boolean causeFire, isEvent; @Override - @SuppressWarnings({"unchecked", "null"}) + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { isEvent = matchedPattern == 2; if (isEvent && !getParser().isCurrentEvent(ExplosionPrimeEvent.class)) { Skript.error("Making 'the explosion' fiery is only usable in an explosion prime event", ErrorQuality.SEMANTIC_ERROR); return false; } + node = getParser().getNode(); if (!isEvent) entities = (Expression) exprs[0]; causeFire = parseResult.mark != 1; @@ -54,25 +55,31 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - protected void execute(Event e) { + protected void execute(Event event) { if (isEvent) { - if (!(e instanceof ExplosionPrimeEvent)) + if (!(event instanceof ExplosionPrimeEvent explosionPrimeEvent)) { + error("The 'incendiary' effect can only be used in an 'explosion prime' event."); return; - - ((ExplosionPrimeEvent) e).setFire(causeFire); + } + explosionPrimeEvent.setFire(causeFire); } else { - for (Entity entity : entities.getArray(e)) { - if (entity instanceof Explosive) - ((Explosive) entity).setIsIncendiary(causeFire); + for (Entity entity : entities.getArray(event)) { + if (entity instanceof Explosive explosive) + explosive.setIsIncendiary(causeFire); } } } @Override - public String toString(@Nullable Event e, boolean debug) { + public Node getNode() { + return node; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { if (isEvent) - return "make the event-explosion " + (causeFire == true ? "" : "not") + " fiery"; - return "make " + entities.toString(e, debug) + (causeFire == true ? "" : " not") + " incendiary"; + return "make the event-explosion " + (causeFire ? "" : "not") + " fiery"; + return "make " + entities.toString(event, debug) + (causeFire ? "" : " not") + " incendiary"; } } diff --git a/src/main/java/ch/njol/skript/effects/EffInvulnerability.java b/src/main/java/ch/njol/skript/effects/EffInvulnerability.java index 9585f88b97f..297de245e62 100644 --- a/src/main/java/ch/njol/skript/effects/EffInvulnerability.java +++ b/src/main/java/ch/njol/skript/effects/EffInvulnerability.java @@ -1,9 +1,5 @@ package ch.njol.skript.effects; -import org.bukkit.entity.Entity; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -13,6 +9,9 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.entity.Entity; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; @Name("Make Invulnerable") @Description("Makes an entity invulnerable/not invulnerable.") @@ -25,8 +24,7 @@ public class EffInvulnerability extends Effect { "make %entities% (invulnerable|invincible)", "make %entities% (not (invulnerable|invincible)|vulnerable|vincible)"); } - - @SuppressWarnings("null") + private Expression entities; private boolean invulnerable; diff --git a/src/main/java/ch/njol/skript/effects/EffKeepInventory.java b/src/main/java/ch/njol/skript/effects/EffKeepInventory.java index 3ed179e28ba..1bdc4e05e87 100644 --- a/src/main/java/ch/njol/skript/effects/EffKeepInventory.java +++ b/src/main/java/ch/njol/skript/effects/EffKeepInventory.java @@ -1,20 +1,15 @@ package ch.njol.skript.effects; -import org.bukkit.event.Event; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.event.entity.PlayerDeathEvent; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Events; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.Since; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.event.Event; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.jetbrains.annotations.Nullable; @Name("Keep Inventory / Experience") @Description("Keeps the inventory or/and experiences of the dead player in a death event.") @@ -52,8 +47,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override protected void execute(Event event) { - if (event instanceof PlayerDeathEvent) { - PlayerDeathEvent deathEvent = (PlayerDeathEvent) event; + if (event instanceof PlayerDeathEvent deathEvent) { if (keepItems) deathEvent.setKeepInventory(true); if (keepExp) diff --git a/src/main/java/ch/njol/skript/effects/EffKick.java b/src/main/java/ch/njol/skript/effects/EffKick.java index ef89ad297ea..5b7668dc47b 100644 --- a/src/main/java/ch/njol/skript/effects/EffKick.java +++ b/src/main/java/ch/njol/skript/effects/EffKick.java @@ -1,13 +1,7 @@ package ch.njol.skript.effects; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.player.PlayerKickEvent; -import org.bukkit.event.player.PlayerLoginEvent; -import org.bukkit.event.player.PlayerLoginEvent.Result; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -16,53 +10,67 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerLoginEvent.Result; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; -/** - * @author Peter Güttinger - */ @Name("Kick") @Description("Kicks a player from the server.") -@Examples({"on place of TNT, lava, or obsidian:", - " kick the player due to \"You may not place %block%!\"", - " cancel the event"}) +@Examples({ + "on place of TNT, lava, or obsidian:", + "\tkick the player due to \"You may not place %block%!\"", + "\tcancel the event" +}) @Since("1.0") -public class EffKick extends Effect { +public class EffKick extends Effect implements SyntaxRuntimeErrorProducer { + static { Skript.registerEffect(EffKick.class, "kick %players% [(by reason of|because [of]|on account of|due to) %-string%]"); } - - @SuppressWarnings("null") + + private Node node; private Expression players; - @Nullable - private Expression reason; - - @SuppressWarnings({"unchecked", "null"}) + private @Nullable Expression reason; + @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); players = (Expression) exprs[0]; reason = (Expression) exprs[1]; return true; } - - @Override - public String toString(final @Nullable Event e, final boolean debug) { - return "kick " + players.toString(e, debug) + (reason != null ? " on account of " + reason.toString(e, debug) : ""); - } - + @Override - protected void execute(final Event e) { - final String r = reason != null ? reason.getSingle(e) : ""; - if (r == null) + protected void execute(Event event) { + String reason = this.reason != null ? this.reason.getSingle(event) : ""; + if (reason == null) { + error("The provided reason was not set.", this.reason.toString()); return; - for (final Player p : players.getArray(e)) { - if (e instanceof PlayerLoginEvent && p.equals(((PlayerLoginEvent) e).getPlayer()) && !Delay.isDelayed(e)) { - ((PlayerLoginEvent) e).disallow(Result.KICK_OTHER, r); - } else if (e instanceof PlayerKickEvent && p.equals(((PlayerKickEvent) e).getPlayer()) && !Delay.isDelayed(e)) { - ((PlayerKickEvent) e).setLeaveMessage(r); + } + for (Player player : players.getArray(event)) { + if (event instanceof PlayerLoginEvent playerLoginEvent && player.equals(playerLoginEvent.getPlayer()) && !Delay.isDelayed(event)) { + playerLoginEvent.disallow(Result.KICK_OTHER, reason); + } else if (event instanceof PlayerKickEvent playerKickEvent && player.equals(playerKickEvent.getPlayer()) && !Delay.isDelayed(event)) { + playerKickEvent.setLeaveMessage(reason); } else { - p.kickPlayer(r); + player.kickPlayer(reason); } } } + + @Override + public Node getNode() { + return node; + } + @Override + public String toString(@Nullable Event event, boolean debug) { + return "kick " + players.toString(event, debug) + (reason != null ? " on account of " + reason.toString(event, debug) : ""); + } + } diff --git a/src/main/java/ch/njol/skript/effects/EffKill.java b/src/main/java/ch/njol/skript/effects/EffKill.java index a7582a9f598..3ecd817416f 100644 --- a/src/main/java/ch/njol/skript/effects/EffKill.java +++ b/src/main/java/ch/njol/skript/effects/EffKill.java @@ -20,11 +20,15 @@ import org.jetbrains.annotations.Nullable; @Name("Kill") -@Description({"Kills an entity.", - "Note: This effect does not set the entity's health to 0 (which causes issues), but damages the entity by 100 times its maximum health."}) -@Examples({"kill the player", - "kill all creepers in the player's world", - "kill all endermen, witches and bats"}) +@Description({ + "Kills an entity.", + "Note: This effect does not set the entity's health to 0 (which causes issues), but damages the entity by 100 times its maximum health." +}) +@Examples({ + "kill the player", + "kill all creepers in the player's world", + "kill all endermen, witches and bats" +}) @Since("1.0, 2.10 (ignoring totem of undying)") public class EffKill extends Effect { diff --git a/src/main/java/ch/njol/skript/effects/EffKnockback.java b/src/main/java/ch/njol/skript/effects/EffKnockback.java index de43ed17322..ee1da29ee17 100644 --- a/src/main/java/ch/njol/skript/effects/EffKnockback.java +++ b/src/main/java/ch/njol/skript/effects/EffKnockback.java @@ -1,11 +1,8 @@ package ch.njol.skript.effects; import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.config.Node; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; @@ -15,29 +12,35 @@ import org.bukkit.event.Event; import org.bukkit.util.Vector; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Knockback") -@Description("Apply the same velocity as a knockback to living entities in a direction. Mechanics such as knockback resistance will be factored in.") +@Description({ + "Apply the same velocity as a knockback to living entities in a direction.", + "Mechanics such as knockback resistance will be factored in." +}) @Examples({ "knockback player north", "knock victim (vector from attacker to victim) with strength 10" }) @Since("2.7") @RequiredPlugins("Paper 1.19.2+") -public class EffKnockback extends Effect { +public class EffKnockback extends Effect implements SyntaxRuntimeErrorProducer { static { if (Skript.methodExists(LivingEntity.class, "knockback", double.class, double.class, double.class)) Skript.registerEffect(EffKnockback.class, "(apply knockback to|knock[back]) %livingentities% [%direction%] [with (strength|force) %-number%]"); } + private Node node; private Expression entities; private Expression direction; - @Nullable - private Expression strength; + private @Nullable Expression strength; @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); entities = (Expression) exprs[0]; direction = (Expression) exprs[1]; strength = (Expression) exprs[2]; @@ -47,10 +50,20 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override protected void execute(Event event) { Direction direction = this.direction.getSingle(event); - if (direction == null) + if (direction == null) { + error("The provided direction was not set.", this.direction.toString()); return; + } - double strength = this.strength != null ? this.strength.getOptionalSingle(event).orElse(1).doubleValue() : 1.0; + double strength = 1; + if (this.strength != null) { + Number number = this.strength.getSingle(event); + if (number == null) { + warning("The provided strength was not set, so defaulted to 1.", this.strength.toString()); + } else { + strength = number.doubleValue(); + } + } for (LivingEntity livingEntity : entities.getArray(event)) { Vector directionVector = direction.getDirection(livingEntity); @@ -63,6 +76,11 @@ protected void execute(Event event) { } } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { return "knockback " + entities.toString(event, debug) + " " + direction.toString(event, debug) + " with strength " + (strength != null ? strength.toString(event, debug) : "1"); diff --git a/src/main/java/ch/njol/skript/effects/EffLeash.java b/src/main/java/ch/njol/skript/effects/EffLeash.java index 4e1b0159b08..1268a8f9012 100644 --- a/src/main/java/ch/njol/skript/effects/EffLeash.java +++ b/src/main/java/ch/njol/skript/effects/EffLeash.java @@ -1,11 +1,7 @@ package ch.njol.skript.effects; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -14,6 +10,11 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Leash entities") @Description({ @@ -26,7 +27,7 @@ "\tsend \"&aYou leashed &2%event-entity%!\" to player" }) @Since("2.3") -public class EffLeash extends Effect { +public class EffLeash extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffLeash.class, @@ -35,15 +36,15 @@ public class EffLeash extends Effect { "un(leash|lead) [holder of] %livingentities%"); } - @SuppressWarnings("null") + private Node node; private Expression holder; - @SuppressWarnings("null") private Expression targets; private boolean leash; @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); leash = matchedPattern != 2; if (leash) { holder = (Expression) exprs[1 - matchedPattern]; @@ -55,25 +56,32 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - protected void execute(Event e) { + protected void execute(Event event) { if (leash) { - Entity holder = this.holder.getSingle(e); - if (holder == null) + Entity holder = this.holder.getSingle(event); + if (holder == null) { + error("The provided leash holder was not set.", this.holder.toString()); return; - for (LivingEntity target : targets.getArray(e)) + } + for (LivingEntity target : targets.getArray(event)) target.setLeashHolder(holder); } else { - for (LivingEntity target : targets.getArray(e)) + for (LivingEntity target : targets.getArray(event)) target.setLeashHolder(null); } } @Override - public String toString(@Nullable Event e, boolean debug) { + public Node getNode() { + return node; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { if (leash) - return "leash " + targets.toString(e, debug) + " to " + holder.toString(e, debug); + return "leash " + targets.toString(event, debug) + " to " + holder.toString(event, debug); else - return "unleash " + targets.toString(e, debug); + return "unleash " + targets.toString(event, debug); } } diff --git a/src/main/java/ch/njol/skript/effects/EffLightning.java b/src/main/java/ch/njol/skript/effects/EffLightning.java index a92d6681e5c..d32c8b527d3 100644 --- a/src/main/java/ch/njol/skript/effects/EffLightning.java +++ b/src/main/java/ch/njol/skript/effects/EffLightning.java @@ -1,10 +1,5 @@ package ch.njol.skript.effects; -import org.bukkit.Location; -import org.bukkit.entity.Entity; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -15,50 +10,50 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.util.Direction; import ch.njol.util.Kleenean; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; -/** - * @author Peter Güttinger - */ @Name("Lightning") @Description("Strike lightning at a given location. Can use 'lightning effect' to create a lightning that does not harm entities or start fires.") -@Examples({"strike lightning at the player", - "strike lightning effect at the victim"}) +@Examples({ + "strike lightning at the player", + "strike lightning effect at the victim" +}) @Since("1.4") public class EffLightning extends Effect { static { Skript.registerEffect(EffLightning.class, "(create|strike) lightning(1¦[ ]effect|) %directions% %locations%"); } - - @SuppressWarnings("null") + + public static @Nullable Entity lastSpawned = null; + private Expression locations; - private boolean effectOnly; - - @Nullable - public static Entity lastSpawned = null; - - @SuppressWarnings({"unchecked", "null"}) + @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { locations = Direction.combine((Expression) exprs[0], (Expression) exprs[1]); effectOnly = parseResult.mark == 1; return true; } @Override - protected void execute(final Event e) { - for (final Location l : locations.getArray(e)) { + protected void execute(Event event) { + for (Location loc : locations.getArray(event)) { if (effectOnly) - lastSpawned = l.getWorld().strikeLightningEffect(l); + lastSpawned = loc.getWorld().strikeLightningEffect(loc); else - lastSpawned = l.getWorld().strikeLightning(l); + lastSpawned = loc.getWorld().strikeLightning(loc); } } @Override - public String toString(final @Nullable Event e, final boolean debug) { - return "strike lightning " + (effectOnly ? "effect " : "") + locations.toString(e, debug); + public String toString(@Nullable Event event, boolean debug) { + return "strike lightning " + (effectOnly ? "effect " : "") + locations.toString(event, debug); } } diff --git a/src/main/java/ch/njol/skript/effects/EffLoadServerIcon.java b/src/main/java/ch/njol/skript/effects/EffLoadServerIcon.java index 93242b6bb05..c267fa7df1d 100644 --- a/src/main/java/ch/njol/skript/effects/EffLoadServerIcon.java +++ b/src/main/java/ch/njol/skript/effects/EffLoadServerIcon.java @@ -1,41 +1,41 @@ package ch.njol.skript.effects; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - +import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; +import ch.njol.skript.doc.*; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.util.AsyncEffect; +import ch.njol.util.Kleenean; import org.bukkit.Bukkit; import org.bukkit.event.Event; import org.bukkit.util.CachedServerIcon; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; -import ch.njol.skript.ScriptLoader; -import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; -import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.SkriptParser; -import ch.njol.skript.util.AsyncEffect; -import ch.njol.util.Kleenean; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; @Name("Load Server Icon") -@Description({"Loads server icons from the given files. You can get the loaded icon using the", - "last loaded server icon expression.", - "Please note that the image must be 64x64 and the file path starts from the server folder.",}) -@Examples({"on load:", - " clear {server-icons::*}", - " loop 5 times:", - " load server icon from file \"icons/%loop-number%.png\"", - " add the last loaded server icon to {server-icons::*}", - "", - "on server list ping:", - " set the icon to a random server icon out of {server-icons::*}"}) +@Description({ + "Loads server icons from the given files. You can get the loaded icon using the", + "last loaded server icon expression.", + "Please note that the image must be 64x64 and the file path starts from the server folder." +}) +@Examples({ + "on load:", + "\tclear {server-icons::*}", + "\tloop 5 times:", + "\t\tload server icon from file \"icons/%loop-number%.png\"", + "\t\tadd the last loaded server icon to {server-icons::*}", + "", + "on server list ping:", + "\tset the icon to a random server icon out of {server-icons::*}" +}) @Since("2.3") -@RequiredPlugins("Paper 1.12.2 or newer") -public class EffLoadServerIcon extends AsyncEffect { +@RequiredPlugins("Paper 1.12.2+") +public class EffLoadServerIcon extends AsyncEffect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffLoadServerIcon.class, "load [the] server icon (from|of) [the] [image] [file] %string%"); @@ -43,34 +43,36 @@ public class EffLoadServerIcon extends AsyncEffect { private static final boolean PAPER_EVENT_EXISTS = Skript.classExists("com.destroystokyo.paper.event.server.PaperServerListPingEvent"); - @SuppressWarnings("null") - private Expression path; + public static @Nullable CachedServerIcon lastLoaded = null; - @Nullable - public static CachedServerIcon lastLoaded = null; + private Node node; + private Expression path; - @SuppressWarnings({"unchecked", "null"}) @Override - public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { getParser().setHasDelayBefore(Kleenean.TRUE); if (!PAPER_EVENT_EXISTS) { - Skript.error("The load server icon effect requires Paper 1.12.2 or newer"); + Skript.error("The load server icon effect requires Paper 1.12.2+"); return false; } + node = getParser().getNode(); path = (Expression) exprs[0]; return true; } @Override - protected void execute(Event e) { - String pathString = path.getSingle(e); - if (pathString == null) + protected void execute(Event event) { + String pathString = path.getSingle(event); + if (pathString == null) { + error("The path string was not set.", path.toString()); return; + } - Path p = Paths.get(pathString); - if (Files.isRegularFile(p)) { + Path path = Paths.get(pathString); + if (Files.isRegularFile(path)) { try { - lastLoaded = Bukkit.loadServerIcon(p.toFile()); + lastLoaded = Bukkit.loadServerIcon(path.toFile()); } catch (NullPointerException | IllegalArgumentException ignored) { } catch (Exception ex) { Skript.exception(ex); @@ -79,8 +81,13 @@ protected void execute(Event e) { } @Override - public String toString(@Nullable Event e, boolean debug) { - return "load server icon from file " + path.toString(e, debug); + public Node getNode() { + return node; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "load server icon from file " + path.toString(event, debug); } } \ No newline at end of file diff --git a/src/main/java/ch/njol/skript/effects/EffLog.java b/src/main/java/ch/njol/skript/effects/EffLog.java index 0d4f0eb2908..6fc225e3f44 100644 --- a/src/main/java/ch/njol/skript/effects/EffLog.java +++ b/src/main/java/ch/njol/skript/effects/EffLog.java @@ -1,18 +1,5 @@ package ch.njol.skript.effects; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.Locale; -import java.util.logging.Level; - -import org.skriptlang.skript.lang.script.Script; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.SkriptConfig; import ch.njol.skript.doc.Description; @@ -25,12 +12,26 @@ import ch.njol.skript.lang.Trigger; import ch.njol.skript.log.SkriptLogger; import ch.njol.skript.util.ExceptionUtils; -import ch.njol.util.Closeable; import ch.njol.util.Kleenean; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.lang.script.Script; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashMap; +import java.util.Locale; +import java.util.logging.Level; @Name("Log") -@Description({"Writes text into a .log file. Skript will write these files to /plugins/Skript/logs.", - "NB: Using 'server.log' as the log file will write to the default server log. Omitting the log file altogether will log the message as '[Skript] [<script>.sk] <message>' in the server log."}) +@Description({ + "Writes text into a .log file. Skript will write these files to /plugins/Skript/logs.", + "NB: Using 'server.log' as the log file will write to the default server log.", + "Omitting the log file altogether will log the message as '[Skript] [<script>.sk] <message>' in the server log." +}) @Examples({ "on join:", "\tlog \"%player% has just joined the server!\"", @@ -41,6 +42,7 @@ }) @Since("2.0, 2.9.0 (severities)") public class EffLog extends Effect { + static { Skript.registerEffect(EffLog.class, "log %strings% [(to|in) [file[s]] %-strings%] [with [the|a] severity [of] (1:warning|2:severe)]"); } @@ -48,6 +50,7 @@ public class EffLog extends Effect { private static final File logsFolder = new File(Skript.getInstance().getDataFolder(), "logs"); final static HashMap writers = new HashMap<>(); + static { Skript.closeOnDisable(() -> { for (PrintWriter pw : writers.values()) @@ -55,12 +58,11 @@ public class EffLog extends Effect { }); } - @SuppressWarnings("null") private Expression messages; - @Nullable - private Expression files; + private @Nullable Expression files; private Level logLevel = Level.INFO; + private static String getLogPrefix(Level logLevel) { String timestamp = SkriptConfig.formatDate(System.currentTimeMillis()); if (logLevel == Level.INFO) @@ -68,8 +70,8 @@ private static String getLogPrefix(Level logLevel) { return "[" + timestamp + " " + logLevel + "]"; } - @SuppressWarnings({"unchecked", "null"}) @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parser) { messages = (Expression) exprs[0]; files = (Expression) exprs[1]; @@ -81,7 +83,6 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye return true; } - @SuppressWarnings("resource") @Override protected void execute(Event event) { for (String message : messages.getArray(event)) { diff --git a/src/main/java/ch/njol/skript/effects/EffLook.java b/src/main/java/ch/njol/skript/effects/EffLook.java index 5b88d37a9a4..498a8645d0b 100644 --- a/src/main/java/ch/njol/skript/effects/EffLook.java +++ b/src/main/java/ch/njol/skript/effects/EffLook.java @@ -1,26 +1,26 @@ package ch.njol.skript.effects; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Mob; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.bukkitutil.PaperEntityUtils; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.config.Node; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; import io.papermc.paper.entity.LookAnchor; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Mob; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Look At") -@Description("Forces the mob(s) or player(s) to look at an entity, vector or location. Vanilla max head pitches range from 10 to 50.") +@Description({ + "Forces the mob(s) or player(s) to look at an entity, vector or location.", + "Vanilla max head pitches range from 10 to 50." +}) @Examples({ "force the player to look towards event-entity's feet", "", @@ -34,7 +34,7 @@ }) @Since("2.7") @RequiredPlugins("Paper 1.17+, Paper 1.19.1+ (Players & Look Anchors)") -public class EffLook extends Effect { +public class EffLook extends Effect implements SyntaxRuntimeErrorProducer { private static final boolean LOOK_ANCHORS = Skript.classExists("io.papermc.paper.entity.LookAnchor"); @@ -54,20 +54,16 @@ public class EffLook extends Effect { } } + private Node node; private LookAnchor anchor = LookAnchor.EYES; private Expression entities; + private Expression target; // can be a vector, location, or entity + private @Nullable Expression speed, maxPitch; - @Nullable - private Expression speed, maxPitch; - - /** - * Can be Vector, Location or an Entity. - */ - private Expression target; - - @SuppressWarnings("unchecked") @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); entities = (Expression) exprs[0]; if (LOOK_ANCHORS && matchedPattern == 0) { target = exprs[parseResult.hasTag("of") ? 2 : 1]; @@ -86,11 +82,30 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override protected void execute(Event event) { Object object = target.getSingle(event); - if (object == null) + if (object == null) { + error("The provided target was not set.", target.toString()); return; + } - Float speed = this.speed == null ? null : this.speed.getOptionalSingle(event).map(Number::floatValue).orElse(null); - Float maxPitch = this.maxPitch == null ? null : this.maxPitch.getOptionalSingle(event).map(Number::floatValue).orElse(null); + Float speed = null; + if (this.speed != null) { + Number provided = this.speed.getSingle(event); + if (provided == null) { + warning("The provided speed was not set.", this.speed.toString()); + } else { + speed = provided.floatValue(); + } + } + + Float maxPitch = null; + if (this.maxPitch != null) { + Number provided = this.maxPitch.getSingle(event); + if (provided == null) { + warning("The provided max pitch was not set.", this.maxPitch.toString()); + } else { + maxPitch = provided.floatValue(); + } + } if (LOOK_ANCHORS) { PaperEntityUtils.lookAt(anchor, object, speed, maxPitch, entities.getArray(event)); @@ -99,6 +114,11 @@ protected void execute(Event event) { } } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { return "force " + entities.toString(event, debug) + " to look at " + target.toString(event, debug); diff --git a/src/main/java/ch/njol/skript/effects/EffMakeEggHatch.java b/src/main/java/ch/njol/skript/effects/EffMakeEggHatch.java index 44f10a91b99..d5587bd7a8e 100644 --- a/src/main/java/ch/njol/skript/effects/EffMakeEggHatch.java +++ b/src/main/java/ch/njol/skript/effects/EffMakeEggHatch.java @@ -1,11 +1,7 @@ package ch.njol.skript.effects; import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Events; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.Since; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; @@ -27,7 +23,7 @@ public class EffMakeEggHatch extends Effect { static { Skript.registerEffect(EffMakeEggHatch.class, - "make [the] egg [:not] hatch" + "make [the] egg [:not] hatch" ); } @@ -44,12 +40,11 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - protected void execute(Event e) { - if (e instanceof PlayerEggThrowEvent) { - PlayerEggThrowEvent event = (PlayerEggThrowEvent) e; - event.setHatching(!not); - if (!not && event.getNumHatches() == 0) // Make it hatch something! - event.setNumHatches((byte) 1); + protected void execute(Event event) { + if (event instanceof PlayerEggThrowEvent playerEggThrowEvent) { + playerEggThrowEvent.setHatching(!not); + if (!not && playerEggThrowEvent.getNumHatches() == 0) // Make it hatch something! + playerEggThrowEvent.setNumHatches((byte) 1); } } diff --git a/src/main/java/ch/njol/skript/effects/EffMakeFly.java b/src/main/java/ch/njol/skript/effects/EffMakeFly.java index ba8812f1e45..8d9d7fe9f90 100644 --- a/src/main/java/ch/njol/skript/effects/EffMakeFly.java +++ b/src/main/java/ch/njol/skript/effects/EffMakeFly.java @@ -1,10 +1,5 @@ package ch.njol.skript.effects; - -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -14,27 +9,33 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; @Name("Make Fly") @Description("Forces a player to start/stop flying.") -@Examples({"make player fly", "force all players to stop flying"}) +@Examples({ + "make player fly", + "force all players to stop flying" +}) @Since("2.2-dev34") public class EffMakeFly extends Effect { static { if (Skript.methodExists(Player.class, "setFlying", boolean.class)) { - Skript.registerEffect(EffMakeFly.class, "force %players% to [(start|1¦stop)] fly[ing]", - "make %players% (start|1¦stop) flying", - "make %players% fly"); + Skript.registerEffect(EffMakeFly.class, + "force %players% to [(start|1:stop)] fly[ing]", + "make %players% (start|1:stop) flying", + "make %players% fly"); } } - @SuppressWarnings("null") private Expression players; private boolean flying; - @SuppressWarnings({"unchecked", "null"}) @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { players = (Expression) exprs[0]; flying = parseResult.mark != 1; @@ -42,16 +43,16 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - protected void execute(Event e) { - for (Player player : players.getArray(e)) { + protected void execute(Event event) { + for (Player player : players.getArray(event)) { player.setAllowFlight(flying); player.setFlying(flying); } } @Override - public String toString(@Nullable Event e, boolean debug) { - return "make " + players.toString(e, debug) + (flying ? " start " : " stop ") + "flying"; + public String toString(@Nullable Event event, boolean debug) { + return "make " + players.toString(event, debug) + (flying ? " start " : " stop ") + "flying"; } } diff --git a/src/main/java/ch/njol/skript/effects/EffMakeSay.java b/src/main/java/ch/njol/skript/effects/EffMakeSay.java index a509558901f..1c2b087a21b 100644 --- a/src/main/java/ch/njol/skript/effects/EffMakeSay.java +++ b/src/main/java/ch/njol/skript/effects/EffMakeSay.java @@ -14,25 +14,28 @@ import org.jetbrains.annotations.Nullable; @Name("Make Say") -@Description("Forces a player to send a message to the chat. If the message starts with a slash it will force the player to use command.") -@Examples({"make the player say \"Hello.\"", "force all players to send the message \"I love this server\""}) +@Description({ + "Forces a player to send a message to the chat.", + "If the message starts with a slash it will force the player to use command." +}) +@Examples({ + "make the player say \"Hello.\"", + "force all players to send the message \"I love this server\"" +}) @Since("2.3") public class EffMakeSay extends Effect { static { Skript.registerEffect(EffMakeSay.class, - "make %players% (say|send [the] message[s]) %strings%", - "force %players% to (say|send [the] message[s]) %strings%"); + "make %players% (say|send [the] message[s]) %strings%", + "force %players% to (say|send [the] message[s]) %strings%"); } - @SuppressWarnings("null") private Expression players; - - @SuppressWarnings("null") private Expression messages; - @SuppressWarnings({"unchecked", "null"}) @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { players = (Expression) exprs[0]; messages = (Expression) exprs[1]; @@ -40,16 +43,16 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - protected void execute(Event e) { - for (Player player : players.getArray(e)) { - for (String message : messages.getArray(e)) { + protected void execute(Event event) { + for (Player player : players.getArray(event)) { + for (String message : messages.getArray(event)) { player.chat(message); } } } @Override - public String toString(@Nullable Event e, boolean debug) { - return "make " + players.toString(e, debug) + " say " + messages.toString(e, debug); + public String toString(@Nullable Event event, boolean debug) { + return "make " + players.toString(event, debug) + " say " + messages.toString(event, debug); } } \ No newline at end of file diff --git a/src/main/java/ch/njol/skript/effects/EffMessage.java b/src/main/java/ch/njol/skript/effects/EffMessage.java index 476ecda14fc..e7c10647380 100644 --- a/src/main/java/ch/njol/skript/effects/EffMessage.java +++ b/src/main/java/ch/njol/skript/effects/EffMessage.java @@ -1,50 +1,54 @@ package ch.njol.skript.effects; -import java.util.List; -import java.util.UUID; - -import ch.njol.skript.registrations.Classes; -import ch.njol.skript.util.LiteralUtils; -import ch.njol.skript.util.chat.MessageComponent; -import ch.njol.util.coll.CollectionUtils; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.doc.*; import ch.njol.skript.expressions.ExprColoured; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ExpressionList; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.VariableString; +import ch.njol.skript.registrations.Classes; +import ch.njol.skript.util.LiteralUtils; import ch.njol.skript.util.chat.BungeeConverter; import ch.njol.skript.util.chat.ChatMessages; +import ch.njol.skript.util.chat.MessageComponent; import ch.njol.util.Kleenean; +import ch.njol.util.coll.CollectionUtils; import net.md_5.bungee.api.chat.BaseComponent; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.UUID; @Name("Message") -@Description({"Sends a message to the given player. Only styles written", - "in given string or in formatted expressions will be parsed.", - "Adding an optional sender allows the messages to be sent as if a specific player sent them.", - "This is useful with Minecraft 1.16.4's new chat ignore system, in which players can choose to ignore other players,", - "but for this to work, the message needs to be sent from a player."}) -@Examples({"message \"A wild %player% appeared!\"", - "message \"This message is a distraction. Mwahaha!\"", - "send \"Your kill streak is %{kill streak::%uuid of player%}%.\" to player", - "if the targeted entity exists:", +@Description({ + "Sends a message to the given player. Only styles written", + "in given string or in formatted expressions will be parsed.", + "Adding an optional sender allows the messages to be sent as if a specific player sent them.", + "This is useful with Minecraft 1.16.4's new chat ignore system, in which players can choose to ignore other players,", + "but for this to work, the message needs to be sent from a player." +}) +@Examples({ + "message \"A wild %player% appeared!\"", + "message \"This message is a distraction. Mwahaha!\"", + "send \"Your kill streak is %{kill streak::%uuid of player%}%.\" to player", + "if the targeted entity exists:", "\tmessage \"You're currently looking at a %type of the targeted entity%!\"", - "on chat:", + "on chat:", "\tcancel event", - "\tsend \"[%player%] >> %message%\" to all players from player"}) + "\tsend \"[%player%] >> %message%\" to all players from player" +}) @RequiredPlugins("Minecraft 1.16.4+ for optional sender") -@Since("1.0, 2.2-dev26 (advanced features), 2.5.2 (optional sender), 2.6 (sending objects)") +@Since({ + "1.0", + "2.2-dev26 (advanced features)", + "2.5.2 (optional sender)", + "2.6 (sending objects)" +}) public class EffMessage extends Effect { private static final boolean SUPPORTS_SENDER = Skript.classExists("org.bukkit.command.CommandSender$Spigot") && @@ -57,23 +61,13 @@ public class EffMessage extends Effect { Skript.registerEffect(EffMessage.class, "(message|send [message[s]]) %objects% [to %commandsenders%]"); } - @SuppressWarnings("NotNullFieldNotInitialized") private Expression[] messages; - - /** - * Used for {@link EffMessage#toString(Event, boolean)} - */ - @SuppressWarnings("NotNullFieldNotInitialized") - private Expression messageExpr; - - @SuppressWarnings("NotNullFieldNotInitialized") + private Expression messageExpr; // used for toString private Expression recipients; - - @Nullable - private Expression sender; - - @SuppressWarnings({"unchecked", "null"}) + private @Nullable Expression sender; + @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parser) { messageExpr = LiteralUtils.defendExpression(exprs[0]); @@ -86,10 +80,10 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - protected void execute(Event e) { - Player sender = this.sender != null ? this.sender.getSingle(e) : null; + protected void execute(Event event) { + Player sender = this.sender != null ? this.sender.getSingle(event) : null; - CommandSender[] commandSenders = recipients.getArray(e); + CommandSender[] commandSenders = recipients.getArray(event); for (Expression message : getMessages()) { @@ -97,27 +91,27 @@ protected void execute(Event e) { List messageComponents = null; for (CommandSender receiver : commandSenders) { - if (receiver instanceof Player && message instanceof VariableString) { + if (receiver instanceof Player && message instanceof VariableString variableString) { if (messageComponents == null) - messageComponents = ((VariableString) message).getMessageComponents(e); + messageComponents = variableString.getMessageComponents(event); } else { if (messageArray == null) - messageArray = message.getArray(e); + messageArray = message.getArray(event); } - if (receiver instanceof Player) { // Can use JSON formatting + if (receiver instanceof Player player) { // Can use JSON formatting if (message instanceof VariableString) { // Process formatting that is safe - sendMessage((Player) receiver, sender, + sendMessage(player, sender, BungeeConverter.convert(messageComponents) ); - } else if (message instanceof ExprColoured && ((ExprColoured) message).isUnsafeFormat()) { // Manually marked as trusted + } else if (message instanceof ExprColoured exprColoured && exprColoured.isUnsafeFormat()) { // Manually marked as trusted for (Object object : messageArray) { - sendMessage((Player) receiver, sender, BungeeConverter.convert(ChatMessages.parse((String) object))); + sendMessage(player, sender, BungeeConverter.convert(ChatMessages.parse((String) object))); } } else { // It is just a string, no idea if it comes from a trusted source -> don't parse anything for (Object object : messageArray) { List components = ChatMessages.fromParsedString(toString(object)); - sendMessage((Player) receiver, sender, BungeeConverter.convert(components)); + sendMessage(player, sender, BungeeConverter.convert(components)); } } } else { // Not a player, send plain text with legacy formatting @@ -144,13 +138,13 @@ private Expression[] getMessages() { } private String toString(Object object) { - return object instanceof String ? (String) object : Classes.toString(object); + return object instanceof String string ? string : Classes.toString(object); } @Override - public String toString(@Nullable Event e, boolean debug) { - return "send " + messageExpr.toString(e, debug) + " to " + recipients.toString(e, debug) + - (sender != null ? " from " + sender.toString(e, debug) : ""); + public String toString(@Nullable Event event, boolean debug) { + return "send " + messageExpr.toString(event, debug) + " to " + recipients.toString(event, debug) + + (sender != null ? " from " + sender.toString(event, debug) : ""); } } diff --git a/src/main/java/ch/njol/skript/effects/EffOp.java b/src/main/java/ch/njol/skript/effects/EffOp.java index 8b8ec5f9404..a9dd2a75793 100644 --- a/src/main/java/ch/njol/skript/effects/EffOp.java +++ b/src/main/java/ch/njol/skript/effects/EffOp.java @@ -1,9 +1,5 @@ package ch.njol.skript.effects; -import org.bukkit.OfflinePlayer; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -13,43 +9,44 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.OfflinePlayer; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; -/** - * @author Peter Güttinger - */ @Name("op/deop") @Description("Grant/revoke a user operator state.") -@Examples({"op the player", - "deop all players"}) +@Examples({ + "op the player", + "deop all players" +}) @Since("1.0") public class EffOp extends Effect { static { Skript.registerEffect(EffOp.class, "[de[-]]op %offlineplayers%"); } - - @SuppressWarnings("null") + private Expression players; private boolean op; - - @SuppressWarnings({"unchecked", "null"}) + @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { players = (Expression) exprs[0]; op = !parseResult.expr.substring(0, 2).equalsIgnoreCase("de"); return true; } @Override - protected void execute(final Event e) { - for (final OfflinePlayer p : players.getArray(e)) { - p.setOp(op); + protected void execute(Event event) { + for (OfflinePlayer player : players.getArray(event)) { + player.setOp(op); } } @Override - public String toString(final @Nullable Event e, final boolean debug) { - return (op ? "" : "de") + "op " + players.toString(e, debug); + public String toString(@Nullable Event event, boolean debug) { + return (op ? "" : "de") + "op " + players.toString(event, debug); } } diff --git a/src/main/java/ch/njol/skript/effects/EffOpenBook.java b/src/main/java/ch/njol/skript/effects/EffOpenBook.java index 209dab7da48..551f14d3c9e 100644 --- a/src/main/java/ch/njol/skript/effects/EffOpenBook.java +++ b/src/main/java/ch/njol/skript/effects/EffOpenBook.java @@ -1,66 +1,73 @@ package ch.njol.skript.effects; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; -import ch.njol.skript.aliases.Aliases; import ch.njol.skript.aliases.ItemType; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.config.Node; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Open Book") @Description("Opens a written book to a player.") @Examples("open book player's tool to player") @RequiredPlugins("Minecraft 1.14.2+") @Since("2.5.1") -public class EffOpenBook extends Effect { +public class EffOpenBook extends Effect implements SyntaxRuntimeErrorProducer { static { if (Skript.methodExists(Player.class, "openBook", ItemStack.class)) { Skript.registerEffect(EffOpenBook.class, "(open|show) book %itemtype% (to|for) %players%"); } } - - @SuppressWarnings("null") + + private Node node; private Expression book; - @SuppressWarnings("null") private Expression players; - - @SuppressWarnings({"unchecked", "null"}) + @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); book = (Expression) exprs[0]; players = (Expression) exprs[1]; return true; } @Override - protected void execute(final Event e) { - ItemType itemType = book.getSingle(e); - if (itemType != null) { - ItemStack itemStack = itemType.getRandom(); - if (itemStack != null && itemStack.getType() == Material.WRITTEN_BOOK) { - for (Player player : players.getArray(e)) { - player.openBook(itemStack); - } - } + protected void execute(Event event) { + ItemType itemType = book.getSingle(event); + if (itemType == null) { + error("The provided book item was not set.", book.toString()); + return; + } + + ItemStack itemStack = itemType.getRandom(); + if (itemStack == null || !(itemStack.getType() == Material.WRITTEN_BOOK)) { + error("The provided book item was either invalid or not a written book.", book.toString()); + return; + } + + for (Player player : players.getArray(event)) { + player.openBook(itemStack); } } - + @Override - public String toString(@Nullable Event e, boolean debug) { - return "open book " + book.toString(e, debug) + " to " + players.toString(e, debug); + public Node getNode() { + return node; } + @Override + public String toString(@Nullable Event event, boolean debug) { + return "open book " + book.toString(event, debug) + " to " + players.toString(event, debug); + } + } diff --git a/src/main/java/ch/njol/skript/effects/EffOpenInventory.java b/src/main/java/ch/njol/skript/effects/EffOpenInventory.java index 29a8f59bc11..721ac375cd8 100644 --- a/src/main/java/ch/njol/skript/effects/EffOpenInventory.java +++ b/src/main/java/ch/njol/skript/effects/EffOpenInventory.java @@ -1,16 +1,5 @@ package ch.njol.skript.effects; -import java.util.Locale; - -import ch.njol.skript.lang.Literal; -import ch.njol.skript.registrations.Classes; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.inventory.Inventory; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -18,45 +7,60 @@ import ch.njol.skript.doc.Since; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.Literal; import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.registrations.Classes; import ch.njol.util.Kleenean; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.Nullable; + +import java.util.Locale; @Name("Open/Close Inventory") -@Description({"Opens an inventory to a player. The player can then access and modify the inventory as if it was a chest that he just opened.", - "Please note that currently 'show' and 'open' have the same effect, but 'show' will eventually show an unmodifiable view of the inventory in the future."}) -@Examples({"show the victim's inventory to the player", - "open the player's inventory for the player"}) -@Since("2.0, 2.1.1 (closing), 2.2-Fixes-V10 (anvil), 2.4 (hopper, dropper, dispenser") +@Description({ + "Opens an inventory to a player. The player can then access and modify the inventory as if it was a chest that was just opened.", + "Please note that currently 'show' and 'open' have the same effect, but 'show' will eventually show an unmodifiable view of the inventory in the future." +}) +@Examples({ + "show the victim's inventory to the player", + "open the player's inventory for the player" +}) +@Since({ + "2.0", + "2.1.1 (closing)", + "2.2-Fixes-V10 (anvil)", + "2.4 (hopper, dropper, dispenser)" +}) public class EffOpenInventory extends Effect { private final static int WORKBENCH = 0, CHEST = 1, ANVIL = 2, HOPPER = 3, DROPPER = 4, DISPENSER = 5; static { Skript.registerEffect(EffOpenInventory.class, - "(open|show) ((0¦(crafting [table]|workbench)|1¦chest|2¦anvil|3¦hopper|4¦dropper|5¦dispenser) (view|window|inventory|)|%-inventory/inventorytype%) (to|for) %players%", - "close [the] inventory [view] (to|of|for) %players%", "close %players%'[s] inventory [view]"); + "(open|show) ((0:(crafting [table]|workbench)|1:chest|2:anvil|3:hopper|4:dropper|5:dispenser) (view|window|inventory|)|%-inventory/inventorytype%) (to|for) %players%", + "close [the] inventory [view] (to|of|for) %players%", "close %players%'[s] inventory [view]"); } - - @Nullable - private Expression invi; - - boolean open; - private int invType; - - @SuppressWarnings("null") + private Expression players; - - @SuppressWarnings({"unchecked", "null"}) + private @Nullable Expression invi; + private boolean open; + private int invType; + @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { int openFlag = 0; - if(parseResult.mark >= 5) { + if (parseResult.mark >= 5) { openFlag = parseResult.mark ^ 5; invType = DISPENSER; - } else if(parseResult.mark >= 4) { + } else if (parseResult.mark >= 4) { openFlag = parseResult.mark ^ 4; invType = DROPPER; - } else if(parseResult.mark >= 3) { + } else if (parseResult.mark >= 3) { openFlag = parseResult.mark ^ 3; invType = HOPPER; } else if (parseResult.mark >= 2) { @@ -86,61 +90,46 @@ public boolean init(final Expression[] exprs, final int matchedPattern, final } @Override - protected void execute(final Event e) { - if (invi != null) { - Inventory i; - - assert invi != null; - Object o = invi.getSingle(e); - if (o instanceof Inventory) { - i = (Inventory) o; - } else if (o instanceof InventoryType inventoryType && inventoryType.isCreatable()) { - i = Bukkit.createInventory(null, inventoryType); + protected void execute(Event event) { + if (this.invi != null) { + Inventory inventory; + Object invi = this.invi.getSingle(event); + if (invi instanceof Inventory inv) { + inventory = inv; + } else if (invi instanceof InventoryType inventoryType && inventoryType.isCreatable()) { + inventory = Bukkit.createInventory(null, inventoryType); } else { return; } - - if (i == null) - return; - for (final Player p : players.getArray(e)) { + + for (Player player : players.getArray(event)) { try { - p.openInventory(i); + player.openInventory(inventory); } catch (IllegalArgumentException ex){ - Skript.error("You can't open a " + i.getType().name().toLowerCase(Locale.ENGLISH).replaceAll("_", "") + " inventory to a player."); + Skript.error("You can't open a " + inventory.getType().name().toLowerCase(Locale.ENGLISH).replaceAll("_", "") + " inventory to a player."); } } } else { - for (final Player p : players.getArray(e)) { + for (Player player : players.getArray(event)) { if (open) { switch (invType) { - case WORKBENCH: - p.openWorkbench(null, true); - break; - case CHEST: - p.openInventory(Bukkit.createInventory(p, InventoryType.CHEST)); - break; - case ANVIL: - p.openInventory(Bukkit.createInventory(p, InventoryType.ANVIL)); - break; - case HOPPER: - p.openInventory(Bukkit.createInventory(p, InventoryType.HOPPER)); - break; - case DROPPER: - p.openInventory(Bukkit.createInventory(p, InventoryType.DROPPER)); - break; - case DISPENSER: - p.openInventory(Bukkit.createInventory(p, InventoryType.DISPENSER)); - + case WORKBENCH -> player.openWorkbench(null, true); + case CHEST -> player.openInventory(Bukkit.createInventory(player, InventoryType.CHEST)); + case ANVIL -> player.openInventory(Bukkit.createInventory(player, InventoryType.ANVIL)); + case HOPPER -> player.openInventory(Bukkit.createInventory(player, InventoryType.HOPPER)); + case DROPPER -> player.openInventory(Bukkit.createInventory(player, InventoryType.DROPPER)); + case DISPENSER -> player.openInventory(Bukkit.createInventory(player, InventoryType.DISPENSER)); } - } else - p.closeInventory(); + } else { + player.closeInventory(); + } } } } @Override - public String toString(final @Nullable Event e, final boolean debug) { - return (open ? "open " + (invi != null ? invi.toString(e, debug) : "crafting table") + " to " : "close inventory view of ") + players.toString(e, debug); + public String toString(@Nullable Event event, boolean debug) { + return (open ? "open " + (invi != null ? invi.toString(event, debug) : "crafting table") + " to " : "close inventory view of ") + players.toString(event, debug); } } diff --git a/src/main/java/ch/njol/skript/effects/EffPathfind.java b/src/main/java/ch/njol/skript/effects/EffPathfind.java index fed033debdf..fb69241237d 100644 --- a/src/main/java/ch/njol/skript/effects/EffPathfind.java +++ b/src/main/java/ch/njol/skript/effects/EffPathfind.java @@ -1,25 +1,24 @@ package ch.njol.skript.effects; -import org.bukkit.Location; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Mob; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.config.Node; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Mob; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Pathfind") -@Description({"Make an entity pathfind towards a location or another entity. Not all entities can pathfind. " + - "If the pathfinding target is another entity, the entities may or may not continuously follow the target."}) +@Description({ + "Make an entity pathfind towards a location or another entity. Not all entities can pathfind.", + "If the pathfinding target is another entity, the entities may or may not continuously follow the target." +}) @Examples({ "make all creepers pathfind towards player", "make all cows stop pathfinding", @@ -27,7 +26,7 @@ }) @Since("2.7") @RequiredPlugins("Paper") -public class EffPathfind extends Effect { +public class EffPathfind extends Effect implements SyntaxRuntimeErrorProducer { static { if (Skript.classExists("org.bukkit.entity.Mob") && Skript.methodExists(Mob.class, "getPathfinder")) @@ -36,17 +35,15 @@ public class EffPathfind extends Effect { "make %livingentities% stop (pathfinding|moving)"); } + private Node node; private Expression entities; - - @Nullable - private Expression speed; - - @Nullable - private Expression target; + private @Nullable Expression speed; + private @Nullable Expression target; @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); entities = (Expression) exprs[0]; target = matchedPattern == 0 ? exprs[1] : null; speed = matchedPattern == 0 ? (Expression) exprs[2] : null; @@ -55,21 +52,38 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override protected void execute(Event event) { - Object target = this.target != null ? this.target.getSingle(event) : null; - double speed = this.speed != null ? this.speed.getOptionalSingle(event).orElse(1).doubleValue() : 1; + Object target = null; + if (this.target != null) { + target = this.target.getSingle(event); + if (target == null) + warning("The provided target was not set, so defaulted to stop pathfinding.", this.target.toString()); + } + + double speed = 1; + if (this.speed != null) { + Number postSpeed = this.speed.getSingle(event); + if (postSpeed == null) + warning("The provided speed was not set, so defaulted to 1.", this.speed.toString()); + } + for (LivingEntity entity : entities.getArray(event)) { - if (!(entity instanceof Mob)) - continue; - if (target instanceof LivingEntity) { - ((Mob) entity).getPathfinder().moveTo((LivingEntity) target, speed); - } else if (target instanceof Location) { - ((Mob) entity).getPathfinder().moveTo((Location) target, speed); - } else if (this.target == null) { - ((Mob) entity).getPathfinder().stopPathfinding(); + if (entity instanceof Mob mob) { + if (target instanceof LivingEntity livingEntity) { + mob.getPathfinder().moveTo(livingEntity, speed); + } else if (target instanceof Location location) { + mob.getPathfinder().moveTo(location, speed); + } else if (this.target == null) { + mob.getPathfinder().stopPathfinding(); + } } } } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { if (target == null) diff --git a/src/main/java/ch/njol/skript/effects/EffPlaySound.java b/src/main/java/ch/njol/skript/effects/EffPlaySound.java index f0efd49446a..105cbdf502e 100644 --- a/src/main/java/ch/njol/skript/effects/EffPlaySound.java +++ b/src/main/java/ch/njol/skript/effects/EffPlaySound.java @@ -3,6 +3,7 @@ import ch.njol.skript.Skript; import ch.njol.skript.bukkitutil.SoundUtils; import ch.njol.skript.bukkitutil.sounds.SoundReceiver; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; @@ -16,6 +17,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; import java.util.ArrayList; import java.util.List; @@ -45,7 +47,7 @@ }) @RequiredPlugins("Minecraft 1.18.1+ (entity emitters), Paper 1.19.4+ or Adventure API 4.12.0+ (sound seed)") @Since("2.2-dev28, 2.4 (sound categories), 2.9 (sound seed & entity emitter)") -public class EffPlaySound extends Effect { +public class EffPlaySound extends Effect implements SyntaxRuntimeErrorProducer { // <=1.17: // Player - Location - Sound/String @@ -79,6 +81,8 @@ public class EffPlaySound extends Effect { ); } + private Node node; + private Expression sounds; @@ -97,6 +101,7 @@ public class EffPlaySound extends Effect { @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); sounds = (Expression) exprs[0]; int index = 1; if (HAS_SEED) @@ -119,17 +124,42 @@ protected void execute(Event event) { OptionalLong seed = OptionalLong.empty(); if (this.seed != null) { Number number = this.seed.getSingle(event); - if (number != null) + if (number == null) { + warning("The provided seed was not set, so defaulted to no seed.", this.seed.toString()); + } else { seed = OptionalLong.of(number.longValue()); + } + } + + SoundCategory category = SoundCategory.MASTER; + if (this.category != null) { + SoundCategory provided = this.category.getSingle(event); + if (provided == null) { + warning("The provided sound category was not set, so defaulted to master.", this.category.toString()); + } else { + category = provided; + } + } + + float volume = 1; + if (this.volume != null) { + Number provided = this.volume.getSingle(event); + if (provided == null) { + warning("The provided volume was not set, so defaulted to 1.", this.volume.toString()); + } else { + volume = provided.floatValue(); + } + } + + float pitch = 1; + if (this.pitch != null) { + Number provided = this.pitch.getSingle(event); + if (provided == null) { + warning("The provided pitch was not set, so defaulted to 1.", this.pitch.toString()); + } else { + pitch = provided.floatValue(); + } } - SoundCategory category = this.category == null ? SoundCategory.MASTER : this.category.getOptionalSingle(event) - .orElse(SoundCategory.MASTER); - float volume = this.volume == null ? 1 : this.volume.getOptionalSingle(event) - .orElse(1) - .floatValue(); - float pitch = this.pitch == null ? 1 : this.pitch.getOptionalSingle(event) - .orElse(1) - .floatValue(); // validate strings List validSounds = new ArrayList<>(); @@ -140,8 +170,10 @@ protected void execute(Event event) { validSounds.add(key); } - if (validSounds.isEmpty()) + if (validSounds.isEmpty()) { + error("No provided sounds were valid.", sounds.toString()); return; + } // play sounds if (players != null) { @@ -181,6 +213,11 @@ protected void execute(Event event) { } } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { StringBuilder builder = new StringBuilder() diff --git a/src/main/java/ch/njol/skript/effects/EffPlayerInfoVisibility.java b/src/main/java/ch/njol/skript/effects/EffPlayerInfoVisibility.java index b07182bad1a..31dd21a2183 100644 --- a/src/main/java/ch/njol/skript/effects/EffPlayerInfoVisibility.java +++ b/src/main/java/ch/njol/skript/effects/EffPlayerInfoVisibility.java @@ -1,44 +1,45 @@ package ch.njol.skript.effects; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - -import com.destroystokyo.paper.event.server.PaperServerListPingEvent; import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Events; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.config.Node; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import com.destroystokyo.paper.event.server.PaperServerListPingEvent; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Player Info Visibility") -@Description({"Sets whether all player related information is hidden in the server list.", - "The Vanilla Minecraft client will display ??? (dark gray) instead of player counts and will not show the", - "hover hist when hiding player info.", - "The version string can override the ???.", - "Also the Online Players Count and", - "Max Players expressions will return -1 when hiding player info."}) -@Examples({"hide player info", - "hide player related information in the server list", - "reveal all player related info"}) +@Description({ + "Sets whether all player related information is hidden in the server list.", + "The Vanilla Minecraft client will display ??? (dark gray) instead of player counts and will not show the", + "hover hist when hiding player info.", + "The version string can override the ???.", + "Also the Online Players Count and", + "Max Players expressions will return -1 when hiding player info." +}) +@Examples({ + "hide player info", + "hide player related information in the server list", + "reveal all player related info" +}) @Since("2.3") -@RequiredPlugins("Paper 1.12.2 or newer") +@RequiredPlugins("Paper 1.12.2+") @Events("server list ping") -public class EffPlayerInfoVisibility extends Effect { +public class EffPlayerInfoVisibility extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffPlayerInfoVisibility.class, - "hide [all] player [related] info[rmation] [(in|on|from) [the] server list]", - "(show|reveal) [all] player [related] info[rmation] [(in|to|on|from) [the] server list]"); + "hide [all] player [related] info[rmation] [(in|on|from) [the] server list]", + "(show|reveal) [all] player [related] info[rmation] [(in|to|on|from) [the] server list]"); } private static final boolean PAPER_EVENT_EXISTS = Skript.classExists("com.destroystokyo.paper.event.server.PaperServerListPingEvent"); + private Node node; private boolean shouldHide; @Override @@ -53,20 +54,28 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye Skript.error("Can't change the player info visibility anymore after the server list ping event has already passed"); return false; } + node = getParser().getNode(); shouldHide = matchedPattern == 0; return true; } @Override - protected void execute(Event e) { - if (!(e instanceof PaperServerListPingEvent)) + protected void execute(Event event) { + if (!(event instanceof PaperServerListPingEvent serverListPingEvent)) { + error("The 'player info visibility' effect can only be used in a 'server list ping' event."); return; + } - ((PaperServerListPingEvent) e).setHidePlayers(shouldHide); + serverListPingEvent.setHidePlayers(shouldHide); + } + + @Override + public Node getNode() { + return node; } @Override - public String toString(@Nullable Event e, boolean debug) { + public String toString(@Nullable Event event, boolean debug) { return (shouldHide ? "hide" : "show") + " player info in the server list"; } diff --git a/src/main/java/ch/njol/skript/effects/EffPoison.java b/src/main/java/ch/njol/skript/effects/EffPoison.java index af04ccd4f13..2a78515eb7e 100644 --- a/src/main/java/ch/njol/skript/effects/EffPoison.java +++ b/src/main/java/ch/njol/skript/effects/EffPoison.java @@ -1,12 +1,7 @@ package ch.njol.skript.effects; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.Event; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -15,37 +10,43 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.util.Timespan; +import ch.njol.skript.util.Timespan.TimePeriod; import ch.njol.util.Kleenean; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Event; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; -/** - * @author Peter Güttinger - */ @Name("Poison/Cure") -@Description("Poison or cure a creature.") -@Examples({"poison the player", - "poison the victim for 20 seconds", - "cure the player from poison"}) +@Description("Poison or cure a living entity.") +@Examples({ + "poison the player", + "poison the victim for 20 seconds", + "cure the player from poison" +}) @Since("1.3.2") -public class EffPoison extends Effect { +public class EffPoison extends Effect implements SyntaxRuntimeErrorProducer { + static { Skript.registerEffect(EffPoison.class, - "poison %livingentities% [for %-timespan%]", - "(cure|unpoison) %livingentities% [(from|of) poison]"); + "poison %livingentities% [for %-timespan%]", + "(cure|unpoison) %livingentities% [(from|of) poison]"); } private final static int DEFAULT_DURATION = 15 * 20; // 15 seconds on hard difficulty, same as EffPotion - - @SuppressWarnings("null") - private Expression entites; - @Nullable - private Expression duration; - + + private Node node; + private Expression entities; + private @Nullable Expression duration; private boolean cure; - - @SuppressWarnings({"unchecked", "null"}) + @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { - entites = (Expression) exprs[0]; + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); + entities = (Expression) exprs[0]; if (matchedPattern == 0) duration = (Expression) exprs[1]; cure = matchedPattern == 1; @@ -53,29 +54,41 @@ public boolean init(final Expression[] exprs, final int matchedPattern, final } @Override - public String toString(final @Nullable Event e, final boolean debug) { - return "poison " + entites.toString(e, debug); - } - - @Override - protected void execute(final Event e) { - for (final LivingEntity le : entites.getArray(e)) { + protected void execute(Event event) { + int duration = DEFAULT_DURATION; + if (this.duration != null) { + Timespan timespan = this.duration.getSingle(event); + if (timespan == null) { + warning("The provided duration was not set, so defaulted to 15 seconds.", this.duration.toString()); + } else { + duration = (int) timespan.getAs(TimePeriod.TICK); // this will truncate anything greater than Integer.MAX_VALUE + } + } + + for (LivingEntity entity : entities.getArray(event)) { if (!cure) { - Timespan dur; - int d = (int) (duration != null && (dur = duration.getSingle(e)) != null ? - (dur.getAs(Timespan.TimePeriod.TICK) >= Integer.MAX_VALUE ? Integer.MAX_VALUE : dur.getAs(Timespan.TimePeriod.TICK)) : DEFAULT_DURATION); - if (le.hasPotionEffect(PotionEffectType.POISON)) { - for (final PotionEffect pe : le.getActivePotionEffects()) { - if (pe.getType() != PotionEffectType.POISON) + if (entity.hasPotionEffect(PotionEffectType.POISON)) { + for (PotionEffect effect : entity.getActivePotionEffects()) { + if (effect.getType() != PotionEffectType.POISON) continue; - d += pe.getDuration(); + duration += effect.getDuration(); } } - le.addPotionEffect(new PotionEffect(PotionEffectType.POISON, d, 0), true); + entity.addPotionEffect(new PotionEffect(PotionEffectType.POISON, duration, 0), true); } else { - le.removePotionEffect(PotionEffectType.POISON); + entity.removePotionEffect(PotionEffectType.POISON); } } } - + + @Override + public Node getNode() { + return node; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "poison " + entities.toString(event, debug); + } + } diff --git a/src/main/java/ch/njol/skript/effects/EffPotion.java b/src/main/java/ch/njol/skript/effects/EffPotion.java index ed347492860..22a35e1ead1 100644 --- a/src/main/java/ch/njol/skript/effects/EffPotion.java +++ b/src/main/java/ch/njol/skript/effects/EffPotion.java @@ -1,12 +1,7 @@ package ch.njol.skript.effects; -import org.bukkit.entity.LivingEntity; -import org.bukkit.event.Event; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -17,6 +12,12 @@ import ch.njol.skript.util.PotionEffectUtils; import ch.njol.skript.util.Timespan; import ch.njol.util.Kleenean; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Event; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Potion Effects") @Description("Apply or remove potion effects to/from entities.") @@ -31,18 +32,19 @@ "apply potion effects of player's tool to player", "apply haste potion of tier 3 without any particles whilst hiding the potion icon to the player # Hide potions" }) -@Since( - "2.0, 2.2-dev27 (ambient and particle-less potion effects), " + - "2.5 (replacing existing effect), 2.5.2 (potion effects), " + +@Since({ + "2.0", + "2.2-dev27 (ambient and particle-less potion effects)", + "2.5 (replacing existing effect), 2.5.2 (potion effects)", "2.7 (icon and infinite)" -) -public class EffPotion extends Effect { +}) +public class EffPotion extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffPotion.class, - "apply %potioneffects% to %livingentities%", - "apply infinite [:ambient] [potion of] %potioneffecttypes% [potion] [[[of] tier] %-number%] [noparticles:without [any] particles] [icon:(whilst hiding [the]|without (the|a)) [potion] icon] to %livingentities% [replacing:replacing [the] existing effect]", - "apply [:ambient] [potion of] %potioneffecttypes% [potion] [[[of] tier] %-number%] [noparticles:without [any] particles] [icon:(whilst hiding [the]|without (the|a)) [potion] icon] to %livingentities% [for %-timespan%] [replacing:replacing [the] existing effect]" + "apply %potioneffects% to %livingentities%", + "apply infinite [:ambient] [potion of] %potioneffecttypes% [potion] [[[of] tier] %-number%] [noparticles:without [any] particles] [icon:(whilst hiding [the]|without (the|a)) [potion] icon] to %livingentities% [replacing:replacing [the] existing effect]", + "apply [:ambient] [potion of] %potioneffecttypes% [potion] [[[of] tier] %-number%] [noparticles:without [any] particles] [icon:(whilst hiding [the]|without (the|a)) [potion] icon] to %livingentities% [for %-timespan%] [replacing:replacing [the] existing effect]" ); } @@ -50,15 +52,14 @@ public class EffPotion extends Effect { private final static int DEFAULT_DURATION = 15 * 20; // 15 seconds, same as EffPoison + private Node node; + private Expression potions; private Expression entities; private Expression effects; - @Nullable - private Expression duration; - - @Nullable - private Expression tier; + private @Nullable Expression duration; + private @Nullable Expression tier; private boolean replaceExisting; // Replace the existing potion if present. private boolean potionEffect; // PotionEffects rather than PotionEffectTypes. @@ -70,6 +71,7 @@ public class EffPotion extends Effect { @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); potionEffect = matchedPattern == 0; replaceExisting = parseResult.hasTag("replacing"); noParticles = parseResult.hasTag("noparticles"); @@ -96,19 +98,31 @@ protected void execute(Event event) { PotionEffectUtils.addEffects(livingEntity, effects.getArray(event)); } else { PotionEffectType[] potionEffectTypes = potions.getArray(event); - if (potionEffectTypes.length == 0) + if (potionEffectTypes.length == 0) { + error("No provided potion effect types were valid.", potions.toString()); return; + } + int tier = 0; - if (this.tier != null) - tier = this.tier.getOptionalSingle(event).orElse(1).intValue() - 1; + if (this.tier != null) { + Number provided = this.tier.getSingle(event); + if (provided == null) { + warning("The provided potion effect tier was not set, so defaulted to 0.", this.tier.toString()); + } else { + tier = provided.intValue() - 1; + } + } int duration = infinite ? (COMPATIBLE ? -1 : Integer.MAX_VALUE) : DEFAULT_DURATION; if (this.duration != null && !infinite) { Timespan timespan = this.duration.getSingle(event); - if (timespan == null) + if (timespan == null) { + error("The provided duration was not set.", this.duration.toString()); return; - duration = (int) Math.min(timespan.getAs(Timespan.TimePeriod.TICK), Integer.MAX_VALUE); + } + duration = (int) timespan.getAs(Timespan.TimePeriod.TICK); // truncates to Integer.MAX_VALUE } + for (LivingEntity entity : entities.getArray(event)) { for (PotionEffectType potionEffectType : potionEffectTypes) { int finalDuration = duration; @@ -128,6 +142,11 @@ protected void execute(Event event) { } } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { if (potionEffect) { diff --git a/src/main/java/ch/njol/skript/effects/EffPush.java b/src/main/java/ch/njol/skript/effects/EffPush.java index 6dedfd3f7ca..ec0e68f605d 100644 --- a/src/main/java/ch/njol/skript/effects/EffPush.java +++ b/src/main/java/ch/njol/skript/effects/EffPush.java @@ -1,11 +1,7 @@ package ch.njol.skript.effects; -import org.bukkit.entity.Entity; -import org.bukkit.event.Event; -import org.bukkit.util.Vector; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -15,30 +11,34 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.util.Direction; import ch.njol.util.Kleenean; +import org.bukkit.entity.Entity; +import org.bukkit.event.Event; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; -/** - * @author Peter Güttinger - */ @Name("Push") @Description("Push entities around.") -@Examples({"push the player upwards", - "push the victim downwards at speed 0.5"}) +@Examples({ + "push the player upwards", + "push the victim downwards at speed 0.5" +}) @Since("1.4.6") -public class EffPush extends Effect { +public class EffPush extends Effect implements SyntaxRuntimeErrorProducer { + static { Skript.registerEffect(EffPush.class, "(push|thrust) %entities% %direction% [(at|with) (speed|velocity|force) %-number%]"); } - - @SuppressWarnings("null") + + private Node node; private Expression entities; - @SuppressWarnings("null") private Expression direction; - @Nullable - private Expression speed = null; - - @SuppressWarnings({"unchecked", "null"}) + private @Nullable Expression speed = null; + @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); entities = (Expression) exprs[0]; direction = (Expression) exprs[1]; speed = (Expression) exprs[2]; @@ -46,30 +46,40 @@ public boolean init(final Expression[] exprs, final int matchedPattern, final } @Override - protected void execute(final Event e) { - final Direction d = direction.getSingle(e); - if (d == null) + protected void execute(Event event) { + Direction direction = this.direction.getSingle(event); + if (direction == null) { + error("The provided direction was not set.", this.direction.toString()); return; - final Number v = speed != null ? speed.getSingle(e) : null; - if (speed != null && v == null) + } + + Number velocity = speed != null ? speed.getSingle(event) : null; + if (speed != null && velocity == null) { + error("The provided velocity was not set.", this.speed.toString()); return; - final Entity[] ents = entities.getArray(e); - for (final Entity en : ents) { - assert en != null; - final Vector mod = d.getDirection(en); - if (v != null) - mod.normalize().multiply(v.doubleValue()); + } + + for (Entity entity : entities.getArray(event)) { + Vector mod = direction.getDirection(entity); + if (velocity != null) + mod.normalize().multiply(velocity.doubleValue()); if (!(Double.isFinite(mod.getX()) && Double.isFinite(mod.getY()) && Double.isFinite(mod.getZ()))) { - // Some component of the mod vector is not finite, so just stop + // Some component of the mod vector is not finite, so just stop{ + error("Either the X, Y, or Z component of the direction vector was not finite.", this.direction.toString()); return; } - en.setVelocity(en.getVelocity().add(mod)); // REMIND add NoCheatPlus exception to players + entity.setVelocity(entity.getVelocity().add(mod)); // REMIND add NoCheatPlus exception to players } } - + @Override - public String toString(final @Nullable Event e, final boolean debug) { - return "push " + entities.toString(e, debug) + " " + direction.toString(e, debug) + (speed != null ? " at speed " + speed.toString(e, debug) : ""); + public Node getNode() { + return node; } + @Override + public String toString(@Nullable Event event, boolean debug) { + return "push " + entities.toString(event, debug) + " " + direction.toString(event, debug) + (speed != null ? " at speed " + speed.toString(event, debug) : ""); + } + } diff --git a/src/main/java/ch/njol/skript/effects/EffPvP.java b/src/main/java/ch/njol/skript/effects/EffPvP.java index c97cd92e142..3b636e9e633 100644 --- a/src/main/java/ch/njol/skript/effects/EffPvP.java +++ b/src/main/java/ch/njol/skript/effects/EffPvP.java @@ -1,9 +1,5 @@ package ch.njol.skript.effects; -import org.bukkit.World; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -13,43 +9,44 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.World; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; -/** - * @author Peter Güttinger - */ @Name("PvP") @Description("Set the PvP state for a given world.") -@Examples({"enable PvP #(current world only)", - "disable PvP in all worlds"}) +@Examples({ + "enable PvP #(current world only)", + "disable PvP in all worlds" +}) @Since("1.3.4") public class EffPvP extends Effect { static { Skript.registerEffect(EffPvP.class, "enable PvP [in %worlds%]", "disable PVP [in %worlds%]"); } - - @SuppressWarnings("null") + private Expression worlds; private boolean enable; - - @SuppressWarnings({"unchecked", "null"}) + @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { worlds = (Expression) exprs[0]; enable = matchedPattern == 0; return true; } @Override - protected void execute(final Event e) { - for (final World w : worlds.getArray(e)) { - w.setPVP(enable); + protected void execute(Event event) { + for (World world : worlds.getArray(event)) { + world.setPVP(enable); } } @Override - public String toString(final @Nullable Event e, final boolean debug) { - return (enable ? "enable" : "disable") + " PvP in " + worlds.toString(e, debug); + public String toString(@Nullable Event event, boolean debug) { + return (enable ? "enable" : "disable") + " PvP in " + worlds.toString(event, debug); } } diff --git a/src/main/java/ch/njol/skript/effects/EffReplace.java b/src/main/java/ch/njol/skript/effects/EffReplace.java index 0141ad2fd8d..b997238aa54 100644 --- a/src/main/java/ch/njol/skript/effects/EffReplace.java +++ b/src/main/java/ch/njol/skript/effects/EffReplace.java @@ -30,10 +30,10 @@ import java.util.regex.Pattern; @Name("Replace") -@Description( - "Replaces all occurrences of a given text or regex with another text. Please note that you can only change " + - "variables and a few expressions, e.g. a message or a line of a sign." -) +@Description({ + "Replaces all occurrences of a given text or regex with another text.", + "Please note that you can only change variables and a few expressions, e.g. a message or a line of a sign." +}) @Examples({ "replace \"\" in {_msg} with \"[%name of player's tool%]\"", "replace every \"&\" with \"§\" in line 1 of targeted block", @@ -45,7 +45,12 @@ "", "replace all stone and dirt in player's inventory and player's top inventory with diamond" }) -@Since("2.0, 2.2-dev24 (multiple strings, items in inventory), 2.5 (replace first, case sensitivity), 2.10 (regex)") +@Since({ + "2.0", + "2.2-dev24 (multiple strings, items in inventory)", + "2.5 (replace first, case sensitivity)", + "2.10 (regex)" +}) public class EffReplace extends Effect { static { @@ -65,8 +70,7 @@ public class EffReplace extends Effect { private boolean caseSensitive = false; @Override - public boolean init(Expression[] expressions, int matchedPattern, - Kleenean isDelayed, ParseResult parseResult) { + public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { haystack = expressions[1 + matchedPattern % 2]; replaceString = matchedPattern < 4; replaceFirst = parseResult.hasTag("first"); diff --git a/src/main/java/ch/njol/skript/effects/EffResetTitle.java b/src/main/java/ch/njol/skript/effects/EffResetTitle.java index 541038b42fb..28a36b4b7c0 100644 --- a/src/main/java/ch/njol/skript/effects/EffResetTitle.java +++ b/src/main/java/ch/njol/skript/effects/EffResetTitle.java @@ -1,9 +1,5 @@ package ch.njol.skript.effects; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -13,38 +9,43 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; @Name("Title - Reset") @Description("Resets the title of the player to the default values.") -@Examples({"reset the titles of all players", - "reset the title"}) +@Examples({ + "reset the titles of all players", + "reset the title" +}) @Since("2.3") public class EffResetTitle extends Effect { static { Skript.registerEffect(EffResetTitle.class, - "reset [the] title[s] [of %players%]", - "reset [the] %players%'[s] title[s]"); + "reset [the] title[s] [of %players%]", + "reset [the] %players%'[s] title[s]"); } - - @SuppressWarnings("null") + private Expression recipients; @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { recipients = (Expression) exprs[0]; return true; } @Override - protected void execute(Event e) { - for (Player recipient : recipients.getArray(e)) + protected void execute(Event event) { + for (Player recipient : recipients.getArray(event)) recipient.resetTitle(); } @Override - public String toString(@Nullable Event e, boolean debug) { - return "reset the title of " + recipients.toString(e, debug); + public String toString(@Nullable Event event, boolean debug) { + return "reset the title of " + recipients.toString(event, debug); } } diff --git a/src/main/java/ch/njol/skript/effects/EffRespawn.java b/src/main/java/ch/njol/skript/effects/EffRespawn.java index b0460be02d1..331529a202e 100644 --- a/src/main/java/ch/njol/skript/effects/EffRespawn.java +++ b/src/main/java/ch/njol/skript/effects/EffRespawn.java @@ -1,12 +1,5 @@ package ch.njol.skript.effects; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.event.player.PlayerRespawnEvent; -import org.bukkit.scheduler.BukkitRunnable; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -17,11 +10,22 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.log.ErrorQuality; import ch.njol.util.Kleenean; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.Nullable; @Name("Force Respawn") -@Description("Forces player(s) to respawn if they are dead. If this is called without delay from death event, one tick is waited before respawn attempt.") -@Examples({"on death of player:", - "\tforce event-player to respawn",}) +@Description({ + "Forces player(s) to respawn if they are dead.", + "If this is called without delay from death event, one tick is waited before respawn attempt." +}) +@Examples({ + "on death of player:", + "\tforce event-player to respawn" +}) @Since("2.2-dev21") public class EffRespawn extends Effect { @@ -29,14 +33,12 @@ public class EffRespawn extends Effect { Skript.registerEffect(EffRespawn.class, "force %players% to respawn"); } - @SuppressWarnings("null") private Expression players; - private boolean forceDelay; @Override @SuppressWarnings("unchecked") - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { if (getParser().isCurrentEvent(PlayerRespawnEvent.class)) { // Just in case someone tries to do this Skript.error("Respawning the player in a respawn event is not possible", ErrorQuality.SEMANTIC_ERROR); return false; @@ -49,26 +51,26 @@ public boolean init(final Expression[] exprs, final int matchedPattern, final } @Override - protected void execute(final Event e) { - for (final Player p : players.getArray(e)) { + protected void execute(Event event) { + for (Player player : players.getArray(event)) { if (forceDelay) { // Use Bukkit runnable new BukkitRunnable() { @Override public void run() { - p.spigot().respawn(); + player.spigot().respawn(); } }.runTaskLater(Skript.getInstance(), 1); } else { // Just respawn - p.spigot().respawn(); + player.spigot().respawn(); } } } @Override - public String toString(final @Nullable Event e, final boolean debug) { - return "force " + players.toString(e, debug) + " to respawn"; + public String toString(@Nullable Event event, boolean debug) { + return "force " + players.toString(event, debug) + " to respawn"; } } diff --git a/src/main/java/ch/njol/skript/effects/EffReturn.java b/src/main/java/ch/njol/skript/effects/EffReturn.java index ab4dafbe16b..60e5e528af2 100644 --- a/src/main/java/ch/njol/skript/effects/EffReturn.java +++ b/src/main/java/ch/njol/skript/effects/EffReturn.java @@ -20,7 +20,7 @@ import java.util.List; @Name("Return") -@Description("Makes a trigger or a section (e.g. a function) return a value") +@Description("Makes a trigger or a section (e.g. a function) return a value.") @Examples({ "function double(i: number) :: number:", "\treturn 2 * {_i}", diff --git a/src/main/java/ch/njol/skript/effects/EffRing.java b/src/main/java/ch/njol/skript/effects/EffRing.java index ba441f9b22c..14ab58f1a94 100644 --- a/src/main/java/ch/njol/skript/effects/EffRing.java +++ b/src/main/java/ch/njol/skript/effects/EffRing.java @@ -1,14 +1,12 @@ package ch.njol.skript.effects; import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.RequiredPlugins; -import ch.njol.skript.doc.Since; +import ch.njol.skript.config.Node; +import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.SyntaxStringBuilder; import ch.njol.skript.util.Direction; import ch.njol.util.Kleenean; import org.bukkit.block.Bell; @@ -18,6 +16,7 @@ import org.bukkit.entity.Entity; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; @Name("Ring Bell") @Description({ @@ -26,45 +25,43 @@ "A bell can only ring in two directions, and the direction is determined by which way the bell is facing.", "By default, the bell will ring in the direction it is facing.", }) -@Examples({"make player ring target-block"}) +@Examples("make player ring target-block") @RequiredPlugins("Spigot 1.19.4+") @Since("2.9.0") -public class EffRing extends Effect { +public class EffRing extends Effect implements SyntaxRuntimeErrorProducer { static { if (Skript.classExists("org.bukkit.block.Bell") && Skript.methodExists(Bell.class, "ring", Entity.class, BlockFace.class)) Skript.registerEffect(EffRing.class, - "ring %blocks% [from [the]] [%-direction%]", - "(make|let) %entity% ring %blocks% [from [the]] [%-direction%]" + "ring %blocks% [from [the]] [%-direction%]", + "(make|let) %entity% ring %blocks% [from [the]] [%-direction%]" ); } - @Nullable - private Expression entity; - - @SuppressWarnings("NotNullFieldNotInitialized") + private Node node; + private @Nullable Expression entity; private Expression blocks; - - @Nullable - private Expression direction; + private @Nullable Expression direction; @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + node = getParser().getNode(); entity = matchedPattern == 0 ? null : (Expression) exprs[0]; blocks = (Expression) exprs[matchedPattern]; direction = (Expression) exprs[matchedPattern + 1]; return true; } - @Nullable - private BlockFace getBlockFace(Event event) { + private @Nullable BlockFace getBlockFace(Event event) { if (this.direction == null) return null; Direction direction = this.direction.getSingle(event); - if (direction == null) + if (direction == null) { + warning("The provided direction was not set, so defaulted to none.", this.direction.toString()); return null; + } return Direction.getFacing(direction.getDirection(), true); } @@ -72,21 +69,34 @@ private BlockFace getBlockFace(Event event) { @Override protected void execute(Event event) { BlockFace blockFace = getBlockFace(event); - Entity actualEntity = entity == null ? null : entity.getSingle(event); + Entity actualEntity = null; + if (entity != null) { + actualEntity = entity.getSingle(event); + if (actualEntity == null) + warning("The provided entity was not set, so defaulted to none.", entity.toString()); + } for (Block block : blocks.getArray(event)) { BlockState state = block.getState(false); - if (state instanceof Bell) { - Bell bell = (Bell) state; + if (state instanceof Bell bell) bell.ring(actualEntity, blockFace); - } } } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { - return (entity != null ? "make " + entity.toString(event, debug) + " " : "") + - "ring " + blocks.toString(event, debug) + " from " + (direction != null ? direction.toString(event, debug) : ""); + SyntaxStringBuilder builder = new SyntaxStringBuilder(event, debug); + if (entity != null) + builder.append("make", entity); + builder.append("ring", blocks); + if (direction != null) + builder.append("from", direction); + return builder.toString(); } } diff --git a/src/main/java/ch/njol/skript/effects/EffRun.java b/src/main/java/ch/njol/skript/effects/EffRun.java index 91e31119162..ddc204849d1 100644 --- a/src/main/java/ch/njol/skript/effects/EffRun.java +++ b/src/main/java/ch/njol/skript/effects/EffRun.java @@ -1,6 +1,7 @@ package ch.njol.skript.effects; import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.*; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; @@ -12,26 +13,28 @@ import ch.njol.util.Kleenean; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; import org.skriptlang.skript.util.Executable; @Name("Run (Experimental)") @Description("Executes a task (a function). Any returned result is discarded.") @Examples({ - "set {_function} to the function named \"myFunction\"", - "run {_function}", - "run {_function} with arguments {_things::*}", + "set {_function} to the function named \"myFunction\"", + "run {_function}", + "run {_function} with arguments {_things::*}", }) @Since("2.10") @Keywords({"run", "execute", "reflection", "function"}) -@SuppressWarnings({"rawtypes", "unchecked"}) -public class EffRun extends Effect { +@SuppressWarnings("rawtypes") +public class EffRun extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffRun.class, - "run %executable% [arguments:with arg[ument]s %-objects%]", - "execute %executable% [arguments:with arg[ument]s %-objects%]"); + "run %executable% [arguments:with arg[ument]s %-objects%]", + "execute %executable% [arguments:with arg[ument]s %-objects%]"); } + private Node node; // We don't bother with the generic type here because we have no way to verify it // from the expression, and it makes casting more difficult to no benefit. private Expression executable; @@ -40,9 +43,11 @@ public class EffRun extends Effect { private boolean hasArguments; @Override + @SuppressWarnings("unchecked") public boolean init(Expression[] expressions, int pattern, Kleenean isDelayed, ParseResult result) { if (!this.getParser().hasExperiment(Feature.SCRIPT_REFLECTION)) return false; + this.node = this.getParser().getNode(); this.executable = ((Expression) expressions[0]); this.hasArguments = result.hasTag("arguments"); if (hasArguments) { @@ -64,22 +69,33 @@ public boolean init(Expression[] expressions, int pattern, Kleenean isDelayed @Override protected void execute(Event event) { Executable task = executable.getSingle(event); - if (task == null) + if (task == null) { + error("The provided executable was not set.", executable.toString()); return; + } + Object[] arguments; if (task instanceof DynamicFunctionReference reference) { Expression validated = reference.validate(input); - if (validated == null) + if (validated == null) { + error("Couldn't validate the function reference.", executable.toString()); return; + } arguments = validated.getArray(event); } else if (hasArguments) { arguments = this.arguments.getArray(event); } else { arguments = new Object[0]; } + //noinspection unchecked task.execute(event, arguments); } + @Override + public Node getNode() { + return node; + } + @Override public String toString(@Nullable Event event, boolean debug) { if (hasArguments) diff --git a/src/main/java/ch/njol/skript/effects/EffScriptFile.java b/src/main/java/ch/njol/skript/effects/EffScriptFile.java index d49d41d3112..fed4d595d46 100644 --- a/src/main/java/ch/njol/skript/effects/EffScriptFile.java +++ b/src/main/java/ch/njol/skript/effects/EffScriptFile.java @@ -2,21 +2,23 @@ import ch.njol.skript.ScriptLoader; import ch.njol.skript.Skript; +import ch.njol.skript.config.Node; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.registrations.Feature; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.UnknownNullability; -import org.skriptlang.skript.lang.script.Script; -import ch.njol.skript.lang.SkriptParser; import ch.njol.skript.util.FileUtils; import ch.njol.util.Kleenean; import ch.njol.util.OpenCloseable; import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.UnknownNullability; +import org.skriptlang.skript.lang.script.Script; +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; import java.io.File; import java.io.FileFilter; @@ -37,7 +39,7 @@ "reload {_script}" }) @Since("2.4, 2.10 (unloading)") -public class EffScriptFile extends Effect { +public class EffScriptFile extends Effect implements SyntaxRuntimeErrorProducer { static { Skript.registerEffect(EffScriptFile.class, @@ -55,13 +57,15 @@ public class EffScriptFile extends Effect { private int mark; + private Node node; private @UnknownNullability Expression scriptNameExpression; private @UnknownNullability Expression