Skip to content

ExprAttachedBlock Plural Support #7897

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

Open
wants to merge 9 commits into
base: dev/feature
Choose a base branch
from
Open
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 68 additions & 23 deletions src/main/java/ch/njol/skript/expressions/ExprAttachedBlock.java
Original file line number Diff line number Diff line change
@@ -1,40 +1,80 @@
package ch.njol.skript.expressions;

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.expressions.base.SimplePropertyExpression;
import ch.njol.skript.doc.*;
import ch.njol.skript.expressions.base.PropertyExpression;
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.block.Block;
import org.bukkit.entity.AbstractArrow;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Projectile;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

@Name("Arrow Attached Block")
@Description("Returns the attached block of an arrow.")
@Examples("set hit block of last shot arrow to diamond block")
@Since("2.8.0")
public class ExprAttachedBlock extends SimplePropertyExpression<Projectile, Block> {
import java.util.HashSet;
import java.util.Set;

private static final boolean HAS_ABSTRACT_ARROW = Skript.classExists("org.bukkit.entity.AbstractArrow");
@Name("Arrow Attached Block")
@Description({
"Returns the attached block of an arrow.",
"If running Paper 1.21.4+, the plural version of the expression should be used as it is more reliable compared to the single version."
})
@Example("set hit block of last shot arrow to diamond block")
@Example("""
on projectile hit:
wait 1 tick
break attached blocks of event-projectile
kill event-projectile
""")
@Since("2.8.0, INSERT VERSION (multiple blocks)")
public class ExprAttachedBlock extends PropertyExpression<Projectile, Block> {

static {
register(ExprAttachedBlock.class, Block.class, "(attached|hit) block", "projectiles");
Skript.registerExpression(ExprAttachedBlock.class, Block.class, ExpressionType.PROPERTY,
"[the] (attached|hit) block[multiple:s] of %projectiles%",
"%projectiles%'[s] (attached|hit) block[multiple:s]"
);
}

// TODO - remove this when 1.21.4 is the minimum supported version
private static final boolean SUPPORTS_MULTIPLE = Skript.methodExists(AbstractArrow.class, "getAttachedBlocks");

private boolean isMultiple;

@Override
@Nullable
public Block convert(Projectile projectile) {
if (HAS_ABSTRACT_ARROW) {
if (projectile instanceof AbstractArrow) {
return ((AbstractArrow) projectile).getAttachedBlock();
public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
isMultiple = parseResult.hasTag("multiple");
setExpr((Expression<? extends Projectile>) expressions[0]);

if (!SUPPORTS_MULTIPLE && isMultiple) {
Skript.error("The plural version of this expression is only available in Paper 1.21.4+.");
return false;
}

if (SUPPORTS_MULTIPLE && !isMultiple) {
Skript.warning("It is recommended to use the plural version of this expression instead.");
}

return true;
}

@Override
protected Block[] get(Event event, Projectile[] source) {
Set<Object> blocks = new HashSet<>();

for (Projectile projectile : source) {
if (projectile instanceof AbstractArrow abstractArrow) {
if (isMultiple) {
blocks.addAll(abstractArrow.getAttachedBlocks());
} else {
blocks.add(abstractArrow.getAttachedBlock());
}
}
} else if (projectile instanceof Arrow) {
return ((Arrow) projectile).getAttachedBlock();
}
return null;

return blocks.toArray(new Block[0]);
}

@Override
Expand All @@ -43,8 +83,13 @@ public Class<? extends Block> getReturnType() {
}

@Override
public String getPropertyName() {
return "attached block";
public boolean isSingle() {
return !isMultiple;
}

@Override
public String toString(@Nullable Event event, boolean debug) {
return "attached block" + (isMultiple ? "s" : "");
}

}