From 1307666ed1637ac04c2c4728e2e2afbd552682a2 Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Sun, 6 Oct 2024 16:44:21 -0400 Subject: [PATCH 01/16] Starter Commit --- .../java/ch/njol/skript/effects/EffShoot.java | 138 ---------------- .../expressions/ExprLastSpawnedEntity.java | 5 +- .../ch/njol/skript/sections/EffSecShoot.java | 154 ++++++++++++++++++ 3 files changed, 156 insertions(+), 141 deletions(-) delete mode 100644 src/main/java/ch/njol/skript/effects/EffShoot.java create mode 100644 src/main/java/ch/njol/skript/sections/EffSecShoot.java diff --git a/src/main/java/ch/njol/skript/effects/EffShoot.java b/src/main/java/ch/njol/skript/effects/EffShoot.java deleted file mode 100644 index 0c1cc223a56..00000000000 --- a/src/main/java/ch/njol/skript/effects/EffShoot.java +++ /dev/null @@ -1,138 +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.Location; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Fireball; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Projectile; -import org.bukkit.projectiles.ProjectileSource; -import org.bukkit.event.Event; -import org.bukkit.util.Vector; -import org.jetbrains.annotations.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.entity.EntityData; -import ch.njol.skript.lang.Effect; -import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.SkriptParser.ParseResult; -import ch.njol.skript.util.Direction; -import ch.njol.util.Kleenean; - -/** - * @author Peter Güttinger - */ -@Name("Shoot") -@Description("Shoots a projectile (or any other entity) from a given entity.") -@Examples({"shoot an arrow", - "make the player shoot a creeper at speed 10", - "shoot a pig from the creeper"}) -@Since("1.4") -public class EffShoot extends Effect { - static { - Skript.registerEffect(EffShoot.class, - "shoot %entitydatas% [from %livingentities/locations%] [(at|with) (speed|velocity) %-number%] [%-direction%]", - "(make|let) %livingentities/locations% shoot %entitydatas% [(at|with) (speed|velocity) %-number%] [%-direction%]"); - } - - private final static Double DEFAULT_SPEED = 5.; - - @SuppressWarnings("null") - private Expression> types; - @SuppressWarnings("null") - private Expression shooters; - @Nullable - private Expression velocity; - @Nullable - private Expression direction; - - @Nullable - public static Entity lastSpawned = null; - - @SuppressWarnings({"unchecked", "null"}) - @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { - types = (Expression>) exprs[matchedPattern]; - shooters = exprs[1 - matchedPattern]; - velocity = (Expression) exprs[2]; - direction = (Expression) exprs[3]; - return true; - } - - @SuppressWarnings("null") - @Override - protected void execute(final Event e) { - lastSpawned = null; - final Number v = velocity != null ? velocity.getSingle(e) : DEFAULT_SPEED; - if (v == null) - return; - final Direction dir = direction != null ? direction.getSingle(e) : Direction.IDENTITY; - if (dir == null) - return; - for (final Object shooter : shooters.getArray(e)) { - for (final EntityData d : types.getArray(e)) { - if (shooter instanceof LivingEntity) { - final Vector vel = dir.getDirection(((LivingEntity) shooter).getLocation()).multiply(v.doubleValue()); - final Class type = d.getType(); - if (Fireball.class.isAssignableFrom(type)) {// fireballs explode in the shooter's face by default - final Fireball projectile = (Fireball) ((LivingEntity) shooter).getWorld().spawn(((LivingEntity) shooter).getEyeLocation().add(vel.clone().normalize().multiply(0.5)), type); - projectile.setShooter((ProjectileSource) shooter); - projectile.setVelocity(vel); - lastSpawned = projectile; - } else if (Projectile.class.isAssignableFrom(type)) { - @SuppressWarnings("unchecked") - final Projectile projectile = ((LivingEntity) shooter).launchProjectile((Class) type); - set(projectile, d); - projectile.setVelocity(vel); - lastSpawned = projectile; - } else { - final Location loc = ((LivingEntity) shooter).getLocation(); - loc.setY(loc.getY() + ((LivingEntity) shooter).getEyeHeight() / 2); - final Entity projectile = d.spawn(loc); - if (projectile != null) - projectile.setVelocity(vel); - lastSpawned = projectile; - } - } else { - final Vector vel = dir.getDirection((Location) shooter).multiply(v.doubleValue()); - final Entity projectile = d.spawn((Location) shooter); - if (projectile != null) - projectile.setVelocity(vel); - lastSpawned = projectile; - } - } - } - } - - @SuppressWarnings("unchecked") - private static void set(final Entity e, final EntityData d) { - d.set((E) e); - } - - @Override - public String toString(final @Nullable Event e, final boolean debug) { - return "shoot " + types.toString(e, debug) + " from " + shooters.toString(e, debug) + (velocity != null ? " at speed " + velocity.toString(e, debug) : "") + (direction != null ? " " + direction.toString(e, debug) : ""); - } - -} diff --git a/src/main/java/ch/njol/skript/expressions/ExprLastSpawnedEntity.java b/src/main/java/ch/njol/skript/expressions/ExprLastSpawnedEntity.java index fc762672b11..5e65e1e0767 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLastSpawnedEntity.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLastSpawnedEntity.java @@ -21,8 +21,8 @@ import java.lang.reflect.Array; import ch.njol.skript.effects.EffFireworkLaunch; +import ch.njol.skript.sections.EffSecShoot; 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; @@ -37,7 +37,6 @@ import ch.njol.skript.doc.Since; import ch.njol.skript.effects.EffDrop; import ch.njol.skript.effects.EffLightning; -import ch.njol.skript.effects.EffShoot; import ch.njol.skript.entity.EntityData; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ExpressionType; @@ -100,7 +99,7 @@ protected Entity[] get(Event event) { en = EffSecSpawn.lastSpawned; break; case 1: - en = EffShoot.lastSpawned; + en = EffSecShoot.lastSpawned; break; case 2: en = EffDrop.lastSpawned; diff --git a/src/main/java/ch/njol/skript/sections/EffSecShoot.java b/src/main/java/ch/njol/skript/sections/EffSecShoot.java new file mode 100644 index 00000000000..d4f5264f74b --- /dev/null +++ b/src/main/java/ch/njol/skript/sections/EffSecShoot.java @@ -0,0 +1,154 @@ +package ch.njol.skript.sections; + +import ch.njol.skript.Skript; +import ch.njol.skript.config.SectionNode; +import ch.njol.skript.entity.EntityData; +import ch.njol.skript.lang.*; +import ch.njol.skript.util.Direction; +import ch.njol.skript.variables.Variables; +import ch.njol.util.Kleenean; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Fireball; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Projectile; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.projectiles.ProjectileSource; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; + +public class EffSecShoot extends EffectSection { + + public static class ShootEvent extends Event { + private Entity projectile, shooter; + public ShootEvent(Entity projectile, @Nullable Entity shooter) { + this.projectile = projectile; + this.shooter = shooter; + } + + public Entity getProjectile() { + return projectile; + } + public Entity getShooter() { + return shooter; + } + + @Override + @NotNull + public HandlerList getHandlers() { + throw new IllegalStateException(); + } + } + + static { + Skript.registerSection(EffSecShoot.class, + "shoot %entitydatas% [from %livingentities/locations%] [(at|with) (speed|velocity) %-number%] [%-direction%]", + "(make|let) %livingentities/locations% shoot %entitydatas% [(at|with) (speed|velocity) %-number%] [%-direction%]" + ); + } + + private final static Double DEFAULT_SPEED = 5.; + private Expression> types; + private Expression shooters; + private @Nullable Expression velocity; + private @Nullable Expression direction; + public static Entity lastSpawned = null; + private @Nullable Trigger trigger; + + @Override + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult, @Nullable SectionNode sectionNode, @Nullable List triggerItems) { + types = (Expression>) exprs[matchedPattern]; + shooters = exprs[1 - matchedPattern]; + velocity = (Expression) exprs[2]; + direction = (Expression) exprs[3]; + + if (sectionNode != null) { + AtomicBoolean delayed = new AtomicBoolean(false); + Runnable afterLoading = () -> delayed.set(!getParser().getHasDelayBefore().isFalse()); + trigger = loadCode(sectionNode, "shoot", afterLoading, ShootEvent.class); + if (delayed.get()) { + Skript.error("Delays can't be used within a Shoot Effect Section"); + return false; + } + } + return true; + } + + @Override + @SuppressWarnings("unchecked") + protected @Nullable TriggerItem walk(Event event) { + lastSpawned = null; + Number finalVelocity = velocity != null ? velocity.getSingle(event) : DEFAULT_SPEED; + Direction finalDirection = direction != null ? direction.getSingle(event) : Direction.IDENTITY; + if (finalVelocity == null || finalDirection == null) + return null; + + Consumer consumer = null; + if (trigger != null) { + consumer = shootEvent -> { + lastSpawned = shootEvent.getProjectile(); + Variables.setLocalVariables(shootEvent, Variables.copyLocalVariables(event)); + TriggerItem.walk(trigger, shootEvent); + Variables.setLocalVariables(event, Variables.copyLocalVariables(event)); + Variables.removeLocals(shootEvent); + }; + } + + for (Object shooter : shooters.getArray(event)) { + for (EntityData entityData : types.getArray(event)) { + Entity finalProjectile = null; + Vector vector; + if (shooter instanceof LivingEntity livingShooter) { + vector = finalDirection.getDirection(livingShooter.getLocation()).multiply(finalVelocity.doubleValue()); + Class type = entityData.getType(); + if (Fireball.class.isAssignableFrom(type)) { + Fireball fireball = (Fireball) livingShooter.getWorld().spawn(livingShooter.getEyeLocation().add(vector.clone().normalize().multiply(0.5)), type); + fireball.setShooter((ProjectileSource) shooter); + finalProjectile = fireball; + } else if (Projectile.class.isAssignableFrom(type)) { + Projectile projectile = livingShooter.launchProjectile((Class) type); + set(projectile, entityData); + finalProjectile = projectile; + } else { + Location location = livingShooter.getLocation(); + location.setY(location.getY() + livingShooter.getEyeHeight() / 2); + Entity projectile = entityData.spawn(location); + finalProjectile = projectile; + } + } else { + vector = finalDirection.getDirection((Location) shooter).multiply(finalVelocity.doubleValue()); + Entity projectile = entityData.spawn((Location) shooter); + finalProjectile = projectile; + } + if (finalProjectile != null) { + finalProjectile.setVelocity(vector); + if (consumer != null) { + consumer.accept(new ShootEvent(finalProjectile, shooter instanceof LivingEntity livingEntity ? livingEntity : null)); + } else { + lastSpawned = finalProjectile; + } + } + } + } + + return null; + } + + @SuppressWarnings("unchecked") + private static void set(final Entity e, final EntityData d) { + d.set((E) e); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "shoot " + types.toString(event, debug) + " from " + shooters.toString(event, debug) + (velocity != null ? " at speed " + velocity.toString(event, debug) : "") + (direction != null ? " " + direction.toString(event, debug) : ""); + } + +} From c7b3b87aab9bcbec9d2f2b284b25f8511388b51b Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Sun, 6 Oct 2024 16:56:45 -0400 Subject: [PATCH 02/16] ExprShooter Update --- .../ch/njol/skript/expressions/ExprShooter.java | 17 ++++++++++++++--- .../ch/njol/skript/sections/EffSecShoot.java | 15 ++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprShooter.java b/src/main/java/ch/njol/skript/expressions/ExprShooter.java index 98111d7b7f8..1af540181cd 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprShooter.java +++ b/src/main/java/ch/njol/skript/expressions/ExprShooter.java @@ -28,6 +28,7 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.sections.EffSecShoot; import ch.njol.util.Kleenean; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Projectile; @@ -46,16 +47,26 @@ public class ExprShooter extends PropertyExpression { static { Skript.registerExpression(ExprShooter.class, LivingEntity.class, ExpressionType.SIMPLE, "[the] shooter [of %projectile%]"); } - + + private boolean withinShootEvent; + @SuppressWarnings({"unchecked", "null"}) @Override public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { - setExpr((Expression) exprs[0]); + if (getParser().isCurrentEvent(EffSecShoot.ShootEvent.class)) { + withinShootEvent = true; + } else { + setExpr((Expression) exprs[0]); + } return true; } @Override - protected LivingEntity[] get(final Event e, final Projectile[] source) { + protected LivingEntity @Nullable [] get(final Event event, final Projectile[] source) { + if (withinShootEvent && event instanceof EffSecShoot.ShootEvent shootEvent) { + return new LivingEntity[]{shootEvent.getShooter()}; + } + return get(source, projectile -> { Object shooter = projectile != null ? projectile.getShooter() : null; if (shooter instanceof LivingEntity) diff --git a/src/main/java/ch/njol/skript/sections/EffSecShoot.java b/src/main/java/ch/njol/skript/sections/EffSecShoot.java index d4f5264f74b..bb67350360e 100644 --- a/src/main/java/ch/njol/skript/sections/EffSecShoot.java +++ b/src/main/java/ch/njol/skript/sections/EffSecShoot.java @@ -4,7 +4,9 @@ import ch.njol.skript.config.SectionNode; import ch.njol.skript.entity.EntityData; import ch.njol.skript.lang.*; +import ch.njol.skript.registrations.EventValues; import ch.njol.skript.util.Direction; +import ch.njol.skript.util.Getter; import ch.njol.skript.variables.Variables; import ch.njol.util.Kleenean; import org.bukkit.Location; @@ -26,8 +28,9 @@ public class EffSecShoot extends EffectSection { public static class ShootEvent extends Event { - private Entity projectile, shooter; - public ShootEvent(Entity projectile, @Nullable Entity shooter) { + private Entity projectile; + private @Nullable LivingEntity shooter; + public ShootEvent(Entity projectile, @Nullable LivingEntity shooter) { this.projectile = projectile; this.shooter = shooter; } @@ -35,7 +38,7 @@ public ShootEvent(Entity projectile, @Nullable Entity shooter) { public Entity getProjectile() { return projectile; } - public Entity getShooter() { + public @Nullable LivingEntity getShooter() { return shooter; } @@ -51,6 +54,12 @@ public HandlerList getHandlers() { "shoot %entitydatas% [from %livingentities/locations%] [(at|with) (speed|velocity) %-number%] [%-direction%]", "(make|let) %livingentities/locations% shoot %entitydatas% [(at|with) (speed|velocity) %-number%] [%-direction%]" ); + EventValues.registerEventValue(ShootEvent.class, Entity.class, new Getter() { + @Override + public @Nullable Entity get(ShootEvent shootEvent) { + return shootEvent.getProjectile(); + } + }, EventValues.TIME_NOW); } private final static Double DEFAULT_SPEED = 5.; From 3d2481deb2e1817ecba888b577c116709f91cb1d Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Sun, 6 Oct 2024 19:50:44 -0400 Subject: [PATCH 03/16] Enhance Consumer --- .../ch/njol/skript/sections/EffSecShoot.java | 83 ++++++++++++------- 1 file changed, 53 insertions(+), 30 deletions(-) diff --git a/src/main/java/ch/njol/skript/sections/EffSecShoot.java b/src/main/java/ch/njol/skript/sections/EffSecShoot.java index bb67350360e..b22c5fc77df 100644 --- a/src/main/java/ch/njol/skript/sections/EffSecShoot.java +++ b/src/main/java/ch/njol/skript/sections/EffSecShoot.java @@ -91,7 +91,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked","rawtypes"}) protected @Nullable TriggerItem walk(Event event) { lastSpawned = null; Number finalVelocity = velocity != null ? velocity.getSingle(event) : DEFAULT_SPEED; @@ -99,17 +99,6 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye if (finalVelocity == null || finalDirection == null) return null; - Consumer consumer = null; - if (trigger != null) { - consumer = shootEvent -> { - lastSpawned = shootEvent.getProjectile(); - Variables.setLocalVariables(shootEvent, Variables.copyLocalVariables(event)); - TriggerItem.walk(trigger, shootEvent); - Variables.setLocalVariables(event, Variables.copyLocalVariables(event)); - Variables.removeLocals(shootEvent); - }; - } - for (Object shooter : shooters.getArray(event)) { for (EntityData entityData : types.getArray(event)) { Entity finalProjectile = null; @@ -118,41 +107,75 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye vector = finalDirection.getDirection(livingShooter.getLocation()).multiply(finalVelocity.doubleValue()); Class type = entityData.getType(); if (Fireball.class.isAssignableFrom(type)) { - Fireball fireball = (Fireball) livingShooter.getWorld().spawn(livingShooter.getEyeLocation().add(vector.clone().normalize().multiply(0.5)), type); - fireball.setShooter((ProjectileSource) shooter); - finalProjectile = fireball; + if (trigger != null) { + livingShooter.getWorld().spawn( + livingShooter.getEyeLocation().add(vector.clone().normalize().multiply(0.5)), + type, + (Consumer) getConsumer(event, vector, entityData, livingShooter) + ); + } else { + finalProjectile = livingShooter.getWorld().spawn( + livingShooter.getEyeLocation().add(vector.clone().normalize().multiply(0.5)), + type + ); + } } else if (Projectile.class.isAssignableFrom(type)) { - Projectile projectile = livingShooter.launchProjectile((Class) type); - set(projectile, entityData); - finalProjectile = projectile; + if (trigger != null) { + livingShooter.launchProjectile( + (Class) type, + vector, + (Consumer) getConsumer(event, vector, entityData, livingShooter) + ); + } else { + finalProjectile = livingShooter.launchProjectile((Class) type); + set(finalProjectile, entityData); + } } else { Location location = livingShooter.getLocation(); location.setY(location.getY() + livingShooter.getEyeHeight() / 2); - Entity projectile = entityData.spawn(location); - finalProjectile = projectile; + if (trigger != null) { + entityData.spawn(location, (Consumer) getConsumer(event, vector, entityData, livingShooter)); + } else { + finalProjectile = entityData.spawn(location); + } } } else { vector = finalDirection.getDirection((Location) shooter).multiply(finalVelocity.doubleValue()); - Entity projectile = entityData.spawn((Location) shooter); - finalProjectile = projectile; + if (trigger != null) { + entityData.spawn((Location) shooter, (Consumer) getConsumer(event, vector, entityData, null)); + } else { + finalProjectile = entityData.spawn((Location) shooter); + } } if (finalProjectile != null) { finalProjectile.setVelocity(vector); - if (consumer != null) { - consumer.accept(new ShootEvent(finalProjectile, shooter instanceof LivingEntity livingEntity ? livingEntity : null)); - } else { - lastSpawned = finalProjectile; - } + lastSpawned = finalProjectile; } } } - return null; + return super.walk(event, false); } @SuppressWarnings("unchecked") - private static void set(final Entity e, final EntityData d) { - d.set((E) e); + private static void set(Entity entity, EntityData entityData) { + entityData.set((E) entity); + } + + private Consumer getConsumer(Event event, Vector vector, EntityData entityData, @Nullable LivingEntity shooter) { + return entity -> { + if (entity instanceof Fireball fireball) + fireball.setShooter(shooter); + else if (entity instanceof Projectile projectile && shooter != null) + set(projectile, entityData); + entity.setVelocity(vector); + ShootEvent shootEvent = new ShootEvent(entity, shooter); + lastSpawned = entity; + Variables.setLocalVariables(shootEvent, Variables.copyLocalVariables(event)); + TriggerItem.walk(trigger, shootEvent); + Variables.setLocalVariables(event, Variables.copyLocalVariables(event)); + Variables.removeLocals(shootEvent); + }; } @Override From affff23c9edd74d683854888ca441249245814da Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Sun, 6 Oct 2024 20:36:04 -0400 Subject: [PATCH 04/16] Cleanup + Tests --- .../njol/skript/expressions/ExprShooter.java | 6 ++---- .../ch/njol/skript/sections/EffSecShoot.java | 6 ++++-- .../tests/syntaxes/sections/EffSecShoot.sk | 20 +++++++++++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 src/test/skript/tests/syntaxes/sections/EffSecShoot.sk diff --git a/src/main/java/ch/njol/skript/expressions/ExprShooter.java b/src/main/java/ch/njol/skript/expressions/ExprShooter.java index 1af540181cd..d996907c012 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprShooter.java +++ b/src/main/java/ch/njol/skript/expressions/ExprShooter.java @@ -53,11 +53,9 @@ public class ExprShooter extends PropertyExpression { @SuppressWarnings({"unchecked", "null"}) @Override public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { - if (getParser().isCurrentEvent(EffSecShoot.ShootEvent.class)) { + if (getParser().isCurrentEvent(EffSecShoot.ShootEvent.class) && exprs[0] == null) withinShootEvent = true; - } else { - setExpr((Expression) exprs[0]); - } + setExpr((Expression) exprs[0]); return true; } diff --git a/src/main/java/ch/njol/skript/sections/EffSecShoot.java b/src/main/java/ch/njol/skript/sections/EffSecShoot.java index b22c5fc77df..a7ef1e2e1e2 100644 --- a/src/main/java/ch/njol/skript/sections/EffSecShoot.java +++ b/src/main/java/ch/njol/skript/sections/EffSecShoot.java @@ -114,10 +114,12 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye (Consumer) getConsumer(event, vector, entityData, livingShooter) ); } else { - finalProjectile = livingShooter.getWorld().spawn( + Fireball fireball = (Fireball) livingShooter.getWorld().spawn( livingShooter.getEyeLocation().add(vector.clone().normalize().multiply(0.5)), type ); + fireball.setShooter(livingShooter); + finalProjectile = fireball; } } else if (Projectile.class.isAssignableFrom(type)) { if (trigger != null) { @@ -173,7 +175,7 @@ else if (entity instanceof Projectile projectile && shooter != null) lastSpawned = entity; Variables.setLocalVariables(shootEvent, Variables.copyLocalVariables(event)); TriggerItem.walk(trigger, shootEvent); - Variables.setLocalVariables(event, Variables.copyLocalVariables(event)); + Variables.setLocalVariables(event, Variables.copyLocalVariables(shootEvent)); Variables.removeLocals(shootEvent); }; } diff --git a/src/test/skript/tests/syntaxes/sections/EffSecShoot.sk b/src/test/skript/tests/syntaxes/sections/EffSecShoot.sk new file mode 100644 index 00000000000..baa05e07112 --- /dev/null +++ b/src/test/skript/tests/syntaxes/sections/EffSecShoot.sk @@ -0,0 +1,20 @@ +test "EffSecShoot": + set {_loc} to spawn of world "world" + spawn pig at {_loc}: + set ai of entity to false + set {_shooter} to entity + + shoot a pig from {_shooter} + assert last shot entity is a pig with "Last shot entity is not a pig" + + set {_pigs::*} to pig, pig, pig, pig and pig + shoot {_pigs::*} from {_shooter}: + add entity to {_projectiles::*} + assert shooter = {_shooter} with "ExprShooter does not return shooter used in effect" + assert size of {_projectiles::*} = 5 with "1 or more projectiles did not spawn" + loop {_projectiles::*}: + assert loop-value is a pig with "Projectile on loop %loop-iteration% is not a pig" + clear entities within {_projectiles::*} + clear {_projectiles::*} + + clear entity within {_shooter} From 25f1c7341b5dc6b7573e4815d3875ccf6170fd48 Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Mon, 7 Oct 2024 12:22:19 -0400 Subject: [PATCH 05/16] Requested Changes - 1 --- .../njol/skript/expressions/ExprShooter.java | 2 +- .../ch/njol/skript/sections/EffSecShoot.java | 25 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprShooter.java b/src/main/java/ch/njol/skript/expressions/ExprShooter.java index d996907c012..95592e180c3 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprShooter.java +++ b/src/main/java/ch/njol/skript/expressions/ExprShooter.java @@ -60,7 +60,7 @@ public boolean init(final Expression[] exprs, final int matchedPattern, final } @Override - protected LivingEntity @Nullable [] get(final Event event, final Projectile[] source) { + protected LivingEntity @Nullable [] get(Event event, Projectile[] source) { if (withinShootEvent && event instanceof EffSecShoot.ShootEvent shootEvent) { return new LivingEntity[]{shootEvent.getShooter()}; } diff --git a/src/main/java/ch/njol/skript/sections/EffSecShoot.java b/src/main/java/ch/njol/skript/sections/EffSecShoot.java index a7ef1e2e1e2..8c91c09a77a 100644 --- a/src/main/java/ch/njol/skript/sections/EffSecShoot.java +++ b/src/main/java/ch/njol/skript/sections/EffSecShoot.java @@ -3,6 +3,7 @@ import ch.njol.skript.Skript; import ch.njol.skript.config.SectionNode; import ch.njol.skript.entity.EntityData; +import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.*; import ch.njol.skript.registrations.EventValues; import ch.njol.skript.util.Direction; @@ -28,8 +29,10 @@ public class EffSecShoot extends EffectSection { public static class ShootEvent extends Event { + private Entity projectile; private @Nullable LivingEntity shooter; + public ShootEvent(Entity projectile, @Nullable LivingEntity shooter) { this.projectile = projectile; this.shooter = shooter; @@ -38,13 +41,13 @@ public ShootEvent(Entity projectile, @Nullable LivingEntity shooter) { public Entity getProjectile() { return projectile; } + public @Nullable LivingEntity getShooter() { return shooter; } @Override - @NotNull - public HandlerList getHandlers() { + public @NotNull HandlerList getHandlers() { throw new IllegalStateException(); } } @@ -72,7 +75,7 @@ public HandlerList getHandlers() { @Override @SuppressWarnings("unchecked") - public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult, @Nullable SectionNode sectionNode, @Nullable List triggerItems) { + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult, @Nullable SectionNode sectionNode, @Nullable List triggerItems) { types = (Expression>) exprs[matchedPattern]; shooters = exprs[1 - matchedPattern]; velocity = (Expression) exprs[2]; @@ -83,7 +86,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye Runnable afterLoading = () -> delayed.set(!getParser().getHasDelayBefore().isFalse()); trigger = loadCode(sectionNode, "shoot", afterLoading, ShootEvent.class); if (delayed.get()) { - Skript.error("Delays can't be used within a Shoot Effect Section"); + Skript.error("Delays cannot be used within a 'shoot' effect section"); return false; } } @@ -111,7 +114,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye livingShooter.getWorld().spawn( livingShooter.getEyeLocation().add(vector.clone().normalize().multiply(0.5)), type, - (Consumer) getConsumer(event, vector, entityData, livingShooter) + (Consumer) getSpawnConsumer(event, vector, entityData, livingShooter) ); } else { Fireball fireball = (Fireball) livingShooter.getWorld().spawn( @@ -126,7 +129,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye livingShooter.launchProjectile( (Class) type, vector, - (Consumer) getConsumer(event, vector, entityData, livingShooter) + (Consumer) getSpawnConsumer(event, vector, entityData, livingShooter) ); } else { finalProjectile = livingShooter.launchProjectile((Class) type); @@ -136,7 +139,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye Location location = livingShooter.getLocation(); location.setY(location.getY() + livingShooter.getEyeHeight() / 2); if (trigger != null) { - entityData.spawn(location, (Consumer) getConsumer(event, vector, entityData, livingShooter)); + entityData.spawn(location, (Consumer) getSpawnConsumer(event, vector, entityData, livingShooter)); } else { finalProjectile = entityData.spawn(location); } @@ -144,7 +147,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } else { vector = finalDirection.getDirection((Location) shooter).multiply(finalVelocity.doubleValue()); if (trigger != null) { - entityData.spawn((Location) shooter, (Consumer) getConsumer(event, vector, entityData, null)); + entityData.spawn((Location) shooter, (Consumer) getSpawnConsumer(event, vector, entityData, null)); } else { finalProjectile = entityData.spawn((Location) shooter); } @@ -164,7 +167,7 @@ private static void set(Entity entity, EntityData entityDa entityData.set((E) entity); } - private Consumer getConsumer(Event event, Vector vector, EntityData entityData, @Nullable LivingEntity shooter) { + private Consumer getSpawnConsumer(Event event, Vector vector, EntityData entityData, @Nullable LivingEntity shooter) { return entity -> { if (entity instanceof Fireball fireball) fireball.setShooter(shooter); @@ -182,7 +185,9 @@ else if (entity instanceof Projectile projectile && shooter != null) @Override public String toString(@Nullable Event event, boolean debug) { - return "shoot " + types.toString(event, debug) + " from " + shooters.toString(event, debug) + (velocity != null ? " at speed " + velocity.toString(event, debug) : "") + (direction != null ? " " + direction.toString(event, debug) : ""); + return "shoot " + types.toString(event, debug) + " from " + shooters.toString(event, debug) + + (velocity != null ? " at speed " + velocity.toString(event, debug) : "") + + (direction != null ? " " + direction.toString(event, debug) : ""); } } From c45855b560556b119c3fa5bae2a6ddabc8f69a87 Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:03:28 -0400 Subject: [PATCH 06/16] Requested Changes - 2 --- src/main/java/ch/njol/skript/expressions/ExprShooter.java | 6 +----- src/main/java/ch/njol/skript/sections/EffSecShoot.java | 6 ++++++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprShooter.java b/src/main/java/ch/njol/skript/expressions/ExprShooter.java index 95592e180c3..f411e8fee31 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprShooter.java +++ b/src/main/java/ch/njol/skript/expressions/ExprShooter.java @@ -48,20 +48,16 @@ public class ExprShooter extends PropertyExpression { Skript.registerExpression(ExprShooter.class, LivingEntity.class, ExpressionType.SIMPLE, "[the] shooter [of %projectile%]"); } - private boolean withinShootEvent; - @SuppressWarnings({"unchecked", "null"}) @Override public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { - if (getParser().isCurrentEvent(EffSecShoot.ShootEvent.class) && exprs[0] == null) - withinShootEvent = true; setExpr((Expression) exprs[0]); return true; } @Override protected LivingEntity @Nullable [] get(Event event, Projectile[] source) { - if (withinShootEvent && event instanceof EffSecShoot.ShootEvent shootEvent) { + if (event instanceof EffSecShoot.ShootEvent shootEvent && !(shootEvent.getProjectile() instanceof Projectile)) { return new LivingEntity[]{shootEvent.getShooter()}; } diff --git a/src/main/java/ch/njol/skript/sections/EffSecShoot.java b/src/main/java/ch/njol/skript/sections/EffSecShoot.java index 8c91c09a77a..e876117b3a7 100644 --- a/src/main/java/ch/njol/skript/sections/EffSecShoot.java +++ b/src/main/java/ch/njol/skript/sections/EffSecShoot.java @@ -63,6 +63,12 @@ public Entity getProjectile() { return shootEvent.getProjectile(); } }, EventValues.TIME_NOW); + EventValues.registerEventValue(ShootEvent.class, Projectile.class, new Getter() { + @Override + public @Nullable Projectile get(ShootEvent shootEvent) { + return shootEvent.getProjectile() instanceof Projectile projectile ? projectile : null; + } + }, EventValues.TIME_NOW); } private final static Double DEFAULT_SPEED = 5.; From d34e2fff76deb41e1f5c56908c56814bb7098441 Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:33:06 -0400 Subject: [PATCH 07/16] Fix ExprShooter --- .../ch/njol/skript/expressions/ExprShooter.java | 2 +- .../java/ch/njol/skript/sections/EffSecShoot.java | 4 +++- .../skript/tests/syntaxes/sections/EffSecShoot.sk | 13 +++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprShooter.java b/src/main/java/ch/njol/skript/expressions/ExprShooter.java index f411e8fee31..57a2682995c 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprShooter.java +++ b/src/main/java/ch/njol/skript/expressions/ExprShooter.java @@ -57,7 +57,7 @@ public boolean init(final Expression[] exprs, final int matchedPattern, final @Override protected LivingEntity @Nullable [] get(Event event, Projectile[] source) { - if (event instanceof EffSecShoot.ShootEvent shootEvent && !(shootEvent.getProjectile() instanceof Projectile)) { + if (event instanceof EffSecShoot.ShootEvent shootEvent && getExpr().isDefault() && !(shootEvent.getProjectile() instanceof Projectile)) { return new LivingEntity[]{shootEvent.getShooter()}; } diff --git a/src/main/java/ch/njol/skript/sections/EffSecShoot.java b/src/main/java/ch/njol/skript/sections/EffSecShoot.java index e876117b3a7..7b7d7e6745b 100644 --- a/src/main/java/ch/njol/skript/sections/EffSecShoot.java +++ b/src/main/java/ch/njol/skript/sections/EffSecShoot.java @@ -177,8 +177,10 @@ private Consumer getSpawnConsumer(Event event, Vector vector, return entity -> { if (entity instanceof Fireball fireball) fireball.setShooter(shooter); - else if (entity instanceof Projectile projectile && shooter != null) + else if (entity instanceof Projectile projectile && shooter != null) { + projectile.setShooter(shooter); set(projectile, entityData); + } entity.setVelocity(vector); ShootEvent shootEvent = new ShootEvent(entity, shooter); lastSpawned = entity; diff --git a/src/test/skript/tests/syntaxes/sections/EffSecShoot.sk b/src/test/skript/tests/syntaxes/sections/EffSecShoot.sk index baa05e07112..0a13f2efab0 100644 --- a/src/test/skript/tests/syntaxes/sections/EffSecShoot.sk +++ b/src/test/skript/tests/syntaxes/sections/EffSecShoot.sk @@ -7,6 +7,18 @@ test "EffSecShoot": shoot a pig from {_shooter} assert last shot entity is a pig with "Last shot entity is not a pig" + spawn cow at {_loc}: + set ai of entity to false + set {_shooter2} to entity + + shoot an arrow from {_shooter2}: + set {_other} to event-projectile + shoot a pig from {_shooter}: + assert (shooter of {_other}) = {_shooter2} with "ExprShooter did not get shooter of other projectile" + set {_projectile} to entity + clear entity within {_other} + clear entity within {_projectile} + set {_pigs::*} to pig, pig, pig, pig and pig shoot {_pigs::*} from {_shooter}: add entity to {_projectiles::*} @@ -18,3 +30,4 @@ test "EffSecShoot": clear {_projectiles::*} clear entity within {_shooter} + clear entity within {_shooter2} From 065f2b89c60653d63071d93bab169bd5e7cf6ba9 Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Mon, 7 Oct 2024 14:07:04 -0400 Subject: [PATCH 08/16] Fix Test --- src/test/skript/tests/syntaxes/sections/EffSecShoot.sk | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/skript/tests/syntaxes/sections/EffSecShoot.sk b/src/test/skript/tests/syntaxes/sections/EffSecShoot.sk index 0a13f2efab0..5ffc75ea374 100644 --- a/src/test/skript/tests/syntaxes/sections/EffSecShoot.sk +++ b/src/test/skript/tests/syntaxes/sections/EffSecShoot.sk @@ -6,6 +6,7 @@ test "EffSecShoot": shoot a pig from {_shooter} assert last shot entity is a pig with "Last shot entity is not a pig" + clear last shot entity spawn cow at {_loc}: set ai of entity to false From fa8dda0d87264814cea86573f1cbcbce888217dc Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Tue, 8 Oct 2024 14:28:30 -0400 Subject: [PATCH 09/16] Update ExprShooter --- .../njol/skript/expressions/ExprShooter.java | 36 +++++-------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprShooter.java b/src/main/java/ch/njol/skript/expressions/ExprShooter.java index 57a2682995c..093c56d502d 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprShooter.java +++ b/src/main/java/ch/njol/skript/expressions/ExprShooter.java @@ -1,21 +1,3 @@ -/** - * 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.expressions; import ch.njol.skript.Skript; @@ -50,7 +32,7 @@ public class ExprShooter extends PropertyExpression { @SuppressWarnings({"unchecked", "null"}) @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { setExpr((Expression) exprs[0]); return true; } @@ -63,30 +45,30 @@ public boolean init(final Expression[] exprs, final int matchedPattern, final return get(source, projectile -> { Object shooter = projectile != null ? projectile.getShooter() : null; - if (shooter instanceof LivingEntity) - return (LivingEntity) shooter; + if (shooter instanceof LivingEntity livingShooter) + return livingShooter; return null; }); } @Override @Nullable - public Class[] acceptChange(final ChangeMode mode) { + public Class[] acceptChange(ChangeMode mode) { if (mode == ChangeMode.SET) return new Class[] {LivingEntity.class}; return super.acceptChange(mode); } @Override - public void change(final Event e, final @Nullable Object[] delta, final ChangeMode mode) { + public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { if (mode == ChangeMode.SET) { assert delta != null; - for (final Projectile p : getExpr().getArray(e)) { + for (Projectile p : getExpr().getArray(event)) { assert p != null : getExpr(); p.setShooter((ProjectileSource) delta[0]); } } else { - super.change(e, delta, mode); + super.change(event, delta, mode); } } @@ -96,8 +78,8 @@ public Class getReturnType() { } @Override - public String toString(final @Nullable Event e, final boolean debug) { - return "the shooter" + (getExpr().isDefault() ? "" : " of " + getExpr().toString(e, debug)); + public String toString(@Nullable Event event, boolean debug) { + return "the shooter" + (getExpr().isDefault() ? "" : " of " + getExpr().toString(event, debug)); } } From c8d08f3b9fb70686bd26ce3186e566d4cde7997c Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Sat, 12 Oct 2024 01:10:27 -0400 Subject: [PATCH 10/16] Efy Changes --- .../njol/skript/expressions/ExprShooter.java | 9 ++++---- .../ch/njol/skript/sections/EffSecShoot.java | 22 ++++++++++++++----- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprShooter.java b/src/main/java/ch/njol/skript/expressions/ExprShooter.java index 093c56d502d..df5635e2cab 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprShooter.java +++ b/src/main/java/ch/njol/skript/expressions/ExprShooter.java @@ -52,8 +52,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - @Nullable - public Class[] acceptChange(ChangeMode mode) { + public @Nullable Class[] acceptChange(ChangeMode mode) { if (mode == ChangeMode.SET) return new Class[] {LivingEntity.class}; return super.acceptChange(mode); @@ -63,9 +62,9 @@ public Class[] acceptChange(ChangeMode mode) { public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { if (mode == ChangeMode.SET) { assert delta != null; - for (Projectile p : getExpr().getArray(event)) { - assert p != null : getExpr(); - p.setShooter((ProjectileSource) delta[0]); + for (Projectile projectile : getExpr().getArray(event)) { + assert projectile != null : getExpr(); + projectile.setShooter((ProjectileSource) delta[0]); } } else { super.change(event, delta, mode); diff --git a/src/main/java/ch/njol/skript/sections/EffSecShoot.java b/src/main/java/ch/njol/skript/sections/EffSecShoot.java index 7b7d7e6745b..6b89035ba4b 100644 --- a/src/main/java/ch/njol/skript/sections/EffSecShoot.java +++ b/src/main/java/ch/njol/skript/sections/EffSecShoot.java @@ -2,6 +2,10 @@ 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.SkriptParser.ParseResult; import ch.njol.skript.lang.*; @@ -26,6 +30,14 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; +@Name("Shoot") +@Description("Shoots a projectile (or any other entity) from a given entity or location.") +@Examples({ + "shoot arrow from all players at speed 2", + "shoot a pig from all players:", + "\tadd event-entity to {_projectiles::*}" +}) +@Since("INSERT VERSION") public class EffSecShoot extends EffectSection { public static class ShootEvent extends Event { @@ -120,7 +132,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye livingShooter.getWorld().spawn( livingShooter.getEyeLocation().add(vector.clone().normalize().multiply(0.5)), type, - (Consumer) getSpawnConsumer(event, vector, entityData, livingShooter) + (Consumer) afterSpawn(event, vector, entityData, livingShooter) ); } else { Fireball fireball = (Fireball) livingShooter.getWorld().spawn( @@ -135,7 +147,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye livingShooter.launchProjectile( (Class) type, vector, - (Consumer) getSpawnConsumer(event, vector, entityData, livingShooter) + (Consumer) afterSpawn(event, vector, entityData, livingShooter) ); } else { finalProjectile = livingShooter.launchProjectile((Class) type); @@ -145,7 +157,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye Location location = livingShooter.getLocation(); location.setY(location.getY() + livingShooter.getEyeHeight() / 2); if (trigger != null) { - entityData.spawn(location, (Consumer) getSpawnConsumer(event, vector, entityData, livingShooter)); + entityData.spawn(location, (Consumer) afterSpawn(event, vector, entityData, livingShooter)); } else { finalProjectile = entityData.spawn(location); } @@ -153,7 +165,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } else { vector = finalDirection.getDirection((Location) shooter).multiply(finalVelocity.doubleValue()); if (trigger != null) { - entityData.spawn((Location) shooter, (Consumer) getSpawnConsumer(event, vector, entityData, null)); + entityData.spawn((Location) shooter, (Consumer) afterSpawn(event, vector, entityData, null)); } else { finalProjectile = entityData.spawn((Location) shooter); } @@ -173,7 +185,7 @@ private static void set(Entity entity, EntityData entityDa entityData.set((E) entity); } - private Consumer getSpawnConsumer(Event event, Vector vector, EntityData entityData, @Nullable LivingEntity shooter) { + private Consumer afterSpawn(Event event, Vector vector, EntityData entityData, @Nullable LivingEntity shooter) { return entity -> { if (entity instanceof Fireball fireball) fireball.setShooter(shooter); From 669f1a51e68b648d63e0d16c2737695e419fe416 Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Sat, 12 Oct 2024 12:43:24 -0400 Subject: [PATCH 11/16] Suppres Change --- src/main/java/ch/njol/skript/sections/EffSecShoot.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/sections/EffSecShoot.java b/src/main/java/ch/njol/skript/sections/EffSecShoot.java index 6b89035ba4b..ba60ac7de67 100644 --- a/src/main/java/ch/njol/skript/sections/EffSecShoot.java +++ b/src/main/java/ch/njol/skript/sections/EffSecShoot.java @@ -112,7 +112,6 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - @SuppressWarnings({"unchecked","rawtypes"}) protected @Nullable TriggerItem walk(Event event) { lastSpawned = null; Number finalVelocity = velocity != null ? velocity.getSingle(event) : DEFAULT_SPEED; @@ -129,6 +128,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye Class type = entityData.getType(); if (Fireball.class.isAssignableFrom(type)) { if (trigger != null) { + //noinspection unchecked,rawtypes livingShooter.getWorld().spawn( livingShooter.getEyeLocation().add(vector.clone().normalize().multiply(0.5)), type, @@ -144,12 +144,14 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } } else if (Projectile.class.isAssignableFrom(type)) { if (trigger != null) { + //noinspection unchecked,rawtypes livingShooter.launchProjectile( (Class) type, vector, (Consumer) afterSpawn(event, vector, entityData, livingShooter) ); } else { + //noinspection unchecked finalProjectile = livingShooter.launchProjectile((Class) type); set(finalProjectile, entityData); } @@ -157,6 +159,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye Location location = livingShooter.getLocation(); location.setY(location.getY() + livingShooter.getEyeHeight() / 2); if (trigger != null) { + //noinspection unchecked,rawtypes entityData.spawn(location, (Consumer) afterSpawn(event, vector, entityData, livingShooter)); } else { finalProjectile = entityData.spawn(location); @@ -165,6 +168,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } else { vector = finalDirection.getDirection((Location) shooter).multiply(finalVelocity.doubleValue()); if (trigger != null) { + //noinspection unchecked,rawtypes entityData.spawn((Location) shooter, (Consumer) afterSpawn(event, vector, entityData, null)); } else { finalProjectile = entityData.spawn((Location) shooter); From 7ec2c38148cd1c5948b7b121d874b07178d3d6db Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Tue, 15 Oct 2024 21:39:50 -0400 Subject: [PATCH 12/16] Consumer var --- .../java/ch/njol/skript/sections/EffSecShoot.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/ch/njol/skript/sections/EffSecShoot.java b/src/main/java/ch/njol/skript/sections/EffSecShoot.java index ba60ac7de67..c9f64d04177 100644 --- a/src/main/java/ch/njol/skript/sections/EffSecShoot.java +++ b/src/main/java/ch/njol/skript/sections/EffSecShoot.java @@ -125,14 +125,16 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye Vector vector; if (shooter instanceof LivingEntity livingShooter) { vector = finalDirection.getDirection(livingShooter.getLocation()).multiply(finalVelocity.doubleValue()); + //noinspection rawtypes + Consumer afterSpawn = afterSpawn(event, vector, entityData, livingShooter); Class type = entityData.getType(); if (Fireball.class.isAssignableFrom(type)) { if (trigger != null) { - //noinspection unchecked,rawtypes + //noinspection unchecked livingShooter.getWorld().spawn( livingShooter.getEyeLocation().add(vector.clone().normalize().multiply(0.5)), type, - (Consumer) afterSpawn(event, vector, entityData, livingShooter) + afterSpawn ); } else { Fireball fireball = (Fireball) livingShooter.getWorld().spawn( @@ -144,11 +146,11 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } } else if (Projectile.class.isAssignableFrom(type)) { if (trigger != null) { - //noinspection unchecked,rawtypes + //noinspection unchecked livingShooter.launchProjectile( (Class) type, vector, - (Consumer) afterSpawn(event, vector, entityData, livingShooter) + afterSpawn ); } else { //noinspection unchecked @@ -159,8 +161,8 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye Location location = livingShooter.getLocation(); location.setY(location.getY() + livingShooter.getEyeHeight() / 2); if (trigger != null) { - //noinspection unchecked,rawtypes - entityData.spawn(location, (Consumer) afterSpawn(event, vector, entityData, livingShooter)); + //noinspection unchecked + entityData.spawn(location, afterSpawn); } else { finalProjectile = entityData.spawn(location); } From fa957e8f516774a70ef18689681d03d6b308befd Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Wed, 16 Oct 2024 02:10:34 -0400 Subject: [PATCH 13/16] Fix 1.19 LivingEntity#launchProjectile --- .../ch/njol/skript/sections/EffSecShoot.java | 69 +++++++++++++++---- 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/src/main/java/ch/njol/skript/sections/EffSecShoot.java b/src/main/java/ch/njol/skript/sections/EffSecShoot.java index c9f64d04177..19930d5a833 100644 --- a/src/main/java/ch/njol/skript/sections/EffSecShoot.java +++ b/src/main/java/ch/njol/skript/sections/EffSecShoot.java @@ -21,7 +21,6 @@ import org.bukkit.entity.Projectile; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; -import org.bukkit.projectiles.ProjectileSource; import org.bukkit.util.Vector; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,6 +29,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; +import java.lang.reflect.Method; + @Name("Shoot") @Description("Shoots a projectile (or any other entity) from a given entity or location.") @Examples({ @@ -40,6 +41,8 @@ @Since("INSERT VERSION") public class EffSecShoot extends EffectSection { + //TODO: Remove reflect method once 1.19 is no longer supported + public static class ShootEvent extends Event { private Entity projectile; @@ -64,6 +67,9 @@ public Entity getProjectile() { } } + private static final boolean RUNNING_1_20_4 = Skript.isRunningMinecraft(1, 20, 4); + private static Method LAUNCH_BUKKIT_CONSUMER_METHOD; + static { Skript.registerSection(EffSecShoot.class, "shoot %entitydatas% [from %livingentities/locations%] [(at|with) (speed|velocity) %-number%] [%-direction%]", @@ -81,7 +87,15 @@ public Entity getProjectile() { return shootEvent.getProjectile() instanceof Projectile projectile ? projectile : null; } }, EventValues.TIME_NOW); - } + + if (!RUNNING_1_20_4) { + try { + LAUNCH_BUKKIT_CONSUMER_METHOD = LivingEntity.class.getMethod("launchProjectile", Class.class, Vector.class, org.bukkit.util.Consumer.class); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + } private final static Double DEFAULT_SPEED = 5.; private Expression> types; @@ -126,7 +140,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye if (shooter instanceof LivingEntity livingShooter) { vector = finalDirection.getDirection(livingShooter.getLocation()).multiply(finalVelocity.doubleValue()); //noinspection rawtypes - Consumer afterSpawn = afterSpawn(event, vector, entityData, livingShooter); + Consumer afterSpawn = afterSpawn(event, entityData, livingShooter); Class type = entityData.getType(); if (Fireball.class.isAssignableFrom(type)) { if (trigger != null) { @@ -146,12 +160,23 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } } else if (Projectile.class.isAssignableFrom(type)) { if (trigger != null) { - //noinspection unchecked - livingShooter.launchProjectile( - (Class) type, - vector, - afterSpawn - ); + if (!RUNNING_1_20_4 && LAUNCH_BUKKIT_CONSUMER_METHOD != null) { + // 1.19 uses Bukkit Consumer instead of Java Consumer + try { + LAUNCH_BUKKIT_CONSUMER_METHOD.invoke(livingShooter, + type, + vector, + afterSpawnBukkit(event, entityData, livingShooter) + ); + } catch (Exception ignored) {}; + } else { + //noinspection unchecked + livingShooter.launchProjectile( + (Class) type, + vector, + afterSpawn + ); + } } else { //noinspection unchecked finalProjectile = livingShooter.launchProjectile((Class) type); @@ -171,7 +196,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye vector = finalDirection.getDirection((Location) shooter).multiply(finalVelocity.doubleValue()); if (trigger != null) { //noinspection unchecked,rawtypes - entityData.spawn((Location) shooter, (Consumer) afterSpawn(event, vector, entityData, null)); + entityData.spawn((Location) shooter, (Consumer) afterSpawn(event, entityData, null)); } else { finalProjectile = entityData.spawn((Location) shooter); } @@ -191,7 +216,7 @@ private static void set(Entity entity, EntityData entityDa entityData.set((E) entity); } - private Consumer afterSpawn(Event event, Vector vector, EntityData entityData, @Nullable LivingEntity shooter) { + private Consumer afterSpawn(Event event, EntityData entityData, @Nullable LivingEntity shooter) { return entity -> { if (entity instanceof Fireball fireball) fireball.setShooter(shooter); @@ -199,7 +224,6 @@ else if (entity instanceof Projectile projectile && shooter != null) { projectile.setShooter(shooter); set(projectile, entityData); } - entity.setVelocity(vector); ShootEvent shootEvent = new ShootEvent(entity, shooter); lastSpawned = entity; Variables.setLocalVariables(shootEvent, Variables.copyLocalVariables(event)); @@ -209,6 +233,27 @@ else if (entity instanceof Projectile projectile && shooter != null) { }; } + /** + * MC 1.19 uses Bukkit Consumer for LivingEntity$launchProjectile instead of Java Consumer + */ + @SuppressWarnings("deprecation") + private org.bukkit.util.Consumer afterSpawnBukkit(Event event, EntityData entityData, @Nullable LivingEntity shooter) { + return entity -> { + if (entity instanceof Fireball fireball) + fireball.setShooter(shooter); + else if (entity instanceof Projectile projectile && shooter != null) { + projectile.setShooter(shooter); + set(projectile, entityData); + } + ShootEvent shootEvent = new ShootEvent(entity, shooter); + lastSpawned = entity; + Variables.setLocalVariables(shootEvent, Variables.copyLocalVariables(event)); + TriggerItem.walk(trigger, shootEvent); + Variables.setLocalVariables(event, Variables.copyLocalVariables(shootEvent)); + Variables.removeLocals(shootEvent); + }; + } + @Override public String toString(@Nullable Event event, boolean debug) { return "shoot " + types.toString(event, debug) + " from " + shooters.toString(event, debug) + From a09040afdd931dec18e06803fd78bcdfeb9e9051 Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Sun, 27 Oct 2024 17:36:08 -0400 Subject: [PATCH 14/16] Changes --- .../ch/njol/skript/sections/EffSecShoot.java | 119 ++++++++++-------- 1 file changed, 67 insertions(+), 52 deletions(-) diff --git a/src/main/java/ch/njol/skript/sections/EffSecShoot.java b/src/main/java/ch/njol/skript/sections/EffSecShoot.java index 19930d5a833..4a8c0b404c4 100644 --- a/src/main/java/ch/njol/skript/sections/EffSecShoot.java +++ b/src/main/java/ch/njol/skript/sections/EffSecShoot.java @@ -67,7 +67,7 @@ public Entity getProjectile() { } } - private static final boolean RUNNING_1_20_4 = Skript.isRunningMinecraft(1, 20, 4); + private static boolean RUNNING_PAPER; private static Method LAUNCH_BUKKIT_CONSUMER_METHOD; static { @@ -88,14 +88,16 @@ public Entity getProjectile() { } }, EventValues.TIME_NOW); - if (!RUNNING_1_20_4) { + if (!Skript.isRunningMinecraft(1, 20, 3)) { try { LAUNCH_BUKKIT_CONSUMER_METHOD = LivingEntity.class.getMethod("launchProjectile", Class.class, Vector.class, org.bukkit.util.Consumer.class); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } - } + boolean LAUNCH_JAVA_CONSUMER = Skript.methodExists(LivingEntity.class, "launchProjectile", Class.class, Vector.class, Consumer.class); + RUNNING_PAPER = LAUNCH_BUKKIT_CONSUMER_METHOD != null || LAUNCH_JAVA_CONSUMER; + } private final static Double DEFAULT_SPEED = 5.; private Expression> types; @@ -142,54 +144,67 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye //noinspection rawtypes Consumer afterSpawn = afterSpawn(event, entityData, livingShooter); Class type = entityData.getType(); + Location shooterLoc = livingShooter.getLocation(); + shooterLoc.setY(shooterLoc.getY() + livingShooter.getEyeHeight() / 2); + boolean isProjectile = false, useWorldSpawn = false; if (Fireball.class.isAssignableFrom(type)) { - if (trigger != null) { - //noinspection unchecked - livingShooter.getWorld().spawn( - livingShooter.getEyeLocation().add(vector.clone().normalize().multiply(0.5)), - type, - afterSpawn - ); - } else { - Fireball fireball = (Fireball) livingShooter.getWorld().spawn( - livingShooter.getEyeLocation().add(vector.clone().normalize().multiply(0.5)), - type - ); - fireball.setShooter(livingShooter); - finalProjectile = fireball; - } + shooterLoc = livingShooter.getEyeLocation().add(vector.clone().normalize().multiply(0.5)); + isProjectile = true; + useWorldSpawn = true; } else if (Projectile.class.isAssignableFrom(type)) { - if (trigger != null) { - if (!RUNNING_1_20_4 && LAUNCH_BUKKIT_CONSUMER_METHOD != null) { - // 1.19 uses Bukkit Consumer instead of Java Consumer - try { - LAUNCH_BUKKIT_CONSUMER_METHOD.invoke(livingShooter, - type, - vector, - afterSpawnBukkit(event, entityData, livingShooter) - ); - } catch (Exception ignored) {}; - } else { + isProjectile = true; + if (trigger != null && !RUNNING_PAPER) { + useWorldSpawn = true; + } + } + + if (isProjectile) { + if (useWorldSpawn) { + if (trigger != null) { //noinspection unchecked - livingShooter.launchProjectile( - (Class) type, - vector, + livingShooter.getWorld().spawn( + shooterLoc, + type, afterSpawn ); + } else { + Projectile projectile = (Projectile) livingShooter.getWorld().spawn( + shooterLoc, + type + ); + projectile.setShooter(livingShooter); + finalProjectile = projectile; } } else { - //noinspection unchecked - finalProjectile = livingShooter.launchProjectile((Class) type); - set(finalProjectile, entityData); + if (trigger != null) { + if (LAUNCH_BUKKIT_CONSUMER_METHOD != null) { + try { + LAUNCH_BUKKIT_CONSUMER_METHOD.invoke(livingShooter, + type, + vector, + afterSpawnBukkit(event, entityData, livingShooter) + ); + } catch (Exception ignored) {}; + } else { + //noinspection unchecked + livingShooter.launchProjectile( + (Class) type, + vector, + afterSpawn + ); + } + } else { + //noinspection unchecked + finalProjectile = livingShooter.launchProjectile((Class) type); + set(finalProjectile, entityData); + } } } else { - Location location = livingShooter.getLocation(); - location.setY(location.getY() + livingShooter.getEyeHeight() / 2); if (trigger != null) { //noinspection unchecked - entityData.spawn(location, afterSpawn); + entityData.spawn(shooterLoc, afterSpawn); } else { - finalProjectile = entityData.spawn(location); + finalProjectile = entityData.spawn(shooterLoc); } } } else { @@ -239,19 +254,19 @@ else if (entity instanceof Projectile projectile && shooter != null) { @SuppressWarnings("deprecation") private org.bukkit.util.Consumer afterSpawnBukkit(Event event, EntityData entityData, @Nullable LivingEntity shooter) { return entity -> { - if (entity instanceof Fireball fireball) - fireball.setShooter(shooter); - else if (entity instanceof Projectile projectile && shooter != null) { - projectile.setShooter(shooter); - set(projectile, entityData); - } - ShootEvent shootEvent = new ShootEvent(entity, shooter); - lastSpawned = entity; - Variables.setLocalVariables(shootEvent, Variables.copyLocalVariables(event)); - TriggerItem.walk(trigger, shootEvent); - Variables.setLocalVariables(event, Variables.copyLocalVariables(shootEvent)); - Variables.removeLocals(shootEvent); - }; + if (entity instanceof Fireball fireball) + fireball.setShooter(shooter); + else if (entity instanceof Projectile projectile && shooter != null) { + projectile.setShooter(shooter); + set(projectile, entityData); + } + ShootEvent shootEvent = new ShootEvent(entity, shooter); + lastSpawned = entity; + Variables.setLocalVariables(shootEvent, Variables.copyLocalVariables(event)); + TriggerItem.walk(trigger, shootEvent); + Variables.setLocalVariables(event, Variables.copyLocalVariables(shootEvent)); + Variables.removeLocals(shootEvent); + }; } @Override From f02e69413cb137c52e0237374afd4dcff6e28cdc Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:20:28 -0400 Subject: [PATCH 15/16] Requested Changes --- .../njol/skript/expressions/ExprShooter.java | 2 +- .../ch/njol/skript/sections/EffSecShoot.java | 22 ++++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprShooter.java b/src/main/java/ch/njol/skript/expressions/ExprShooter.java index df5635e2cab..6868742e8a6 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprShooter.java +++ b/src/main/java/ch/njol/skript/expressions/ExprShooter.java @@ -30,9 +30,9 @@ public class ExprShooter extends PropertyExpression { Skript.registerExpression(ExprShooter.class, LivingEntity.class, ExpressionType.SIMPLE, "[the] shooter [of %projectile%]"); } - @SuppressWarnings({"unchecked", "null"}) @Override public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + //noinspection unchecked setExpr((Expression) exprs[0]); return true; } diff --git a/src/main/java/ch/njol/skript/sections/EffSecShoot.java b/src/main/java/ch/njol/skript/sections/EffSecShoot.java index 4a8c0b404c4..83cb98461e8 100644 --- a/src/main/java/ch/njol/skript/sections/EffSecShoot.java +++ b/src/main/java/ch/njol/skript/sections/EffSecShoot.java @@ -67,8 +67,8 @@ public Entity getProjectile() { } } - private static boolean RUNNING_PAPER; - private static Method LAUNCH_BUKKIT_CONSUMER_METHOD; + private static final boolean RUNNING_PAPER; + private static Method launchWithBukkitConsumer; static { Skript.registerSection(EffSecShoot.class, @@ -90,13 +90,13 @@ public Entity getProjectile() { if (!Skript.isRunningMinecraft(1, 20, 3)) { try { - LAUNCH_BUKKIT_CONSUMER_METHOD = LivingEntity.class.getMethod("launchProjectile", Class.class, Vector.class, org.bukkit.util.Consumer.class); + launchWithBukkitConsumer = LivingEntity.class.getMethod("launchProjectile", Class.class, Vector.class, org.bukkit.util.Consumer.class); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } - boolean LAUNCH_JAVA_CONSUMER = Skript.methodExists(LivingEntity.class, "launchProjectile", Class.class, Vector.class, Consumer.class); - RUNNING_PAPER = LAUNCH_BUKKIT_CONSUMER_METHOD != null || LAUNCH_JAVA_CONSUMER; + boolean launchHasJavaConsumer = Skript.methodExists(LivingEntity.class, "launchProjectile", Class.class, Vector.class, Consumer.class); + RUNNING_PAPER = launchWithBukkitConsumer != null || launchHasJavaConsumer; } private final static Double DEFAULT_SPEED = 5.; @@ -108,11 +108,13 @@ public Entity getProjectile() { private @Nullable Trigger trigger; @Override - @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult, @Nullable SectionNode sectionNode, @Nullable List triggerItems) { + //noinspection unchecked types = (Expression>) exprs[matchedPattern]; shooters = exprs[1 - matchedPattern]; + //noinspection unchecked velocity = (Expression) exprs[2]; + //noinspection unchecked direction = (Expression) exprs[3]; if (sectionNode != null) { @@ -177,9 +179,9 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } } else { if (trigger != null) { - if (LAUNCH_BUKKIT_CONSUMER_METHOD != null) { + if (launchWithBukkitConsumer != null) { try { - LAUNCH_BUKKIT_CONSUMER_METHOD.invoke(livingShooter, + launchWithBukkitConsumer.invoke(livingShooter, type, vector, afterSpawnBukkit(event, entityData, livingShooter) @@ -226,8 +228,8 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye return super.walk(event, false); } - @SuppressWarnings("unchecked") private static void set(Entity entity, EntityData entityData) { + //noinspection unchecked entityData.set((E) entity); } @@ -249,7 +251,7 @@ else if (entity instanceof Projectile projectile && shooter != null) { } /** - * MC 1.19 uses Bukkit Consumer for LivingEntity$launchProjectile instead of Java Consumer + * MC 1.19 uses Bukkit Consumer for LivingEntity#launchProjectile instead of Java Consumer */ @SuppressWarnings("deprecation") private org.bukkit.util.Consumer afterSpawnBukkit(Event event, EntityData entityData, @Nullable LivingEntity shooter) { From 5903c377096647c82985ec8206b555144bb3459f Mon Sep 17 00:00:00 2001 From: SirSmurfy2 <82696841+TheAbsolutionism@users.noreply.github.com> Date: Fri, 8 Nov 2024 21:56:58 -0500 Subject: [PATCH 16/16] Reduce Nesting --- .../ch/njol/skript/sections/EffSecShoot.java | 113 ++++++++++-------- 1 file changed, 65 insertions(+), 48 deletions(-) diff --git a/src/main/java/ch/njol/skript/sections/EffSecShoot.java b/src/main/java/ch/njol/skript/sections/EffSecShoot.java index 83cb98461e8..bdc45da781c 100644 --- a/src/main/java/ch/njol/skript/sections/EffSecShoot.java +++ b/src/main/java/ch/njol/skript/sections/EffSecShoot.java @@ -7,8 +7,11 @@ 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.*; +import ch.njol.skript.lang.Trigger; +import ch.njol.skript.lang.TriggerItem; import ch.njol.skript.registrations.EventValues; import ch.njol.skript.util.Direction; import ch.njol.skript.util.Getter; @@ -25,12 +28,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.reflect.Method; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; -import java.lang.reflect.Method; - @Name("Shoot") @Description("Shoots a projectile (or any other entity) from a given entity or location.") @Examples({ @@ -43,6 +45,16 @@ public class EffSecShoot extends EffectSection { //TODO: Remove reflect method once 1.19 is no longer supported + private enum CaseUsage { + NOT_PROJECTILE_NO_TRIGGER, + NOT_PROJECTILE_TRIGGER, + PROJECTILE_NO_WORLD_NO_TRIGGER, + PROJECTILE_NO_WORLD_TRIGGER_BUKKIT, + PROJECTILE_NO_WORLD_TRIGGER, + PROJECTILE_WORLD_NO_TRIGGER, + PROJECTILE_WORLD_TRIGGER; + } + public static class ShootEvent extends Event { private Entity projectile; @@ -136,9 +148,10 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye Direction finalDirection = direction != null ? direction.getSingle(event) : Direction.IDENTITY; if (finalVelocity == null || finalDirection == null) return null; + EntityData[] data = types.getArray(event); for (Object shooter : shooters.getArray(event)) { - for (EntityData entityData : types.getArray(event)) { + for (EntityData entityData : data) { Entity finalProjectile = null; Vector vector; if (shooter instanceof LivingEntity livingShooter) { @@ -160,54 +173,40 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } } - if (isProjectile) { - if (useWorldSpawn) { - if (trigger != null) { - //noinspection unchecked - livingShooter.getWorld().spawn( - shooterLoc, - type, - afterSpawn - ); - } else { - Projectile projectile = (Projectile) livingShooter.getWorld().spawn( - shooterLoc, - type - ); - projectile.setShooter(livingShooter); - finalProjectile = projectile; - } - } else { - if (trigger != null) { - if (launchWithBukkitConsumer != null) { - try { - launchWithBukkitConsumer.invoke(livingShooter, - type, - vector, - afterSpawnBukkit(event, entityData, livingShooter) - ); - } catch (Exception ignored) {}; - } else { - //noinspection unchecked - livingShooter.launchProjectile( - (Class) type, - vector, - afterSpawn - ); - } - } else { - //noinspection unchecked - finalProjectile = livingShooter.launchProjectile((Class) type); - set(finalProjectile, entityData); - } + CaseUsage caseUsage = getCaseUsage(isProjectile, useWorldSpawn, trigger != null); + + switch (caseUsage) { + case NOT_PROJECTILE_NO_TRIGGER -> { + finalProjectile = entityData.spawn(shooterLoc); } - } else { - if (trigger != null) { + case NOT_PROJECTILE_TRIGGER -> { //noinspection unchecked entityData.spawn(shooterLoc, afterSpawn); - } else { - finalProjectile = entityData.spawn(shooterLoc); } + case PROJECTILE_NO_WORLD_NO_TRIGGER -> { + //noinspection unchecked + finalProjectile = livingShooter.launchProjectile((Class) type); + set(finalProjectile, entityData); + } + case PROJECTILE_NO_WORLD_TRIGGER_BUKKIT -> { + try { + launchWithBukkitConsumer.invoke(livingShooter, type, vector, afterSpawnBukkit(event, entityData, livingShooter)); + } catch (Exception ignored) {}; + } + case PROJECTILE_NO_WORLD_TRIGGER -> { + //noinspection unchecked + livingShooter.launchProjectile((Class) type, vector, afterSpawn); + } + case PROJECTILE_WORLD_NO_TRIGGER -> { + Projectile projectile = (Projectile) livingShooter.getWorld().spawn(shooterLoc, type); + projectile.setShooter(livingShooter); + finalProjectile = projectile; + } + case PROJECTILE_WORLD_TRIGGER -> { + //noinspection unchecked + livingShooter.getWorld().spawn(shooterLoc, type, afterSpawn); + } + default -> throw new IllegalStateException("Unexpected value: " + caseUsage); } } else { vector = finalDirection.getDirection((Location) shooter).multiply(finalVelocity.doubleValue()); @@ -233,6 +232,24 @@ private static void set(Entity entity, EntityData entityDa entityData.set((E) entity); } + private CaseUsage getCaseUsage(Boolean isProjectile, Boolean useWorldSpawn, Boolean hasTrigger) { + if (!isProjectile) { + if (!hasTrigger) + return CaseUsage.NOT_PROJECTILE_NO_TRIGGER; + return CaseUsage.NOT_PROJECTILE_TRIGGER; + } + if (!useWorldSpawn) { + if (!hasTrigger) + return CaseUsage.PROJECTILE_NO_WORLD_NO_TRIGGER; + if (launchWithBukkitConsumer != null) + return CaseUsage.PROJECTILE_NO_WORLD_TRIGGER_BUKKIT; + return CaseUsage.PROJECTILE_NO_WORLD_TRIGGER; + } + if (!hasTrigger) + return CaseUsage.PROJECTILE_WORLD_NO_TRIGGER; + return CaseUsage.PROJECTILE_WORLD_TRIGGER; + } + private Consumer afterSpawn(Event event, EntityData entityData, @Nullable LivingEntity shooter) { return entity -> { if (entity instanceof Fireball fireball)