diff --git a/src/main/java/ch/njol/skript/expressions/ExprAffectedEntities.java b/src/main/java/ch/njol/skript/expressions/ExprAffectedEntities.java index ee463e3ea8d..3666dd45d4f 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprAffectedEntities.java +++ b/src/main/java/ch/njol/skript/expressions/ExprAffectedEntities.java @@ -74,19 +74,18 @@ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { if (!(event instanceof AreaEffectCloudApplyEvent areaEvent)) return; - LivingEntity[] entities = (LivingEntity[]) delta; switch (mode) { case REMOVE: - for (LivingEntity entity : entities) { - areaEvent.getAffectedEntities().remove(entity); + for (Object entity : delta) { + areaEvent.getAffectedEntities().remove((LivingEntity) entity); } break; case SET: areaEvent.getAffectedEntities().clear(); // FALLTHROUGH case ADD: - for (LivingEntity entity : entities) { - areaEvent.getAffectedEntities().add(entity); + for (Object entity : delta) { + areaEvent.getAffectedEntities().add((LivingEntity) entity); } break; case RESET, DELETE: diff --git a/src/main/java/ch/njol/skript/expressions/ExprElement.java b/src/main/java/ch/njol/skript/expressions/ExprElement.java index 86b454f88db..0d1bb8fdc3c 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprElement.java +++ b/src/main/java/ch/njol/skript/expressions/ExprElement.java @@ -10,7 +10,6 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.simplification.SimplifiedLiteral; import ch.njol.skript.lang.util.SimpleExpression; -import ch.njol.skript.registrations.Feature; import ch.njol.skript.util.LiteralUtils; import ch.njol.skript.util.Patterns; import ch.njol.util.Kleenean; @@ -48,17 +47,11 @@ public class ExprElement extends SimpleExpression implements KeyProviderExpression { private static final Patterns PATTERNS = new Patterns<>(new Object[][]{ - {"[the] (first|1:last) element [out] of %objects%", new ElementType[] {ElementType.FIRST_ELEMENT, ElementType.LAST_ELEMENT}}, - {"[the] (first|1:last) %integer% elements [out] of %objects%", new ElementType[] {ElementType.FIRST_X_ELEMENTS, ElementType.LAST_X_ELEMENTS}}, - {"[a] random element [out] of %objects%", new ElementType[] {ElementType.RANDOM}}, - {"[the] %integer%(st|nd|rd|th) [1:[to] last] element [out] of %objects%", new ElementType[] {ElementType.ORDINAL, ElementType.TAIL_END_ORDINAL}}, - {"[the] elements (from|between) %integer% (to|and) %integer% [out] of %objects%", new ElementType[] {ElementType.RANGE}}, - - {"[the] (first|next|1:last) element (of|in) %queue%", new ElementType[] {ElementType.FIRST_ELEMENT, ElementType.LAST_ELEMENT}}, - {"[the] (first|1:last) %integer% elements (of|in) %queue%", new ElementType[] {ElementType.FIRST_X_ELEMENTS, ElementType.LAST_X_ELEMENTS}}, - {"[a] random element (of|in) %queue%", new ElementType[] {ElementType.RANDOM}}, - {"[the] %integer%(st|nd|rd|th) [1:[to] last] element (of|in) %queue%", new ElementType[] {ElementType.ORDINAL, ElementType.TAIL_END_ORDINAL}}, - {"[the] elements (from|between) %integer% (to|and) %integer% (of|in) %queue%", new ElementType[] {ElementType.RANGE}}, + {"[the] (first|1:last) element [out] (of|in) %objects%", new ElementType[]{ElementType.FIRST_ELEMENT, ElementType.LAST_ELEMENT}}, + {"[the] (first|1:last) %integer% elements [out] (of|in) %objects%", new ElementType[]{ElementType.FIRST_X_ELEMENTS, ElementType.LAST_X_ELEMENTS}}, + {"[a] random element [out] (of|in) %objects%", new ElementType[]{ElementType.RANDOM}}, + {"[the] %integer%(st|nd|rd|th) [1:[to] last] element [out] (of|in) %objects%", new ElementType[]{ElementType.ORDINAL, ElementType.TAIL_END_ORDINAL}}, + {"[the] elements (from|between) %integer% (to|and) %integer% [out] (of|in) %objects%", new ElementType[]{ElementType.RANGE}}, }); static { @@ -132,23 +125,16 @@ public Iterator apply(Iterator iterator, int startIndex, int endIndex) private final Map> cache = new WeakHashMap<>(); private Expression expr; - private @Nullable Expression startIndex, endIndex; + private @Nullable Expression startIndex, endIndex; private ElementType type; - private boolean queue; private boolean keyed; @Override @SuppressWarnings("unchecked") public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { ElementType[] types = PATTERNS.getInfo(matchedPattern); - this.queue = matchedPattern > 4; - if (queue && !this.getParser().hasExperiment(Feature.QUEUES)) - return false; - if (queue) { - this.expr = (Expression) expressions[expressions.length - 1]; - } else { - this.expr = LiteralUtils.defendExpression(expressions[expressions.length - 1]); - } + this.expr = LiteralUtils.defendExpression(expressions[expressions.length - 1]); + switch (type = types[parseResult.mark]) { case RANGE: endIndex = (Expression) expressions[1]; @@ -160,13 +146,11 @@ public boolean init(Expression[] expressions, int matchedPattern, Kleenean is break; } this.keyed = KeyProviderExpression.canReturnKeys(this.expr); - return queue || LiteralUtils.canInitSafely(expr); + return LiteralUtils.canInitSafely(expr); } @Override protected T @Nullable [] get(Event event) { - if (queue) - return this.getFromQueue(event); if (keyed) { KeyedValue.UnzippedKeyValues unzipped = KeyedValue.unzip(keyedIterator(event)); cache.put(event, unzipped.keys()); @@ -174,7 +158,19 @@ public boolean init(Expression[] expressions, int matchedPattern, Kleenean is T[] empty = (T[]) Array.newInstance(getReturnType(), 0); return unzipped.values().toArray(empty); } - Iterator iterator = iterator(event); + + Iterator iterator; + if (expr.isSingle()) { + T single = expr.getSingle(event); + if (single instanceof SkriptQueue queue) { + return this.getFromQueue(event, queue); + } else { + iterator = transformIterator(event, Iterators.singletonIterator(single)); + } + } else { + iterator = transformIterator(event, expr.iterator(event)); + } + assert iterator != null; //noinspection unchecked return Iterators.toArray(iterator, (Class) getReturnType()); @@ -191,8 +187,13 @@ public boolean init(Expression[] expressions, int matchedPattern, Kleenean is @Override public @Nullable Iterator iterator(Event event) { - if (queue) - return Optional.ofNullable(getFromQueue(event)).map(Iterators::forArray).orElse(null); + if (expr.isSingle()) { + T single = expr.getSingle(event); + if (single instanceof SkriptQueue queue) { + return Optional.ofNullable(getFromQueue(event, queue)).map(Iterators::forArray).orElse(null); + } + return Iterators.singletonIterator(single); + } Iterator iterator = expr.iterator(event); return transformIterator(event, iterator); } @@ -224,8 +225,7 @@ private Iterator transformIterator(Event event, @Nullable Iterator ite } @SuppressWarnings("unchecked") - private T @Nullable [] getFromQueue(Event event) { - SkriptQueue queue = (SkriptQueue) expr.getSingle(event); + private T @Nullable [] getFromQueue(Event event, SkriptQueue queue) { if (queue == null) return null; Integer startIndex = 0, endIndex = 0; @@ -242,11 +242,13 @@ private Iterator transformIterator(Event event, @Nullable Iterator ite return switch (type) { case FIRST_ELEMENT -> CollectionUtils.array((T) queue.pollFirst()); case LAST_ELEMENT -> CollectionUtils.array((T) queue.pollLast()); - case RANDOM -> CollectionUtils.array((T) queue.removeSafely(ThreadLocalRandom.current().nextInt(0, queue.size()))); + case RANDOM -> + CollectionUtils.array((T) queue.removeSafely(ThreadLocalRandom.current().nextInt(0, queue.size()))); case ORDINAL -> CollectionUtils.array((T) queue.removeSafely(startIndex - 1)); case TAIL_END_ORDINAL -> CollectionUtils.array((T) queue.removeSafely(queue.size() - startIndex)); case FIRST_X_ELEMENTS -> CollectionUtils.array((T[]) queue.removeRangeSafely(0, startIndex)); - case LAST_X_ELEMENTS -> CollectionUtils.array((T[]) queue.removeRangeSafely(queue.size() - startIndex, queue.size())); + case LAST_X_ELEMENTS -> + CollectionUtils.array((T[]) queue.removeRangeSafely(queue.size() - startIndex, queue.size())); case RANGE -> { boolean reverse = startIndex > endIndex; T[] elements = CollectionUtils.array((T[]) queue.removeRangeSafely(Math.min(startIndex, endIndex) - 1, Math.max(startIndex, endIndex))); @@ -284,7 +286,6 @@ public Expression getConvertedExpression(Class... to) { exprElement.startIndex = startIndex; exprElement.endIndex = endIndex; exprElement.type = type; - exprElement.queue = queue; return exprElement; } @@ -295,37 +296,33 @@ public boolean isSingle() { @Override public Class getReturnType() { - if (queue) - return (Class) Object.class; - return expr.getReturnType(); + Class returnType = expr.getReturnType(); + //noinspection unchecked + return returnType == SkriptQueue.class ? (Class) Object.class : returnType; } @Override public Class[] possibleReturnTypes() { - if (!queue) { - return expr.possibleReturnTypes(); - } - return super.possibleReturnTypes(); + Class returnType = expr.getReturnType(); + //noinspection unchecked + return returnType == SkriptQueue.class ? new Class[]{Object.class} : expr.possibleReturnTypes(); } @Override public boolean canReturn(Class returnType) { - if (!queue) { - return expr.canReturn(returnType); - } - return super.canReturn(returnType); + return returnType == SkriptQueue.class || expr.canReturn(returnType); } - - @Override + + @Override public Expression simplify() { - if (!queue && expr instanceof Literal - && type != ElementType.RANDOM - && (startIndex == null || startIndex instanceof Literal) - && (endIndex == null || endIndex instanceof Literal)) { + if (expr instanceof Literal + && type != ElementType.RANDOM + && (startIndex == null || startIndex instanceof Literal) + && (endIndex == null || endIndex instanceof Literal)) { return SimplifiedLiteral.fromExpression(this); } return this; - } + } @Override public String toString(@Nullable Event event, boolean debug) { diff --git a/src/test/skript/tests/regressions/8548-first queue element.sk b/src/test/skript/tests/regressions/8548-first queue element.sk new file mode 100644 index 00000000000..c6ac89ac47b --- /dev/null +++ b/src/test/skript/tests/regressions/8548-first queue element.sk @@ -0,0 +1,7 @@ +using queues + +test "8548 first queue element": + set {queue} to a new queue + add "hello" and "there" to {queue} + assert the first element of {queue} is "hello" + assert the first element of {queue} is "there"