Skip to content

Commit c0f6ba4

Browse files
Entity/Block Persistence + Entity Despawnable (#7564)
* Initial Commit * Remove JUnit Test Discrepancies * Fix Example * Update Docs * Requested Changes * Readd "not" * Fixxy Fix --------- Co-authored-by: Efnilite <[email protected]>
1 parent 1c2846f commit c0f6ba4

File tree

5 files changed

+249
-0
lines changed

5 files changed

+249
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package ch.njol.skript.conditions;
2+
3+
import ch.njol.skript.conditions.base.PropertyCondition;
4+
import ch.njol.skript.doc.Description;
5+
import ch.njol.skript.doc.Examples;
6+
import ch.njol.skript.doc.Name;
7+
import ch.njol.skript.doc.Since;
8+
import org.bukkit.entity.LivingEntity;
9+
10+
@Name("Can Despawn")
11+
@Description({
12+
"Check if an entity can despawn when the chunk they're located at is unloaded.",
13+
"More information on what and when entities despawn can be found at "
14+
+ "<a href=\"https://minecraft.wiki/w/Mob_spawning#Despawning\">reference</a>."
15+
})
16+
@Examples({
17+
"if last spawned entity can despawn on chunk unload:",
18+
"\tmake last spawned entity not despawn on chunk unload"
19+
})
20+
@Since("INSERT VERSION")
21+
public class CondEntityUnload extends PropertyCondition<LivingEntity> {
22+
23+
static {
24+
register(CondEntityUnload.class, PropertyType.CAN, "despawn (on chunk unload|when far away)", "livingentities");
25+
}
26+
27+
@Override
28+
public boolean check(LivingEntity entity) {
29+
return entity.getRemoveWhenFarAway();
30+
}
31+
32+
@Override
33+
protected String getPropertyName() {
34+
return "despawn on chunk unload";
35+
}
36+
37+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package ch.njol.skript.conditions;
2+
3+
import ch.njol.skript.conditions.base.PropertyCondition;
4+
import ch.njol.skript.doc.Description;
5+
import ch.njol.skript.doc.Examples;
6+
import ch.njol.skript.doc.Name;
7+
import ch.njol.skript.doc.Since;
8+
import org.bukkit.block.Block;
9+
import org.bukkit.block.data.type.Leaves;
10+
import org.bukkit.entity.Entity;
11+
12+
@Name("Is Persistent")
13+
@Description({
14+
"Whether entities, players, or leaves are persistent.",
15+
"Persistence of entities is whether they are retained through server restarts.",
16+
"Persistence of leaves is whether they should decay when not connected to a log block within 6 meters.",
17+
"Persistence of players is if the player's playerdata should be saved when they leave the server. "
18+
+ "Players' persistence is reset back to 'true' when they join the server.",
19+
"Passengers inherit the persistence of their vehicle, meaning a persistent zombie put on a "
20+
+ "non-persistent chicken will become non-persistent. This does not apply to players.",
21+
"By default, all entities are persistent."
22+
})
23+
@Examples({
24+
"on spawn:",
25+
"\tif event-entity is persistent:",
26+
"\t\tmake event-entity not persistent"
27+
})
28+
@Since("INSERT VERSION")
29+
public class CondIsPersistent extends PropertyCondition<Object> {
30+
31+
static {
32+
register(CondIsPersistent.class, "persistent", "entities/blocks");
33+
}
34+
35+
@Override
36+
public boolean check(Object object) {
37+
if (object instanceof Entity entity) {
38+
return entity.isPersistent();
39+
} else if (object instanceof Block block && block.getBlockData() instanceof Leaves leaves) {
40+
return leaves.isPersistent();
41+
}
42+
return false;
43+
}
44+
45+
@Override
46+
protected String getPropertyName() {
47+
return "persistent";
48+
}
49+
50+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package ch.njol.skript.effects;
2+
3+
import ch.njol.skript.Skript;
4+
import ch.njol.skript.doc.Description;
5+
import ch.njol.skript.doc.Examples;
6+
import ch.njol.skript.doc.Name;
7+
import ch.njol.skript.doc.Since;
8+
import ch.njol.skript.lang.Effect;
9+
import ch.njol.skript.lang.Expression;
10+
import ch.njol.skript.lang.SkriptParser.ParseResult;
11+
import ch.njol.util.Kleenean;
12+
import org.bukkit.entity.LivingEntity;
13+
import org.bukkit.event.Event;
14+
import org.jetbrains.annotations.Nullable;
15+
16+
@Name("Entity Despawn")
17+
@Description({
18+
"Make a living entity despawn when the chunk they're located at is unloaded.",
19+
"Setting a custom name on a living entity automatically makes it not despawnable.",
20+
"More information on what and when entities despawn can be found at "
21+
+ "<a href=\"https://minecraft.wiki/w/Mob_spawning#Despawning\">reference</a>."
22+
})
23+
@Examples({
24+
"make all entities not despawnable on chunk unload",
25+
"spawn zombie at location(0, 0, 0):",
26+
"\tforce event-entity to not despawn when far away",
27+
})
28+
@Since("INSERT VERSION")
29+
public class EffEntityUnload extends Effect {
30+
31+
static {
32+
Skript.registerEffect(EffEntityUnload.class,
33+
"make %livingentities% despawn[able] (on chunk unload|when far away)",
34+
"force %livingentities% to despawn (on chunk unload|when far away)",
35+
"prevent %livingentities% from despawning [on chunk unload|when far away]");
36+
}
37+
38+
private Expression<LivingEntity> entities;
39+
private boolean despawn;
40+
41+
@Override
42+
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
43+
//noinspection unchecked
44+
entities = (Expression<LivingEntity>) exprs[0];
45+
despawn = matchedPattern != 2;
46+
return true;
47+
}
48+
49+
@Override
50+
protected void execute(Event event) {
51+
for (LivingEntity entity : entities.getArray(event)) {
52+
entity.setRemoveWhenFarAway(despawn);
53+
}
54+
}
55+
56+
@Override
57+
public String toString(@Nullable Event event, boolean debug) {
58+
if (despawn)
59+
return "make " + entities.toString(event, debug) + " despawn on chunk unload";
60+
return "prevent " + entities.toString(event, debug) + " from despawning on chunk unload";
61+
}
62+
63+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package ch.njol.skript.effects;
2+
3+
import ch.njol.skript.Skript;
4+
import ch.njol.skript.doc.Description;
5+
import ch.njol.skript.doc.Examples;
6+
import ch.njol.skript.doc.Name;
7+
import ch.njol.skript.doc.Since;
8+
import ch.njol.skript.lang.Effect;
9+
import ch.njol.skript.lang.Expression;
10+
import ch.njol.skript.lang.SkriptParser.ParseResult;
11+
import ch.njol.util.Kleenean;
12+
import org.bukkit.block.Block;
13+
import org.bukkit.block.data.type.Leaves;
14+
import org.bukkit.entity.Entity;
15+
import org.bukkit.event.Event;
16+
import org.jetbrains.annotations.Nullable;
17+
18+
@Name("Persistent")
19+
@Description({
20+
"Make entities, players, or leaves be persistent.",
21+
"Persistence of entities is whether they are retained through server restarts.",
22+
"Persistence of leaves is whether they should decay when not connected to a log block within 6 meters.",
23+
"Persistence of players is if the player's playerdata should be saved when they leave the server. "
24+
+ "Players' persistence is reset back to 'true' when they join the server.",
25+
"Passengers inherit the persistence of their vehicle, meaning a persistent zombie put on a "
26+
+ "non-persistent chicken will become non-persistent. This does not apply to players.",
27+
"By default, all entities are persistent."
28+
})
29+
@Examples({
30+
"prevent all entities from persisting",
31+
"force {_leaves} to persist",
32+
"",
33+
"command /kickcheater <cheater: player>:",
34+
"\tpermission: op",
35+
"\ttrigger:",
36+
"\t\tprevent {_cheater} from persisting",
37+
"\t\tkick {_cheater}"
38+
})
39+
@Since("INSERT VERSION")
40+
public class EffPersistent extends Effect {
41+
42+
static {
43+
Skript.registerEffect(EffPersistent.class,
44+
"make %entities/blocks% [:not] persist[ent]",
45+
"force %entities/blocks% to [:not] persist",
46+
"prevent %entities/blocks% from persisting");
47+
}
48+
49+
private Expression<?> source;
50+
private boolean persist;
51+
52+
@Override
53+
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
54+
source = exprs[0];
55+
if (matchedPattern < 2) {
56+
persist = !parseResult.hasTag("not");
57+
} else {
58+
persist = false;
59+
}
60+
return true;
61+
}
62+
63+
@Override
64+
protected void execute(Event event) {
65+
for (Object object : source.getArray(event)) {
66+
if (object instanceof Entity entity) {
67+
entity.setPersistent(persist);
68+
} else if (object instanceof Block block && block.getBlockData() instanceof Leaves leaves) {
69+
leaves.setPersistent(persist);
70+
block.setBlockData(leaves);
71+
}
72+
}
73+
}
74+
75+
@Override
76+
public String toString(@Nullable Event event, boolean debug) {
77+
if (persist)
78+
return "make " + source.toString(event, debug) + " persistent";
79+
return "prevent " + source.toString(event, debug) + " from persisting";
80+
}
81+
82+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
test "entity persistence":
2+
spawn a zombie, a skeleton and a villager at test-location
3+
assert all entities are persistent with "All entities should be persistent by default"
4+
prevent all entities from persisting
5+
assert all entities are not persistent with "Failed to make all entities not persistent"
6+
force all entities to persist
7+
assert all entities are persistent with "Failed to make all entities persistent"
8+
clear all entities
9+
10+
test "leaves persistence":
11+
set {_old} to block data of test-block
12+
set test-block to oak leaves
13+
prevent test-block from persisting
14+
assert test-block is not persistent with "Failed to make leaves not persistent"
15+
force test-block to persist
16+
assert test-block is persistent with "Failed to make leaves persist"
17+
set block data of test-block to {_old}

0 commit comments

Comments
 (0)