diff --git a/src/main/java/ch/njol/skript/effects/EffFireworkLaunch.java b/src/main/java/ch/njol/skript/effects/EffFireworkLaunch.java
deleted file mode 100644
index 6f610ad6e4b..00000000000
--- a/src/main/java/ch/njol/skript/effects/EffFireworkLaunch.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * This file is part of Skript.
- *
- * Skript is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Skript is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Skript. If not, see .
- *
- * Copyright Peter Güttinger, SkriptLang team and contributors
- */
-package ch.njol.skript.effects;
-
-import org.bukkit.FireworkEffect;
-import org.bukkit.Location;
-import org.bukkit.World;
-import org.bukkit.entity.Entity;
-import org.bukkit.entity.Firework;
-import org.bukkit.event.Event;
-import org.bukkit.inventory.meta.FireworkMeta;
-import org.eclipse.jdt.annotation.Nullable;
-
-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.lang.Effect;
-import ch.njol.skript.lang.Expression;
-import ch.njol.skript.lang.SkriptParser.ParseResult;
-import ch.njol.util.Kleenean;
-
-@Name("Launch firework")
-@Description("Launch firework effects at the given location(s).")
-@Examples("launch ball large colored red, purple and white fading to light green and black at player's location with duration 1")
-@Since("2.4")
-public class EffFireworkLaunch extends Effect {
-
- static {
- Skript.registerEffect(EffFireworkLaunch.class, "(launch|deploy) [[a] firework [with effect[s]]] %fireworkeffects% at %locations% [([with] (duration|power)|timed) %number%]");
- }
-
- @Nullable
- public static Entity lastSpawned = null;
-
- @SuppressWarnings("NotNullFieldNotInitialized")
- private Expression effects;
- @SuppressWarnings("NotNullFieldNotInitialized")
- private Expression locations;
- @SuppressWarnings("NotNullFieldNotInitialized")
- private Expression lifetime;
-
- @Override
- @SuppressWarnings("unchecked")
- public boolean init(Expression>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
- effects = (Expression) exprs[0];
- locations = (Expression) exprs[1];
- lifetime = (Expression) exprs[2];
- return true;
- }
-
- @Override
- protected void execute(Event event) {
- FireworkEffect[] effects = this.effects.getArray(event);
- int power = lifetime.getOptionalSingle(event).orElse(1).intValue();
- power = Math.min(127, Math.max(0, power));
- for (Location location : locations.getArray(event)) {
- World world = location.getWorld();
- if (world == null)
- continue;
- Firework firework = world.spawn(location, Firework.class);
- FireworkMeta meta = firework.getFireworkMeta();
- meta.addEffects(effects);
- meta.setPower(power);
- firework.setFireworkMeta(meta);
- lastSpawned = firework;
- }
- }
-
- @Override
- public String toString(@Nullable Event event, boolean debug) {
- return "Launch firework(s) " + effects.toString(event, debug) +
- " at location(s) " + locations.toString(event, debug) +
- " timed " + lifetime.toString(event, debug);
- }
-
-}
diff --git a/src/main/java/ch/njol/skript/entity/EntityData.java b/src/main/java/ch/njol/skript/entity/EntityData.java
index 8d6bf363440..c52d841bd75 100644
--- a/src/main/java/ch/njol/skript/entity/EntityData.java
+++ b/src/main/java/ch/njol/skript/entity/EntityData.java
@@ -40,6 +40,7 @@
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.eclipse.jdt.annotation.Nullable;
+import org.jetbrains.annotations.ApiStatus.ScheduledForRemoval;
import ch.njol.skript.Skript;
import ch.njol.skript.SkriptAPIException;
@@ -674,8 +675,14 @@ protected boolean deserialize(final String s) {
return false;
}
- @SuppressWarnings({"unchecked", "deprecation"})
- protected static @Nullable E spawn(Location location, Class type, Consumer consumer) {
+ /**
+ * Utility method to handle Bukkit changing from org.bukkit.util.Consumer to java Consumer.
+ * Subject to removal in the future, when some older versions get dropped.
+ */
+ @Deprecated
+ @ScheduledForRemoval
+ @SuppressWarnings("unchecked")
+ public static @Nullable E spawn(Location location, Class type, Consumer consumer) {
World world = location.getWorld();
if (world == null)
return null;
diff --git a/src/main/java/ch/njol/skript/expressions/ExprLastSpawnedEntity.java b/src/main/java/ch/njol/skript/expressions/ExprLastSpawnedEntity.java
index 92bd4ea8e35..2de4f5e3f45 100644
--- a/src/main/java/ch/njol/skript/expressions/ExprLastSpawnedEntity.java
+++ b/src/main/java/ch/njol/skript/expressions/ExprLastSpawnedEntity.java
@@ -20,9 +20,6 @@
import java.lang.reflect.Array;
-import ch.njol.skript.effects.EffFireworkLaunch;
-import ch.njol.skript.sections.EffSecSpawn;
-import ch.njol.util.coll.CollectionUtils;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Firework;
import org.bukkit.entity.Item;
@@ -44,12 +41,18 @@
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.util.SimpleExpression;
+import ch.njol.skript.sections.EffSecFireworkLaunch;
+import ch.njol.skript.sections.EffSecSpawn;
import ch.njol.util.Kleenean;
@Name("Last Spawned Entity")
-@Description("Holds the entity that was spawned most recently with the spawn effect (section), dropped with the drop effect, shot with the shoot effect or created with the lightning effect. " +
- "Please note that even though you can spawn multiple mobs simultaneously (e.g. with 'spawn 5 creepers'), only the last spawned mob is saved and can be used. " +
- "If you spawn an entity, shoot a projectile and drop an item you can however access all them together.")
+@Description({
+ "Holds the entity that was spawned most recently with the spawn effect (section), dropped with the drop effect,",
+ "shot with the shoot effect, launched firework firework launch effect section,",
+ "or created with the lightning effect.",
+ "Please note that even though you can spawn multiple mobs simultaneously (e.g. with 'spawn 5 creepers'), only the last spawned mob is saved and can be used.",
+ "If you spawn an entity, shoot a projectile and drop an item you can however access all them together."
+})
@Examples({
"spawn a priest",
"set {healer::%spawned priest%} to true",
@@ -62,16 +65,15 @@
})
@Since("1.3 (spawned entity), 2.0 (shot entity), 2.2-dev26 (dropped item), 2.7 (struck lightning, firework)")
public class ExprLastSpawnedEntity extends SimpleExpression {
-
+
static {
Skript.registerExpression(ExprLastSpawnedEntity.class, Entity.class, ExpressionType.SIMPLE,
- "[the] [last[ly]] (0:spawned|1:shot) %*entitydata%",
- "[the] [last[ly]] dropped (2:item)",
- "[the] [last[ly]] (created|struck) (3:lightning)",
- "[the] [last[ly]] (launched|deployed) (4:firework)");
+ "[the] [last[ly]] (0:spawned|1:shot) %*entitydata%",
+ "[the] [last[ly]] dropped (2:item)",
+ "[the] [last[ly]] (created|struck) (3:lightning)",
+ "[the] [last[ly]] (launched|deployed) (4:firework)");
}
-
- @SuppressWarnings("NotNullFieldNotInitialized")
+
private EntityData> type;
private int from;
@@ -90,51 +92,51 @@ public boolean init(Expression>[] exprs, int matchedPattern, Kleenean isDelaye
}
return true;
}
-
+
@Override
@Nullable
protected Entity[] get(Event event) {
- Entity en;
+ Entity entity;
switch (from) {
case 0:
- en = EffSecSpawn.lastSpawned;
+ entity = EffSecSpawn.lastSpawned;
break;
case 1:
- en = EffShoot.lastSpawned;
+ entity = EffShoot.lastSpawned;
break;
case 2:
- en = EffDrop.lastSpawned;
+ entity = EffDrop.lastSpawned;
break;
case 3:
- en = EffLightning.lastSpawned;
+ entity = EffLightning.lastSpawned;
break;
case 4:
- en = EffFireworkLaunch.lastSpawned;
+ entity = EffSecFireworkLaunch.lastSpawned;
break;
default:
- en = null;
+ entity = null;
}
- if (en == null)
+ if (entity == null)
return null;
- if (!type.isInstance(en))
+ if (!type.isInstance(entity))
return null;
Entity[] one = (Entity[]) Array.newInstance(type.getType(), 1);
- one[0] = en;
+ one[0] = entity;
return one;
}
-
+
@Override
public boolean isSingle() {
return true;
}
-
+
@Override
public Class extends Entity> getReturnType() {
return type.getType();
}
-
+
@Override
public String toString(@Nullable Event event, boolean debug) {
String word = "";
@@ -157,7 +159,7 @@ public String toString(@Nullable Event event, boolean debug) {
default:
assert false;
}
- return "the last " + word + " " + type;
+ return "last " + word + " " + type;
}
-
+
}
diff --git a/src/main/java/ch/njol/skript/sections/EffSecFireworkLaunch.java b/src/main/java/ch/njol/skript/sections/EffSecFireworkLaunch.java
new file mode 100644
index 00000000000..1327756be6a
--- /dev/null
+++ b/src/main/java/ch/njol/skript/sections/EffSecFireworkLaunch.java
@@ -0,0 +1,175 @@
+/**
+ * This file is part of Skript.
+ *
+ * Skript is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Skript is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Skript. If not, see .
+ *
+ * Copyright Peter Güttinger, SkriptLang team and contributors
+ */
+
+package ch.njol.skript.sections;
+
+import java.util.List;
+import java.util.function.Consumer;
+
+import org.bukkit.FireworkEffect;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Firework;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.bukkit.inventory.meta.FireworkMeta;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import ch.njol.skript.Skript;
+import ch.njol.skript.config.SectionNode;
+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.entity.EntityData;
+import ch.njol.skript.lang.EffectSection;
+import ch.njol.skript.lang.Expression;
+import ch.njol.skript.lang.SkriptParser.ParseResult;
+import ch.njol.skript.lang.Trigger;
+import ch.njol.skript.lang.TriggerItem;
+import ch.njol.skript.registrations.EventValues;
+import ch.njol.skript.util.Getter;
+import ch.njol.skript.variables.Variables;
+import ch.njol.util.Kleenean;
+
+@Name("Launch Firework")
+@Description({
+ "Launch firework effects at the given location(s).",
+ "This can be used as an effect and as a section.",
+ "If it is used as a section, the section is run before the entity is added to the world.",
+ "You can modify the firework in this section, using for example event-entity
.",
+ "Do note that other event values, such as player
, won't work in this section."
+})
+@Examples({
+ "launch ball large coloured red, purple and white fading to light green and black at player's location with duration 1",
+ "",
+ "command /firework:",
+ "\ttrigger:",
+ "\t\tlaunch a firework with effects ball large coloured red at player:",
+ "\t\t\tset metadata value \"cancel damage\" of event-entity to true",
+ "",
+ "# Firework launch section example",
+ "on damage:",
+ "\tdamage cause is entity explosion",
+ "\tmetadata value \"cancel damage\" of event-projectile is true",
+ "\tcancel event",
+})
+@Since("2.4, INSERT VERSION (section)")
+public class EffSecFireworkLaunch extends EffectSection {
+
+ public static class FireworkSectionLaunchEvent extends Event {
+
+ private final Firework firework;
+
+ public FireworkSectionLaunchEvent(Firework firework) {
+ this.firework = firework;
+ }
+
+ public Firework getFirework() {
+ return firework;
+ }
+
+ @Override
+ @NotNull
+ public HandlerList getHandlers() {
+ throw new IllegalStateException();
+ }
+
+ }
+
+ static {
+ Skript.registerSection(EffSecFireworkLaunch.class, "(launch|deploy) [[a] firework [with effect[s]]] %fireworkeffects% at %locations% [([with] (duration|power)|timed) %-number%]");
+ EventValues.registerEventValue(FireworkSectionLaunchEvent.class, Firework.class, new Getter() {
+ @Override
+ public Firework get(FireworkSectionLaunchEvent fireworkLaunchEvent) {
+ return fireworkLaunchEvent.getFirework();
+ }
+ }, EventValues.TIME_NOW);
+ }
+
+ private Expression effects;
+ private Expression locations;
+
+ @Nullable
+ public static Entity lastSpawned;
+
+ @Nullable
+ private Expression power;
+
+ @Nullable
+ private Trigger trigger;
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public boolean init(Expression>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult,
+ @Nullable SectionNode sectionNode, @Nullable List triggerItems) {
+
+ effects = (Expression) exprs[0];
+ locations = (Expression) exprs[1];
+ power = (Expression) exprs[2];
+
+ if (sectionNode != null)
+ trigger = loadCode(sectionNode, "firework launch", FireworkSectionLaunchEvent.class);
+
+ return true;
+ }
+
+ @Override
+ @Nullable
+ protected TriggerItem walk(Event event) {
+ FireworkEffect[] effects = this.effects.getArray(event);
+ // Uses org.bukkit consumer for older versions support. If newer, bukkit maps this class to java utils.
+ Consumer consumer = null;
+ if (trigger != null) {
+ consumer = firework -> {
+ FireworkSectionLaunchEvent fireworkLaunchEvent = new FireworkSectionLaunchEvent(firework);
+ Variables.setLocalVariables(fireworkLaunchEvent, Variables.copyLocalVariables(event));
+ TriggerItem.walk(trigger, fireworkLaunchEvent);
+ Variables.setLocalVariables(event, Variables.copyLocalVariables(fireworkLaunchEvent));
+ Variables.removeLocals(fireworkLaunchEvent);
+ };
+ }
+
+ int power = this.power != null ? this.power.getOptionalSingle(event).orElse(1).intValue() : 1;
+ for (Location location : locations.getArray(event)) {
+ World world = location.getWorld();
+ if (world == null)
+ continue;
+ @SuppressWarnings("deprecation")
+ Firework firework = EntityData.spawn(location, Firework.class, consumer);
+ FireworkMeta meta = firework.getFireworkMeta();
+ meta.addEffects(effects);
+ meta.setPower(power);
+ firework.setFireworkMeta(meta);
+ lastSpawned = firework;
+ }
+
+ return super.walk(event, false);
+ }
+
+ @Override
+ public String toString(@Nullable Event event, boolean debug) {
+ return "launch fireworks " + effects.toString(event, debug) +
+ " at " + locations.toString(event, debug) +
+ " timed " + (power != null ? power.toString(event, debug) : "1");
+ }
+
+}
diff --git a/src/test/skript/tests/syntaxes/sections/EffSecFireworkLaunch.sk b/src/test/skript/tests/syntaxes/sections/EffSecFireworkLaunch.sk
new file mode 100644
index 00000000000..08977631b1b
--- /dev/null
+++ b/src/test/skript/tests/syntaxes/sections/EffSecFireworkLaunch.sk
@@ -0,0 +1,10 @@
+test "firework launch section":
+ set {_foo} to true
+ launch a firework with effects ball large coloured red at spawn of "world":
+ assert {_foo} is true with "variables from previous section wasn't carried over"
+ set {_foo} to false
+ assert event-entity is a firework with "entity should be a firework but is %event-entity%"
+ assert location of event-entity is set with "location of firework is not set"
+ set metadata value "test" of event-entity to true
+ assert metadata value "test" of event-entity is true with "metadata value not true (check from section)"
+ assert {_foo} is false with "variables from launch section wasn't carried over"