mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-10-18 15:37:38 +00:00
Compare commits
13 Commits
v1.12.2-1.
...
v1.12.2-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0dde859582 | ||
![]() |
e59c043fb6 | ||
![]() |
ae928c4397 | ||
![]() |
da41c65128 | ||
![]() |
4d18234714 | ||
![]() |
d254c6464b | ||
![]() |
3a5d50e572 | ||
![]() |
03b6d2f1ab | ||
![]() |
b0397ed3c5 | ||
![]() |
fa70ebcac2 | ||
![]() |
86e0330100 | ||
![]() |
0ae70fed13 | ||
![]() |
121802a683 |
@@ -11,5 +11,8 @@ insert_final_newline = true
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.sexp]
|
||||
indent_size = 2
|
||||
|
||||
[*.properties]
|
||||
insert_final_newline = false
|
||||
|
15
.github/workflows/main-ci.yml
vendored
15
.github/workflows/main-ci.yml
vendored
@@ -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
|
||||
|
35
.luacheckrc
35
.luacheckrc
@@ -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' },
|
||||
}
|
11
build.gradle
11
build.gradle
@@ -59,6 +59,10 @@ repositories {
|
||||
name "Amadornes"
|
||||
url "https://maven.amadornes.com/"
|
||||
}
|
||||
maven {
|
||||
name "CraftTweaker"
|
||||
url "https://maven.blamejared.com/"
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
@@ -70,9 +74,10 @@ configurations {
|
||||
dependencies {
|
||||
checkstyle "com.puppycrawl.tools:checkstyle:8.25"
|
||||
|
||||
deobfProvided "CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.554"
|
||||
deobfProvided "MCMultiPart2:MCMultiPart:2.5.3"
|
||||
deobfProvided "mezz.jei:jei_1.12.2:4.15.0.269:api"
|
||||
deobfProvided "pl.asie:Charset-Lib:0.5.4.6"
|
||||
deobfProvided "MCMultiPart2:MCMultiPart:2.5.3"
|
||||
|
||||
runtime "mezz.jei:jei_1.12.2:4.15.0.269"
|
||||
|
||||
@@ -132,6 +137,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") }
|
||||
@@ -146,9 +152,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>(...); }'
|
||||
}
|
||||
|
||||
task proguardMove(dependsOn: proguard) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
# Mod properties
|
||||
mod_version=1.85.0
|
||||
mod_version=1.86.0
|
||||
|
||||
# Minecraft properties
|
||||
mc_version=1.12.2
|
||||
|
28
illuaminate.sexp
Normal file
28
illuaminate.sexp
Normal 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))
|
@@ -54,8 +54,8 @@ public final class Config
|
||||
|
||||
private static Property httpEnable;
|
||||
private static Property httpWebsocketEnable;
|
||||
private static Property httpWhitelist;
|
||||
private static Property httpBlacklist;
|
||||
private static Property httpAllowedDomains;
|
||||
private static Property httpBlockedDomains;
|
||||
|
||||
private static Property httpTimeout;
|
||||
private static Property httpMaxRequests;
|
||||
@@ -163,30 +163,32 @@ public final class Config
|
||||
{ // HTTP
|
||||
renameProperty( CATEGORY_GENERAL, "http_enable", CATEGORY_HTTP, "enabled" );
|
||||
renameProperty( CATEGORY_GENERAL, "http_websocket_enable", CATEGORY_HTTP, "websocket_enabled" );
|
||||
renameProperty( CATEGORY_GENERAL, "http_whitelist", CATEGORY_HTTP, "whitelist" );
|
||||
renameProperty( CATEGORY_GENERAL, "http_blacklist", CATEGORY_HTTP, "blacklist" );
|
||||
renameProperty( CATEGORY_GENERAL, "http_whitelist", CATEGORY_HTTP, "allowed_domains" );
|
||||
renameProperty( CATEGORY_GENERAL, "http_blacklist", CATEGORY_HTTP, "blocked_domains" );
|
||||
renameProperty( CATEGORY_HTTP, "whitelist", CATEGORY_HTTP, "allowed_domains" );
|
||||
renameProperty( CATEGORY_HTTP, "blacklist", CATEGORY_HTTP, "blocked_domains" );
|
||||
|
||||
config.getCategory( CATEGORY_HTTP )
|
||||
.setComment( "Controls the HTTP API" );
|
||||
|
||||
httpEnable = config.get( CATEGORY_HTTP, "enabled", ComputerCraft.http_enable );
|
||||
httpEnable.setComment( "Enable the \"http\" API on Computers (see \"http_whitelist\" and \"http_blacklist\" for " +
|
||||
"more fine grained control than this)" );
|
||||
httpEnable.setComment( "Enable the \"http\" API on Computers (see \"allowed_domains\" and \"blocked_domains\" " +
|
||||
"for more fine grained control than this)" );
|
||||
|
||||
httpWebsocketEnable = config.get( CATEGORY_HTTP, "websocket_enabled", ComputerCraft.http_websocket_enable );
|
||||
httpWebsocketEnable.setComment( "Enable use of http websockets. This requires the \"http_enable\" option to also be true." );
|
||||
|
||||
httpWhitelist = config.get( CATEGORY_HTTP, "whitelist", DEFAULT_HTTP_WHITELIST );
|
||||
httpWhitelist.setComment( "A list of wildcards for domains or IP ranges that can be accessed through the " +
|
||||
httpAllowedDomains = config.get( CATEGORY_HTTP, "allowed_domains", DEFAULT_HTTP_WHITELIST );
|
||||
httpAllowedDomains.setComment( "A list of wildcards for domains or IP ranges that can be accessed through the " +
|
||||
"\"http\" API on Computers.\n" +
|
||||
"Set this to \"*\" to access to the entire internet. Example: \"*.pastebin.com\" will restrict access to " +
|
||||
"just subdomains of pastebin.com.\n" +
|
||||
"You can use domain names (\"pastebin.com\"), wilcards (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\")." );
|
||||
|
||||
httpBlacklist = config.get( CATEGORY_HTTP, "blacklist", DEFAULT_HTTP_BLACKLIST );
|
||||
httpBlacklist.setComment( "A list of wildcards for domains or IP ranges that cannot be accessed through the " +
|
||||
httpBlockedDomains = config.get( CATEGORY_HTTP, "blocked_domains", DEFAULT_HTTP_BLACKLIST );
|
||||
httpBlockedDomains.setComment( "A list of wildcards for domains or IP ranges that cannot be accessed through the " +
|
||||
"\"http\" API on Computers.\n" +
|
||||
"If this is empty then all whitelisted domains will be accessible. Example: \"*.github.com\" will block " +
|
||||
"If this is empty then all explicitly allowed domains will be accessible. Example: \"*.github.com\" will block " +
|
||||
"access to all subdomains of github.com.\n" +
|
||||
"You can use domain names (\"pastebin.com\"), wilcards (\"*.pastebin.com\") or CIDR notation (\"127.0.0.0/8\")." );
|
||||
|
||||
@@ -220,7 +222,7 @@ public final class Config
|
||||
|
||||
setOrder(
|
||||
CATEGORY_HTTP,
|
||||
httpEnable, httpWebsocketEnable, httpWhitelist, httpBlacklist,
|
||||
httpEnable, httpWebsocketEnable, httpAllowedDomains, httpBlockedDomains,
|
||||
httpTimeout, httpMaxRequests, httpMaxDownload, httpMaxUpload, httpMaxWebsockets, httpMaxWebsocketMessage
|
||||
);
|
||||
}
|
||||
@@ -441,8 +443,8 @@ public final class Config
|
||||
// HTTP
|
||||
ComputerCraft.http_enable = httpEnable.getBoolean();
|
||||
ComputerCraft.http_websocket_enable = httpWebsocketEnable.getBoolean();
|
||||
ComputerCraft.http_whitelist = new AddressPredicate( httpWhitelist.getStringList() );
|
||||
ComputerCraft.http_blacklist = new AddressPredicate( httpBlacklist.getStringList() );
|
||||
ComputerCraft.http_whitelist = new AddressPredicate( httpAllowedDomains.getStringList() );
|
||||
ComputerCraft.http_blacklist = new AddressPredicate( httpBlockedDomains.getStringList() );
|
||||
|
||||
ComputerCraft.httpTimeout = Math.max( 0, httpTimeout.getInt() );
|
||||
ComputerCraft.httpMaxRequests = Math.max( 1, httpMaxRequests.getInt() );
|
||||
|
@@ -19,12 +19,35 @@ import net.minecraftforge.fml.common.ModContainer;
|
||||
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 = Loader.instance().activeModContainer();
|
||||
|
||||
this.upgrade = upgrade;
|
||||
this.legacyId = upgrade.getLegacyUpgradeID();
|
||||
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 Int2ObjectMap<ITurtleUpgrade> legacyUpgrades = new Int2ObjectOpenHashMap<>();
|
||||
private static final IdentityHashMap<ITurtleUpgrade, String> upgradeOwners = new IdentityHashMap<>();
|
||||
private static final IdentityHashMap<ITurtleUpgrade, Wrapper> wrappers = new IdentityHashMap<>();
|
||||
|
||||
private TurtleUpgrades() {}
|
||||
|
||||
@@ -35,9 +58,7 @@ public final class TurtleUpgrades
|
||||
int id = upgrade.getLegacyUpgradeID();
|
||||
if( id >= 0 && id < 64 )
|
||||
{
|
||||
String message = getMessage( upgrade, "Legacy UpgradeID '" + id + "' is reserved by ComputerCraft" );
|
||||
ComputerCraft.log.error( message );
|
||||
throw new RuntimeException( message );
|
||||
throw registrationError( upgrade, "Legacy Upgrade ID '" + id + "' is reserved by ComputerCraft" );
|
||||
}
|
||||
|
||||
registerInternal( upgrade );
|
||||
@@ -47,58 +68,63 @@ public final class TurtleUpgrades
|
||||
{
|
||||
Objects.requireNonNull( upgrade, "upgrade cannot be null" );
|
||||
|
||||
Wrapper wrapper = new Wrapper( upgrade );
|
||||
|
||||
// Check conditions
|
||||
int legacyId = upgrade.getLegacyUpgradeID();
|
||||
int legacyId = wrapper.legacyId;
|
||||
if( legacyId >= 0 )
|
||||
{
|
||||
if( legacyId >= Short.MAX_VALUE )
|
||||
{
|
||||
String message = getMessage( upgrade, "UpgradeID '" + legacyId + "' is out of range" );
|
||||
ComputerCraft.log.error( message );
|
||||
throw new RuntimeException( message );
|
||||
throw registrationError( upgrade, "Upgrade ID '" + legacyId + "' is out of range" );
|
||||
}
|
||||
|
||||
ITurtleUpgrade existing = legacyUpgrades.get( legacyId );
|
||||
if( existing != null )
|
||||
{
|
||||
String message = getMessage( upgrade, "UpgradeID '" + legacyId + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" );
|
||||
ComputerCraft.log.error( message );
|
||||
throw new RuntimeException( message );
|
||||
throw registrationError( upgrade, "Upgrade ID '" + legacyId + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" );
|
||||
}
|
||||
}
|
||||
|
||||
String id = upgrade.getUpgradeID().toString();
|
||||
String id = wrapper.id;
|
||||
ITurtleUpgrade existing = upgrades.get( id );
|
||||
if( existing != null )
|
||||
{
|
||||
String message = getMessage( upgrade, "UpgradeID '" + id + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" );
|
||||
ComputerCraft.log.error( message );
|
||||
throw new RuntimeException( message );
|
||||
throw registrationError( upgrade, "Upgrade '" + id + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" );
|
||||
}
|
||||
|
||||
// Register
|
||||
if( legacyId >= 0 ) legacyUpgrades.put( legacyId, upgrade );
|
||||
upgrades.put( id, upgrade );
|
||||
|
||||
ModContainer mc = Loader.instance().activeModContainer();
|
||||
if( mc != null && mc.getModId() != null ) upgradeOwners.put( upgrade, mc.getModId() );
|
||||
wrappers.put( upgrade, wrapper );
|
||||
}
|
||||
|
||||
private static String getMessage( ITurtleUpgrade upgrade, String rest )
|
||||
private static RuntimeException registrationError( ITurtleUpgrade upgrade, String rest )
|
||||
{
|
||||
return "Error registering '" + upgrade.getUnlocalisedAdjective() + " Turtle'. " + rest;
|
||||
String message = "Error registering '" + upgrade.getUnlocalisedAdjective() + " Turtle'. " + rest;
|
||||
ComputerCraft.log.error( message );
|
||||
throw new IllegalArgumentException( message );
|
||||
}
|
||||
|
||||
@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;
|
||||
@@ -115,25 +141,24 @@ public final class TurtleUpgrades
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Iterable<ITurtleUpgrade> getVanillaUpgrades()
|
||||
public static Stream<ITurtleUpgrade> getVanillaUpgrades()
|
||||
{
|
||||
List<ITurtleUpgrade> vanilla = new ArrayList<>();
|
||||
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 );
|
||||
vanilla.add( ComputerCraft.TurtleUpgrades.wirelessModem );
|
||||
vanilla.add( ComputerCraft.TurtleUpgrades.advancedModem );
|
||||
vanilla.add( ComputerCraft.TurtleUpgrades.speaker );
|
||||
return vanilla;
|
||||
if( vanilla == null )
|
||||
{
|
||||
vanilla = new ITurtleUpgrade[] {
|
||||
ComputerCraft.TurtleUpgrades.diamondPickaxe,
|
||||
ComputerCraft.TurtleUpgrades.diamondAxe,
|
||||
ComputerCraft.TurtleUpgrades.diamondSword,
|
||||
ComputerCraft.TurtleUpgrades.diamondShovel,
|
||||
ComputerCraft.TurtleUpgrades.diamondHoe,
|
||||
ComputerCraft.TurtleUpgrades.craftingTable,
|
||||
ComputerCraft.TurtleUpgrades.wirelessModem,
|
||||
ComputerCraft.TurtleUpgrades.advancedModem,
|
||||
ComputerCraft.TurtleUpgrades.speaker,
|
||||
};
|
||||
}
|
||||
|
||||
@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()
|
||||
@@ -145,4 +170,14 @@ public final class TurtleUpgrades
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
@@ -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 ) );
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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." );
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -8,6 +8,7 @@ package dan200.computercraft.shared.turtle.core;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import dan200.computercraft.api.turtle.ITurtleAccess;
|
||||
import dan200.computercraft.shared.util.FakeNetHandler;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import dan200.computercraft.shared.util.WorldUtil;
|
||||
import net.minecraft.entity.Entity;
|
||||
@@ -46,11 +47,13 @@ public class TurtlePlayer extends FakePlayer
|
||||
public TurtlePlayer( World world )
|
||||
{
|
||||
super( (WorldServer) world, DEFAULT_PROFILE );
|
||||
connection = new FakeNetHandler( this );
|
||||
}
|
||||
|
||||
private TurtlePlayer( ITurtleAccess turtle )
|
||||
{
|
||||
super( (WorldServer) turtle.getWorld(), getProfile( turtle.getOwningPlayer() ) );
|
||||
connection = new FakeNetHandler( this );
|
||||
setState( turtle );
|
||||
}
|
||||
|
||||
|
@@ -48,13 +48,11 @@ public abstract class ItemTurtleBase extends ItemComputerBase implements ITurtle
|
||||
ItemStack normalStack = TurtleItemFactory.create( -1, null, -1, family, null, null, 0, null );
|
||||
if( !normalStack.isEmpty() && normalStack.getItem() == this ) list.add( normalStack );
|
||||
|
||||
for( ITurtleUpgrade upgrade : TurtleUpgrades.getVanillaUpgrades() )
|
||||
{
|
||||
if( !TurtleUpgrades.suitableForFamily( family, upgrade ) ) continue;
|
||||
|
||||
ItemStack stack = TurtleItemFactory.create( -1, null, -1, family, null, upgrade, 0, null );
|
||||
if( !stack.isEmpty() && stack.getItem() == this ) list.add( stack );
|
||||
}
|
||||
TurtleUpgrades.getVanillaUpgrades()
|
||||
.filter( x -> TurtleUpgrades.suitableForFamily( family, x ) )
|
||||
.map( x -> TurtleItemFactory.create( -1, null, -1, family, null, x, 0, null ) )
|
||||
.filter( x -> !x.isEmpty() && x.getItem() == this )
|
||||
.forEach( list::add );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@@ -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 class TurtleAxe extends TurtleTool
|
||||
super( id, legacyId, item );
|
||||
}
|
||||
|
||||
public TurtleAxe( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
|
||||
{
|
||||
super( id, craftItem, toolItem );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getDamageMultiplier()
|
||||
{
|
||||
|
@@ -35,6 +35,11 @@ public class TurtleHoe extends TurtleTool
|
||||
super( id, legacyId, item );
|
||||
}
|
||||
|
||||
public TurtleHoe( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
|
||||
{
|
||||
super( id, craftItem, toolItem );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canBreakBlock( IBlockState state, World world, BlockPos pos, TurtlePlayer player )
|
||||
{
|
||||
|
@@ -35,6 +35,11 @@ public class TurtleShovel extends TurtleTool
|
||||
super( id, legacyId, item );
|
||||
}
|
||||
|
||||
public TurtleShovel( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
|
||||
{
|
||||
super( id, craftItem, toolItem );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canBreakBlock( IBlockState state, World world, BlockPos pos, TurtlePlayer player )
|
||||
{
|
||||
|
@@ -10,6 +10,7 @@ import dan200.computercraft.shared.turtle.core.TurtlePlayer;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
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 class TurtleSword extends TurtleTool
|
||||
super( id, legacyId, item );
|
||||
}
|
||||
|
||||
public TurtleSword( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
|
||||
{
|
||||
super( id, craftItem, toolItem );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canBreakBlock( IBlockState state, World world, BlockPos pos, TurtlePlayer player )
|
||||
{
|
||||
|
@@ -62,6 +62,12 @@ public class TurtleTool extends AbstractTurtleUpgrade
|
||||
this.item = new ItemStack( item, 1, 0 );
|
||||
}
|
||||
|
||||
public TurtleTool( ResourceLocation id, ItemStack craftItem, ItemStack toolItem )
|
||||
{
|
||||
super( id, -1, TurtleUpgradeType.Tool, craftItem );
|
||||
this.item = toolItem;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
@SideOnly( Side.CLIENT )
|
||||
@@ -76,7 +82,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
|
||||
);
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
return Pair.of(
|
||||
mc.getRenderItem().getItemModelMesher().getItemModel( item ),
|
||||
mc.getRenderItem().getItemModelMesher().getItemModel( getCraftingItem() ),
|
||||
transform
|
||||
);
|
||||
}
|
||||
|
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import net.minecraft.network.*;
|
||||
import net.minecraft.network.play.client.*;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
public class FakeNetHandler extends NetHandlerPlayServer
|
||||
{
|
||||
public static class FakeNetworkManager extends NetworkManager
|
||||
{
|
||||
private INetHandler handler;
|
||||
|
||||
public FakeNetworkManager()
|
||||
{
|
||||
super( EnumPacketDirection.CLIENTBOUND );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive( ChannelHandlerContext context )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConnectionState( @Nonnull EnumConnectionState state )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive( ChannelHandlerContext context )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught( ChannelHandlerContext context, @Nonnull Throwable e )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNetHandler( INetHandler handler )
|
||||
{
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processReceivedPackets()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeChannel( @Nonnull ITextComponent channel )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocalChannel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void enableEncryption( SecretKey key )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChannelOpen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public INetHandler getNetHandler()
|
||||
{
|
||||
return handler;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ITextComponent getExitMessage()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableAutoRead()
|
||||
{
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Channel channel()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public FakeNetHandler( FakePlayer player )
|
||||
{
|
||||
this( player.server, player );
|
||||
}
|
||||
|
||||
public FakeNetHandler( MinecraftServer server, FakePlayer player )
|
||||
{
|
||||
super( server, new FakeNetworkManager(), player );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processInput( CPacketInput packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPlayer( CPacketPlayer packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayerLocation( double x, double y, double z, float yaw, float pitch )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPlayerDigging( CPacketPlayerDigging packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect( @Nonnull ITextComponent chat )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( "rawtypes" )
|
||||
public void sendPacket( @Nonnull final Packet packet )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processHeldItemChange( CPacketHeldItemChange packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processChatMessage( @Nonnull CPacketChatMessage packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processEntityAction( CPacketEntityAction packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processUseEntity( CPacketUseEntity packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processClientStatus( CPacketClientStatus packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCloseWindow( @Nonnull CPacketCloseWindow packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processClickWindow( CPacketClickWindow packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processEnchantItem( CPacketEnchantItem packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCreativeInventoryAction( @Nonnull CPacketCreativeInventoryAction packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processConfirmTransaction( @Nonnull CPacketConfirmTransaction packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processUpdateSign( CPacketUpdateSign packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processKeepAlive( @Nonnull CPacketKeepAlive packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPlayerAbilities( CPacketPlayerAbilities packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processTabComplete( CPacketTabComplete packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processClientSettings( @Nonnull CPacketClientSettings packet )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCustomPayload( CPacketCustomPayload packetIn )
|
||||
{
|
||||
}
|
||||
}
|
@@ -168,8 +168,8 @@ gui.computercraft:config.execution.max_main_computer_time=Computer Servertick Ze
|
||||
gui.computercraft:config.http=HTTP
|
||||
gui.computercraft:config.http.enabled=HTTP-API aktivieren
|
||||
gui.computercraft:config.http.websocket_enabled=Websockets aktivieren
|
||||
gui.computercraft:config.http.whitelist=HTTP-Whitelist
|
||||
gui.computercraft:config.http.blacklist=HTTP-Blacklist
|
||||
gui.computercraft:config.http.allowed_domains=HTTP-Whitelist
|
||||
gui.computercraft:config.http.blocked_domains=HTTP-Blacklist
|
||||
|
||||
gui.computercraft:config.http.timeout=Zeitüberschreitung
|
||||
gui.computercraft:config.http.max_requests=Maximale Anzahl gleichzeitiger Anfragen
|
||||
|
@@ -168,8 +168,8 @@ gui.computercraft:config.execution.max_main_computer_time=Server tick computer t
|
||||
gui.computercraft:config.http=HTTP
|
||||
gui.computercraft:config.http.enabled=Enable the HTTP API
|
||||
gui.computercraft:config.http.websocket_enabled=Enable websockets
|
||||
gui.computercraft:config.http.whitelist=HTTP whitelist
|
||||
gui.computercraft:config.http.blacklist=HTTP blacklist
|
||||
gui.computercraft:config.http.allowed_domains=Allowed domains
|
||||
gui.computercraft:config.http.blocked_domains=Blocked domains
|
||||
|
||||
gui.computercraft:config.http.timeout=Timeout
|
||||
gui.computercraft:config.http.max_requests=Maximum concurrent requests
|
||||
|
@@ -57,8 +57,8 @@ gui.computercraft:config.default_computer_settings=Configuración de Ordenador p
|
||||
gui.computercraft:config.log_computer_errors=Grabar errores periféricos
|
||||
|
||||
gui.computercraft:config.http.enabled=Habilitar API de HTTP
|
||||
gui.computercraft:config.http.whitelist=Lista blanca de HTTP
|
||||
gui.computercraft:config.http.blacklist=Lista negra de HTTP
|
||||
gui.computercraft:config.http.allowed_domains=Lista blanca de HTTP
|
||||
gui.computercraft:config.http.blocked_domains=Lista negra de HTTP
|
||||
|
||||
gui.computercraft:config.peripheral.command_block_enabled=Habilitar bloque de comandos periférico
|
||||
gui.computercraft:config.peripheral.modem_range=Rango del módem (Por defecto)
|
||||
|
@@ -57,8 +57,8 @@ gui.computercraft:config.default_computer_settings=Configuration d'Ordinateur pa
|
||||
gui.computercraft:config.log_computer_errors=Journal d'erreur périphériques
|
||||
|
||||
gui.computercraft:config.http.enabled=Permettre l'API HTTP
|
||||
gui.computercraft:config.http.whitelist=HTTP liste blanche
|
||||
gui.computercraft:config.http.blacklist=HTTP liste noire
|
||||
gui.computercraft:config.http.allowed_domains=HTTP liste blanche
|
||||
gui.computercraft:config.http.blocked_domains=HTTP liste noire
|
||||
|
||||
gui.computercraft:config.peripheral.command_block_enabled=Permettre l'accès d'un Bloc de Commande par périphérique
|
||||
gui.computercraft:config.peripheral.modem_range=Portée d'un Modem (par défaut)
|
||||
|
@@ -63,8 +63,8 @@ gui.computercraft:config.execution.computer_threads=Threads computer
|
||||
gui.computercraft:config.http=HTTP
|
||||
gui.computercraft:config.http.enabled=Attiva l'API HTTP
|
||||
gui.computercraft:config.http.websocket_enabled=Attiva websocket
|
||||
gui.computercraft:config.http.whitelist=Lista bianca HTTP
|
||||
gui.computercraft:config.http.blacklist=Lista nera HTTP
|
||||
gui.computercraft:config.http.allowed_domains=Lista bianca HTTP
|
||||
gui.computercraft:config.http.blocked_domains=Lista nera HTTP
|
||||
|
||||
gui.computercraft:config.http.timeout=Tempo di scadenza
|
||||
gui.computercraft:config.http.max_requests=Richieste correnti massime
|
||||
|
@@ -63,8 +63,8 @@ gui.computercraft:config.execution.computer_threads=Threads por computador
|
||||
gui.computercraft:config.http=HTTP
|
||||
gui.computercraft:config.http.enabled=Habilitar a biblioteca de HTTP
|
||||
gui.computercraft:config.http.websocket_enabled=Habilitar websockets
|
||||
gui.computercraft:config.http.whitelist=Lista de endereços autorizados
|
||||
gui.computercraft:config.http.blacklist=Lista de endereços proíbidos
|
||||
gui.computercraft:config.http.allowed_domains=Lista de endereços autorizados
|
||||
gui.computercraft:config.http.blocked_domains=Lista de endereços proíbidos
|
||||
|
||||
gui.computercraft:config.http.timeout=Tempo limite para conexões
|
||||
gui.computercraft:config.http.max_requests=Limite de conexões paralelas
|
||||
|
@@ -63,8 +63,8 @@ gui.computercraft:config.execution.computer_threads=Dator trådar
|
||||
gui.computercraft:config.http=HTTP
|
||||
gui.computercraft:config.http.enabled=Aktivera HTTP API
|
||||
gui.computercraft:config.http.websocket_enabled=Aktivera websockets
|
||||
gui.computercraft:config.http.whitelist=HTTP vitlista
|
||||
gui.computercraft:config.http.blacklist=HTTP svartlista
|
||||
gui.computercraft:config.http.allowed_domains=HTTP vitlista
|
||||
gui.computercraft:config.http.blocked_domains=HTTP svartlista
|
||||
|
||||
gui.computercraft:config.http.timeout=Timeout
|
||||
gui.computercraft:config.http.max_requests=Maximalt antal samgående förfrågningar
|
||||
|
@@ -168,8 +168,8 @@ gui.computercraft:config.execution.max_main_computer_time=服务器计算机tick
|
||||
gui.computercraft:config.http=HTTP
|
||||
gui.computercraft:config.http.enabled=启用HTTP API
|
||||
gui.computercraft:config.http.websocket_enabled=启用websockets
|
||||
gui.computercraft:config.http.whitelist=HTTP白名单
|
||||
gui.computercraft:config.http.blacklist=HTTP黑名单
|
||||
gui.computercraft:config.http.allowed_domains=HTTP白名单
|
||||
gui.computercraft:config.http.blocked_domains=HTTP黑名单
|
||||
|
||||
gui.computercraft:config.http.timeout=Timeout
|
||||
gui.computercraft:config.http.max_requests=最大并发请求数
|
||||
|
@@ -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 )
|
||||
@@ -291,7 +291,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
|
||||
sLine = ""
|
||||
end
|
||||
local nHistoryPos
|
||||
local nPos = #sLine
|
||||
local nPos, nScroll = #sLine, 0
|
||||
if _sReplaceChar then
|
||||
_sReplaceChar = string.sub( _sReplaceChar, 1, 1 )
|
||||
end
|
||||
@@ -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
|
||||
@@ -321,16 +321,20 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
|
||||
local sx = term.getCursorPos()
|
||||
|
||||
local function redraw( _bClear )
|
||||
local nScroll = 0
|
||||
if sx + nPos >= w then
|
||||
nScroll = (sx + nPos) - w
|
||||
local cursor_pos = nPos - nScroll
|
||||
if sx + cursor_pos >= w then
|
||||
-- We've moved beyond the RHS, ensure we're on the edge.
|
||||
nScroll = sx + nPos - w
|
||||
elseif cursor_pos < 0 then
|
||||
-- We've moved beyond the LHS, ensure we're on the edge.
|
||||
nScroll = nPos
|
||||
end
|
||||
|
||||
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( string.len(sLine) - nScroll, 0 ) ) )
|
||||
term.write( string.rep( sReplace, math.max( #sLine - nScroll, 0 ) ) )
|
||||
else
|
||||
term.write( string.sub( sLine, nScroll + 1 ) )
|
||||
end
|
||||
@@ -345,7 +349,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
|
||||
term.setBackgroundColor( colors.gray )
|
||||
end
|
||||
if sReplace then
|
||||
term.write( string.rep( sReplace, string.len( sCompletion ) ) )
|
||||
term.write( string.rep( sReplace, #sCompletion ) )
|
||||
else
|
||||
term.write( sCompletion )
|
||||
end
|
||||
@@ -373,7 +377,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
|
||||
-- Find the common prefix of all the other suggestions which start with the same letter as the current one
|
||||
local sCompletion = tCompletions[ nCompletion ]
|
||||
sLine = sLine .. sCompletion
|
||||
nPos = string.len( sLine )
|
||||
nPos = #sLine
|
||||
|
||||
-- Redraw
|
||||
recomplete()
|
||||
@@ -381,7 +385,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
|
||||
end
|
||||
end
|
||||
while true do
|
||||
local sEvent, param = os.pullEvent()
|
||||
local sEvent, param, param1, param2 = os.pullEvent()
|
||||
if sEvent == "char" then
|
||||
-- Typed key
|
||||
clear()
|
||||
@@ -394,7 +398,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
|
||||
-- Pasted text
|
||||
clear()
|
||||
sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
|
||||
nPos = nPos + string.len( param )
|
||||
nPos = nPos + #param
|
||||
recomplete()
|
||||
redraw()
|
||||
|
||||
@@ -419,7 +423,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
|
||||
|
||||
elseif param == keys.right then
|
||||
-- Right
|
||||
if nPos < string.len(sLine) then
|
||||
if nPos < #sLine then
|
||||
-- Move right
|
||||
clear()
|
||||
nPos = nPos + 1
|
||||
@@ -470,10 +474,10 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
|
||||
end
|
||||
if nHistoryPos then
|
||||
sLine = _tHistory[nHistoryPos]
|
||||
nPos = string.len( sLine )
|
||||
nPos, nScroll = #sLine, 0
|
||||
else
|
||||
sLine = ""
|
||||
nPos = 0
|
||||
nPos, nScroll = 0, 0
|
||||
end
|
||||
uncomplete()
|
||||
redraw()
|
||||
@@ -486,6 +490,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
|
||||
clear()
|
||||
sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )
|
||||
nPos = nPos - 1
|
||||
if nScroll > 0 then nScroll = nScroll - 1 end
|
||||
recomplete()
|
||||
redraw()
|
||||
end
|
||||
@@ -501,7 +506,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
|
||||
|
||||
elseif param == keys.delete then
|
||||
-- Delete
|
||||
if nPos < string.len(sLine) then
|
||||
if nPos < #sLine then
|
||||
clear()
|
||||
sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 )
|
||||
recomplete()
|
||||
@@ -510,9 +515,9 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
|
||||
|
||||
elseif param == keys["end"] then
|
||||
-- End
|
||||
if nPos < string.len(sLine ) then
|
||||
if nPos < #sLine then
|
||||
clear()
|
||||
nPos = string.len(sLine)
|
||||
nPos = #sLine
|
||||
recomplete()
|
||||
redraw()
|
||||
end
|
||||
@@ -525,9 +530,9 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
|
||||
|
||||
elseif sEvent == "mouse_click" or sEvent == "mouse_drag" and param == 1 then
|
||||
local _, cy = term.getCursorPos()
|
||||
if param2 >= sx and param2 <= w and param2 == cy then
|
||||
-- Then ensure we don't scroll beyond the current line
|
||||
nPos = math.min(math.max(nScroll + x - sx, 0), #sLine)
|
||||
if param1 >= sx and param1 <= w and param2 == cy then
|
||||
-- Ensure we don't scroll beyond the current line
|
||||
nPos = math.min(math.max(nScroll + param1 - sx, 0), #sLine)
|
||||
redraw()
|
||||
end
|
||||
|
||||
@@ -539,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()
|
||||
@@ -675,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 )
|
||||
@@ -770,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
|
||||
@@ -803,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 )
|
||||
@@ -831,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 )
|
||||
@@ -862,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
|
||||
@@ -876,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
|
||||
@@ -891,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
|
||||
@@ -920,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 )
|
||||
@@ -941,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" )
|
||||
|
@@ -30,12 +30,12 @@ end
|
||||
local tAsync = {}
|
||||
local tNonNBTJSONCommands = {
|
||||
[ "tellraw" ] = true,
|
||||
[ "title" ] = true
|
||||
[ "title" ] = true,
|
||||
}
|
||||
local tCommands = native.list()
|
||||
for n,sCommandName in ipairs(tCommands) do
|
||||
for _, sCommandName in ipairs(tCommands) do
|
||||
if env[ sCommandName ] == nil then
|
||||
local bJSONIsNBT = (tNonNBTJSONCommands[ sCommandName ] == nil)
|
||||
local bJSONIsNBT = tNonNBTJSONCommands[ sCommandName ] == nil
|
||||
env[ sCommandName ] = function( ... )
|
||||
local sCommand = collapseArgs( bJSONIsNBT, sCommandName, ... )
|
||||
return native.exec( sCommand )
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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 )
|
||||
|
@@ -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
|
||||
|
@@ -46,7 +46,7 @@ local tKeys = {
|
||||
nil, "pause", nil, "home", "up", -- 196
|
||||
"pageUp", nil, "left", nil, "right", -- 201
|
||||
nil, "end", "down", "pageDown", "insert", -- 206
|
||||
"delete" -- 211
|
||||
"delete", -- 211
|
||||
}
|
||||
|
||||
local keys = _ENV
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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 )
|
||||
|
@@ -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 = {}
|
||||
|
@@ -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
|
||||
|
@@ -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]
|
||||
|
@@ -1,3 +1,23 @@
|
||||
# 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.
|
||||
|
||||
# New features in CC: Tweaked 1.85.1
|
||||
|
||||
* Add basic mouse support to `read`
|
||||
|
||||
And several bug fixes:
|
||||
* Fix turtles not having breaking particles.
|
||||
|
||||
# New features in CC: Tweaked 1.85.0
|
||||
|
||||
* Window.reposition now allows changing the redirect buffer
|
||||
|
@@ -1,11 +1,10 @@
|
||||
New features in CC: Tweaked 1.85.0
|
||||
New features in CC: Tweaked 1.86.0
|
||||
|
||||
* Window.reposition now allows changing the redirect buffer
|
||||
* Add cc.completion and cc.shell.completion modules
|
||||
* command.exec also returns the number of affected objects, when exposed by the game.
|
||||
* Add PATCH and TRACE HTTP methods. (jaredallard)
|
||||
* Add more MOTD messages. (JakobDev)
|
||||
* Allow removing and adding turtle upgrades via CraftTweaker.
|
||||
|
||||
And several bug fixes:
|
||||
* Change how turtle mining drops are handled, improving compatibility with some mods.
|
||||
* Fix several GUI desyncs after a turtle moves.
|
||||
* Fix crash when interacting with Wearable Backpacks.
|
||||
|
||||
Type "help changelog" to see the full version history.
|
||||
|
@@ -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!
|
||||
|
@@ -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()
|
||||
|
@@ -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
|
||||
|
@@ -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: ", "")))
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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")
|
||||
|
@@ -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." )
|
||||
|
@@ -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
|
||||
|
@@ -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 )
|
||||
|
@@ -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" )
|
||||
|
@@ -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()
|
||||
|
@@ -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
|
||||
|
@@ -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 )
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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 )
|
||||
|
@@ -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
|
||||
|
@@ -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 )
|
||||
|
@@ -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))
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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." )
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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()
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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()
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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"))
|
||||
|
@@ -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"))
|
||||
|
@@ -1,5 +1,4 @@
|
||||
local capture = require "test_helpers".capture_program
|
||||
local testFile = require "test_helpers".testFile
|
||||
|
||||
describe("The edit program", function()
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -14,7 +14,7 @@ describe("The wget program", function()
|
||||
close = function()
|
||||
end,
|
||||
}
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
|
@@ -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"))
|
||||
|
@@ -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"))
|
||||
|
@@ -17,7 +17,7 @@ describe("The refuel program", function()
|
||||
end,
|
||||
getFuelLimit = function()
|
||||
return fuel_limit
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
|
@@ -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"))
|
||||
|
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user