Merge branch 'master' into mc-1.14.x

Unfortunately we can't apply the config changes due to backwards
compatibility. This'll be something we may need to PR into Forge.

CraftTweaker support still needs to be added.
This commit is contained in:
SquidDev 2019-12-23 22:34:28 +00:00
commit 037cbabb32
101 changed files with 1569 additions and 1173 deletions

View File

@ -11,5 +11,8 @@ insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[*.sexp]
indent_size = 2
[*.properties]
insert_final_newline = false

View File

@ -4,6 +4,7 @@ on: [push, pull_request]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
@ -16,3 +17,17 @@ jobs:
- name: Build with Gradle
run: ./gradlew build --no-daemon
lint-lua:
name: Lint Lua
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Lint Lua code
run: |
test -d bin || mkdir bin
test -f bin/illuaminate || wget -q -Obin/illuaminate https://squiddev.cc/illuaminate/bin/illuaminate
chmod +x bin/illuaminate
bin/illuaminate lint

View File

@ -1,35 +0,0 @@
std = "max"
ignore = {
-- Allow access to undefined globals or their fields. In the future we'll
-- define all of CC's globals within this file
'113', '143',
-- FIXME: Ignore unused arguments and loop variables
'212', '213',
-- Disable line is too long for now. It would be possible to clean
-- this up in the future.
'631',
}
-- Only run the linter on ROM and bios for now, as the treasure disks
-- are largely unsupported.
include_files = {
'src/main/resources/assets/computercraft/lua/rom',
'src/main/resources/assets/computercraft/lua/bios.lua',
'src/test/resources/test-rom',
}
files['src/main/resources/assets/computercraft/lua/bios.lua'] = {
-- Allow declaring and mutating globals
allow_defined_top = true,
ignore = { '112', '121', '122', '131', '142' },
}
files['src/main/resources/assets/computercraft/lua/rom/apis'] = {
-- APIs may define globals on the top level. We'll ignore unused globals,
-- as obviously they may be used outside that API.
allow_defined_top = true,
ignore = { '131' },
}

View File

