From 66f20dcd0870af4569b039d0cab1eb12ea25621c Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Mon, 2 Jan 2023 13:25:35 -0700 Subject: [PATCH 01/15] Update passengers and vehicles --- .../skript/bukkitutil/PassengerUtils.java | 105 ---------- .../skript/conditions/CondHasPassengers.java | 62 ++++++ .../njol/skript/conditions/CondIsEmpty.java | 45 ++-- .../ch/njol/skript/effects/EffVehicle.java | 100 +++++---- .../skript/expressions/ExprPassenger.java | 190 ----------------- .../skript/expressions/ExprPassengers.java | 197 ++++++++++++++++++ .../njol/skript/expressions/ExprVehicle.java | 149 +++++++------ .../syntaxes/conditions/CondHasPassengers.sk | 24 +++ 8 files changed, 435 insertions(+), 437 deletions(-) delete mode 100644 src/main/java/ch/njol/skript/bukkitutil/PassengerUtils.java create mode 100644 src/main/java/ch/njol/skript/conditions/CondHasPassengers.java delete mode 100644 src/main/java/ch/njol/skript/expressions/ExprPassenger.java create mode 100644 src/main/java/ch/njol/skript/expressions/ExprPassengers.java create mode 100644 src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk diff --git a/src/main/java/ch/njol/skript/bukkitutil/PassengerUtils.java b/src/main/java/ch/njol/skript/bukkitutil/PassengerUtils.java deleted file mode 100644 index 70b84941f93..00000000000 --- a/src/main/java/ch/njol/skript/bukkitutil/PassengerUtils.java +++ /dev/null @@ -1,105 +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.bukkitutil; - -import java.lang.reflect.Method; - -import org.bukkit.entity.Entity; - -import ch.njol.skript.Skript; - -/** - * @author Peter Güttinger and contributors - */ -@SuppressWarnings("null") -public abstract class PassengerUtils { - - private PassengerUtils() {} - - //Using reflection methods cause it will be removed soon in 1.12 - private static Method getPassenger = null; - private static Method setPassenger = null; - - - static { - if (!Skript.methodExists(Entity.class, "getPassengers")) { - try { - getPassenger = Entity.class.getDeclaredMethod("getPassenger"); - setPassenger = Entity.class.getDeclaredMethod("setPassenger", Entity.class); - } catch (final NoSuchMethodException ex) { - Skript.outdatedError(ex); - } catch (final Exception ex) { - Skript.exception(ex); - } - } - } - - public static Entity[] getPassenger(Entity e) { - if (hasMultiplePassenger()) { - return e.getPassengers().toArray(new Entity[0]); - } else { - try { - return new Entity[]{(Entity)getPassenger.invoke(e)}; - } catch (final Exception ex) { //I don't think it can happen, but just in case. - Skript.exception(ex, "A error occured while trying to get a passenger in version lower than 1.11.2."); - } - } - return null; - } - /** - * Add the passenger to the vehicle - * @param vehicle - The entity vehicle - * @param passenger - The entity passenger - */ - public static void addPassenger(Entity vehicle, Entity passenger) { - if (vehicle == null || passenger == null) - return; - if (hasMultiplePassenger()) { - vehicle.addPassenger(passenger); - } else { - try { - vehicle.eject(); - setPassenger.invoke(vehicle, passenger); - } catch (final Exception ex) { - Skript.exception(ex, "A error occured while trying to set a passenger in version lower than 1.11.2."); - } - } - } - /** - * Remove the passenger from the vehicle. - * @param vehicle - The entity vehicle - * @param passenger - The entity passenger - */ - public static void removePassenger(Entity vehicle, Entity passenger){ - if (vehicle == null || passenger == null) - return; - if (hasMultiplePassenger()){ - vehicle.removePassenger(passenger); - } else { - vehicle.eject(); - } - } - /** - * @return True if it supports multiple passengers - */ - public static boolean hasMultiplePassenger(){ - return setPassenger == null; - } - -} diff --git a/src/main/java/ch/njol/skript/conditions/CondHasPassengers.java b/src/main/java/ch/njol/skript/conditions/CondHasPassengers.java new file mode 100644 index 00000000000..e8d5ce8d80d --- /dev/null +++ b/src/main/java/ch/njol/skript/conditions/CondHasPassengers.java @@ -0,0 +1,62 @@ +/** + * 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.conditions; + +import org.bukkit.entity.Entity; + +import ch.njol.skript.conditions.base.PropertyCondition; +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.Expression; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.util.Kleenean; + +@Name("Has Passengers") +@Description("Checks whether the given entities have passengers.") +@Examples("if the vehicle has passengers:") +@Since("INSERT VERSION") +public class CondHasPassengers extends PropertyCondition { + + static { + register(CondHasPassengers.class, PropertyType.HAVE, "[a|:no] passenger[s]", "entities"); + } + + @Override + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + setExpr((Expression) exprs[0]); + setNegated(matchedPattern == 1); + if (parseResult.hasTag("no")) + setNegated(true); + return true; + } + + @Override + public boolean check(Entity entity) { + return !entity.isEmpty(); + } + + @Override + protected String getPropertyName() { + return "passengers"; + } + +} diff --git a/src/main/java/ch/njol/skript/conditions/CondIsEmpty.java b/src/main/java/ch/njol/skript/conditions/CondIsEmpty.java index 972f38ed5d3..189e65314ae 100644 --- a/src/main/java/ch/njol/skript/conditions/CondIsEmpty.java +++ b/src/main/java/ch/njol/skript/conditions/CondIsEmpty.java @@ -19,6 +19,7 @@ package ch.njol.skript.conditions; import org.bukkit.Material; +import org.bukkit.entity.Entity; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -29,42 +30,46 @@ import ch.njol.skript.doc.Since; import ch.njol.skript.util.slot.Slot; -/** - * @author Peter Güttinger - */ @Name("Is Empty") -@Description("Checks whether an inventory, an inventory slot, or a text is empty.") +@Description({ + "Checks whether an inventory, an inventory slot, or a text is empty.", + "An entity can be a type, which will check if there are no passengers." +}) @Examples("player's inventory is empty") -@Since("unknown (before 2.1)") +@Since("unknown (before 2.1), INSERT VERSION (Entity)") public class CondIsEmpty extends PropertyCondition { - + static { - register(CondIsEmpty.class, "empty", "inventories/slots/strings"); + register(CondIsEmpty.class, "empty", "entities/inventories/slots/strings"); } - + @Override - public boolean check(final Object o) { - if (o instanceof String) - return ((String) o).isEmpty(); - if (o instanceof Inventory) { - for (ItemStack s : ((Inventory) o).getContents()) { - if (s != null && s.getType() != Material.AIR) + public boolean check(Object object) { + if (object instanceof String) + return ((String) object).isEmpty(); + if (object instanceof Inventory) { + for (ItemStack item : ((Inventory) object).getContents()) { + if (item != null && item.getType() != Material.AIR) return false; // There is an item here! } return true; } - if (o instanceof Slot) { - final Slot s = (Slot) o; - final ItemStack i = s.getItem(); - return i == null || i.getType() == Material.AIR; + if (object instanceof Slot) { + Slot slot = (Slot) object; + ItemStack item = slot.getItem(); + return item == null || item.getType() == Material.AIR; + } + if (object instanceof Entity) { + Entity entity = (Entity) object; + return entity.isEmpty(); } assert false; return false; } - + @Override protected String getPropertyName() { return "empty"; } - + } diff --git a/src/main/java/ch/njol/skript/effects/EffVehicle.java b/src/main/java/ch/njol/skript/effects/EffVehicle.java index 2bf3da326e7..8d7d27f0d1a 100644 --- a/src/main/java/ch/njol/skript/effects/EffVehicle.java +++ b/src/main/java/ch/njol/skript/effects/EffVehicle.java @@ -23,103 +23,111 @@ import org.eclipse.jdt.annotation.Nullable; import ch.njol.skript.Skript; -import ch.njol.skript.bukkitutil.PassengerUtils; 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.expressions.ExprLastSpawnedEntity; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.sections.EffSecSpawn; import ch.njol.util.Kleenean; -/** - * @author Peter Güttinger - */ @Name("Vehicle") @Description({"Makes an entity ride another entity, e.g. a minecart, a saddled pig, an arrow, etc."}) -@Examples({"make the player ride a saddled pig", - "make the attacker ride the victim"}) +@Examples({ + "make the player ride a saddled pig", + "make the attacker ride the victim" +}) @Since("2.0") public class EffVehicle extends Effect { + static { Skript.registerEffect(EffVehicle.class, - "(make|let|force) %entities% [to] (ride|mount) [(in|on)] %"+ (PassengerUtils.hasMultiplePassenger() ? "entities" : "entity") +"/entitydatas%", + "(make|let|force) %entities% [to] (ride|mount) [(in|on)] %entities/entitydatas%", "(make|let|force) %entities% [to] (dismount|(dismount|leave) (from|of|) (any|the[ir]|his|her|) vehicle[s])", "(eject|dismount) (any|the|) passenger[s] (of|from) %entities%"); } - + @Nullable private Expression passengers; + @Nullable private Expression vehicles; - - @SuppressWarnings({"unchecked", "null"}) + @Override - public boolean init(final Expression[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) { + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { passengers = matchedPattern == 2 ? null : (Expression) exprs[0]; vehicles = matchedPattern == 1 ? null : exprs[exprs.length - 1]; - if (!PassengerUtils.hasMultiplePassenger() && passengers != null && vehicles != null && !passengers.isSingle() && vehicles.isSingle() && Entity.class.isAssignableFrom(vehicles.getReturnType())) - Skript.warning("An entity can only have one passenger"); + if (passengers != null && vehicles != null && !passengers.isSingle() && vehicles.isSingle() && Entity.class.isAssignableFrom(vehicles.getReturnType())) + Skript.error("You cannot force multiple entities to have the same vehicle. Use the 'passengers of' expression."); return true; } - + @Override - protected void execute(final Event e) { - final Expression vehicles = this.vehicles; - final Expression passengers = this.passengers; + protected void execute(Event event) { if (vehicles == null) { assert passengers != null; - for (final Entity p : passengers.getArray(e)) - p.leaveVehicle(); + for (Entity passenger : passengers.getArray(event)) { + if (passenger == null) + continue; + passenger.leaveVehicle(); + } return; } if (passengers == null) { assert vehicles != null; - for (final Object v : vehicles.getArray(e)) - ((Entity) v).eject(); + for (Object vehicle : vehicles.getArray(event)) { + if (vehicle == null) + continue; + ((Entity) vehicle).eject(); + } return; } - final Object[] vs = vehicles.getArray(e); - if (vs.length == 0) + Object[] vehicles = this.vehicles.getArray(event); + if (vehicles.length == 0) return; - final Entity[] ps = passengers.getArray(e); - if (ps.length == 0) + Entity[] passengers = this.passengers.getArray(event); + if (passengers.length == 0) return; - for (final Object v : vs) { - if (v instanceof Entity) { - ((Entity) v).eject(); - for (Entity p : ps){ - assert p != null; - p.leaveVehicle(); - PassengerUtils.addPassenger((Entity)v, p); //For 1.9 and lower, it will only set the last one. + for (Object object : vehicles) { + if (object instanceof Entity) { + Entity vehicle = (Entity) object; + vehicle.eject(); + for (Entity passenger : passengers) { + if (passenger == null) + continue; + passenger.leaveVehicle(); + vehicle.addPassenger(passenger); } } else { - for (final Entity p : ps) { - assert p != null : passengers; - final Entity en = ((EntityData) v).spawn(p.getLocation()); - if (en == null) - return; - PassengerUtils.addPassenger(en, p); + for (Entity passenger : passengers) { + if (passenger == null) + continue; + Entity entity = ((EntityData) object).spawn(passenger.getLocation()); + if (entity == null) + continue; + EffSecSpawn.lastSpawned = entity; + entity.addPassenger(passenger); } } } } - + @Override - public String toString(final @Nullable Event e, final boolean debug) { - final Expression vehicles = this.vehicles; - final Expression passengers = this.passengers; + public String toString(@Nullable Event event, boolean debug) { if (vehicles == null) { assert passengers != null; - return "make " + passengers.toString(e, debug) + " dismount"; + return "make " + passengers.toString(event, debug) + " dismount"; } if (passengers == null) { assert vehicles != null; - return "eject passenger" + (vehicles.isSingle() ? "" : "s") + " of " + vehicles.toString(e, debug); + return "eject passenger" + (vehicles.isSingle() ? "" : "s") + " of " + vehicles.toString(event, debug); } - return "make " + passengers.toString(e, debug) + " ride " + vehicles.toString(e, debug); + return "make " + passengers.toString(event, debug) + " ride " + vehicles.toString(event, debug); } - + } diff --git a/src/main/java/ch/njol/skript/expressions/ExprPassenger.java b/src/main/java/ch/njol/skript/expressions/ExprPassenger.java deleted file mode 100644 index 1ecb1839e8f..00000000000 --- a/src/main/java/ch/njol/skript/expressions/ExprPassenger.java +++ /dev/null @@ -1,190 +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.expressions; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.bukkit.entity.Entity; -import org.bukkit.event.Event; -import org.bukkit.event.vehicle.VehicleEnterEvent; -import org.bukkit.event.vehicle.VehicleExitEvent; -import org.eclipse.jdt.annotation.Nullable; - -import ch.njol.skript.Skript; -import ch.njol.skript.bukkitutil.PassengerUtils; -import ch.njol.skript.classes.Changer.ChangeMode; -import ch.njol.skript.classes.Converter; -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.effects.Delay; -import ch.njol.skript.entity.EntityData; -import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.ExpressionType; -import ch.njol.skript.lang.SkriptParser.ParseResult; -import ch.njol.skript.lang.util.SimpleExpression; -import ch.njol.util.Kleenean; - -/** - * @author Peter Güttinger - */ -@Name("Passenger") -@Description({"The passenger of a vehicle, or the rider of a mob.", - "For 1.11.2 and above, it returns a list of passengers and you can use all changers in it.", - "See also: vehicle"}) -@Examples({"#for 1.11 and lower", - "passenger of the minecart is a creeper or a cow", - "the saddled pig's passenger is a player", - "#for 1.11.2+", - "passengers of the minecart contains a creeper or a cow", - "the boat's passenger contains a pig", - "add a cow and a zombie to passengers of last spawned boat", - "set passengers of player's vehicle to a pig and a horse", - "remove all pigs from player's vehicle", - "clear passengers of boat"}) -@Since("2.0, 2.2-dev26 (Multiple passengers for 1.11.2+)") -public class ExprPassenger extends SimpleExpression { // REMIND create 'vehicle' and 'passenger' expressions for vehicle enter/exit events? - static { // It was necessary to convert to SimpleExpression due to the method 'isSingle()'. - Skript.registerExpression(ExprPassenger.class, Entity.class, ExpressionType.PROPERTY, "[the] passenger[s] of %entities%", "%entities%'[s] passenger[s]"); - } - - @SuppressWarnings("null") - private Expression vehicle; - - @Override - @Nullable - protected Entity[] get(Event e) { - Entity[] source = vehicle.getAll(e); - Converter conv = new Converter(){ - @Override - @Nullable - public Entity[] convert(Entity v) { - if (getTime() >= 0 && e instanceof VehicleEnterEvent && v.equals(((VehicleEnterEvent) e).getVehicle()) && !Delay.isDelayed(e)) { - return new Entity[] {((VehicleEnterEvent) e).getEntered()}; - } - if (getTime() >= 0 && e instanceof VehicleExitEvent && v.equals(((VehicleExitEvent) e).getVehicle()) && !Delay.isDelayed(e)) { - return new Entity[] {((VehicleExitEvent) e).getExited()}; - } - return PassengerUtils.getPassenger(v); - }}; - - List entities = new ArrayList<>(); - for (Entity v : source) { - if (v == null) - continue; - Entity[] array = conv.convert(v); - if (array != null && array.length > 0) - entities.addAll(Arrays.asList(array)); - } - return entities.toArray(new Entity[entities.size()]); - } - - - @SuppressWarnings({"unchecked", "null"}) - @Override - public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { - vehicle = (Expression) exprs[0]; - return true; - } - - @Override - @Nullable - public Class[] acceptChange(final ChangeMode mode) { - if (!isSingle()) - return new Class[] {Entity[].class, EntityData[].class}; // To support more than one entity - if (mode == ChangeMode.SET) - return new Class[] {Entity.class, EntityData.class}; - return super.acceptChange(mode); - } - - @SuppressWarnings("null") - @Override - public void change(final Event e, final @Nullable Object[] delta, final ChangeMode mode) { - Entity[] vehicles = this.vehicle.getArray(e); - if (!isSingle() || mode == ChangeMode.SET) { - for (Entity vehicle: vehicles){ - if (vehicle == null) - continue; - switch(mode){ - case SET: - vehicle.eject(); - //$FALL-THROUGH$ - case ADD: - if (delta == null || delta.length == 0) - return; - for (Object obj : delta){ - if (obj == null) - continue; - Entity passenger = obj instanceof Entity ? (Entity)obj: ((EntityData)obj).spawn(vehicle.getLocation()); - PassengerUtils.addPassenger(vehicle, passenger); - } - break; - case REMOVE_ALL: - case REMOVE: - if (delta == null || delta.length == 0) - return; - for (Object obj : delta){ - if (obj == null) - continue; - if (obj instanceof Entity){ - PassengerUtils.removePassenger(vehicle, (Entity)obj); - } else { - for (Entity passenger : PassengerUtils.getPassenger(vehicle)) - if (passenger != null && ((EntityData)obj).isInstance((passenger))){ - PassengerUtils.removePassenger(vehicle, passenger); - } - } - } - break; - case RESET: - case DELETE: - vehicle.eject(); - } - } - } else { - super.change(e, delta, mode); - } - - } - - @Override - public Class getReturnType() { - return Entity.class; - } - - @Override - public String toString(@Nullable Event e, boolean debug) { - return "the passenger of " + vehicle.toString(e, debug); - } - - @Override - public boolean isSingle() { - // In case it doesn't have multiple passenger support, it's up to the source expression to determine if it's single, otherwise is always false - return !PassengerUtils.hasMultiplePassenger() ? vehicle.isSingle() : false; - } - - @SuppressWarnings("unchecked") - @Override - public boolean setTime(final int time) { - return super.setTime(time, vehicle, VehicleEnterEvent.class, VehicleExitEvent.class); - } -} diff --git a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java new file mode 100644 index 00000000000..b909bc7c301 --- /dev/null +++ b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java @@ -0,0 +1,197 @@ +/** + * 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 java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.bukkit.entity.Entity; +import org.bukkit.event.Event; +import org.bukkit.event.vehicle.VehicleEnterEvent; +import org.bukkit.event.vehicle.VehicleExitEvent; +import org.eclipse.jdt.annotation.Nullable; +import org.spigotmc.event.entity.EntityDismountEvent; +import org.spigotmc.event.entity.EntityMountEvent; + +import ch.njol.skript.Skript; +import ch.njol.skript.classes.Changer.ChangeMode; +import ch.njol.skript.classes.Converter; +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.Expression; +import ch.njol.skript.lang.ExpressionType; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.util.SimpleExpression; +import ch.njol.skript.registrations.EventValues; +import ch.njol.util.Kleenean; +import ch.njol.util.coll.CollectionUtils; + +@Name("Passenger") +@Description({"The passenger of a vehicle, or the rider of a mob.", + "For 1.11.2 and above, it returns a list of passengers and you can use all changers in it.", + "See also: vehicle"}) +@Examples({"#for 1.11 and lower", + "passenger of the minecart is a creeper or a cow", + "the saddled pig's passenger is a player", + "#for 1.11.2+", + "passengers of the minecart contains a creeper or a cow", + "the boat's passenger contains a pig", + "add a cow and a zombie to passengers of last spawned boat", + "set passengers of player's vehicle to a pig and a horse", + "remove all pigs from player's vehicle", + "clear passengers of boat"}) +@Since("2.0, 2.2-dev26 (Multiple passengers for 1.11.2+)") +public class ExprPassengers extends SimpleExpression { // SimpleExpression due to isSingle + + static { + Skript.registerExpression(ExprPassengers.class, Entity.class, ExpressionType.PROPERTY, + "[the] passenger[:s] [of %entities%]", // Passenger can be non plural due to event default expression 'passenger' + "%entities%'[s] passenger[s]" + ); + } + + @Nullable + private Expression vehicles; + private boolean plural; + + @Override + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + vehicles = (Expression) exprs[0]; + plural = parseResult.hasTag("s"); + return true; + } + + @Override + @Nullable + protected Entity[] get(Event event) { + Entity[] source = vehicles.getAll(event); + Converter converter = new Converter() { + @Override + @Nullable + public Entity[] convert(Entity entity) { + if (getTime() != EventValues.TIME_PAST && event instanceof VehicleEnterEvent && entity.equals(((VehicleEnterEvent) event).getVehicle())) + return new Entity[] {((VehicleEnterEvent) event).getEntered()}; + if (getTime() != EventValues.TIME_PAST && event instanceof VehicleExitEvent && entity.equals(((VehicleExitEvent) event).getVehicle())) + return new Entity[] {((VehicleExitEvent) event).getExited()}; + if (getTime() != EventValues.TIME_PAST && event instanceof EntityMountEvent && entity.equals(((EntityMountEvent) event).getEntity())) + return new Entity[] {((EntityMountEvent) event).getEntity()}; + if (getTime() != EventValues.TIME_PAST && event instanceof EntityDismountEvent && entity.equals(((EntityDismountEvent) event).getEntity())) + return new Entity[] {((EntityDismountEvent) event).getEntity()}; + return entity.getPassengers().toArray(Entity[]::new); + }}; + List entities = new ArrayList<>(); + for (Entity entity : source) { + if (entity == null) + continue; + Entity[] array = converter.convert(entity); + if (array != null && array.length > 0) + entities.addAll(Arrays.asList(array)); + } + return entities.toArray(Entity[]::new); + } + + @Override + @Nullable + public Class[] acceptChange(ChangeMode mode) { + return CollectionUtils.array(Entity[].class, EntityData[].class); + } + + @Override + public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { + Entity[] vehicles = this.vehicles.getArray(event); + switch (mode) { + case SET: + for (Entity vehicle: vehicles) { + if (vehicle == null) + continue; + vehicle.eject(); + } + //$FALL-THROUGH$ + case ADD: + if (delta == null || delta.length == 0) + return; + for (Object object : delta) { + if (object == null) + continue; + for (Entity vehicle: vehicles) { + Entity passenger = object instanceof Entity ? (Entity) object : ((EntityData) object).spawn(vehicle.getLocation()); + vehicle.addPassenger(passenger); + } + } + break; + case REMOVE_ALL: + case REMOVE: + if (delta == null || delta.length == 0) + return; + for (Object object : delta) { + if (object == null) + continue; + for (Entity vehicle: vehicles) { + if (object instanceof Entity) { + vehicle.removePassenger((Entity) object); + } else { + for (Entity passenger : vehicle.getPassengers()) { + if (passenger != null && ((EntityData) object).isInstance((passenger))) + vehicle.removePassenger(passenger); + } + } + } + } + break; + case DELETE: + case RESET: + for (Entity vehicle: vehicles) { + if (vehicle == null) + continue; + vehicle.eject(); + } + break; + default: + break; + } + } + + @Override + public boolean setTime(int time) { + if (time == EventValues.TIME_PAST) + return super.setTime(time); + return super.setTime(time, vehicles, VehicleEnterEvent.class, VehicleExitEvent.class); + } + + @Override + public boolean isSingle() { + return !plural && vehicles.isSingle(); + } + + @Override + public Class getReturnType() { + return Entity.class; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "the passengers of " + vehicles.toString(event, debug); + } + +} diff --git a/src/main/java/ch/njol/skript/expressions/ExprVehicle.java b/src/main/java/ch/njol/skript/expressions/ExprVehicle.java index ea0313ff896..f223aa98a4a 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprVehicle.java +++ b/src/main/java/ch/njol/skript/expressions/ExprVehicle.java @@ -33,111 +33,108 @@ import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; -import ch.njol.skript.effects.Delay; import ch.njol.skript.entity.EntityData; -import ch.njol.skript.expressions.base.SimplePropertyExpression; +import ch.njol.skript.expressions.base.PropertyExpression; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.ExpressionType; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.registrations.EventValues; +import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; -/** - * @author Peter Güttinger - */ @Name("Vehicle") -@Description({"The vehicle an entity is in, if any. This can actually be any entity, e.g. spider jockeys are skeletons that ride on a spider, so the spider is the 'vehicle' of the skeleton.", - "See also: passenger"}) +@Description({ + "The vehicle an entity is in, if any. This can actually be any entity, e.g. spider jockeys are skeletons that ride on a spider, so the spider is the 'vehicle' of the skeleton.", + "See also: passenger" +}) @Examples({"vehicle of the player is a minecart"}) @Since("2.0") -public class ExprVehicle extends SimplePropertyExpression { - - static final boolean hasMountEvents = Skript.classExists("org.spigotmc.event.entity.EntityMountEvent"); - +public class ExprVehicle extends PropertyExpression { + static { - register(ExprVehicle.class, Entity.class, "vehicle[s]", "entities"); + Skript.registerExpression(ExprPassengers.class, Entity.class, ExpressionType.PROPERTY, + "[the] vehicle[:s] [of %entities%]", // Vehicles can be plural due to there being multiple entities. + "%entities%'[s] vehicle[s]" + ); + } + + @Override + @SuppressWarnings("unchecked") + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + setExpr((Expression) exprs[0]); + if (parseResult.hasTag("s") && getExpr().isDefault()) + Skript.error("An event cannot contain multiple vehicles. Use 'vehicle' in vehicle events."); + return true; } - + @Override - protected Entity[] get(final Event e, final Entity[] source) { + protected Entity[] get(Event event, Entity[] source) { return get(source, new Converter() { @Override @Nullable - public Entity convert(final Entity p) { - if (getTime() >= 0 && e instanceof VehicleEnterEvent && p.equals(((VehicleEnterEvent) e).getEntered()) && !Delay.isDelayed(e)) { - return ((VehicleEnterEvent) e).getVehicle(); - } - if (getTime() >= 0 && e instanceof VehicleExitEvent && p.equals(((VehicleExitEvent) e).getExited()) && !Delay.isDelayed(e)) { - return ((VehicleExitEvent) e).getVehicle(); - } - if (hasMountEvents) { - if (getTime() >= 0 && e instanceof EntityMountEvent && p.equals(((EntityMountEvent) e).getEntity()) && !Delay.isDelayed(e)) { - return ((EntityMountEvent) e).getMount(); - } - if (getTime() >= 0 && e instanceof EntityDismountEvent && p.equals(((EntityDismountEvent) e).getEntity()) && !Delay.isDelayed(e)) { - return ((EntityDismountEvent) e).getDismounted(); - } - } - return p.getVehicle(); + public Entity convert(Entity entity) { + if (getTime() != EventValues.TIME_PAST && event instanceof VehicleEnterEvent && entity.equals(((VehicleEnterEvent) event).getEntered())) + return ((VehicleEnterEvent) event).getVehicle(); + if (getTime() != EventValues.TIME_PAST && event instanceof VehicleExitEvent && entity.equals(((VehicleExitEvent) event).getExited())) + return ((VehicleExitEvent) event).getVehicle(); + if (getTime() != EventValues.TIME_PAST && event instanceof EntityMountEvent && entity.equals(((EntityMountEvent) event).getEntity())) + return ((EntityMountEvent) event).getMount(); + if (getTime() != EventValues.TIME_PAST && event instanceof EntityDismountEvent && entity.equals(((EntityDismountEvent) event).getEntity())) + return ((EntityDismountEvent) event).getDismounted(); + return entity.getVehicle(); } }); } - - @Override - @Nullable - public Entity convert(final Entity e) { - assert false; - return e.getVehicle(); - } - - @Override - public Class getReturnType() { - return Entity.class; - } - - @Override - protected String getPropertyName() { - return "vehicle"; - } - + @Override @Nullable - public Class[] acceptChange(final ChangeMode mode) { + public Class[] acceptChange(ChangeMode mode) { if (mode == ChangeMode.SET) { - return new Class[] {Entity.class, EntityData.class}; + if (isSingle()) + return CollectionUtils.array(Entity.class, EntityData.class); + Skript.error("You may only set the vehicle of one entity at a time." + + "The same vehicle cannot be applied to multiple entities." + + "Use the 'passengers of' expression if you wish to update multiple riders."); } return super.acceptChange(mode); } - + @Override - public void change(final Event e, final @Nullable Object[] delta, final ChangeMode mode) { + public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { if (mode == ChangeMode.SET) { assert delta != null; - final Entity[] ps = getExpr().getArray(e); - if (ps.length == 0) + Entity passenger = getExpr().getSingle(event); + if (passenger == null) return; - final Object o = delta[0]; - if (o instanceof Entity) { - ((Entity) o).eject(); - final Entity p = CollectionUtils.getRandom(ps); - assert p != null; - p.leaveVehicle(); - ((Entity) o).setPassenger(p); - } else if (o instanceof EntityData) { - for (final Entity p : ps) { - final Entity v = ((EntityData) o).spawn(p.getLocation()); - if (v == null) - continue; - v.setPassenger(p); - } - } else { - assert false; + Object object = delta[0]; + if (object instanceof Entity) { + ((Entity) object).eject(); + passenger.leaveVehicle(); + ((Entity) object).addPassenger(passenger); + } else if (object instanceof EntityData) { + Entity vehicle = ((EntityData) object).spawn(passenger.getLocation()); + if (vehicle == null) + return; + vehicle.addPassenger(vehicle); } - } else { - super.change(e, delta, mode); + return; } + super.change(event, delta, mode); } - - @SuppressWarnings("unchecked") + @Override - public boolean setTime(final int time) { + public boolean setTime(int time) { return super.setTime(time, getExpr(), VehicleEnterEvent.class, VehicleExitEvent.class); } - + + @Override + public Class getReturnType() { + return Entity.class; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "vehicle of " + getExpr().toString(event, debug); + } + } diff --git a/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk b/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk new file mode 100644 index 00000000000..101cf9230d5 --- /dev/null +++ b/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk @@ -0,0 +1,24 @@ +test "has passengers": + spawn a cow at spawn of world "world" + set {_cow} to last spawned cow + spawn a pig at spawn of world "world": + assert event-entity has no passengers with "The pig had passengers after being spawned" + set passengers of event-entity to {_cow} + assert event-entity has a passenger with "The pig did not have any passengers" + assert size of passengers is 1 with "The size of the passengers was incorrect" + eject any passengers from event-entity + make event-entity ride on {_cow} + assert {_cow} has a passenger with "The cow did not have any passengers" + assert vehicle of {_cow} is event-entity with "The cow did not have the pig as a passenger" + clear event-entity + assert event-entity is dead with "The pig is not dead" + eject any passengers from {_cow} # takes a tick for the game to register the pig died to update passengers + assert vehicle of {_cow} is not set with "The cow had passengers 1" + assert {_cow} does not have a passenger with "The cow had passengers 2" + make {_cow} ride a sheep # Spawns a sheep + assert last spawned sheep is set with "A sheep did not get set" + assert passengers of last spawned sheep contains {_cow} with "The sheep did not have the cow as a passenger" + eject any passengers from the last spawned sheep + assert passengers of the last spawned sheep is not set with "The last spawned sheep had passengers" + clear all entities + clear {_cow} From a0d9eb0ca89c9e8827a9611f3fb6f309d0afa41e Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Mon, 2 Jan 2023 13:41:25 -0700 Subject: [PATCH 02/15] Java 8 fixes --- src/main/java/ch/njol/skript/expressions/ExprPassengers.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java index b909bc7c301..4a4fc1f44c5 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java +++ b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java @@ -98,7 +98,7 @@ public Entity[] convert(Entity entity) { return new Entity[] {((EntityMountEvent) event).getEntity()}; if (getTime() != EventValues.TIME_PAST && event instanceof EntityDismountEvent && entity.equals(((EntityDismountEvent) event).getEntity())) return new Entity[] {((EntityDismountEvent) event).getEntity()}; - return entity.getPassengers().toArray(Entity[]::new); + return entity.getPassengers().toArray(new Entity[0]); }}; List entities = new ArrayList<>(); for (Entity entity : source) { @@ -108,7 +108,7 @@ public Entity[] convert(Entity entity) { if (array != null && array.length > 0) entities.addAll(Arrays.asList(array)); } - return entities.toArray(Entity[]::new); + return entities.toArray(new Entity[0]); } @Override From aa48be0760b60f95a369f3ed8bb5016041b4c0a4 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Thu, 19 Jan 2023 16:52:19 -0700 Subject: [PATCH 03/15] Apply requested changes --- .../skript/conditions/CondHasPassengers.java | 6 ++- .../njol/skript/conditions/CondIsEmpty.java | 6 +-- .../ch/njol/skript/effects/EffVehicle.java | 15 +------ .../skript/expressions/ExprPassengers.java | 39 +++++++++---------- .../njol/skript/expressions/ExprVehicle.java | 2 +- 5 files changed, 30 insertions(+), 38 deletions(-) diff --git a/src/main/java/ch/njol/skript/conditions/CondHasPassengers.java b/src/main/java/ch/njol/skript/conditions/CondHasPassengers.java index e8d5ce8d80d..56745e28314 100644 --- a/src/main/java/ch/njol/skript/conditions/CondHasPassengers.java +++ b/src/main/java/ch/njol/skript/conditions/CondHasPassengers.java @@ -20,6 +20,7 @@ import org.bukkit.entity.Entity; +import ch.njol.skript.Skript; import ch.njol.skript.conditions.base.PropertyCondition; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -36,7 +37,10 @@ public class CondHasPassengers extends PropertyCondition { static { - register(CondHasPassengers.class, PropertyType.HAVE, "[a|:no] passenger[s]", "entities"); + Skript.registerCondition(CondHasPassengers.class, + "%entities% (has|have) [a[ny]|:no] passenger[s]", + "%entities% (doesn't|does not|do not|don't) have [a[ny]] passenger[s]" + ); } @Override diff --git a/src/main/java/ch/njol/skript/conditions/CondIsEmpty.java b/src/main/java/ch/njol/skript/conditions/CondIsEmpty.java index 189e65314ae..3ed035f474d 100644 --- a/src/main/java/ch/njol/skript/conditions/CondIsEmpty.java +++ b/src/main/java/ch/njol/skript/conditions/CondIsEmpty.java @@ -18,11 +18,11 @@ */ package ch.njol.skript.conditions; -import org.bukkit.Material; import org.bukkit.entity.Entity; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import ch.njol.skript.bukkitutil.ItemUtils; import ch.njol.skript.conditions.base.PropertyCondition; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; @@ -49,7 +49,7 @@ public boolean check(Object object) { return ((String) object).isEmpty(); if (object instanceof Inventory) { for (ItemStack item : ((Inventory) object).getContents()) { - if (item != null && item.getType() != Material.AIR) + if (item != null && !ItemUtils.isAir(item.getType())) return false; // There is an item here! } return true; @@ -57,7 +57,7 @@ public boolean check(Object object) { if (object instanceof Slot) { Slot slot = (Slot) object; ItemStack item = slot.getItem(); - return item == null || item.getType() == Material.AIR; + return item == null || !ItemUtils.isAir(item.getType()); } if (object instanceof Entity) { Entity entity = (Entity) object; diff --git a/src/main/java/ch/njol/skript/effects/EffVehicle.java b/src/main/java/ch/njol/skript/effects/EffVehicle.java index 8d7d27f0d1a..e0985378b5c 100644 --- a/src/main/java/ch/njol/skript/effects/EffVehicle.java +++ b/src/main/java/ch/njol/skript/effects/EffVehicle.java @@ -28,7 +28,6 @@ import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; import ch.njol.skript.entity.EntityData; -import ch.njol.skript.expressions.ExprLastSpawnedEntity; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; @@ -71,20 +70,14 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye protected void execute(Event event) { if (vehicles == null) { assert passengers != null; - for (Entity passenger : passengers.getArray(event)) { - if (passenger == null) - continue; + for (Entity passenger : passengers.getArray(event)) passenger.leaveVehicle(); - } return; } if (passengers == null) { assert vehicles != null; - for (Object vehicle : vehicles.getArray(event)) { - if (vehicle == null) - continue; + for (Object vehicle : vehicles.getArray(event)) ((Entity) vehicle).eject(); - } return; } Object[] vehicles = this.vehicles.getArray(event); @@ -98,15 +91,11 @@ protected void execute(Event event) { Entity vehicle = (Entity) object; vehicle.eject(); for (Entity passenger : passengers) { - if (passenger == null) - continue; passenger.leaveVehicle(); vehicle.addPassenger(passenger); } } else { for (Entity passenger : passengers) { - if (passenger == null) - continue; Entity entity = ((EntityData) object).spawn(passenger.getLocation()); if (entity == null) continue; diff --git a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java index 4a4fc1f44c5..725b5227f0f 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java +++ b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java @@ -47,19 +47,23 @@ import ch.njol.util.coll.CollectionUtils; @Name("Passenger") -@Description({"The passenger of a vehicle, or the rider of a mob.", - "For 1.11.2 and above, it returns a list of passengers and you can use all changers in it.", - "See also: vehicle"}) -@Examples({"#for 1.11 and lower", - "passenger of the minecart is a creeper or a cow", - "the saddled pig's passenger is a player", - "#for 1.11.2+", - "passengers of the minecart contains a creeper or a cow", - "the boat's passenger contains a pig", - "add a cow and a zombie to passengers of last spawned boat", - "set passengers of player's vehicle to a pig and a horse", - "remove all pigs from player's vehicle", - "clear passengers of boat"}) +@Description({ + "The passenger of a vehicle, or the rider of a mob.", + "For 1.11.2 and above, it returns a list of passengers and you can use all changers in it.", + "See also: vehicle" +}) +@Examples({ + "#for 1.11 and lower", + "passenger of the minecart is a creeper or a cow", + "the saddled pig's passenger is a player", + "#for 1.11.2+", + "passengers of the minecart contains a creeper or a cow", + "the boat's passenger contains a pig", + "add a cow and a zombie to passengers of last spawned boat", + "set passengers of player's vehicle to a pig and a horse", + "remove all pigs from player's vehicle", + "clear passengers of boat" +}) @Since("2.0, 2.2-dev26 (Multiple passengers for 1.11.2+)") public class ExprPassengers extends SimpleExpression { // SimpleExpression due to isSingle @@ -85,7 +89,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override @Nullable protected Entity[] get(Event event) { - Entity[] source = vehicles.getAll(event); + Entity[] source = vehicles.getArray(event); Converter converter = new Converter() { @Override @Nullable @@ -102,8 +106,6 @@ public Entity[] convert(Entity entity) { }}; List entities = new ArrayList<>(); for (Entity entity : source) { - if (entity == null) - continue; Entity[] array = converter.convert(entity); if (array != null && array.length > 0) entities.addAll(Arrays.asList(array)); @@ -122,11 +124,8 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { Entity[] vehicles = this.vehicles.getArray(event); switch (mode) { case SET: - for (Entity vehicle: vehicles) { - if (vehicle == null) - continue; + for (Entity vehicle : vehicles) vehicle.eject(); - } //$FALL-THROUGH$ case ADD: if (delta == null || delta.length == 0) diff --git a/src/main/java/ch/njol/skript/expressions/ExprVehicle.java b/src/main/java/ch/njol/skript/expressions/ExprVehicle.java index f223aa98a4a..d71fe318122 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprVehicle.java +++ b/src/main/java/ch/njol/skript/expressions/ExprVehicle.java @@ -47,7 +47,7 @@ "The vehicle an entity is in, if any. This can actually be any entity, e.g. spider jockeys are skeletons that ride on a spider, so the spider is the 'vehicle' of the skeleton.", "See also: passenger" }) -@Examples({"vehicle of the player is a minecart"}) +@Examples("vehicle of the player is a minecart") @Since("2.0") public class ExprVehicle extends PropertyExpression { From 6d96ab9a80f7f173004ccbda7dc81229676811f9 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Thu, 19 Jan 2023 16:53:41 -0700 Subject: [PATCH 04/15] Apply requested changes --- src/main/java/ch/njol/skript/effects/EffVehicle.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/effects/EffVehicle.java b/src/main/java/ch/njol/skript/effects/EffVehicle.java index e0985378b5c..bb2a4b1c6d3 100644 --- a/src/main/java/ch/njol/skript/effects/EffVehicle.java +++ b/src/main/java/ch/njol/skript/effects/EffVehicle.java @@ -35,7 +35,7 @@ import ch.njol.util.Kleenean; @Name("Vehicle") -@Description({"Makes an entity ride another entity, e.g. a minecart, a saddled pig, an arrow, etc."}) +@Description("Makes an entity ride another entity, e.g. a minecart, a saddled pig, an arrow, etc.") @Examples({ "make the player ride a saddled pig", "make the attacker ride the victim" From 837e12bea3e19ea331a1598e5e34a096b298907a Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 15 Feb 2023 16:58:35 -0700 Subject: [PATCH 05/15] Apply changes --- src/main/java/ch/njol/skript/expressions/ExprPassengers.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java index 04f8901c577..4bad361b8aa 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java +++ b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java @@ -27,12 +27,12 @@ import org.bukkit.event.vehicle.VehicleEnterEvent; import org.bukkit.event.vehicle.VehicleExitEvent; import org.eclipse.jdt.annotation.Nullable; +import org.skriptlang.skript.lang.converter.Converter; import org.spigotmc.event.entity.EntityDismountEvent; import org.spigotmc.event.entity.EntityMountEvent; import ch.njol.skript.Skript; import ch.njol.skript.classes.Changer.ChangeMode; -import ch.njol.skript.classes.Converter; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; From 6648e339c8a20ea30a84779ba946563905496b46 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 15 Feb 2023 17:02:03 -0700 Subject: [PATCH 06/15] use the new default register --- .../java/ch/njol/skript/expressions/ExprPassengers.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java index 4bad361b8aa..66ac41d71cc 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java +++ b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java @@ -31,15 +31,14 @@ import org.spigotmc.event.entity.EntityDismountEvent; import org.spigotmc.event.entity.EntityMountEvent; -import ch.njol.skript.Skript; import ch.njol.skript.classes.Changer.ChangeMode; 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.expressions.base.PropertyExpression; import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.skript.registrations.EventValues; @@ -68,10 +67,7 @@ public class ExprPassengers extends SimpleExpression { // SimpleExpression due to isSingle static { - Skript.registerExpression(ExprPassengers.class, Entity.class, ExpressionType.PROPERTY, - "[the] passenger[:s] [of %entities%]", // Passenger can be non plural due to event default expression 'passenger' - "%entities%'[s] passenger[s]" - ); + PropertyExpression.registerDefault(ExprPassengers.class, Entity.class, "passenger[:s]", "entities"); } @Nullable From af74e7513ddd8ac3631bf8aae2fe2bf0e74ced28 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Sat, 18 Feb 2023 06:39:27 -0700 Subject: [PATCH 07/15] Apply changes --- .../java/ch/njol/skript/conditions/CondHasPassengers.java | 5 +++++ .../java/ch/njol/skript/expressions/ExprPassengers.java | 8 -------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/ch/njol/skript/conditions/CondHasPassengers.java b/src/main/java/ch/njol/skript/conditions/CondHasPassengers.java index 56745e28314..61ef404b555 100644 --- a/src/main/java/ch/njol/skript/conditions/CondHasPassengers.java +++ b/src/main/java/ch/njol/skript/conditions/CondHasPassengers.java @@ -58,6 +58,11 @@ public boolean check(Entity entity) { return !entity.isEmpty(); } + @Override + protected PropertyType getPropertyType() { + return PropertyType.HAVE; + } + @Override protected String getPropertyName() { return "passengers"; diff --git a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java index 66ac41d71cc..9165b077988 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java +++ b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java @@ -124,11 +124,7 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { vehicle.eject(); //$FALL-THROUGH$ case ADD: - if (delta == null || delta.length == 0) - return; for (Object object : delta) { - if (object == null) - continue; for (Entity vehicle : vehicles) { Entity passenger = object instanceof Entity ? (Entity) object : ((EntityData) object).spawn(vehicle.getLocation()); vehicle.addPassenger(passenger); @@ -137,11 +133,7 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { break; case REMOVE_ALL: case REMOVE: - if (delta == null || delta.length == 0) - return; for (Object object : delta) { - if (object == null) - continue; for (Entity vehicle : vehicles) { if (object instanceof Entity) { vehicle.removePassenger((Entity) object); From d10738b51b3dc3752799475ea1b9a3e79c8a917f Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Tue, 21 Feb 2023 20:07:32 -0700 Subject: [PATCH 08/15] Update src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk Co-authored-by: Kiip <25848425+kiip1@users.noreply.github.com> --- src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk b/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk index 101cf9230d5..7c129f707df 100644 --- a/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk +++ b/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk @@ -21,4 +21,3 @@ test "has passengers": eject any passengers from the last spawned sheep assert passengers of the last spawned sheep is not set with "The last spawned sheep had passengers" clear all entities - clear {_cow} From 2e25c11a27bcc9881b9982cc944cabd41002141a Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Fri, 5 May 2023 21:18:12 -0600 Subject: [PATCH 09/15] Update src/main/java/ch/njol/skript/conditions/CondIsEmpty.java Co-authored-by: Ayham Al Ali <20037329+AyhamAl-Ali@users.noreply.github.com> --- src/main/java/ch/njol/skript/conditions/CondIsEmpty.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/ch/njol/skript/conditions/CondIsEmpty.java b/src/main/java/ch/njol/skript/conditions/CondIsEmpty.java index 3ed035f474d..1c5ed6fc511 100644 --- a/src/main/java/ch/njol/skript/conditions/CondIsEmpty.java +++ b/src/main/java/ch/njol/skript/conditions/CondIsEmpty.java @@ -60,8 +60,7 @@ public boolean check(Object object) { return item == null || !ItemUtils.isAir(item.getType()); } if (object instanceof Entity) { - Entity entity = (Entity) object; - return entity.isEmpty(); + return ((Entity) object).isEmpty(); } assert false; return false; From 481a5626d24d859c227f2c4c71ae6aef31d68e67 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 30 Aug 2023 14:38:48 -0600 Subject: [PATCH 10/15] I can finally use the PropertyExpression class with isSingle --- .../skript/expressions/ExprPassengers.java | 30 +++++++++---------- .../njol/skript/expressions/ExprVehicle.java | 8 +++-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java index c1f191e2b12..b94eb65c9c1 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java +++ b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java @@ -40,7 +40,6 @@ import ch.njol.skript.expressions.base.PropertyExpression; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; -import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.skript.registrations.EventValues; import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; @@ -60,28 +59,25 @@ "clear passengers of boat" }) @Since("2.0, 2.2-dev26 (multiple passengers)") -public class ExprPassengers extends SimpleExpression { // SimpleExpression due to isSingle +public class ExprPassengers extends PropertyExpression { static { - PropertyExpression.registerDefault(ExprPassengers.class, Entity.class, "passenger[:s]", "entities"); + registerDefault(ExprPassengers.class, Entity.class, "passenger[:s]", "entities"); } - @Nullable - private Expression vehicles; private boolean plural; @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { - vehicles = (Expression) exprs[0]; + setExpr((Expression) exprs[0]); plural = parseResult.hasTag("s"); return true; } @Override @Nullable - protected Entity[] get(Event event) { - Entity[] source = vehicles.getArray(event); + protected Entity[] get(Event event, Entity[] source) { Converter converter = entity -> { if (getTime() != EventValues.TIME_PAST && event instanceof VehicleEnterEvent && entity.equals(((VehicleEnterEvent) event).getVehicle())) return new Entity[] {((VehicleEnterEvent) event).getEntered()}; @@ -120,7 +116,7 @@ public Class[] acceptChange(ChangeMode mode) { @Override public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { - Entity[] vehicles = this.vehicles.getArray(event); + Entity[] vehicles = getExpr().getArray(event); switch (mode) { case SET: for (Entity vehicle : vehicles) @@ -160,15 +156,17 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { } @Override - public boolean setTime(int time) { - if (time == EventValues.TIME_PAST) - return super.setTime(time); - return super.setTime(time, vehicles, VehicleEnterEvent.class, VehicleExitEvent.class); + public boolean isSingle() { + return !plural && getExpr().isSingle(); } @Override - public boolean isSingle() { - return !plural && vehicles.isSingle(); + public boolean setTime(int time) { + if (time == EventValues.TIME_PAST) + super.setTime(time, getExpr(), EntityDismountEvent.class, VehicleExitEvent.class); + if (time == EventValues.TIME_FUTURE) + return super.setTime(time, getExpr(), EntityMountEvent.class, VehicleEnterEvent.class); + return super.setTime(time, getExpr(), EntityDismountEvent.class, VehicleExitEvent.class, EntityMountEvent.class, VehicleEnterEvent.class); } @Override @@ -178,7 +176,7 @@ public Class getReturnType() { @Override public String toString(@Nullable Event event, boolean debug) { - return "passengers of " + vehicles.toString(event, debug); + return "passengers of " + getExpr().toString(event, debug); } } diff --git a/src/main/java/ch/njol/skript/expressions/ExprVehicle.java b/src/main/java/ch/njol/skript/expressions/ExprVehicle.java index a44c2fa9757..f9d3ef94792 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprVehicle.java +++ b/src/main/java/ch/njol/skript/expressions/ExprVehicle.java @@ -77,8 +77,6 @@ protected Entity[] get(Event event, Entity[] source) { return ((EntityDismountEvent) event).getDismounted(); if (getTime() != EventValues.TIME_FUTURE && event instanceof VehicleExitEvent && entity.equals(((VehicleExitEvent) event).getExited())) return ((VehicleExitEvent) event).getVehicle(); - if (getTime() == EventValues.TIME_PAST) - return entity.getVehicle(); if (getTime() != EventValues.TIME_PAST && event instanceof VehicleEnterEvent && entity.equals(((VehicleEnterEvent) event).getEntered())) return ((VehicleEnterEvent) event).getVehicle(); return entity.getVehicle(); @@ -124,7 +122,11 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { @Override public boolean setTime(int time) { - return super.setTime(time, getExpr(), VehicleEnterEvent.class, VehicleExitEvent.class); + if (time == EventValues.TIME_PAST) + super.setTime(time, getExpr(), EntityDismountEvent.class, VehicleExitEvent.class); + if (time == EventValues.TIME_FUTURE) + return super.setTime(time, getExpr(), EntityMountEvent.class, VehicleEnterEvent.class); + return super.setTime(time, getExpr(), EntityDismountEvent.class, VehicleExitEvent.class, EntityMountEvent.class, VehicleEnterEvent.class); } @Override From f1917cb2513e4dafa132409e29f2008559d8c171 Mon Sep 17 00:00:00 2001 From: TheLimeGlass Date: Wed, 30 Aug 2023 14:48:04 -0600 Subject: [PATCH 11/15] Use streams to flatMap --- .../njol/skript/expressions/ExprPassengers.java | 16 +++++----------- .../ch/njol/skript/expressions/ExprVehicle.java | 14 +++++++++++--- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java index b94eb65c9c1..6b996e013ee 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprPassengers.java +++ b/src/main/java/ch/njol/skript/expressions/ExprPassengers.java @@ -18,9 +18,7 @@ */ package ch.njol.skript.expressions; -import java.util.ArrayList; import java.util.Arrays; -import java.util.List; import org.bukkit.entity.Entity; import org.bukkit.event.Event; @@ -76,7 +74,6 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } @Override - @Nullable protected Entity[] get(Event event, Entity[] source) { Converter converter = entity -> { if (getTime() != EventValues.TIME_PAST && event instanceof VehicleEnterEvent && entity.equals(((VehicleEnterEvent) event).getVehicle())) @@ -89,13 +86,10 @@ protected Entity[] get(Event event, Entity[] source) { return new Entity[] {((EntityDismountEvent) event).getEntity()}; return entity.getPassengers().toArray(new Entity[0]); }; - List entities = new ArrayList<>(); - for (Entity entity : source) { - Entity[] array = converter.convert(entity); - if (array != null && array.length > 0) - entities.addAll(Arrays.asList(array)); - } - return entities.toArray(new Entity[0]); + return Arrays.stream(source) + .map(converter::convert) + .flatMap(Arrays::stream) + .toArray(Entity[]::new); } @Override @@ -176,7 +170,7 @@ public Class getReturnType() { @Override public String toString(@Nullable Event event, boolean debug) { - return "passengers of " + getExpr().toString(event, debug); + return "passenger" + (plural ? "s " : " ") + "of " + getExpr().toString(event, debug); } } diff --git a/src/main/java/ch/njol/skript/expressions/ExprVehicle.java b/src/main/java/ch/njol/skript/expressions/ExprVehicle.java index f9d3ef94792..9db437b4f59 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprVehicle.java +++ b/src/main/java/ch/njol/skript/expressions/ExprVehicle.java @@ -59,11 +59,14 @@ public class ExprVehicle extends PropertyExpression { registerDefault(ExprPassengers.class, Entity.class, "vehicle[:s]", "entities"); } + private boolean plural; + @Override @SuppressWarnings("unchecked") public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { - setExpr((Expression) exprs[0]); - if (parseResult.hasTag("s") && getExpr().isDefault()) + setExpr((Expression) exprs[0]); + plural = parseResult.hasTag("s"); + if (plural && getExpr().isDefault()) Skript.error("An event cannot contain multiple vehicles. Use 'vehicle' with no plurality in vehicle events."); return true; } @@ -120,6 +123,11 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { super.change(event, delta, mode); } + @Override + public boolean isSingle() { + return !plural && getExpr().isSingle(); + } + @Override public boolean setTime(int time) { if (time == EventValues.TIME_PAST) @@ -136,7 +144,7 @@ public Class getReturnType() { @Override public String toString(@Nullable Event event, boolean debug) { - return "vehicle of " + getExpr().toString(event, debug); + return "vehicle" + (plural ? "s " : " ") + "of " + getExpr().toString(event, debug); } } From f8ea0800d5aa0965448fb228e402df69008a137e Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Sun, 31 Dec 2023 18:42:05 -0700 Subject: [PATCH 12/15] Update src/main/java/ch/njol/skript/expressions/ExprVehicle.java --- src/main/java/ch/njol/skript/expressions/ExprVehicle.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprVehicle.java b/src/main/java/ch/njol/skript/expressions/ExprVehicle.java index 9db437b4f59..fed0fdb5a61 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprVehicle.java +++ b/src/main/java/ch/njol/skript/expressions/ExprVehicle.java @@ -56,7 +56,7 @@ public class ExprVehicle extends PropertyExpression { static { - registerDefault(ExprPassengers.class, Entity.class, "vehicle[:s]", "entities"); + registerDefault(ExprVehicle.class, Entity.class, "vehicle[:s]", "entities"); } private boolean plural; From 32e42afd51d395af0245aa1999c8666e8eb24f90 Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Fri, 29 Mar 2024 18:17:04 -0600 Subject: [PATCH 13/15] Update CondHasPassengers.sk --- .../syntaxes/conditions/CondHasPassengers.sk | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk b/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk index 7c129f707df..c130932d898 100644 --- a/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk +++ b/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk @@ -1,17 +1,19 @@ test "has passengers": spawn a cow at spawn of world "world" set {_cow} to last spawned cow - spawn a pig at spawn of world "world": - assert event-entity has no passengers with "The pig had passengers after being spawned" - set passengers of event-entity to {_cow} - assert event-entity has a passenger with "The pig did not have any passengers" - assert size of passengers is 1 with "The size of the passengers was incorrect" - eject any passengers from event-entity - make event-entity ride on {_cow} - assert {_cow} has a passenger with "The cow did not have any passengers" - assert vehicle of {_cow} is event-entity with "The cow did not have the pig as a passenger" - clear event-entity - assert event-entity is dead with "The pig is not dead" + spawn a pig at spawn of world "world" + set {_pig} to the last spawned pig + assert {_pig} has no passengers with "The pig had passengers after being spawned" + set passengers of {_pig} to {_cow} + assert {_pig} has a passenger with "The pig did not have any passengers" + assert size of passengers of {_pig} is 1 with "The size of the passengers was incorrect" + eject any passengers from {_pig} + make {_pig} ride on {_cow} + assert {_cow} has a passenger with "The cow did not have any passengers" + assert vehicle of {_cow} is {_pig} with "The cow did not have the pig as a passenger" + clear entity within {_pig} + assert {_pig} is not valid with "The pig is not dead" + eject any passengers from {_cow} # takes a tick for the game to register the pig died to update passengers assert vehicle of {_cow} is not set with "The cow had passengers 1" assert {_cow} does not have a passenger with "The cow had passengers 2" From 536fe86c0a2e8e9b146147a5bcef17e7119c75d9 Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Fri, 29 Mar 2024 18:17:51 -0600 Subject: [PATCH 14/15] Update CondHasPassengers.sk --- .../skript/tests/syntaxes/conditions/CondHasPassengers.sk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk b/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk index c130932d898..64f50316f7b 100644 --- a/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk +++ b/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk @@ -1,7 +1,7 @@ test "has passengers": - spawn a cow at spawn of world "world" - set {_cow} to last spawned cow - spawn a pig at spawn of world "world" + spawn a cow at spawn of world "world" + set {_cow} to last spawned cow + spawn a pig at spawn of world "world" set {_pig} to the last spawned pig assert {_pig} has no passengers with "The pig had passengers after being spawned" set passengers of {_pig} to {_cow} From f6e1a36054fdaa03bb74db58b527c3dcfe83225b Mon Sep 17 00:00:00 2001 From: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Date: Fri, 29 Mar 2024 18:19:00 -0600 Subject: [PATCH 15/15] Update CondHasPassengers.sk --- .../skript/tests/syntaxes/conditions/CondHasPassengers.sk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk b/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk index 64f50316f7b..9a77b5b690f 100644 --- a/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk +++ b/src/test/skript/tests/syntaxes/conditions/CondHasPassengers.sk @@ -1,8 +1,8 @@ test "has passengers": - spawn a cow at spawn of world "world" - set {_cow} to last spawned cow - spawn a pig at spawn of world "world" - set {_pig} to the last spawned pig + spawn a cow at spawn of world "world" + set {_cow} to last spawned cow + spawn a pig at spawn of world "world" + set {_pig} to the last spawned pig assert {_pig} has no passengers with "The pig had passengers after being spawned" set passengers of {_pig} to {_cow} assert {_pig} has a passenger with "The pig did not have any passengers"