Skip to content

Commit

Permalink
Fix BlockLineIterator completion failure exception (SkriptLang#7062)
Browse files Browse the repository at this point in the history
Caused by height clamping
  • Loading branch information
TheAbsolutionism authored and Burbulinis committed Dec 3, 2024
1 parent 73323d5 commit 6ada656
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 25 deletions.
10 changes: 8 additions & 2 deletions src/main/java/ch/njol/skript/expressions/ExprBlocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@
@Since("1.0, 2.5.1 (within/cuboid/chunk)")
public class ExprBlocks extends SimpleExpression<Block> {

private static final boolean SUPPORTS_WORLD_LOADED = Skript.methodExists(Location.class, "isWorldLoaded");

static {
Skript.registerExpression(ExprBlocks.class, Block.class, ExpressionType.COMBINED,
"[(all [[of] the]|the)] blocks %direction% [%locations%]", // TODO doesn't loop all blocks?
"[(all [[of] the]|the)] blocks %direction% [%locations%]",
"[(all [[of] the]|the)] blocks from %location% [on] %direction%",
"[(all [[of] the]|the)] blocks from %location% to %location%",
"[(all [[of] the]|the)] blocks between %location% and %location%",
Expand Down Expand Up @@ -116,7 +118,11 @@ protected Block[] get(Event event) {
return from.stream(event)
.filter(Location.class::isInstance)
.map(Location.class::cast)
.filter(Location::isWorldLoaded)
.filter(location -> {
if (SUPPORTS_WORLD_LOADED)
return location.isWorldLoaded();
return location.getChunk().isLoaded();
})
.map(direction::getRelative)
.map(Location::getBlock)
.toArray(Block[]::new);
Expand Down
30 changes: 7 additions & 23 deletions src/main/java/ch/njol/skript/util/BlockLineIterator.java
Original file line number Diff line number Diff line change
@@ -1,31 +1,13 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.skript.util;

import ch.njol.skript.bukkitutil.WorldUtils;
import ch.njol.util.Math2;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.util.BlockIterator;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.Nullable;

import ch.njol.skript.bukkitutil.WorldUtils;
import ch.njol.util.Math2;
import ch.njol.util.NullableChecker;
import ch.njol.util.coll.iterator.StoppableIterator;

Expand All @@ -37,8 +19,10 @@ public class BlockLineIterator extends StoppableIterator<Block> {
* @throws IllegalStateException randomly (Bukkit bug)
*/
public BlockLineIterator(Block start, Block end) throws IllegalStateException {
super(new BlockIterator(start.getWorld(), fitInWorld(start.getLocation().add(0.5, 0.5, 0.5), end.getLocation().subtract(start.getLocation()).toVector()),
end.equals(start) ? new Vector(1, 0, 0) : end.getLocation().subtract(start.getLocation()).toVector(), 0, 0), // should prevent an error if start = end
super(new BlockIterator(start.getWorld(), start.getLocation().toVector(),
end.equals(start) ? new Vector(1, 0, 0) : end.getLocation().subtract(start.getLocation()).toVector(), // should prevent an error if start = end
0, 0
),
new NullableChecker<Block>() {
private final double overshotSq = Math.pow(start.getLocation().distance(end.getLocation()) + 2, 2);

Expand All @@ -59,7 +43,7 @@ public boolean check(@Nullable Block block) {
* @throws IllegalStateException randomly (Bukkit bug)
*/
public BlockLineIterator(Location start, Vector direction, double distance) throws IllegalStateException {
super(new BlockIterator(start.getWorld(), fitInWorld(start, direction), direction, 0, 0), new NullableChecker<Block>() {
super(new BlockIterator(start.getWorld(), start.toVector(), direction, 0, 0), new NullableChecker<Block>() {
private final double distSq = distance * distance;

@Override
Expand Down
18 changes: 18 additions & 0 deletions src/test/skript/tests/syntaxes/expressions/ExprBlocks.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
test "blocks void":
set {_loc} to location(0.5, 320.5, 0.5)
set {_blocks::*} to blocks between {_loc} and ({_loc} ~ vector(10,0,0))
assert size of {_blocks::*} is 11 with "Blocks between loc and (loc~vector(10,0,0)) is not 11"
assert blocks at {_blocks::*} is void air with "Blocks can be set in the void?"
set blocks at {_blocks::*} to stone
assert blocks at {_blocks::*} is void air with "Blocks can be set in the void?"

test "blocks vector direction":
set {_loc} to location(0.5, 20.5, 0.5)
set {_blocks::*} to blocks vector(1,0,0) {_loc}
assert size of {_blocks::*} is 100 with "Blocks vector(1,0,0) loc is not 100"
set blocks at {_blocks::*} to stone
assert blocks at {_blocks::*} is stone with "1 or more blocks were not set to stone"
set blocks at {_blocks::*} to air
assert blocks at {_blocks::*} is air with "1 or more blocks were not set to air"
loop {_blocks::*}:
set block at loop-value to loop-value

0 comments on commit 6ada656

Please sign in to comment.