@ -81,6 +81,10 @@ accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
name "Amadornes"
url "https://maven.amadornes.com/"
}
maven {
name "CraftTweaker"
url "https://maven.blamejared.com/"
}
}
configurations {
@ -95,8 +99,7 @@ accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
compileOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.25:api")
// deobfProvided "pl.asie:Charset-Lib:0.5.4.6"
// deobfProvided "MCMultiPart2:MCMultiPart:2.5.3"
compileOnly fg.deobf("com.blamejared.crafttweaker:CraftTweaker-1.14.4:5.0.1.150")
runtimeOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.25")
@ -162,6 +165,7 @@ task proguard(type: ProGuardTask, dependsOn: jar) {
// Add the main runtime jar and all non-shadowed dependencies
libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
libraryjars "${System.getProperty('java.home')}/lib/jce.jar"
doFirst {
sourceSets.main.compileClasspath
.filter { !it.name.contains("Cobalt") }
@ -177,9 +181,6 @@ task proguard(type: ProGuardTask, dependsOn: jar) {
// Preserve ComputerCraft classes - we only want to strip shadowed files.
keep 'class dan200.computercraft.** { *; }'
// Preserve the constructors in Cobalt library class, as we init them via reflection
keepclassmembers 'class org.squiddev.cobalt.lib.** { <init>(...); }'
// LWJGL and Apache bundle Java 9 versions, which is great, but rather breaks Proguard
dontwarn 'module-info'
dontwarn 'org.apache.**,org.lwjgl.**'

View File

@ -1,5 +1,5 @@
# Mod properties
mod_version=1.85.2
mod_version=1.86.0
# Minecraft properties (update mods.toml when changing)
mc_version=1.14.4

28
illuaminate.sexp Normal file
View File

@ -0,0 +1,28 @@
; -*- mode: Lisp;-*-
(sources
/src/main/resources/assets/computercraft/lua/bios.lua
/src/main/resources/assets/computercraft/lua/rom/
/src/test/resources/test-rom)
(at /
(linters
;; It'd be nice to avoid this, but right now there's a lot of instances of
;; it.
-var:set-loop
;; It's useful to name arguments for documentation, so we allow this. It'd
;; be good to find a compromise in the future, but this works for now.
-var:unused-arg))
;; We disable the unused global linter in bios.lua and the APIs. In the future
;; hopefully we'll get illuaminate to handle this.
(at
(/src/main/resources/assets/computercraft/lua/bios.lua
/src/main/resources/assets/computercraft/lua/rom/apis/)
(linters -var:unused-global)
(lint
(allow-toplevel-global true)))
;; These warnings are broken right now
(at (bios.lua worm.lua) (linters -control:unreachable))

View File

@ -17,11 +17,33 @@
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.stream.Stream;
public final class TurtleUpgrades
{
public static class Wrapper
{
final ITurtleUpgrade upgrade;
final int legacyId;
final String id;
final String modId;
boolean enabled;
public Wrapper( ITurtleUpgrade upgrade )
{
ModContainer mc = ModLoadingContext.get().getActiveContainer();
this.upgrade = upgrade;
this.id = upgrade.getUpgradeID().toString();
this.modId = mc != null && mc.getModId() != null ? mc.getModId() : null;
this.enabled = true;
}
}
private static ITurtleUpgrade[] vanilla;
private static final Map<String, ITurtleUpgrade> upgrades = new HashMap<>();
private static final IdentityHashMap<ITurtleUpgrade, String> upgradeOwners = new IdentityHashMap<>();
private static final IdentityHashMap<ITurtleUpgrade, Wrapper> wrappers = new IdentityHashMap<>();
private TurtleUpgrades() {}
@ -29,7 +51,8 @@ public static void register( @Nonnull ITurtleUpgrade upgrade )
{
Objects.requireNonNull( upgrade, "upgrade cannot be null" );
String id = upgrade.getUpgradeID().toString();
Wrapper wrapper = new Wrapper( upgrade );
String id = wrapper.id;
ITurtleUpgrade existing = upgrades.get( id );
if( existing != null )
{
@ -37,17 +60,28 @@ public static void register( @Nonnull ITurtleUpgrade upgrade )
}
upgrades.put( id, upgrade );
ModContainer mc = ModLoadingContext.get().getActiveContainer();
if( mc != null && mc.getModId() != null ) upgradeOwners.put( upgrade, mc.getModId() );
wrappers.put( upgrade, wrapper );
}
@Nullable
public static ITurtleUpgrade get( String id )
{
return upgrades.get( id );
}
@Nullable
public static ITurtleUpgrade get( int id )
{
return legacyUpgrades.get( id );
}
@Nullable
public static String getOwner( @Nonnull ITurtleUpgrade upgrade )
{
Wrapper wrapper = wrappers.get( upgrade );
return wrapper != null ? wrapper.modId : null;
}
public static ITurtleUpgrade get( @Nonnull ItemStack stack )
{
if( stack.isEmpty() ) return null;
@ -64,30 +98,27 @@ public static ITurtleUpgrade get( @Nonnull ItemStack stack )
return null;
}
public static Iterable<ITurtleUpgrade> getVanillaUpgrades()
public static Stream<ITurtleUpgrade> getVanillaUpgrades()
{
List<ITurtleUpgrade> vanilla = new ArrayList<>();
if( vanilla == null )
{
vanilla = new ITurtleUpgrade[] {
// ComputerCraft upgrades
vanilla.add( ComputerCraft.TurtleUpgrades.wirelessModemNormal );
vanilla.add( ComputerCraft.TurtleUpgrades.wirelessModemAdvanced );
vanilla.add( ComputerCraft.TurtleUpgrades.speaker );
ComputerCraft.TurtleUpgrades.wirelessModemNormal,
ComputerCraft.TurtleUpgrades.wirelessModemAdvanced,
ComputerCraft.TurtleUpgrades.speaker,
// Vanilla Minecraft upgrades
vanilla.add( ComputerCraft.TurtleUpgrades.diamondPickaxe );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondAxe );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondSword );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondShovel );
vanilla.add( ComputerCraft.TurtleUpgrades.diamondHoe );
vanilla.add( ComputerCraft.TurtleUpgrades.craftingTable );
return vanilla;
ComputerCraft.TurtleUpgrades.diamondPickaxe,
ComputerCraft.TurtleUpgrades.diamondAxe,
ComputerCraft.TurtleUpgrades.diamondSword,
ComputerCraft.TurtleUpgrades.diamondShovel,
ComputerCraft.TurtleUpgrades.diamondHoe,
ComputerCraft.TurtleUpgrades.craftingTable,
};
}
@Nullable
public static String getOwner( @Nonnull ITurtleUpgrade upgrade )
{
return upgradeOwners.get( upgrade );
return Arrays.stream( vanilla ).filter( x -> x != null && wrappers.get( x ).enabled );
}
public static Iterable<ITurtleUpgrade> getUpgrades()
@ -99,4 +130,14 @@ public static boolean suitableForFamily( ComputerFamily family, ITurtleUpgrade u
{
return true;
}
public static void disable( ITurtleUpgrade upgrade )
{
Wrapper wrapper = wrappers.get( upgrade );
if( !wrapper.enabled ) return;
wrapper.enabled = false;
upgrades.remove( wrapper.id );
if( wrapper.legacyId >= 0 ) legacyUpgrades.remove( wrapper.legacyId );
}
}

View File

@ -0,0 +1,70 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker;
import crafttweaker.CraftTweakerAPI;
import crafttweaker.annotations.ModOnly;
import crafttweaker.annotations.ZenDoc;
import crafttweaker.annotations.ZenRegister;
import crafttweaker.api.item.IItemStack;
import crafttweaker.api.minecraft.CraftTweakerMC;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.integration.crafttweaker.actions.AddTurtleTool;
import dan200.computercraft.shared.integration.crafttweaker.actions.RemoveTurtleUpgradeByItem;
import dan200.computercraft.shared.integration.crafttweaker.actions.RemoveTurtleUpgradeByName;
import stanhebben.zenscript.annotations.ZenClass;
import stanhebben.zenscript.annotations.ZenMethod;
@ZenRegister
@ZenClass( "dan200.computercraft.turtle" )
@ModOnly( ComputerCraft.MOD_ID )
public class TurtleTweaker
{
@ZenMethod
@ZenDoc( "Remove a turtle upgrade with the given id" )
public static void removeUpgrade( String upgrade )
{
CraftTweakerAPI.apply( new RemoveTurtleUpgradeByName( upgrade ) );
}
@ZenMethod
@ZenDoc( "Remove a turtle upgrade crafted with the given item stack" )
public static void removeUpgrade( IItemStack stack )
{
CraftTweakerAPI.apply( new RemoveTurtleUpgradeByItem( CraftTweakerMC.getItemStack( stack ) ) );
}
@ZenMethod
@ZenDoc( "Add a new turtle tool with the given id, which crafts and acts using the given stack." )
public static void addTool( String id, IItemStack stack )
{
addTool( id, stack, stack, "tool" );
}
@ZenMethod
@ZenDoc( "Add a new turtle tool with the given id, which is crafted with one item, and uses another." )
public static void addTool( String id, IItemStack craftingStack, IItemStack toolStack )
{
addTool( id, craftingStack, toolStack, "tool" );
}
@ZenMethod
@ZenDoc( "Add a new turtle tool with the given id, which crafts and acts using the given stack. You may also" +
"specify a 'kind' of tool, which limits what blocks the turtle can break (for instance, an 'axe' may only break wood)." )
public static void addTool( String id, IItemStack stack, String kind )
{
addTool( id, stack, stack, kind );
}
@ZenMethod
@ZenDoc( "Add a new turtle tool with the given id, which is crafted with one item, and uses another. You may also" +
"specify a 'kind' of tool, which limits what blocks the turtle can break (for instance, an 'axe' may only break wood)." )
public static void addTool( String id, IItemStack craftingStack, IItemStack toolStack, String kind )
{
CraftTweakerAPI.apply( new AddTurtleTool( id, CraftTweakerMC.getItemStack( craftingStack ), CraftTweakerMC.getItemStack( toolStack ), kind ) );
}
}

View File

@ -0,0 +1,96 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker.actions;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.TurtleUpgrades;
import dan200.computercraft.shared.turtle.upgrades.*;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* Register a new turtle tool.
*/
public class AddTurtleTool implements IAction
{
private interface Factory
{
TurtleTool create( ResourceLocation location, ItemStack craftItem, ItemStack toolItem );
}
private static final Map<String, Factory> kinds = new HashMap<>();
static
{
kinds.put( "tool", TurtleTool::new );
kinds.put( "axe", TurtleAxe::new );
kinds.put( "hoe", TurtleHoe::new );
kinds.put( "shovel", TurtleShovel::new );
kinds.put( "sword", TurtleSword::new );
}
private final String id;
private final ItemStack craftItem;
private final ItemStack toolItem;
private final String kind;
public AddTurtleTool( String id, ItemStack craftItem, ItemStack toolItem, String kind )
{
this.id = id;
this.craftItem = craftItem;
this.toolItem = toolItem;
this.kind = kind;
}
@Override
public void apply()
{
Factory factory = kinds.get( kind );
if( factory == null )
{
ComputerCraft.log.error( "Unknown turtle upgrade kind '{}' (this should have been rejected by verify!)", kind );
return;
}
try
{
TurtleUpgrades.register( factory.create( new ResourceLocation( id ), craftItem, toolItem ) );
}
catch( RuntimeException e )
{
ComputerCraft.log.error( "Registration of turtle tool failed", e );
}
}
@Override
public String describe()
{
return String.format( "Add new turtle %s '%s' (crafted with '%s', uses a '%s')", kind, id, craftItem, toolItem );
}
public Optional<String> getValidationProblem()
{
if( craftItem.isEmpty() ) return Optional.of( "Crafting item stack is empty." );
if( craftItem.hasTagCompound() && !craftItem.getTagCompound().isEmpty() )
{
return Optional.of( "Crafting item has NBT." );
}
if( toolItem.isEmpty() ) return Optional.of( "Tool item stack is empty." );
if( !kinds.containsKey( kind ) ) return Optional.of( String.format( "Unknown kind '%s'.", kind ) );
if( TurtleUpgrades.get( id ) != null )
{
return Optional.of( String.format( "An upgrade with the same name ('%s') has already been registered.", id ) );
}
return Optional.empty();
}
}

View File

@ -0,0 +1,32 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker.actions;
import java.util.Optional;
/**
* An extension of {@link IAction} with a single validation function, rather than two.
*/
public interface IAction extends crafttweaker.IAction
{
default Optional<String> getValidationProblem()
{
return Optional.empty();
}
@Override
default boolean validate()
{
return !getValidationProblem().isPresent();
}
@Override
default String describeInvalid()
{
return getValidationProblem().orElse( "No problems found." );
}
}

View File

@ -0,0 +1,50 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker.actions;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.shared.TurtleUpgrades;
import net.minecraft.item.ItemStack;
import java.util.Optional;
/**
* Removes a turtle upgrade crafted with the given stack.
*/
public class RemoveTurtleUpgradeByItem implements IAction
{
private final ItemStack stack;
public RemoveTurtleUpgradeByItem( ItemStack stack )
{
this.stack = stack;
}
@Override
public void apply()
{
ITurtleUpgrade upgrade = TurtleUpgrades.get( stack );
if( upgrade != null ) TurtleUpgrades.disable( upgrade );
}
@Override
public String describe()
{
return String.format( "Remove turtle upgrades crafted with '%s'", stack );
}
@Override
public Optional<String> getValidationProblem()
{
if( TurtleUpgrades.get( stack ) == null )
{
return Optional.of( String.format( "Unknown turtle upgrade crafted with '%s'.", stack ) );
}
return Optional.empty();
}
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.integration.crafttweaker.actions;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.shared.TurtleUpgrades;
import java.util.Optional;
/**
* Removes a turtle upgrade with the given id.
*/
public class RemoveTurtleUpgradeByName implements IAction
{
private final String id;
public RemoveTurtleUpgradeByName( String id )
{
this.id = id;
}
@Override
public void apply()
{
ITurtleUpgrade upgrade = TurtleUpgrades.get( id );
if( upgrade != null ) TurtleUpgrades.disable( upgrade );
}
@Override
public String describe()
{
return String.format( "Remove turtle upgrade '%s'", id );
}
@Override
public Optional<String> getValidationProblem()
{
if( TurtleUpgrades.get( id ) == null )
{
return Optional.of( String.format( "Unknown turtle upgrade '%s'.", id ) );
}
return Optional.empty();
}
}

View File

@ -7,6 +7,7 @@
package dan200.computercraft.shared.turtle.upgrades;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
public class TurtleAxe extends TurtleTool
@ -21,6 +22,11 @@ public TurtleAxe( ResourceLocation id, Item item )
super( id, item );
}
public TurtleAxe( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
{
super( id, craftItem, toolItem );
}
@Override
protected float getDamageMultiplier()
{

View File

@ -35,6 +35,11 @@ public TurtleHoe( ResourceLocation id, Item item )
super( id, item );
}
public TurtleHoe( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
{
super( id, craftItem, toolItem );
}
@Override
protected boolean canBreakBlock( BlockState state, World world, BlockPos pos, TurtlePlayer player )
{

View File

@ -35,6 +35,11 @@ public TurtleShovel( ResourceLocation id, Item item )
super( id, item );
}
public TurtleShovel( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
{
super( id, craftItem, toolItem );
}
@Override
protected boolean canBreakBlock( BlockState state, World world, BlockPos pos, TurtlePlayer player )
{

View File

@ -10,6 +10,7 @@
import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@ -26,6 +27,11 @@ public TurtleSword( ResourceLocation id, Item item )
super( id, item );
}
public TurtleSword( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
{
super( id, craftItem, toolItem );
}
@Override
protected boolean canBreakBlock( BlockState state, World world, BlockPos pos, TurtlePlayer player )
{

View File

@ -63,6 +63,12 @@ public TurtleTool( ResourceLocation id, Item item )
this.item = new ItemStack( item );
}
public TurtleTool( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
{
super( id, -1, TurtleUpgradeType.Tool, craftItem );
this.item = toolItem;
}
@Nonnull
@Override
@OnlyIn( Dist.CLIENT )
@ -77,7 +83,7 @@ public Pair<IBakedModel, Matrix4f> getModel( ITurtleAccess turtle, @Nonnull Turt
);
Minecraft mc = Minecraft.getInstance();
return Pair.of(
mc.getItemRenderer().getItemModelMesher().getItemModel( item ),
mc.getItemRenderer().getItemModelMesher().getItemModel( getCraftingItem() ),
transform
);
}

View File

@ -93,7 +93,7 @@ if _VERSION == "Lua 5.1" then
bxor = bit32.bxor,
brshift = bit32.arshift,
blshift = bit32.lshift,
blogic_rshift = bit32.rshift
blogic_rshift = bit32.rshift,
}
end
end
@ -184,7 +184,7 @@ function sleep( nTime )
expect(1, nTime, "number", "nil")
local timer = os.startTimer( nTime or 0 )
repeat
local sEvent, param = os.pullEvent( "timer" )
local _, param = os.pullEvent( "timer" )
until param == timer
end
@ -207,13 +207,13 @@ function write( sText )
end
-- Print the line with proper word wrapping
while string.len(sText) > 0 do
while #sText > 0 do
local whitespace = string.match( sText, "^[ \t]+" )
if whitespace then
-- Print whitespace
term.write( whitespace )
x, y = term.getCursorPos()
sText = string.sub( sText, string.len(whitespace) + 1 )
sText = string.sub( sText, #whitespace + 1 )
end
local newline = string.match( sText, "^\n" )
@ -225,20 +225,20 @@ function write( sText )
local text = string.match( sText, "^[^ \t\n]+" )
if text then
sText = string.sub( sText, string.len(text) + 1 )
if string.len(text) > w then
sText = string.sub( sText, #text + 1 )
if #text > w then
-- Print a multiline word
while string.len( text ) > 0 do
while #text > 0 do
if x > w then
newLine()
end
term.write( text )
text = string.sub( text, (w-x) + 2 )
text = string.sub( text, w - x + 2 )
x, y = term.getCursorPos()
end
else
-- Print a word normally
if x + string.len(text) - 1 > w then
if x + #text - 1 > w then
newLine()
end
term.write( text )
@ -299,7 +299,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
local tCompletions
local nCompletion
local function recomplete()
if _fnComplete and nPos == string.len(sLine) then
if _fnComplete and nPos == #sLine then
tCompletions = _fnComplete( sLine )
if tCompletions and #tCompletions > 0 then
nCompletion = 1
@ -332,7 +332,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
local _, cy = term.getCursorPos()
term.setCursorPos( sx, cy )
local sReplace = (_bClear and " ") or _sReplaceChar
local sReplace = _bClear and " " or _sReplaceChar
if sReplace then
term.write( string.rep( sReplace, math.max( #sLine - nScroll, 0 ) ) )
else
@ -544,7 +544,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
end
end
local cx, cy = term.getCursorPos()
local _, cy = term.getCursorPos()
term.setCursorBlink( false )
term.setCursorPos( w + 1, cy )
print()
@ -680,7 +680,8 @@ if http then
local methods = {
GET = true, POST = true, HEAD = true,
OPTIONS = true, PUT = true, DELETE = true
OPTIONS = true, PUT = true, DELETE = true,
PATCH = true, TRACE = true,
}
local function checkKey( options, key, ty, opt )
@ -775,7 +776,7 @@ if http then
if not ok then return ok, err end
while true do
local event, url, ok, err = os.pullEvent( "http_check" )
local _, url, ok, err = os.pullEvent( "http_check" )
if url == _url then return ok, err end
end
end
@ -808,8 +809,8 @@ function fs.complete( sPath, sLocation, bIncludeFiles, bIncludeDirs )
expect(3, bIncludeFiles, "boolean", "nil")
expect(4, bIncludeDirs, "boolean", "nil")
bIncludeFiles = (bIncludeFiles ~= false)
bIncludeDirs = (bIncludeDirs ~= false)
bIncludeFiles = bIncludeFiles ~= false
bIncludeDirs = bIncludeDirs ~= false
local sDir = sLocation
local nStart = 1
local nSlash = string.find( sPath, "[/\\]", nStart )
@ -836,9 +837,9 @@ function fs.complete( sPath, sLocation, bIncludeFiles, bIncludeDirs )
end
if sDir ~= "" then
if sPath == "" then
table.insert( tResults, (bIncludeDirs and "..") or "../" )
table.insert( tResults, bIncludeDirs and ".." or "../" )
elseif sPath == "." then
table.insert( tResults, (bIncludeDirs and ".") or "./" )
table.insert( tResults, bIncludeDirs and "." or "./" )
end
end
local tFiles = fs.list( sDir )
@ -867,7 +868,7 @@ end
-- Load APIs
local bAPIError = false
local tApis = fs.list( "rom/apis" )
for n,sFile in ipairs( tApis ) do
for _, sFile in ipairs( tApis ) do
if string.sub( sFile, 1, 1 ) ~= "." then
local sPath = fs.combine( "rom/apis", sFile )
if not fs.isDir( sPath ) then
@ -881,7 +882,7 @@ end
if turtle and fs.isDir( "rom/apis/turtle" ) then
-- Load turtle APIs
local tApis = fs.list( "rom/apis/turtle" )
for n,sFile in ipairs( tApis ) do
for _, sFile in ipairs( tApis ) do
if string.sub( sFile, 1, 1 ) ~= "." then
local sPath = fs.combine( "rom/apis/turtle", sFile )
if not fs.isDir( sPath ) then
@ -896,7 +897,7 @@ end
if pocket and fs.isDir( "rom/apis/pocket" ) then
-- Load pocket APIs
local tApis = fs.list( "rom/apis/pocket" )
for n,sFile in ipairs( tApis ) do
for _, sFile in ipairs( tApis ) do
if string.sub( sFile, 1, 1 ) ~= "." then
local sPath = fs.combine( "rom/apis/pocket", sFile )
if not fs.isDir( sPath ) then
@ -925,7 +926,7 @@ if commands and fs.isDir( "rom/apis/command" ) then
end
end
return nil
end
end,
}
setmetatable( commands, tCaseInsensitiveMetatable )
setmetatable( commands.async, tCaseInsensitiveMetatable )
@ -946,7 +947,7 @@ end
-- Set default settings
settings.set( "shell.allow_startup", true )
settings.set( "shell.allow_disk_startup", (commands == nil) )
settings.set( "shell.allow_disk_startup", commands == nil )
settings.set( "shell.autocomplete", true )
settings.set( "edit.autocomplete", true )
settings.set( "edit.default_extension", "lua" )

View File

@ -62,7 +62,7 @@ end
function stopAudio( name )
if not name then
for n,sName in ipairs( peripheral.getNames() ) do
for _, sName in ipairs( peripheral.getNames() ) do
stopAudio( sName )
end
else

View File

@ -13,7 +13,7 @@ local function trilaterate( A, B, C )
local d = a2b:length()
local ex = a2b:normalize( )
local i = ex:dot( a2c )
local ey = (a2c - (ex * i)):normalize()
local ey = (a2c - ex * i):normalize()
local j = ey:dot( a2c )
local ez = ex:cross( ey )
@ -24,13 +24,13 @@ local function trilaterate( A, B, C )
local x = (r1 * r1 - r2 * r2 + d * d) / (2 * d)
local y = (r1 * r1 - r3 * r3 - x * x + (x - i) * (x - i) + j * j) / (2 * j)
local result = A.vPosition + (ex * x) + (ey * y)
local result = A.vPosition + ex * x + ey * y
local zSquared = r1 * r1 - x * x - y * y
if zSquared > 0 then
local z = math.sqrt( zSquared )
local result1 = result + (ez * z)
local result2 = result - (ez * z)
local result1 = result + ez * z
local result2 = result - ez * z
local rounded1, rounded2 = result1:round( 0.01 ), result2:round( 0.01 )
if rounded1.x ~= rounded2.x or rounded1.y ~= rounded2.y or rounded1.z ~= rounded2.z then
@ -66,7 +66,7 @@ function locate( _nTimeout, _bDebug )
-- Find a modem
local sModemSide = nil
for n,sSide in ipairs( rs.getSides() ) do
for _, sSide in ipairs( rs.getSides() ) do
if peripheral.getType( sSide ) == "modem" and peripheral.call( sSide, "isWireless" ) then
sModemSide = sSide
break

View File

@ -30,14 +30,14 @@ end
function topics()
-- Add index
local tItems = {
[ "index" ] = true
[ "index" ] = true,
}
-- Add topics from the path
for sPath in string.gmatch(sPath, "[^:]+") do
if fs.isDir( sPath ) then
local tList = fs.list( sPath )
for n,sFile in pairs( tList ) do
for _, sFile in pairs( tList ) do
if string.sub( sFile, 1, 1 ) ~= "." then
if not fs.isDir( fs.combine( sPath, sFile ) ) then
if #sFile > 4 and sFile:sub(-4) == ".txt" then
@ -52,7 +52,7 @@ function topics()
-- Sort and return
local tItemList = {}
for sItem, b in pairs( tItems ) do
for sItem in pairs( tItems ) do
table.insert( tItemList, sItem )
end
table.sort( tItemList )

View File

@ -129,11 +129,11 @@ handleMetatable = {
}
local defaultInput = setmetatable({
_handle = { readLine = _G.read }
_handle = { readLine = _G.read },
}, handleMetatable)
local defaultOutput = setmetatable({
_handle = { write = _G.write }
_handle = { write = _G.write },
}, handleMetatable)
local defaultError = setmetatable({
@ -147,7 +147,7 @@ local defaultError = setmetatable({
_G.write(...)
if term.isColour() then term.setTextColour(oldColour) end
end,
}
},
}, handleMetatable)
local currentInput = defaultInput

View File

@ -147,8 +147,8 @@ function drawBox( startX, startY, endX, endY, nColour )
drawPixelInternal( x, maxY )
end
if (maxY - minY) >= 2 then
for y=(minY+1),(maxY-1) do
if maxY - minY >= 2 then
for y = minY + 1, maxY - 1 do
drawPixelInternal( minX, y )
drawPixelInternal( maxX, y )
end

View File

@ -4,12 +4,12 @@ local native = peripheral
function getNames()
local tResults = {}
for n,sSide in ipairs( rs.getSides() ) do
for _, sSide in ipairs( rs.getSides() ) do
if native.isPresent( sSide ) then
table.insert( tResults, sSide )
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
local tRemote = native.call( sSide, "getNamesRemote" )
for n,sName in ipairs( tRemote ) do
for _, sName in ipairs( tRemote ) do
table.insert( tResults, sName )
end
end
@ -23,7 +23,7 @@ function isPresent( _sSide )
if native.isPresent( _sSide ) then
return true
end
for n,sSide in ipairs( rs.getSides() ) do
for _, sSide in ipairs( rs.getSides() ) do
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
if native.call( sSide, "isPresentRemote", _sSide ) then
return true
@ -38,7 +38,7 @@ function getType( _sSide )
if native.isPresent( _sSide ) then
return native.getType( _sSide )
end
for n,sSide in ipairs( rs.getSides() ) do
for _, sSide in ipairs( rs.getSides() ) do
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
if native.call( sSide, "isPresentRemote", _sSide ) then
return native.call( sSide, "getTypeRemote", _sSide )
@ -53,7 +53,7 @@ function getMethods( _sSide )
if native.isPresent( _sSide ) then
return native.getMethods( _sSide )
end
for n,sSide in ipairs( rs.getSides() ) do
for _, sSide in ipairs( rs.getSides() ) do
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
if native.call( sSide, "isPresentRemote", _sSide ) then
return native.call( sSide, "getMethodsRemote", _sSide )
@ -69,7 +69,7 @@ function call( _sSide, _sMethod, ... )
if native.isPresent( _sSide ) then
return native.call( _sSide, _sMethod, ... )
end
for n,sSide in ipairs( rs.getSides() ) do
for _, sSide in ipairs( rs.getSides() ) do
if native.getType( sSide ) == "modem" and not native.call( sSide, "isWireless" ) then
if native.call( sSide, "isPresentRemote", _sSide ) then
return native.call( sSide, "callRemote", _sSide, _sMethod, ... )
@ -84,7 +84,7 @@ function wrap( _sSide )
if peripheral.isPresent( _sSide ) then
local tMethods = peripheral.getMethods( _sSide )
local tResult = {}
for n,sMethod in ipairs( tMethods ) do
for _, sMethod in ipairs( tMethods ) do
tResult[sMethod] = function( ... )
return peripheral.call( _sSide, sMethod, ... )
end
@ -98,7 +98,7 @@ function find( sType, fnFilter )
expect(1, sType, "string")
expect(2, fnFilter, "function", "nil")
local tResults = {}
for n,sName in ipairs( peripheral.getNames() ) do
for _, sName in ipairs( peripheral.getNames() ) do
if peripheral.getType( sName ) == sType then
local wrapped = peripheral.wrap( sName )
if fnFilter == nil or fnFilter( sName, wrapped ) then

View File

@ -27,7 +27,7 @@ function close( sModem )
peripheral.call( sModem, "close", CHANNEL_BROADCAST )
else
-- Close all modems
for n,sModem in ipairs( peripheral.getNames() ) do
for _, sModem in ipairs( peripheral.getNames() ) do
if isOpen( sModem ) then
close( sModem )
end
@ -44,7 +44,7 @@ function isOpen( sModem )
end
else
-- Check if any modem is open
for n,sModem in ipairs( peripheral.getNames() ) do
for _, sModem in ipairs( peripheral.getNames() ) do
if isOpen( sModem ) then
return true
end
@ -79,10 +79,10 @@ function send( nRecipient, message, sProtocol )
sent = true
else
-- Send on all open modems, to the target and to repeaters
for n,sModem in ipairs( peripheral.getNames() ) do
for _, sModem in ipairs( peripheral.getNames() ) do
if isOpen( sModem ) then
peripheral.call( sModem, "transmit", nRecipient, nReplyChannel, tMessage );
peripheral.call( sModem, "transmit", CHANNEL_REPEAT, nReplyChannel, tMessage );
peripheral.call( sModem, "transmit", nRecipient, nReplyChannel, tMessage )
peripheral.call( sModem, "transmit", CHANNEL_REPEAT, nReplyChannel, tMessage )
sent = true
end
end

View File

@ -47,7 +47,7 @@ end
function getNames()
local result = {}
for k,v in pairs( tSettings ) do
for k in pairs( tSettings ) do
result[ #result + 1 ] = k
end
table.sort(result)

View File

@ -1,6 +1,6 @@
local expect = dofile("rom/modules/main/cc/expect.lua").expect
local native = (term.native and term.native()) or term
local native = term.native and term.native() or term
local redirectTarget = native
local function wrap( _sFunction )

View File

@ -10,13 +10,13 @@ function slowWrite( sText, nRate )
sText = tostring( sText )
local x, y = term.getCursorPos()
local len = string.len( sText )
local len = #sText
for n = 1, len do
term.setCursorPos( x, y )
sleep( nSleep )
local nLines = write( string.sub( sText, 1, n ) )
local newX, newY = term.getCursorPos()
local _, newY = term.getCursorPos()
y = newY - nLines
end
end
@ -54,11 +54,11 @@ local function makePagedScroll( _term, _nFreeLines )
local nativeScroll = _term.scroll
local nFreeLines = _nFreeLines or 0
return function( _n )
for n=1,_n do
for _ = 1, _n do
nativeScroll( 1 )
if nFreeLines <= 0 then
local w,h = _term.getSize()
local _, h = _term.getSize()
_term.setCursorPos( 1, h )
_term.write( "Press any key to continue" )
os.pullEvent( "key" )
@ -116,14 +116,14 @@ local function tabulateCommon( bPaged, ... )
if type( sItem ) ~= "string" then
error( "bad argument #" .. n .. "." .. nu .. " (expected string, got " .. type( sItem ) .. ")", 3 )
end
nMaxLen = math.max( string.len( sItem ) + 1, nMaxLen )
nMaxLen = math.max( #sItem + 1, nMaxLen )
end
end
end
local nCols = math.floor( w / nMaxLen )
local nLines = 0
local function newLine()
if bPaged and nLines >= (h-3) then
if bPaged and nLines >= h - 3 then
pagedPrint()
else
print()
@ -133,14 +133,14 @@ local function tabulateCommon( bPaged, ... )
local function drawCols( _t )
local nCol = 1
for n, s in ipairs( _t ) do
for _, s in ipairs( _t ) do
if nCol > nCols then
nCol = 1
newLine()
end
local cx, cy = term.getCursorPos()
cx = 1 + ((nCol - 1) * nMaxLen)
cx = 1 + (nCol - 1) * nMaxLen
term.setCursorPos( cx, cy )
term.write( s )
@ -148,7 +148,7 @@ local function tabulateCommon( bPaged, ... )
end
print()
end
for n, t in ipairs( tAll ) do
for _, t in ipairs( tAll ) do
if type(t) == "table" then
if #t > 0 then
drawCols( t )
@ -241,7 +241,7 @@ end
empty_json_array = setmetatable({}, {
__newindex = function()
error("attempt to mutate textutils.empty_json_array", 2)
end
end,
})
local function serializeJSONImpl( t, tTracking, bNBTStyle )
@ -280,7 +280,7 @@ local function serializeJSONImpl( t, tTracking, bNBTStyle )
nObjectSize = nObjectSize + 1
end
end
for n,v in ipairs(t) do
for _, v in ipairs(t) do
local sEntry = serializeJSONImpl( v, tTracking, bNBTStyle )
if nArraySize == 0 then
sArrayResult = sArrayResult .. sEntry
@ -388,7 +388,7 @@ function complete( sSearchText, tSearchTable )
end
local sPart = string.sub( sSearchText, nStart )
local nPartLength = string.len( sPart )
local nPartLength = #sPart
local tResults = {}
local tSeen = {}

View File

@ -54,9 +54,9 @@ local vector = {
round = function( self, nTolerance )
nTolerance = nTolerance or 1.0
return vector.new(
math.floor( (self.x + (nTolerance * 0.5)) / nTolerance ) * nTolerance,
math.floor( (self.y + (nTolerance * 0.5)) / nTolerance ) * nTolerance,
math.floor( (self.z + (nTolerance * 0.5)) / nTolerance ) * nTolerance
math.floor( (self.x + nTolerance * 0.5) / nTolerance ) * nTolerance,
math.floor( (self.y + nTolerance * 0.5) / nTolerance ) * nTolerance,
math.floor( (self.z + nTolerance * 0.5) / nTolerance ) * nTolerance
)
end,
tostring = function( self )
@ -78,7 +78,7 @@ function new( x, y, z )
local v = {
x = tonumber(x) or 0,
y = tonumber(y) or 0,
z = tonumber(z) or 0
z = tonumber(z) or 0,
}
setmetatable( v, vmetatable )
return v

View File

@ -49,7 +49,7 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
createEmptyLines( nWidth )
-- Setup
local bVisible = (bStartVisible ~= false)
local bVisible = bStartVisible ~= false
local nCursorX = 1
local nCursorY = 1
local bCursorBlink = false
@ -456,7 +456,7 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
tNewLines[y] = {
text = sEmptyText,
textColor = sEmptyTextColor,
backgroundColor = sEmptyBackgroundColor
backgroundColor = sEmptyBackgroundColor,
}
else
local tOldLine = tLines[y]

View File

@ -1,3 +1,12 @@
# New features in CC: Tweaked 1.86.0
* Add PATCH and TRACE HTTP methods. (jaredallard)
* Add more MOTD messages. (JakobDev)
* Allow removing and adding turtle upgrades via CraftTweaker.
And several bug fixes:
* Fix crash when interacting with Wearable Backpacks.
# New features in CC: Tweaked 1.85.2
* Fix crashes when using the mouse with advanced computers.

View File

@ -1,5 +1,10 @@
New features in CC: Tweaked 1.85.2
New features in CC: Tweaked 1.86.0
* Fix crashes when using the mouse with advanced computers.
* Add PATCH and TRACE HTTP methods. (jaredallard)
* Add more MOTD messages. (JakobDev)
* Allow removing and adding turtle upgrades via CraftTweaker.
And several bug fixes:
* Fix crash when interacting with Wearable Backpacks.
Type "help changelog" to see the full version history.

View File

@ -1,7 +1,7 @@
View the source code at https://github.com/SquidDev-CC/CC-Tweaked
View the documentation at https://wiki.computercraft.cc
Visit the forum at https://forums.computercraft.cc
You can disable these messages by running "set motd.enable false"
You can disable these messages by running "set motd.enable false".
You can create directories with "mkdir".
Want to see hidden files? Run "set list.show_hidden true".
Run "list" or "ls" to see all files in a directory.
@ -13,3 +13,22 @@ Use the "edit" program to create and edit your programs.
You can copy files with "copy" or "cp".
You can use "wget run <url>" to run a program from the internet.
You can use "wget" to download a file from the internet.
On an advanced computer you can use "fg" or "bg" to run multiple programs at the same time.
Use "type" to see if a path is a file or a directory.
Get a list of all programs with "programs".
Use an advanced computer to use colours and the mouse.
With a speaker you can play sounds.
Use "motd" to print the Message of the Day.
You can disable the startup from a computer with "set shell.allow_startup false".
You can disable the startup from a disk with "set shell.allow_disk_startup false".
Programs that are placed in the "startup" folder in the root of a computer are started on boot.
Use a modem to connect with other computers.
With the "gps" program you can get the position of a computer.
Use "monitor" to run a program on a attached monitor.
View all attached peripherals with "peripherals".
Use "time" to see the in-game time.
You can set the label of a computer with "label set".
A computer needs a label to keep its files if it got destroyed.
You can disable auto completion in the shell with "set shell.autocomplete false".
You can disable auto completion in edit with "set edit.autocomplete false".
Feeling creative? Use a printer to print a book!

View File

@ -172,7 +172,6 @@ local function resizeWindows()
end
for n = 1, #tProcesses do
local tProcess = tProcesses[n]
local window = tProcess.window
local x, y = tProcess.window.getCursorPos()
if y > windowHeight then
tProcess.window.scroll( y - windowHeight )
@ -232,7 +231,7 @@ function multishell.launch( tProgramEnv, sProgramPath, ... )
expect(1, tProgramEnv, "table")
expect(2, sProgramPath, "string")
local previousTerm = term.current()
setMenuVisible( (#tProcesses + 1) >= 2 )
setMenuVisible( #tProcesses + 1 >= 2 )
local nResult = launchProcess( false, tProgramEnv, sProgramPath, ... )
redrawMenu()
term.redirect( previousTerm )
@ -288,7 +287,7 @@ while #tProcesses > 0 do
tabStart = 2
end
for n = nScrollPos, #tProcesses do
local tabEnd = tabStart + string.len( tProcesses[n].sTitle ) + 1
local tabEnd = tabStart + #tProcesses[n].sTitle + 1
if x >= tabStart and x <= tabEnd then
selectProcess( n )
redrawMenu()
@ -299,7 +298,7 @@ while #tProcesses > 0 do
end
else
-- Passthrough to current process
resumeProcess( nCurrentProcess, sEvent, button, x, (bShowMenu and y-1) or y )
resumeProcess( nCurrentProcess, sEvent, button, x, bShowMenu and y - 1 or y )
if cullProcess( nCurrentProcess ) then
setMenuVisible( #tProcesses >= 2 )
redrawMenu()
@ -319,7 +318,7 @@ while #tProcesses > 0 do
end
elseif not (bShowMenu and y == 1) then
-- Passthrough to current process
resumeProcess( nCurrentProcess, sEvent, p1, x, (bShowMenu and y-1) or y )
resumeProcess( nCurrentProcess, sEvent, p1, x, bShowMenu and y - 1 or y )
if cullProcess( nCurrentProcess ) then
setMenuVisible( #tProcesses >= 2 )
redrawMenu()

View File

@ -9,7 +9,7 @@ local sSource = shell.resolve( tArgs[1] )
local sDest = shell.resolve( tArgs[2] )
local tFiles = fs.find( sSource )
if #tFiles > 0 then
for n,sFile in ipairs( tFiles ) do
for _, sFile in ipairs( tFiles ) do
if fs.isDir( sDest ) then
fs.copy( sFile, fs.combine( sDest, fs.getName(sFile) ) )
elseif #tFiles == 1 then

View File

@ -8,7 +8,7 @@ end
for i = 1, args.n do
local files = fs.find(shell.resolve(args[i]))
if #files > 0 then
for n, file in ipairs(files) do
for _, file in ipairs(files) do
local ok, err = pcall(fs.delete, file)
if not ok then
printError((err:gsub("^pcall: ", "")))

View File

@ -10,9 +10,9 @@ if fs.exists( sPath ) then
write( fs.getDrive( sPath ) .. " (" )
local nSpace = fs.getFreeSpace( sPath )
if nSpace >= 1000 * 1000 then
print( (math.floor( nSpace / (100 * 1000) ) / 10) .. "MB remaining)" )
print( math.floor( nSpace / (100 * 1000) ) / 10 .. "MB remaining)" )
elseif nSpace >= 1000 then
print( (math.floor( nSpace / 100 ) / 10) .. "KB remaining)" )
print( math.floor( nSpace / 100 ) / 10 .. "KB remaining)" )
else
print( nSpace .. "B remaining)" )
end

View File

@ -62,7 +62,7 @@ end
table.insert( tMenuItems, "Exit" )
local sStatus = "Press Ctrl to access menu"
if string.len( sStatus ) > w - 5 then
if #sStatus > w - 5 then
sStatus = "Press Ctrl for menu"
end
@ -95,7 +95,7 @@ local function save( _sPath )
local function innerSave()
file, fileerr = fs.open( _sPath, "w" )
if file then
for n, sLine in ipairs( tLines ) do
for _, sLine in ipairs( tLines ) do
file.write( sLine .. "\n" )
end
else
@ -144,13 +144,13 @@ local function tryWrite( sLine, regex, colour )
end
term.write( match )
term.setTextColour( textColour )
return string.sub( sLine, string.len(match) + 1 )
return string.sub( sLine, #match + 1 )
end
return nil
end
local function writeHighlighted( sLine )
while string.len(sLine) > 0 do
while #sLine > 0 do
sLine =
tryWrite( sLine, "^%-%-%[%[.-%]%]", commentColour ) or
tryWrite( sLine, "^%-%-.*", commentColour ) or
@ -188,7 +188,7 @@ end
local function recomplete()
local sLine = tLines[y]
if not bMenu and not bReadOnly and x == string.len(sLine) + 1 then
if not bMenu and not bReadOnly and x == #sLine + 1 then
tCompletions = complete( sLine )
if tCompletions and #tCompletions > 0 then
nCompletion = 1
@ -248,7 +248,7 @@ local function redrawMenu()
term.clearLine()
-- Draw line numbers
term.setCursorPos( w - string.len( "Ln "..y ) + 1, h )
term.setCursorPos( w - #( "Ln " .. y ) + 1, h )
term.setTextColour( highlightColour )
term.write( "Ln " )
term.setTextColour( textColour )
@ -287,7 +287,7 @@ local tMenuFuncs = {
if bReadOnly then
sStatus = "Access denied"
else
local ok, err, fileerr = save( sPath )
local ok, _, fileerr = save( sPath )
if ok then
sStatus = "Saved to " .. sPath
else
@ -357,7 +357,7 @@ local tMenuFuncs = {
term.redirect( printerTerminal )
local ok, error = pcall( function()
term.scroll()
for n, sLine in ipairs( tLines ) do
for _, sLine in ipairs( tLines ) do
print( sLine )
end
end )
@ -385,7 +385,7 @@ local tMenuFuncs = {
end,
Run = function()
local sTempPath = "/.temp"
local ok, err = save( sTempPath )
local ok = save( sTempPath )
if ok then
local nTask = shell.openTab( sTempPath )
if nTask then
@ -398,7 +398,7 @@ local tMenuFuncs = {
sStatus = "Error saving to " .. sTempPath
end
redrawMenu()
end
end,
}
local function doMenuItem( _n )
@ -411,7 +411,7 @@ local function doMenuItem( _n )
end
local function setCursor( newX, newY )
local oldX, oldY = x, y
local _, oldY = x, y
x, y = newX, newY
local screenX = x - scrollX
local screenY = y - scrollY
@ -468,7 +468,7 @@ local function acceptCompletion()
-- Append the completion
local sCompletion = tCompletions[ nCompletion ]
tLines[y] = tLines[y] .. sCompletion
setCursor( x + string.len( sCompletion ), y )
setCursor( x + #sCompletion , y )
end
end
@ -476,7 +476,6 @@ end
while bRunning do
local sEvent, param, param2, param3 = os.pullEvent()
if sEvent == "key" then
local oldX, oldY = x, y
if param == keys.up then
-- Up
if not bMenu then
@ -491,7 +490,7 @@ while bRunning do
elseif y > 1 then
-- Move cursor up
setCursor(
math.min( x, string.len( tLines[y - 1] ) + 1 ),
math.min( x, #tLines[y - 1] + 1 ),
y - 1
)
end
@ -512,7 +511,7 @@ while bRunning do
elseif y < #tLines then
-- Move cursor down
setCursor(
math.min( x, string.len( tLines[y + 1] ) + 1 ),
math.min( x, #tLines[y + 1] + 1 ),
y + 1
)
end
@ -521,7 +520,7 @@ while bRunning do
elseif param == keys.tab then
-- Tab
if not bMenu and not bReadOnly then
if nCompletion and x == string.len(tLines[y]) + 1 then
if nCompletion and x == #tLines[y] + 1 then
-- Accept autocomplete
acceptCompletion()
else
@ -543,7 +542,7 @@ while bRunning do
newY = 1
end
setCursor(
math.min( x, string.len( tLines[newY] ) + 1 ),
math.min( x, #tLines[newY] + 1 ),
newY
)
end
@ -558,7 +557,7 @@ while bRunning do
else
newY = #tLines
end
local newX = math.min( x, string.len( tLines[newY] ) + 1 )
local newX = math.min( x, #tLines[newY] + 1 )
setCursor( newX, newY )
end
@ -575,7 +574,7 @@ while bRunning do
-- End
if not bMenu then
-- Move cursor to the end
local nLimit = string.len( tLines[y] ) + 1
local nLimit = #tLines[y] + 1
if x < nLimit then
setCursor( nLimit, y )
end
@ -588,7 +587,7 @@ while bRunning do
-- Move cursor left
setCursor( x - 1, y )
elseif x == 1 and y > 1 then
setCursor( string.len( tLines[y-1] ) + 1, y - 1 )
setCursor( #tLines[y - 1] + 1, y - 1 )
end
else
-- Move menu left
@ -602,11 +601,11 @@ while bRunning do
elseif param == keys.right then
-- Right
if not bMenu then
local nLimit = string.len( tLines[y] ) + 1
local nLimit = #tLines[y] + 1
if x < nLimit then
-- Move cursor right
setCursor( x + 1, y )
elseif nCompletion and x == string.len(tLines[y]) + 1 then
elseif nCompletion and x == #tLines[y] + 1 then
-- Accept autocomplete
acceptCompletion()
elseif x == nLimit and y < #tLines then
@ -625,7 +624,7 @@ while bRunning do
elseif param == keys.delete then
-- Delete
if not bMenu and not bReadOnly then
local nLimit = string.len( tLines[y] ) + 1
local nLimit = #tLines[y] + 1
if x < nLimit then
local sLine = tLines[y]
tLines[y] = string.sub(sLine, 1, x - 1) .. string.sub(sLine, x + 1)
@ -654,7 +653,7 @@ while bRunning do
end
elseif y > 1 then
-- Remove newline
local sPrevLen = string.len( tLines[y-1] )
local sPrevLen = #tLines[y - 1]
tLines[y - 1] = tLines[y - 1] .. tLines[y]
table.remove( tLines, y )
setCursor( sPrevLen + 1, y - 1 )
@ -722,7 +721,7 @@ while bRunning do
-- Input text
local sLine = tLines[y]
tLines[y] = string.sub(sLine, 1, x - 1) .. param .. string.sub(sLine, x)
setCursor( x + string.len( param ), y )
setCursor( x + #param , y )
end
elseif sEvent == "mouse_click" then
@ -732,7 +731,7 @@ while bRunning do
local cx, cy = param2, param3
if cy < h then
local newY = math.min( math.max( scrollY + cy, 1 ), #tLines )
local newX = math.min( math.max( scrollX + cx, 1 ), string.len( tLines[newY] ) + 1 )
local newX = math.min( math.max( scrollX + cx, 1 ), #tLines[newY] + 1 )
setCursor( newX, newY )
end
end

View File

@ -148,7 +148,7 @@ local function save(path)
end
sLine = string.sub( sLine, 1, nLastChar )
tLines[y] = sLine
if string.len( sLine ) > 0 then
if #sLine > 0 then
nLastLine = y
end
end
@ -186,8 +186,8 @@ local function drawInterface()
term.write("\127\127")
-- Left and Right Selected Colours
for i=18,18 do
term.setCursorPos(w-1, i)
do
term.setCursorPos(w - 1, 18)
if leftColour ~= nil then
term.setBackgroundColour( leftColour )
term.write(" ")
@ -269,7 +269,7 @@ local function accessMenu()
for k, v in pairs(mChoices) do
if selection == k then
term.setTextColour(colours.yellow)
local ox,_ = term.getCursorPos()
local ox = term.getCursorPos()
term.write("[" .. string.rep(" ", #v) .. "]")
term.setCursorPos(ox + 1, h)
term.setTextColour(colours.white)

View File

@ -60,14 +60,14 @@ local tArgs = { ... }
--Functions--
local function printCentred( yc, stg )
local xc = math.floor((TermW - string.len(stg)) / 2) + 1
local xc = math.floor((TermW - #stg) / 2) + 1
term.setCursorPos(xc, yc)
term.write( stg )
end
local function centerOrgin()
XOrgin = math.floor((TermW/2)-(SizeW/2))
YOrgin = math.floor((TermH/2)-(SizeH/2))
XOrgin = math.floor(TermW / 2 - SizeW / 2)
YOrgin = math.floor(TermH / 2 - SizeH / 2)
end
local function reMap()
@ -177,10 +177,9 @@ local function loadLevel(nNum)
local sLevelD = sDir .. "/levels/" .. tostring(nNum) .. ".dat"
if not ( fs.exists(sLevelD) or fs.isDir(sLevelD) ) then return error("Level Not Exists : " .. sLevelD) end
fLevel = fs.open(sLevelD, "r")
local Line = 0
local wl = true
Blocks = tonumber(string.sub(fLevel.readLine(), 1, 1))
local xSize = string.len(fLevel.readLine())+2
local xSize = #fLevel.readLine() + 2
local Lines = 3
while wl do
local wLine = fLevel.readLine()
@ -188,7 +187,7 @@ local function loadLevel(nNum)
fLevel.close()
wl = false
else
xSize = math.max(string.len(wLine)+2,xSize)
xSize = math.max(#wLine + 2, xSize)
Lines = Lines + 1
end
end
@ -198,7 +197,7 @@ local function loadLevel(nNum)
fLevel.readLine()
for Line = 2, Lines - 1 do
local sLine = fLevel.readLine()
local chars = string.len(sLine)
local chars = #sLine
for char = 1, chars do
local el = string.sub(sLine, char, char)
if el == "8" then
@ -557,7 +556,7 @@ function InterFace.render()
elseif p3 == TermH and p2 >= TermW - 4 and p2 <= TermW - 3 then
bPaused = not bPaused
fSpeedS = false
Speed = (bPaused and 0) or nSpeed
Speed = bPaused and 0 or nSpeed
if Speed > 0 then
Tick = os.startTimer(Speed)
else
@ -567,7 +566,7 @@ function InterFace.render()
elseif p3 == TermH and p2 >= TermW - 1 then
bPaused = false
fSpeedS = not fSpeedS
Speed = (fSpeedS and fSpeed) or nSpeed
Speed = fSpeedS and fSpeed or nSpeed
Tick = os.startTimer(Speed)
InterFace.drawBar()
elseif p3 - 1 < YOrgin + SizeH + 1 and p3 - 1 > YOrgin and
@ -596,7 +595,6 @@ local function startG(LevelN)
drawStars()
loadLevel(LevelN)
centerOrgin()
local create = true
drawMap()
InterFace.drawBar()
gRender("start")

View File

@ -112,7 +112,7 @@ local items = {
desc = "A perfect handle for torches or a pickaxe.",
},
["a crafting table"] = {
aliases = { "crafting table", "craft table", "work bench", "workbench", "crafting bench", "table", },
aliases = { "crafting table", "craft table", "work bench", "workbench", "crafting bench", "table" },
desc = "It's a crafting table. I shouldn't tell you this, but these don't actually do anything in this game, you can craft tools whenever you like.",
},
["a furnace"] = {
@ -270,7 +270,7 @@ local tAnimals = {
}
local tMonsters = {
"a creeper", "a skeleton", "a zombie", "a spider"
"a creeper", "a skeleton", "a zombie", "a spider",
}
local tRecipes = {
@ -309,7 +309,7 @@ local tGoWest = {
local nGoWest = 0
local bRunning = true
local tMap = { { {}, }, }
local tMap = { { {} } }
local x, y, z = 0, 0, 0
local inventory = {
["no tea"] = items["no tea"],
@ -342,7 +342,7 @@ local function getTimeOfDay()
end
local function isSunny()
return (getTimeOfDay() < 10)
return getTimeOfDay() < 10
end
local function getRoom( x, y, z, dontCreate )
@ -365,7 +365,7 @@ local function getRoom( x, y, z, dontCreate )
-- Add animals
if math.random(1, 3) == 1 then
for n = 1,math.random(1,2) do
for _ = 1, math.random(1, 2) do
local sAnimal = tAnimals[ math.random( 1, #tAnimals ) ]
room.items[ sAnimal ] = items[ sAnimal ]
end
@ -478,7 +478,7 @@ local function findItem( _tList, _sQuery )
return sItem
end
if tItem.aliases ~= nil then
for n, sAlias in pairs( tItem.aliases ) do
for _, sAlias in pairs( tItem.aliases ) do
if sAlias == _sQuery then
return sItem
end
@ -613,7 +613,7 @@ local function doCommand( text )
end
for sCommand, t in pairs( tMatches ) do
for n, sMatch in pairs( t ) do
for _, sMatch in pairs( t ) do
local tCaptures = { string.match( text, "^" .. sMatch .. "$" ) }
if #tCaptures ~= 0 then
local fnCommand = commands[ sCommand ]
@ -679,7 +679,7 @@ function commands.look( _sTarget )
end
if tItem then
print( tItem.desc or ("You see nothing special about "..sItem..".") )
print( tItem.desc or "You see nothing special about " .. sItem .. "." )
else
print( "You don't see any " .. _sTarget .. " here." )
end
@ -752,7 +752,7 @@ function commands.dig( _sDir, _sTool )
tTool = inventory[ sTool ]
end
local bActuallyDigging = (room.exits[ _sDir ] ~= true)
local bActuallyDigging = room.exits[ _sDir ] ~= true
if bActuallyDigging then
if sTool == nil or tTool.toolType ~= "pick" then
print( "You need to use a pickaxe to dig through stone." )
@ -1021,7 +1021,7 @@ function commands.cbreak( _sItem, _sTool )
print( "The " .. tItem.aliases[1] .. " dies." )
if tItem.drops then
for n, sDrop in pairs( tItem.drops ) do
for _, sDrop in pairs( tItem.drops ) do
if not room.items[sDrop] then
print( "The " .. tItem.aliases[1] .. " dropped " .. sDrop .. "." )
room.items[sDrop] = items[sDrop]
@ -1037,7 +1037,7 @@ function commands.cbreak( _sItem, _sTool )
end
if tItem.hitDrops then
for n, sDrop in pairs( tItem.hitDrops ) do
for _, sDrop in pairs( tItem.hitDrops ) do
if not room.items[sDrop] then
print( "The " .. tItem.aliases[1] .. " dropped " .. sDrop .. "." )
room.items[sDrop] = items[sDrop]
@ -1071,18 +1071,17 @@ function commands.craft( _sItem )
return
end
local room = getRoom( x,y,z )
local sItem = findItem( items, _sItem )
local tRecipe = (sItem and tRecipes[ sItem ]) or nil
local tRecipe = sItem and tRecipes[ sItem ] or nil
if tRecipe then
for n,sReq in ipairs( tRecipe ) do
for _, sReq in ipairs( tRecipe ) do
if inventory[sReq] == nil then
print( "You don't have the items you need to craft " .. sItem .. "." )
return
end
end
for n,sReq in ipairs( tRecipe ) do
for _, sReq in ipairs( tRecipe ) do
inventory[sReq] = nil
end
inventory[ sItem ] = items[ sItem ]
@ -1223,7 +1222,7 @@ local function simulate()
-- Spawn monsters
if room.nMonsters < 2 and
((h == 0 and not isSunny() and not room.items["a torch"]) or room.dark) and
(h == 0 and not isSunny() and not room.items["a torch"] or room.dark) and
math.random(1, 6) == 1 then
local sMonster = tMonsters[ math.random(1, #tMonsters) ]
@ -1240,7 +1239,7 @@ local function simulate()
-- Burn monsters
if h == 0 and isSunny() then
for n,sMonster in ipairs( tMonsters ) do
for _, sMonster in ipairs( tMonsters ) do
if room.items[sMonster] and items[sMonster].nocturnal then
room.items[sMonster] = nil
if sx == 0 and sy == 0 and sz == 0 and not room.dark then
@ -1258,10 +1257,10 @@ local function simulate()
-- Make monsters attack
local room = getRoom( x, y, z )
if nTimeInRoom >= 2 and not bNewMonstersThisRoom then
for n,sMonster in ipairs( tMonsters ) do
for _, sMonster in ipairs( tMonsters ) do
if room.items[sMonster] then
if math.random(1, 4) == 1 and
not (y == 0 and isSunny() and (sMonster == "a spider")) then
not (y == 0 and isSunny() and sMonster == "a spider") then
if sMonster == "a creeper" then
if room.dark then
print( "A creeper explodes." )

View File

@ -23,7 +23,7 @@ elseif sCommand == "play" or sCommand == nil then
if sName == nil then
-- No disc specified, pick one at random
local tNames = {}
for n,sName in ipairs( peripheral.getNames() ) do
for _, sName in ipairs( peripheral.getNames() ) do
if disk.isPresent( sName ) and disk.hasAudio( sName ) then
table.insert( tNames, sName )
end

View File

@ -2,15 +2,13 @@
-- Display the start screen
local w, h = term.getSize()
local titleColour, headingColour, textColour, wormColour, fruitColour
local headingColour, textColour, wormColour, fruitColour
if term.isColour() then
titleColour = colours.red
headingColour = colours.yellow
textColour = colours.white
wormColour = colours.green
fruitColour = colours.red
else
titleColour = colours.white
headingColour = colours.white
textColour = colours.white
wormColour = colours.white
@ -18,7 +16,7 @@ else
end
local function printCentred( y, s )
local x = math.floor((w - string.len(s)) / 2)
local x = math.floor((w - #s) / 2)
term.setCursorPos(x, y)
--term.clearLine()
term.write( s )
@ -27,8 +25,6 @@ end
local xVel, yVel = 1, 0
local xPos, yPos = math.floor(w / 2), math.floor(h / 2)
local pxVel, pyVel = nil, nil
local nLength = 1
local nExtraLength = 6
local bRunning = true
@ -58,7 +54,7 @@ local tFruits = {
"q", "r", "s", "t", "u", "v", "w", "x",
"y", "z",
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
"@", "$", "%", "#", "&", "!", "?", "+", "*", "~"
"@", "$", "%", "#", "&", "!", "?", "+", "*", "~",
}
local function addFruit()
@ -103,7 +99,6 @@ local function drawMenu()
end
local function update( )
local x,y = xPos,yPos
if pxVel and pyVel then
xVel, yVel = pxVel, pyVel
pxVel, pyVel = nil, nil
@ -190,7 +185,7 @@ end
drawMenu()
drawFrontend()
while true do
local e,key = os.pullEvent( "key" )
local _, key = os.pullEvent( "key" )
if key == keys.up or key == keys.w then
-- Up
if nDifficulty > 1 then
@ -228,7 +223,7 @@ addFruit()
-- Play the game
local timer = os.startTimer(0)
while bRunning do
local event, p1, p2 = os.pullEvent()
local event, p1 = os.pullEvent()
if event == "timer" and p1 == timer then
timer = os.startTimer(nInterval)
update( false )

View File

@ -28,7 +28,7 @@ elseif sCommand == "host" then
-- Find a modem
local sModemSide = nil
for n,sSide in ipairs( rs.getSides() ) do
for _, sSide in ipairs( rs.getSides() ) do
if peripheral.getType( sSide ) == "modem" and peripheral.call( sSide, "isWireless" ) then
sModemSide = sSide
break
@ -80,7 +80,7 @@ elseif sCommand == "host" then
-- Print the number of requests handled
nServed = nServed + 1
if nServed > 1 then
local x,y = term.getCursorPos()
local _, y = term.getCursorPos()
term.setCursorPos(1, y - 1)
end
print( nServed .. " GPS requests served" )

View File

@ -14,7 +14,7 @@ if sTopic == "index" then
end
local sFile = help.lookup( sTopic )
local file = ((sFile ~= nil) and io.open( sFile )) or nil
local file = sFile ~= nil and io.open( sFile ) or nil
if file then
local sContents = file:read("*a")
file:close()

View File

@ -18,7 +18,7 @@ local tFiles = {}
local tDirs = {}
local bShowHidden = settings.get( "list.show_hidden" )
for n, sItem in pairs( tAll ) do
for _, sItem in pairs( tAll ) do
if bShowHidden or string.sub( sItem, 1, 1 ) ~= "." then
local sPath = fs.combine( sDir, sItem )
if fs.isDir( sPath ) then

View File

@ -67,7 +67,7 @@ while bRunning do
local nForcePrint = 0
local func, e = load( s, "=lua", "t", tEnv )
local func2, e2 = load( "return _echo("..s..");", "=lua", "t", tEnv )
local func2 = load( "return _echo(" .. s .. ");", "=lua", "t", tEnv )
if not func then
if func2 then
func = func2
@ -84,7 +84,7 @@ while bRunning do
local tResults = table.pack( pcall( func ) )
if tResults[1] then
local n = 1
while n < tResults.n or (n <= nForcePrint) do
while n < tResults.n or n <= nForcePrint do
local value = tResults[ n + 1 ]
if type( value ) == "table" then
local metatable = getmetatable( value )

View File

@ -9,7 +9,7 @@ local sSource = shell.resolve( tArgs[1] )
local sDest = shell.resolve( tArgs[2] )
local tFiles = fs.find( sSource )
if #tFiles > 0 then
for n,sFile in ipairs( tFiles ) do
for _, sFile in ipairs( tFiles ) do
if fs.isDir( sDest ) then
fs.move( sFile, fs.combine( sDest, fs.getName(sFile) ) )
elseif #tFiles == 1 then

View File

@ -10,16 +10,16 @@ end
local block_s1 = {
{
{ 1,0,0,0, },
{ 1,1,0,0, },
{ 0,1,0,0, },
{ 0,0,0,0, },
{ 1, 0, 0, 0 },
{ 1, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 },
},
{
{ 0,0,0,0, },
{ 0,1,1,0, },
{ 1,1,0,0, },
{ 0,0,0,0, },
{ 0, 0, 0, 0 },
{ 0, 1, 1, 0 },
{ 1, 1, 0, 0 },
{ 0, 0, 0, 0 },
},
ch = colorass(" ", "{}"),
fg = colorass(colors.blue, colors.black),
@ -27,16 +27,16 @@ local block_s1= {
}
local block_s2 = {
{
{ 0,1,0,0, },
{ 1,1,0,0, },
{ 1,0,0,0, },
{ 0,0,0,0, },
{ 0, 1, 0, 0 },
{ 1, 1, 0, 0 },
{ 1, 0, 0, 0 },
{ 0, 0, 0, 0 },
},
{
{ 0,0,0,0, },
{ 1,1,0,0, },
{ 0,1,1,0, },
{ 0,0,0,0, },
{ 0, 0, 0, 0 },
{ 1, 1, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 },
},
ch = colorass(" ", "{}"),
fg = colorass(colors.green, colors.black),
@ -44,16 +44,16 @@ local block_s2= {
}
local block_line = {
{
{ 0,1,0,0, },
{ 0,1,0,0, },
{ 0,1,0,0, },
{ 0,1,0,0, },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
},
{
{ 0,0,0,0, },
{ 1,1,1,1, },
{ 0,0,0,0, },
{ 0,0,0,0, },
{ 0, 0, 0, 0 },
{ 1, 1, 1, 1 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
},
ch = colorass(" ", "[]"),
fg = colorass(colors.pink, colors.black),
@ -61,10 +61,10 @@ local block_line = {
}
local block_square = {
{
{ 1,1,0,0, },
{ 1,1,0,0, },
{ 0,0,0,0, },
{ 0,0,0,0, },
{ 1, 1, 0, 0 },
{ 1, 1, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
},
ch = colorass(" ", "[]"),
fg = colorass(colors.lightBlue, colors.black),
@ -72,28 +72,28 @@ local block_square = {
}
local block_L1 = {
{
{ 1,1,0,0, },
{ 0,1,0,0, },
{ 0,1,0,0, },
{ 0,0,0,0, },
{ 1, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 },
},
{
{ 0,0,0,0, },
{ 1,1,1,0, },
{ 1,0,0,0, },
{ 0,0,0,0, },
{ 0, 0, 0, 0 },
{ 1, 1, 1, 0 },
{ 1, 0, 0, 0 },
{ 0, 0, 0, 0 },
},
{
{ 0,1,0,0, },
{ 0,1,0,0, },
{ 0,1,1,0, },
{ 0,0,0,0, },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 },
},
{
{ 0,0,1,0, },
{ 1,1,1,0, },
{ 0,0,0,0, },
{ 0,0,0,0, },
{ 0, 0, 1, 0 },
{ 1, 1, 1, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
},
ch = colorass(" ", "()"),
fg = colorass(colors.orange, colors.black),
@ -101,28 +101,28 @@ local block_L1 = {
}
local block_L2 = {
{
{ 0,1,0,0, },
{ 0,1,0,0, },
{ 1,1,0,0, },
{ 0,0,0,0, },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 1, 1, 0, 0 },
{ 0, 0, 0, 0 },
},
{
{ 0,0,0,0, },
{ 1,1,1,0, },
{ 0,0,1,0, },
{ 0,0,0,0, },
{ 0, 0, 0, 0 },
{ 1, 1, 1, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 0 },
},
{
{ 0,1,1,0, },
{ 0,1,0,0, },
{ 0,1,0,0, },
{ 0,0,0,0, },
{ 0, 1, 1, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 },
},
{
{ 1,0,0,0, },
{ 1,1,1,0, },
{ 0,0,0,0, },
{ 0,0,0,0, },
{ 1, 0, 0, 0 },
{ 1, 1, 1, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
},
ch = colorass(" ", "()"),
fg = colorass(colors.brown, colors.black),
@ -130,28 +130,28 @@ local block_L2 = {
}
local block_T = {
{
{ 0,1,0,0, },
{ 1,1,0,0, },
{ 0,1,0,0, },
{ 0,0,0,0, },
{ 0, 1, 0, 0 },
{ 1, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 },
},
{
{ 0,0,0,0, },
{ 1,1,1,0, },
{ 0,1,0,0, },
{ 0,0,0,0, },
{ 0, 0, 0, 0 },
{ 1, 1, 1, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 },
},
{
{ 0,1,0,0, },
{ 0,1,1,0, },
{ 0,1,0,0, },
{ 0,0,0,0, },
{ 0, 1, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 },
},
{
{ 0,1,0,0, },
{ 1,1,1,0, },
{ 0,0,0,0, },
{ 0,0,0,0, },
{ 0, 1, 0, 0 },
{ 1, 1, 1, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
},
ch = colorass(" ", "<>"),
fg = colorass(colors.cyan, colors.black),
@ -424,7 +424,7 @@ local function playGame()
end
if #rows > 0 then
for i=1,4 do
for _ = 1, 4 do
sleep(.1)
for r = 1, #rows do
r = rows[r]
@ -469,7 +469,6 @@ local function playGame()
end
local function blockFall()
local result = false
if testBlockAt(curBlock, curX, curY + 1, curRot) then
pitBlock(curBlock, curX, curY, curRot)
--detect rows that clear
@ -524,16 +523,16 @@ local function playGame()
dropTimer = os.startTimer(dropSpeed)
end
if dx + dr ~= 0 then
if not testBlockAt(curBlock,curX+dx,curY+dy,(dr>0 and curRot%#curBlock+dr or curRot)) then
if not testBlockAt(curBlock, curX + dx, curY + dy, dr > 0 and curRot % #curBlock + dr or curRot) then
eraseBlockAt(curBlock, curX, curY, curRot)
curX = curX + dx
curY = curY + dy
curRot=dr==0 and curRot or (curRot%#curBlock+dr)
curRot = dr == 0 and curRot or curRot % #curBlock + dr
drawBlockAt(curBlock, curX, curY, curRot)
end
end
elseif e[1] == "term_resize" then
local w,h=term.getSize()
local _, h = term.getSize()
if h == 20 then
heightAdjust = 0
else
@ -617,7 +616,7 @@ local function runMenu()
level = math.max(level - 1, 1)
drawMenu()
elseif key >= keys.one and key <= keys.nine and selected == 1 then
level=(key-keys.one) + 1
level = key - keys.one + 1
drawMenu()
elseif key == keys.up or key == keys.w then
selected = selected - 1

View File

@ -9,7 +9,7 @@ end
local sOpenedModem = nil
local function openModem()
for n,sModem in ipairs( peripheral.getNames() ) do
for _, sModem in ipairs( peripheral.getNames() ) do
if peripheral.getType( sModem ) == "modem" then
if not rednet.isOpen( sModem ) then
rednet.open( sModem )
@ -94,7 +94,7 @@ if sCommand == "host" then
end
local function printUsers()
local x,y = term.getCursorPos()
local _, y = term.getCursorPos()
term.setCursorPos( 1, y - 1 )
term.clearLine()
if nUsers == 1 then
@ -108,7 +108,7 @@ if sCommand == "host" then
local ok, error = pcall( function()
parallel.waitForAny( function()
while true do
local sEvent, timer = os.pullEvent( "timer" )
local _, timer = os.pullEvent( "timer" )
local nUserID = tPingPongTimer[ timer ]
if nUserID and tUsers[ nUserID ] then
local tUser = tUsers[ nUserID ]
@ -130,14 +130,14 @@ if sCommand == "host" then
local tCommands
tCommands = {
["me"] = function( tUser, sContent )
if string.len(sContent) > 0 then
if #sContent > 0 then
send( "* " .. tUser.sUsername .. " " .. sContent )
else
send( "* Usage: /me [words]", tUser.nUserID )
end
end,
["nick"] = function( tUser, sContent )
if string.len(sContent) > 0 then
if #sContent > 0 then
local sOldName = tUser.sUsername
tUser.sUsername = sContent
send( "* " .. sOldName .. " is now known as " .. tUser.sUsername )
@ -148,7 +148,7 @@ if sCommand == "host" then
["users"] = function( tUser, sContent )
send( "* Connected Users:", tUser.nUserID )
local sUsers = "*"
for nUserID, tUser in pairs( tUsers ) do
for _, tUser in pairs( tUsers ) do
sUsers = sUsers .. " " .. tUser.sUsername
end
send( sUsers, tUser.nUserID )
@ -156,7 +156,7 @@ if sCommand == "host" then
["help"] = function( tUser, sContent )
send( "* Available commands:", tUser.nUserID )
local sCommands = "*"
for sCommand, fnCommand in pairs( tCommands ) do
for sCommand in pairs( tCommands ) do
sCommands = sCommands .. " /" .. sCommand
end
send( sCommands .. " /logout", tUser.nUserID )
@ -199,7 +199,7 @@ if sCommand == "host" then
if sCommand then
local fnCommand = tCommands[ sCommand ]
if fnCommand then
local sContent = string.sub( sMessage, string.len(sCommand)+3 )
local sContent = string.sub( sMessage, #sCommand + 3 )
fnCommand( tUser, sContent )
else
send( "* Unrecognised command: /" .. sCommand, tUser.nUserID )
@ -297,11 +297,10 @@ elseif sCommand == "join" then
promptWindow.restoreCursor()
local function drawTitle()
local x,y = titleWindow.getCursorPos()
local w,h = titleWindow.getSize()
local w = titleWindow.getSize()
local sTitle = sUsername .. " on " .. sHostname
titleWindow.setTextColour( highlightColour )
titleWindow.setCursorPos( math.floor( w/2 - string.len(sTitle)/2 ), 1 )
titleWindow.setCursorPos( math.floor( w / 2 - #sTitle / 2 ), 1 )
titleWindow.clearLine()
titleWindow.write( sTitle )
promptWindow.restoreCursor()
@ -322,7 +321,7 @@ elseif sCommand == "join" then
term.setTextColour( highlightColour )
write( sUsernameBit )
term.setTextColour( textColour )
write( string.sub( sMessage, string.len( sUsernameBit ) + 1 ) )
write( string.sub( sMessage, #sUsernameBit + 1 ) )
else
write( sMessage )
end
@ -410,7 +409,7 @@ elseif sCommand == "join" then
term.redirect( parentTerm )
-- Print error notice
local w,h = term.getSize()
local _, h = term.getSize()
term.setCursorPos( 1, h )
term.clearLine()
term.setCursorBlink( false )

View File

@ -1,7 +1,7 @@
-- Find modems
local tModems = {}
for n,sModem in ipairs( peripheral.getNames() ) do
for _, sModem in ipairs( peripheral.getNames() ) do
if peripheral.getType( sModem ) == "modem" then
table.insert( tModems, sModem )
end
@ -59,7 +59,7 @@ local ok, error = pcall( function()
-- Log the event
nTransmittedMessages = nTransmittedMessages + 1
local x,y = term.getCursorPos()
local _, y = term.getCursorPos()
term.setCursorPos( 1, y - 1 )
term.clearLine()
if nTransmittedMessages == 1 then

View File

@ -17,7 +17,7 @@ if sCommand == "probe" then
local count = 0
local bundledCount = 0
for n,sSide in ipairs( redstone.getSides() ) do
for _, sSide in ipairs( redstone.getSides() ) do
if redstone.getBundledInput( sSide ) > 0 then
bundledCount = bundledCount + 1
end
@ -39,7 +39,7 @@ if sCommand == "probe" then
if bundledCount > 0 then
print()
print( "Bundled inputs:" )
for i,sSide in ipairs( redstone.getSides() ) do
for _, sSide in ipairs( redstone.getSides() ) do
local nInput = redstone.getBundledInput( sSide )
if nInput ~= 0 then
write( sSide .. ": " )
@ -69,7 +69,7 @@ elseif sCommand == "pulse" then
local sSide = tArgs[2]
local nCount = tonumber( tArgs[3] ) or 1
local nPeriod = tonumber( tArgs[4] ) or 0.5
for n=1,nCount do
for _ = 1, nCount do
redstone.setOutput( sSide, true )
sleep( nPeriod / 2 )
redstone.setOutput( sSide, false )

View File

@ -2,7 +2,7 @@
local tArgs = { ... }
if #tArgs == 0 then
-- "set"
local x,y = term.getCursorPos()
local _, y = term.getCursorPos()
local tSettings = {}
for n, sName in ipairs( settings.getNames() ) do
tSettings[n] = textutils.serialize(sName) .. " is " .. textutils.serialize(settings.get(sName))

View File

@ -9,10 +9,10 @@ if multishell then
end
local bExit = false
local sDir = (parentShell and parentShell.dir()) or ""
local sPath = (parentShell and parentShell.path()) or ".:/rom/programs"
local tAliases = (parentShell and parentShell.aliases()) or {}
local tCompletionInfo = (parentShell and parentShell.getCompletionInfo()) or {}
local sDir = parentShell and parentShell.dir() or ""
local sPath = parentShell and parentShell.path() or ".:/rom/programs"
local tAliases = parentShell and parentShell.aliases() or {}
local tCompletionInfo = parentShell and parentShell.getCompletionInfo() or {}
local tProgramStack = {}
local shell = {}
@ -70,7 +70,7 @@ local function createShellEnv( sDir )
end
end
return nil, sError
end
end,
}
local sentinel = {}
@ -287,7 +287,7 @@ function shell.programs( _bIncludeHidden )
-- Sort and return
local tItemList = {}
for sItem, b in pairs( tItems ) do
for sItem in pairs( tItems ) do
table.insert( tItemList, sItem )
end
table.sort( tItemList )
@ -304,7 +304,7 @@ local function completeProgram( sLine )
local tSeen = {}
-- Add aliases
for sAlias, sCommand in pairs( tAliases ) do
for sAlias in pairs( tAliases ) do
if #sAlias > #sLine and string.sub( sAlias, 1, #sLine ) == sLine then
local sResult = string.sub( sAlias, #sLine + 1 )
if not tSeen[ sResult ] then
@ -397,7 +397,7 @@ function shell.setCompletionFunction( sProgram, fnComplete )
expect(1, sProgram, "string")
expect(2, fnComplete, "function")
tCompletionInfo[ sProgram ] = {
fnComplete = fnComplete
fnComplete = fnComplete,
}
end

View File

@ -81,7 +81,7 @@ textutils.slowWrite( "Preparing to get down." )
textutils.slowPrint( "..", 0.75 )
local sAudio = nil
for n,sName in pairs( peripheral.getNames() ) do
for _, sName in pairs( peripheral.getNames() ) do
if disk.hasAudio( sName ) then
disk.playAudio( sName )
print( "Jamming to " .. disk.getAudioTitle( sName ) )
@ -95,7 +95,7 @@ print( "Press any key to stop the groove" )
parallel.waitForAny(
function()
while not bEnd do
local event, key = os.pullEvent("key")
local _, key = os.pullEvent("key")
if key ~= keys.escape then
return
end

View File

@ -81,7 +81,7 @@ local function collect()
if nTotalItems > collected then
collected = nTotalItems
if math.fmod(collected + unloaded, 50) == 0 then
print( "Mined "..(collected + unloaded).." items." )
print( "Mined " .. collected + unloaded .. " items." )
end
end
@ -98,9 +98,8 @@ function refuel( ammount )
return true
end
local needed = ammount or (xPos + zPos + depth + 2)
local needed = ammount or xPos + zPos + depth + 2
if turtle.getFuelLevel() < needed then
local fueled = false
for n = 1, 16 do
if turtle.getItemCount(n) > 0 then
turtle.select(n)
@ -292,7 +291,7 @@ local alternate = 0
local done = false
while not done do
for n = 1, size do
for m=1,size-1 do
for _ = 1, size - 1 do
if not tryForwards() then
done = true
break
@ -354,4 +353,4 @@ if reseal then
turtle.placeDown()
end
print( "Mined "..(collected + unloaded).." items total." )
print( "Mined " .. collected + unloaded .. " items total." )

View File

@ -23,7 +23,7 @@ end
if turtle.getFuelLevel() ~= "unlimited" then
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
if nLimit and nLimit <= 0 or turtle.getFuelLevel() >= turtle.getFuelLimit() then
break
end

View File

@ -15,8 +15,6 @@ if length < 1 then
print( "Tunnel length must be positive" )
return
end
local depth = 0
local collected = 0
local function collect()

View File

@ -31,7 +31,7 @@ while nArg <= #tArgs do
local fnHandler = tHandlers[string.lower(sDirection)]
if fnHandler then
for n=1,nDistance do
for _ = 1, nDistance do
fnHandler( nArg )
end
else

View File

@ -163,7 +163,7 @@ if settings.get( "shell.allow_startup" ) then
tUserStartups = findStartups( "/" )
end
if settings.get( "shell.allow_disk_startup" ) then
for n,sName in pairs( peripheral.getNames() ) do
for _, sName in pairs( peripheral.getNames() ) do
if disk.isPresent( sName ) and disk.hasData( sName ) then
local startups = findStartups( disk.getMountPath( sName ) )
if startups then

View File

@ -11,19 +11,19 @@
--- Assert an argument to the given function has the specified type.
--
-- @tparam string The function's name
-- @tparam int The argument index to this function
-- @tparam string The type this argument should have. May be 'value' for any
-- non-nil value.
-- @param val The value to check
-- @raise If this value doesn't match the expected type.
local function check(func, arg, ty, val)
-- @tparam string func The function's name
-- @tparam int idx The argument index to this function
-- @tparam string ty The type this argument should have. May be 'value' for
-- any non-nil value.
-- @param val val The value to check
-- @throws If this value doesn't match the expected type.
local function check(func, idx, ty, val)
if ty == 'value' then
if val == nil then
error(('%s: bad argument #%d (got nil)'):format(func, arg), 3)
error(('%s: bad argument #%d (got nil)'):format(func, idx), 3)
end
elseif type(val) ~= ty then
return error(('%s: bad argument #%d (expected %s, got %s)'):format(func, arg, ty, type(val)), 3)
return error(('%s: bad argument #%d (expected %s, got %s)'):format(func, idx, ty, type(val)), 3)
end
end
@ -122,7 +122,7 @@ local error_mt = { __tostring = function(self) return self.message end }
--- Attempt to execute the provided function, gathering a stack trace when it
-- errors.
--
-- @tparam
-- @tparam function() fn The function to run
-- @return[1] true
-- @return[2] false
-- @return[2] The error object
@ -170,7 +170,7 @@ end
--- Fail a test with the given message
--
-- @tparam string message The message to fail with
-- @raises An error with the given message
-- @throws An error with the given message
local function fail(message)
check('fail', 1, 'string', message)
error(setmetatable({ message = message, fail = true }, error_mt))
@ -192,7 +192,7 @@ expect_mt.__index = expect_mt
--- Assert that this expectation has the provided value
--
-- @param value The value to require this expectation to be equal to
-- @raises If the values are not equal
-- @throws If the values are not equal
function expect_mt:equals(value)
if value ~= self.value then
fail(("Expected %s\n but got %s"):format(format(value), format(self.value)))
@ -206,7 +206,7 @@ expect_mt.eq = expect_mt.equals
--- Assert that this expectation does not equal the provided value
--
-- @param value The value to require this expectation to not be equal to
-- @raises If the values are equal
-- @throws If the values are equal
function expect_mt:not_equals(value)
if value == self.value then
fail(("Expected any value but %s"):format(format(value)))
@ -220,7 +220,7 @@ expect_mt.ne = expect_mt.not_equals
--- Assert that this expectation has something of the provided type
--
-- @tparam string exp_type The type to require this expectation to have
-- @raises If it does not have that thpe
-- @throws If it does not have that thpe
function expect_mt:type(exp_type)
local actual_type = type(self.value)
if exp_type ~= actual_type then
@ -270,7 +270,7 @@ end
-- the provided object.
--
-- @param value The value to check for structural equivalence
-- @raises If they are not equivalent
-- @throws If they are not equivalent
function expect_mt:same(value)
if not matches({}, true, self.value, value) then
fail(("Expected %s\n but got %s"):format(format(value), format(self.value)))
@ -283,7 +283,7 @@ end
-- in the provided object.
--
-- @param value The value to check against
-- @raises If this does not match the provided value
-- @throws If this does not match the provided value
function expect_mt:matches(value)
if not matches({}, false, value, self.value) then
fail(("Expected %s\nto match %s"):format(format(self.value), format(value)))
@ -296,7 +296,7 @@ end
--
-- @tparam[opt] number The exact number of times the function must be called.
-- If not given just require the function to be called at least once.
-- @raises If this function was not called the expected number of times.
-- @throws If this function was not called the expected number of times.
function expect_mt:called(times)
if getmetatable(self.value) ~= stub_mt or self.value.arguments == nil then
fail(("Expected stubbed function, got %s"):format(type(self.value)))
@ -380,7 +380,7 @@ local expect = setmetatable( {
-- @return The new expectation
__call = function(_, value)
return setmetatable({ value = value }, expect_mt)
end
end,
})
--- The stack of "describe"s.
@ -623,7 +623,7 @@ end
-- And some summary statistics
local actual_count = tests_run - test_status.pending
local info = ("Ran %s test(s), of which %s passed (%g%%).")
:format(actual_count, test_status.pass, (test_status.pass / actual_count) * 100)
:format(actual_count, test_status.pass, test_status.pass / actual_count * 100)
if test_status.pending > 0 then
info = info .. (" Skipped %d pending test(s)."):format(test_status.pending)

View File

@ -2,7 +2,7 @@ describe("The gps library", function()
describe("gps.locate", function()
it("validates arguments", function()
stub(_G, "commands", { getBlockPosition = function()
end })
end, })
gps.locate()
gps.locate(1)

View File

@ -60,10 +60,10 @@ describe("The io library", function()
expect(io.output():seek()):equal(0)
assert(io.write("alo alo"))
expect(io.output():seek()):equal(#("alo alo"))
expect(io.output():seek("cur", -3)):equal(#("alo alo") - 3)
expect(io.output():seek()):equal(#"alo alo")
expect(io.output():seek("cur", -3)):equal(#"alo alo" - 3)
assert(io.write("joao"))
expect(io.output():seek("end"):equal(#("alo joao")))
expect(io.output():seek("end"):equal(#"alo joao"))
expect(io.output():seek("set")):equal(0)

View File

@ -70,7 +70,7 @@ describe("The Lua base library", function()
it("does not prefix for unnamed chunks", function()
local info = debug.getinfo(loadstring("return 1"), "S")
expect(info):matches { short_src = '[string "return 1"]', source = "return 1", }
expect(info):matches { short_src = '[string "return 1"]', source = "return 1" }
end)
it("does not prefix when already prefixed", function()

View File

@ -5,7 +5,7 @@ describe("cc.shell.completion", function()
it("completes both", function()
expect(c.dirOrFile(shell, "rom/")):same {
"apis/", "apis", "autorun/", "autorun", "help/", "help",
"modules/", "modules", "motd.txt", "programs/", "programs", "startup.lua"
"modules/", "modules", "motd.txt", "programs/", "programs", "startup.lua",
}
end)

View File

@ -10,7 +10,7 @@ describe("The commands program", function()
it("lists commands", function()
local pagedTabulate = stub(textutils, "pagedTabulate", function(x) print(table.unpack(x)) end)
stub(_G, "commands", {
list = function() return { "computercraft" } end
list = function() return { "computercraft" } end,
})
expect(capture(stub, "/rom/programs/command/commands.lua"))

View File

@ -15,7 +15,7 @@ describe("The exec program", function()
it("runs a command", function()
stub(_G, "commands", {
exec = function() return true, {"Hello World!"} end
exec = function() return true, {"Hello World!"} end,
})
expect(capture(stub, "/rom/programs/command/exec.lua computercraft"))
@ -24,7 +24,7 @@ describe("The exec program", function()
it("reports command failures", function()
stub(_G, "commands", {
exec = function() return false, {"Hello World!"} end
exec = function() return false, {"Hello World!"} end,
})
expect(capture(stub, "/rom/programs/command/exec.lua computercraft"))

View File

@ -1,5 +1,4 @@
local capture = require "test_helpers".capture_program
local testFile = require "test_helpers".testFile
describe("The edit program", function()

View File

@ -17,7 +17,7 @@ describe("The pastebin program", function()
local tHeader = {}
tHeader["Content-Type"] = "text/plain; charset=utf-8"
return tHeader
end
end,
}
end,
post = function()
@ -28,7 +28,7 @@ describe("The pastebin program", function()
close = function()
end,
}
end
end,
})
end

View File

@ -14,7 +14,7 @@ describe("The wget program", function()
close = function()
end,
}
end
end,
})
end

View File

@ -9,7 +9,7 @@ describe("The pocket equip program", function()
it("can equip an upgrade", function()
stub(_G, "pocket", {
equipBack = function() return true end
equipBack = function() return true end,
})
expect(capture(stub, "/rom/programs/pocket/equip.lua"))
@ -18,7 +18,7 @@ describe("The pocket equip program", function()
it("handles when an upgrade cannot be equipped", function()
stub(_G, "pocket", {
equipBack = function() return false, "Cannot equip this item." end
equipBack = function() return false, "Cannot equip this item." end,
})
expect(capture(stub, "/rom/programs/pocket/equip.lua"))

View File

@ -9,7 +9,7 @@ describe("The pocket unequip program", function()
it("unequips an upgrade", function()
stub(_G, "pocket", {
unequipBack = function() return true end
unequipBack = function() return true end,
})
expect(capture(stub, "/rom/programs/pocket/unequip.lua"))
@ -18,7 +18,7 @@ describe("The pocket unequip program", function()
it("handles when an upgrade cannot be equipped", function()
stub(_G, "pocket", {
unequipBack = function() return false, "Nothing to remove." end
unequipBack = function() return false, "Nothing to remove." end,
})
expect(capture(stub, "/rom/programs/pocket/unequip.lua"))

View File

@ -17,7 +17,7 @@ describe("The refuel program", function()
end,
getFuelLimit = function()
return fuel_limit
end
end,
})
end

View File

@ -21,7 +21,7 @@ describe("The turtle unequip program", function()
select = function() end,
getItemCount = function() return 0 end,
equipRight = function() return true end,
equipLeft = function() return true end
equipLeft = function() return true end,
})
expect(capture(stub, "/rom/programs/turtle/unequip.lua left"))
@ -42,7 +42,7 @@ describe("The turtle unequip program", function()
equipLeft = function()
item_count = 1
return true
end
end,
})
expect(capture(stub, "/rom/programs/turtle/unequip.lua left"))
@ -57,7 +57,7 @@ describe("The turtle unequip program", function()
select = function() end,
getItemCount = function() return 1 end,
equipRight = function() return true end,
equipLeft = function() return true end
equipLeft = function() return true end,
})
expect(capture(stub, "/rom/programs/turtle/unequip.lua left"))

View File

@ -37,7 +37,7 @@ local function capture_program(stub, program, ...)
output = table.concat(output),
error = table.concat(error),
combined = table.concat(combined),
ok = ok
ok = ok,
}
end