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/effects/EffVehicle.java b/src/main/java/ch/njol/skript/effects/EffVehicle.java index 2bf3da326e7..022651fae56 100644 --- a/src/main/java/ch/njol/skript/effects/EffVehicle.java +++ b/src/main/java/ch/njol/skript/effects/EffVehicle.java @@ -23,7 +23,6 @@ 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; @@ -45,11 +44,11 @@ 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] (dismount|(dismount|leave) (from|of|) (any|the[ir]|his|her|) vehicle[s])", - "(eject|dismount) (any|the|) passenger[s] (of|from) %entities%"); + "(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 @@ -57,60 +56,58 @@ public class EffVehicle extends Effect { @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) { 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"); return true; } @Override - protected void execute(final Event e) { - final Expression vehicles = this.vehicles; - final Expression passengers = this.passengers; + protected void execute(Event e) { + Expression vehicles = this.vehicles; + Expression passengers = this.passengers; if (vehicles == null) { assert passengers != null; - for (final Entity p : passengers.getArray(e)) - p.leaveVehicle(); + for (Entity passenger : passengers.getArray(e)) + passenger.leaveVehicle(); return; } if (passengers == null) { assert vehicles != null; - for (final Object v : vehicles.getArray(e)) - ((Entity) v).eject(); + for (Object vehicle : vehicles.getArray(e)) + ((Entity) vehicle).eject(); return; } - final Object[] vs = vehicles.getArray(e); - if (vs.length == 0) + Object[] vehiclesArray = vehicles.getArray(e); + if (vehiclesArray.length == 0) return; - final Entity[] ps = passengers.getArray(e); - if (ps.length == 0) + Entity[] passengersArray = passengers.getArray(e); + if (passengersArray.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 vehicle : vehiclesArray) { + if (vehicle instanceof Entity) { + ((Entity) vehicle).eject(); + for (Entity passenger : passengersArray){ + assert passenger != null; + passenger.leaveVehicle(); + ((Entity) vehicle).addPassenger(passenger); } } else { - for (final Entity p : ps) { - assert p != null : passengers; - final Entity en = ((EntityData) v).spawn(p.getLocation()); - if (en == null) + for (Entity passenger : passengersArray) { + assert passenger != null : passengers; + Entity entity = ((EntityData) vehicle).spawn(passenger.getLocation()); + if (entity == null) return; - PassengerUtils.addPassenger(en, p); + 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 e, boolean debug) { + Expression vehicles = this.vehicles; + Expression passengers = this.passengers; if (vehicles == null) { assert passengers != null; return "make " + passengers.toString(e, debug) + " dismount"; @@ -121,5 +118,4 @@ public String toString(final @Nullable Event e, final boolean debug) { } return "make " + passengers.toString(e, debug) + " ride " + vehicles.toString(e, debug); } - } diff --git a/src/main/java/ch/njol/skript/expressions/ExprPassenger.java b/src/main/java/ch/njol/skript/expressions/ExprPassenger.java index fcb174224af..e520038be4b 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprPassenger.java +++ b/src/main/java/ch/njol/skript/expressions/ExprPassenger.java @@ -22,14 +22,15 @@ import java.util.Arrays; import java.util.List; +import ch.njol.skript.expressions.base.PropertyExpression; +import ch.njol.util.coll.CollectionUtils; +import org.bukkit.Bukkit; 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 org.skriptlang.skript.lang.converter.Converter; import ch.njol.skript.doc.Description; @@ -39,152 +40,132 @@ 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.", +@Name("Passengers") +@Description({"The passengers of a vehicle, or the riders of a mob.", + "This 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+", +@Examples({ "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]"); +@Since("2.0, 2.2-dev26 (Multiple passengers)") +public class ExprPassenger extends PropertyExpression { // TODO create 'vehicle' and 'passenger' expressions for vehicle enter/exit events? + + static { + register(ExprPassenger.class, Entity.class, "passenger[s]", "entities"); + } + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + setExpr((Expression) exprs[0]); + return true; } - - @SuppressWarnings("null") - private Expression vehicle; @Override @Nullable - protected Entity[] get(Event e) { - Entity[] source = vehicle.getAll(e); - Converter conv = new Converter(){ + protected Entity[] get(Event event, Entity[] source) { + Converter converter = 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) + public Entity[] convert(Entity vehicle) { + if (getTime() >= 0 && event instanceof VehicleEnterEvent && vehicle.equals(((VehicleEnterEvent) event).getVehicle()) && !Delay.isDelayed(event)) + return new Entity[]{((VehicleEnterEvent) event).getEntered()}; + if (getTime() >= 0 && event instanceof VehicleExitEvent && vehicle.equals(((VehicleExitEvent) event).getVehicle()) && !Delay.isDelayed(event)) + return new Entity[]{((VehicleExitEvent) event).getExited()}; + return vehicle.getPassengers().toArray(new Entity[0]); + } + }; + + List totalPassengers = new ArrayList<>(); + for (Entity vehicle : source) { + if (vehicle == null) continue; - Entity[] array = conv.convert(v); - if (array != null && array.length > 0) - entities.addAll(Arrays.asList(array)); + Entity[] passengers = converter.convert(vehicle); + if (passengers != null && passengers.length > 0) + totalPassengers.addAll(Arrays.asList(passengers)); } - 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; + return totalPassengers.toArray(new Entity[0]); } @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); + public Class[] acceptChange(ChangeMode mode) { + return CollectionUtils.array(Entity[].class, EntityData[].class); } @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); - } + public void change(Event event, @Nullable Object[] delta, ChangeMode mode) { + for (Entity vehicle : getExpr().getArray(event)) { + if (vehicle == null) + continue; + + switch (mode) { + case SET: + vehicle.eject(); + // falls through + case ADD: + if (delta == null || delta.length == 0) + return; + for (Object object : delta) { + if (object == null) + continue; + 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; + 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 RESET: - case DELETE: - vehicle.eject(); - } + } + break; + case RESET: + case DELETE: + vehicle.eject(); } - } else { - super.change(e, delta, mode); } - } - + @Override - public Class getReturnType() { - return Entity.class; + public boolean setTime(int time) { + return super.setTime(time, getExpr(), VehicleEnterEvent.class, VehicleExitEvent.class); } - + @Override - public String toString(@Nullable Event e, boolean debug) { - return "the passenger of " + vehicle.toString(e, debug); + public boolean isSingle() { + return false; } @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; + public Class getReturnType() { + return Entity.class; } - - @SuppressWarnings("unchecked") + @Override - public boolean setTime(final int time) { - return super.setTime(time, vehicle, VehicleEnterEvent.class, VehicleExitEvent.class); - } + public String toString(@Nullable Event event, boolean debug) { + return "the passengers of " + getExpr().toString(event, debug); + } + }