mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-10-18 07:27:39 +00:00
Compare commits
27 Commits
v1.14.4-1.
...
v1.14.4-1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3ea2d6a0a8 | ||
![]() |
c802290437 | ||
![]() |
f7781defe5 | ||
![]() |
418420523a | ||
![]() |
d342a1f368 | ||
![]() |
81f85361d5 | ||
![]() |
f1621b30ec | ||
![]() |
d4f6a594b6 | ||
![]() |
ff5ba5c131 | ||
![]() |
4243f30308 | ||
![]() |
813e91073d | ||
![]() |
7250f22ff6 | ||
![]() |
db31a53bba | ||
![]() |
3023f235a4 | ||
![]() |
79cd8b4da5 | ||
![]() |
8e4d311cd9 | ||
![]() |
9bd8c86a94 | ||
![]() |
cbc0c1d0b6 | ||
![]() |
49c37857d4 | ||
![]() |
b1139a4bf6 | ||
![]() |
7e8559278e | ||
![]() |
1e7f1c98fc | ||
![]() |
a802f25dd6 | ||
![]() |
f1d6d21d6d | ||
![]() |
a80302c513 | ||
![]() |
1c46949da7 | ||
![]() |
46d78af068 |
18
.github/workflows/main-ci.yml
vendored
Normal file
18
.github/workflows/main-ci.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: Build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build --no-daemon
|
14
.travis.yml
14
.travis.yml
@@ -1,14 +0,0 @@
|
||||
language: java
|
||||
|
||||
script: ./gradlew build --no-daemon
|
||||
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.gradle/caches/
|
||||
- $HOME/.gradle/wrapper/s
|
||||
|
||||
jdk:
|
||||
- openjdk8
|
@@ -1,5 +1,5 @@
|
||||
# 
|
||||
[](https://travis-ci.org/SquidDev-CC/CC-Tweaked "Current build status") [](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
|
||||
[](https://github.com/SquidDev-CC/CC-Tweaked/actions "Current build status") [](https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked on CurseForge")
|
||||
|
||||
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
|
||||
turtles and more to Minecraft.
|
||||
|
@@ -9,7 +9,7 @@ buildscript {
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.google.code.gson:gson:2.8.1'
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.134'
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.147'
|
||||
classpath 'net.sf.proguard:proguard-gradle:6.1.0beta2'
|
||||
classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0'
|
||||
}
|
||||
@@ -94,11 +94,11 @@ dependencies {
|
||||
|
||||
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
|
||||
|
||||
compileOnly fg.deobf("mezz.jei:jei-1.14.3:6.0.0.7:api")
|
||||
compileOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.10:api")
|
||||
// deobfProvided "pl.asie:Charset-Lib:0.5.4.6"
|
||||
// deobfProvided "MCMultiPart2:MCMultiPart:2.5.3"
|
||||
|
||||
runtimeOnly fg.deobf("mezz.jei:jei-1.14.3:6.0.0.7")
|
||||
runtimeOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.10")
|
||||
|
||||
shade 'org.squiddev:Cobalt:0.5.0-SNAPSHOT'
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# Mod properties
|
||||
mod_version=1.84.1
|
||||
mod_version=1.85.0
|
||||
|
||||
# Minecraft properties
|
||||
mc_version=1.14.4
|
||||
forge_version=28.0.45
|
||||
mappings_version=20190806-1.14.3
|
||||
forge_version=28.1.26
|
||||
mappings_version=20190912-1.14.3
|
||||
|
@@ -12,6 +12,7 @@ import dan200.computercraft.shared.common.IColouredItem;
|
||||
import dan200.computercraft.shared.media.items.ItemDisk;
|
||||
import dan200.computercraft.shared.pocket.items.ItemPocketComputer;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.model.IUnbakedModel;
|
||||
import net.minecraft.client.renderer.model.ModelResourceLocation;
|
||||
@@ -58,8 +59,8 @@ public final class ClientRegistry
|
||||
};
|
||||
|
||||
private static final String[] EXTRA_TEXTURES = new String[] {
|
||||
// TODO: Gather these automatically from the model. I'm unable to get this working with Forge's current
|
||||
// model loading code.
|
||||
// TODO: Gather these automatically from the model. Sadly the model loader isn't available
|
||||
// when stitching textures.
|
||||
"block/turtle_colour",
|
||||
"block/turtle_elf_overlay",
|
||||
"block/turtle_crafty_face",
|
||||
@@ -77,13 +78,12 @@ public final class ClientRegistry
|
||||
@SubscribeEvent
|
||||
public static void onTextureStitchEvent( TextureStitchEvent.Pre event )
|
||||
{
|
||||
/*
|
||||
IResourceManager manager = Minecraft.getInstance().getResourceManager();
|
||||
if( event.getMap() != Minecraft.getInstance().getTextureMap() ) return;
|
||||
|
||||
for( String extra : EXTRA_TEXTURES )
|
||||
{
|
||||
// TODO: event.getMap().registerSprite( manager, new ResourceLocation( ComputerCraft.MOD_ID, extra ) );
|
||||
event.addSprite( new ResourceLocation( ComputerCraft.MOD_ID, extra ) );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@@ -176,11 +176,4 @@ public final class GuiComputer<T extends ContainerComputerBase> extends Containe
|
||||
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|
||||
|| super.mouseDragged( x, y, button, deltaX, deltaY );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseReleased( double x, double y, int button )
|
||||
{
|
||||
return (getFocused() != null && getFocused().mouseReleased( x, y, button ))
|
||||
|| super.mouseReleased( x, y, button );
|
||||
}
|
||||
}
|
||||
|
@@ -129,4 +129,11 @@ public class GuiTurtle extends ContainerScreen<ContainerTurtle>
|
||||
super.render( mouseX, mouseY, partialTicks );
|
||||
renderHoveredToolTip( mouseX, mouseY );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
|
||||
{
|
||||
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|
||||
|| super.mouseDragged( x, y, button, deltaX, deltaY );
|
||||
}
|
||||
}
|
||||
|
@@ -241,11 +241,12 @@ public class WidgetTerminal implements IGuiEventListener
|
||||
charX = Math.min( Math.max( charX, 0 ), term.getWidth() - 1 );
|
||||
charY = Math.min( Math.max( charY, 0 ), term.getHeight() - 1 );
|
||||
|
||||
computer.mouseDrag( button + 1, charX + 1, charY + 1 );
|
||||
|
||||
lastMouseX = charX;
|
||||
lastMouseY = charY;
|
||||
lastMouseButton = button;
|
||||
if( button == lastMouseButton && (charX != lastMouseX || charY != lastMouseY) )
|
||||
{
|
||||
computer.mouseDrag( button + 1, charX + 1, charY + 1 );
|
||||
lastMouseX = charX;
|
||||
lastMouseY = charY;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -427,4 +428,10 @@ public class WidgetTerminal implements IGuiEventListener
|
||||
ClientComputer computer = this.computer.get();
|
||||
if( computer != null ) computer.queueEvent( event, args );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMouseOver( double x, double y )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -95,4 +95,11 @@ public class WidgetWrapper implements IGuiEventListener
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMouseOver( double x, double y )
|
||||
{
|
||||
double dx = x - this.x, dy = y - this.y;
|
||||
return dx >= 0 && dx < width && dy >= 0 && dy < height;
|
||||
}
|
||||
}
|
||||
|
@@ -8,7 +8,6 @@ package dan200.computercraft.shared.common;
|
||||
|
||||
import dan200.computercraft.shared.network.container.ContainerData;
|
||||
import dan200.computercraft.shared.network.container.HeldItemContainerData;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
@@ -33,7 +32,7 @@ public class ContainerHeldItem extends Container
|
||||
super( type, id );
|
||||
|
||||
this.hand = hand;
|
||||
stack = InventoryUtil.copyItem( player.getHeldItem( hand ) );
|
||||
stack = player.getHeldItem( hand ).copy();
|
||||
}
|
||||
|
||||
private static ContainerHeldItem createPrintout( int id, PlayerInventory inventory, HeldItemContainerData data )
|
||||
|
@@ -85,7 +85,7 @@ public class CommandAPI implements ILuaAPI
|
||||
{
|
||||
receiver.clearOutput();
|
||||
int result = commandManager.handleCommand( m_computer.getSource(), command );
|
||||
return new Object[] { result > 0, receiver.copyOutput() };
|
||||
return new Object[] { result > 0, receiver.copyOutput(), result };
|
||||
}
|
||||
catch( Throwable t )
|
||||
{
|
||||
|
@@ -311,13 +311,13 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
||||
@Override
|
||||
public double getTimeOfDay()
|
||||
{
|
||||
return (m_world.getGameTime() + 6000) % 24000 / 1000.0;
|
||||
return (m_world.getDayTime() + 6000) % 24000 / 1000.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDay()
|
||||
{
|
||||
return (int) ((m_world.getGameTime() + 6000) / 24000) + 1;
|
||||
return (int) ((m_world.getDayTime() + 6000) / 24000) + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -210,7 +210,7 @@ public class BlockCable extends BlockGeneric implements IWaterLoggable
|
||||
|
||||
BlockPos offsetPos = pos.offset( facing );
|
||||
BlockState offsetState = world.getBlockState( offsetPos );
|
||||
return Block.hasSolidSide( offsetState, world, offsetPos, facing.getOpposite() );
|
||||
return hasSolidSide( offsetState, world, offsetPos, facing.getOpposite() );
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@@ -201,8 +201,7 @@ public class TileCable extends TileGeneric implements IPeripheralTile
|
||||
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
||||
{
|
||||
Direction dir = getDirection();
|
||||
if( neighbour.equals( getPos().offset( dir ) ) && hasModem()
|
||||
&& getBlockState().isValidPosition( world, pos ) )
|
||||
if( neighbour.equals( getPos().offset( dir ) ) && hasModem() && !getBlockState().isValidPosition( getWorld(), getPos() ) )
|
||||
{
|
||||
if( hasCable() )
|
||||
{
|
||||
|
@@ -12,8 +12,7 @@ import dan200.computercraft.api.turtle.event.TurtleRefuelEvent;
|
||||
import dan200.computercraft.shared.util.InventoryUtil;
|
||||
import dan200.computercraft.shared.util.WorldUtil;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.FurnaceTileEntity;
|
||||
import net.minecraftforge.event.ForgeEventFactory;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@@ -52,15 +51,9 @@ public final class FurnaceRefuelHandler implements TurtleRefuelEvent.Handler
|
||||
return fuelToGive;
|
||||
}
|
||||
|
||||
|
||||
private static int getFuelPerItem( @Nonnull ItemStack stack )
|
||||
{
|
||||
int basicBurnTime = stack.getBurnTime();
|
||||
int burnTime = ForgeEventFactory.getItemBurnTime(
|
||||
stack,
|
||||
basicBurnTime == -1 ? FurnaceTileEntity.getBurnTimes().getOrDefault( stack.getItem(), 0 ) : basicBurnTime
|
||||
);
|
||||
return (burnTime * 5) / 100;
|
||||
return (ForgeHooks.getBurnTime( stack ) * 5) / 100;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@@ -237,7 +237,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
m_inventoryChanged = false;
|
||||
for( int n = 0; n < getSizeInventory(); n++ )
|
||||
{
|
||||
m_previousInventory.set( n, InventoryUtil.copyItem( getStackInSlot( n ) ) );
|
||||
m_previousInventory.set( n, getStackInSlot( n ).copy() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -286,7 +286,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
||||
if( slot < getSizeInventory() )
|
||||
{
|
||||
m_inventory.set( slot, ItemStack.read( tag ) );
|
||||
m_previousInventory.set( slot, InventoryUtil.copyItem( m_inventory.get( slot ) ) );
|
||||
m_previousInventory.set( slot, m_inventory.get( slot ).copy() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@ import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||
import dan200.computercraft.shared.util.Colour;
|
||||
import dan200.computercraft.shared.util.Holiday;
|
||||
import dan200.computercraft.shared.util.HolidayUtil;
|
||||
import dan200.computercraft.shared.util.InventoryDelegate;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
@@ -43,6 +44,7 @@ import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.wrapper.InvWrapper;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.*;
|
||||
@@ -68,6 +70,9 @@ public class TurtleBrain implements ITurtleAccess
|
||||
private ComputerProxy m_proxy;
|
||||
private GameProfile m_owningPlayer;
|
||||
|
||||
private final IInventory m_inventory = (InventoryDelegate) () -> m_owner;
|
||||
private final IItemHandlerModifiable m_inventoryWrapper = new InvWrapper( m_inventory );
|
||||
|
||||
private Queue<TurtleCommandQueueEntry> m_commandQueue = new ArrayDeque<>();
|
||||
private int m_commandsIssued = 0;
|
||||
|
||||
@@ -439,14 +444,14 @@ public class TurtleBrain implements ITurtleAccess
|
||||
@Override
|
||||
public IInventory getInventory()
|
||||
{
|
||||
return m_owner;
|
||||
return m_inventory;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IItemHandlerModifiable getItemHandler()
|
||||
{
|
||||
return m_owner.getItemHandler();
|
||||
return m_inventoryWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -14,8 +14,6 @@ import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingDropsEvent;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.eventbus.api.EventPriority;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
@@ -36,7 +34,6 @@ public final class DropConsumer
|
||||
private static Function<ItemStack, ItemStack> dropConsumer;
|
||||
private static List<ItemStack> remainingDrops;
|
||||
private static WeakReference<World> dropWorld;
|
||||
private static BlockPos dropPos;
|
||||
private static AxisAlignedBB dropBounds;
|
||||
private static WeakReference<Entity> dropEntity;
|
||||
|
||||
@@ -46,7 +43,6 @@ public final class DropConsumer
|
||||
remainingDrops = new ArrayList<>();
|
||||
dropEntity = new WeakReference<>( entity );
|
||||
dropWorld = new WeakReference<>( entity.world );
|
||||
dropPos = null;
|
||||
dropBounds = new AxisAlignedBB( entity.getPosition() ).grow( 2, 2, 2 );
|
||||
|
||||
entity.captureDrops( new ArrayList<>() );
|
||||
@@ -55,10 +51,9 @@ public final class DropConsumer
|
||||
public static void set( World world, BlockPos pos, Function<ItemStack, ItemStack> consumer )
|
||||
{
|
||||
dropConsumer = consumer;
|
||||
remainingDrops = new ArrayList<>();
|
||||
remainingDrops = new ArrayList<>( 2 );
|
||||
dropEntity = null;
|
||||
dropWorld = new WeakReference<>( world );
|
||||
dropPos = pos;
|
||||
dropBounds = new AxisAlignedBB( pos ).grow( 2, 2, 2 );
|
||||
}
|
||||
|
||||
@@ -83,7 +78,6 @@ public final class DropConsumer
|
||||
remainingDrops = null;
|
||||
dropEntity = null;
|
||||
dropWorld = null;
|
||||
dropPos = null;
|
||||
dropBounds = null;
|
||||
|
||||
return remainingStacks;
|
||||
@@ -95,34 +89,7 @@ public final class DropConsumer
|
||||
if( !remaining.isEmpty() ) remainingDrops.add( remaining );
|
||||
}
|
||||
|
||||
@SubscribeEvent( priority = EventPriority.LOWEST )
|
||||
public static void onEntityLivingDrops( LivingDropsEvent event )
|
||||
{
|
||||
// Capture any mob drops for the current entity
|
||||
if( dropEntity != null && event.getEntity() == dropEntity.get() )
|
||||
{
|
||||
Collection<ItemEntity> drops = event.getDrops();
|
||||
for( ItemEntity entityItem : drops ) handleDrops( entityItem.getItem() );
|
||||
drops.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent( priority = EventPriority.LOWEST )
|
||||
public static void onHarvestDrops( BlockEvent.HarvestDropsEvent event )
|
||||
{
|
||||
// Capture block drops for the current entity
|
||||
if( dropWorld != null && dropWorld.get() == event.getWorld()
|
||||
&& dropPos != null && dropPos.equals( event.getPos() ) )
|
||||
{
|
||||
for( ItemStack item : event.getDrops() )
|
||||
{
|
||||
if( event.getWorld().getRandom().nextFloat() < event.getDropChance() ) handleDrops( item );
|
||||
}
|
||||
event.getDrops().clear();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent( priority = EventPriority.LOWEST )
|
||||
@SubscribeEvent( priority = EventPriority.HIGHEST )
|
||||
public static void onEntitySpawn( EntityJoinWorldEvent event )
|
||||
{
|
||||
// Capture any nearby item spawns
|
||||
|
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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 net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Provides a delegate over inventories.
|
||||
*
|
||||
* This may be used both on {@link net.minecraft.tileentity.TileEntity}s to redirect the inventory to another tile,
|
||||
* and by other interfaces to have inventories which change their backing store.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface InventoryDelegate extends IInventory
|
||||
{
|
||||
IInventory getInventory();
|
||||
|
||||
@Override
|
||||
default int getSizeInventory()
|
||||
{
|
||||
return getInventory().getSizeInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isEmpty()
|
||||
{
|
||||
return getInventory().isEmpty();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
default ItemStack getStackInSlot( int slot )
|
||||
{
|
||||
return getInventory().getStackInSlot( slot );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
default ItemStack decrStackSize( int slot, int count )
|
||||
{
|
||||
return getInventory().decrStackSize( slot, count );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
default ItemStack removeStackFromSlot( int slot )
|
||||
{
|
||||
return getInventory().removeStackFromSlot( slot );
|
||||
}
|
||||
|
||||
@Override
|
||||
default void setInventorySlotContents( int slot, ItemStack stack )
|
||||
{
|
||||
getInventory().setInventorySlotContents( slot, stack );
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getInventoryStackLimit()
|
||||
{
|
||||
return getInventory().getInventoryStackLimit();
|
||||
}
|
||||
|
||||
@Override
|
||||
default void markDirty()
|
||||
{
|
||||
getInventory().markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isUsableByPlayer( @Nonnull PlayerEntity player )
|
||||
{
|
||||
return getInventory().isUsableByPlayer( player );
|
||||
}
|
||||
|
||||
@Override
|
||||
default void openInventory( @Nonnull PlayerEntity player )
|
||||
{
|
||||
getInventory().openInventory( player );
|
||||
}
|
||||
|
||||
@Override
|
||||
default void closeInventory( @Nonnull PlayerEntity player )
|
||||
{
|
||||
getInventory().closeInventory( player );
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isItemValidForSlot( int slot, @Nonnull ItemStack stack )
|
||||
{
|
||||
return getInventory().isItemValidForSlot( slot, stack );
|
||||
}
|
||||
|
||||
@Override
|
||||
default void clear()
|
||||
{
|
||||
getInventory().clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
default int count( @Nonnull Item stack )
|
||||
{
|
||||
return getInventory().count( stack );
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean hasAny( @Nonnull Set<Item> set )
|
||||
{
|
||||
return getInventory().hasAny( set );
|
||||
}
|
||||
}
|
@@ -70,12 +70,6 @@ public final class InventoryUtil
|
||||
return shareTagA.equals( shareTagB );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static ItemStack copyItem( @Nonnull ItemStack a )
|
||||
{
|
||||
return a.copy();
|
||||
}
|
||||
|
||||
// Methods for finding inventories:
|
||||
|
||||
public static IItemHandler getInventory( World world, BlockPos pos, Direction side )
|
||||
|
@@ -431,16 +431,20 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
|
||||
return nX, nY
|
||||
end
|
||||
|
||||
function window.reposition( nNewX, nNewY, nNewWidth, nNewHeight )
|
||||
function window.reposition( nNewX, nNewY, nNewWidth, nNewHeight, newParent )
|
||||
if type(nNewX) ~= "number" then expect(1, nNewX, "number") end
|
||||
if type(nNewY) ~= "number" then expect(2, nNewY, "number") end
|
||||
if nNewWidth ~= nil or nNewHeight ~= nil then
|
||||
expect(3, nNewWidth, "number")
|
||||
expect(4, nNewHeight, "number")
|
||||
end
|
||||
if newParent ~= nil and type(newParent) ~= "table" then expect(5, newParent, "table") end
|
||||
|
||||
nX = nNewX
|
||||
nY = nNewY
|
||||
|
||||
if newParent then parent = newParent end
|
||||
|
||||
if nNewWidth and nNewHeight then
|
||||
local tNewLines = {}
|
||||
createEmptyLines( nNewWidth )
|
||||
|
@@ -1,3 +1,16 @@
|
||||
# New features in CC: Tweaked 1.85.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.
|
||||
|
||||
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 os.day/os.time using the incorrect world time.
|
||||
* Prevent wired modems dropping incorrectly.
|
||||
* Fix mouse events not firing within the computer GUI.
|
||||
|
||||
# New features in CC: Tweaked 1.84.1
|
||||
|
||||
* Update to latest Forge
|
||||
|
@@ -1,5 +1,14 @@
|
||||
New features in CC: Tweaked 1.84.1
|
||||
New features in CC: Tweaked 1.85.0
|
||||
|
||||
* Update to latest Forge
|
||||
* 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.
|
||||
|
||||
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 os.day/os.time using the incorrect world time.
|
||||
* Prevent wired modems dropping incorrectly.
|
||||
* Fix mouse events not firing within the computer GUI.
|
||||
|
||||
Type "help changelog" to see the full version history.
|
||||
|
@@ -0,0 +1,105 @@
|
||||
--- A collection of helper methods for working with input completion, such
|
||||
-- as that require by @{read}.
|
||||
--
|
||||
-- @module craftos.completion
|
||||
-- @see cc.shell.completion For additional helpers to use with
|
||||
-- @{shell.setCompletionFunction}.
|
||||
|
||||
local expect = require "cc.expect".expect
|
||||
|
||||
local function choice_impl(text, choices, add_space)
|
||||
local results = {}
|
||||
for n = 1, #choices do
|
||||
local option = choices[n]
|
||||
if #option + (add_space and 1 or 0) > #text and option:sub(1, #text) == text then
|
||||
local result = option:sub(#text + 1)
|
||||
if add_space then
|
||||
table.insert(results, result .. " ")
|
||||
else
|
||||
table.insert(results, result)
|
||||
end
|
||||
end
|
||||
end
|
||||
return results
|
||||
end
|
||||
|
||||
--- Complete from a choice of one or more strings.
|
||||
--
|
||||
-- @tparam string text The input string to complete.
|
||||
-- @tparam { string... } choices The list of choices to complete from.
|
||||
-- @tparam[opt] boolean add_space Whether to add a space after the completed item.
|
||||
-- @treturn { string... } A list of suffixes of matching strings.
|
||||
-- @usage Call @{read}, completing the names of various animals.
|
||||
--
|
||||
-- local animals = { "dog", "cat", "lion", "unicorn" }
|
||||
-- read(nil, nil, function(text) return choice(text, animals) end)
|
||||
local function choice(text, choices, add_space)
|
||||
expect(1, text, "string")
|
||||
expect(2, choices, "table")
|
||||
expect(3, add_space, "boolean", "nil")
|
||||
return choice_impl(text, choices, add_space)
|
||||
end
|
||||
|
||||
--- Complete the name of a currently attached peripheral.
|
||||
--
|
||||
-- @tparam string text The input string to complete.
|
||||
-- @tparam[opt] boolean add_space Whether to add a space after the completed name.
|
||||
-- @treturn { string... } A list of suffixes of matching peripherals.
|
||||
-- @usage read(nil, nil, peripheral)
|
||||
local function peripheral_(text, add_space)
|
||||
expect(1, text, "string")
|
||||
expect(2, add_space, "boolean", "nil")
|
||||
return choice_impl(text, peripheral.getNames(), add_space)
|
||||
end
|
||||
|
||||
local sides = redstone.getSides()
|
||||
|
||||
--- Complete the side of a computer.
|
||||
--
|
||||
-- @tparam string text The input string to complete.
|
||||
-- @tparam[opt] boolean add_space Whether to add a space after the completed side.
|
||||
-- @treturn { string... } A list of suffixes of matching sides.
|
||||
-- @usage read(nil, nil, side)
|
||||
local function side(text, add_space)
|
||||
expect(1, text, "string")
|
||||
expect(2, add_space, "boolean", "nil")
|
||||
return choice_impl(text, sides, add_space)
|
||||
end
|
||||
|
||||
--- Complete a @{settings|setting}.
|
||||
--
|
||||
-- @tparam string text The input string to complete.
|
||||
-- @tparam[opt] boolean add_space Whether to add a space after the completed settings.
|
||||
-- @treturn { string... } A list of suffixes of matching settings.
|
||||
-- @usage read(nil, nil, setting)
|
||||
local function setting(text, add_space)
|
||||
expect(1, text, "string")
|
||||
expect(2, add_space, "boolean", "nil")
|
||||
return choice_impl(text, settings.getNames(), add_space)
|
||||
end
|
||||
|
||||
local command_list
|
||||
|
||||
--- Complete the name of a Minecraft @{commands|command}.
|
||||
--
|
||||
-- @tparam string text The input string to complete.
|
||||
-- @tparam[opt] boolean add_space Whether to add a space after the completed command.
|
||||
-- @treturn { string... } A list of suffixes of matching commands.
|
||||
-- @usage read(nil, nil, command)
|
||||
local function command(text, add_space)
|
||||
expect(1, text, "string")
|
||||
expect(2, add_space, "boolean", "nil")
|
||||
if command_list == nil then
|
||||
command_list = commands and commands.list() or {}
|
||||
end
|
||||
|
||||
return choice_impl(text, command_list, add_space)
|
||||
end
|
||||
|
||||
return {
|
||||
choice = choice,
|
||||
peripheral = peripheral_,
|
||||
side = side,
|
||||
setting = setting,
|
||||
command = command,
|
||||
}
|
@@ -0,0 +1,151 @@
|
||||
--- A collection of helper methods for working with shell completion.
|
||||
--
|
||||
-- Most programs may be completed using the @{build} helper method, rather than
|
||||
-- manually switching on the argument index.
|
||||
--
|
||||
-- Note, the helper functions within this module do not accept an argument index,
|
||||
-- and so are not directly usable with the @{shell.setCompletionFunction}. Instead,
|
||||
-- wrap them using @{build}, or your own custom function.
|
||||
--
|
||||
-- @module craftos.shell.completion
|
||||
-- @see cc.completion For more general helpers, suitable for use with @{read}.
|
||||
-- @see shell.setCompletionFunction
|
||||
|
||||
local expect = require "cc.expect".expect
|
||||
local completion = require "cc.completion"
|
||||
|
||||
--- Complete the name of a file relative to the current working directory.
|
||||
--
|
||||
-- @tparam shell shell The shell we're completing in
|
||||
-- @tparam { string... } choices The list of choices to complete from.
|
||||
-- @treturn { string... } A list of suffixes of matching files.
|
||||
local function file(shell, text)
|
||||
return fs.complete(text, shell.dir(), true, false)
|
||||
end
|
||||
|
||||
--- Complete the name of a directory relative to the current working directory.
|
||||
--
|
||||
-- @tparam shell shell The shell we're completing in
|
||||
-- @tparam { string... } choices The list of choices to complete from.
|
||||
-- @treturn { string... } A list of suffixes of matching directories.
|
||||
local function dir(shell, text)
|
||||
return fs.complete(text, shell.dir(), false, true)
|
||||
end
|
||||
|
||||
--- Complete the name of a file or directory relative to the current working
|
||||
-- directory.
|
||||
--
|
||||
-- @tparam shell shell The shell we're completing in
|
||||
-- @tparam { string... } choices The list of choices to complete from.
|
||||
-- @tparam { string... } previous The shell arguments before this one.
|
||||
-- @tparam[opt] boolean add_space Whether to add a space after the completed item.
|
||||
-- @treturn { string... } A list of suffixes of matching files and directories.
|
||||
local function dirOrFile(shell, text, previous, add_space)
|
||||
local results = fs.complete(text, shell.dir(), true, true)
|
||||
if add_space then
|
||||
for n = 1, #results do
|
||||
local result = results[n]
|
||||
if result:sub(-1) ~= "/" then
|
||||
results[n] = result .. " "
|
||||
end
|
||||
end
|
||||
end
|
||||
return results
|
||||
end
|
||||
|
||||
local function wrap(func)
|
||||
return function(shell, text, previous, ...)
|
||||
return func(text, ...)
|
||||
end
|
||||
end
|
||||
|
||||
--- Complete the name of a program.
|
||||
--
|
||||
-- @tparam shell shell The shell we're completing in
|
||||
-- @tparam { string... } choices The list of choices to complete from.
|
||||
-- @treturn { string... } A list of suffixes of matching programs.
|
||||
local function program(shell, text)
|
||||
return shell.completeProgram(text)
|
||||
end
|
||||
|
||||
--- A helper function for building shell completion arguments.
|
||||
--
|
||||
-- This accepts a series of single-argument completion functions, and combines
|
||||
-- them into a function suitable for use with @{shell.setCompletionFunction}.
|
||||
--
|
||||
-- @tparam nil|table|function ... Every argument to @{build} represents an argument
|
||||
-- to the program you wish to complete. Each argument can be one of three types:
|
||||
--
|
||||
-- - `nil`: This argument will not be completed.
|
||||
--
|
||||
-- - A function: This argument will be completed with the given function. It is
|
||||
-- called with the @{shell} object, the string to complete and the arguments
|
||||
-- before this one.
|
||||
--
|
||||
-- - A table: This acts as a more powerful version of the function case. The table
|
||||
-- must have a function as the first item - this will be called with the shell,
|
||||
-- string and preceding arguments as above, but also followed by any additional
|
||||
-- items in the table. This provides a more convenient interface to pass
|
||||
-- options to your completion functions.
|
||||
--
|
||||
-- If this table is the last argument, it may also set the `many` key to true,
|
||||
-- which states this function should be used to complete any remaining arguments.
|
||||
--
|
||||
-- @usage Prompt for a choice of options, followed by a directory, and then multiple
|
||||
-- files.
|
||||
--
|
||||
-- complete.build(
|
||||
-- { complete.choice, { "get", "put" } },
|
||||
-- complete.dir,
|
||||
-- } complete.file, many = true }
|
||||
-- )
|
||||
local function build(...)
|
||||
local arguments = table.pack(...)
|
||||
for i = 1, arguments.n do
|
||||
local arg = arguments[i]
|
||||
if arg ~= nil then
|
||||
expect(i, arg, "table", "function")
|
||||
if type(arg) == "function" then
|
||||
arg = { arg }
|
||||
arguments[i] = arg
|
||||
end
|
||||
|
||||
if type(arg[1]) ~= "function" then
|
||||
error(("Bad table entry #1 at argument #%d (expected function, got %s)"):format(i, type(arg[1])), 2)
|
||||
end
|
||||
|
||||
if arg.many and i < arguments.n then
|
||||
error(("Unexpected 'many' field on argument #%d (should only occur on the last argument)"):format(i), 2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return function(shell, index, text, previous)
|
||||
local arg = arguments[index]
|
||||
if not arg then
|
||||
if index <= arguments.n then return end
|
||||
|
||||
arg = arguments[arguments.n]
|
||||
if not arg or not arg.many then return end
|
||||
end
|
||||
|
||||
return arg[1](shell, text, previous, table.unpack(arg, 2))
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
file = file,
|
||||
dir = dir,
|
||||
dirOrFile = dirOrFile,
|
||||
program = program,
|
||||
|
||||
-- Re-export various other functions
|
||||
help = wrap(help.completeTopic),
|
||||
choice = wrap(completion.choice),
|
||||
peripheral = wrap(completion.peripheral),
|
||||
side = wrap(completion.side),
|
||||
setting = wrap(completion.setting),
|
||||
command = wrap(completion.command),
|
||||
|
||||
build = build,
|
||||
}
|
@@ -7,7 +7,7 @@ else
|
||||
end
|
||||
|
||||
if sTopic == "index" then
|
||||
print( "Help topics availiable:" )
|
||||
print( "Help topics available:" )
|
||||
local tTopics = help.topics()
|
||||
textutils.pagedTabulate( tTopics )
|
||||
return
|
||||
|
@@ -1,3 +1,4 @@
|
||||
local completion = require "cc.shell.completion"
|
||||
|
||||
-- Setup paths
|
||||
local sPath = ".:/rom/programs"
|
||||
@@ -39,217 +40,86 @@ if term.isColor() then
|
||||
end
|
||||
|
||||
-- Setup completion functions
|
||||
local function completeMultipleChoice( sText, tOptions, bAddSpaces )
|
||||
local tResults = {}
|
||||
for n=1,#tOptions do
|
||||
local sOption = tOptions[n]
|
||||
if #sOption + (bAddSpaces and 1 or 0) > #sText and string.sub( sOption, 1, #sText ) == sText then
|
||||
local sResult = string.sub( sOption, #sText + 1 )
|
||||
if bAddSpaces then
|
||||
table.insert( tResults, sResult .. " " )
|
||||
else
|
||||
table.insert( tResults, sResult )
|
||||
end
|
||||
end
|
||||
end
|
||||
return tResults
|
||||
end
|
||||
local function completePeripheralName( sText, bAddSpaces )
|
||||
return completeMultipleChoice( sText, peripheral.getNames(), bAddSpaces )
|
||||
end
|
||||
local tRedstoneSides = redstone.getSides()
|
||||
local function completeSide( sText, bAddSpaces )
|
||||
return completeMultipleChoice( sText, tRedstoneSides, bAddSpaces )
|
||||
end
|
||||
local function completeFile( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return fs.complete( sText, shell.dir(), true, false )
|
||||
|
||||
local function completePastebinPut(shell, text, previous)
|
||||
if previous[2] == "put" then
|
||||
return fs.complete(text, shell.dir(), true, false )
|
||||
end
|
||||
end
|
||||
local function completeFileMany( shell, nIndex, sText, tPreviousText )
|
||||
return fs.complete( sText, shell.dir(), true, false )
|
||||
end
|
||||
local function completeDir( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return fs.complete( sText, shell.dir(), false, true )
|
||||
end
|
||||
end
|
||||
local function completeEither( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return fs.complete( sText, shell.dir(), true, true )
|
||||
end
|
||||
end
|
||||
local function completeEitherMany( shell, nIndex, sText, tPreviousText )
|
||||
return fs.complete( sText, shell.dir(), true, true )
|
||||
end
|
||||
local function completeEitherEither( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
local tResults = fs.complete( sText, shell.dir(), true, true )
|
||||
for n=1,#tResults do
|
||||
local sResult = tResults[n]
|
||||
if string.sub( sResult, #sResult, #sResult ) ~= "/" then
|
||||
tResults[n] = sResult .. " "
|
||||
end
|
||||
end
|
||||
return tResults
|
||||
elseif nIndex == 2 then
|
||||
return fs.complete( sText, shell.dir(), true, true )
|
||||
end
|
||||
end
|
||||
local function completeProgram( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return shell.completeProgram( sText )
|
||||
end
|
||||
end
|
||||
local function completeHelp( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return help.completeTopic( sText )
|
||||
end
|
||||
end
|
||||
local function completeAlias( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 2 then
|
||||
return shell.completeProgram( sText )
|
||||
end
|
||||
end
|
||||
local function completePeripheral( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return completePeripheralName( sText )
|
||||
end
|
||||
end
|
||||
local tGPSOptions = { "host", "host ", "locate" }
|
||||
local function completeGPS( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return completeMultipleChoice( sText, tGPSOptions )
|
||||
end
|
||||
end
|
||||
local tLabelOptions = { "get", "get ", "set ", "clear", "clear " }
|
||||
local function completeLabel( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return completeMultipleChoice( sText, tLabelOptions )
|
||||
elseif nIndex == 2 then
|
||||
return completePeripheralName( sText )
|
||||
end
|
||||
end
|
||||
local function completeMonitor( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return completePeripheralName( sText, true )
|
||||
elseif nIndex == 2 then
|
||||
return shell.completeProgram( sText )
|
||||
end
|
||||
end
|
||||
local tRedstoneOptions = { "probe", "set ", "pulse " }
|
||||
local function completeRedstone( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return completeMultipleChoice( sText, tRedstoneOptions )
|
||||
elseif nIndex == 2 then
|
||||
return completeSide( sText )
|
||||
end
|
||||
end
|
||||
local tDJOptions = { "play", "play ", "stop " }
|
||||
local function completeDJ( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return completeMultipleChoice( sText, tDJOptions )
|
||||
elseif nIndex == 2 then
|
||||
return completePeripheralName( sText )
|
||||
end
|
||||
end
|
||||
local tPastebinOptions = { "put ", "get ", "run " }
|
||||
local function completePastebin( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return completeMultipleChoice( sText, tPastebinOptions )
|
||||
elseif nIndex == 2 then
|
||||
if tPreviousText[2] == "put" then
|
||||
return fs.complete( sText, shell.dir(), true, false )
|
||||
end
|
||||
end
|
||||
end
|
||||
local tChatOptions = { "host ", "join " }
|
||||
local function completeChat( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return completeMultipleChoice( sText, tChatOptions )
|
||||
end
|
||||
end
|
||||
local function completeSet( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return completeMultipleChoice( sText, settings.getNames(), true )
|
||||
end
|
||||
end
|
||||
local tCommands
|
||||
if commands then
|
||||
tCommands = commands.list()
|
||||
end
|
||||
local function completeExec( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 and commands then
|
||||
return completeMultipleChoice( sText, tCommands, true )
|
||||
end
|
||||
end
|
||||
local tWgetOptions = { "run" }
|
||||
local function completeWget( shell, nIndex, sText, tPreviousText )
|
||||
if nIndex == 1 then
|
||||
return completeMultipleChoice( sText, tWgetOptions, true )
|
||||
end
|
||||
end
|
||||
shell.setCompletionFunction( "rom/programs/alias.lua", completeAlias )
|
||||
shell.setCompletionFunction( "rom/programs/cd.lua", completeDir )
|
||||
shell.setCompletionFunction( "rom/programs/copy.lua", completeEitherEither )
|
||||
shell.setCompletionFunction( "rom/programs/delete.lua", completeEitherMany )
|
||||
shell.setCompletionFunction( "rom/programs/drive.lua", completeDir )
|
||||
shell.setCompletionFunction( "rom/programs/edit.lua", completeFile )
|
||||
shell.setCompletionFunction( "rom/programs/eject.lua", completePeripheral )
|
||||
shell.setCompletionFunction( "rom/programs/gps.lua", completeGPS )
|
||||
shell.setCompletionFunction( "rom/programs/help.lua", completeHelp )
|
||||
shell.setCompletionFunction( "rom/programs/id.lua", completePeripheral )
|
||||
shell.setCompletionFunction( "rom/programs/label.lua", completeLabel )
|
||||
shell.setCompletionFunction( "rom/programs/list.lua", completeDir )
|
||||
shell.setCompletionFunction( "rom/programs/mkdir.lua", completeFileMany )
|
||||
shell.setCompletionFunction( "rom/programs/monitor.lua", completeMonitor )
|
||||
shell.setCompletionFunction( "rom/programs/move.lua", completeEitherEither )
|
||||
shell.setCompletionFunction( "rom/programs/redstone.lua", completeRedstone )
|
||||
shell.setCompletionFunction( "rom/programs/rename.lua", completeEitherEither )
|
||||
shell.setCompletionFunction( "rom/programs/shell.lua", completeProgram )
|
||||
shell.setCompletionFunction( "rom/programs/type.lua", completeEither )
|
||||
shell.setCompletionFunction( "rom/programs/set.lua", completeSet )
|
||||
shell.setCompletionFunction( "rom/programs/advanced/bg.lua", completeProgram )
|
||||
shell.setCompletionFunction( "rom/programs/advanced/fg.lua", completeProgram )
|
||||
shell.setCompletionFunction( "rom/programs/fun/dj.lua", completeDJ )
|
||||
shell.setCompletionFunction( "rom/programs/fun/advanced/paint.lua", completeFile )
|
||||
shell.setCompletionFunction( "rom/programs/http/pastebin.lua", completePastebin )
|
||||
shell.setCompletionFunction( "rom/programs/rednet/chat.lua", completeChat )
|
||||
shell.setCompletionFunction( "rom/programs/command/exec.lua", completeExec )
|
||||
shell.setCompletionFunction( "rom/programs/http/wget.lua", completeWget )
|
||||
|
||||
shell.setCompletionFunction( "rom/programs/alias.lua", completion.build(nil, completion.program) )
|
||||
shell.setCompletionFunction( "rom/programs/cd.lua", completion.build(completion.dir) )
|
||||
shell.setCompletionFunction( "rom/programs/copy.lua", completion.build(
|
||||
{ completion.dirOrFile, true },
|
||||
completion.dirOrFile
|
||||
) )
|
||||
shell.setCompletionFunction( "rom/programs/delete.lua", completion.build({ completion.dirOrFile, many = true }) )
|
||||
shell.setCompletionFunction( "rom/programs/drive.lua", completion.build(completion.dir) )
|
||||
shell.setCompletionFunction( "rom/programs/edit.lua", completion.build(completion.file) )
|
||||
shell.setCompletionFunction( "rom/programs/eject.lua", completion.build(completion.peripheral) )
|
||||
shell.setCompletionFunction( "rom/programs/gps.lua", completion.build({ completion.choice, { "host", "host ", "locate" } }) )
|
||||
shell.setCompletionFunction( "rom/programs/help.lua", completion.build(completion.help) )
|
||||
shell.setCompletionFunction( "rom/programs/id.lua", completion.build(completion.peripheral) )
|
||||
shell.setCompletionFunction( "rom/programs/label.lua", completion.build(
|
||||
{ completion.choice, { "get", "get ", "set ", "clear", "clear " } },
|
||||
completion.peripheral
|
||||
) )
|
||||
shell.setCompletionFunction( "rom/programs/list.lua", completion.build(completion.dir) )
|
||||
shell.setCompletionFunction( "rom/programs/mkdir.lua", completion.build({ completion.dir, many = true }) )
|
||||
shell.setCompletionFunction( "rom/programs/monitor.lua", completion.build(
|
||||
{ completion.peripheral, true },
|
||||
completion.program
|
||||
) )
|
||||
shell.setCompletionFunction( "rom/programs/move.lua", completion.build(
|
||||
{ completion.dirOrFile, true },
|
||||
completion.dirOrFile
|
||||
) )
|
||||
shell.setCompletionFunction( "rom/programs/redstone.lua", completion.build(
|
||||
{ completion.choice, { "probe", "set ", "pulse " } },
|
||||
completion.side
|
||||
) )
|
||||
shell.setCompletionFunction( "rom/programs/rename.lua", completion.build(
|
||||
{ completion.dirOrFile, true },
|
||||
completion.dirOrFile
|
||||
) )
|
||||
shell.setCompletionFunction( "rom/programs/shell.lua", completion.build(completion.program) )
|
||||
shell.setCompletionFunction( "rom/programs/type.lua", completion.build(completion.dirOrFile) )
|
||||
shell.setCompletionFunction( "rom/programs/set.lua", completion.build({ completion.setting, true }) )
|
||||
shell.setCompletionFunction( "rom/programs/advanced/bg.lua", completion.build(completion.program) )
|
||||
shell.setCompletionFunction( "rom/programs/advanced/fg.lua", completion.build(completion.program) )
|
||||
shell.setCompletionFunction( "rom/programs/fun/dj.lua", completion.build(
|
||||
{ completion.choice, { "play", "play ", "stop " } },
|
||||
completion.peripheral
|
||||
) )
|
||||
shell.setCompletionFunction( "rom/programs/fun/advanced/paint.lua", completion.build(completion.file) )
|
||||
shell.setCompletionFunction( "rom/programs/http/pastebin.lua", completion.build(
|
||||
{ completion.choice, { "put ", "get ", "run " } },
|
||||
completePastebinPut
|
||||
) )
|
||||
shell.setCompletionFunction( "rom/programs/rednet/chat.lua", completion.build({ completion.choice, { "host ", "join " } }) )
|
||||
shell.setCompletionFunction( "rom/programs/command/exec.lua", completion.build(completion.command) )
|
||||
shell.setCompletionFunction( "rom/programs/http/wget.lua", completion.build({ completion.choice, { "run " } }) )
|
||||
|
||||
if turtle then
|
||||
local tGoOptions = { "left", "right", "forward", "back", "down", "up" }
|
||||
local function completeGo( shell, nIndex, sText )
|
||||
return completeMultipleChoice( sText, tGoOptions, true)
|
||||
end
|
||||
local tTurnOptions = { "left", "right" }
|
||||
local function completeTurn( shell, nIndex, sText )
|
||||
return completeMultipleChoice( sText, tTurnOptions, true )
|
||||
end
|
||||
local tEquipOptions = { "left", "right" }
|
||||
local function completeEquip( shell, nIndex, sText )
|
||||
if nIndex == 2 then
|
||||
return completeMultipleChoice( sText, tEquipOptions )
|
||||
end
|
||||
end
|
||||
local function completeUnequip( shell, nIndex, sText )
|
||||
if nIndex == 1 then
|
||||
return completeMultipleChoice( sText, tEquipOptions )
|
||||
end
|
||||
end
|
||||
shell.setCompletionFunction( "rom/programs/turtle/go.lua", completeGo )
|
||||
shell.setCompletionFunction( "rom/programs/turtle/turn.lua", completeTurn )
|
||||
shell.setCompletionFunction( "rom/programs/turtle/equip.lua", completeEquip )
|
||||
shell.setCompletionFunction( "rom/programs/turtle/unequip.lua", completeUnequip )
|
||||
shell.setCompletionFunction( "rom/programs/turtle/go.lua", completion.build(
|
||||
{ completion.choice, { "left", "right", "forward", "back", "down", "up" }, true, many = true }
|
||||
) )
|
||||
shell.setCompletionFunction( "rom/programs/turtle/turn.lua", completion.build(
|
||||
{ completion.choice, { "left", "right" }, true, many = true }
|
||||
))
|
||||
shell.setCompletionFunction( "rom/programs/turtle/equip.lua", completion.build(
|
||||
nil,
|
||||
{ completion.choice, { "left", "right" } }
|
||||
) )
|
||||
shell.setCompletionFunction( "rom/programs/turtle/unequip.lua", completion.build(
|
||||
{ completion.choice, { "left", "right" } }
|
||||
) )
|
||||
end
|
||||
|
||||
|
||||
-- Run autorun files
|
||||
if fs.exists( "/rom/autorun" ) and fs.isDir( "/rom/autorun" ) then
|
||||
local tFiles = fs.list( "/rom/autorun" )
|
||||
table.sort( tFiles )
|
||||
for n, sFile in ipairs( tFiles ) do
|
||||
for _, sFile in ipairs( tFiles ) do
|
||||
if string.sub( sFile, 1, 1 ) ~= "." then
|
||||
local sPath = "/rom/autorun/"..sFile
|
||||
if not fs.isDir( sPath ) then
|
||||
|
@@ -118,6 +118,26 @@ describe("The window library", function()
|
||||
expect.error(w.reposition, 1, 1, false, 1):eq("bad argument #3 (expected number, got boolean)")
|
||||
expect.error(w.reposition, 1, 1, nil, 1):eq("bad argument #3 (expected number, got nil)")
|
||||
expect.error(w.reposition, 1, 1, 1, nil):eq("bad argument #4 (expected number, got nil)")
|
||||
expect.error(w.reposition, 1, 1, 1, 1, true):eq("bad argument #5 (expected table, got boolean)")
|
||||
end)
|
||||
|
||||
it("can change the buffer", function()
|
||||
local a, b = mk(), mk()
|
||||
local target = window.create(a, 1, 1, a.getSize())
|
||||
|
||||
target.write("Test")
|
||||
expect((a.getLine(1))):equal("Test ")
|
||||
expect({ a.getCursorPos() }):same { 5, 1 }
|
||||
|
||||
target.reposition(1, 1, nil, nil, b)
|
||||
|
||||
target.redraw()
|
||||
expect((a.getLine(1))):equal("Test ")
|
||||
expect({ a.getCursorPos() }):same { 5, 1 }
|
||||
|
||||
target.setCursorPos(1, 1) target.write("More")
|
||||
expect((a.getLine(1))):equal("Test ")
|
||||
expect((b.getLine(1))):equal("More ")
|
||||
end)
|
||||
end)
|
||||
|
||||
|
@@ -0,0 +1,57 @@
|
||||
describe("cc.completion", function()
|
||||
local c = require("cc.completion")
|
||||
|
||||
describe("choice", function()
|
||||
it("provides all choices", function()
|
||||
expect(c.choice("", { "some text", "some other", "other" }))
|
||||
:same { "some text", "some other", "other" }
|
||||
end)
|
||||
|
||||
it("provides a filtered list of choices", function()
|
||||
expect(c.choice("som", { "some text", "some other", "other" }))
|
||||
:same { "e text", "e other" }
|
||||
|
||||
expect(c.choice("none", { "some text", "some other", "other" }))
|
||||
:same { }
|
||||
end)
|
||||
|
||||
it("adds text if needed", function()
|
||||
expect(c.choice("som", { "some text", "some other", "other" }, true))
|
||||
:same { "e text ", "e other " }
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("peripheral", function()
|
||||
it("provides a choice of peripherals", function()
|
||||
stub(peripheral, "getNames", function() return { "drive_0", "left" } end)
|
||||
|
||||
expect(c.peripheral("dri")):same { "ve_0" }
|
||||
expect(c.peripheral("dri", true)):same { "ve_0 " }
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("side", function()
|
||||
it("provides a choice of sides", function()
|
||||
expect(c.side("le")):same { "ft" }
|
||||
expect(c.side("le", true)):same { "ft " }
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("setting", function()
|
||||
it("provides a choice of setting names", function()
|
||||
stub(settings, "getNames", function() return { "shell.allow_startup", "list.show_hidden" } end)
|
||||
|
||||
expect(c.setting("li")):same { "st.show_hidden" }
|
||||
expect(c.setting("li", true)):same { "st.show_hidden " }
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("command", function()
|
||||
it("provides a choice of command names", function()
|
||||
stub(_G, "commands", { list = function() return { "list", "say" } end })
|
||||
|
||||
expect(c.command("li")):same { "st" }
|
||||
expect(c.command("li", true)):same { "st " }
|
||||
end)
|
||||
end)
|
||||
end)
|
@@ -0,0 +1,41 @@
|
||||
describe("cc.shell.completion", function()
|
||||
local c = require "cc.shell.completion"
|
||||
|
||||
describe("dirOrFile", 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"
|
||||
}
|
||||
end)
|
||||
|
||||
it("adds a space", function()
|
||||
expect(c.dirOrFile(shell, "rom/", nil, true)):same {
|
||||
"apis/", "apis ", "autorun/", "autorun ", "help/", "help ",
|
||||
"modules/", "modules ", "motd.txt ", "programs/", "programs ", "startup.lua ",
|
||||
}
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("build", function()
|
||||
it("completes multiple arguments", function()
|
||||
local spec = c.build(
|
||||
function() return { "a", "b", "c" } end,
|
||||
nil,
|
||||
{ c.choice, { "d", "e", "f"} }
|
||||
)
|
||||
|
||||
expect(spec(shell, 1, "")):same { "a", "b", "c" }
|
||||
expect(spec(shell, 2, "")):same(nil)
|
||||
expect(spec(shell, 3, "")):same { "d", "e", "f" }
|
||||
expect(spec(shell, 4, "")):same(nil)
|
||||
end)
|
||||
|
||||
it("supports variadic completions", function()
|
||||
local spec = c.build({ function() return { "a", "b", "c" } end, many = true })
|
||||
|
||||
expect(spec(shell, 1, "")):same({ "a", "b", "c" })
|
||||
expect(spec(shell, 2, "")):same({ "a", "b", "c" })
|
||||
end)
|
||||
end)
|
||||
end)
|
@@ -23,7 +23,7 @@ describe("The mkdir program", function()
|
||||
io.open("/test-files.a.txt", "w"):close()
|
||||
|
||||
local complete = shell.getCompletionInfo()["rom/programs/mkdir.lua"].fnComplete
|
||||
expect(complete(shell, 1, "/test-files/", {})):same { "a/", "b/" }
|
||||
expect(complete(shell, 2, "/test-files/", { "/" })):same { "a/", "b/" }
|
||||
expect(complete(shell, 1, "/test-files/", {})):same { "a/", "a", "b/", "b" }
|
||||
expect(complete(shell, 2, "/test-files/", { "/" })):same { "a/", "a", "b/", "b" }
|
||||
end)
|
||||
end)
|
||||
|
Reference in New Issue
Block a user