Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
16 changes: 10 additions & 6 deletions src/main/java/ch/njol/skript/conditions/CondLeashed.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,25 @@
import ch.njol.skript.doc.Example;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Entity;
import io.papermc.paper.entity.Leashable;

@Name("Is Leashed")
@Description("Checks to see if an entity is currently leashed.")
@Example("target entity is leashed")
@Since("2.5")
public class CondLeashed extends PropertyCondition<LivingEntity> {
@Since("2.5, INSERT VERSION (all leashable entities)")
public class CondLeashed extends PropertyCondition<Entity> {

static {
register(CondLeashed.class, PropertyType.BE, "leashed", "livingentities");
register(CondLeashed.class, PropertyType.BE, "leashed", "entities");
}

@Override
public boolean check(LivingEntity entity) {
return entity.isLeashed();
public boolean check(Entity entity) {
if (entity instanceof Leashable leashable) {
return leashable.isLeashed();
}
return false;
}

@Override
Expand Down
41 changes: 19 additions & 22 deletions src/main/java/ch/njol/skript/effects/EffLeash.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ch.njol.skript.effects;

import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

Expand All @@ -14,31 +13,30 @@
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;
import io.papermc.paper.entity.Leashable;

@Name("Leash entities")
@Description({
"Leash living entities to other entities. When trying to leash an Ender Dragon, Wither, Player, or a Bat, this effect will not work.",
"See <a href=\"https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/LivingEntity.html#setLeashHolder(org.bukkit.entity.Entity)\">Spigot's Javadocs for more info</a>."
"Leash entities to other entities, or unleash them.",
"Most mobs, iron golems, snow golems, and boats can be leashed."
})
@Example("""
on right click:
leash event-entity to player
send "&aYou leashed &2%event-entity%!" to player
""")
@Since("2.3")
@Since("2.3, INSERT VERSION (all leashable entities)")
public class EffLeash extends Effect {

static {
Skript.registerEffect(EffLeash.class,
"(leash|lead) %livingentities% to %entity%",
"make %entity% (leash|lead) %livingentities%",
"un(leash|lead) [holder of] %livingentities%");
"(leash|lead) %entities% to %entity%",
"make %entity% (leash|lead) %entities%",
"un(leash|lead) [holder of] %entities%");
}

@SuppressWarnings("null")
private Expression<Entity> holder;
@SuppressWarnings("null")
private Expression<LivingEntity> targets;
private Expression<Entity> targets;
private boolean leash;

@Override
Expand All @@ -47,24 +45,23 @@ public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelaye
leash = matchedPattern != 2;
if (leash) {
holder = (Expression<Entity>) exprs[1 - matchedPattern];
targets = (Expression<LivingEntity>) exprs[matchedPattern];
targets = (Expression<Entity>) exprs[matchedPattern];
} else {
targets = (Expression<LivingEntity>) exprs[0];
targets = (Expression<Entity>) exprs[0];
}
return true;
}

@Override
protected void execute(Event e) {
if (leash) {
Entity holder = this.holder.getSingle(e);
if (holder == null)
return;
for (LivingEntity target : targets.getArray(e))
target.setLeashHolder(holder);
} else {
for (LivingEntity target : targets.getArray(e))
target.setLeashHolder(null);
protected void execute(Event event) {
Entity holder = leash ? this.holder.getSingle(event) : null;
if (leash && holder == null)
return;

for (Entity target : targets.getArray(event)) {
if (target instanceof Leashable leashable) {
leashable.setLeashHolder(holder);
}
}
}

Expand Down
18 changes: 10 additions & 8 deletions src/main/java/ch/njol/skript/expressions/ExprLeashHolder.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
package ch.njol.skript.expressions;

import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.Nullable;

import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Example;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.expressions.base.SimplePropertyExpression;
import io.papermc.paper.entity.Leashable;

@Name("Leash Holder")
@Description("The leash holder of a living entity.")
@Description("The leash holder of an entity.")
@Example("set {_example} to the leash holder of the target mob")
@Since("2.3")
public class ExprLeashHolder extends SimplePropertyExpression<LivingEntity, Entity> {
@Since("2.3, INSERT VERSION (all leashable entities)")
public class ExprLeashHolder extends SimplePropertyExpression<Entity, Entity> {

static {
register(ExprLeashHolder.class, Entity.class, "leash holder[s]", "livingentities");
register(ExprLeashHolder.class, Entity.class, "leash holder[s]", "entities");
}

@Override
@Nullable
public Entity convert(LivingEntity entity) {
return entity.isLeashed() ? entity.getLeashHolder() : null;
public @Nullable Entity convert(Entity entity) {
if (entity instanceof Leashable leashable) {
return leashable.isLeashed() ? leashable.getLeashHolder() : null;
}
return null;
}

@Override
Expand Down
23 changes: 23 additions & 0 deletions src/test/skript/tests/syntaxes/conditions/CondLeashed.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
test "is leashed condition":
spawn a wolf at test-location
set {_wolf} to last spawned entity
assert {_wolf} is not leashed with "wolf should not be leashed initially"
assert {_wolf} isn't leashed with "wolf should not be leashed initially (alternate syntax)"
clear entity within {_wolf}

spawn an armor stand at test-location
set {_stand} to last spawned entity
assert {_stand} is not leashed with "non-leashable entity should return false for is leashed"
clear entity within {_stand}

spawn a wolf at test-location
set {_leash_holder} to last spawned entity
spawn a wolf at test-location
set {_wolf} to last spawned entity
assert {_wolf} is not leashed with "wolf should not be leashed initially"
leash {_wolf} to {_leash_holder}
assert {_wolf} is leashed with "wolf should be leashed after leashing"
unleash {_wolf}
assert {_wolf} is not leashed with "wolf should not be leashed after unleashing"
clear entity within {_wolf}
clear entity within {_leash_holder}
36 changes: 36 additions & 0 deletions src/test/skript/tests/syntaxes/effects/EffLeash.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
test "leash effect":
spawn a wolf at test-location
set {_leash_holder} to last spawned entity
spawn a wolf at test-location
set {_wolf} to last spawned entity
assert {_wolf} is not leashed with "wolf should not be leashed initially"
leash {_wolf} to {_leash_holder}
assert {_wolf} is leashed with "wolf should be leashed after leash effect"
assert leash holder of {_wolf} is {_leash_holder} with "wolf should be leashed to the correct entity"
unleash {_wolf}
assert {_wolf} is not leashed with "wolf should be unleashed after unleash effect"
clear entity within {_wolf}
clear entity within {_leash_holder}

spawn a wolf at test-location
set {_leash_holder} to last spawned entity
spawn 3 wolves at test-location
assert size of all wolves >= 4 with "at least 4 wolves should be spawned"
leash all wolves to {_leash_holder}
loop all wolves:
if loop-entity is not {_leash_holder}:
assert loop-entity is leashed with "all wolves (except holder) should be leashed"
assert leash holder of loop-entity is {_leash_holder} with "all wolves should be leashed to the correct entity"
unleash all wolves
loop all wolves:
assert loop-entity is not leashed with "all wolves should be unleashed"
clear all entities

# Test leashing entity to itself
spawn a wolf at test-location
set {_self} to last spawned entity
leash {_self} to {_self}
# Check if self-leashing is supported by the Leashable API
if {_self} is leashed:
assert leash holder of {_self} is {_self} with "if self-leashing works, holder should be itself"
Comment on lines +33 to +35
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit iffy, we should really be checking exact versions it should work on.
But whatever, it's probably ok.

clear entity within {_self}
20 changes: 20 additions & 0 deletions src/test/skript/tests/syntaxes/expressions/ExprLeashHolder.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
test "leash holder expression":
spawn a wolf at test-location
set {_leash_holder} to last spawned entity
spawn a wolf at test-location
set {_wolf} to last spawned entity
assert {_wolf} is not leashed with "wolf should not be leashed initially"
assert leash holder of {_wolf} is not set with "leash holder should not be set initially"
leash {_wolf} to {_leash_holder}
assert {_wolf} is leashed with "wolf should be leashed after leashing"
assert leash holder of {_wolf} is set with "leash holder should be set after leashing"
assert leash holder of {_wolf} is {_leash_holder} with "leash holder should be the entity it was leashed to"
unleash {_wolf}
assert leash holder of {_wolf} is not set with "leash holder should not be set after unleashing"
clear entity within {_wolf}
clear entity within {_leash_holder}

spawn an armor stand at test-location
set {_stand} to last spawned entity
assert leash holder of {_stand} is not set with "non-leashable entity should return null for leash holder"
clear entity within {_stand}