diff --git a/build.gradle b/build.gradle index 8f751ab63..37df62d8f 100644 --- a/build.gradle +++ b/build.gradle @@ -345,6 +345,11 @@ task compressJson(dependsOn: jar) { releaseAssets.from(jar.archivePath) } +task uploadAll(dependsOn: [uploadArchives, "curseforge", "githubRelease"]) { + group "upload" + description "Uploads to all repositories (Maven, Curse, GitHub release)" +} + test { useJUnitPlatform() testLogging { diff --git a/gradle.properties b/gradle.properties index 90ef03b55..d5966e7e8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Mod properties -mod_version=1.82.1 +mod_version=1.82.3 # Minecraft properties mc_version=1.13.2 diff --git a/src/main/java/dan200/computercraft/core/filesystem/JarMount.java b/src/main/java/dan200/computercraft/core/filesystem/JarMount.java index 13af67fe5..941837c94 100644 --- a/src/main/java/dan200/computercraft/core/filesystem/JarMount.java +++ b/src/main/java/dan200/computercraft/core/filesystem/JarMount.java @@ -69,7 +69,7 @@ public JarMount( File jarFile, String subPath ) throws IOException // Cleanup any old mounts. It's unlikely that there will be any, but it's best to be safe. cleanup(); - if( !jarFile.exists() || jarFile.isDirectory() ) throw new FileNotFoundException(); + if( !jarFile.exists() || jarFile.isDirectory() ) throw new FileNotFoundException( "Cannot find " + jarFile ); // Open the zip file try @@ -85,7 +85,7 @@ public JarMount( File jarFile, String subPath ) throws IOException if( zip.getEntry( subPath ) == null ) { zip.close(); - throw new IOException( "Zip does not contain path" ); + throw new FileNotFoundException( "Zip does not contain path" ); } // We now create a weak reference to this mount. This is automatically added to the appropriate queue. diff --git a/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java b/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java index 2de41b96c..55a986e16 100644 --- a/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java +++ b/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java @@ -242,7 +242,7 @@ public Varargs invoke( final LuaState state, Varargs args ) throws LuaError } catch( InterruptedException e ) { - throw new OrphanedThread(); + throw new InterruptedError( e ); } catch( LuaException e ) { diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputerBase.java b/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputerBase.java index a63bf66ce..2ff6df99b 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputerBase.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/BlockComputerBase.java @@ -67,7 +67,7 @@ public int getStrongPower( IBlockState state, IBlockReader world, BlockPos pos, if( computer == null ) return 0; ComputerSide localSide = computerEntity.remapToLocalSide( incomingSide.getOpposite() ); - return computerEntity.isRedstoneBlockedOnSide( localSide ) ? 0 : computer.getRedstoneOutput( localSide ); + return computer.getRedstoneOutput( localSide ); } @Nonnull @@ -88,11 +88,7 @@ public int getWeakPower( IBlockState state, IBlockReader world, BlockPos pos, En @Override public boolean getBundledRedstoneConnectivity( World world, BlockPos pos, EnumFacing side ) { - TileEntity entity = world.getTileEntity( pos ); - if( !(entity instanceof TileComputerBase) ) return false; - - TileComputerBase computerEntity = (TileComputerBase) entity; - return !computerEntity.isRedstoneBlockedOnSide( computerEntity.remapToLocalSide( side ) ); + return true; } @Override @@ -106,7 +102,7 @@ public int getBundledRedstoneOutput( World world, BlockPos pos, EnumFacing side if( computer == null ) return 0; ComputerSide localSide = computerEntity.remapToLocalSide( side ); - return computerEntity.isRedstoneBlockedOnSide( localSide ) ? 0 : computer.getBundledRedstoneOutput( localSide ); + return computer.getBundledRedstoneOutput( localSide ); } @Nonnull diff --git a/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java b/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java index 0fe8c8a66..a79a53f21 100644 --- a/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java +++ b/src/main/java/dan200/computercraft/shared/computer/blocks/TileComputerBase.java @@ -20,7 +20,10 @@ import dan200.computercraft.shared.util.DirectionUtil; import dan200.computercraft.shared.util.RedstoneUtil; import joptsimple.internal.Strings; +import net.minecraft.block.BlockRedstoneWire; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -32,6 +35,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; +import net.minecraft.world.World; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -204,11 +208,6 @@ protected boolean isPeripheralBlockedOnSide( ComputerSide localSide ) return false; } - protected boolean isRedstoneBlockedOnSide( ComputerSide localSide ) - { - return false; - } - protected abstract EnumFacing getDirection(); protected ComputerSide remapToLocalSide( EnumFacing globalSide ) @@ -225,17 +224,35 @@ private void updateSideInput( ServerComputer computer, EnumFacing dir, BlockPos { EnumFacing offsetSide = dir.getOpposite(); ComputerSide localDir = remapToLocalSide( dir ); - if( !isRedstoneBlockedOnSide( localDir ) ) - { - computer.setRedstoneInput( localDir, getWorld().getRedstonePower( offset, dir ) ); - computer.setBundledRedstoneInput( localDir, BundledRedstone.getOutput( getWorld(), offset, offsetSide ) ); - } + + computer.setRedstoneInput( localDir, getRedstoneInput( world, offset, dir ) ); + computer.setBundledRedstoneInput( localDir, BundledRedstone.getOutput( getWorld(), offset, offsetSide ) ); if( !isPeripheralBlockedOnSide( localDir ) ) { computer.setPeripheral( localDir, Peripherals.getPeripheral( getWorld(), offset, offsetSide ) ); } } + /** + * Gets the redstone input for an adjacent block + * + * @param world The world we exist in + * @param pos The position of the neighbour + * @param side The side we are reading from + * @return The effective redstone power + * @see net.minecraft.block.BlockRedstoneDiode#calculateInputStrength(World, BlockPos, IBlockState) + */ + protected static int getRedstoneInput( World world, BlockPos pos, EnumFacing side ) + { + int power = world.getRedstonePower( pos, side ); + if( power >= 15 ) return power; + + IBlockState neighbour = world.getBlockState( pos ); + return neighbour.getBlock() == Blocks.REDSTONE_WIRE + ? Math.max( power, neighbour.get( BlockRedstoneWire.POWER ) ) + : power; + } + public void updateInput() { if( getWorld() == null || getWorld().isRemote ) return; diff --git a/src/main/java/dan200/computercraft/shared/integration/mcmp/MCMPIntegration.java b/src/main/java/dan200/computercraft/shared/integration/mcmp/MCMPIntegration.java index 58bc39edd..358fcda92 100644 --- a/src/main/java/dan200/computercraft/shared/integration/mcmp/MCMPIntegration.java +++ b/src/main/java/dan200/computercraft/shared/integration/mcmp/MCMPIntegration.java @@ -10,8 +10,10 @@ import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheralTile; +import dan200.computercraft.shared.peripheral.common.TilePeripheralBase; import dan200.computercraft.shared.peripheral.modem.wireless.TileAdvancedModem; import dan200.computercraft.shared.peripheral.modem.wireless.TileWirelessModem; +import dan200.computercraft.shared.peripheral.monitor.TileMonitor; import mcmultipart.api.addon.IMCMPAddon; import mcmultipart.api.addon.MCMPAddon; import mcmultipart.api.container.IMultipartContainer; @@ -52,7 +54,7 @@ private static void register( IMultipartRegistry registry, Block block, IMultipa public void registerParts( IMultipartRegistry registry ) { // Setup all parts - register( registry, ComputerCraft.Blocks.peripheral, new PartNormalModem() ); + register( registry, ComputerCraft.Blocks.peripheral, new PartPeripheral() ); register( registry, ComputerCraft.Blocks.advancedModem, new PartAdvancedModem() ); // Subscribe to capability events @@ -83,8 +85,11 @@ public void registerParts( IMultipartRegistry registry ) public static void attach( AttachCapabilitiesEvent event ) { TileEntity tile = event.getObject(); - if( tile instanceof TileAdvancedModem || tile instanceof TileWirelessModem ) + if( tile instanceof TileAdvancedModem || tile instanceof TileWirelessModem + || tile instanceof TilePeripheralBase || tile instanceof TileMonitor ) { + // We need to attach to modems (obviously), but also any other tile created by BlockPeripheral. Otherwise + // IMultipart.convertToMultipartTile will error. event.addCapability( CAPABILITY_KEY, new BasicMultipart( tile ) ); } } @@ -94,7 +99,10 @@ private static final class BasicMultipart implements ICapabilityProvider private final TileEntity tile; private IMultipartTile wrapped; - private BasicMultipart( TileEntity tile ) {this.tile = tile;} + private BasicMultipart( TileEntity tile ) + { + this.tile = tile; + } @Override public boolean hasCapability( @Nonnull Capability capability, @Nullable EnumFacing facing ) diff --git a/src/main/java/dan200/computercraft/shared/integration/mcmp/PartNormalModem.java b/src/main/java/dan200/computercraft/shared/integration/mcmp/PartPeripheral.java similarity index 73% rename from src/main/java/dan200/computercraft/shared/integration/mcmp/PartNormalModem.java rename to src/main/java/dan200/computercraft/shared/integration/mcmp/PartPeripheral.java index 5e5811196..daf25450b 100644 --- a/src/main/java/dan200/computercraft/shared/integration/mcmp/PartNormalModem.java +++ b/src/main/java/dan200/computercraft/shared/integration/mcmp/PartPeripheral.java @@ -10,6 +10,7 @@ import dan200.computercraft.shared.peripheral.common.BlockPeripheral; import dan200.computercraft.shared.peripheral.common.BlockPeripheralVariant; import mcmultipart.api.multipart.IMultipart; +import mcmultipart.api.slot.EnumCenterSlot; import mcmultipart.api.slot.EnumFaceSlot; import mcmultipart.api.slot.IPartSlot; import net.minecraft.block.Block; @@ -20,34 +21,41 @@ import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -public class PartNormalModem implements IMultipart +import javax.annotation.Nonnull; + +public class PartPeripheral implements IMultipart { @Override public IPartSlot getSlotForPlacement( World world, BlockPos pos, IBlockState state, EnumFacing facing, float hitX, float hitY, float hitZ, EntityLivingBase placer ) { - return EnumFaceSlot.fromFace( getFacing( state ) ); + return getSlot( state ); } @Override public IPartSlot getSlotFromWorld( IBlockAccess world, BlockPos pos, IBlockState state ) { - return EnumFaceSlot.fromFace( getFacing( state ) ); + return getSlot( state ); } - private EnumFacing getFacing( IBlockState state ) + @Nonnull + private static IPartSlot getSlot( IBlockState state ) { BlockPeripheralVariant type = state.getValue( BlockPeripheral.VARIANT ); if( type == BlockPeripheralVariant.WirelessModemUpOn || type == BlockPeripheralVariant.WirelessModemUpOff ) { - return EnumFacing.UP; + return EnumFaceSlot.UP; } else if( type == BlockPeripheralVariant.WirelessModemDownOn || type == BlockPeripheralVariant.WirelessModemDownOff ) { - return EnumFacing.UP; + return EnumFaceSlot.DOWN; + } + else if( type == BlockPeripheralVariant.WirelessModemOff || type == BlockPeripheralVariant.WirelessModemOn ) + { + return EnumFaceSlot.fromFace( state.getValue( BlockPeripheral.FACING ) ); } else { - return state.getValue( BlockPeripheral.FACING ); + return EnumCenterSlot.CENTER; } } diff --git a/src/main/java/dan200/computercraft/shared/turtle/apis/TurtleAPI.java b/src/main/java/dan200/computercraft/shared/turtle/apis/TurtleAPI.java index 9b9927909..7e581fb81 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/apis/TurtleAPI.java +++ b/src/main/java/dan200/computercraft/shared/turtle/apis/TurtleAPI.java @@ -304,7 +304,8 @@ public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull O case 31: { // refuel - int count = parseCount( args, 0 ); + int count = optInt( args, 0, Integer.MAX_VALUE ); + if( count < 0 ) throw new LuaException( "Refuel count " + count + " out of range" ); return tryCommand( context, new TurtleRefuelCommand( count ) ); } case 32: diff --git a/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java b/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java index 8579838f8..59a396a9c 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java +++ b/src/main/java/dan200/computercraft/shared/turtle/blocks/TileTurtle.java @@ -338,12 +338,6 @@ protected boolean isPeripheralBlockedOnSide( ComputerSide localSide ) return hasPeripheralUpgradeOnSide( localSide ); } - @Override - protected boolean isRedstoneBlockedOnSide( ComputerSide localSide ) - { - return false; - } - // IDirectionalTile @Override diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCompareCommand.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCompareCommand.java index 5b5be1263..7e14655e1 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCompareCommand.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCompareCommand.java @@ -16,8 +16,10 @@ import net.minecraft.util.NonNullList; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import javax.annotation.Nonnull; +import java.lang.reflect.Method; public class TurtleCompareCommand implements ITurtleCommand { @@ -50,24 +52,18 @@ public TurtleCommandResult execute( @Nonnull ITurtleAccess turtle ) Block lookAtBlock = lookAtState.getBlock(); if( !lookAtBlock.isAir( lookAtState, world, newPosition ) ) { - // Try createStackedBlock first - /* + // Try getSilkTouchDrop first if( !lookAtBlock.hasTileEntity( lookAtState ) ) { try { - Method method = ReflectionHelper.findMethod( - Block.class, - "func_180643_i", "getSilkTouchDrop", - IBlockState.class - ); + Method method = ObfuscationReflectionHelper.findMethod( Block.class, "func_180643_i", IBlockState.class ); lookAtStack = (ItemStack) method.invoke( lookAtBlock, lookAtState ); } - catch( ReflectiveOperationException ignored ) + catch( ReflectiveOperationException | RuntimeException ignored ) { } } - */ // See if the block drops anything with the same ID as itself // (try 5 times to try and beat random number generators) diff --git a/src/main/resources/data/computercraft/lua/rom/programs/turtle/refuel.lua b/src/main/resources/data/computercraft/lua/rom/programs/turtle/refuel.lua index 41956d59c..618b199cb 100644 --- a/src/main/resources/data/computercraft/lua/rom/programs/turtle/refuel.lua +++ b/src/main/resources/data/computercraft/lua/rom/programs/turtle/refuel.lua @@ -6,19 +6,27 @@ if #tArgs > 1 then return elseif #tArgs > 0 then if tArgs[1] == "all" then - nLimit = 64 * 16 + nLimit = nil else nLimit = tonumber( tArgs[1] ) + if not nLimit then + print("Invalid limit, expected a number or \"all\"") + return + end end end if turtle.getFuelLevel() ~= "unlimited" then - for n=1,16 do + for n = 1, 16 do + -- Stop if we've reached the limit, or are fully refuelled. + if (nLimit and nLimit <= 0) or turtle.getFuelLevel() >= turtle.getFuelLimit() then + break + end + local nCount = turtle.getItemCount(n) - if nLimit > 0 and nCount > 0 and turtle.getFuelLevel() < turtle.getFuelLimit() then - local nBurn = math.min( nLimit, nCount ) + if nCount > 0 then turtle.select( n ) - if turtle.refuel( nBurn ) then + if turtle.refuel( nLimit ) and nLimit then local nNewCount = turtle.getItemCount(n) nLimit = nLimit - (nCount - nNewCount) end