Skip to content

Commit

Permalink
ExprElement converted expression (#4268)
Browse files Browse the repository at this point in the history
  • Loading branch information
TPGamesNL authored Aug 30, 2021
1 parent 5326f26 commit afc6c28
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 40 deletions.
102 changes: 67 additions & 35 deletions src/main/java/ch/njol/skript/expressions/ExprElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -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: <a href='#ExprRandom'>random</a>"})
@Examples("give a random element out of {free items::*} to the player")
@Since("2.0")
public class ExprElement extends SimpleExpression<Object> {

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> 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<Number>) 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 <R> Expression<? extends R> getConvertedExpression(Class<R>... to) {
Expression<? extends R> 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<? extends R>) exprElement;
}

@Override
public boolean isSingle() {
return true;
}

@Override
public Class<? extends Object> 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<Number>) 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);
}

}
11 changes: 6 additions & 5 deletions src/main/java/ch/njol/util/StringUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
Expand Down

0 comments on commit afc6c28

Please sign in to comment.