diff --git a/gradle.properties b/gradle.properties index e31c5a65002..3271da70815 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ org.gradle.parallel=true groupid=ch.njol name=skript -version=2.8.3 +version=2.8.4 jarName=Skript.jar testEnv=java17/paper-1.20.4 testEnvJavaVersion=17 diff --git a/src/main/java/ch/njol/skript/aliases/ItemData.java b/src/main/java/ch/njol/skript/aliases/ItemData.java index b6f90b30f42..32323c57e6f 100644 --- a/src/main/java/ch/njol/skript/aliases/ItemData.java +++ b/src/main/java/ch/njol/skript/aliases/ItemData.java @@ -31,6 +31,7 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockState; +import org.bukkit.block.data.BlockData; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemFactory; import org.bukkit.inventory.ItemFlag; @@ -188,15 +189,23 @@ public ItemData(ItemStack stack) { this(stack, BlockCompat.INSTANCE.getBlockValues(stack)); this.itemForm = true; } - - public ItemData(BlockState block) { - this.type = ItemUtils.asItem(block.getType()); + + /** + * @deprecated Use {@link ItemData#ItemData(BlockData)} instead + */ + @Deprecated + public ItemData(BlockState blockState) { + this(blockState.getBlockData()); + } + + public ItemData(BlockData blockData) { + this.type = blockData.getMaterial(); this.stack = new ItemStack(type); - this.blockValues = BlockCompat.INSTANCE.getBlockValues(block); + this.blockValues = BlockCompat.INSTANCE.getBlockValues(blockData); } public ItemData(Block block) { - this(block.getState()); + this(block.getBlockData()); } /** diff --git a/src/main/java/ch/njol/skript/aliases/ItemType.java b/src/main/java/ch/njol/skript/aliases/ItemType.java index 6b56e9cee17..7341667fa91 100644 --- a/src/main/java/ch/njol/skript/aliases/ItemType.java +++ b/src/main/java/ch/njol/skript/aliases/ItemType.java @@ -43,6 +43,7 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.Skull; +import org.bukkit.block.data.BlockData; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; @@ -184,10 +185,16 @@ public ItemType(ItemStack i) { add_(new ItemData(i)); } - public ItemType(BlockState b) { -// amount = 1; - add_(new ItemData(b)); - // TODO metadata - spawners, skulls, etc. + /** + * @deprecated Use {@link #ItemType(BlockData)} instead + */ + @Deprecated + public ItemType(BlockState blockState) { + this(blockState.getBlockData()); + } + + public ItemType(BlockData blockData) { + add_(new ItemData(blockData)); } /** @@ -211,7 +218,7 @@ public void setTo(ItemType i) { } public ItemType(Block block) { - this(block.getState()); + this(block.getBlockData()); } /** @@ -272,17 +279,25 @@ public boolean isOfType(@Nullable ItemStack item) { return isOfType(new ItemData(item)); } - public boolean isOfType(@Nullable BlockState block) { - if (block == null) + /** + * @deprecated Use {@link #isOfType(BlockData)} instead + */ + @Deprecated + public boolean isOfType(@Nullable BlockState blockState) { + return blockState != null && isOfType(blockState.getBlockData()); + } + + public boolean isOfType(@Nullable BlockData blockData) { + if (blockData == null) return isOfType(Material.AIR, null); - return isOfType(new ItemData(block)); + return isOfType(new ItemData(blockData)); } public boolean isOfType(@Nullable Block block) { if (block == null) return isOfType(Material.AIR, null); - return isOfType(block.getState()); + return isOfType(block.getBlockData()); } public boolean isOfType(ItemData type) { diff --git a/src/main/java/ch/njol/skript/bukkitutil/ItemUtils.java b/src/main/java/ch/njol/skript/bukkitutil/ItemUtils.java index ca373598eff..c6d5f25870e 100644 --- a/src/main/java/ch/njol/skript/bukkitutil/ItemUtils.java +++ b/src/main/java/ch/njol/skript/bukkitutil/ItemUtils.java @@ -74,13 +74,15 @@ public static Material asBlock(Material type) { return null; } } - + /** * Gets an item material corresponding to given block material, which might * be the given material. * @param type Material. * @return Item version of material or null. + * @deprecated This just returns itself and has no use */ + @Deprecated public static Material asItem(Material type) { // Assume (naively) that all types are valid items return type; diff --git a/src/main/java/ch/njol/skript/bukkitutil/block/BlockCompat.java b/src/main/java/ch/njol/skript/bukkitutil/block/BlockCompat.java index 5ffb1063284..eef0866a01b 100644 --- a/src/main/java/ch/njol/skript/bukkitutil/block/BlockCompat.java +++ b/src/main/java/ch/njol/skript/bukkitutil/block/BlockCompat.java @@ -23,11 +23,11 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockState; +import org.bukkit.block.data.BlockData; import org.bukkit.entity.FallingBlock; import org.bukkit.inventory.ItemStack; import org.eclipse.jdt.annotation.Nullable; -import ch.njol.skript.Skript; import ch.njol.skript.aliases.ItemFlags; /** @@ -42,13 +42,15 @@ public interface BlockCompat { BlockCompat INSTANCE = new NewBlockCompat(); static final BlockSetter SETTER = INSTANCE.getSetter(); - + /** * Gets block values from a block state. They can be compared to other * values if needed, but cannot be used to retrieve any other data. * @param block Block state to retrieve value from. * @return Block values. + * @deprecated Use {@link #getBlockValues(BlockData)} instead */ + @Deprecated @Nullable BlockValues getBlockValues(BlockState block); @@ -60,8 +62,11 @@ public interface BlockCompat { */ @Nullable default BlockValues getBlockValues(Block block) { - return getBlockValues(block.getState()); + return getBlockValues(block.getBlockData()); } + + @Nullable + BlockValues getBlockValues(BlockData blockData); /** * Gets block values from a item stack. They can be compared to other values @@ -71,17 +76,19 @@ default BlockValues getBlockValues(Block block) { */ @Nullable BlockValues getBlockValues(ItemStack stack); - + /** * Creates a block state from a falling block. * @param entity Falling block entity * @return Block state. + * @deprecated This shouldn't be used */ + @Deprecated BlockState fallingBlockToState(FallingBlock entity); - + @Nullable default BlockValues getBlockValues(FallingBlock entity) { - return getBlockValues(fallingBlockToState(entity)); + return getBlockValues(entity.getBlockData()); } /** diff --git a/src/main/java/ch/njol/skript/bukkitutil/block/NewBlockCompat.java b/src/main/java/ch/njol/skript/bukkitutil/block/NewBlockCompat.java index 0610022d1c9..2a0ecd36da8 100644 --- a/src/main/java/ch/njol/skript/bukkitutil/block/NewBlockCompat.java +++ b/src/main/java/ch/njol/skript/bukkitutil/block/NewBlockCompat.java @@ -325,16 +325,23 @@ public void sendBlockChange(Player player, Location location, Material type, @Nu } private NewBlockSetter setter = new NewBlockSetter(); - + + /** + * @deprecated Use {@link #getBlockValues(BlockData)} instead + */ + @Deprecated @Nullable @Override - public BlockValues getBlockValues(BlockState block) { - // If block doesn't have useful data, data field of type is MaterialData - if (block.getType().isBlock()) - return new NewBlockValues(block.getType(), block.getBlockData(), false); - return null; + public BlockValues getBlockValues(BlockState blockState) { + return getBlockValues(blockState.getBlockData()); } - + + @Nullable + @Override + public BlockValues getBlockValues(BlockData blockData) { + return new NewBlockValues(blockData.getMaterial(), blockData, false); + } + @Override @Nullable public BlockValues getBlockValues(ItemStack stack) { @@ -345,15 +352,16 @@ public BlockValues getBlockValues(ItemStack stack) { } return null; } - + @Override public BlockSetter getSetter() { return setter; } + @Deprecated @Override public BlockState fallingBlockToState(FallingBlock entity) { - BlockState state = entity.getWorld().getBlockAt(0, 0, 0).getState(); + BlockState state = entity.getLocation().getBlock().getState(); state.setBlockData(entity.getBlockData()); return state; } diff --git a/src/main/java/ch/njol/skript/classes/data/DefaultFunctions.java b/src/main/java/ch/njol/skript/classes/data/DefaultFunctions.java index 556f396b80b..e2c5392dd39 100644 --- a/src/main/java/ch/njol/skript/classes/data/DefaultFunctions.java +++ b/src/main/java/ch/njol/skript/classes/data/DefaultFunctions.java @@ -376,10 +376,28 @@ public Location[] execute(FunctionEvent e, Object[][] params) { } }.description("Creates a location from a world and 3 coordinates, with an optional yaw and pitch.", "If for whatever reason the world is not found, it will fallback to the server's main world.") - .examples("location(0, 128, 0)", - "location(player's x-coordinate, player's y-coordinate + 5, player's z-coordinate, player's world, 0, 90)", - "location(0, 64, 0, world \"world_nether\")", - "location(100, 110, -145, world(\"my_custom_world\"))") + .examples("# TELEPORTING", + "teleport player to location(1,1,1, world \"world\")", + "teleport player to location(1,1,1, world \"world\", 100, 0)", + "teleport player to location(1,1,1, world \"world\", yaw of player, pitch of player)", + "teleport player to location(1,1,1, world of player)", + "teleport player to location(1,1,1, world(\"world\"))", + "teleport player to location({_x}, {_y}, {_z}, {_w}, {_yaw}, {_pitch})", + "# SETTING BLOCKS", + "set block at location(1,1,1, world \"world\") to stone", + "set block at location(1,1,1, world \"world\", 100, 0) to stone", + "set block at location(1,1,1, world of player) to stone", + "set block at location(1,1,1, world(\"world\")) to stone", + "set block at location({_x}, {_y}, {_z}, {_w}) to stone", + "# USING VARIABLES", + "set {_l1} to location(1,1,1)", + "set {_l2} to location(10,10,10)", + "set blocks within {_l1} and {_l2} to stone", + "if player is within {_l1} and {_l2}:", + "# OTHER", + "kill all entities in radius 50 around location(1,65,1, world \"world\")", + "delete all entities in radius 25 around location(50,50,50, world \"world_nether\")", + "ignite all entities in radius 25 around location(1,1,1, world of player)") .since("2.2")); Functions.registerFunction(new SimpleJavaFunction("date", new Parameter[] { diff --git a/src/main/java/ch/njol/skript/entity/EntityData.java b/src/main/java/ch/njol/skript/entity/EntityData.java index 2b4fbd1947e..9cf1f427fd7 100644 --- a/src/main/java/ch/njol/skript/entity/EntityData.java +++ b/src/main/java/ch/njol/skript/entity/EntityData.java @@ -670,15 +670,18 @@ public void deserialize(final Fields fields) throws StreamCorruptedException, No protected boolean deserialize(final String s) { return false; } - + @SuppressWarnings({"unchecked", "deprecation"}) protected static @Nullable E spawn(Location location, Class type, Consumer consumer) { + World world = location.getWorld(); + if (world == null) + return null; try { if (WORLD_1_17_CONSUMER) { - return (@Nullable E) WORLD_1_17_CONSUMER_METHOD.invoke(location.getWorld(), location, type, + return (@Nullable E) WORLD_1_17_CONSUMER_METHOD.invoke(world, location, type, (org.bukkit.util.Consumer) consumer::accept); } else if (WORLD_1_13_CONSUMER) { - return (@Nullable E) WORLD_1_13_CONSUMER_METHOD.invoke(location.getWorld(), location, type, + return (@Nullable E) WORLD_1_13_CONSUMER_METHOD.invoke(world, location, type, (org.bukkit.util.Consumer) consumer::accept); } } catch (InvocationTargetException | IllegalAccessException e) { @@ -686,7 +689,7 @@ protected boolean deserialize(final String s) { Skript.exception(e, "Can't spawn " + type.getName()); return null; } - return location.getWorld().spawn(location, type, consumer); + return world.spawn(location, type, consumer); } - + } diff --git a/src/main/java/ch/njol/skript/entity/FallingBlockData.java b/src/main/java/ch/njol/skript/entity/FallingBlockData.java index 2f937148fe9..262b2b564d8 100644 --- a/src/main/java/ch/njol/skript/entity/FallingBlockData.java +++ b/src/main/java/ch/njol/skript/entity/FallingBlockData.java @@ -93,7 +93,7 @@ public ItemType convert(ItemType t) { @Override protected boolean init(final @Nullable Class c, final @Nullable FallingBlock e) { if (e != null) // TODO material data support - types = new ItemType[] {new ItemType(BlockCompat.INSTANCE.fallingBlockToState(e))}; + types = new ItemType[] {new ItemType(e.getBlockData())}; return true; } @@ -101,7 +101,7 @@ protected boolean init(final @Nullable Class c, final @N protected boolean match(final FallingBlock entity) { if (types != null) { for (final ItemType t : types) { - if (t.isOfType(BlockCompat.INSTANCE.fallingBlockToState(entity))) + if (t.isOfType(entity.getBlockData())) return true; } return false; diff --git a/src/main/java/ch/njol/skript/events/EvtBlock.java b/src/main/java/ch/njol/skript/events/EvtBlock.java index 4a393146600..78d5fc1dc59 100644 --- a/src/main/java/ch/njol/skript/events/EvtBlock.java +++ b/src/main/java/ch/njol/skript/events/EvtBlock.java @@ -104,7 +104,7 @@ public boolean check(final Event event) { if (event instanceof BlockFormEvent) { BlockFormEvent blockFormEvent = (BlockFormEvent) event; BlockState newState = blockFormEvent.getNewState(); - item = new ItemType(newState); + item = new ItemType(newState.getBlockData()); blockData = newState.getBlockData(); } else if (event instanceof BlockEvent) { BlockEvent blockEvent = (BlockEvent) event; diff --git a/src/main/java/ch/njol/skript/events/EvtGrow.java b/src/main/java/ch/njol/skript/events/EvtGrow.java index 98f5f281728..ff2deb11a8d 100644 --- a/src/main/java/ch/njol/skript/events/EvtGrow.java +++ b/src/main/java/ch/njol/skript/events/EvtGrow.java @@ -174,7 +174,7 @@ private static boolean checkFrom(Event event, Literal types) { BlockState oldState = ((BlockGrowEvent) event).getBlock().getState(); return types.check(event, type -> { if (type instanceof ItemType) { - return ((ItemType) type).isOfType(oldState); + return ((ItemType) type).isOfType(oldState.getBlockData()); } else if (type instanceof BlockData) { return ((BlockData) type).matches(oldState.getBlockData()); } @@ -201,7 +201,7 @@ private static boolean checkTo(Event event, Literal types) { BlockState newState = ((BlockGrowEvent) event).getNewState(); return types.check(event, type -> { if (type instanceof ItemType) { - return ((ItemType) type).isOfType(newState); + return ((ItemType) type).isOfType(newState.getBlockData()); } else if (type instanceof BlockData) { return ((BlockData) type).matches(newState.getBlockData()); } diff --git a/src/main/java/ch/njol/skript/expressions/ExprAnvilText.java b/src/main/java/ch/njol/skript/expressions/ExprAnvilText.java index acc05ae124c..15490749007 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprAnvilText.java +++ b/src/main/java/ch/njol/skript/expressions/ExprAnvilText.java @@ -35,7 +35,7 @@ @Examples({ "on inventory click:", "\ttype of event-inventory is anvil inventory", - "\tif the anvil input text of the event-inventory is \"FREE OP\":", + "\tif the anvil text input of the event-inventory is \"FREE OP\":", "\t\tban player" }) @Since("2.7") diff --git a/src/main/java/ch/njol/skript/expressions/ExprElement.java b/src/main/java/ch/njol/skript/expressions/ExprElement.java index 15b6d96afb5..e3d414fe2d3 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprElement.java +++ b/src/main/java/ch/njol/skript/expressions/ExprElement.java @@ -46,7 +46,13 @@ "The first, last, range or a random element of a set, e.g. a list variable.", "See also: random expression" }) -@Examples("broadcast the first 3 elements of {top players::*}") +@Examples({ + "broadcast the first 3 elements of {top players::*}", + "set {_last} to last element of {top players::*}", + "set {_random player} to random element out of all players", + "send 2nd last element of {top players::*} to player", + "set {page2::*} to elements from 11 to 20 of {top players::*}" +}) @Since("2.0, 2.7 (relative to last element), 2.8.0 (range of elements)") public class ExprElement extends SimpleExpression { diff --git a/src/main/java/ch/njol/skript/expressions/ExprIndices.java b/src/main/java/ch/njol/skript/expressions/ExprIndices.java index 1f4439273b6..c09bfe81964 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprIndices.java +++ b/src/main/java/ch/njol/skript/expressions/ExprIndices.java @@ -28,7 +28,6 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.Variable; import ch.njol.skript.lang.util.SimpleExpression; -import org.skriptlang.skript.lang.comparator.Comparators; import ch.njol.skript.util.LiteralUtils; import ch.njol.util.Kleenean; import org.bukkit.event.Event; @@ -102,7 +101,7 @@ protected String[] get(Event e) { if (sort) { int direction = descending ? -1 : 1; return variable.entrySet().stream() - .sorted((a, b) -> compare(a, b, direction)) + .sorted((a, b) -> ExprSortedList.compare(a.getValue(), b.getValue()) * direction) .map(Entry::getKey) .toArray(String[]::new); } @@ -130,8 +129,4 @@ public String toString(@Nullable Event e, boolean debug) { return text; } - // Extracted method for better readability - private int compare(Entry a, Entry b, int direction) { - return Comparators.compare(a.getValue(), b.getValue()).getRelation() * direction; - } } diff --git a/src/main/java/ch/njol/skript/expressions/ExprRandom.java b/src/main/java/ch/njol/skript/expressions/ExprRandom.java index c3a87f7e957..5ab7e45996a 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprRandom.java +++ b/src/main/java/ch/njol/skript/expressions/ExprRandom.java @@ -78,9 +78,7 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye } else { expr = exprs[1].getConvertedExpression((((Literal>) exprs[0]).getSingle()).getC()); } - if (expr == null) - return false; - return true; + return expr != null && LiteralUtils.canInitSafely(expr); } @Override diff --git a/src/main/java/ch/njol/skript/expressions/ExprRandomCharacter.java b/src/main/java/ch/njol/skript/expressions/ExprRandomCharacter.java index 32afa678c42..13660c7ccd8 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprRandomCharacter.java +++ b/src/main/java/ch/njol/skript/expressions/ExprRandomCharacter.java @@ -50,17 +50,17 @@ public class ExprRandomCharacter extends SimpleExpression { static { Skript.registerExpression(ExprRandomCharacter.class, String.class, ExpressionType.COMBINED, - "[a|%-number%] random [:alphanumeric] character[s] (from|between) %string% (to|and) %string%"); + "[a|%-integer%] random [:alphanumeric] character[s] (from|between) %string% (to|and) %string%"); } @Nullable - private Expression amount; + private Expression amount; private Expression from, to; private boolean isAlphanumeric; @Override public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { - amount = (Expression) exprs[0]; + amount = (Expression) exprs[0]; from = (Expression) exprs[1]; to = (Expression) exprs[2]; isAlphanumeric = parseResult.hasTag("alphanumeric"); @@ -70,7 +70,10 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye @Override @Nullable protected String[] get(Event event) { - int amount = this.amount == null ? 1 : this.amount.getOptionalSingle(event).orElse(1).intValue(); + Integer amount = this.amount == null ? Integer.valueOf(1) : this.amount.getSingle(event); + if (amount == null || amount <= 0) + return new String[0]; + String from = this.from.getSingle(event); String to = this.to.getSingle(event); if (from == null || to == null) @@ -117,7 +120,7 @@ protected String[] get(Event event) { @Override public boolean isSingle() { if (amount instanceof Literal) - return ((Literal) amount).getSingle().intValue() == 1; + return ((Literal) amount).getSingle() == 1; return amount == null; } diff --git a/src/main/java/ch/njol/skript/expressions/ExprSortedList.java b/src/main/java/ch/njol/skript/expressions/ExprSortedList.java index 3cfed13b0a6..0a4af988476 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprSortedList.java +++ b/src/main/java/ch/njol/skript/expressions/ExprSortedList.java @@ -34,6 +34,7 @@ import org.eclipse.jdt.annotation.Nullable; import org.skriptlang.skript.lang.comparator.Comparator; import org.skriptlang.skript.lang.comparator.Comparators; +import org.skriptlang.skript.lang.comparator.Relation; import java.lang.reflect.Array; @@ -77,12 +78,14 @@ protected Object[] get(Event event) { } @SuppressWarnings("unchecked") - private static int compare(A a, B b) throws IllegalArgumentException, ClassCastException { + public static int compare(A a, B b) throws IllegalArgumentException, ClassCastException { + if (a instanceof String && b instanceof String) + return Relation.get(((String) a).compareToIgnoreCase((String) b)).getRelation(); Comparator comparator = Comparators.getComparator((Class) a.getClass(), (Class) b.getClass()); if (comparator != null && comparator.supportsOrdering()) return comparator.compare(a, b).getRelation(); if (!(a instanceof Comparable)) - throw new IllegalArgumentException(); + throw new IllegalArgumentException("Cannot compare " + a.getClass()); return ((Comparable) a).compareTo(b); } diff --git a/src/main/java/ch/njol/skript/lang/SkriptParser.java b/src/main/java/ch/njol/skript/lang/SkriptParser.java index 3d6a16b4eba..930c8e0639a 100644 --- a/src/main/java/ch/njol/skript/lang/SkriptParser.java +++ b/src/main/java/ch/njol/skript/lang/SkriptParser.java @@ -531,6 +531,9 @@ private Expression parseSingleExpr(boolean allowUnparsedLiteral, @Nullable Lo Expression parsedExpression = parseExpression(types, expr); if (parsedExpression != null) { // Expression/VariableString parsing success Class returnType = parsedExpression.getReturnType(); // Sometimes getReturnType does non-trivial costly operations + if (returnType == null) + throw new SkriptAPIException("Expression '" + expr + "' returned null for method Expression#getReturnType. Null is not a valid return."); + for (int i = 0; i < types.length; i++) { Class type = types[i]; if (type == null) // Ignore invalid (null) types diff --git a/src/main/resources/lang/default.lang b/src/main/resources/lang/default.lang index ef3af71ee90..3a41f411249 100644 --- a/src/main/resources/lang/default.lang +++ b/src/main/resources/lang/default.lang @@ -1934,12 +1934,21 @@ attribute types: generic_attack_speed: generic attack speed, attack speed generic_flying_speed: generic flying speed, flying speed generic_follow_range: generic follow range, follow range + generic_gravity: generic gravity, gravity + generic_jump_strength: generic jump strength, jump strength generic_knockback_resistance: generic knockback resistance, knockback resistance generic_luck: generic luck, luck generic_max_absorption: generic max absorption, max absorption generic_max_health: generic max health, max health generic_movement_speed: generic movement speed, movement speed + generic_safe_fall_distance: generic safe fall distance, safe fall distance + generic_fall_damage_multiplier: generic fall damage multiplier, fall damage multiplier + generic_scale: generic scale, scale + generic_step_height: generic step height, step height horse_jump_strength: horse jump strength + player_block_break_speed: player block break speed, block break speed + player_block_interaction_range: player block interaction range, block interaction range + player_entity_interaction_range: player entity interaction range, entity interaction range zombie_spawn_reinforcements: zombie spawn reinforcements # -- Environments -- diff --git a/src/test/skript/tests/syntaxes/expressions/ExprCharacters.sk b/src/test/skript/tests/syntaxes/expressions/ExprCharacters.sk index 5c57a474378..0805fb13d85 100644 --- a/src/test/skript/tests/syntaxes/expressions/ExprCharacters.sk +++ b/src/test/skript/tests/syntaxes/expressions/ExprCharacters.sk @@ -1,5 +1,13 @@ test "characters between": set {_a} to 1 random character between "a" and "z" + assert {_a} is set with "failed to generate random character" + + set {_a::*} to -10 random character between "a" and "z" + assert {_a::*} is not set with "-10 random characters returned non-null value: %{_a::*}%" + + set {_a::*} to {_null} random character between "a" and "z" + assert {_a::*} is not set with "null random characters returned non-null value: %{_a::*}%" + assert join characters between "a" and "d" is "abcd" with "Invalid characters between a and d" assert join characters between "d" and "a" is "dcba" with "Invalid characters between d and a" assert join characters between "Z" and "a" is "Z[\]^_`a" with "Invalid characters between Z and a" diff --git a/src/test/skript/tests/syntaxes/expressions/ExprIndices.sk b/src/test/skript/tests/syntaxes/expressions/ExprIndices.sk index fccca1d6a6d..855e4129b78 100644 --- a/src/test/skript/tests/syntaxes/expressions/ExprIndices.sk +++ b/src/test/skript/tests/syntaxes/expressions/ExprIndices.sk @@ -23,3 +23,17 @@ test "sorted indices": set {_a} to {_leader-board::%loop-value%} set {_b} to {_descending-values::%loop-index%} assert {_a} is equal to {_b} with "Sorting indices in descending order is incorrect" + +test "alphabetically sorted indices": + set {_test::a} to "Bob" + set {_test::b} to "Donald" + set {_test::c} to "Zeffer" + set {_test::d} to "Angus" + set {_test::e} to "Kevin" + set {_test::f} to "anderson" + set {_test::g} to "robertson" + + set {_indexes::*} to sorted indices of {_test::*} in ascending order + + assert {_test::%{_indexes::1}%} = "anderson" with "First element of sorted strings should be 'anderson'" + assert {_test::%{_indexes::7}%} = "Zeffer" with "Last element of sorted strings should be 'Zeffer'"