diff --git a/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java b/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java index f59709717..9c2d609b9 100644 --- a/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java +++ b/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java @@ -18,9 +18,13 @@ import net.minecraft.nbt.CompoundNBT; import net.minecraft.server.MinecraftServer; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.RegistryKey; +import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.registry.Registry; import net.minecraft.world.World; +import javax.annotation.Nonnull; import java.util.*; /** @@ -187,22 +191,24 @@ public final Object[] getBlockPosition() * Blocks are traversed by ascending y level, followed by z and x - the returned * table may be indexed using `x + z*width + y*depth*depth`. * - * @param minX The start x coordinate of the range to query. - * @param minY The start y coordinate of the range to query. - * @param minZ The start z coordinate of the range to query. - * @param maxX The end x coordinate of the range to query. - * @param maxY The end y coordinate of the range to query. - * @param maxZ The end z coordinate of the range to query. + * @param minX The start x coordinate of the range to query. + * @param minY The start y coordinate of the range to query. + * @param minZ The start z coordinate of the range to query. + * @param maxX The end x coordinate of the range to query. + * @param maxY The end y coordinate of the range to query. + * @param maxZ The end z coordinate of the range to query. + * @param dimension The dimension to query (e.g. "minecraft:overworld"). Defaults to the current dimension. * @return A list of information about each block. * @throws LuaException If the coordinates are not within the world. * @throws LuaException If trying to get information about more than 4096 blocks. * @cc.since 1.76 + * @cc.changed 1.99 Added {@code dimension} argument. */ @LuaFunction( mainThread = true ) - public final List> getBlockInfos( int minX, int minY, int minZ, int maxX, int maxY, int maxZ ) throws LuaException + public final List> getBlockInfos( int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Optional dimension ) throws LuaException { // Get the details of the block - World world = computer.getLevel(); + World world = getLevel( dimension ); BlockPos min = new BlockPos( Math.min( minX, maxX ), Math.min( minY, maxY ), @@ -244,26 +250,38 @@ public final Object[] getBlockPosition() * with @{turtle.inspect}). If there is a tile entity for that block, its NBT * will also be returned. * - * @param x The x position of the block to query. - * @param y The y position of the block to query. - * @param z The z position of the block to query. + * @param x The x position of the block to query. + * @param y The y position of the block to query. + * @param z The z position of the block to query. + * @param dimension The dimension to query (e.g. "minecraft:overworld"). Defaults to the current dimension. * @return The given block's information. * @throws LuaException If the coordinates are not within the world, or are not currently loaded. * @cc.changed 1.76 Added block state info to return value + * @cc.changed 1.99 Added {@code dimension} argument. */ @LuaFunction( mainThread = true ) - public final Map getBlockInfo( int x, int y, int z ) throws LuaException + public final Map getBlockInfo( int x, int y, int z, Optional dimension ) throws LuaException { - // Get the details of the block - World world = computer.getLevel(); + World world = getLevel( dimension ); BlockPos position = new BlockPos( x, y, z ); - if( World.isInWorldBounds( position ) ) - { - return getBlockInfo( world, position ); - } - else - { - throw new LuaException( "Co-ordinates out of range" ); - } + if( !World.isInWorldBounds( position ) ) throw new LuaException( "Co-ordinates out of range" ); + return getBlockInfo( world, position ); + } + + @Nonnull + private World getLevel( @Nonnull Optional id ) throws LuaException + { + World currentWorld = computer.getLevel(); + if( currentWorld == null ) throw new LuaException( "No world exists" ); + + if( !id.isPresent() ) return currentWorld; + + ResourceLocation dimensionId = ResourceLocation.tryParse( id.get() ); + if( dimensionId == null ) throw new LuaException( "Invalid dimension name" ); + + World world = currentWorld.getServer().getLevel( RegistryKey.create( Registry.DIMENSION_REGISTRY, dimensionId ) ); + if( world == null ) throw new LuaException( "Unknown dimension" ); + + return world; } }