|
1 | 1 | package ch.njol.skript.effects; |
2 | 2 |
|
3 | | -import org.bukkit.entity.Entity; |
4 | | -import org.bukkit.entity.LivingEntity; |
5 | | -import org.bukkit.event.Event; |
6 | | -import org.jetbrains.annotations.Nullable; |
7 | | - |
8 | 3 | import ch.njol.skript.Skript; |
9 | | -import ch.njol.skript.doc.Description; |
10 | | -import ch.njol.skript.doc.Examples; |
11 | | -import ch.njol.skript.doc.Name; |
12 | | -import ch.njol.skript.doc.RequiredPlugins; |
13 | | -import ch.njol.skript.doc.Since; |
| 4 | +import ch.njol.skript.config.Node; |
| 5 | +import ch.njol.skript.doc.*; |
14 | 6 | import ch.njol.skript.lang.Effect; |
15 | 7 | import ch.njol.skript.lang.Expression; |
16 | 8 | import ch.njol.skript.lang.SkriptParser.ParseResult; |
| 9 | +import ch.njol.skript.lang.SyntaxStringBuilder; |
17 | 10 | import ch.njol.util.Kleenean; |
| 11 | +import org.bukkit.entity.Damageable; |
| 12 | +import org.bukkit.entity.Entity; |
| 13 | +import org.bukkit.entity.LivingEntity; |
| 14 | +import org.bukkit.event.Event; |
| 15 | +import org.jetbrains.annotations.Nullable; |
| 16 | +import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer; |
18 | 17 |
|
19 | 18 | @Name("Force Attack") |
20 | | -@Description("Makes a living entity attack an entity with a melee attack.") |
| 19 | +@Description({ |
| 20 | + "Makes a living entity attack an entity with a melee attack.", |
| 21 | + "Using 'attack' will make the attacker use the item in their main hand " |
| 22 | + + "and will apply extra data from the item, including enchantments and attributes.", |
| 23 | + "Using 'damage' with a number of hearts will not account for the item in the main hand " |
| 24 | + + "and will always be the number provided." |
| 25 | +}) |
| 26 | +@Example(""" |
| 27 | + spawn a wolf at location(0, 0, 0) |
| 28 | + make last spawned wolf attack all players |
| 29 | + """) |
| 30 | +@Example(""" |
| 31 | + spawn a zombie at location(0, 0, 0) |
| 32 | + make player damage last spawned zombie by 2 |
| 33 | + """) |
21 | 34 | @Examples({"spawn a wolf at player's location", |
22 | 35 | "make last spawned wolf attack player"}) |
23 | | -@Since("2.5.1") |
| 36 | +@Since("2.5.1, INSERT VERSION (multiple, amount)") |
24 | 37 | @RequiredPlugins("Minecraft 1.15.2+") |
25 | | -public class EffForceAttack extends Effect { |
| 38 | +public class EffForceAttack extends Effect implements SyntaxRuntimeErrorProducer { |
26 | 39 |
|
27 | 40 | static { |
28 | 41 | Skript.registerEffect(EffForceAttack.class, |
29 | | - "make %livingentities% attack %entity%", |
30 | | - "force %livingentities% to attack %entity%"); |
| 42 | + "make %livingentities% attack %entities%", |
| 43 | + "force %livingentities% to attack %entities%", |
| 44 | + "make %livingentities% damage %entities% by %number% [heart[s]]", |
| 45 | + "force %livingentities% to damage %entities% by %number% [heart[s]]"); |
31 | 46 | } |
| 47 | + |
| 48 | + private Expression<LivingEntity> attackers; |
| 49 | + private Expression<Entity> victims; |
| 50 | + private @Nullable Expression<Number> amount; |
| 51 | + private Node node; |
32 | 52 |
|
33 | | - @SuppressWarnings("null") |
34 | | - private Expression<LivingEntity> entities; |
35 | | - @SuppressWarnings("null") |
36 | | - private Expression<Entity> target; |
37 | | - |
38 | | - @Override |
39 | 53 | @SuppressWarnings("unchecked") |
| 54 | + @Override |
40 | 55 | public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { |
41 | | - entities = (Expression<LivingEntity>) exprs[0]; |
42 | | - target = (Expression<Entity>) exprs[1]; |
| 56 | + attackers = (Expression<LivingEntity>) exprs[0]; |
| 57 | + victims = (Expression<Entity>) exprs[1]; |
| 58 | + if (matchedPattern >= 2) |
| 59 | + amount = (Expression<Number>) exprs[2]; |
| 60 | + node = getParser().getNode(); |
43 | 61 | return true; |
44 | 62 | } |
45 | 63 |
|
46 | 64 | @Override |
47 | | - protected void execute(Event e) { |
48 | | - Entity target = this.target.getSingle(e); |
49 | | - if (target != null) { |
50 | | - for (LivingEntity entity : entities.getArray(e)) { |
51 | | - entity.attack(target); |
| 65 | + protected void execute(Event event) { |
| 66 | + Double amount = null; |
| 67 | + if (this.amount != null) { |
| 68 | + Number number = this.amount.getSingle(event); |
| 69 | + if (number == null) |
| 70 | + return; |
| 71 | + Double preAmount = number.doubleValue(); |
| 72 | + if (preAmount <= 0) { |
| 73 | + error("Cannot damage an entity by 0 or less. Consider healing instead."); |
| 74 | + return; |
| 75 | + } else if (!Double.isFinite(preAmount)) { |
| 76 | + return; |
| 77 | + } |
| 78 | + amount = preAmount * 2; // hearts |
| 79 | + } |
| 80 | + |
| 81 | + LivingEntity[] attackers = this.attackers.getArray(event); |
| 82 | + Entity[] victims = this.victims.getArray(event); |
| 83 | + if (amount == null) { |
| 84 | + for (Entity victim : victims) { |
| 85 | + for (LivingEntity attacker : attackers) { |
| 86 | + attacker.attack(victim); |
| 87 | + } |
| 88 | + } |
| 89 | + } else { |
| 90 | + for (Entity victim : victims) { |
| 91 | + if (!(victim instanceof Damageable damageable)) |
| 92 | + continue; |
| 93 | + for (LivingEntity attacker : attackers) { |
| 94 | + damageable.damage(amount, attacker); |
| 95 | + } |
52 | 96 | } |
53 | 97 | } |
54 | 98 | } |
55 | | - |
| 99 | + |
56 | 100 | @Override |
57 | | - public String toString(@Nullable Event e, boolean debug) { |
58 | | - return "make " + entities.toString(e, debug) + " attack " + target.toString(e, debug); |
| 101 | + public Node getNode() { |
| 102 | + return node; |
| 103 | + } |
| 104 | + |
| 105 | + @Override |
| 106 | + public String toString(Event event, boolean debug) { |
| 107 | + SyntaxStringBuilder builder = new SyntaxStringBuilder(event, debug); |
| 108 | + builder.append("make", attackers); |
| 109 | + if (amount == null) { |
| 110 | + builder.append("attack", victims); |
| 111 | + } else { |
| 112 | + builder.append("damage", victims, "by", amount); |
| 113 | + } |
| 114 | + return builder.toString(); |
59 | 115 | } |
60 | 116 |
|
61 | 117 | } |
0 commit comments