From afc6c287cd2ae78c0c341383669f075b6b82e0dc Mon Sep 17 00:00:00 2001 From: TPGamesNL <29547183+TPGamesNL@users.noreply.github.com> Date: Mon, 30 Aug 2021 18:52:39 +0200 Subject: [PATCH] ExprElement converted expression (#4268) --- .../njol/skript/expressions/ExprElement.java | 102 ++++++++++++------ src/main/java/ch/njol/util/StringUtils.java | 11 +- 2 files changed, 73 insertions(+), 40 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprElement.java b/src/main/java/ch/njol/skript/expressions/ExprElement.java index 6659499e556..2daecf559bb 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprElement.java +++ b/src/main/java/ch/njol/skript/expressions/ExprElement.java @@ -25,93 +25,125 @@ import ch.njol.skript.doc.Since; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ExpressionType; +import ch.njol.skript.lang.Literal; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.skript.util.LiteralUtils; import ch.njol.util.Kleenean; +import ch.njol.util.StringUtils; import ch.njol.util.coll.CollectionUtils; import org.bukkit.event.Event; import org.eclipse.jdt.annotation.Nullable; import java.lang.reflect.Array; -import java.util.Iterator; -/** - * @author Peter Güttinger - */ @Name("Element of") @Description({"The first, last or a random element of a set, e.g. a list variable.", "See also: random"}) @Examples("give a random element out of {free items::*} to the player") @Since("2.0") public class ExprElement extends SimpleExpression { - + static { Skript.registerExpression(ExprElement.class, Object.class, ExpressionType.PROPERTY, "(-1¦[the] first|1¦[the] last|0¦[a] random|2¦%-number%(st|nd|rd|th)) element [out] of %objects%"); } - + private int element; - - @SuppressWarnings("null") + private Expression expr; @Nullable private Expression number; - - @SuppressWarnings("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) { expr = LiteralUtils.defendExpression(exprs[1]); number = (Expression) exprs[0]; element = parseResult.mark; return LiteralUtils.canInitSafely(expr); } - + @Override @Nullable - @SuppressWarnings("null") - protected Object[] get(final Event e) { - final Object o; + protected Object[] get(Event e) { + Object[] os = expr.getArray(e); + if (os.length == 0) + return null; + Object o; if (element == -1) { - final Iterator iter = expr.iterator(e); - if (iter == null || !iter.hasNext()) - return null; - o = iter.next(); + o = os[0]; } else if (element == 1) { - final Object[] os = expr.getArray(e); - if (os.length == 0) - return null; o = os[os.length - 1]; } else if (element == 2) { - final Object[] os = expr.getArray(e); - final Number number = this.number.getSingle(e); + Number number = this.number.getSingle(e); if (number == null || number.intValue() - 1 >= os.length || number.intValue() - 1 < 0) return null; o = os[number.intValue() - 1]; } else { - final Object[] os = expr.getArray(e); - if (os.length == 0) - return null; o = CollectionUtils.getRandom(os); } - final Object[] r = (Object[]) Array.newInstance(getReturnType(), 1); + Object[] r = (Object[]) Array.newInstance(getReturnType(), 1); r[0] = o; return r; } - + + @Override + @Nullable + @SuppressWarnings("unchecked") + public Expression getConvertedExpression(Class... to) { + Expression convExpr = expr.getConvertedExpression(to); + if (convExpr == null) + return null; + + ExprElement exprElement = new ExprElement(); + exprElement.element = this.element; + exprElement.expr = convExpr; + exprElement.number = this.number; + return (Expression) exprElement; + } + @Override public boolean isSingle() { return true; } - + @Override - public Class getReturnType() { + public Class getReturnType() { return expr.getReturnType(); } - + @Override - public String toString(final @Nullable Event e, final boolean debug) { - return (element == 0 ? "a " : "the ") + (element == -1 ? "first" : element == 1 ? "last" : "random") + " element of " + expr.toString(e, debug); + public String toString(@Nullable Event e, boolean debug) { + String prefix; + switch (element) { + case -1: + prefix = "the first"; + break; + case 1: + prefix = "the last"; + break; + case 0: + prefix = "a random"; + break; + case 2: + assert number != null; + prefix = "the "; + // Proper ordinal number + if (number instanceof Literal) { + Number number = ((Literal) this.number).getSingle(); + if (number == null) + prefix += this.number.toString(e, debug) + "th"; + else + prefix += StringUtils.fancyOrderNumber(number.intValue()); + } else { + prefix += number.toString(e, debug) + "th"; + } + break; + default: + throw new IllegalStateException(); + } + return prefix + " element of " + expr.toString(e, debug); } - + } diff --git a/src/main/java/ch/njol/util/StringUtils.java b/src/main/java/ch/njol/util/StringUtils.java index 9776d00a1bd..1fa271111e3 100644 --- a/src/main/java/ch/njol/util/StringUtils.java +++ b/src/main/java/ch/njol/util/StringUtils.java @@ -41,13 +41,14 @@ public static void checkIndices(final String s, final int start, final int end) * @param i the number * @return 1st, 2nd, 3rd, 4th, etc. */ - public static String fancyOrderNumber(final int i) { - final int imod10 = i % 10; - if (imod10 == 1) + public static String fancyOrderNumber(int i) { + int iModTen = i % 10; + int iModHundred = i % 100; + if (iModTen == 1 && iModHundred != 11) return i + "st"; - if (imod10 == 2) + if (iModTen == 2 && iModHundred != 12) return i + "nd"; - if (imod10 == 3) + if (iModTen == 3 && iModHundred != 13) return i + "rd"; return i + "th"; }