Skip to content

Commit 4d8ff11

Browse files
authored
Refactor ExprBeaconValues into multiple expressions, fix bugs (#7729)
1 parent f6c19be commit 4d8ff11

File tree

5 files changed

+240
-214
lines changed

5 files changed

+240
-214
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package ch.njol.skript.expressions;
2+
3+
import ch.njol.skript.Skript;
4+
import ch.njol.skript.classes.Changer.ChangeMode;
5+
import ch.njol.skript.doc.*;
6+
import ch.njol.skript.expressions.base.PropertyExpression;
7+
import ch.njol.skript.lang.Expression;
8+
import ch.njol.skript.lang.SkriptParser.ParseResult;
9+
import ch.njol.util.Kleenean;
10+
import ch.njol.util.coll.CollectionUtils;
11+
import io.papermc.paper.event.player.PlayerChangeBeaconEffectEvent;
12+
import org.bukkit.block.Beacon;
13+
import org.bukkit.block.Block;
14+
import org.bukkit.event.Event;
15+
import org.bukkit.potion.PotionEffect;
16+
import org.bukkit.potion.PotionEffectType;
17+
import org.jetbrains.annotations.Nullable;
18+
19+
import java.util.function.BiConsumer;
20+
21+
@Name("Beacon Effects")
22+
@Description({
23+
"The active effects of a beacon.",
24+
"The secondary effect can be set to anything, but the icon in the GUI will not display correctly.",
25+
"The secondary effect can only be set when the beacon is at max tier.",
26+
"The primary and secondary effect can not be the same, primary will always retain the potion type and secondary will be cleared."
27+
})
28+
@Example("""
29+
set primary beacon effect of {_block} to haste
30+
set secondary effect of {_block} to resistance
31+
"""
32+
)
33+
@Events({"Beacon Effect", "Beacon Toggle", "Beacon Change Effect"})
34+
@Since("2.10")
35+
public class ExprBeaconEffects extends PropertyExpression<Block, PotionEffectType> {
36+
37+
private static final boolean SUPPORTS_CHANGE_EVENT = Skript.classExists("io.papermc.paper.event.player.PlayerChangeBeaconEffectEvent");
38+
39+
static {
40+
registerDefault(ExprBeaconEffects.class, PotionEffectType.class, "(:primary|secondary) [beacon] effect", "blocks");
41+
}
42+
43+
private boolean primary;
44+
45+
@Override
46+
public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
47+
//noinspection unchecked
48+
setExpr((Expression<? extends Block>) expressions[0]);
49+
primary = parseResult.hasTag("primary");
50+
return true;
51+
}
52+
53+
@Override
54+
protected PotionEffectType[] get(Event event, Block[] blocks) {
55+
return get(blocks, block -> {
56+
if (!(block.getState() instanceof Beacon beacon))
57+
return null;
58+
59+
if (SUPPORTS_CHANGE_EVENT
60+
&& event instanceof PlayerChangeBeaconEffectEvent changeEvent
61+
&& block.equals(changeEvent.getBeacon()))
62+
return primary ? changeEvent.getPrimary() : changeEvent.getSecondary();
63+
64+
PotionEffect effect = primary ? beacon.getPrimaryEffect() : beacon.getSecondaryEffect();
65+
if (effect == null)
66+
return null;
67+
return effect.getType();
68+
});
69+
}
70+
71+
@Override
72+
public Class<?> @Nullable [] acceptChange(ChangeMode mode) {
73+
return switch (mode) {
74+
case SET, RESET, DELETE -> CollectionUtils.array(PotionEffectType.class);
75+
default -> null;
76+
};
77+
}
78+
79+
@Override
80+
public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
81+
PotionEffectType type = delta == null ? null : (PotionEffectType) delta[0];
82+
BiConsumer<Beacon, PotionEffectType> changer = primary ? Beacon::setPrimaryEffect : Beacon::setSecondaryEffect;
83+
for (Block block : getExpr().getArray(event)) {
84+
if (!(block.getState() instanceof Beacon beacon))
85+
continue;
86+
changer.accept(beacon, type);
87+
beacon.update(true);
88+
}
89+
}
90+
91+
@Override
92+
public Class<PotionEffectType> getReturnType() {
93+
return PotionEffectType.class;
94+
}
95+
96+
@Override
97+
public String toString(@Nullable Event event, boolean debug) {
98+
return (primary ? "primary" : "secondary") + " beacon effect of " + getExpr().toString(event, debug);
99+
}
100+
101+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package ch.njol.skript.expressions;
2+
3+
import ch.njol.skript.Skript;
4+
import ch.njol.skript.classes.Changer.ChangeMode;
5+
import ch.njol.skript.doc.*;
6+
import ch.njol.skript.expressions.base.SimplePropertyExpression;
7+
import ch.njol.util.Math2;
8+
import ch.njol.util.coll.CollectionUtils;
9+
import org.bukkit.block.Beacon;
10+
import org.bukkit.block.Block;
11+
import org.bukkit.event.Event;
12+
import org.jetbrains.annotations.Nullable;
13+
14+
@Name("Beacon Range")
15+
@Description({
16+
"The range of a beacon's effects, in blocks."
17+
})
18+
@Example("""
19+
if the beacon tier of the clicked block is 4:
20+
set the beacon effect range of the clicked block to 100
21+
"""
22+
)
23+
@RequiredPlugins("Paper")
24+
@Since("2.10")
25+
public class ExprBeaconRange extends SimplePropertyExpression<Block, Double> {
26+
27+
static {
28+
if (Skript.methodExists(Beacon.class, "getEffectRange"))
29+
register(ExprBeaconRange.class, Double.class, "beacon [effect] range", "blocks");
30+
}
31+
32+
@Override
33+
public @Nullable Double convert(Block block) {
34+
if (block.getState() instanceof Beacon beacon)
35+
return beacon.getEffectRange();
36+
return null;
37+
}
38+
39+
@Override
40+
public Class<?> @Nullable [] acceptChange(ChangeMode mode) {
41+
return switch (mode) {
42+
case SET, ADD, REMOVE, RESET -> CollectionUtils.array(Double.class);
43+
default -> null;
44+
};
45+
}
46+
47+
@Override
48+
public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
49+
if (mode == ChangeMode.RESET) {
50+
for (Block block : getExpr().getArray(event)) {
51+
if (block.getState() instanceof Beacon beacon) {
52+
beacon.resetEffectRange();
53+
beacon.update(true);
54+
}
55+
}
56+
return;
57+
}
58+
59+
assert delta != null;
60+
double range = ((Number) delta[0]).doubleValue();
61+
for (Block block : getExpr().getArray(event)) {
62+
if (block.getState() instanceof Beacon beacon) {
63+
switch (mode) {
64+
case SET -> beacon.setEffectRange(Math2.fit(0, range, Double.MAX_VALUE));
65+
case ADD -> beacon.setEffectRange(Math2.fit(0, beacon.getEffectRange() + range, Double.MAX_VALUE));
66+
case REMOVE -> beacon.setEffectRange(Math2.fit(0, beacon.getEffectRange() - range, Double.MAX_VALUE));
67+
default -> throw new IllegalStateException();
68+
}
69+
beacon.update(true);
70+
}
71+
}
72+
}
73+
74+
@Override
75+
public Class<? extends Double> getReturnType() {
76+
return Double.class;
77+
}
78+
79+
@Override
80+
protected String getPropertyName() {
81+
return "beacon range";
82+
}
83+
84+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package ch.njol.skript.expressions;
2+
3+
import ch.njol.skript.doc.Description;
4+
import ch.njol.skript.doc.Example;
5+
import ch.njol.skript.doc.Name;
6+
import ch.njol.skript.doc.Since;
7+
import ch.njol.skript.expressions.base.SimplePropertyExpression;
8+
import org.bukkit.block.Beacon;
9+
import org.bukkit.block.Block;
10+
import org.jetbrains.annotations.Nullable;
11+
12+
@Name("Beacon Tier")
13+
@Description({
14+
"The tier of a beacon. Ranges from 0 to 4."
15+
})
16+
@Example("""
17+
if the beacon tier of the clicked block is 4:
18+
send "This is a max tier beacon!"
19+
"""
20+
)
21+
@Since("2.10")
22+
public class ExprBeaconTier extends SimplePropertyExpression<Block, Integer> {
23+
24+
static {
25+
register(ExprBeaconTier.class, Integer.class, "beacon tier", "blocks");
26+
}
27+
28+
@Override
29+
public @Nullable Integer convert(Block block) {
30+
if (block.getState() instanceof Beacon beacon)
31+
return beacon.getTier();
32+
return null;
33+
}
34+
35+
@Override
36+
public Class<Integer> getReturnType() {
37+
return Integer.class;
38+
}
39+
40+
@Override
41+
protected String getPropertyName() {
42+
return "beacon tier";
43+
}
44+
45+
}

0 commit comments

Comments
 (0)