Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Breakable Syntax to Existing Unbreakable Syntaxes #6160

Merged
merged 12 commits into from
May 8, 2024
33 changes: 20 additions & 13 deletions src/main/java/ch/njol/skript/conditions/CondIsUnbreakable.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,45 @@
*/
package ch.njol.skript.conditions;

import org.bukkit.inventory.meta.ItemMeta;

import ch.njol.skript.Skript;
import ch.njol.skript.aliases.ItemType;
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.RequiredPlugins;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;

@Name("Is Unbreakable")
@Description("Checks whether an item is unbreakable.")
@Examples("if event-item is unbreakable")
@Since("2.5.1")
@RequiredPlugins("Minecraft 1.11+")
@Examples({
"if event-item is unbreakable",
"if player's tool is breakable"
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved
})
@Since("2.5.1, INSERT VERSION (breakable)")
public class CondIsUnbreakable extends PropertyCondition<ItemType> {

static {
if (Skript.methodExists(ItemMeta.class, "isUnbreakable")) {
register(CondIsUnbreakable.class, "unbreakable", "itemtypes");
}
register(CondIsUnbreakable.class, "[:un]breakable", "itemtypes");
}


private boolean negated;

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
negated = !parseResult.hasTag("un");
NotSoDelayed marked this conversation as resolved.
Show resolved Hide resolved
return super.init(exprs, matchedPattern, isDelayed, parseResult);
}

@Override
public boolean check(ItemType item) {
return item.getItemMeta().isUnbreakable();
return item.getItemMeta().isUnbreakable() ^ negated;
}

@Override
protected String getPropertyName() {
return "unbreakable";
return negated ? "breakable" : "unbreakable";
}

}
71 changes: 25 additions & 46 deletions src/main/java/ch/njol/skript/expressions/ExprUnbreakable.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,67 +18,47 @@
*/
package ch.njol.skript.expressions;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Arrays;

import org.bukkit.event.Event;
import org.bukkit.inventory.meta.ItemMeta;
import org.eclipse.jdt.annotation.Nullable;

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.Since;
import ch.njol.skript.expressions.base.PropertyExpression;
import ch.njol.skript.expressions.base.SimplePropertyExpression;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;
import org.bukkit.inventory.meta.ItemMeta;

@Name("Unbreakable Items")
@Description("Creates unbreakable copies of given items.")
@Examples("unbreakable iron sword #Creates unbreakable iron sword")
@Since("2.2-dev13b")
public class ExprUnbreakable extends PropertyExpression<ItemType, ItemType> {
@Examples({
"unbreakable iron sword",
"breakable {_weapon}"
})
@Since("2.2-dev13b, INSERT VERSION (breakable)")
public class ExprUnbreakable extends SimplePropertyExpression<ItemType, ItemType> {

@Nullable
private static final MethodHandle setUnbreakableMethod;

static {
Skript.registerExpression(ExprUnbreakable.class, ItemType.class, ExpressionType.PROPERTY, "unbreakable %itemtypes%");

MethodHandle handle;
try {
handle = MethodHandles.lookup().findVirtual(Class.forName("package org.bukkit.inventory.meta.ItemMeta.Spigot"),
"setUnbreakable", MethodType.methodType(void.class, boolean.class));
} catch (NoSuchMethodException | IllegalAccessException | ClassNotFoundException e) {
handle = null;
}
setUnbreakableMethod = handle;
Skript.registerExpression(ExprUnbreakable.class, ItemType.class, ExpressionType.PROPERTY, "[:un]breakable %itemtypes%");
}

@SuppressWarnings({"unchecked", "null"})

private boolean unbreakable;

@Override
public boolean init(final Expression<?>[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) {
setExpr((Expression<? extends ItemType>) exprs[0]);
return true;
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
unbreakable = parseResult.hasTag("un");
return super.init(exprs, matchedPattern, isDelayed, parseResult);
}

@Override
protected ItemType[] get(final Event e, final ItemType[] source) {
return get(source, itemType -> {
ItemType clone = itemType.clone();

ItemMeta meta = clone.getItemMeta();
meta.setUnbreakable(true);
clone.setItemMeta(meta);

return clone;
});
@Override
public ItemType convert(ItemType itemType) {
ItemType clone = itemType.clone();
ItemMeta meta = clone.getItemMeta();
meta.setUnbreakable(unbreakable);
clone.setItemMeta(meta);
return clone;
}

@Override
Expand All @@ -87,9 +67,8 @@ public Class<? extends ItemType> getReturnType() {
}

@Override
public String toString(@Nullable Event e, boolean debug) {
if (e == null)
return "unbreakable items";
return "unbreakable " + Arrays.toString(getExpr().getAll(e));
protected String getPropertyName() {
return unbreakable ? "unbreakable" : "breakable";
}

}
15 changes: 15 additions & 0 deletions src/test/skript/tests/syntaxes/expressions/ExprUnbreakable.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
test "unbreakable":
set {_breakable1} to iron sword
assert {_breakable1} is breakable with "Iron Sword should be breakable ##1"
assert {_breakable1} is not unbreakable with "Iron Sword should be not unbreakable ##1"
set {_unbreakable1} to unbreakable iron sword
assert {_unbreakable1} is unbreakable with "Iron Sword should be unbreakable ##2"
assert {_unbreakable1} is not breakable with "Iron Sword should be not breakable ##2"
set {_breakable2} to breakable {_unbreakable1}
assert {_breakable2} is breakable with "Iron Sword should be breakable ##2"
assert {_breakable2} is not unbreakable with "Iron Sword should be not unbreakable ##2"
set {_unbreakable2} to unbreakable {_breakable1}
assert {_unbreakable2} is unbreakable with "Iron Sword should be unbreakable ##2"
assert {_unbreakable2} is not breakable with "Iron Sword should be not breakable ##2"
assert {_null} is not breakable with "CondIsUnbreakable on unset variable check failed ##1"
assert {_null} is not unbreakable with "CondIsUnbreakable on unset variable check failed ##2"