diff --git a/src/main/java/ch/njol/skript/conditions/CondLidState.java b/src/main/java/ch/njol/skript/conditions/CondLidState.java new file mode 100644 index 00000000000..2b24bb226e8 --- /dev/null +++ b/src/main/java/ch/njol/skript/conditions/CondLidState.java @@ -0,0 +1,63 @@ +package ch.njol.skript.conditions; + +import ch.njol.skript.Skript; +import ch.njol.skript.conditions.base.PropertyCondition; +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.Expression; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.util.Kleenean; +import org.bukkit.block.Block; +import org.bukkit.block.Lidded; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +@Name("Lid Is Open/Closed") +@Description("Check to see whether lidded blocks (chests, shulkers, etc.) are open or closed.") +@Examples({ + "if the lid of {_chest} is closed:", + "\topen the lid of {_block}" +}) +@Since("INSERT VERSION") +public class CondLidState extends PropertyCondition { + + static { + Skript.registerCondition(CondLidState.class, ConditionType.PROPERTY, + "[the] lid[s] of %blocks% (is|are) (open[ed]|:close[d])", + "[the] lid[s] of %blocks% (isn't|is not|aren't|are not) (open[ed]|:close[d])", + "%blocks%'[s] lid[s] (is|are) (open[ed]|:close[d])", + "%blocks%'[s] lid[s] (isn't|is not|aren't|are not) (open[ed]|:close[d])" + ); + } + + private boolean checkOpen; + private Expression blocks; + + @Override + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + checkOpen = !parseResult.hasTag("close"); + blocks = (Expression) exprs[0]; + setExpr(blocks); + setNegated(matchedPattern == 1 || matchedPattern == 3); + return true; + } + + @Override + public boolean check(Block block) { + return (block.getState() instanceof Lidded lidded) ? lidded.isOpen() == checkOpen : false; + } + + @Override + protected String getPropertyName() { + return (checkOpen ? "opened" : "closed") + " lid state"; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "the lids of " + blocks.toString(event, debug) + (isNegated() ? "are not " : "are ") + (checkOpen ? "opened" : "closed"); + } + +} diff --git a/src/main/java/ch/njol/skript/effects/EffLidState.java b/src/main/java/ch/njol/skript/effects/EffLidState.java new file mode 100644 index 00000000000..6d9c1b8e241 --- /dev/null +++ b/src/main/java/ch/njol/skript/effects/EffLidState.java @@ -0,0 +1,62 @@ +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.Since; +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.block.Block; +import org.bukkit.block.Lidded; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +@Name("Open/Close Lid") +@Description("Open or close the lid of the block(s).") +@Examples({ + "open the lid of {_chest}", + "close the lid of {_blocks::*}" +}) +@Since("INSERT VERSION") +public class EffLidState extends Effect { + + static { + Skript.registerEffect(EffLidState.class, + "(open|:close) [the] lid[s] (of|for) %blocks%", + "(open|:close) %blocks%'[s] lid[s]" + ); + } + + private boolean setOpen; + private Expression blocks; + + @Override + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + setOpen = !parseResult.hasTag("close"); + blocks = (Expression) exprs[0]; + return true; + } + + @Override + protected void execute(Event event) { + for (Block block : blocks.getArray(event)) { + if (block.getState() instanceof Lidded lidded) { + if (setOpen) { + lidded.open(); + } else { + lidded.close(); + } + } + } + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return (setOpen ? "open" : "close") + " lid of " + blocks.toString(event, debug); + } + +} diff --git a/src/test/skript/tests/syntaxes/effects/EffLidStates.sk b/src/test/skript/tests/syntaxes/effects/EffLidStates.sk new file mode 100644 index 00000000000..f5e99ea6c36 --- /dev/null +++ b/src/test/skript/tests/syntaxes/effects/EffLidStates.sk @@ -0,0 +1,18 @@ +test "lid states": + set {_loc} to spawn of world "world" ~ vector(3,0,0) + set block at {_loc} to chest + set {_locs::*} to {_loc} + loop 2 times: + add {_loc} ~ vector(loop-number,0,0) to {_locs::*} + set block at {_locs::2} to ender chest + set block at {_locs::3} to barrel + + open the lids for (blocks at {_locs::*}) + assert the lids of (blocks at {_locs::*}) are opened with "1 or more lidded blocks are not open" + assert the lids of (blocks at {_locs::*}) are not closed with "1 or more lidded block are closed" + + close the lids for (blocks at {_locs::*}) + assert the lids of (blocks at {_locs::*}) are closed with "1 or more lidded block are not closed" + assert the lids of (blocks at {_locs::*}) are not opened with "1 or more lidded blocks are open" + + set blocks at {_locs::*} to air